5面阿里,4面騰訊,卻進了字節?Android程序狗開發三年9次大廠面試真實記錄

到今年7月,我已經工作了整整3年!記得還是2017年的夏天,我脫下了屬于大學時代的學位服,告別我的整個學生時代,當我找到第一份正式的工作時,就已經宣布我成為正式的上班族了!那個朝氣蓬勃的時代、也是一個屬于青春的年代。現在回味、無比悠長。

原諒我矯情了一會兒,現在進入正題。想知道阿里面了5次,騰訊面了4次的我,為什么會入職字節跳動嗎?看官,請你們接著往下看。

9面大廠的原因

我相信每一位軟件開發的畢業生都夢想著進入像BAT這樣一線大廠,你們都想著進入當然我也不例外,誰叫我們都是“同道中人”呢!

先說說我吧,雖然我不喜歡別人夸但是你們夸我還是有一點小驕傲的。雙非一本畢業,雖然談不上多么厲害但是也還行,別說讀研我是真的不喜歡讀書,讀研天天要背英語單詞難道你們不覺得煩嗎?我比較喜歡有邏輯性的事物,因為這樣在之后的大廠面試中算法題基本都答對了。

我吧,接觸編程接觸的比較早,在高一的時候因為我哥給我帶了一本自學C語言的書,我便開始沉迷在編程的海洋里,一蹶不振。到現在那本書我還沒有扔掉,現在有時間的時候都會看一看,不過現在看來里面的知識點太少了,適合剛起步的新手學習。對了這本書叫《C primer plus》,安利一下。

因為高中三年都熱愛著編程,所以我高考完以后報考的志愿只能是計算機這一方向,別人說大學生活都是豐富多彩的,我也信了高中老師的鬼話,說什么高中三年不要玩,好好學習等到上了大學隨便你玩,老師都不帶管你的。以至于到現在都還沒有女朋友,真氣死我了...

大學四年中,我自學過Java、Andorid、C++,到后來火熱的GO語言、AI,也有一定的了解,卻因為大學老師的一段話走上了APP的開發之路,因為當年抖音的爆火,無數短視頻APP橫空出世,他說:將來做Android的程序員肯定特別吃香,聽了老頭這話一入坑便是三年。

雖然現在也挺好,在字節能到稅后34K,但是我還是覺得,程序員需要的不是行情行業,需要的是實力和技術,只要你有硬實力,無論市場行情怎樣,走到哪都會公司企業接納你。內推不就是一個很好例子嗎?

5面阿里,4面騰訊的心路歷程

阿里和騰訊和字節一直是我追求目標,其實畢業前,我并沒有找到心儀的工作,只是找到了一家小型互聯網公司做Android開發(當然,是在面試完騰訊和阿里之后我才明白了我自身實力的不足)。

但是咱不能放棄,一次不行還有第二次,兩次不行還有無數次。起碼我得進他們的研發部看看他們的大牛到底有多厲害才能進得去那樣的大廠?

于是,我開始我的三年面試大廠之路;

三年,我卡死在無數面試題之下,挫敗了我也成就了我

我這個人最好的好處就是會在失敗中總結,面試遇到不會的題目我會在心中記下,面試結束以后再網上找答案,在記錄在我自己的學習筆記中。

比如像Android的音視頻,UI線程、view分發反向制約的方法、Future和microtask執行順序,Java的對象鎖和類鎖、生產者消費者(非阻塞式)我都會記下來。這也為我之后成功入職字節跳動做好了鋪墊。

一面(2018年10月秋招)

  1. 簡單介紹項目

  2. 了解哪些數據結構

  3. 了解哪些排序算法

  4. 堆排序

  5. LinkedList與ArrayList;HashMap擴容 ConcurrentHashMap

  6. TCP與UDP,區別及運用場景

  7. http是用的TCP還是UDP

  8. http與https的區別

  9. JVM內存模型(Static方法在哪個區)

  10. Activity生命周期,Activity啟動模式,Handler源碼

  11. 旋轉數組

二面(2019年3月春招)

  1. final、finally、finalize的區別

  2. 抽象類的成員變量與成員方法的繼承

  3. union與union all的區別

  4. MySQL的索引的實現

  5. B+樹查找的時間復雜度,數據結構

  6. 在瀏覽器輸入網址敲回車后經歷了什么

  7. 三次握手

  8. https的加密流程

  9. 對稱加密與非對稱加密原理(RSA、AES)

  10. 手撕DCL單例

  11. 還了解什么設計模式

三面(2019年四月春招)

  1. 動態代理的方法怎么初始化的

  2. cglib動態代理

  3. 三個線程wait,喚醒情況是什么樣的

  4. 最終是誰持有的activity,handler內存泄露(內存泄漏這點真的是無比幸運,剛好找到的視頻里面講過)

  5. handler的sendmessage和postdelay的區別

  6. arraylist和hashmap的區別,為什么取數快

  7. 差不多重復的和模糊的

四面(2019年9月秋招)

  1. stringbuilder 和stringbuffer區別

  2. lock和syncrognized原理區別,適合什么場景。

  3. 實現生產者,消費者

  4. handler原理,是如何實現延時的。

  5. 一個activity啟動另外一個activity的生命周期。

  6. 反轉鏈表

  7. 歸并排序

  8. 快速排序

五面(2020年5月春招)

  1. 抽象類和接口解釋一下。

  2. 講講類的加載機制。

  3. jvm的內存回收機制,那你了解哪些內存回收算法。主要用的那個算法。

  4. 抽象類和接口的區別。

  5. Activity有哪些啟動模式

  6. Fragment的生命周期和Activity有哪些不同,執行順序解釋一下。(這個回答的有點迷,只能說大體是那么一回事)

  7. 線程和服務的區別,解釋一下。

  8. 事件分發機制講解一下,view中有個onFilterTouchEventForSecurity還是啥,小哥哥說是view中獨有的一個方法,你了解嗎?(英語水平不過關,沒聽清是啥方法,表示不清楚。)

  9. 充值模塊如何進行的封裝

  10. handler的機制講解一下。

  11. 模板方法講解一下(腦袋抽了,記不起來)

  12. 如何保證應用的安全性,做了哪些處理。

  13. 加固的原理了解嘛。

騰訊5面面經

一面

  • 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 方面的

二面

  1. 單例設計模式都寫寫,靜態內部類是怎么保證線程安全的?

  2. synchronized 底層實現原理,ReentrantLock 公平鎖與非公平鎖。

  3. 主線程等待所有線程執行完畢,再執行某個特定任務怎么實現?原理和源碼看過沒?

  4. 自定義 view 的一般流程,要注意些什么如何優化,點擊事件和長按時間分別是怎么實現的?

  5. 四種啟動模式,在源碼分析中的原理是怎樣的?

  6. 講講 bindService 的過程,你當初是怎么優化后臺服務進程的?

  7. 開發中你都用到了哪些設計模式?說說當時具體的場景。為什么你要用方法工廠,另外兩種呢?

  8. RxJava 在使用過程中碰到了某些不友好的錯誤一般怎么解決?發現了內存泄露一般怎么解決分析,有沒有碰到過系統服務內存泄露的問題?

  9. 你們用的 okhttp ?那你有沒有做過一些網絡優化呢?比如弱網環境。

  10. 給你個數 1 吧,比如 1000011 里面有幾個 1 ?

  11. 快排了解不?最壞的情況是怎樣?如果有大量重復數據怎么優化?

三面

  1. 講講 handler 的底層實現原理? 這么簡單?問到碗里來了,后面漸漸說到延遲消息是 nativePollOnce 來處理的,在 6.0 以上用的是 epoll 方式來監聽文件描述符。接著問道了為什么要用這種方案?它跟 poll 和 select 比起來有哪些優勢?它是怎么監聽的你看過它的內部實現原理沒?反正感覺很難受了。

  2. 說說你做的日志記錄優化? 把第一輪面試的又講了一通,你在每個文件的最后寫入了當前內容的大小,你有沒有想過如果文件被破壞的情況?這種異常情況怎么處理?后面還問到了加密和壓縮。

  3. 你看過 binder 驅動的源碼,說說他的內存映射過程,說說客戶端等待服務端處理返回的流程,如果要跨進程傳遞大內存數據你具體會怎么做?簡單寫一寫吧。

  4. 在公司做過哪些優化? 內存優化,啟動優化,網絡優化,包體積優化,具體說說包體積優化。我提到了包體積優化不僅僅是優化了包的大小,包體積太大從安裝的那一刻開始,我們的應用就可能比較慢了,因為 pms 會去拷貝解壓解析我們的 apk 安裝文件,會去優化我們的 dex 等等,包體積太大還會影響我們的啟動速度。然后就巴拉巴拉說具體怎么做,問到了為啥混淆資源能減少包體積大?。磕惝敃r優化的時候效果是怎樣的減少了多少?

  5. 開發過程中遇到的一些最難解決的問題? 提到了動態修復替換加載 so ,那你知道怎么修復 class 嗎?怎么修復資源呢?后面又聊到了插件化,提到了 360 用的是借尸還魂,那如果我們在插件的 Androidmanifest.xml 中注冊了其它屬性該怎么解決,資源方面怎么處理?

四面

  1. 先談談自己的項目

遠程數據庫傳輸圖片到app端,我們當時將圖片轉換成base64存在數據庫中,然后傳到app端,app解析base64獲得bitmap,直接顯示然后面試官瘋狂diss 為什么要將圖片轉成base64再傳(二面也diss這個,問是否可以直接傳圖片地址)

  1. 講一下http連接的框架

  2. retrofit原理

  3. 什么是動態代理

  4. 自定義view

  5. 繼承viewGroup的情況

  6. activity的生命周期

  7. 對handler機制的了解

字節跳動面試題

一面

  1. Jvm虛擬機

  2. messageQueue會不會阻塞ui線程

  3. 對象鎖和類鎖

  4. 之字形打印樹

  5. 還有其他的記不清了,主要是我對二面印象太深刻了

二面

  1. dart是值傳遞還是引用傳遞、

  2. Widget和element和RenderObject之間的關系

  3. widget的root節點

  4. mixin extends implement之間的關系

  5. jvm內存模型

  6. Future和microtask執行順序

  7. dart中…的用法

  8. await for

三面

  1. linux網絡模型

  2. b+樹

  3. 阻塞隊列

  4. redis和MongoDB的區別。幾個概念對比,還有底層實現。

  5. 算法題: mergeksortedlist,時間復雜度如何?

  6. HashMap 如果一直 put 元素會怎么樣?hashcode 全都相同如何?equals方法都相同 如何?

所以的面試題和答案都被我整理成PDF,這也為我入職字節跳動提供的保證,近期需要面試的,需要面試題參考的小伙伴(Github領取)PDF資料

文末

最后希望小伙伴們都能有個好的歸宿,找到高薪的工作,拿到自己滿意的offer。一起朝著大廠努力前進,共勉!喜歡的小伙伴可以拿出自己的小手指點個贊喲(#.#)

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。