1.如何準備代碼考查
很多面試的能力都不是突擊可以獲得的。項目經(jīng)歷不是,代碼能力也不是。如果說項目經(jīng)歷的獲取還需要環(huán)境支持的話,代碼能力的提高基本只需要自己投入就可以了。
在網(wǎng)上有很多練習編程的網(wǎng)站,特別是像面向求職者的 LeetCode 一類的網(wǎng)站,提供了各大公司的代碼考察題目,并且大部分題目還有標準解答和示意代碼。你可以在上面一遍一遍地練習,以提高自己的代碼轉(zhuǎn)換能力和邏輯思維能力。我建議大家至少做 100 道 LeetCode 里面 Facebook、Apple 這些大公司的代碼題目,很多題目都設(shè)計得非常好,既是很好的練習題,又可能在實際工作中用到。Google 的面試題通常還要更難一些,對自己要求更高的同學也可以挑戰(zhàn)一下。
除此之外,在紙或白板上寫代碼的能力也需要好好練習。紙上寫代碼麻煩的地方在于不方便及時涂改,所以需要思考得比較清楚再動手寫。準備一些 A4 紙,然后拿 LeetCode 題目多練習幾次,慢慢就會有感覺。
我最后總結(jié)出來在紙上寫代碼的要訣是:一定要先把整體邏輯框架梳理清楚,然后再填充細節(jié)。所以你可以用文字、流程圖或任何你喜歡的方式先把代碼整體邏輯描述在紙上,然后檢查沒有邊界問題后,再在紙上細化成具體的代碼。
2.寫代碼之外的溝通
即使是做代碼題目,必要的溝通交流也是必須的。我見過很多候選人聽完題目就埋頭寫代碼,完全不和面試官交流,這其實是非常錯誤得做法。如果寫代碼完全不需要交流,那么為什么不當做筆試題,而要耽誤面試官的時間坐在你旁邊?難道就只是為了監(jiān)督嗎?
其實,解決一道代碼題目的思考過程是非常有價值的,面試官問你一道代碼題目,其實是希望和你一起溝通交流,了解你的思路,幫助你找到最好的解法,最后才是把代碼完成的事情。
所以,當面試官給你一道題目,你首先要做的是和面試官足夠地交流。你可以首先確保你完整地理解了題意,這可以通過詢問題目的一些細節(jié)來達到,比如問輸入的數(shù)據(jù)范圍,輸出的具體要求,一些異常的情況是否要考慮等等。
等你完全理解題意之后,下一步就是將你的想法說出來。你完全不必擔心沒有一下子說出最好、最完美的解法,大部分好的代碼題目都可以一題多解,你可以先說一個最簡單直接的方法,然后說出這種方法的時間復雜度、空間復雜度。一般面試官都會問你有沒有更好的做法,或者你也可以直接說想思考有沒有更好的做法。接著你可以試試看能不能想出一些辦法,即使一些辦法沒有完全想清楚所有細節(jié),也可以說出來。好的面試官如果發(fā)現(xiàn)你的方法完全方向不對,還可以及時干預。
你如果在思路上有卡住,你甚至可以請求面試官給你一些 “提示”。雖然這可能使得你面試表現(xiàn)稍微減分,但是比起完全沒有寫出代碼來說也要好很多。
除了寫代碼之前和面試官交流、確認解法,寫完代碼之后,你也需要和面試官討論你的代碼細節(jié)問題。通常代碼中多多少少會出現(xiàn)一些問題,面試官會給你一些引導,幫助你發(fā)現(xiàn)并且修改有問題的代碼。
3.如何準備系統(tǒng)設(shè)計
如果你是一個應屆生,通??疾榈南到y(tǒng)設(shè)計題都不太難,你只需要有一些系統(tǒng)設(shè)計的基礎(chǔ),都不至于完全答不上來。在準備資料上,可以看看《設(shè)計模式》相關(guān)的書。如果有機會實習,可以多嘗試一些不同的職位,如果你同時嘗試過客戶端和服務(wù)器端開發(fā),在系統(tǒng)設(shè)計上就可以更加綜合考慮設(shè)計方案在多端的實現(xiàn)難度,以便做出權(quán)衡。
另外,你可以通過學習分析一些開源項目的代碼,來學習架構(gòu)設(shè)計。在網(wǎng)上,你通常也可以搜索到一些常見的系統(tǒng)設(shè)計題目,在本書的上一節(jié)中,我也提供了好多系統(tǒng)設(shè)計題。把這些系統(tǒng)設(shè)計題目仔細研究,嘗試自己實現(xiàn)一下,通過實踐并且和同學討論,相信你也會有不錯的成長。
雖然沒有標準的答案,但是系統(tǒng)設(shè)計還是有一些解題套路,下面我就給大家介紹一下。
首先系統(tǒng)設(shè)計題都非常考查一個人知識的全面性。所以大家應該平時多了解一些 iOS 之外的技術(shù),比如適度了解一下 Android 端、Web 端以及服務(wù)器端的各種技術(shù)方案背后的原理。你可以不寫別的平臺的代碼,但是一定要理解它們在技術(shù)上能做到什么,不能做到什么。你也不必過于擔心,面試官在考查的時候,還是會重點考查 iOS 相關(guān)的部分。
在知識足夠?qū)挿旱那闆r下,你需要首先和面試官明確問題的各種細節(jié),比如假如題目是“設(shè)計一個類似微博的信息流應用”,你需要了解清楚這個信息流應用更多的技術(shù)要求,比如:
信息流的內(nèi)容是否包括圖片,文字,語音。
平均每個用戶每天有多少的信息流更新量。
是否需要做圖文混排。
是否需要做圖片的緩存,歷史信息的緩存。
斷網(wǎng)情況下是否需要顯示離線內(nèi)容。
發(fā)送失敗情況下是否需要暫存內(nèi)容。
系統(tǒng)對核心功能的性能(例如發(fā)送,刷新)的要求是多少。
有一些技術(shù)細節(jié)可能是面試官想考查的,你問的時候他就會要求多一些;有一些技術(shù)方案明顯很復雜的,你提出來,他即使不考查你,也會覺得你的考慮是足夠周全的。
在確定技術(shù)細節(jié)要求后,你就可以開始講你的系統(tǒng)架構(gòu)設(shè)計了,這個時候講的要訣是先框架,再細節(jié)。你需要先把各個模塊的層次畫出來,比如剛剛那道題目,你先介紹一下整體 App 是怎么和服務(wù)器通訊的,服務(wù)器端的信息流大概是如何存儲的,然后你就需要詳細介紹 App 的部分。
在介紹 App 的框架時,先畫出 Model 層,Controller 層,View 層。然后再進一步細化,比如把 Model 層細化到本地存儲,圖片緩存,網(wǎng)絡(luò)請求等模塊。View 層如何處理圖文混排,Controller 層如何與其它層通訊。
當框架介紹得差不多的時候,你需要把后續(xù)的選擇交給面試官。面試官可能會選其中某一個模塊,讓你做更細一步的設(shè)計。比如讓你設(shè)計網(wǎng)絡(luò)通訊的 RESTful 接口,細化緩存相關(guān)的 API 名字。面試官甚至可能選一兩個具體的函數(shù),讓你寫寫。面試官也可能進一步挑戰(zhàn)你的一些設(shè)計細節(jié),這個過程中,你可能需要修正自己的設(shè)計,也可能需要解釋你的設(shè)計。

5.復盤
復盤是一個人持續(xù)提高和進步的源泉。也許你覺得你的面試表現(xiàn)很好,但是為什么面試沒有通過呢?當你被拒的時候,與其抱怨面試官或者面試流程不公正,倒不如靜下心來想一想,看看是不是自己忽視了某些細節(jié)或者關(guān)鍵點。如下圖所示:

除了復盤算法和系統(tǒng)設(shè)計題,也需要復盤一下自己整體的面試流程是否表現(xiàn)正常。例如:
(1)我的自我介紹是否流利?
(2)我的項目溝通是否介紹清楚了?
(3)面試官有沒有完全理解我介紹的項目挑戰(zhàn)?
(4)我的時間控制是否到位?
(5)我有沒有遲到,中途接電話,或者任何被認為不禮貌的行為?
(6)我做得不好的地方,有沒有短期可以改善的?
(7)我做得不好的地方,短期不能改善的,我能不能用別的方式適當彌補?比如面試中強調(diào)自己的強項。
每次面試后,做一個小結(jié),可以使得自己每次都會有一點點進步,幾十場面試下來,相信大家都會有不小的成長。