寫在前面
一直有同學(xué)跟我反饋說,你能不能說說你的一些面試經(jīng)驗(yàn)啥的夸赫,其實(shí)很多時(shí)候我是拒絕的讯赏,因?yàn)槲覀兒啔v經(jīng)歷不一樣問的問題也會不一樣,且大廠面試光靠背幾個(gè)面試題就想過還是比較難的禾进。因此在這里提醒一下大家不要臨時(shí)抱佛腳,你花幾天能背下的東西廉涕,別人花幾天一定能超過你的泻云,但我們花幾年沉淀的東西,人家花幾個(gè)月就未必能趕上狐蜕,希望大家不飛則已宠纯,一飛沖天。
說說當(dāng)時(shí)面試的過程层释,是 boss 直聘 HR 推了簡歷給有關(guān)部門婆瓜,簡歷通過后電話約的面試機(jī)會。當(dāng)時(shí)約的是 10:30 的面試時(shí)間贡羔,所以只請了半天假廉白。十點(diǎn)早早就到了華潤大樓樓下,由于那個(gè)樓層有點(diǎn)復(fù)雜花了整整十幾分鐘才到 32 樓(是個(gè)食堂)乖寒。第一輪是兩個(gè)面試官輪流問問題猴蹂,第一面大約面了一個(gè)小時(shí)到了 11:40 漸漸有人吃飯了,撕了手機(jī)標(biāo)簽我就準(zhǔn)備走了楣嘁。這時(shí)兩個(gè)面試官說你要不再等會磅轻,我打電話給我們老大珍逸,后來打電話又打不通就直接下去叫了,我就在食堂開始看著別人吃飯聋溜。大約等了十幾分鐘第二面的面試官把我叫到了 31 樓谆膳,也是兩個(gè)面試官輪流問了大概一個(gè)小時(shí),面完二面后就差不多到了下午一點(diǎn)勤婚,面試官說我?guī)闳ナ程贸詡€(gè)飯摹量,吃完飯面試官幫我約了下午兩點(diǎn)的 HR 面。感覺整個(gè)流程下來非常爽馒胆,總共三輪面試,兩輪技術(shù)面(每輪2個(gè)面試官)凝果,一輪 HR 面祝迂。
技術(shù)一面
mmap + native 日志優(yōu)化?
講了傳統(tǒng)日志打印的兩個(gè)性能問題器净,一個(gè)是反復(fù)操作文件描述符表型雳,一個(gè)是反復(fù)進(jìn)入內(nèi)核態(tài),然后講了 mmap 的原理機(jī)制山害。講講 Android 開機(jī)啟動的流程
講了一大堆纠俭,其中說到 ServiceManager 進(jìn)程是用來管理系統(tǒng)服務(wù)的,面試官說你確定浪慌?不是 SystemServer 進(jìn)程來管理系統(tǒng)服務(wù)的嗎冤荆?討論了一番面試官懵逼了,提到了 SystemUI 服務(wù)权纤,提到了桌面進(jìn)程钓简,問到了怎么替換開機(jī)啟動的動畫?系統(tǒng)是怎么幫我們啟動找到桌面應(yīng)用的
我說通過意圖汹想,他說怎么找到是哪個(gè)意圖? 我說 PMS 會解析所有 apk 的 AndroidManifest.xml 外邓,如果解析過會存到 package.xml 中不會反復(fù)解析,PMS 有了它就能找到了古掏。講講動態(tài)狀態(tài)頁的加載损话,為什么要這么弄?
我說為了減少 xml 解析和反射創(chuàng)建對象的時(shí)間槽唾,避免同時(shí)創(chuàng)建多個(gè)用不上的對象丧枪,我就寫了個(gè)框架用代碼動態(tài)添加的。這時(shí)面試官誤解了我的意思夏漱,以為所有的界面都是用代碼寫的豪诲,那得多麻煩呀,后來解釋清楚了挂绰。講講頁面的刷新機(jī)制屎篱,GPU 調(diào)試工具幾個(gè)顏色值分別代表什么服赎?
講到了 Surface 底層管理的其實(shí)是 IBPQ , 講了異步信號的由來是 SurfaceFlinger 由硬件和軟件機(jī)制發(fā)出來的,講了我們 app 界面繪制的內(nèi)容是怎么提交傳遞到 SurfaceFlinger 的交播。GPU 調(diào)試工具幾種顏色的意思也大概講了下重虑。說說 ConcurrentHashMap 的實(shí)現(xiàn)原理說下
是線程安全的,實(shí)現(xiàn)原理采用的是分段鎖秦士。你知道 okhttp 是怎么復(fù)用連接的嗎缺厉?
這是個(gè)網(wǎng)絡(luò)優(yōu)化的問題,同一個(gè) ip 同一個(gè)端口能復(fù)用一個(gè)連接隧土,后面問道了 http 2.0 的多路復(fù)用提针,我說一個(gè) tcp 可以多個(gè)請求,原理呢曹傀?我說不知道辐脖。后面讓我說了下 https 。數(shù)組和鏈表的區(qū)別說下
快排和遞歸
技術(shù)二面
講一講動態(tài)注冊和靜態(tài)注冊
靜態(tài)注冊是通過包名和函數(shù)名去找方法皆愉,動態(tài)注冊是通過注冊方法表嗜价,其中還被問到了具體是調(diào)用哪個(gè)函數(shù)注冊方法表。so 的加載流程是怎樣的幕庐,生命周期是怎樣的
這個(gè)要從 java 層去看源碼分析久锥,是從 ClassLoader 的 PathList 中去找到目標(biāo)路徑加載的,同時(shí) so 是通過 mmap 加載映射到虛擬空間的异剥。生命周期加載庫和卸載庫時(shí)分別調(diào)用 JNI_OnLoad 和 JNI_OnUnload() 方法瑟由。native 層怎么檢測內(nèi)存泄漏
我說按道理可以 hook 函數(shù),開辟內(nèi)存和釋放內(nèi)存的次數(shù)應(yīng)該是一樣的届吁,如果不一樣可以懷疑內(nèi)存泄漏错妖。面試官接著問有沒有什么第三方工具或者庫可以檢測?我說我在公司其實(shí)也寫的不多疚沐,不知道引擎組集成的是啥框架暂氯,主要擅長應(yīng)用層開發(fā)。leakcanary 的原理亮蛔,哪些對象可以用來做 gc-root
好痴施,你說你主要擅長應(yīng)用層開發(fā),那 Java 層的內(nèi)存泄漏怎么檢測究流,我說我們用的 leakcanary辣吃,讓我說說原理,說完原理又問我是不是所有對象泄漏 leakcanary 都能檢測得到芬探,他的引用鏈?zhǔn)窃趺垂芾淼纳竦茫亢竺鎲柕侥銊傉f弱引用對象在 gc 的時(shí)候會被釋放,那什么時(shí)候不會被釋放偷仿?我這時(shí)懵逼了哩簿,其實(shí)就是有內(nèi)存泄漏的時(shí)候不會被釋放宵蕉,我當(dāng)時(shí)腦子短路了居然沒反應(yīng)過來。ui 怎么優(yōu)化的节榜?
我主要從底層講了一下 UI 刷新機(jī)制的流程羡玛,又把一面的 SurfaceFlinger 底層機(jī)制講了一遍,原理搞清了就可以做很多優(yōu)化宗苍,巴拉巴拉說了一大堆稼稿,最后講了怎么去監(jiān)聽 UI 卡頓。線程耗時(shí)卡頓怎么監(jiān)聽的讳窟?
主要用工具去檢測让歼,當(dāng)時(shí)只提到了 systrace + 函數(shù)插樁的方式。說說你看的 Tinker 的原理挪钓?
你遇到的最難解決的問題是越?
我說我們公司項(xiàng)目沒有采用動態(tài)加載框架,但是后面集成 U3D 項(xiàng)目需要動態(tài)加載碌上,但只需要用到 so 和資源動態(tài)加載,功能上第三庫也不支持我們的需求浦徊,我就自己硬著頭皮看了各大版本的源碼馏予,支持動態(tài)修復(fù)替換加載 so 和 assets 資源動態(tài)修復(fù)加載,然后把具體的細(xì)節(jié)說了一遍盔性。常見數(shù)據(jù)結(jié)構(gòu)你都熟悉哪些霞丧?不是本專業(yè)算法你是怎么學(xué)的?
數(shù)組冕香,鏈表蛹尝,堆,二叉樹悉尾,隊(duì)列突那,棧,平衡二叉樹构眯,紅黑樹愕难,霍夫曼樹,圖惫霸。自己看書算法通過刷題猫缭,這里沒具體問算法細(xì)節(jié)。線上有人反饋問題你一般怎么處理的壹店?
開發(fā)過程中記錄關(guān)鍵日志猜丹,線上獲取用戶日志來分析。
個(gè)人體會
不用凡是都抱著得到的心態(tài)去做硅卢,就好比學(xué)習(xí)我就一定是為了進(jìn) BAT射窒,如果是這樣那當(dāng)我們進(jìn)了 BAT 又該如何藏杖,就好比死亡并不是代表生命的結(jié)束,學(xué)習(xí)這件事應(yīng)該是終身的轮洋。只要我們能靜下心來該來的自然會來制市,作人無甚高遠(yuǎn)事業(yè),擺脫得俗情弊予,便入名流祥楣;為學(xué)無甚增益工夫,減除得物累汉柒,便超圣境误褪。
不要凡是都抱著利益的心態(tài)去做,一直以來我都是崇尚成就自己的同時(shí)去成就別人碾褂。只要自己不抱著利益的心態(tài)去做兽间,那么便能拿得起放得下,當(dāng)我想講的時(shí)候便可以講正塌,不想講的時(shí)候便可以不講嘀略。過程中肯定會有各種疑問和懷疑,若堅(jiān)持不了就放棄乓诽,但心中若有掛礙就銘記帜羊。
大家要記住凡事都只能靠自己,不要輕信某些培訓(xùn)機(jī)構(gòu)誰誰是 BAT 大佬鸠天,誰又是華為出來的讼育,作為過來人來看很多是為了營銷, BAT 的要求絕對高于培訓(xùn)的那些知識稠集。但倘若我們的知識體系的確還沒有達(dá)到那個(gè)程度奶段,肯定是可以考慮且選擇的,只是我們自己要知道光學(xué)那些還不夠剥纷,當(dāng)然大家也不要相信我痹籍,凡事多問問自己的心。