一、Swift 語言基礎(chǔ)
問:值類型與引用類型區(qū)別?何時(shí)選 struct,何時(shí)選 class?
答:值類型拷貝語義、線程安全性更好;引用類型共享狀態(tài)、有動(dòng)態(tài)繼承。數(shù)據(jù)模型、不可變小對(duì)象優(yōu)先用 struct;需要繼承、多態(tài)或與 ObjC 交互時(shí)用 class。
問:mutating 關(guān)鍵字的作用?
答:標(biāo)記會(huì)修改自身狀態(tài)的值類型方法;使得方法內(nèi)可變更 self 或其存儲(chǔ)屬性。
問:stored vs computed property?property observers 何時(shí)觸發(fā)?
答:stored 持有數(shù)據(jù);computed 基于計(jì)算返回。willSet/didSet 在直接賦值時(shí)觸發(fā),對(duì) init 內(nèi)賦值不觸發(fā)。
問:lazy 的使用場景與注意點(diǎn)?
答:延遲初始化,適合昂貴或依賴外部環(huán)境的屬性;在并發(fā)場景要注意線程安全。
問:enum 帶關(guān)聯(lián)值的優(yōu)勢?
答:把狀態(tài)與數(shù)據(jù)綁定,窮盡性檢查更安全,替代多處 if/else 與易錯(cuò)的魔法數(shù)。
問:OptionSet 與 enum 的差別?
答:OptionSet 表示可組合的位掩碼集合;enum 表示互斥的離散取值。
問:訪問控制 five levels 及常用場景?
答:open > public > internal > fileprivate > private。庫 API 用 public/open;模塊內(nèi)默認(rèn) internal;封裝細(xì)節(jié)用 private/fileprivate。
問:extension 與繼承的取舍?
答:extension 用于拆分實(shí)現(xiàn)、增加協(xié)議一致性;繼承用于復(fù)用并引入多態(tài)。
問:Equatable/Hashable/Codable 自動(dòng)合成條件?
答:當(dāng)所有存儲(chǔ)屬性都滿足相同協(xié)議時(shí)編譯器可自動(dòng)合成。
問:ABI 穩(wěn)定的意義?
答:運(yùn)行時(shí)二進(jìn)制接口穩(wěn)定后,系統(tǒng)可內(nèi)置 Swift 標(biāo)準(zhǔn)庫,App 可與不同編譯器版本互操作。
二、可選與錯(cuò)誤處理
問:Optional 與 IUO 的區(qū)別?
答:Optional 需安全解包;IUO 在使用點(diǎn)隱式解包,若為 nil 會(huì)崩潰,僅用于過渡或 IBOutlets 等。
問:guard let vs if let?
答:guard 更適合“早退”;保持主路徑縮進(jìn)淺、可讀性更好。
問:try、try?、try! 區(qū)別?
答:try 傳播錯(cuò)誤;try? 把錯(cuò)誤轉(zhuǎn)為 nil;try! 斷言不出錯(cuò),出錯(cuò)即崩潰。
問:rethrows 的用途?
答:高階函數(shù)只在傳入閉包拋錯(cuò)時(shí)才拋錯(cuò),自己不額外拋錯(cuò)。
問:throwing initializer 有何約束?
答:拋錯(cuò)前需保證已釋放已分配資源;失敗則實(shí)例化不成功。
問:throws vs Result 如何取舍?
答:同步鏈用 throws 可讀性更高;需要跨線程、存儲(chǔ)或組合多錯(cuò)誤時(shí)可用 Result。
三、ARC 與內(nèi)存管理
問:ARC 工作原理?
答:編譯期插入 retain/release;計(jì)數(shù)歸零即釋放;不處理循環(huán)引用。
問:strong/weak/unowned 的差異與使用場景?
答:strong 持有;weak 不持有且可為 nil(需可選);unowned 不持有且不為 nil(生命周期受控,錯(cuò)誤會(huì)崩潰)。
問:閉包捕獲列表作用?
答:控制捕獲方式以避免循環(huán)引用或過度持有,如 [weak self]。
問:何時(shí)選擇 weak self vs unowned self?
答:self 可能先于閉包釋放用 weak;生命周期嚴(yán)格一致用 unowned。
問:常見循環(huán)引用場景與解法?
答:對(duì)象互持有、定時(shí)器/代理/閉包持有 self;用 weak/unowned/中介者/使閉包短生命周期。
問:escape 與 non-escape 閉包區(qū)別?
答:逃逸閉包可在函數(shù)返回后調(diào)用,需顯式 self;非逃逸則不需要。
問:Copy-on-Write 在 Array/String/Data 中如何工作?
答:結(jié)構(gòu)體共享底層緩沖,寫時(shí)獨(dú)享拷貝,減少不必要復(fù)制。
問:autoreleasepool 何時(shí)使用?
答:處理大批臨時(shí)對(duì)象或循環(huán)中釋放峰值內(nèi)存,尤其圖片/數(shù)據(jù)處理。
問:內(nèi)存泄漏排查手段?
答:Xcode Memory Graph、Instruments Leaks/Allocations、斷點(diǎn) + 打印 deinit。
問:橋接到 ObjC 的內(nèi)存注意點(diǎn)?
答:遵循 ARC 規(guī)則;避免 toll-free bridging 下的不匹配釋放。
四、泛型、協(xié)議與類型系統(tǒng)
問:泛型 vs 面向協(xié)議的取舍?
答:泛型性能更好、靜態(tài)分發(fā);協(xié)議更靈活、可抽象存在類型,但有擦類型成本。
問:associatedtype 的限制?
答:帶關(guān)聯(lián)類型的協(xié)議不能直接當(dāng)作具體類型使用,需要泛型約束或類型擦除。
問:any 關(guān)鍵字的含義?
答:顯式存在類型(existential),通過 witness table 動(dòng)態(tài)分發(fā),可能帶裝箱開銷。
問:some 不透明返回類型的優(yōu)勢?
答:隱藏具體類型同時(shí)保留靜態(tài)分發(fā)與編譯期優(yōu)化,常見于 SwiftUI 的 View。
問:where 子句能做什么?
答:對(duì)泛型參數(shù)/關(guān)聯(lián)類型施加額外約束,提高表達(dá)力與代碼可讀性。
問:類型擦除是什么?
答:用包裝器把泛型/關(guān)聯(lián)類型隱藏成固定接口(如 AnySequence、AnyPublisher)。
問:方法派發(fā):靜態(tài) vs 動(dòng)態(tài)?
答:struct/enum/extension 靜態(tài)分發(fā);class 默認(rèn)虛表動(dòng)態(tài)分發(fā);final 可靜態(tài)分發(fā)優(yōu)化;協(xié)議通過 witness table。
問:Swift 的協(xié)變/逆變?
答:泛型總體上不變;函數(shù)類型參數(shù)逆變、返回值協(xié)變;需要用泛型約束表達(dá)。
問:Codable 在泛型中的限制?
答:條件符合時(shí)自動(dòng)合成;復(fù)雜多態(tài)需自定義 key 與類型標(biāo)識(shí)。
問:KeyPath 有啥用?
答:以值的形式引用屬性,便于泛型編程、KVC/KVO 橋接、數(shù)據(jù)綁定。
五、并發(fā)與多線程
問:async/await 的核心優(yōu)勢?
答:結(jié)構(gòu)化并發(fā)、線性可讀、錯(cuò)誤與取消自動(dòng)傳播,避免回調(diào)地獄。
問:Task 與 TaskGroup 區(qū)別?
答:Task 啟動(dòng)單個(gè)異步;TaskGroup 并行多個(gè)子任務(wù)并聚合結(jié)果。
問:Actor 解決什么問題?
答:通過隔離可變狀態(tài)保證數(shù)據(jù)競爭安全;MainActor 專用于 UI。
問:Actor 可重入與隔離規(guī)則?
答:await 點(diǎn)可能讓出執(zhí)行導(dǎo)致重入;跨 actor 訪問需 await;非隔離 let 可并發(fā)讀。
問:Sendable 的作用?
答:標(biāo)記跨并發(fā)域安全傳遞的類型;對(duì)可變引用需加 @unchecked Sendable 并自保。
問:Task.detached 何時(shí)使用?
答:需要脫離當(dāng)前上下文(包括優(yōu)先級(jí)/actor)時(shí);慎用,手動(dòng)管理隔離與優(yōu)先級(jí)。
問:取消是如何傳播的?
答:從父到子結(jié)構(gòu)化傳播;任務(wù)應(yīng)定期檢查 Task.isCancelled 并盡早退出。
問:withCheckedContinuation 用于什么?
答:橋接回調(diào) API 到 async/await;保證 resume 恰好一次。
問:AsyncSequence 的應(yīng)用?
答:表達(dá)異步流,如通知、網(wǎng)絡(luò)流、計(jì)時(shí)器;for await 消費(fèi)。
問:GCD 與 OperationQueue 還何時(shí)用?
答:與舊代碼、第三方庫集成;需要依賴、取消、優(yōu)先級(jí)時(shí) Operation 更合適。
問:避免死鎖的常見準(zhǔn)則?
答:不要在主隊(duì)列 sync;不要持鎖中等待回調(diào);盡量使用 await 的結(jié)構(gòu)化并發(fā)。
問:優(yōu)先級(jí)反轉(zhuǎn)如何避免?
答:使用質(zhì)量服務(wù)級(jí)別合適的隊(duì)列/任務(wù);避免在高優(yōu)先級(jí)任務(wù)中等待低優(yōu)先級(jí)。
六、SwiftUI
問:View 是值類型意味著什么?
答:聲明式、不可變描述;狀態(tài)在外部屬性包裝器中維護(hù),body 可頻繁重算。
問:@State/@Binding/@ObservedObject/@StateObject 區(qū)別?
答:State 本地狀態(tài);Binding 傳遞可變引用;ObservedObject 外部擁有者;StateObject 本地持有引用類型。iOS 17+ 可用 Observation @Observable 簡化。
問:EnvironmentObject 用途與風(fēng)險(xiǎn)?
答:全局依賴注入,使用便捷但耦合大,易引發(fā)運(yùn)行時(shí)崩潰(未注入)。
問:導(dǎo)航棧與深鏈接處理?
答:使用 NavigationStack + NavigationPath;解析 URL 同步更新 Path。
問:性能優(yōu)化常見手段?
答:細(xì)分視圖、使用 EquatableView/transaction、減少 body 工作、使用 @MainActor 正確更新。
問:List/ForEach 標(biāo)識(shí)符的重要性?
答:穩(wěn)定 id 使 diff 正確;避免使用索引作為 id。
問:布局系統(tǒng)與 preference 如何協(xié)作?
答:布局是自上而下提議、自下而上報(bào)告;偏好鍵用于向上游傳遞信息。
問:任務(wù)生命周期 task 與 onAppear 差異?
答:task 與視圖生命周期耦合、可取消;onAppear 可能多次觸發(fā)且不可取消。
問:與 UIKit 互操作?
答:UIViewRepresentable/UIViewControllerRepresentable 封裝;協(xié)調(diào)器做代理橋接。
問:SwiftData vs Core Data 在 SwiftUI 中?
答:SwiftData(iOS 17+) 以 @Model、@Query 更貼合 SwiftUI;底層仍基于 Core Data。
七、UIKit 與布局
問:UIViewController 生命周期關(guān)鍵點(diǎn)?
答:loadView/viewDidLoad/appear/disappear;布局相關(guān)在 viewDidLayoutSubviews。
問:Responder Chain 有何用?
答:事件傳遞與未處理動(dòng)作上行;便于解耦(target-action、鍵盤等)。
問:Auto Layout 的 intrinsic size、Hugging/Compression?
答:內(nèi)在尺寸提供默認(rèn)大小;Hugging 抵抗變大,Compression 抵抗變小。
問:updateConstraints vs layoutSubviews?
答:約束變化放 updateConstraints;幾何調(diào)整放 layoutSubviews。
問:自適應(yīng) cell 實(shí)現(xiàn)要點(diǎn)?
答:內(nèi)容視圖約束完備、優(yōu)先級(jí)正確、estimatedSize 配置。
問:DiffableDataSource 的優(yōu)勢?
答:基于快照的線程安全 diff,避免不一致崩潰。
問:離屏渲染的原因與優(yōu)化?
答:圓角、遮罩、陰影易觸發(fā);用 rasterization、路徑裁剪、預(yù)渲染圖片優(yōu)化。
問:UI 必須在主線程的原因?
答:UIKit 非線程安全;布局/繪制需主線程。
問:Safe Area 與 Content Insets 區(qū)別?
答:Safe Area 是系統(tǒng)保留區(qū)域邊界;Content Insets 是滾動(dòng)內(nèi)容的內(nèi)邊距。
問:大圖滾動(dòng)卡頓的優(yōu)化?
答:異步解碼、按需下采樣、緩存、預(yù)取與占位。
八、網(wǎng)絡(luò)
問:URLSession 常見任務(wù)類型?
答:data、download、upload、stream、WebSocket。
問:Codable 解碼日期與鍵策略?
答:配置 dateDecodingStrategy、keyDecodingStrategy;或自定義 CodingKeys。
問:重試與退避策略?
答:指數(shù)退避 + 抖動(dòng);對(duì)冪等請(qǐng)求安全重試。
問:網(wǎng)絡(luò)狀態(tài)檢測?
答:NWPathMonitor 代替舊 Reachability;僅作提示,不等同業(yè)務(wù)可用性。
問:HTTP 緩存與條件請(qǐng)求?
答:URLCache + ETag/If-None-Match 或 Last-Modified;合理 Cache-Control。
問:證書/公鑰綁定(SSL Pinning)?
答:在認(rèn)證回調(diào)校驗(yàn)證書或公鑰指紋;注意證書更新與降級(jí)攻擊防護(hù)。
問:后臺(tái)傳輸?shù)囊c(diǎn)?
答:使用 background URLSession,系統(tǒng)代管,配合 BGProcessingTask。
問:用 async/await 包裝 URLSession?
答:調(diào)用 data(from:) async API;或用 continuation 橋接舊回調(diào)。
九、數(shù)據(jù)持久化
問:UserDefaults/Keychain/File/Core Data/SwiftData 取舍?
答:偏好小量數(shù)據(jù)用 Defaults;敏感憑據(jù)用 Keychain;文件大對(duì)象;關(guān)系型/查詢用 Core Data/SwiftData。
問:Core Data 上下文并發(fā)模型?
答:主隊(duì)列與私有隊(duì)列上下文;通過 perform/performAndWait 串行化訪問。
問:輕量遷移 vs 自定義遷移?
答:字段/實(shí)體簡單變更可輕量;復(fù)雜變更需映射模型與遷移策略。
問:NSPersistentContainer 的作用?
答:封裝棧初始化、加載存儲(chǔ)、提供背景上下文。
問:SwiftData 核心概念?
答:@Model 標(biāo)注、@Query 自動(dòng)獲取、ModelContext 管理事務(wù)。
問:文件加密與保護(hù)等級(jí)?
答:NSFileProtectionComplete 等;敏感數(shù)據(jù)在設(shè)備鎖定時(shí)不可訪問。
問:App Group 共享數(shù)據(jù)?
答:使用 containerURL(forSecurityApplicationGroupIdentifier:) 指向共享目錄。
問:iCloud 同步注意點(diǎn)?
答:沖突合并、離線策略、隱私與數(shù)據(jù)體量控制。
十、架構(gòu)與工程實(shí)踐
問:MVC 痛點(diǎn)與 MVVM/Redux/Clean 的改進(jìn)?
答:MVC 容易 Massive-VC;MVVM 分離視圖狀態(tài);單向數(shù)據(jù)流可控性強(qiáng);Clean 分層解耦。
問:依賴注入的方式?
答:構(gòu)造注入優(yōu)先;屬性注入/服務(wù)定位器次之;SwiftUI 可用環(huán)境注入。
問:模塊化的收益與手段?
答:并行開發(fā)、編譯加速、重用;用 SPM/多 target/二進(jìn)制框架。
問:路由/導(dǎo)航協(xié)調(diào)器(Coordinator)模式?
答:抽離導(dǎo)航邏輯,降低 VC 復(fù)雜度與耦合。
問:特性開關(guān)與遠(yuǎn)程配置?
答:解耦發(fā)布與上線,灰度與 A/B;注意緩存與兜底。
問:SOLID 在 iOS 實(shí)踐?
答:接口隔離、單一職責(zé)、里氏替換、依賴倒置,配合協(xié)議/組合。
問:線程安全的數(shù)據(jù)層設(shè)計(jì)?
答:不可變模型、串行化訪問、actor 或隊(duì)列屏障。
問:錯(cuò)誤與日志策略?
答:區(qū)分可恢復(fù)/不可恢復(fù);結(jié)構(gòu)化日志與打點(diǎn)埋點(diǎn)。
問:國際化本地化要點(diǎn)?
答:String Catalogs、文案長度/排版、RTL、時(shí)區(qū)/日歷。
問:可觀測性與診斷?
答:統(tǒng)一日志、signpost、崩潰收集、性能監(jiān)控指標(biāo)。
十一、性能與調(diào)優(yōu)
問:冷啟動(dòng)優(yōu)化思路?
答:減小可執(zhí)行體與依賴、延遲初始化、減少 ObjC 元數(shù)據(jù)/類別、優(yōu)化 Storyboard。
問:Time Profiler 看什么?
答:熱路徑、符號(hào)化、反向調(diào)用樹,找出最高自耗時(shí)與總耗時(shí)函數(shù)。
問:內(nèi)存峰值與泄漏定位?
答:Allocations 看駐留對(duì)象;Leaks/Memory Graph 找循環(huán)引用。
問:滾動(dòng)掉幀定位?
答:Core Animation FPS、長任務(wù)、離屏渲染、圖片解碼。
問:圖片優(yōu)化策略?
答:按需下采樣(CGImageSource)、預(yù)解碼、合適像素格式與緩存策略。
問:主線程卡頓排查?
答:主線程看門狗、符號(hào)化堆棧、避免同步 IO/鎖競爭。
問:能耗優(yōu)化?
答:批量網(wǎng)絡(luò)、后臺(tái)計(jì)劃、避免頻繁喚醒與定位;Energy Log 驗(yàn)證。
問:Swift 編譯時(shí)間優(yōu)化?
答:簡化泛型/類型推斷、減少大文件、啟用增量構(gòu)建、模塊化。
問:二進(jìn)制體積降低?
答:移除未用架構(gòu)、LTO/Link Dead Code Stripping、資源切分與按需加載。
問:線程爆炸問題?
答:限制并發(fā)度、使用任務(wù)組/隊(duì)列 QoS、避免無限遞歸異步。
十二、測試與持續(xù)集成
問:XCTest 單元 vs UI 測試區(qū)別?
答:單元快而穩(wěn)定;UI 測試端到端但脆弱,需良好可測性與穩(wěn)定定位符。
問:異步測試怎么寫?
答:XCTestExpectation 或 async 測試 + await;設(shè)置合理超時(shí)。
問:依賴注入與可測試性?
答:通過協(xié)議與構(gòu)造注入替換實(shí)現(xiàn)為假對(duì)象或記錄器。
問:快照測試注意點(diǎn)?
答:控制環(huán)境一致性(字體/尺寸/主題);審慎更新基線。
問:代碼覆蓋率意義與局限?
答:衡量到達(dá)率非正確性;關(guān)注關(guān)鍵路徑與分支。
問:CI/CD 常見方案?
答:Xcode Cloud、GitHub Actions + Fastlane;自動(dòng)化構(gòu)建、簽名、測試與發(fā)布。
問:簽名與配置文件基礎(chǔ)?
答:證書 + Provisioning Profile(開發(fā)/測試/發(fā)布);Bundle ID/Entitlements 匹配。
問:崩潰符號(hào)化與回溯?
答:保留 dSYM,集成崩潰平臺(tái),符號(hào)化后分析堆棧熱點(diǎn)。
十三、應(yīng)用生命周期、后臺(tái)與通知
問:App 狀態(tài)與回調(diào)?
答:not running/inactive/active/background/suspended;App/Scene Delegate 生命周期。
問:后臺(tái)模式有哪些?
答:音頻、定位、VoIP、藍(lán)牙、后臺(tái)獲取、后臺(tái)處理任務(wù)等,需聲明 Capabilities。
問:BGTaskScheduler 用法?
答:注冊標(biāo)識(shí)、提交 BGAppRefreshTask/BGProcessingTask、設(shè)置最早開始時(shí)間、注意時(shí)限與電量策略。
問:APNs 推送流程?
答:設(shè)備向 APNs 注冊獲取 token,服務(wù)端發(fā)推送,系統(tǒng)交付到 App;生產(chǎn)/沙盒證書或基于 token 的鑒權(quán)。
問:UNUserNotificationCenter 本地通知?
答:請(qǐng)求權(quán)限、創(chuàng)建觸發(fā)器、添加請(qǐng)求、處理回調(diào)與分類動(dòng)作。
問:前臺(tái)通知顯示策略?
答:實(shí)現(xiàn) willPresent 回調(diào)自定義 alert/badge/sound。
問:Universal Links 處理?
答:apple-app-site-association 配置;在 Scene/SwiftUI onOpenURL 處理跳轉(zhuǎn)。
問:狀態(tài)恢復(fù)與深度鏈接一致性?
答:統(tǒng)一路由層,編碼/解碼導(dǎo)航狀態(tài)。
十四、安全與隱私
問:Keychain 適用場景與注意點(diǎn)?
答:存儲(chǔ)敏感憑據(jù);訪問組、同步、項(xiàng)級(jí)別訪問控制;避免明文。
問:ATS 是什么?
答:App Transport Security 強(qiáng)制安全網(wǎng)絡(luò)(HTTPS);例外需說明理由。
問:隱私權(quán)限最佳實(shí)踐?
答:按需請(qǐng)求、清晰用途描述、失敗兜底、尊重用戶選擇。
問:剪貼板/傳感器隱私提示?
答:最小化訪問并明確用戶操作觸發(fā);系統(tǒng)會(huì)顯示訪問提示。
問:加密與簽名建議?
答:使用 CryptoKit,高層 API 優(yōu)先;需要時(shí)用 Secure Enclave。
問:生物識(shí)別策略?
答:LAContext 評(píng)估策略、回退口令、錯(cuò)誤處理與 UI 提示。
問:日志脫敏?
答:避免記錄 PII/密鑰/Token;按需采樣與加密。
問:反破解與完整性?
答:Jailbreak 檢測有限;重在后端校驗(yàn)、API 限流與風(fēng)控。
十五、工具鏈與依賴管理
問:SPM/Pods/Carthage 取舍?
答:SPM 官方優(yōu)先、集成輕;Pods 生態(tài)廣但引入工作區(qū);Carthage 二進(jìn)制/預(yù)編譯控制更細(xì)。
問:XCFramework 的優(yōu)點(diǎn)?
答:統(tǒng)一多架構(gòu)與平臺(tái)分發(fā),替代 fat frameworks。
問:Build Configuration/Scheme 的作用?
答:區(qū)分 Debug/Release/自定義環(huán)境;配合編譯標(biāo)記與配置文件。
問:App thinning/ slicing 與 bitcode(已棄用)的現(xiàn)狀?
答:App Thinning 仍有效;Bitcode 已被棄用,專注資源與架構(gòu)裁剪。
問:符號(hào)與日志的等級(jí)管理?
答:OSLog 分類/級(jí)別,控制生產(chǎn)環(huán)境開銷與隱私。
問:依賴庫集成后是否還需構(gòu)建?
答:需要。依賴解析/編譯/鏈接發(fā)生在構(gòu)建期,才能運(yùn)行與打包。
十六、常見“手撕”與思考題
問:設(shè)計(jì)一個(gè)圖片緩存組件要考慮什么?
答:內(nèi)存+磁盤緩存、LRU、下采樣、并發(fā)下載合并、緩存鍵、失效策略、可觀測性。
問:實(shí)現(xiàn)去抖與節(jié)流?
答:基于 DispatchWorkItem/Task 或 Combine/AsyncSequence;去抖延遲執(zhí)行、節(jié)流限頻。
問:線程安全的計(jì)數(shù)器/隊(duì)列如何實(shí)現(xiàn)?
答:actor/串行隊(duì)列/鎖;權(quán)衡吞吐與公平性。
問:避免 TableView 重用錯(cuò)位?
答:cellForRowIdempotent、取消舊請(qǐng)求、使用 index 變化檢測與占位。
問:圖片瀑布流的性能優(yōu)化?