1. Android大廠面試經驗分享(OPPO,位元組,華為,阿里)
我是從小公司跳出來的,最終入職OPPO,說實話這段時間的經歷讓我深深地感受到,我們為跳槽做的一些臨時抱佛腳的提升跟那些大佬的沉澱比起來太渺小了。我們都知道找資料學習、刷面試題,但也許只能應付這一次的面試,後面還是會技術發愁,那些短時間背下來的東西遲早會忘掉, 大家還是做好長期提升自己的准備,好好沉澱的東西最後才是屬於自己的。
說說當時的面試過程,我是內推獲得的面試機會,很感謝當時幫我內推的兄弟,總共三輪面試,兩輪技術,一輪HR面,當天面試結束。
我10:10分到的公司,10:30開始面試,第一輪面試將近一個小時,聊的點我基本上都答得上來,自我感覺良好。然後面試官讓我等一下,他去叫他們老大來給我二面,我等了有二十幾分鍾吧,二面有一個多小時,這次問的比較深,有些地方答的有些嗑吧,總體來說我自己是滿意的。HR面約到下午了,整個流程下來每輪面試官都讓人感覺很不錯,我自己做的准備也讓我面試感覺下來很爽。
我把面試遇到過的以及自己學慣用到過相關內容都整理到一起了,方便自己進行復盤和後續的查漏補缺:
一、 java基礎
1.1 靜態內部類和非靜態內部類的比較
1.2 多態的理解與應用
1.3 java方法的多態性理解
1.4 java中介面和繼承的區別
1.5 線程池的好處,詳解,單例(絕對好記)
1.6 線程池的優點及其原理
1.7 線程池的優點(重點)
1.8 為什麼不推薦通過Executors直接創建線程池
1.9 不怕難之BlockingQueue及其實現
1.10 深入理解ReentrantLock與Condition
1.11 Java多線程:線程間通信之Lock
1.12 Synchronized 關鍵字原理
1.13 ReentrantLock原理
1.14 HashMap中的Hash沖突解決和擴容機制
1.14 Java並發
1.15 Java虛擬機
1.16 JVM常見面試題
1.17 JVM內存結構
1.18 類載入機制/雙親委託
二、 Android基礎
2.1 Activity知識點(必問)
2.2 Fragment知識點
2.3 Service知識點
2.4 Intent知識點
2.5 數據存儲
三、UI控制項篇
3.1 屏幕適配
3.2 主要控制項優化
3.3 事件分發與嵌套滾動
3.4 動態化頁面構建方案
四、網路通信篇
4.1 網路協議
五、架構設計篇
5.1 MVP架構設計
5.2 組件化架構
六、性能優化篇
6.1 啟動優化
6.2 內存優化
6.3 繪制優化
6.4 安裝包優化
七、源碼流程篇
7.1 開源庫源碼分析
7.2 Glide源碼分析
7.3 day 20 面試題:Glide面試題
7.4 聊一聊關於Glide在面試中的那些事
7.5 面試官:簡歷上如果寫Glide,請注意以下幾點…
7.6 Glide OOM問題解決方法匯總
7.7 LeakCanary源碼分析
7.8 OkHttp源碼分析
7.9 okhttp連接池復用機制
7.10 okhttp 流程和優化的實現
7.11 一篇讓你受用的okhttp分析
7.12 OkHttp面試之–OkHttp的整個非同步請求流程
7.13 OkHttp面試之–HttpEngine中的sendRequest方法詳解
7.14 OkHttp解析大總結
7.15 Okhttp任務隊列工作原理
7.16 Android高頻面試專題 - 架構篇(二)okhttp面試必知必會
7.17 Android 網路優化,使用 HTTPDNS 優化 DNS,從原理到 OkHttp 集成
7.18 Retrofit源碼分析
7.19 RxJava源碼分析
7.20 RxJava原理與源碼分析
7.21 RxJava如何進行線程切換的?
7.22 Rxjava內存泄漏防止方案——RxLifecycle,AutoDispose,RxLife框架
7.23 Tinker源碼分析
7.24 ARouter源碼分析
7.25 Android框架層源碼解析
7.26 演算法設計
八、新技術篇
8.1 實戰問題篇
九、面試篇
9.1 開源文檔
9.2 面試文獻
以上就是我的學習和面試積累,有自己面試經歷過的,也有整理的一些大廠面試題,篇幅有限,具體內容就不展示了,我已經整理成文檔了。
還是開頭說的,僅靠面試期間臨時抱佛腳和刷題對自身發展不是長久之計,做好長期提升的規劃,好好沉澱每一次的學習和面試經歷,把這些最終都轉化成屬於自己的東西才是實質上對自己最有用的。
2. 面試時,問哪些問題能試出一個 Android 應用開發者真正的水平
首先,面試官們一定要知道,每個人由於經歷不同,擅長的方向是千差萬別的,所以一定不要抓住自己擅長的某個方面去問的很深,覺得「如果連這個都不會還算毛程序員啊」。
所以我問問題的時候,往往是「兩步走」的循環:
1. 問他做過什麼,如果有成品的話,我能看看更好。
2. 從他做過的東西裡面,找到問題進行提問。具體的問題要看情況,可以是界面或效果的實現方式、相關bug的排除、該部分原理的分析。
舉一次面試時的對話作為例子吧:
我先開始:
「這份簡歷和網上投過來的那份是一樣的吧?」
「嗯,應該是一樣的。」
「嗯好。你在之前的團隊的位置是什麼?」
「中高級吧。」
「具體的工作呢?」
「寫框架,讓新人比較容易上手,能夠輕松工作。」
「你說的框架具體包括什麼呢?」
「一些會共用的東西,寫出來可以讓新人就算是剛來也能很好的完成工作。」
「聯網是你封裝的嗎?」
「是。」
「你們聯網用的是什麼?」
「就是……安卓自帶的……HttpClient。」
「直接用的?」
「嗯。」
「那你們的網路請求是怎麼做的非同步呢?」
「嗯……用Handler嘛,還有AsyncTask。」
「能具體一點嗎?」
「嗯……就是……額……」
「例如什麼情況下用Handler,什麼情況下用AsyncTask,你是怎麼決定的呢?」
「嗯……」
「或者說,他們有什麼區別呢?谷歌為什麼要造他們兩個出來,而不是只造一個呢?」
「區別……區別……他們肯定是有區別的,不然谷歌不可能造兩個。嗯……」(到這里,這個問題就可以結束了。評級減一。)
「這樣吧,你的簡歷上提到『熟悉大圖片的載入』,能說一下大圖片載入有什麼需要注意的嗎?」
「緩存嘛。」
「緩存?」
「嗯,大圖片的載入不就是ListView裡面的大圖片載入嗎?要防止內存溢出。」
「ListView裡面一定是大圖?」
「嗯……」(不了解的東西卻說自己熟悉,評級減一。繼續順著問。)
「那麼ListView中圖片的緩存你是怎麼做的呢?」
「三級緩存嘛。」
「哪三級?」
「如果內存裡面有,就用內存裡面的;如果沒有就用本地的;如果本地也沒有就從網路上取。三級。」
「網路上的也叫緩存?」
「啊。你可以把他看作緩存,也可以不看作緩存嘛。」(這個……)
「內存緩存你是怎麼實現的?」
「用的一個HashMap。」
「直接用的HashMap嗎?」
「嗯……嗯。」
「直接用HashMap的話,怎麼防止你剛才提到的內存溢出呢?」
「你可以用軟引用嘛。」(首先答案有問題,另外當聽到關鍵詞「你可以」,多數情況下這個問題也可以結束了——八成是不會,僅僅聽說過。不過出於謹慎還是繼續問了)
「軟引用就能防止內存溢出嗎?」
「還有……還有谷歌出的一個叫LRUCache的。」(迴避正面回答,確認他是不會。這個問題結束。評級減一。到此就再沒必要聊下去了。)
然後簡單過渡一下,就結束了面試。
所以你看,只需要簡單提問,然後接著對方的回答繼續往深了問,就什麼都問出來了。
--------------------------------------------------------------------------------
評論中有人問到這次面試中我沒有問完的問題的答案,那簡單就說一下,想了解更多還請自行谷歌。
Handler和AsyncTask:這倆類都是用來實現非同步的,其中AsyncTask的集成度較高,使用簡單,Handler則需要手動寫Runnable或者Thread的代碼;另外,由於AsyncTask內部實現了一個非常簡單的線程池,實際上是只適用於輕量級的非同步操作的,一般不應該用於網路操作。我問他Handler和AsyncTask的區別,一方面是因為他說用AsyncTask聯網,因此我認為他對AsyncTask並不熟悉;但更重要的是在我問他實現非同步的具體手段的時候,他同時提到了Handler和AsyncTask——用這種「混搭」的使用方式來寫聯網框架,就算不考慮AsyncTask的可用性,也顯得非常怪異,這聽起來更像是在「列舉Android實現非同步操作最常用的類」,而非「講述實現網路非同步操作的具體方式」。也就是說,我聽了這句話後開始懷疑他封裝過聯網框架這件事的真實性。但我只是懷疑,並不確定,因此接著問了我想問的。
圖片緩存:大多數情況下,內存中使用LRUCache是最合適的。如果用HashMap來實現,不是不可以,但完全沒必要嘛!需要注意在合適的時候釋放緩存。至於具體怎麼釋放,我沒考慮過,但用軟引用的問題在於,你很難控制緩存的大小,也就是說,只有等到你的內存快要撐爆,你的圖片緩存才會被回收。是不是感覺傻傻的?
對於初級和中級工程師,我更傾向於考慮對方的學習能力,也就是你對於自己所做過的東西是否足夠了解,而非要求你那裡都強,因為就像我開頭說的,每個人由於經歷不同,擅長的方向是千差萬別的,我不喜歡挑別人的軟肋問。只要你學習能力強,我就安全感滿滿噠!