半年前在知乎瀏覽到一個(gè)帖子聘萨,是關(guān)于如何面試iOS工程師课竣。由于當(dāng)時(shí)公司正在招聘iOS工程師,自己也面試了不少同學(xué)叉信,就饒有興致的把自己的面試問(wèn)題清單貼了出去亩冬,卻意外的引來(lái)了不少關(guān)注。還有不少同學(xué)認(rèn)真回答并將答案私信于我交流的,還有求隱藏關(guān)卡的:(硅急。由于工作太忙覆享,私信和評(píng)論后面都沒(méi)怎么回復(fù),這里一并做下總結(jié)回復(fù):p
一份面試題的意義
我把收到的私信和一百多條評(píng)論都仔細(xì)讀了遍营袜,發(fā)現(xiàn)大家之所以會(huì)關(guān)注大致出于以下幾個(gè)原因:
剛畢業(yè)的同學(xué)最近在找工作面試撒顿,想刷題增加面試通過(guò)率。
有一定的工作經(jīng)歷的同學(xué)荚板,想測(cè)試下自己的iOS水平凤壁,看自己能賣(mài)多少錢(qián)。
本身iOS基礎(chǔ)不錯(cuò)跪另,抱著技多不壓身心態(tài)補(bǔ)充知識(shí)的拧抖。
土豪老板就差一個(gè)程序員了,想找份帶標(biāo)準(zhǔn)答案的面試題找真愛(ài)罚斗。
除了第三類(lèi)同學(xué)心態(tài)正確外徙鱼,其他的都高估面試題的作用了。面試題只是武功招式针姿,知識(shí)體系才是內(nèi)功心法袱吆。剛?cè)腴T(mén)記住的都是招式,但招式何其多距淫,面試的時(shí)候總會(huì)有遺漏和盲區(qū)绞绒,內(nèi)功心法才是一通萬(wàn)通,能以不變應(yīng)萬(wàn)變榕暇。這份面試題你答不全不能說(shuō)明你iOS不及格蓬衡,你全答對(duì)了你也不能上天。真正應(yīng)該關(guān)注的是這份題背后所包含的理論知識(shí)體系彤枢。帖子里還有其他不少優(yōu)質(zhì)回答狰晚,涵蓋候選人心態(tài),習(xí)慣缴啡,基礎(chǔ)知識(shí)壁晒,產(chǎn)品理解等各個(gè)方面,都值得一讀业栅。當(dāng)然啦秒咐,既然出了題,就得有答案碘裕,就有它的目標(biāo)群體携取。主要考察對(duì)象是從事iOS開(kāi)發(fā) 1~3年的同學(xué)。不需要全部答對(duì)帮孔,能對(duì)一半以上問(wèn)題侃侃而談就不錯(cuò)了雷滋。
評(píng)論區(qū)百態(tài)
評(píng)論區(qū)有各路神仙吐槽,有的說(shuō)難,有的說(shuō)太容易惊豺,還有美工和安卓黨出現(xiàn)燎孟。大家七嘴八舌的討論意見(jiàn)很雜,但從中可以看出不少同學(xué)心態(tài)都不正確尸昧。技術(shù)這條路無(wú)窮無(wú)盡揩页,廣度和深度的拓展都需要長(zhǎng)年累月的積累,不存在什么夠用就好了烹俗,用的時(shí)候再查下爆侣,沒(méi)必要了解這么深。技術(shù)人員的視野和耐力決定在這條路上你能夠走多遠(yuǎn)幢妄。下面幾類(lèi)同學(xué)點(diǎn)名批評(píng):
故作無(wú)知都機(jī)靈的兔仰。
覺(jué)得sqlite太重沒(méi)必要用的。
說(shuō)太容易不愿意答題的蕉鸳。
說(shuō)都不會(huì)但不影響做項(xiàng)目的乎赴。
說(shuō)圓角頭像讓美工切個(gè)圖就搞定的。
說(shuō)一半不會(huì)沒(méi)必要深究的潮尝。
心態(tài)不及格榕吼。
合格的答案
出乎我意料之外的是有好幾位同學(xué)都正二八經(jīng)的答了題,還把答案私信了我勉失。這里貼出其中一份答得還不錯(cuò)的羹蚣,再后面是答主自己的答案。 過(guò)關(guān)回答
我的答案
我有過(guò)不少面試和被面試的經(jīng)歷乱凿,作為面試官出這份面試題從來(lái)就不是為了難倒面試者顽素,而是為了多角度全面的了解面試者從而建立信任。面試的時(shí)候最擔(dān)心的是冷場(chǎng)徒蟆,面試題只不過(guò)個(gè)引子胁出,我心底里最希望遇到的面試者是能夠舉一反三,除了回答問(wèn)題本身之外段审,還能自信的旁征博引划鸽,深談其背后原理或者相關(guān)的知識(shí)理論的。問(wèn)題本身反而并不怎么重要戚哎。這份清單里的問(wèn)題也并不難,這里我列下我的回答以及從我的角度所期望的答案嫂用。
什么是arc型凳?(arc是為了解決什么問(wèn)題誕生的?)現(xiàn)在有不少程序員是直接從arc上手的嘱函,從沒(méi)接觸過(guò)mrc甘畅,對(duì)arc的理解僅僅停留在apple幫助管理內(nèi)存的層面。這個(gè)問(wèn)題真正想了解的是對(duì)內(nèi)存管理的理解,retain release雖然不用寫(xiě)了疏唾,但arc下還是會(huì)有內(nèi)存泄漏野指針crash的bug存在蓄氧。如果能從retain count這種內(nèi)存管理策略的角度去闡述arc誕生的意義就算答對(duì)了。如果還能扯下其他類(lèi)型的策略槐脏,比如java里的mark and sweep喉童,那就加分點(diǎn)贊。
請(qǐng)解釋以下keywords的區(qū)別: assign vs weak, __block vs __weak這道題屬于基礎(chǔ)語(yǔ)法題顿天,可以網(wǎng)上搜到答案堂氯。不過(guò)真有不少同學(xué)不知道weak在對(duì)象釋放后會(huì)置為nil。__block關(guān)鍵字的理解稍微難點(diǎn)牌废,因?yàn)樵赼rc和mrc下含義(對(duì)retain count的影響)完全不同咽白。理解了這幾個(gè)關(guān)鍵字就能應(yīng)付使用block時(shí)引入retain cycle的風(fēng)險(xiǎn)了。這題還在內(nèi)存管理的范疇之內(nèi)鸟缕。
使用atomic一定是線程安全的嗎晶框?看這題的問(wèn)法不用想答案肯定是NO。有些人說(shuō)不出所以然懂从,有些人知道通過(guò)property的方式使用才能保證安全授段,還有人知道這個(gè)用來(lái)做多線程安全會(huì)有性能損耗,更有出色的候選人能談atomic,synchronized,NSLock,pthread mutex,OSSpinLock的差別莫绣。好奇寶寶點(diǎn)我畴蒲。
描述一個(gè)你遇到過(guò)的retain cycle例子。(別撒謊对室,你肯定遇到過(guò))說(shuō)沒(méi)遇到過(guò)的我很難相信你有過(guò)成熟項(xiàng)目的經(jīng)歷模燥。這題答不出了會(huì)扣很多很多分。用過(guò)block掩宜,寫(xiě)過(guò)delegate的肯定都踩過(guò)坑蔫骂。
+(void)load; +(void)initialize;有什么用處牺汤?這題屬于runtime范疇辽旋,我遇到過(guò)能說(shuō)出對(duì)runtime的理解卻不知道這兩個(gè)方法的候選人。所以答不出來(lái)也沒(méi)關(guān)系檐迟,這屬于細(xì)節(jié)知識(shí)點(diǎn)补胚,是加分項(xiàng),能答出兩個(gè)message各在什么階段接收就可以了追迟。
為什么其他語(yǔ)言里叫函數(shù)調(diào)用溶其, objective c里則是給對(duì)象發(fā)消息(或者談下對(duì)runtime的理解)這題考查的是objective c這門(mén)語(yǔ)言的dynamic特性,需要對(duì)比c++這類(lèi)傳統(tǒng)靜態(tài)方法調(diào)用才能理解敦间。最好能說(shuō)出一個(gè)對(duì)象收到message之后的完整的流程是如何的瓶逃。對(duì)runtime有完整理解的候選人還能說(shuō)出oc的對(duì)象模型束铭。
什么是method swizzling?說(shuō)了解runtime但沒(méi)聽(tīng)過(guò)method swizzling是騙人的。這題很容易搜到答案厢绝。定位一些疑難雜癥bug契沫,hack老項(xiàng)目實(shí)現(xiàn),閱讀第三方源碼都有機(jī)會(huì)接觸到這個(gè)概念昔汉。
UIView和CALayer是啥關(guān)系?能答出UIView是CALayer的delegate就及格了懈万,能說(shuō)出UIView主要處理事件,CALayer負(fù)責(zé)繪制就更好挤庇,再聊下二者在使用過(guò)程中對(duì)動(dòng)畫(huà)流暢性影響的注意點(diǎn)就superb钞速。UI流暢性是個(gè)大話題,推薦看下這兩篇文章嫡秕。中餐渴语,西餐。
如何高性能的給UIImageView加個(gè)圓角昆咽?(不準(zhǔn)說(shuō)layer.cornerRadius!)這題討論的最多驾凶,還有說(shuō)美工切圖就搞定的。答主在項(xiàng)目里做過(guò)圓角頭像的處理掷酗,里面的坑還真不少调违。cornerRadius會(huì)導(dǎo)致offscreen drawing有性能問(wèn)題,美工切圖無(wú)法適用有背景圖的場(chǎng)景泻轰,即使加上shouldRasterize也有cache實(shí)效問(wèn)題技肩。正確的做法是切換到工作線程利用CoreGraphic API生成一個(gè)offscreen UIImage,再切換到main thread賦值給UIImageView浮声。這里還涉及到UIImageView復(fù)用虚婿,圓角頭像cache緩存(不能每次都去繪制),新舊頭像替換等等邏輯泳挥。還有其他的實(shí)現(xiàn)方式然痊,但思路離不開(kāi)工作線程與主線程切換。
使用drawRect有什么影響屉符?(這個(gè)可深可淺剧浸,你至少得用過(guò)。矗钟。)不少同學(xué)都用過(guò)drawRect或者看別人用過(guò)唆香,但不知道這個(gè)api存在的含義。這不僅僅是另一種做UI的方式吨艇。drawRect會(huì)利用CPU生成offscreen bitmap躬它,從而減輕GPU的繪制壓力,用這種方式最UI可以將動(dòng)畫(huà)流暢性?xún)?yōu)化到極致秸应,但缺點(diǎn)是繪制api復(fù)雜虑凛,offscreen cache增加內(nèi)存開(kāi)銷(xiāo)。UI動(dòng)畫(huà)流暢性的優(yōu)化主要平衡CPU和GPU的工作壓力软啼。推薦一篇文章:西餐
ASIHttpRequest或者SDWebImage里面給UIImageView加載圖片的邏輯是什么樣的桑谍?(把UIImageView放到UITableViewCell里面問(wèn)更贊) 很多同學(xué)沒(méi)有讀源碼的習(xí)慣,別人的輪子拿來(lái)只是用用卻不知道真正的營(yíng)養(yǎng)都在源代碼里面祸挪。這兩個(gè)經(jīng)典的framework代碼并不復(fù)雜锣披,很值得一讀。能對(duì)一個(gè)UIImageView怎么通過(guò)url展示一張圖片有完整的理解贿条。涉及到的知識(shí)點(diǎn)也非常多雹仿,UITableViewCell的復(fù)用,memory cache, disk cache, 多線程切換整以,甚至http協(xié)議本身都需要有一定的涉及胧辽。
麻煩你設(shè)計(jì)個(gè)簡(jiǎn)單的圖片內(nèi)存緩存器(移除策略是一定要說(shuō)的)內(nèi)存緩存是個(gè)通用話題,每個(gè)平臺(tái)都會(huì)涉及到公黑。cache算法會(huì)影響到整個(gè)app的表現(xiàn)邑商。候選人最好能談下自己都了解哪些cache策略及各自的特點(diǎn)。常見(jiàn)的有FIFO,LRU,LRU-2,2Q等等凡蚜。由于NSCache的緩存策略不透明人断,一些app開(kāi)發(fā)者會(huì)選擇自己做一套cache機(jī)制,其實(shí)并不難朝蜘。
講講你用Instrument優(yōu)化動(dòng)畫(huà)性能的經(jīng)歷吧(別問(wèn)我什么是Instrument)Apple的instrument為開(kāi)發(fā)者提供了各種template去優(yōu)化app性能和定位問(wèn)題恶迈。很多公司都在趕feature,并沒(méi)有充足的時(shí)間來(lái)做優(yōu)化谱醇,導(dǎo)致不少開(kāi)發(fā)者對(duì)instrument不怎么熟悉暇仲。但這里面其實(shí)涵蓋了非常完整的計(jì)算機(jī)基礎(chǔ)理論知識(shí)體系,memory枣抱,disk熔吗,network,thread佳晶,cpu桅狠,gpu等等,順藤摸瓜去學(xué)習(xí)轿秧,是一筆巨大的知識(shí)財(cái)富中跌。動(dòng)畫(huà)性能只是其中一個(gè)template,重點(diǎn)還是理解上面問(wèn)題當(dāng)中CPU GPU如何配合工作的知識(shí)菇篡。
loadView是干嘛用的漩符?不要就簡(jiǎn)單的告訴我沒(méi)用過(guò),至少問(wèn)下我有什么用驱还。嗜暴。這里是apple給開(kāi)發(fā)者自己設(shè)置custom view的位置凸克。說(shuō)UI熟悉的一定要知道。
viewWillLayoutSubView你總是知道的闷沥。萎战。controller layout觸發(fā)的時(shí)候,開(kāi)發(fā)者有機(jī)會(huì)去重新layout自己的各個(gè)subview舆逃。說(shuō)UI熟悉的一定要知道蚂维。
GCD里面有哪幾種Queue?你自己建立過(guò)串行queue嗎路狮?背后的線程模型是什么樣的虫啥?兩種queue,串行和并行奄妨。main queue是串行涂籽,global queue是并行。有些開(kāi)發(fā)者為了在工作線程串行的處理任務(wù)會(huì)自己建立一個(gè)serial queue展蒂。背后是蘋(píng)果維護(hù)的線程池又活,各種queue要用線程都是這個(gè)池子里取的。GCD大家都用過(guò)锰悼,但很多關(guān)鍵的概念不少人都理解的模凌兩可柳骄。串行,并行箕般,同步耐薯,異步是GCD的核心概念。
用過(guò)coredata或者sqlite嗎丝里?讀寫(xiě)是分線程的嗎曲初?遇到過(guò)死鎖沒(méi)?咋解決的杯聚?沒(méi)用過(guò)sqlite是說(shuō)不過(guò)去的臼婆。用過(guò)CoreData的肯定有很多血淚史要說(shuō)。多謝線程模型你肯定做過(guò)比較選擇幌绍。死鎖是啥肯定也是要知道的颁褂,沒(méi)遇到過(guò)至少能舉個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明。單個(gè)線程可以死鎖(main thread里dispatch_sync到main queue)傀广,多個(gè)線程直接也可以死鎖(A颁独,B線程互相持有對(duì)方需要的資源且互相等待)。
http的post和get啥區(qū)別伪冰?(區(qū)別挺多的誓酒,麻煩多說(shuō)點(diǎn))這個(gè)可以說(shuō)很多。不希望聽(tīng)到的答案有
兩個(gè)差不多贮聂,隨便用一個(gè)靠柑。
post比get安全(其實(shí)兩個(gè)都不安全)
能說(shuō)下兩個(gè)http格式有什么不同寨辩,各自應(yīng)用的場(chǎng)景就合格了。更多可以閱讀下這個(gè)答案歼冰。
我知道你大學(xué)畢業(yè)過(guò)后就沒(méi)接觸過(guò)算法數(shù)據(jù)結(jié)構(gòu)了捣染,但是請(qǐng)你一定告訴我什么是Binary search tree? search的時(shí)間復(fù)雜度是多少?我很想知道停巷!很多人都很排斥數(shù)據(jù)結(jié)構(gòu)和算法題,我個(gè)人意見(jiàn)是復(fù)雜的可以不知道榕栏,基礎(chǔ)的一定要了解畔勤。時(shí)間復(fù)雜度是什么得知道,list扒磁,queue庆揪,stack,table妨托,tree這些都要明白是啥缸榛。連hash表的概念都不知道怎么能保證在寫(xiě)代碼的時(shí)候注意性能呢。
轉(zhuǎn)載:http://mrpeak.cn/ios/2016/01/07/push