
每年到了秋招季總會有不少準備投 Android 方向的學弟學妹來問我同一件事歡聚時代YY當年的校招筆試到底考了什么這份 2017 年的 Android 工程師類 A 卷在當年可以說是很多安卓求職者人手一份的“經典參考題”哪怕放到現在它考察的知識框架依然沒過時——Java 基礎、Android 四大組件、Handler 機制、性能優化、設計題幾乎覆蓋了客戶端崗位筆試的所有核心模塊。我當年備考時就反復刷過這類的題目也幫助過不少人復盤今天就用一篇文章把這份卷子背后的考點、解題思路和備考方法完整拆一遍。無論你是正在準備暑期實習的在校生還是剛轉行想做 Android 開發的初學者這份復盤都會比單純背題庫有用得多。1. 整體認知與出題思路拆解1.1 一份校招筆試卷子能看出什么先說一個很多人忽略的事實筆試不是面試的“前菜”它本身就是一道篩選漏斗。歡聚時代作為當年移動直播和社交賽道里非常有代表性的公司校招筆試的出題風格其實很有指向性——它不追求把每個知識點都考到最偏最難的角落而是特別看重三件事基礎扎實度、代碼手寫能力、以及對 Android 生態整體理解。A 卷這類題目通常由四類組成單選題/多選題、簡答題、代碼題和開放設計題。單選題說難不難但陷阱集中在對基礎概念的混淆上簡答題則是拉開差距的地方Handler、Binder、事件分發這些高頻點幾乎必考代碼題考察的不只是會寫還要寫得對、寫得穩最后一兩道開放設計題才是真正把“只會背 API”和“真正做過項目”的人區分開的題目。所以這份卷子表面上是考知識點本質上是在問你你有沒有真正從“會用 Android”走到“理解 Android”這一步。這也是我把這份 2017 年 A 卷拿出來復盤的原因——雖然技術棧年年更新但底層原理和考察方法論是穩定的弄懂這套題你再去面對其他大廠的筆試也會順手很多。1.2 從歡聚時代 A 卷反推考察優先級我結合當年很多參加筆試的同學反饋整理出一份比較靠譜的考點優先級表。你可以把它當成復習地圖來用優先級考點模塊常見出題形式考察目的高Java 基礎與集合單選、多選、代碼題語言功底是否扎實高Android 四大組件單選、簡答是否理解組件運行機制高Handler 消息機制簡答、代碼是否理解主線程與子線程協作高View 繪制與事件分發簡答、場景題是否有 UI 層面的實戰經驗中網絡與圖片加載簡答、設計是否熟悉框架原理與選型中JVM 與并發單選、簡答是否了解內存與性能問題中算法與數據結構手寫代碼基礎編碼能力中低Binder 與進程通信簡答是否理解系統底層運行機制低冷門 API 與版本特性單選平時積累面是否夠廣你會發現當年這份卷子并沒有像后來一些大廠那樣瘋狂堆砌“超綱題”而是老老實實地把日常開發中最常用的東西拿出來深挖一遍這一點直到今天都很值得后輩學習。真正見功底的地方不在題目本身而在于你能不能把答案寫透。1.3 考場上的時間分配怎么做提到時間分配可能有人覺得沒必要但我在復盤過大量筆試經驗后可以負責任地說時間分配直接決定你能不能做完。A 卷這種 90 分鐘左右的題量合理的分配大致是選擇題 20 分鐘、簡答題 30 分鐘、代碼題 25 分鐘、設計題 15 分鐘。選擇題如果一眼不能確定答案先跳過不要戀戰。尤其要注意簡答題的篇幅控制。很多人習慣性地把簡答題寫成大作文結果后面的代碼題和設計題根本沒時間寫。面試官閱卷時并不會為洋洋灑灑但抓不住重點的長篇大論加分相反條理清晰、關鍵詞到位、代碼正確才是王道。說白了筆試拼的不僅是知識量還有你在有限時間里輸出關鍵信息的能力。2. 核心考點解析與答題要點2.1 四大組件不能只背生命周期Android 工程師筆試里四大組件幾乎是必考項。但要注意2017 年 A 卷這類題目很少直接問“Activity 有哪些生命周期方法”這種送分題而是喜歡換著法子考比如“Activity A 啟動 Activity B兩者分別回調哪些方法”、“onSaveInstanceState 在什么時候被調用”、“啟動模式 standard、singleTop、singleTask、singleInstance 分別適合什么場景”。答題時不要只羅列方法名要答出“為什么”。以啟動模式為例standard 模式默認每次啟動都會創建新的實例適合大多數普通頁面singleTop 解決的是棧頂重復創建的問題比如通知欄點擊跳轉singleTask 會讓 Activity 在棧中只保留一個實例適合 App 主頁這種場景singleInstance 更加極端整個系統只有一個實例常用于來電界面這類需要全局唯一的場景。這樣組織答案比單純寫一句“啟動模式有四種”有說服力得多。另外Service 和 BroadcastReceiver 的考察頻率也不低。要注意記住Service 默認運行在主線程里面不能直接做耗時操作onStartCommand 的返回值在不同場景下的意義廣播分為靜態注冊和動態注冊8.0 之后靜態注冊受到了很多限制這也是一個很好的延展點能體現出你關注版本演進的習慣。2.2 Handler 消息機制筆試常青樹我可以毫不夸張地說十份 Android 筆試卷里至少有八份會寫“請簡述 Handler 的工作原理”。這份 A 卷也一樣。哪怕今天已經進入 Kotlin 和協程時代Handler 依然是 Android 源碼級的核心知識點因為它直接關系到線程間通信、主線程消息循環、以及 ANR 問題的理解。答題的核心框架就三句話Handler 通過 sendMessage 發送消息消息進入 MessageQueue 隊列Looper 通過 loop() 方法不斷從隊列里取出消息取出的消息最終回調到 Handler 的 handleMessage 方法中并且這個過程發生在 Looper 所在的線程。把這三點答清楚框架分就到手了。但想拿高分還需要補充幾個細節主線程的 Looper 是在 ActivityThread 的 main 方法里通過 Looper.prepareMainLooper() 和 Looper.loop() 啟動的子線程里要用 Handler必須先 Looper.prepare()ThreadLocal 在 Looper 中扮演的角色是保存每個線程獨有的 Looper 實例以及 handler.post 和 handler.sendMessage 本質上是一回事——post 的 Runnable 最終還是被包裝成 Message 處理的。這些細節一旦寫出來就證明你不是背過一篇博客而是真正讀過源碼。2.3 集合與并發一道題能挖出很多內容Java 基礎部分集合類和并發是筆試的重頭戲。當年這份卷子里的選擇題經常在 HashMap、HashSet、ArrayList、LinkedList 這些類的底層實現和線程安全性上做文章。比如問你 HashMap 和 Hashtable 的區別、ArrayList 和 LinkedList 的適用場景、ConcurrentHashMap 為什么比 Hashtable 并發度高。這里要特別提一下 HashMap。Jdk 1.7 和 1.8 的底層實現是不一樣的1.7 是數組鏈表1.8 是數組鏈表紅黑樹當鏈表長度超過 8 且數組長度超過 64 時會樹化。很多人被問到這里就卡住了尤其是“為什么鏈表轉紅黑樹的閾值是 8”這種問題如果沒看過源碼很容易懵。實際上這個數字是基于泊松分布的統計結果在負載因子 0.75 的情況下鏈表長度達到 8 的概率已經低到千萬分之一級別所以這個閾值是時間和空間的平衡取舍。并發方面synchronized 和 volatile 的區別、線程池的核心參數corePoolSize、maximumPoolSize、keepAliveTime、workQueue、RejectedExecutionHandler也是高頻考點。線程池這個問題我建議按照“為什么要用線程池、核心參數是什么、執行流程是怎樣的、如何配置”這個順序來答邏輯鏈條完整面試官聽起來也舒服。3. 實操過程與代碼題實戰參考3.1 手寫單例模式寫出讓面試官挑不出毛病的版本代碼題里手寫單例出現的概率非常高。但別高興太早大多數人寫的都是簡單的懶漢式這種答案在筆試里只能拿基礎分。想拿高分你要能寫出 DCL 雙重檢查鎖版本并且把 volatile 關鍵字的作用解釋清楚。核心代碼如下public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance null) { synchronized (Singleton.class) { if (instance null) { instance new Singleton(); } } } return instance; } }為什么這里必須加 volatile這一點一定要答上來。因為 instance new Singleton() 并不是一個原子操作它實際上分三步走分配內存、初始化對象、將引用指向內存地址。在并發場景下如果不加 volatile第三步可能被指令重排到第二步前面導致另一個線程拿到一個“雖然不為 null 但還沒有初始化完成”的對象。用了 volatile 之后內存屏障會禁止這種重排從根源上杜絕問題。另外要補充的一點是如果是在現代 Android 開發中官方更推薦用 Kotlin 的 object 關鍵字或者枚舉來實現單例這個問題也可以作為擴展話題寫進答案里展示你對新技術方案的了解。但筆試時能把 DCL 寫對并且解釋清楚 volatile 的必要性已經足夠和大多數人拉開差距了。3.2 鏈表反轉與常用算法模板算法題方面這份卷子大概率會出現鏈表相關的題目。鏈表反轉是一個經典中的經典它考察的不是你記不記得住代碼而是你對指針操作的熟悉程度。完整的迭代寫法如下public ListNode reverseList(ListNode head) { ListNode prev null; ListNode curr head; while (curr ! null) { ListNode nextTemp curr.next; curr.next prev; prev curr; curr nextTemp; } return prev; }筆試時除了寫對代碼建議在代碼旁邊用一兩句話標注你的思路比如“使用三個指針依次改變當前節點的 next 指向”。因為筆試閱卷速度很快一段清晰的注釋會讓面試官第一時間判斷你的代碼邏輯是正確的比讓他慢慢讀代碼省力得多。除了鏈表反轉常見的算法模板還應該準備二分查找、快排/歸并排序、二叉樹前中后序遍歷、廣度優先搜索BFS、動態規劃的入門題目如爬樓梯、最長公共子序列。不需要刷很多難題但基礎題必須做到閉著眼睛能寫出來。記住一個原則校招筆試的算法題不是為了難倒你而是為了確認你具備基本的編程素養所以“寫得對、寫得穩”比“寫得快”重要。3.3 如何組織簡答題答案才能拿高分簡答題是最容易拉開分數差距的題型但也是很多人最不會答的題型。我復盤過大量的筆試答卷發現低分答案和高分答案的區別通常不在于“知道多少”而在于“怎么組織”。低分答案的特點是“流水賬式羅列”想到什么寫什么寫完自己也心里沒底高分答案則是“結論先行、層次分明、有補充細節”。我自己推薦一個很實用的框架總分總。第一步先一句話給出核心結論比如“Handler 機制的本質是生產者-消費者模型”第二步分點展開比如“第一消息的發送和入隊第二Looper 的循環取出第三最終的 dispatchMessage 分發”第三步補充一句進階理解比如“整個機制的核心是避免在子線程直接操作 UI將線程切換的任務交給消息隊列完成”。這樣下來一道簡答題不僅字數達標而且邏輯脈絡清晰閱卷人掃一眼就能 get 到你的重點。平時練習的時候也可以這么做拿到一個知識點不要急著背別人的答案而是先自己按“結論-分點-補充”的方式寫一遍再對照資料看看漏了什么。這樣練習過的知識點記憶深度和考場上臨場組織的速度都會明顯好于直接背書。4. 常見問題與備考踩坑記錄4.1 筆試中的典型失分點我在看別人模擬筆試時發現很多人的失分并不是因為不會而是因為踩了各種低級坑。這里整理一份高頻失分點清單你可以對著自查選擇題沒有看清“多選”還是“單選”導致多選少選丟分這個在 A 卷這種混合題型里尤其常見。簡答題只答了結論沒有展開過程比如寫了“Handler 用于線程切換”就停筆完全沒提 Looper、MessageQueue、ThreadLocal 這些關鍵詞。代碼題沒有注意邊界條件比如反轉鏈表沒有處理 head 為 null 的情況或者循環里沒有判空導致空指針。設計題沒有體現“技術選型”意識想到什么寫什么完全沒有對比方案也沒有說明為什么采用這個方案。字體潦草、排版混亂導致明明寫對了的內容面試官看不清楚這種丟分最冤。針對以上問題我的建議很直接平時做題就養成習慣把題干里的關鍵詞圈出來寫完答案后花 10 秒檢查一遍邊界條件代碼題注意寫注釋。筆試拼的是穩定輸出不是靈光一現。4.2 復習多久才能從容應對這是一個被問了無數次的問題。我只能說根據不同基礎差異很大。如果是從零開始準備我建議給自己留出至少三個月的時間并且把時間切成三個階段第一個月主攻 Java 基礎和 Android 四大組件同時簡單過一遍 Handler、Binder 這些高頻底層原理第二個月開始刷題重點是選擇題和簡答題的專項訓練同時每天保持兩道手寫算法的節奏第三個月進入綜合模擬階段掐時間做整套卷子并且把開放設計題的思路好好打磨一遍。如果你是已經有項目經驗的在校生時間可以壓縮到六周左右。但不管是三個月還是六周原則都一樣前期求廣、后期求深。前期先把知識樹鋪滿避免出現“完全沒聽過”的知識盲區后期再針對自己薄弱的部分精細加工。記住筆試中的大部分題目都是基礎題的變體與其追求做十套新題不如把一套經典題反復吃透包括今天拆解的這份 A 卷。4.3 筆試結束后如何銜接面試筆試通過只是第一步很多人忽略了筆試和面試之間的銜接。我的經驗是筆試結束后立刻把整張卷子復盤一遍哪些題有把握、哪些題模棱兩可、哪些題完全不會。這份自我復盤就是你準備面試的第一手素材。因為面試官常常會在看到你的筆試答卷后專挑你答得不好的地方展開追問——如果筆試時 Handler 那道題寫得很含糊面試時大概率會被追問 Looper 和 MessageQueue 的實現細節。所以考完筆試不等于解脫反而是新一輪復習的開始。我的做法是考完當天趁記憶還熱著把所有不確定的題目整理到一個文檔里然后逐個查資料、補充知識、重新組織答案。這樣等面試通知來了你手里已經有了一份針對性的高頻問答清單比臨時抱佛腳要踏實太多。這也是為什么我一直建議大家不要把筆試和面試割裂看待你完全可以把每一場筆試都當作對面試的提前押題。5. 開放設計題的答題思路5.1 圖片加載框架怎么答才顯專業開放設計題是 A 卷里最有意思的部分也是最容易拿到高分但也最容易偏題的部分。我印象比較深的一類題目是“如果讓你設計一個圖片加載框架你會怎么設計”。這種題目沒有標準答案但面試官心里其實有一套隱含的評分標準核心是考察你有沒有完整的架構意識。我的答題框架通常是這樣首先明確需求圖片加載框架要解決什么問題——異步加載、內存緩存、磁盤緩存、圖片壓縮、生命周期管理、避免 OOM。然后給出整體架構分層最底層是網絡加載模塊負責從網絡拉取圖片數據往上一層是解碼模塊負責把字節流解碼成 Bitmap并且做采樣壓縮再往上是緩存模塊采用 LruCache 做內存緩存DiskLruCache 做磁盤緩存最上層是對外 API提供簡單的 load 方法給調用方使用。最后補充擴展點比如三級緩存策略、圖片加載中的線程池設計、ImageView 復用時的 tag 處理。答題時如果能把“三級緩存內存、磁盤、網絡”這個概念完整講出來就說明你有基本的設計能力如果再能補充“如何應對列表快速滑動導致的圖片錯亂”比如用 ImageView.setTag 記錄 URL在加載回調中進行匹配校驗那這道題基本就穩了。這種細節才是面試官真正想聽到的實戰經驗。5.2 啟動速度優化這類性能題怎么展開性能優化相關的設計題也經常出現尤其是 App 啟動速度優化。這個問題在 2017 年的筆試題里出現過放到今天依然不過時因為啟動速度是用戶對 App 的第一感知。答這道題時我建議從兩個維度展開一個是“如何排查”一個是“如何優化”。排查方面可以利用 Traceview、Systrace 或者后來的 Profiler 工具來定位耗時方法優化方面核心思路是把啟動過程中的耗時操作往后延遲。具體的優化手段包括減少 Application 中不必要的初始化把耗時但非必需的 SDK 放到子線程去初始化用啟動閃屏頁快速響應用戶點擊在后臺再加載主界面資源避免在首幀繪制時執行太復雜的布局和 Measure/Layout 邏輯使用懶加載的方式處理 ViewPager 等多頁面組件。這類題目最忌諱的寫法是“我覺得應該優化布局、優化啟動動畫”這種既空泛又沒有操作性的答案。你需要做到的是把優化手段分類說清楚哪些是文件層面的比如類加載、資源加載、哪些是代碼層面的比如初始化順序、哪些是布局層面的比如層級深度分類越清晰你的答案就越專業。5.3 答設計題最容易犯的三個錯誤開放設計題的高分和低分之間差距往往不是知識量而是答題習慣。我總結了三個最容易犯的錯誤大家可以引以為戒第一只寫方案不寫理由。很多人上來就寫“用三級緩存”但完全不解釋為什么需要三級緩存、每一級緩存的容量限制依據是什么。面試官看到這種答案只會覺得你在背概念而不是真的理解。第二不考慮邊界條件。比如設計圖片加載框架時完全沒提內存不足時該怎么辦、圖片超大時會不會 OOM、網絡異常時怎么處理。好的設計題答案一定要包含異常情況的兜底策略這才是真實開發中最重要的能力。第三答案沒有取舍意識。設計題本質是“在約束條件下做權衡”比如緩存策略中內存緩存越大加載越快但占用內存也越多如何在性能和資源之間取舍如果答案里完全沒有“權衡”兩個字這道題基本就停留在及格線附近了。記住開放設計題考察的是工程思維不是記憶力。你不需要把 Guilde 或者 Coil 的源碼背下來但你需要理解一個框架為什么這樣設計、它解決了什么問題、有沒有更好的方案。帶著這種思維去答題你的答案才能讓面試官眼前一亮。6. 備考節奏與個人心得走到這里相信你對這份 2017 歡聚時代 Android A 卷的整體面貌已經有了比較完整的了解。最后再說一點我個人帶人備考時最深的一個體會千萬不要把筆試當成一場“知識的搬運”。考場上你寫的每一道題其實都在向面試官展示你的思維方式、你的知識組織能力、你面對未知問題時的應對策略。這些能力比任何一份“面經”都更有用。如果只讓我從這篇復盤里提煉一條最重要的建議那就是不要背題去理解題。舉個例子你與其花時間把“Handler 的原理”的標準答案背得滾瓜爛熟不如自己動手在 IDE 里看一遍 MessageQueue 的源碼親手梳理一遍消息從發送到處理的全流程。一旦你真正理解了不管面試官換什么角度問你都能接得住。反過來如果你只是背答案一旦被追問“Looper.prepare 和 Looper.prepareMainLooper 有什么區別”瞬間就會露餡。備考 Android 筆試這條路確實有點長也有點辛苦但每一步都不會白走。把這份 2017 年的 A 卷當作一面鏡子照出自己的薄弱點再用我上面講的方法把這些點逐個補強你會發現當你真正站到面試官面前時你已經不再是那個只會背書的求職者而是一個有能力解決問題、有自己思考的工程師。這才是筆試真正想篩選出的人。