三年Android經驗面經,靠這70道面試題,我斬獲了3個offer

  • 2020 年 3 月 27 日
  • 筆記

面經分享 作者:New_X

除非大廠,其他都問的差不多,問大部分也就著簡歷問,問了5年+的,也差不多就問這些…都是基礎吧,區分度應該主要在於項目經驗匹配度、職業素質、思維和運氣上。

1. 基礎

1. 自定義View的流程,requestLayout和invalidate的區別

–> ViewRoot的performTraversal切入measure、layout、draw(講完基礎,可提一提Surface的顯示原理)

2. Handler原理,Handler/Looper/MessageQueue關係

–> 消息循環需要創建一個Looper並利用ThreadLocal綁定到當前執行緒,內部創建了MessageQueue(是個單鏈表結構),當前Handler通過Looper取消息,可向不同的Handler發送消息,達到執行緒間通訊的目的(意識流的談到了消息屏障和Choreographer)

3. 子執行緒可以運行looper嗎?多次looper. prepare會不會有問題?怎麼進入循環的?looper.loop的關鍵點?消息延遲怎麼實現?延時的依據是什麼?為什麼?

–> 可參考HandlerThread以及基於HandlerThread實現的IntentService(可以往ThreadLocal切入,也可以往底層運行機制);注意延時是根據開機後的時間,但可能因為消息堆積造成不精確

4. 事件分發機制

–> 從Activity的dispatchTouchEvent切入,ViewGroup和View的onInterceptTouchEvent,onTouch優先於onClick

5. 繪製為什麼要二級緩衝?一級二級三級演變的原因?

–> 和消息循環的消息堆積類似,會滾雪球(雙緩衝技術是遊戲開發中的一個重要的技術,也是SurfaceView和View的一個主要區別,解決解決反覆局部刷屏帶來的閃爍)

6. Aspectj是運行時織入還是編譯時織入?

–> 我的理解是都有的

7. jvm編譯優化是什麼意思?

–> 運行和編譯時都有優化,以循環、反射、鎖的優化舉例(可以引申到方法內聯、棧上分配、標量替換,再多總結總結jvm相關知識形成一個閉環,是個很大的亮點)

8. 責任鏈在framework里的應用?

–> 事件分發、View繪製(更偏組合模式)

9. 啟動優化?非同步了為什麼還要優化?

–> 啟動器(注意任務的依賴關係,參考work-steaking機制可作為後期優化方向)+ 結合業務 + SP的不足 + Provider + 鎖檢查等(業務不複雜,其實收益不明顯,但是知道好過不知道,很多黑科技得慎用)

10. 插件化原理,換膚原理,熱修復原理,插件化怎麼實現把apk渲染成介面的?

–> 這幾個都是熱門話題,其實現實中負責相關開發的應該不多,但是可以提現技術追求,答出要點即可,細坑背也沒用的,你沒做過啊

11. mmkv一般不是做快取的嗎?為什麼和啟動優化有關係?

–> 啟動期間用到了SP,MMKV是可以無縫替代SP的,順便可以提提mmap原理,引申到binder,談談為什麼mmap可靠,mmap其實也不是銀彈

12. 說下udp、tcp和socket?

13. 說下http,以及http是基於tcp還是udp?為什麼?

14. tcp的可靠性怎麼保證的?–> 三次握手、奇偶校驗(Checksum)、超時重傳、滑動窗口(是根據tcp頭資訊的seq實現的,分成多部分數據)

15. 數組和鏈表的區別?

–> 可從實現,擴容,增刪改查角度切入

16. app點擊到啟動第一個activity的流程?

–> 可能畢竟3年,framework深點的問來問去就這一個,感覺白看這麼久了(雖然確實很難apply到實際工作上,但這個啟動流程知道其實能解決很多問題,而且可以牽帶問向其他問題,插件化、渲染、組件通訊、優化等)

17. 項目是MVVM還是MVP,怎麼實現的?有沒有引入LiveData?

18. 講一下優化相關的

–> 啟動優化、記憶體優化、埋點優化(業務向),這幾個印象深,如果不打斷,結合底層知識,半小時都不夠講(我一直懷疑我面試的時候說的太多,會不會太啰嗦了…)

19. 有沒有做過Socket和串口通訊,有用過藍牙嗎?

–> 這個真沒有,只有大學期末作業寫過藍牙聊天室

20. 有沒有用過kotlin?協程有了解嗎?

–> kotlin是入門水平,但是其實如果很看重這個,說明項目深度接入kt,各種擴展方法應該都是封裝的很好的,快速上手肯定沒問題

21. 用過Flutter?

–> Flutter學過好幾遍了,但是一直沒有商業項目來apply,真的想嘗試,但是精力有限,我還是先挖深度吧

22. 分層架構怎麼理解?

–> 這個需要結合組件化、模組化來講,也是個演進過程,先拆,再聚合為一層,拆的過程也是煎熬的(尤其是原先項目很耦合的情況,根本沒法多人協作進行,merge全是衝突,舉棋不定的需要temp層),可以結合OSI七層網路架構,Binder分層等經典實現升華

23. 反射的原理和應用?–> 反射是Java的一大特性,無處不在,ide程式碼提示就是,而且需要做些高級功能就需要結合反射,比如動態代理,升華一下可以講反射為什麼慢的原因,jvm對其的優化等

24. 螢幕適配使用哪個方案?有了解過AutoSize嗎?

–> sw限定符沒出問題,沒考慮其他方案,頭條的適配方案,肯定了解過

25. onCreate和onPostCreate的區別(onResume和onPostResume的區別)?

–> 這是個很細節的點,我確實不知道,但是其實無傷大雅,生命周期相關,AspectJ切一下,一目了然

26. 深拷貝和淺拷貝的區別,序列化是深拷貝還是淺拷貝?

–> 序列化就是簡單實現深拷貝的一種方式

27. 貝塞爾曲線怎麼實現?

–> UI繪製是我弱項,但寫了一次發現其實真的是數學相關,其注意點和優化點,IDE都有提示…

28. Activity、Window、View的聯繫?

–> 從Activity開始顯示View切入輔以一些拓展,感覺很清晰

29. View的繪製流程,測量模式?

30. Android的兩個特別重要的服務是什麼時候啟動的?

–> 以為是問的android系統啟動的概覽,其實問的是WMS和AMS啟動(這個我就沒懂想要知道什麼要點了),回答了是分批分階段啟動,目的是為了解決相互依賴的問題和提升啟動速度

31. 滑動窗口如何實現?

–> 滑動窗口的實現主要是把發送內容分成幾部分,然後邊確認邊發送,發送窗口就逐漸往前滑動了,接收方同理

32. start和run的區別?sleep和wait的區別?

–> 這種低級問題,其實我都不想回答…

33. Thread的join方法?

–> 使用wait來等待結果,可以設置超時,和FutureTask比較<使用Unsafe和CAS實現>(和CountDownLatch<等待事件、利用ReetrantLock實現<內部是AQS,再內部是CAS+UnSafe>>、CyclicBarrier<等待執行緒,底層實現和CountDownLatch相同>比較)

34. new Integer(123)和123的區別(Integer.valueOf(123)) –> 基本數據類型有快取池進行優化

35. private static 方法,子類能重寫嗎?

–> private是該類可見,static是類屬性,沒有重寫概念的(這個細講要從class的載入切入了)

36. Looper.loop為什麼不會導致ANR?

–> ANR的原理和基於消息的機制實現角度,可升華到底層fd

37. dialog和activity調用getWindow獲取到的對象有什麼不同?

–> 問的應該是層級問題(上家公司的UI框架應該是參考了Window管理模型的)

38. Int可以作為執行緒安全的單位嗎?AtomicInteger實現原理?

–> CAS+版本記錄

39. Intent的使用中有遇到什麼問題嗎?如何解決大圖傳輸問題?

–> 傳輸上限、類型解析,Ashmem

40. 雙向認證的流程?

–> 其實就是https加了個驗證client端的步驟

41. 啟動模式的應用場景?

42. 熟悉的設計模式?

43. 異常設計?

–> 這個需要很結合業務了,throw和throws的區別,比如sdk拋異常的時機,可以結合講講異常的實現原理和比if..else慢的原因

44. 如何排查記憶體泄露?

–> 逐漸演進+線上監控

45. 紅黑樹的實現原理?怎麼染色的?

–> 當時確實記不清了,重點是顏色翻轉+臨時4節點+二三樹+(LL、LR、RL、RR)

46. 說下常見的排序演算法?

–> 冒泡、插入、歸併、快速的實現

47. 說下常見的集合類?

48. 說下JVM的特性?

49. 瀏覽器輸入一個url點擊發送後發生了什麼?

50. 如何顯示一張大圖?

51. 一些多執行緒和JVM的問題

—> 這兩個算強項了,不打斷能講很久

52. 執行緒池的實現原理?裡面的隊列有了解過嗎?

【Android進階學習影片】、【全套Android面試秘籍】關注我【主頁簡介】查看免費領取方式

2. 開源庫

1. ARouter原理,攔截器怎麼實現的?

–> ARouter核心是apt註解生成路由資訊,調用init進行初始化,使用navigation進行跳轉。攔截器可以實現未登錄功能統跳,也是路由功能的(ARouter第一次接觸,之前公司的路由框架是自己寫的)

2. okhttp原理,有沒有自定義過攔截器,遇到過什麼問題?

–> okhttp的亮點在於其攔截器,提了下域名收斂優化,自定義攔截器實現了日誌列印,攔截器分為響應前和響應後兩大部分,注意一下應該不會有問題。最近幫其他人解決了一個雙認證的final問題。

3. glide的快取策略

–> 記憶體快取(正在使用的用弱引用,不在使用的用LRUCache)+磁碟快取(可設置快取類型)

3. 項目相關

1. 項目中的亮點和難點?工作中對自己感覺提高最大的?

–> 印象比較深的是啟動優化和埋點

2. 埋點實現,如何去除多餘的業務埋點,有沒有了解過無痕埋點和全埋點?無痕埋點如何加入業務數據。

–> 可以從埋點的演進(域名收斂、結合頁面切換、環境切換臟數據、雙周期、統一管理實時、mmap+fd)、之前上報策略的問題和當前埋點現狀來切入,無痕埋點加入業務數據可以採用腳本化應對產品到易變需求(提了下lua)

4. 發散性問題

1. 未來的規劃?

2. 如何像一個不懂技術的說明白什麼是多執行緒?

–> 考驗語言表達能力

3. 同一項任務再做一次,你會如何執行?

–> 考驗復盤總結能力

4. 寫幾個Sql

—> 這個其實不是我強項,我是發散學習過資料庫的實現和一些相關注意點,希望以後能夠提供一些優化思路(確實會有,資料庫相當於一個非常成熟的框架,也是一步步優化過來的,而且發現優化相關有三條線,一是不斷演進,二是不斷侵入底層<畢竟最終都是實體,執行緒調度實際上也是為了IO>,三是需要結合不同場景調度不同策略)

5. 遇到問題怎麼解決?

其實沒什麼好分享的,雖然本來是抱著不進大廠以後就不走技術路線的想法準備的。刷了好幾個framework、演算法數據結構相關課程,梳理了多執行緒相關、JVM相關,也刷了一些leetCode等,而且一直工作認真負責,不斷思考找突破點,不斷跟進優化和埋點,差一步入C和OS,真的只是差一個看對眼的機會(不是自戀,這點信心還是有的,可以說只要不惡意刁難和我腦子不斷路,難倒我的不多)。

原計劃(本來是抱著不進個叫的出名字的公司就不打算走技術路線的心準備的):小公司熱身 –> 拿幾個可以的備用offer –> 試一試杭州的大廠 –> 不行,試試上海的 –> 再不行,試試北京的 –> 再不行,南下

但是,後面發現其實路子走窄了,應該備用和大廠面試組合著來的,大廠面試流程久,一直不敢投(原諒一個2020年到現在還沒拿到一分錢工資的小Android的內心惶恐,怕上半年就稀里糊塗過了,要恰飯的嘛)

現在先找個離家近的,也比較穩的站穩腳跟(一是安全,二是穩,我覺得後面會越來越難了)。接下來抽時間整理整理現在的知識體系,然後繼續挖深深度,遺憾的是這次沒沖大廠,而且現在很累,想緩一緩,有機會直接去沖高級。運氣也是很重要的一項因素,繼續努力,為了早日加入大廠寫程式碼,老了以後在大廠搞保潔。

希望疫情早日過去,希望我後面能好運一些。

最後

今天分享的面試題就到這裡,還是那句話,有些東西你不僅要懂,而且要能夠很好地表達出來,能夠讓面試官認可你的理解,例如Handler機制,這個是面試必問之題。有些晦澀的點,或許它只活在面試當中,實際工作當中你壓根不會用到它,但是你要知道它是什麼東西。

不管怎麼樣,不論是什麼樣的大小面試,要想不被面試官虐的不要不要的,只有刷爆面試題題做好全面的準備,當然除了這個還需要在平時把自己的基礎打紮實,這樣不論面試官怎麼樣一個知識點裡往死里鑿,你也能應付如流啊~