寫在前面
那天剛好是下午 oppo hr 面完,大約 3 點左右騰訊來電,我在電梯里沒太注意沒接到電話,下午就一直盼呀盼,大約九點剛下班到公司樓下來電了,問方不方便我當然說方便,就在馬路邊上面了大約 50 來分鐘,我感覺應該是掛了的,因為過程中電話老是斷加上環境又比較吵,第二天問獵頭說,下班前查了一下同一批面試的都釋放了,你應該是過了只說是應該過了。過了整整一周到了隔周五上午,接到了第二面的面試通知,約的是隔周三上午 10:30 。第二面面試官時不時的面帶笑容,給人很輕松的感覺。二面完后要我稍等一下接著面三面,三面面完面試官問我下午還有事沒?我們***(應該是領導)有點事,下午四點左右可以面第四面,具體我也沒聽清楚是誰我也不敢問。我說下午要上班就先回去了,下午接到 hr 電話約的是隔周二的上午。總共五輪面試含 hr 面,持續周期一個月左右。
技術一面
mmap + native 日志優化?
講了傳統日志打印的兩個性能問題,一個是反復操作文件描述符表,一個是反復進入內核態,然后講了 mmap 的原理機制。廣播和 EventBus 的區別?
說 EventBus 的實現原理是基于反射,里面管理了兩張表,且代碼之間關聯性不大不易于維護,EventBus 不支持跨進程通信,被面試官反問你確定不支持跨進程?我說我的看的源碼是不支持,面試官說那好吧。常用設計模式你了解哪些?
我開始巴拉巴拉說了一大堆,其中說到了裝飾設計模式,被面試官打斷了,請你具體說說裝飾設計模式。跨進程通信有哪些?
管道,信號,信號量,文件,本地套接字,共享內存,binder 驅動簡單講講 binder 驅動吧?
從 Java 層來看就像訪問本地接口一樣,客戶端基于 BinderProxy 服務端基于 IBinder 對象,從 native 層來看來看客戶端基于 BpBinder 到 ICPThreadState 到 binder 驅動,服務端由 binder 驅動喚醒 IPCThreadSate 到 BbBinder 。然后又講了虛擬內存、物理內存和內存映射,跨進程通信的原理是要基于內核的, 當我講到 binder_open 、binder_mmap 和 binder_ioctl 是被面試官打斷了,估計是怕我講太久了。跨進程傳遞大內存數據如何做?
我說 binder 肯定是不行的,因為映射的最大內存只有 1M-8K,可以采用 binder + 匿名共享內存的形式,像跨進程傳遞大的 bitmap 需要打開系統底層的 ashmem 機制。說說 ConcurrentHashMap 的實現原理說下,初始化大小是多少?
是線程安全的,實現原理采用的是分段鎖,初始化大小是 16 ,必須是 2 的冪次。啟動優化怎么優化?
我說了關鍵優化 Application ,被面試官打斷了,說大家都能想到的東西你不要說了,我想聽的是你能不能站在系統的角度去做一些優化,我提到了優化包體積大小能優化啟動速度,優化 dex 分包能優化啟動速度,可以參考最新的華為方舟編譯器等等。你寫的 rxpay 和 rxlogin 具體怎么實現的?
一般我們集成第三方登錄和第三方支付 SDK 都需要監聽 onActivityResult 方法,我是參考了 RxPermission 的實現方案添加了透明 Activity 。kotlin + fullter 方面的
kotlin 自己學了語法但是開發項目中沒用上,fullter 我是了解了它的實現原理但是開發中也沒用上。
技術二面
單例設計模式都寫寫,靜態內部類是怎么保證線程安全的?
synchronized 底層實現原理,ReentrantLock 公平鎖與非公平鎖。
主線程等待所有線程執行完畢,再執行某個特定任務怎么實現?原理和源碼看過沒?
自定義 view 的一般流程,要注意些什么如何優化,點擊事件和長按時間分別是怎么實現的?
四種啟動模式,在源碼分析中的原理是怎樣的?
講講 bindService 的過程,你當初是怎么優化后臺服務進程的?
開發中你都用到了哪些設計模式?說說當時具體的場景。為什么你要用方法工廠,另外兩種呢?
RxJava 在使用過程中碰到了某些不友好的錯誤一般怎么解決?發現了內存泄露一般怎么解決分析,有沒有碰到過系統服務內存泄露的問題?
你們用的 okhttp ?那你有沒有做過一些網絡優化呢?比如弱網環境。
給你個數 1 吧,比如 1000011 里面有幾個 1 ?
快排了解不?最壞的情況是怎樣?如果有大量重復數據怎么優化?
技術三面
講講 handler 的底層實現原理?
這么簡單?問到碗里來了,后面漸漸說到延遲消息是 nativePollOnce 來處理的,在 6.0 以上用的是 epoll 方式來監聽文件描述符。接著問道了為什么要用這種方案?它跟 poll 和 select 比起來有哪些優勢?它是怎么監聽的你看過它的內部實現原理沒?反正感覺很難受了。說說你做的日志記錄優化?
把第一輪面試的又講了一通,你在每個文件的最后寫入了當前內容的大小,你有沒有想過如果文件被破壞的情況?這種異常情況怎么處理?后面還問到了加密和壓縮。你看過 binder 驅動的源碼,說說他的內存映射過程,說說客戶端等待服務端處理返回的流程,如果要跨進程傳遞大內存數據你具體會怎么做?簡單寫一寫吧。
在公司做過哪些優化?
內存優化,啟動優化,網絡優化,包體積優化,具體說說包體積優化。我提到了包體積優化不僅僅是優化了包的大小,包體積太大從安裝的那一刻開始,我們的應用就可能比較慢了,因為 pms 會去拷貝解壓解析我們的 apk 安裝文件,會去優化我們的 dex 等等,包體積太大還會影響我們的啟動速度。然后就巴拉巴拉說具體怎么做,問到了為啥混淆資源能減少包體積大小?你當時優化的時候效果是怎樣的減少了多少?開發過程中遇到的一些最難解決的問題?
提到了動態修復替換加載 so ,那你知道怎么修復 class 嗎?怎么修復資源呢?后面又聊到了插件化,提到了 360 用的是借尸還魂,那如果我們在插件的 Androidmanifest.xml 中注冊了其它屬性該怎么解決,資源方面怎么處理?
- 還有什么要問我的?
個人體會
要是換幾年前我也跟大家一樣,感覺這些面試題估計一個也答不好,但是今天回過頭再來看其實感覺也就一般般吧。當我們讀小學時感覺初中知識比較難,但當我們讀到高中時再回過頭來看就很簡單了。因此我們不必在乎現在的自己能力是否足夠強,一口也是吃不成胖子的,只要今天比昨天有進步這就足夠了。但道理我們都懂,可是能堅持下來的同學卻比較少了,人生貴在堅持!
隨著年齡的增長意味著我們的時間也越來越少了,所以我們自己心里要明白想要什么?是想成為某個領域的專家,還是想多方面發展以后做領導型人才。一個時間段往往只能做好一件事情,有舍必會有得。當我們開著拖拉機在鄉村道路時,不要看著別人開著跑車就羨慕,以為拖拉機也能上高速,但內心要有換噴氣式飛機的勇氣和決心。
大廠的正常面試流程周期一般是一到兩個月,就算薪資談完到 offer 最終審批下來可能都需要一到兩周,這段時間心理是比較難熬的,因此建議大家盡量不要裸辭。面試完畢一般都會透露多久給答復,如果是獵頭推的多跟獵頭聯系,大家要盡量想辦法打聽到最新的動態。
二本大學也會有一流的專業,所以并不一定說一線互聯網企業就是最好的,因此在面試的時候一定要問一下部門和項目,自己根據自身的情況來選擇企業和項目組。一般情況下通過面試的難易程度就能判斷出部門的技術沉淀,那種幾乎不問技術很容易過的情況,并不見得就一定是好現象,還是得根據自身的情況和以后的打算來判斷,有時選擇可能會大于努力。