Android 開發面經,騰訊之旅!

寫在前面

我每年都會隔一段時間出去面試一次,面試的目的不是爲了找到好的工作,而是想知道自己的技術能力是否符合市場需求,有沒有與時代發展速度脫軌。 同樣,面試你的也是同行,這樣也能夠碰撞出不同的思想。當然,如果遇到好的機會那也是不能錯過不過了。試想?如果你一直待在一家公司,都不知道外面的情況如何的話,那是很可怕的,至少我這麼認爲。如果您同意這樣的觀點,不妨接着往下看,讓我們一起研究面試過程中需要具備的知識。下面是我親生經歷的一次面試,這裏寫出來給大家分享,更多的是總結面試中遇到的問題以及以後學習過程中的方向。只有這樣才能和時代發展速度接上軌跡。

這次面試的公司是互聯網BAT大廠中的騰訊,這也大多數開發者們一直進入的大廠之一吧。技術面試一共是三面。下面是我的一個面試過程和總結。

面試過程

技術一面

1.mmap + native 日誌優化?

講了傳統日誌打印的兩個性能問題,一個是反覆操作文件描述符表,一個是反覆進入內核態,然後講了 mmap 的原理機制。

2.廣播和 EventBus 的區別?

說 EventBus 的實現原理是基於反射,裏面管理了兩張表,且代碼之間關聯性不大不易於維護,EventBus 不支持跨進程通信,被面試官反問你確定不支持跨進程?我說我的看的源碼是不支持,面試官說那好吧。

3.常用設計模式你瞭解哪些?

我開始巴拉巴拉說了一大堆,其中說到了裝飾設計模式,被面試官打斷了,請你具體說說裝飾設計模式。

4.跨進程通信有哪些?

管道,信號,信號量,文件,本地套接字,共享內存,binder 驅動

5.簡單講講 binder 驅動吧?

從 Java 層來看就像訪問本地接口一樣,客戶端基於 BinderProxy 服務端基於 IBinder 對象,從 native 層來看來看客戶端基於 BpBinder 到 ICPThreadState 到 binder 驅動,服務端由 binder 驅動喚醒 IPCThreadSate 到 BbBinder 。然後又講了虛擬內存、物理內存和內存映射,跨進程通信的原理是要基於內核的, 當我講到 binder_open 、binder_mmap 和 binder_ioctl 是被面試官打斷了,估計是怕我講太久了。

6.跨進程傳遞大內存數據如何做?

我說 binder 肯定是不行的,因爲映射的最大內存只有 1M-8K,可以採用 binder + 匿名共享內存的形式,像跨進程傳遞大的 bitmap 需要打開系統底層的 ashmem 機制。

7.說說 ConcurrentHashMap 的實現原理說下,初始化大小是多少?

是線程安全的,實現原理採用的是分段鎖,初始化大小是 16 ,必須是 2 的冪次。

8.啓動優化怎麼優化?

我說了關鍵優化 Application ,被面試官打斷了,說大家都能想到的東西你不要說了,我想聽的是你能不能站在系統的角度去做一些優化,我提到了優化包體積大小能優化啓動速度,優化 dex 分包能優化啓動速度,可以參考最新的華爲方舟編譯器等等。

9.你寫的 rxpay 和 rxlogin 具體怎麼實現的?

一般我們集成第三方登錄和第三方支付 SDK 都需要監聽 onActivityResult 方法,我是參考了 RxPermission 的實現方案添加了透明 Activity 。

10.kotlin + fullter 方面的

kotlin 自己學了語法但是開發項目中沒用上,fullter 我是瞭解了它的實現原理但是開發中也沒用上。

技術二面

1.單例設計模式都寫寫,靜態內部類是怎麼保證線程安全的?
2.synchronized 底層實現原理,ReentrantLock 公平鎖與非公平鎖。
3.主線程等待所有線程執行完畢,再執行某個特定任務怎麼實現?原理和源碼看過沒?
4.自定義 view 的一般流程,要注意些什麼如何優化,點擊事件和長按時間分別是怎麼實現的?
5.四種啓動模式,在源碼分析中的原理是怎樣的?
6.講講 bindService 的過程,你當初是怎麼優化後臺服務進程的?
7.開發中你都用到了哪些設計模式?說說當時具體的場景。爲什麼你要用方法工廠,另外兩種呢?
8.RxJava 在使用過程中碰到了某些不友好的錯誤一般怎麼解決?發現了內存泄露一般怎麼解決分析,有沒有碰到過系統服務內存泄露的問題?
9.你們用的 okhttp ?那你有沒有做過一些網絡優化呢?比如弱網環境。
10.給你個數 1 吧,比如 1000011 裏面有幾個 1 ?
11.快排瞭解不?最壞的情況是怎樣?如果有大量重複數據怎麼優化?

技術三面

1.講講 handler 的底層實現原理?

這麼簡單?問到碗裏來了,後面漸漸說到延遲消息是 nativePollOnce 來處理的,在 6.0 以上用的是 epoll 方式來監聽文件描述符。接着問道了爲什麼要用這種方案?它跟 poll 和 select 比起來有哪些優勢?它是怎麼監聽的你看過它的內部實現原理沒?反正感覺很難受了。

2.說說你做的日誌記錄優化?

把第一輪面試的又講了一通,你在每個文件的最後寫入了當前內容的大小,你有沒有想過如果文件被破壞的情況?這種異常情況怎麼處理?後面還問到了加密和壓縮。

3.你看過 binder 驅動的源碼,說說他的內存映射過程,說說客戶端等待服務端處理返回的流程,如果要跨進程傳遞大內存數據你具體會怎麼做?簡單寫一寫吧。

略……

4.在公司做過哪些優化?

內存優化,啓動優化,網絡優化,包體積優化,具體說說包體積優化。我提到了包體積優化不僅僅是優化了包的大小,包體積太大從安裝的那一刻開始,我們的應用就可能比較慢了,因爲 pms 會去拷貝解壓解析我們的 apk 安裝文件,會去優化我們的 dex 等等,包體積太大還會影響我們的啓動速度。然後就巴拉巴拉說具體怎麼做,問到了爲啥混淆資源能減少包體積大小?你當時優化的時候效果是怎樣的減少了多少?

5.開發過程中遇到的一些最難解決的問題?

提到了動態修復替換加載 so ,那你知道怎麼修復 class 嗎?怎麼修復資源呢?後面又聊到了插件化,提到了 360 用的是借屍還魂,那如果我們在插件的 Androidmanifest.xml 中註冊了其它屬性該怎麼解決,資源方面怎麼處理?

6.還有什麼要問我的?

總結

要是換幾年前我可能也跟大家一樣,感覺這些面試題估計一個也答不好,但是今天回過頭再來看其實感覺也就一般般吧。當我們讀小學時感覺初中知識比較難,但當我們讀到高中時再回過頭來看就很簡單了。因此我們不必在乎現在的自己能力是否足夠強,只要今天比昨天有進步這就足夠了。但道理我們都懂,可是能堅持下來的人卻比較少了,人生貴在堅持!

隨着年齡的增長意味着我們的時間也越來越少了,所以我們自己心裏要明白想要什麼?是想成爲某個領域的專家,還是想多方面發展以後做領導型人才。一個時間段往往只能做好一件事情,有舍必會有得。當我們開着拖拉機在鄉村道路時,不要看着別人開着跑車就羨慕,以爲拖拉機也能上高速,但內心要有換噴氣式飛機的勇氣和決心。

但是不用凡是都抱着得到的心態去做,就好比自己勤奮學習就一定是爲了進 BAT大廠,如果是這樣那當我們進了 BAT 又該如何,學習這件事應該是終身的。只要我們能靜下心來該來的自然會來,作人無甚高遠事業,擺脫得俗情,便入名流;爲學無甚增益工夫,減除得物累,便超聖境。

不要凡是都抱着利益的心態去做,一直以來我都是崇尚成就自己的同時去成就別人。只要自己不抱着利益的心態去做,那麼便能拿得起放得下,當我想講的時候便可以講,不想講的時候便可以不講。過程中肯定會有各種疑問和懷疑,若堅持不了就放棄,但心中若有掛礙就銘記。

最後

我在每次面試完後都會對自己的面經進行整理歸納,方面以後進行翻閱瀏覽。而且我在每次面試之前還會去網上收集一些面試相關的進階文檔進行學習,希望能夠讓自己在面試中對答如流,順利的去斬獲Offer。這次的面試能通過有部分的功勞來自這些學習文檔,因此小編想讓讓這些文檔發揮出它應有的作用,特此上傳收錄至我的GitHub項目中:https://github.com/733gh/Android-T3/blob/master/JianShu.md大家可以去自行查閱,望能在面試中助大家一臂之力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章