18年底Android面經分享(已獲頭條、順豐、OPPO等大廠offer)
前言
本人水平有限,此文針對於自認為技術實力對標阿里P6,百度T5或者以下的讀者,如果是大佬不小心點進來了,可以自行點x略過。文內並不會出現每一家公司的面試過程細節,主要目的在於幫助大家怎麼在像我一樣菜的情況下在這寒冬拿下offer或者說有複習準備方向。(文章純乾貨分享 請仔細閱讀 )
背景介紹
11月因公司團隊解散而離職,突聞網際網路最寒冬又雙叒叕來了,什麼小廠大量倒閉,大廠裁員或鎖HC,慌得一批,惶惶不安準備了一個多星期後,開始踏上面試求職之路,截止最終確定入職單位總計用了二十多天(期間有一半時間在做頸椎康復治療)。
求職開始於某個週日晚上十一點把簡歷公開到獵聘,第二天開始就被獵頭的電話打爆(對這個所謂寒冬有點疑惑),按先後順序面了xxx體育資訊(搞BC的)、xx者科技(技術方向不同,去了幾乎沒怎麼面就讓我回家了)、騰訊音樂(電話一面掛)、技威時代(智慧家居方向)、悅動圈(跑步運動,使用者量過億)、順豐科技、OPPO、百度(止步現場第三輪技術面)、頭條 ,加粗的是拿到offer的,最終入職了頭條。
個人簡介
本人985學校本科畢業,非科班出身,三年多Android開發經驗,半年iOS開發經驗,和一個JavaScript小遊戲開發經驗。技術水平,略低於百度T5的樣子(去百度面過,止步第四輪技術面)。一直在創業小廠工作,團隊總人數沒超過90人過,絕大多數時間處於獨立開發,也就是一個人負責一個APP,甚至同時負責多個APP。技術棧得益於產品汪頻頻更改的需求,還是積累了不少廣度,但是因為人少活多,精力有限,所以深度還是有所欠缺。
面試準備
簡歷攻略
首先從企業招聘端分析他們想看到什麼樣的簡歷,一般看簡歷的有三種人,獵頭、HR、技術負責人。獵頭和HR關注的點比較近似,放一起說,這兩者一般比較關注工作經歷、專案經驗、掌握的技能點 是否和用人單位JD匹配,對於工作年限低的,比如三五年以下的,還會關注學歷,尤其是大廠,比如本科是很多廠的硬性要求,因為HR看簡歷的時間有限(我猜的,大廠投簡歷的人那麼多,肯定看不過來啊),HR還會關注你在過往的經歷中的產出成績,能量化的最好。對於技術負責人,主要關注的就是你所熟悉的技術棧,和專案經驗 了,也許會因人而異,這個可以換位思考,如果你想找一個隊友,你期待你的隊友是怎樣的一個人。
我對簡歷的理解是,對自己的基本情況做總結形成你的人設,目的是讓用人單位對你感興趣,獲得面試邀約。 簡歷格式用PDF,兩頁最好,如果你覺得你足夠屌,可以一頁。注意排版要整潔,自我認知要客觀,別什麼精通xxx張口就來,除非你是真的精通,已經完全不怕被面試官問倒的程度,反正我一個精通沒寫。對於什麼教育程度、自我評價、專業技能點、工作專案經歷之類的用什麼順序寫之類的,我覺得沒有一個固定的標準,我的建議就是以突出自身亮點、優勢,揚長避短為原則的優先順序排序。比如你是985的學校畢業的,但是工作履歷不出彩,可以把學校放前面,我因為專業不是計算機類的,為了防止被HR刷掉,我只寫了xx大學,本科,事實上一般技術面試官也不是那麼看重專業出身的,就我經歷的幾個廠面試而言,我在自我介紹時主動說明了我的專業出身,面試官一般也會表示理解。那如果,學歷不夠出彩,但是之前公司背景屌或者說做過的專案比較知名比較屌,例如使用者量、日活很多之類的,那麼就可以把專案經歷寫在比較靠前醒目的位置。如果自己有寫高質量部落格的好習慣,或者在GayHub上有star比較多的開源專案,可以寫在自我評價裡,作為加分項,因為本人這兩者都沒有,所以我自己沒寫自我評價。
有朋友問我,技能點該怎麼寫,寫多少寫什麼比較合適?這個主要還是要看個人情況,我只能提幾點供參考的建議,把你的技術棧提取出亮點來,把你的亮點和理解的最深的有門檻的技術寫在靠前的位置 ,可以參考下你目標公司的jd需要什麼,你把你會的寫上去,不要寫太多,也不用寫那些一眼看上去沒啥技術含量的東西。可以適當的抽象一點,不用具體到點,舉個例子,熟悉常用的資料結構與演算法,肯定比熟練運用HashMap、ArrayList,知道快速排序原理要強。專案經歷怎麼寫?那還就是用著名的star法則,即情境(situation)、任務(task)、行動(action)、結果(result)。在什麼場景下,採用了什麼技術方案,取得了什麼成果,通俗來講,還是提取專案中的技術亮點和能體現你能力的地方。比如說,對應用啟動的做了xx優化,啟動速度快了30%,比競品厲害了多少。
還有很多人最關心的,面試題一般都問啥?很簡單,一部分從你的技能點 發起提問,一部分從你的專案經歷 發起提問,從這個角度來看,你是在給你自己設計考點,想要證明你的實力 ,那麼你就在這兩個地方多花點功夫,把你簡歷上的東西琢磨深一點,不被面試官問起來虐到就行。因為你能進入面試環節,就說明用人單位,通過簡歷對你的“畫像”基本能達到錄用需求了,你只需要在面試時表現出來,你簡歷上的不是吹牛B,而是真正的你,那麼不說能拿多少錢,至少offer是穩了。
投遞渠道
我自己在這過程中幾乎只用了獵聘、BOSS直聘,拉鉤也公開了簡歷,但拉鉤只約過一家,基本都是獵頭推薦和BOSS上的招聘方主動聯絡我。
高頻題集
下面的題是混合了我面過的公司中還記得起來的題目,每個型別都大致是按照出現頻率倒序排列的,有些題目其實只是一系列問題的引子,讓面試官和候選人開啟話題的。
基礎題
網路相關
Https的原理?
Tcp和Udp的區別?
Http的報文結構?cookie是用來幹嘛的?有哪些響應碼,分別都代表什麼意思?
有自己實現過Socket協議嗎?
多執行緒
Sleep()和wait()的區別?
Java有哪些執行緒池?他們的區別是什麼?執行緒池工作流程是怎樣的?執行緒池實現原理是怎樣的?Cache執行緒池有哪些弊端?
多執行緒間的通訊方式?
synchronize關鍵字怎麼用的?還知道哪些同步的方式?
Thread直接呼叫run方法會怎麼樣?start方法作用是什麼?
volatile關鍵字的作用是什麼?
怎麼安全停止一個執行緒任務?原理是什麼?執行緒池裡有類似機制嗎?
資料結構
HashMap和HashTable的區別?和 ConcurrentHashMap 區別?和LinkedHashMap區別?內部實現原理?
LRUCache的原理?
ArrayList和LinkedList區別?為什麼ArrayList不是執行緒安全的?
資料庫的索引用的什麼資料結構?
虛擬機器
垃圾回收機制?有哪些物件可以作為GC roots?
跟Art、Dalvik對比
Java記憶體模型?
類載入機制?雙親委託模型?
其它
用過哪些設計模式?DCL單例模式為什麼要兩次判空?Android裡原始碼或者你用過的開源庫都用到了什麼設計模式?
— final關鍵字的作用?
靜態內部類和內部類的區別?
值傳遞類問題
Kotlin為什麼能和Java混編
Android題
你有什麼亮點?專案中遇到過什麼難題或者坑,怎麼解決的?
做過哪些效能優化?是怎麼評測和具體優化的
Activity的冷啟動流程?AMS的作用?
怎麼分析記憶體洩漏?
View的事件分發機制?滑動衝突怎麼解決?
自定義View的原理和流程?
Handler原理?(一般會花式擴充套件)
有哪些多程序通訊方式?Binder機制?
Android的生命週期和啟動模式相關?
你專案中用到哪些開源庫?說說其實現原理?(OKhttp、RxJava、Retroit重點,如果有用到的話)
Android的打包流程?apk裡有哪些東西?簽名演算法的原理?
瞭解哪些外掛化技術?
LinearLayout的佈局流程?
對Mvp的理解?
Android怎麼做保活?
演算法
排序相關的(快排,分析不同排序區別,時間複雜度等)
字串、陣列相關的(滑動視窗、雙指標)
連結串列(反轉連結串列)
遞迴、斐波那契數列(爬樓梯)
動態規劃
文末有分享!
答題技巧
分析考點
技術面是一場技術面試官對候選人的綜合評估
先從面試官角度來分析,在面試過程中的對候選人一些考查點吧。知己知彼百戰不殆,面試過程中逆向思考 一波,有助於我們怎麼應對技術面。
候選人人設是否跟簡歷一致
主要看候選人是否坦誠真實 ,這個會直接影響能不能通過。候選人上的專案經驗和技能點應該儘可能與候選人匹配,比如說,候選人說做了XX專案,但是問起是怎麼實現的,卻答不上來,或者說熟悉xx技能點,卻只會呼叫常用的api,對其原始碼細節一點都不熟悉,那多半是不給過的。如果候選人要吹牛B,能拿出能圓上吹牛B的實力,也是可行的。比如說某某模組其實是你同事做的,但是你也完全理解了,可以應答如流,面試官是不會計較的。
技術的紮實程度和專案經驗匹配程度
考查包括對技術的理解和解決問題的能力,包含一些細節,運用的場景,實現的原理等等,目的是為了測試候選人技術水平上限。答得越清晰,越深入,對細節掌握越牢靠越好,不一定需要全部答出答完美才能拿到offer,但這些題回答的效果最能影響到offer能談多少錢。小廠偏重於技能、專案經驗匹配度,大廠偏重於基礎、原理。小公司,面試官通常希望候選人儘快上手,就希望候選人有類似競品或者功能開發經驗的候選人,所以也可以從這些方面做準備。大公司呢,可能會提出一些場景來考查候選人怎麼設計,這就要求候選人功底深厚,邏輯嚴謹了。上面的題集我沒寫答案,因為我覺得很多題本就沒有標準答案,也沒有必要背題的“標準答案”,優秀的回答,應該是形成自己的理解輸出的,說的有理有據就行。
候選人亮點、優勢
一般是作為候選人的加分項,或者是面試官為了更快的開啟話題,瞭解候選人的優勢,並測測候選人的優勢到底屌到什麼程度。這個問題回答好了,候選人甚至能翻盤。
溝通能力
在一線搬磚過的應該都懂,每天正正經經寫程式碼的時間通常不到一半,還得花不少時間跟產品撕,跟後臺撕,跟UI撕等等。所以溝通協調能力也是很重要的,候選人需要理解面試官出題意圖,表達要邏輯清晰 。最好是候選人能跟面試官建立起討論技術的氛圍。這方面很容易被多數候選人忽略,但其實挺重要的,面試官也許不能直接決定要你,但是一般可以直接決定淘汰你,候選人要不卑不亢,保持謙遜。候選人技術再屌,態度傲慢的話,也是很容易翻車的,但也不能太慫,顯得沒有技術底氣,所以最好是和諧的討論氛圍。
學習能力,自驅性
一般總監或負責人會比較關注這個。
答會的問題
要聽明白麵試官的出題意圖,也就是注意審題,不要答非所問,如果對面試官提出的問題不是很理解,及時進一步溝通,把問題問清楚,這也體現了溝通能力,畢竟平時工作時,也會接到一些不是很清晰的需求,自己主動獲取更清晰的需求也是程式設計師的優秀素質。
回答要儘量清晰準確,最好能答到問題的本質,展示出你對技術的更深層次的探索和挖掘。同時要注意面試官的反饋,這時候就要察言觀色了。
如果面試官聽的津津有味,並不斷追問加大問題難度,那麼恭喜你,你回答的很好!
如果面試官表現得有點不耐煩,那就精簡下回答,畢竟面試時間有限,去掉那些囉嗦的話和題目關聯不大的東西。
如果發現面試官問的題越來越簡單,越來越常規表面,那麼就得警惕下了 ,可能是你之前的回答太一般,讓面試官覺得你比較菜,所以就不給你出難題了,這種情況就算最後給到offer,多半價格也談上不去了,甚至還可能是為了給你個臺階下,然後讓你回家等遙遙無期的通知了,這種情況下就得把問題回答得更深入一些了,知道多少答多少,儘可能主動展現出自己的水平來。
答不會(不確信)的問題
首先要對這個問題有一定的思考分析,不要輕易的說不會,但也不能完全不會還瞎答,完全不會的還是要敢於說不會,坦誠也是必要的素質。
如何思考分析呢?以我的經驗來看,主要是從問題的關聯知識或者可替代方案的角度來思考。對問題不是很清楚瞭解的時候,嘗試從已知的相關聯的知識點來做出合理推測,比如從一些開源庫裡面借鑑思路,或者從Android原始碼裡面借鑑思路,但是這種情況就得跟面試官說清楚,你是推測的,還要說下為什麼要這麼推測,避免面試官誤以為你不懂裝懂。還有一種方式,就是你也提出一個可替代的能解決問題的方案。
例題分析
上面的題集有些問題看起來比較簡略,我這邊舉幾個典型例子做拓展,其它題目類似。
做過哪些效能優化?是怎麼評測和具體優化的?(具體問法可能有很多種,注意識別考點)
效能優化通常會設計到流暢度優化、啟動優化、apk瘦身優化、網路優化、耗電量優化,先給面試官丟擲幾個大的方向,一邊回答一邊觀察面試官反饋,通常面試官會從這幾個方面挑揀一兩個感興趣的讓你更進一步的講解,如果沒有,那你就對每個方面抓住最核心關鍵的部分簡要回答就行了。舉個讓你繼續談流暢度優化的問題,那你就得考慮到,怎麼評測出是否流暢的?用了什麼工具或者技巧?比如說用了GPU程式模式分析,用了騰訊GT外掛的SM指標,用了TraceView、Systrace、Hierarchy Viewer等等,很可能面試官還會問,卡頓的原理是什麼?哪些情況會導致卡頓?這時候你就得回答出FPS、垂直同步的原理了。接著你得說出你用了哪些技巧優化的,優化的成果怎麼樣?那數字肯定是最有說服力的,所以大家平時在優化前和優化後都得做好記錄。你回答優化技巧後,比如減少過度繪製啊、佈局優化啊,還有可能會追著問view的gone和ViewStub的區別,以及分別用在了什麼場景?原理是什麼?為什麼就能優化了?
反思點:
平時工作時,對技術細節、原理需要多關注,不光要知道怎麼用,還要知道背後的機制。
你專案中用到哪些開源庫?說說其實現原理?
回答開源庫相關的問題,要想回答的好,就得自己想清楚幾個問題,這幾個問題想清楚了,就可以隨便回答了。
這個庫是做什麼用的?
為什麼要在專案中使用這個庫?
這個庫都有哪些用法?對應什麼樣的使用場景?
這個庫的優缺點是什麼,跟同類型庫的比較?
這個庫的核心實現原理是什麼?如果讓你實現這個庫的某些核心功能,你會考慮怎麼去實現?
你從這個庫中學到什麼有價值的或者說可借鑑的設計思想?
演算法相關的
首先要想答好,還是得多理解資料結構,去LeetCode多刷題,多總結套路。我這塊兒也比較薄弱,只能說一些淺見。面試了這幾家,大概有一半考察了在白紙上手寫演算法題。而且很多題我也答的並不是很理想完美,但依然拿到了offer,所以我就說一些逆風應對技巧吧。舉個爬樓梯的例子。
假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
-
先審題,發現n是個未知數,題目也沒明說n的範圍,那麼這個時候你應該跟面試官確認一些這個n的範圍(這體現了你的溝通能動性和對需求的理解能力)
-
審完題後,發現還是一臉懵逼,不知道怎麼下手。這時先冷靜,別指望一步登天,解出最優解,考慮什麼時間複雜度啊什麼的,先解出答案再說。如果暴力解法都想不出來,那麼就先把題目縮小範圍,把n明確化,比如是3階的樓梯怎麼爬,這個時候一般可以畫圖來輔助自己尋找思路,直接腦子幹想不如影象直觀,很可能這麼一頓操作你就能發現規律,找到解題思路了,就算最後真的沒寫出具體演算法,將已知思路和阻塞自己的難點告知面試官,也可能會通過面試(這個過程體現了你解決未知難題的能力,程式設計師解決未知問題的能力是很重要的素質)。
-
你畫了圖之後發現這個是個樹形結構,憑藉刷題的套路總結,一般樹形結構的問題通常可以使用遞迴解決。而且巧得很,這還是一個斐波那契數列問題。這個時候你開始寫程式碼,用到了遞迴演算法,那就得注意遞迴的一些特性,比如說遞迴終止條件。在你寫完後,就可以跟面試官講解你的思路,和分析時間複雜度了。
-
還沒完,你學過的演算法課會告訴你,有些遞迴演算法,是可以進一步用動態規劃的方式優化的,你仔細觀察了一下,發現這個問題還可以用動態規劃的思想優化(位元組範兒:追求極致!)