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