0.寫在前面
(全文約4k字,已經(jīng)投稿 鴻洋 老師的公眾號(hào),只想做個(gè)小透明,對(duì)鵝是真愛)
總共是面了8家,(2小,4中,2大廠)
小的都拿下了,4中里3個(gè)一輪游,1個(gè)三輪游。2大的都談薪了。
小公司會(huì)比較偏重于業(yè)務(wù),面試上也偏重業(yè)務(wù),比如做了什么,大概方案,用了哪些庫(kù),庫(kù)的原理。
這些基本上會(huì)集中在 圖片處理,網(wǎng)絡(luò)封裝,自定義view這幾個(gè)部分。
大廠會(huì)從業(yè)務(wù)入手,遞進(jìn)深入到原理及相關(guān)知識(shí)點(diǎn),尤其集中在原理部分,這里對(duì)平時(shí)源碼閱讀有一定要求。
或者直接問對(duì)xxx源碼有沒有了解。
比如一個(gè)handler機(jī)制,因其涉及的地方特別多而且很容易展開,想完美答好,真的不是一次兩次就能行的。
建議每次面試完,都及時(shí)對(duì)面試內(nèi)容進(jìn)行回憶記錄,
這里不是為了泄題漏題,以后吹牛逼,這個(gè)沒有任何意義。
目的是進(jìn)行復(fù)盤,打磨自己的回答。
目錄
- 簡(jiǎn)歷書寫
- 面試原題
- 算法刷題
- 學(xué)習(xí)總結(jié)
1. 簡(jiǎn)歷書寫
強(qiáng)烈建議,把自己的強(qiáng)項(xiàng),亮點(diǎn)加粗注明放在簡(jiǎn)歷前面,大家都很忙,也很煩躁,讓人一眼就看到優(yōu)點(diǎn),對(duì)雙方都友好。
因?yàn)槲覍?duì)安卓性能優(yōu)化方面感興趣,平時(shí)工作也花了很多時(shí)間在這里,所以我會(huì)在簡(jiǎn)歷上突出說明,
我做了內(nèi)存優(yōu)化,熟練掌握使用xxx,內(nèi)存性能提升xxx
(因?yàn)檫@里的內(nèi)容是可控的,如果面試官對(duì)你感興趣,這里的回答你也是能提早準(zhǔn)備好的)
項(xiàng)目經(jīng)歷如何寫?建議按照是什么,做了啥,有啥數(shù)據(jù)指標(biāo)佐證的方式去寫。
比如,我做了xx項(xiàng)目,負(fù)責(zé)xx模塊,使用了xxx框架,可配合xx做xxx,效率提高xxx%
2.面試題
字節(jié)一輪
1.先聊簡(jiǎn)歷。
2.聊性能優(yōu)化方面的問題,我這邊體系化展開講卡頓,瘦身,內(nèi)存,crash等方面的優(yōu)化經(jīng)驗(yàn)。
3.sychronized,volatile區(qū)別?
這里可以體系化的回答,主要從JMM角度去回答,最后深入到字節(jié)碼層面的區(qū)別。因?yàn)樘岬搅诵揎椀姆秶胁顒e,就有了下一題。
4.對(duì)于鎖的對(duì)象的不同,效果會(huì)有什么差別。
5.講一下handler機(jī)制。
這個(gè)問題問得太多了,一定要去看一回源碼。
重點(diǎn)答的是msgQueue這塊,包括什么時(shí)候空閑,阻塞。
發(fā)散講了線程相關(guān)的threadLocal,還有IdleHanlder
6.出了一個(gè)設(shè)計(jì)題,當(dāng)你的服務(wù)商出現(xiàn)問題,設(shè)計(jì)一個(gè)網(wǎng)絡(luò)請(qǐng)求可用性的兜底方案。
大概從httpDNS,域名容災(zāi)等方面回答吧。
7.設(shè)計(jì)一個(gè)方案,apk已經(jīng)發(fā)出去了,java代碼是最新,但是分包下發(fā)的so文件是舊版本,如何做一個(gè)兼容方案,保證兼容可用。
這里沒答好,我也忘了怎么答的了。
8.java類加載機(jī)制。
這是個(gè)基礎(chǔ)概念題,沒答好,回答的雙親加載機(jī)制。
然后引出pathClassLoader,dexClassLoader的區(qū)別,一個(gè)dex的加載到一個(gè)java類的加載過程。
9.一道算法題。
字節(jié)二輪
1.聊簡(jiǎn)歷。
2.性能優(yōu)化,展開講了卡頓,內(nèi)存。
3.數(shù)據(jù)結(jié)構(gòu)的題,hashCode的擾動(dòng)算法,涉及到一個(gè)數(shù)字,31,這個(gè)31是怎么來的?
4.類的static屬性字段,比如 public static int a = 1,被賦值幾次?
這個(gè)需要對(duì)類的加載機(jī)制有了解。
5.多個(gè)Activity共同bind一個(gè)service,一個(gè)Activity destory,問service的情況。
這里就是問service的生命周期,考察bind跟start的區(qū)別。
6.裝飾器模式,跟代理模式的區(qū)別。
考察對(duì)常用的設(shè)計(jì)模式
7.okhttp的緩存邏輯實(shí)現(xiàn)。
我以為是問的 鏈接緩存跟io緩存,我回答的是連接池復(fù)用跟 okio的io復(fù)用。
后來提醒是cache,就回答cacheInspector,及其源碼實(shí)現(xiàn)。
8.sharedPreference的commit ,apply區(qū)別。
9.sharedPreference的其性能問題。
apply的anr是有一個(gè)字段,會(huì)block住主線程,需要清理queuedWork隊(duì)列。
10.sharedPreference線程安全性,還有進(jìn)程安全性,sharedPreference鎖的對(duì)象是誰?
sharedPreference線程安全,鎖的是contentImpl.class
11.synchornized鎖對(duì)象,匯編實(shí)現(xiàn)。volatile的匯編實(shí)現(xiàn)。
12.volatile 修飾 boolean能保證原子性么?
13.Android有哪幾種動(dòng)畫。
14.設(shè)計(jì)題,設(shè)計(jì)一個(gè)埋點(diǎn)數(shù)據(jù)上報(bào)庫(kù),需要哪幾個(gè)模塊,提供哪樣的接口。
15.算法題,生產(chǎn)消費(fèi)者模型。
16.concurrentHashMap的相關(guān)。
包括實(shí)現(xiàn)原理,put方法,樹化,擴(kuò)容,繼承了誰,擴(kuò)容的時(shí)候,其余桶怎么感知。
17.安卓打包簽名v1,v2,v3的區(qū)別。
字節(jié)三輪
1.裝飾器模式,適配器模式區(qū)別。舉個(gè)Android或java里的應(yīng)用例子。
2.單例的優(yōu)缺點(diǎn)。
3.架構(gòu)有做過么。
4.說一下項(xiàng)目,項(xiàng)目中最能提現(xiàn)你能力的事情。
5.平時(shí)怎么學(xué)習(xí)的。
6.以后的職業(yè)規(guī)劃
7.離職原因
8.插件化,做過插件化么,了解的主流方案?
9.算法題。
因第三輪掛了,撈出來換崗位再戰(zhàn)。
字節(jié)一輪(這輪面了175分鐘,記憶深刻)
1.聊聊平時(shí)做過的性能優(yōu)化。
2.界面卡頓
從viewStub源碼開始談layoutInflate的整個(gè)過程
包括xml的解析,如何解析tag,細(xì)節(jié)到里面哪些特殊tag。
3.xml的解析耗時(shí)在哪些方面,反射,讀文件,解析。
4.如何優(yōu)化這個(gè)過程:xml在編譯期就生成為class文件,那這是gradle編譯的哪個(gè)階段做這個(gè)事情。
5.checkthread的問題,從window到viewrootimpl的創(chuàng)建,幾者之間的關(guān)系。
以上這是繪制相關(guān),然后是渲染。
6.矢量圖的原理。
7.canvas怎么來的。
8.window跟view的關(guān)系。
9.硬件加速原理。
10.雙緩沖機(jī)制。
11.丟幀的原因。
12.幀數(shù)計(jì)算。
13.設(shè)計(jì)如何檢測(cè)過度繪制的工具,要具體到view。
14.blockcanary原理,目的。
15.listview的滑動(dòng)優(yōu)化,比如一個(gè)kmoji可以用textview渲染,也可以用imageview渲染,哪個(gè)更優(yōu)。
16.toast為什么不需要權(quán)限就可以顯示。
17.badwindowtoken的原因。
18.怎么實(shí)現(xiàn)懸浮窗。
啟動(dòng)加速
1.怎么做app啟動(dòng)加速
我的回答說利用intentService,就是異步加載機(jī)制。但是還不夠。
2.引導(dǎo)我從app啟動(dòng)流程開始講一遍,看從啟動(dòng)流程上能不能找到方法。
3.zygote的內(nèi)部實(shí)現(xiàn),zygote.fork有沒有了解。
4.zygote跟ams的通信方式用的是什么。
5.整個(gè)啟動(dòng)過程中,mHandler做哪些事。
6.設(shè)計(jì)一個(gè)工具,監(jiān)控啟動(dòng)時(shí)間,粒度要求在方法級(jí)別。
內(nèi)存相關(guān)
1.講下內(nèi)存泄露。以handler匿名內(nèi)部類做例子講。泄露鏈?zhǔn)窃鯓拥摹?/p>
2.looper.prepare干了啥。
3.threadLocalMap的實(shí)現(xiàn)。
4.leakcanary原理。
5.為什么要做抖動(dòng)的檢查,有啥用,
6.為什么會(huì)出現(xiàn)抖動(dòng)。
7.線上有泄露,怎么收集,排查,設(shè)計(jì)方案。
穩(wěn)定性
1.解決線上穩(wěn)定性bug的方法論。
2.講個(gè)能體現(xiàn)亮點(diǎn)的解決線上bug的案例。
3.給了一個(gè)具體案例,讓我現(xiàn)場(chǎng)分析原因。
主要考察思維方式吧。
4.怎么收集java的crash。
5.怎么收集native的crash。
6.用線程安全的數(shù)據(jù)結(jié)構(gòu),concurrentHashMap會(huì)出現(xiàn)modifyCountException么?
ANR相關(guān)
1.常見的anr問題怎么解。
2.不常見的anr,比如 msgQueue.nativePollOnce都很正常,怎么去定位,如果是線上,怎么去收集。
3.anr的原因
4.intentService會(huì)anr么,講內(nèi)部實(shí)現(xiàn)。
?;钕嚓P(guān)問題
1.殺進(jìn)程機(jī)制的源碼。
2.進(jìn)程優(yōu)先級(jí)。
3.怎么提升優(yōu)先級(jí)。
4.常見的?;钍侄巍?br> 我這里著重講了Tim的?;钤?。還有第三方庫(kù)Leonic的原理。
APP瘦身相關(guān)
1.andRes原理。
2.proguard源碼。
3.Facebook 的redex,字節(jié)的bytex原理。
4.multidex原理。
5.很多資源包,如何瘦身。
問了一下我自己維護(hù)的github庫(kù)相關(guān)問題
1.防多開原理
2.檢測(cè)模擬器原理
3.查root權(quán)限,如果是自編的rom怎么處理。
聊了下簡(jiǎn)歷里的經(jīng)歷
1.contentProvider的初始化時(shí)機(jī)。
這里主要是問我LeakCanary1.* 跟2.*有啥不同引出的問題。
2.LocalBroadCast 和broadCast的區(qū)別。
3.xposed的原理。
4.beforeMethodHooked,xposed內(nèi)部做了什么事
5.免root hook框架 legend的源碼實(shí)現(xiàn)。
記不太清,好像我說的是native方法指針的變更。
6.一道算法。
7.設(shè)計(jì)一個(gè)埋點(diǎn)庫(kù)。
需要哪些模塊。
8.設(shè)計(jì)一個(gè)組件,統(tǒng)計(jì)activity的前臺(tái)時(shí)長(zhǎng),fragment的前臺(tái)時(shí)長(zhǎng)。
字節(jié)后續(xù)的面試我忘了記錄復(fù)盤了,現(xiàn)在也記不住了。這一輪面試反正是把我榨干了。
最后進(jìn)入談薪階段。只不過沒談攏,哈哈。
最后就是我一直想去的南山必勝客,粵海公仔廠了
這里面試具體輪次我就不細(xì)說了。題目其實(shí)也都是那些題目,重點(diǎn)提供平時(shí)要學(xué)習(xí)的方向吧。
1.聊簡(jiǎn)歷,性能優(yōu)化。
2.view的繪制流程,盡可能越詳細(xì),越全面越好。
因?yàn)橛辛俗止?jié)之前的面試經(jīng)驗(yàn),這里聊了很多view相關(guān)的。
大概從ActivityThread講起,到window,windowManager,viewRootImpl,
setContentView內(nèi)部實(shí)現(xiàn)干了什么,layoutInflator
下發(fā)到requestLayout,performShechdules,checkThread,繪制屏障消息
雙緩沖,sync信號(hào),最后再performOnMesure,layout,draw。
這里真的是要求自己平時(shí)除了寫界面,也一定要深入源碼進(jìn)行學(xué)習(xí)。
很多奇奇怪怪的業(yè)務(wù)問題,真的就是靠讀源碼解決。
3.問網(wǎng)絡(luò)優(yōu)化,當(dāng)網(wǎng)絡(luò)帶寬足夠大,信號(hào)足夠好,下載大文件,怎么快?
開多個(gè)鏈接,wifi+4G同時(shí),分片下。
協(xié)議層 ,udp去下,本地做完整性校驗(yàn),我記得qq客戶端時(shí)這樣做的。
m3u8的思想去下。
4.apk安全措施,當(dāng)apk已經(jīng)被破解了,怎么處理?
我回答借助v1簽名思想,本地做對(duì)文件md5的校驗(yàn)?;蛘呓柚鷙3的思想,連續(xù)簽名。
5.兩個(gè)設(shè)計(jì)模式的區(qū)別。具體哪兩個(gè)我忘了。
6.三道算法題
第一題寫一個(gè)必然死鎖的代碼。講一下解決死鎖的方式。鎖對(duì)象的不同的區(qū)別。
第一個(gè)出現(xiàn)的字符。
數(shù)組里的元素,組合起來求最大值。
7.checkThread里的thread是什么時(shí)候被賦值的。
8.講下數(shù)字證書是什么。
9.解決內(nèi)存抖動(dòng)的實(shí)際案例。
10.降低bug的實(shí)際案例。
11.設(shè)計(jì)一個(gè)如何處理 app接收到服務(wù)器臟數(shù)據(jù)的方案。
12.設(shè)計(jì)一個(gè)云相冊(cè)。
13.classLoader機(jī)制的原理。
14.硬件加速的底層實(shí)現(xiàn)。
15.操作系統(tǒng)相關(guān)問題。
16.如何處理多語言問題。
17.jvm虛擬機(jī)相關(guān)問題,具體忘了。
18.職業(yè)規(guī)劃相關(guān)。
最后歡迎大家來鵝廠,有一說一不吹牛逼,這里同事真的很不錯(cuò)。
3.算法題
多說兩句,客戶端要學(xué)算法,不是說算法沒用,你知道什么叫樹的遍歷你就能理解viewTree解析過程。
而且在大家層次不齊的情況下,用算法打回同一層次,看看誰的邏輯性強(qiáng),代碼書寫風(fēng)格好,這是對(duì)面試篩選有好處的。
誰都會(huì)說,買菜要用高數(shù)嘛?但是人家會(huì)你不會(huì),那就是在面試上吃虧。
正題,我的刷題路程
劍指offer來入門
https://cyc2018.github.io/CS-Notes/#/README
里面有很多題,你在力扣評(píng)論區(qū)可以看到各種解法,建議多看各種解法,體會(huì)不同的思路
https://leetcode-cn.com/problemset/algorithms/?difficulty=%E7%AE%80%E5%8D%95
然后我推薦的是我頭條朋友的刷題筆記(可能近期三到五年內(nèi)都不會(huì)更新了)
https://juejin.im/post/6844904012987236359
刷題的方式,一定要自己動(dòng)手寫代碼,調(diào)試,運(yùn)行。
可以自己創(chuàng)個(gè)小庫(kù),督促自己提交。
https://github.com/lamster2018/DailyLeetCode
也順便把常見的設(shè)計(jì)模式復(fù)習(xí)了
https://www.runoob.com/design-pattern/design-pattern-intro.html
http://c.biancheng.net/design_pattern/
差不多刷完了基本的排序,遍歷,貪心,局部最優(yōu)等思想,也就有個(gè)一百來道題了。
此時(shí)面對(duì)面試,也就有個(gè)眼熟了。真心不建議采用突擊的方式,應(yīng)該要做一個(gè)長(zhǎng)期寫題的規(guī)劃。
4.學(xué)習(xí)總結(jié)
我把鎖相關(guān),線程相關(guān),handler機(jī)制等知識(shí),以題目入手,遞進(jìn)發(fā)散的方式做了一個(gè)平時(shí)我學(xué)習(xí)的索引。
Android線程學(xué)習(xí)索引
http://www.itdecent.cn/p/fb07e8b77eb1
我把常見的數(shù)據(jù)結(jié)構(gòu),分析源碼寫得比較好的文章,歸納了一個(gè)索引
Java學(xué)習(xí)索引
http://www.itdecent.cn/p/384ab2f83c60
接下來就是深入到app啟動(dòng),繪制渲染,AMS等問題做了一個(gè)集中索引
Android framework學(xué)習(xí)索引
http://www.itdecent.cn/p/1a333fa8e42d
然后是網(wǎng)絡(luò)
Android 網(wǎng)絡(luò)學(xué)習(xí)索引
http://www.itdecent.cn/p/2100897f6670
我自己的Android源碼閱讀
http://www.itdecent.cn/nb/35261090
我寫的面向面試的閱讀第三方庫(kù)筆記
http://www.itdecent.cn/p/6fa13048a6cf