
做了這么多年iOS開發和校招輔導我一直覺得筆試是候選人最容易被誤判的一環。代碼能力在線但基礎概念含糊或者刷題刷得太泛沒抓到重點都會在筆試卷上直接暴露出來。B站2020校園招聘的這套iOS方向筆試卷二屬于典型的大廠移動端校招筆試風格覆蓋了Objective-C與Swift底層機制、內存管理、多線程、網絡、UI事件傳遞、架構設計等核心模塊。這篇文章就專門拆一拆這套卷子背后的考察意圖、高頻考點和解題思路給正在準備iOS校招筆試的人一份可以直接照著復習的清單。這套卷子適合誰看主要是兩類人一類是準備投遞B站或其他中大型互聯網公司iOS崗位的應屆生另一類是工作一兩年后想系統梳理iOS基礎、準備跳槽的初級開發。不管你是哪種只要把下面這些考點吃透筆試環節基本不會翻車。1. 從一張筆試卷看B站的校招篩選邏輯1.1 這套卷子到底想篩什么樣的人先聊一個很多人忽略的問題B站這類公司的校招筆試卷并不是為了考倒你而是為了在幾千份簡歷里快速定位“基礎扎實、有工程思維、能直接上手干活”的人。所以你看這套iOS卷子題目雖然覆蓋范圍廣但每一道題背后都對應著一個實際開發中會遇到的場景。比如內存管理這塊考察循環引用和Auto Release Pool對應的是日常開發中寫閉包、使用NSTimer、處理圖片加載時最容易埋的坑。再比如多線程部分考察死鎖對應的是主線程同步操作、并發隊列嵌套這類線上事故高發場景。也就是說筆試卷本質上是在模擬“一個新人入職后會不會寫出讓線上崩潰的代碼”這件事。明白了這個邏輯復習方向就清晰了不是去背零散的知識點而是要理解每個考點在真實業務里的觸發條件。這樣即使題目換個馬甲你也能一眼看穿它考的是哪塊知識。1.2 題型分布與答題節奏建議根據B站這套筆試卷二的常見結構題目大致分三類單選多選、簡答題、編程題。選擇題考察的是知識面廣度和概念準確性簡答題考察表達能力和原理理解深度編程題則直接檢驗手寫代碼的基本功。我建議的答題節奏是選擇題控制在25分鐘內遇到拿不準的不要死磕先標記跳過。簡答題每道控制在10分鐘左右核心是“結論先行、再說原因、最后補個例子”。編程題留足40分鐘先理清思路再動筆哪怕不能完整跑通也要把關鍵邏輯和邊界條件寫清楚。這里有一個很重要的心得校招筆試的閱卷人通常是iOS組的技術骨干他們看卷子時最在意的是“這個人有沒有自己的思考”而不是“答案和標準答案一字不差”。所以簡答題千萬不要只寫一句話哪怕你對這個知識點只有七八成把握也要把相關的上下文、觸發場景、解決思路都鋪開寫讓閱卷人看到你的分析過程。2. 核心考點拆解語言機制與內存管理2.1 Objective-C與Swift的底層差異這套卷子的語言基礎部分十有八九會圍繞Objective-C和Swift的差異展開。常見考法有兩種一種是直接問“你如何理解Swift中的值類型與引用類型”另一種是給出一個混合工程場景讓你分析OC和Swift橋接時的注意事項。先說值類型與引用類型。Swift里Struct是值類型Class是引用類型這個幾乎所有候選人都知道。但筆試想考察的是更深一層值類型在賦值、傳參時會觸發拷貝而Swift為了保證性能引入了Copy-on-Write機制也就是只有真正修改數據時才發生拷貝。很多答案只寫到了“Struct是值拷貝”沒有點出COW這就丟掉了一個加分項。再說OC和Swift橋接。實際工程中OC代碼調用Swift類需要在頭文件里引入#import Target-Swift.h而Swift調用OC代碼則需要通過Bridging Header。筆試如果出這個知識點通常會埋一個坑Swift類如果要被OC使用必須繼承自NSObject否則橋接后OC無法正確識別這個類的方法調用。2.2 Runtime機制與消息轉發流程Runtime是iOS筆試的釘子戶考點B站這套卷子大概率也會涉及。最基本的是消息發送機制objc_msgSend根據對象的isa指針找到類對象再通過SEL在method_list里查找IMP。如果找不到會走消息轉發流程。消息轉發的完整鏈路是動態方法解析resolveInstanceMethod→ 快速轉發forwardingTargetForSelector→ 完整轉發methodSignatureForSelector和forwardInvocation。筆試常考的場景是你有一個對象調用了未實現的方法程序為什么沒有崩然后讓你描述整個查找過程。準備這個考點時我建議你多問自己一個“為什么”——為什么需要快速轉發和完整轉發兩層設計快速轉發是直接把消息轉發給另一個能處理的對象性能開銷小完整轉發需要生成NSInvocation開銷大但更靈活。理解了這層設計意圖題目怎么變你都能應對而且這種“為什么這么設計”的思路恰恰是閱卷人最想在卷子上看到的。另外KVC和KVO也是Runtime的常見延伸考點。KVO的底層原理是動態生成子類并重寫setter方法這個子類會重寫class方法讓外部感知不到類型變化。筆試很可能接著追問手動觸發KVO怎么實現答案是調用willChangeValueForKey和didChangeValueForKey這兩個方法。2.3 內存管理從ARC到循環引用內存管理部分每年都是重頭戲B站的卷子自然也不例外。ARC雖然是編譯器自動插入retain/release但面試官真正想考的是你知不知道哪些場景會造成循環引用以及怎么定位和解決。最常見的循環引用場景有三個Block捕獲self、NSTimer持有target、Delegate使用strong修飾。筆試給出的代碼片段往往就是這三種之一讓你分析是否有循環引用并寫出解決方案。Block捕獲self的解法是用__weak修飾self但在Block內部如果需要長期持有self比如異步任務完成后的回調單純使用weak可能導致對象提前釋放。這種場景的正確姿勢是在Block外部用weakSelfBlock內部再聲明一個strongSelf來保證執行期間self不會被釋放同時避免執行過程中self被置nil導致的邏輯異常。NSTimer的坑在于Timer會強持有target如果target又強持有Timer通常作為屬性就形成了循環引用。iOS 10之后推薦使用block版本的timer方法在deinit里主動調用invalidate。如果你回答的是“使用weakSelf”閱卷人一眼就能看出你只是背了答案因為weakSelf并不能打破Timer對target的持有關系。還有一個筆試高頻陷阱是autoreleasepool。很多候選人只知道autoreleasepool是自動釋放池但不知道為什么for循環大量創建臨時對象時要用它包裹。答案是大量臨時對象比如循環讀取圖片數據如果都往當前runloop綁定的autoreleasepool里注冊會持續占用內存直到RunLoop進入休眠才釋放。手動添加一個局部的autoreleasepool可以及時釋放降低峰值內存。3. 并發編程與網絡層基礎3.1 GCD核心概念與死鎖陷阱GCD是iOS并發編程的基礎這套卷子在這塊的考察通常集中在幾個方向隊列與任務的組合方式、死鎖的產生條件、線程安全的實現手段。先明確基本概念串行隊列和并發隊列決定任務的執行方式同步和異步決定任務的分發方式。筆試常考的組合包括并發隊列同步任務不會開新線程串行隊列異步任務也只有一個線程。很多人在這里記混我建議你死記一個結論只有“并發隊列異步任務”才會真正并發開辟多個線程。死鎖是選擇題和簡答題都愛考的點。最經典的陷阱就是在主隊列上執行sync操作這時主隊列被當前任務占用sync又去等這個任務完成就形成了互相等待。我在輔導時經常讓候選人記住一句話不要在已經處于某個串行隊列的環境里再對這個隊列執行sync操作。還有一道B站當年考過的變體題在一個自定義串行隊列里異步執行任務AA內部又對同一個串行隊列執行sync操作。結果同樣會死鎖原因和主隊列死鎖一樣——串行隊列同一時刻只能執行一個任務sync在等前面的任務結束而前面的任務又被sync阻塞了。3.2 鎖的選型與線程安全方案線程安全這塊考點從重量級到輕量級依次排開NSLock、synchronized、信號量、atomic、以及無鎖方案。筆試題經常給一個多線程讀寫同一個字典的場景讓你選擇最合適的方案。synchronized本質是對傳入對象加了一個遞歸鎖性能較差但使用簡單適合低頻的臨界區保護。NSLock是標準的互斥鎖但要注意lock和unlock必須成對調用否則會死鎖。dispatch_semaphore是處理“資源并發數限制”的利器設置初始value為1就等價于一個互斥鎖設置為更大的值則可以實現流量控制。OC屬性的atomic修飾也經常被拿來考察。很多人以為atomic就是絕對線程安全這是最大的誤解。atomic只保證屬性的getter和setter是原子操作但如果你先讀取字典、再修改其中某個key對應的值這整個復合操作并沒有被原子化多條線程仍可能產生數據競爭。筆試如果想拿高分要在答案里主動點出這個“atomic不等于線程安全”的結論并且補充說明真正安全的方式是使用并發隊列加讀寫柵欄或者用NSLock把整個讀寫邏輯包裹起來。3.3 網絡層考點HTTP、HTTPS與TCP網絡基礎也是校招筆試的常客。三次握手和四次揮手基本是必考但光背狀態碼和標志位是不夠的你需要能結合開發場景解釋為什么是三次而不是兩次。三次握手的核心作用在于確認雙方的接收和發送能力都正常兩次握手無法防止歷史重復連接請求導致的資源浪費。HTTPS方面重點是TLS握手過程中證書驗證和密鑰協商的流程。筆試簡答題如果問HTTPS為什么安全一定要從“機密性、完整性、身份驗證”三個維度作答對稱加密保證數據機密性、摘要算法保證完整性、數字證書保證服務端身份可信。只要從這三個角度展開得分率會高很多。B站作為視頻平臺面試中還可能順帶問CDN和弱網優化的基本思路。這里你得懂一點HTTPDNS可以繞過本地DNS的解析耗時和污染問題長連接和連接復用能減少頻繁建連的開銷弱網環境下可以通過降低圖片清晰度、批量請求合并等手段優化體驗。這些點不一定在筆試中出現但在同場面試里被追問的概率非常高建議一并準備。4. 架構設計、UI機制與性能優化4.1 從MVC到MVVM的架構演進B站的iOS客戶端體量不小筆試對架構設計的考察往往不是讓你默寫定義而是給一個場景讓你分析現有架構的問題并提出改進方案。最典型的就是MVC在大型項目中的困境。MVC本身是清晰的但App規模變大后Controller會越來越臃腫大量業務邏輯、網絡回調、視圖更新都堆在Controller里導致它既難測試也難維護。MVVM的核心變化是引入ViewModel來承接原本屬于Controller的展示邏輯和業務邏輯Controller只負責視圖綁定和生命周期管理。筆試如果讓你寫MVVM記得要提到數據綁定這一環。MVVM在iOS中有兩種實現路線一是基于KVO或Block手寫綁定二是引入ReactiveCocoa或RxSwift這樣的響應式框架。手寫綁定的代碼量較大但能讓閱卷人看到你對處理邏輯的理解深度如果你選擇用RxSwift務必把關鍵操作符和線程切換寫清楚。還有一個加分的角度是組件化。你可以把思路延伸到模塊劃分和依賴管理頂層是App殼工程中間是各個業務組件底層是基礎組件庫。組件間通信可以通過路由表或中間層完成避免模塊間直接引用。這個角度能讓你的答案脫穎而出因為大部分候選人只會聊MVC和MVVM的區別。4.2 事件傳遞機制與響應鏈UI事件傳遞是iOS筆試中區分度最高的一塊。常見的考法是給出一個復雜的視圖層級讓你判斷點擊某個位置時事件最終由誰響應。完整的傳遞機制分兩個階段第一階段是Hit-Test系統從UIWindow開始倒序遍歷子視圖調用pointInside:withEvent:和hitTest:withEvent:找到最合適的視圖。第二階段是響應鏈事件從第一響應者開始沿著nextResponder鏈條向上傳遞直到有對象處理這個事件。這個知識點的難點在于理解Hit-Test的逆向遍歷順序后添加的子視圖會先被遍歷因為它在層級里處于最上面。筆試還經常加一個變體——某個視圖的userInteractionEnabled設置為NO或者alpha小于0.01或者hidden為YES這三種情況下該視圖不會出現在Hit-Test的命中結果里事件會直接傳給它的兄弟視圖。準備這個考點時我建議你親手寫一個例子驗證自定義一個UIView重寫hitTest:withEvent:打印調用順序和坐標判斷能幫助你真正記住流程而不是背幾個結論。4.3 RunLoop與UI卡頓排查性能優化方面RunLoop和卡頓排查是高頻命題角度。RunLoop的基本邏輯是App啟動后主線程始終處于一個循環中不斷接收事件源并處理然后進入休眠等待新事件。這里要重點理解RunLoop的兩種SourceSource0處理如觸摸事件這樣手動觸發的源Source1處理基于端口的系統消息。定時器Timer則被注冊在RunLoop的Timer模式下。關于UI卡頓核心結論是主線程的RunLoop在一個周期內要處理繪制、布局、點擊事件等所有任務如果單個任務執行時間過長就會觸發掉幀。筆試題經常給一段在主線程同步加載大圖和數據解析的代碼讓你分析為什么卡頓并寫出優化方案。優化的思路是把耗時操作放到子線程比如用異步隊列處理圖片解碼和JSON解析然后回到主線程更新UI。這里有一個常見的坑就是子線程回到主線程如果使用sync操作在某些情況下可能造成死鎖最好統一使用async。還有一個加分的進階點預排版和預渲染。在子線程提前計算好文本的size和布局信息避免主線程在滑動時才做計算這是短視頻和直播類App保障流暢度的重要手段。B站這類視頻App對這種優化非常看重你如果能在答案里提到這個點很容易和閱卷人產生共鳴。5. 常見失分點與筆試實戰技巧5.1 高頻失分點速查表根據我這些年看到的校招筆試卷有些失分點幾乎是統一的。整理成表格方便你復習時對照自查失分點錯誤表現正確思路選擇題陷阱看到“原子性”就直接選線程安全atomic只保證getter/setter原子不保證復合操作安全簡答題太過簡短只寫“會循環引用”不寫原因要寫出誰持有誰、為什么形成環、用什么方式打破死鎖判斷不完整只判斷出主線程sync導致死鎖要補充自定義串行隊列的同類問題事件響應鏈答反以為事件從最上層視圖先處理先Hit-Test確定第一響應者再沿響應鏈向上傳遞不會手寫綁定只會口述MVVM概念至少能寫出簡單的Block回調或KVO綁定示例代碼這份表格里的內容本質上是“概念記憶”和“機制理解”之間的差距。選擇題可以靠背簡答題和編程題只能靠實打實的理解。5.2 編程題的解題套路這套卷子的編程題通常不會太偏常見類型包括鏈表反轉、二叉樹遍歷、字符串處理、簡單的動態規劃以及少量iOS相關的代碼題如手寫一個線程安全的單例、手寫KVO的替代方案。手寫單例幾乎年年考。以OC為例正經的寫法是保證兩個層面安全一是用dispatch_once保證線程安全二是重寫allocWithZone、copyWithZone等方法防止外部通過非shared接口創建新實例。很多候選人只寫了dispatch_once漏掉了后一層保護這會被扣分。另外一個值得關注的題型是“給一段有Bug的代碼找出問題并修復”。這種題考的其實是代碼Review能力。答題時要按嚴重程度排序輸出先說會導致崩潰的問題比如數組越界、空指針再說邏輯錯誤最后說性能和規范問題。這種分層的表達方式能讓閱卷人一眼看出你具備工程思維。5.3 筆試前的復習節奏與心態調整最后聊一下備考策略。如果你還有兩到三周的時間我建議按“廣度優先、深度跟進”的節奏走第一周把所有基礎考點過一遍做到每個概念都能用自己的話復述第二周集中刷題重點是在紙上手寫代碼不要只在IDE里敲第三周做模擬卷嚴格計時訓練答題節奏。筆試前一天不要再學新知識把這份速查表和自己的錯題筆記翻一遍就行。真正上了考場遇到不會的題不要慌先用排除法縮小范圍再調動相關的上下文寫點與分析過程相關的內容。校招筆試不是要求你滿分而是要求你在有限時間里把自己會的都穩定輸出。這一點比多背十個知識點更值錢。我自己的體會是準備B站這類大廠筆試卷最大的收獲不是最后拿到Offer而是通過復習把iOS的知識體系真正串起來了。很多開發者在日常工作中只用到了UI搭建和接口聯調對底層機制是模糊的但筆試卷會逼你把這塊短板補上。這種系統性沉淀對后續的面試和實際開發都有長期幫助。還是那句話基礎不牢地動山搖——別只盯著題目本身把每個考點背后的原理吃透你拿到的就不只是一份及格卷。