隨著各大公司秋招的即將開始,很多小伙伴都行動起來了,我有幸能夠在春招時加入百度,并在此和大家分享自己的經(jīng)驗心得,希望能幫助每位讀者找到自己心儀的工作。
作為 iOS 開發(fā)者,雖然 Swift 已經(jīng)發(fā)布了快兩年,但是大公司轉(zhuǎn)向 Swift 的動作還不明顯,所以 -C 幾乎是必備項,Swift 都不一定能算是加分項。iOS 方面的知識也必不可少,雖然招聘信息上寫著如果基礎(chǔ)扎實,零 iOS 基礎(chǔ)也可以,但是現(xiàn)實往往是比較殘酷的。
我的面試經(jīng)歷
分享一下我的面試經(jīng)歷,題目如下,破折線后面是簡單的解決思路。
百度
一面:約 1.5 小時
首先是四個算法題:
不用臨時變量怎么實現(xiàn) swap(a, b)——用加法或者異或都可以
二維有序數(shù)組查找數(shù)字——劍指 offer 第 3題
億級日志中,查找登陸次數(shù)最多的十個用戶——(不確定對不對,我的思路是)先用哈希表保存登陸次數(shù)和ID,然后用紅黑樹保存最大的十個數(shù)。劍指 offer 第 30題
簡述排序算法——快排,函數(shù)的原理,堆排(不穩(wěn)定),歸并排序,基數(shù)排序。
然后有一個智力題,沒完整的答出來,好像影響不是很大。
最后是 iOS 相關(guān),面試官問的很開放,都是談談自己的理解:
說說你對 OC 中l(wèi)oad方法和方法的異同。——主要說一下執(zhí)行時間,各自用途,沒實現(xiàn)子類的方法會不會調(diào)用父類的?
說說你對 block 的理解。—— 三種 block,棧上的自動復制到堆上,block 的屬性修飾符是 copy,循環(huán)引用的原理和解決方案。
說說你對 的理解。——主要是方法調(diào)用時如何查找緩存,如何找到方法,找不到方法時怎么轉(zhuǎn)發(fā),對象的內(nèi)存布局。
說說你對 MVC 和 MVVM 的理解。—— MVC 的 C 太臃腫,可以和 V 合并,變成 MVVM 中的 V,而 VM 用來將 M 轉(zhuǎn)化成 V 能用的數(shù)據(jù)。
說說 的調(diào)優(yōu)。——一方面是通過 檢查影響性能的地方,另一方面是估算高度并在 空閑時緩存。
談談你對 ARC 的理解。ARC 是編譯器完成的,依靠引用計數(shù),談談幾個屬性修飾符的內(nèi)存管理策略,什么情況下會內(nèi)存泄露。
一面的問題非常基礎(chǔ),主要是算法和 -C,因為準備比較充分,基本上答出來 80% 吧。大約一周后突然二面。
二面:約 0.5 小時
二面比較突然,先是簡單的自我介紹,然后問了三個問題:
野指針是什么,iOS 開發(fā)中什么情況下會有野指針?——野指針是不為 nil,但是指向已經(jīng)被釋放的內(nèi)存的指針,不知道什么時候會有,如果有知道的讀者還望提醒。
介紹 block。—— (接第一問) 我讓面試官提示我一下什么時候會有野指針,他說用 block 時,我表示還是不知道,只知道 block 會有循環(huán)引用。于是就扯回了一面的問題。
說說你是怎么優(yōu)化 的。——還是一面的問題。
三面:北京 ,約 2.5 小時
首先是給一個小時,手寫算法:
給一個字符串,如何判斷它是否是合法的 IP 地址,比如 “192.168.1.1” 就是合法的。
說說大數(shù)相加的思路,動手寫代碼實現(xiàn)。
沒能寫完,主要是大數(shù)相加的時候需要考慮負數(shù),耽擱了一點時間。
然后讓我簡述 TCP 建立和關(guān)閉連接時,握手的過程。還問了前者為什么是三次,后者需要四次?
接下來是設(shè)計了一個實際場景,為了簡化問題,我們考慮這個問題:假設(shè)有 10W 條電話號碼,如何通過輸入電話號碼的某一段內(nèi)容,快速搜索出來。比如輸入234,以下兩個號碼都會顯示在搜索結(jié)果中:
0
0
其實最簡單的解決方案是遍歷所有字符串,然后用 KMP 算法。但是這樣的問題是需要遍歷 10W 個元素,效率比較低。我想到的是辦法是使用索引。建立 100 個索引(00 到 99),比如輸入234時只需要在索引23對應的區(qū)域查找即可,可以加快 100 倍速度。但是缺點是插入數(shù)據(jù)時ios 判斷字符串是否為空,需要更新多個索引,數(shù)據(jù)量會是原來的 10 倍。
目前還沒有想到好的解決方案。有大神提醒說用字典樹,有空研究一番。
最后問了 OC 的數(shù)組中,添加nil對象會有什么問題。當時沒答上來,現(xiàn)在想想很不應該,因為數(shù)組是以nil結(jié)尾的,如果添加了nil,后續(xù)就不能添加對象了。
網(wǎng)易
筆試:
主要是計算機方面的大雜燴,涉及操作系統(tǒng),網(wǎng)絡,移動開發(fā),算法等。難度不大,目測是為了淘汰渾水摸魚的人,就不列出題目了,算法有三題,直接在線寫(木有 IDE 表示很憂傷):
很長一道題,讀了很久才讀懂,目測是 DFS,但是最后沒時間了,寫了個思路。
把 “” 這樣的字符串改成 “com/baidu//www”。——老題目了,劍指 offer 的,兩次逆序排列即可。
求數(shù)組中和為某個值的所有子數(shù)組,比如數(shù)組是[5,5,10,2,3]一共有四個子數(shù)組的和是 15,比如[5,10],[5,10],[10,2,3],[5,5,2,3]。這個就是簡單的遞歸了,分兩種情況,當前位置的數(shù)字在子數(shù)組中,以及不在子數(shù)組中。
一面:
全部是 iOS 題,可能是覺得算法已經(jīng)面過了:
介紹 block。——我提到棧上的 block 在 ARC 下會自動復制到堆上,面試官問我從 iOS 4 還是 5 開始支持這一特性,表示不知道,我又不是學 OC 歷史的,后來想想可能是公司內(nèi)部老項目有這個坑。
ARC 會對代碼做什么優(yōu)化?——比如 *s2 = s1; s2 = nil這樣的語句,可能就不會有和方法了。
介紹一下 MVVM 和 RAC。——可能是我簡歷的某個角落寫了用過 RAC,被挖出來了,大概談了一下,結(jié)果面試官問我數(shù)據(jù)的雙向綁定怎么做,bind函數(shù)了解過么,果斷說已經(jīng)忘了:joy::joy::joy:
介紹自己用過哪些開源庫。—— 和 ,,,,,
如果讓你寫,你能實現(xiàn)么?——當然不能,不然還要實習?
讀過某個庫的源碼么?——扯了一點 ,后來被告知這個庫用了 來保證滑動是加載數(shù)據(jù)的流暢性,自己看了源碼后表示沒有發(fā)現(xiàn),唯一用到 地方是保證后臺線程一直跑,也有可能是我理解錯了,如果錯誤歡迎指正。
下載了圖片后為什么要解碼?——當時蒙住了,面試官很 nice 的解釋了一下,說是要把 png 文件建立一個什么內(nèi)存映射,目前還不太懂,有空研究一下。
本來以為面的這么差肯定是掛了,沒想到還是過了一面。過了不到一個小時ios 判斷字符串是否為空,HR 電話打過來,約了兩天后二面。
二面:
純數(shù)學和算法:
下面這段代碼的輸出結(jié)果是:
c
int main() {
? ?int a[5]={1,2,3,4,5};
? ?int *ptr=(int *)(&a+1);

? ?printf(“%d,%d”,*(a+1),*(ptr-1));
}
答案是 2 和 5。a是指向數(shù)組開頭元素的指針,a + 1就是指向下一個元素的指針,所以星號求值以后是 2。&a相當于是數(shù)組的指針,&a + 1是數(shù)組后面一個數(shù)組的指針,然后轉(zhuǎn)換成int *類型是 5 這個數(shù)字后面的一個數(shù)字的指針。再減一就是指向 5 的指針,所以星號求值以后是 5。
某個地方天氣有如下規(guī)律:如果第一天和第二天都不下雨,則第三天下雨的概率為30%;如果第一天和第二天中有任 意一天下雨,則第三天下雨的概率為60%。問如果周一周二都沒下雨,那么周四下雨的概率為_。簡單的概率題,答案是:30% * 60% + 70% * 30% = 39%
某癡迷撲克的小團體喜歡用來計數(shù),A后面是22,23,…,2A,32,…,AA,222,… 依次類推。請用C/C++或Java寫個程序,將用字符串表示這種計數(shù)法轉(zhuǎn)換成字符串表示的10進制整數(shù)。其中,該計數(shù)法的2就對應于十進制的2,之后依 次遞增。C/C++函數(shù)接口: char* (char *)我的解決思路是進制轉(zhuǎn)換,類似于 16 進制轉(zhuǎn)換 10 進制這種,最后再把數(shù)字轉(zhuǎn)成char *類型。
然后好像沒結(jié)果了,可能是編程實在太渣了?
其他我知道的面試題
阿里一面:
MVC具有什么樣的優(yōu)勢,各個模塊之間怎么通信,比如點擊 后 怎么通知 Model?
兩個無限長度鏈表(也就是可能有環(huán)) 判斷有沒有交點
的相關(guān)優(yōu)化
KVO、、各自的優(yōu)缺點,效率還有使用場景
如何手動通知KVO
-C 中的copy方法
中,SEL和IMP的區(qū)別
的使用場景和原理
的實現(xiàn)原理和數(shù)據(jù)結(jié)構(gòu),什么時候會用到
block為什么會有循環(huán)引用
使用GCD如何實現(xiàn)這個需求:A、B、C 三個任務并發(fā),完成后執(zhí)行任務 D。
和GCD的區(qū)別
的使用,如何處理多線程問題
如何設(shè)計圖片緩存?
有沒有自己設(shè)計過網(wǎng)絡控件?
阿里二面:
怎么判斷某個cell是否顯示在屏幕上
進程和線程的區(qū)別
TCP與UDP區(qū)別
TCP流量控制
數(shù)組和鏈表的區(qū)別
生命周期
如果頁面 A 跳轉(zhuǎn)到 頁面 B,A 的方法和 B 的方法哪個先調(diào)用?
block循環(huán)引用問題
ARC的本質(zhì)
的基本概念,它是怎么休眠的?
什么時候釋放,在什么場景下使用?
如何找到字符串中第一個不重復的字符
哈希表如何處理沖突
面試收獲
1. 算法題怎么答
面試官可能會問到你聞所未聞的算法,這時候你不應該自己瞎想,而是先和面試官把問題討論清楚。要知道,通過溝通弄明白復雜的問題也是一種能力, 在和面試官交流的過程中,不僅僅可以搞清楚題目真正的意思是什么,還可以展現(xiàn)自己良好的交流溝通能力。所以千萬不要因為緊張或者害羞而浪費這次大好的機會。
有些題目似曾相識,但是暫時沒有思路。這時候不妨告訴面試官,給我一些時間思考這個題。然后不要急,不要慌,就當他不存在,拿出紙和筆慢慢算 (這充分說明了面試戴耳機的重要性)。你一定要堅定一個信念:“任何一道稍微有難度的算法題,除非做過,否則一定是需要時間想的”。所以,合理的安排思考 時間吧。如果十幾分鐘都想不出來,可以直接放棄。
有時候面試官會要求在線編程,相信我,他不會無聊到盯著你的代碼看的,面試官一般都很忙,他也有自己的工作要完成,所以你就當是用自己的 IDE 就好。在線編程往往是一個中等難度的問題,所以不要自己嚇唬自己。同時要注意代碼格式的規(guī)范,適當?shù)淖⑨專崆熬帉懞脺y試用例等,即使沒有解決問題,也至 少要把自己良好的編程習慣展示給面試官。
2. 遇到不會的問題怎么處理
這個問題有可能是面試官故意說得含糊不清,考察你的交流能力,也有可能是無意的,或者是你的理解方式出現(xiàn)了偏差。不管是以上哪種問題,你都應該先和面試官交流,直到你搞懂了面試官要問你什么,而不是按照自己的理解說了一堆無用的東西。
舉個例子,面試官可能會問了一道算法題:“如何判斷兩個無限長度的鏈表是否有交點?”。對于“無限長度”可以有不同的理解,如果真的是有無窮多 個節(jié)點,那顯然這個問題是無法解決的。但如果鏈表僅僅是有環(huán),那么還是可以解決的。如果面試官的本意是鏈表有環(huán),但你錯誤的理解成了無窮多個節(jié)點,那么必 然會導致無法回答這個問題。而且這并非能力不足,而是屬于交流溝通方面的失誤,這也正是我想分享的“技巧”。
還有一些問題,雖然你沒有接觸過,但是由于對類似的問題或者情況有過思考,所以可以合理假設(shè)。比如面試官問 “ARC 會對代碼做什么樣的優(yōu)化?”。我們知道 ARC 的本質(zhì)就是在合適的地方插入和等方法,那么就應該從這個角度出發(fā)去思考問題。
顯然分別執(zhí)行和操作是沒有必要的,那么就可以構(gòu)造出相應的例子:
NSString *s1 = @"hello"; ?
NSString *s2 = s1; ?
NSString *s2 = nil; ?
由于這種問題我們沒有真正實踐過,所以可以委婉的告訴面試官:“根據(jù)我的推理,可能會有……”。
3. 遇到真的不會的問題怎么處理
遇到不會的問題果斷承認啊。如果是基本問題,比如問你哈希表怎么實現(xiàn),你說不會,那么這次面試可能就懸了。如果是有一定難度的問題,那么你承認不會,也是一種明智之舉,畢竟人無完人,一個問題不會并不能全盤否定一個人的能力。
但是比較糟糕的一種情況是,面試者由于過分緊張,擔心答不上面試官的問題會有嚴重后果,所以嘗試著去敷衍面試官。比如:“我猜是 xxx 吧”,“我覺得可能是 ……”,更有甚者直接裝逼:“這個我試過,不就是 xxx 么”。要知道,此時的你,由于緊張,在心態(tài)上已經(jīng)輸給了面試官,更何況面試官問你的問題一定是他有把握的,你覺得這時候你負隅頑抗會有幾成勝算呢?
所以,面試官問我“堆排序”的細節(jié)時,由于我當時忘了堆排序是怎么實現(xiàn)的,所以我直接告訴他我記不清了。另一個主動認輸?shù)睦邮敲嬖嚬賳栁?RAC 如何實現(xiàn)雙向綁定,我告訴他這個是我當時學習的時候?qū)戇^的 demo,因為不常用,已經(jīng)只記得一些簡單的概念了。
最后,還需要保持一個平穩(wěn)的心態(tài):“面試時盡力就好,遇到自己不會的問題也是正常情況”。如果面試者順利答對了所有問題,難免會讓面試官感到一絲尷尬,面試者也有可能會產(chǎn)生一些別的情緒。所以,我們要做的只是把自己的能力展示給面試官,做到不驕不躁。
4. 準備殺手锏
除了能夠回答上面試官的問題以外,我建議自己準備一兩個殺手锏級別的話題。所謂的殺手锏,至少具備以下幾個特征:
由于此類話題數(shù)量不多,所以準備一個或數(shù)個即可,面試時可以有意識的將面試官引導到這些話題上去,從而充分的展示自己。
5. 心態(tài)
通常情況下,面試結(jié)果都會在 1 – 3 天內(nèi)知道。有的面試官會當場告訴你通過了,有的公司面試結(jié)束后幾個小時就能出結(jié)果。
但有些時候,由于某些原因(我也不清楚。。。。可能是比較忙?),你遲遲無法獲知面試結(jié)果。這時候你可以選擇耐心等待,或者直接給 HR or 內(nèi)推者發(fā)送郵件。一般來說面試結(jié)束后三天還沒收到通知,你可以發(fā)送郵件詢問。