一、Swift 语言基础
问:值类型与引用类型区别?何时选 struct,何时选 class?
答:值类型拷贝语义、线程安全性更好;引用类型共享状态、有动态继承。数据模型、不可变小对象优先用 struct;需要继承、多态或与 ObjC 交互时用 class。
问:mutating 关键字的作用?
答:标记会修改自身状态的值类型方法;使得方法内可变更 self 或其存储属性。
问:stored vs computed property?property observers 何时触发?
答:stored 持有数据;computed 基于计算返回。willSet/didSet 在直接赋值时触发,对 init 内赋值不触发。
问:lazy 的使用场景与注意点?
答:延迟初始化,适合昂贵或依赖外部环境的属性;在并发场景要注意线程安全。
问:enum 带关联值的优势?
答:把状态与数据绑定,穷尽性检查更安全,替代多处 if/else 与易错的魔法数。
问:OptionSet 与 enum 的差别?
答:OptionSet 表示可组合的位掩码集合;enum 表示互斥的离散取值。
问:访问控制 five levels 及常用场景?
答:open > public > internal > fileprivate > private。库 API 用 public/open;模块内默认 internal;封装细节用 private/fileprivate。
问:extension 与继承的取舍?
答:extension 用于拆分实现、增加协议一致性;继承用于复用并引入多态。
问:Equatable/Hashable/Codable 自动合成条件?
答:当所有存储属性都满足相同协议时编译器可自动合成。
问:ABI 稳定的意义?
答:运行时二进制接口稳定后,系统可内置 Swift 标准库,App 可与不同编译器版本互操作。
二、可选与错误处理
问:Optional 与 IUO 的区别?
答:Optional 需安全解包;IUO 在使用点隐式解包,若为 nil 会崩溃,仅用于过渡或 IBOutlets 等。
问:guard let vs if let?
答:guard 更适合“早退”;保持主路径缩进浅、可读性更好。
问:try、try?、try! 区别?
答:try 传播错误;try? 把错误转为 nil;try! 断言不出错,出错即崩溃。
问:rethrows 的用途?
答:高阶函数只在传入闭包抛错时才抛错,自己不额外抛错。
问:throwing initializer 有何约束?
答:抛错前需保证已释放已分配资源;失败则实例化不成功。
问:throws vs Result 如何取舍?
答:同步链用 throws 可读性更高;需要跨线程、存储或组合多错误时可用 Result。
三、ARC 与内存管理
问:ARC 工作原理?
答:编译期插入 retain/release;计数归零即释放;不处理循环引用。
问:strong/weak/unowned 的差异与使用场景?
答:strong 持有;weak 不持有且可为 nil(需可选);unowned 不持有且不为 nil(生命周期受控,错误会崩溃)。
问:闭包捕获列表作用?
答:控制捕获方式以避免循环引用或过度持有,如 [weak self]。
问:何时选择 weak self vs unowned self?
答:self 可能先于闭包释放用 weak;生命周期严格一致用 unowned。
问:常见循环引用场景与解法?
答:对象互持有、定时器/代理/闭包持有 self;用 weak/unowned/中介者/使闭包短生命周期。
问:escape 与 non-escape 闭包区别?
答:逃逸闭包可在函数返回后调用,需显式 self;非逃逸则不需要。
问:Copy-on-Write 在 Array/String/Data 中如何工作?
答:结构体共享底层缓冲,写时独享拷贝,减少不必要复制。
问:autoreleasepool 何时使用?
答:处理大批临时对象或循环中释放峰值内存,尤其图片/数据处理。
问:内存泄漏排查手段?
答:Xcode Memory Graph、Instruments Leaks/Allocations、断点 + 打印 deinit。
问:桥接到 ObjC 的内存注意点?
答:遵循 ARC 规则;避免 toll-free bridging 下的不匹配释放。
四、泛型、协议与类型系统
问:泛型 vs 面向协议的取舍?
答:泛型性能更好、静态分发;协议更灵活、可抽象存在类型,但有擦类型成本。
问:associatedtype 的限制?
答:带关联类型的协议不能直接当作具体类型使用,需要泛型约束或类型擦除。
问:any 关键字的含义?
答:显式存在类型(existential),通过 witness table 动态分发,可能带装箱开销。
问:some 不透明返回类型的优势?
答:隐藏具体类型同时保留静态分发与编译期优化,常见于 SwiftUI 的 View。
问:where 子句能做什么?
答:对泛型参数/关联类型施加额外约束,提高表达力与代码可读性。
问:类型擦除是什么?
答:用包装器把泛型/关联类型隐藏成固定接口(如 AnySequence、AnyPublisher)。
问:方法派发:静态 vs 动态?
答:struct/enum/extension 静态分发;class 默认虚表动态分发;final 可静态分发优化;协议通过 witness table。
问:Swift 的协变/逆变?
答:泛型总体上不变;函数类型参数逆变、返回值协变;需要用泛型约束表达。
问:Codable 在泛型中的限制?
答:条件符合时自动合成;复杂多态需自定义 key 与类型标识。
问:KeyPath 有啥用?
答:以值的形式引用属性,便于泛型编程、KVC/KVO 桥接、数据绑定。
五、并发与多线程
问:async/await 的核心优势?
答:结构化并发、线性可读、错误与取消自动传播,避免回调地狱。
问:Task 与 TaskGroup 区别?
答:Task 启动单个异步;TaskGroup 并行多个子任务并聚合结果。
问:Actor 解决什么问题?
答:通过隔离可变状态保证数据竞争安全;MainActor 专用于 UI。
问:Actor 可重入与隔离规则?
答:await 点可能让出执行导致重入;跨 actor 访问需 await;非隔离 let 可并发读。
问:Sendable 的作用?
答:标记跨并发域安全传递的类型;对可变引用需加 @unchecked Sendable 并自保。
问:Task.detached 何时使用?
答:需要脱离当前上下文(包括优先级/actor)时;慎用,手动管理隔离与优先级。
问:取消是如何传播的?
答:从父到子结构化传播;任务应定期检查 Task.isCancelled 并尽早退出。
问:withCheckedContinuation 用于什么?
答:桥接回调 API 到 async/await;保证 resume 恰好一次。
问:AsyncSequence 的应用?
答:表达异步流,如通知、网络流、计时器;for await 消费。
问:GCD 与 OperationQueue 还何时用?
答:与旧代码、第三方库集成;需要依赖、取消、优先级时 Operation 更合适。
问:避免死锁的常见准则?
答:不要在主队列 sync;不要持锁中等待回调;尽量使用 await 的结构化并发。
问:优先级反转如何避免?
答:使用质量服务级别合适的队列/任务;避免在高优先级任务中等待低优先级。
六、SwiftUI
问:View 是值类型意味着什么?
答:声明式、不可变描述;状态在外部属性包装器中维护,body 可频繁重算。
问:@State/@Binding/@ObservedObject/@StateObject 区别?
答:State 本地状态;Binding 传递可变引用;ObservedObject 外部拥有者;StateObject 本地持有引用类型。iOS 17+ 可用 Observation @Observable 简化。
问:EnvironmentObject 用途与风险?
答:全局依赖注入,使用便捷但耦合大,易引发运行时崩溃(未注入)。
问:导航栈与深链接处理?
答:使用 NavigationStack + NavigationPath;解析 URL 同步更新 Path。
问:性能优化常见手段?
答:细分视图、使用 EquatableView/transaction、减少 body 工作、使用 @MainActor 正确更新。
问:List/ForEach 标识符的重要性?
答:稳定 id 使 diff 正确;避免使用索引作为 id。
问:布局系统与 preference 如何协作?
答:布局是自上而下提议、自下而上报告;偏好键用于向上游传递信息。
问:任务生命周期 task 与 onAppear 差异?
答:task 与视图生命周期耦合、可取消;onAppear 可能多次触发且不可取消。
问:与 UIKit 互操作?
答:UIViewRepresentable/UIViewControllerRepresentable 封装;协调器做代理桥接。
问:SwiftData vs Core Data 在 SwiftUI 中?
答:SwiftData(iOS 17+) 以 @Model、@Query 更贴合 SwiftUI;底层仍基于 Core Data。
七、UIKit 与布局
问:UIViewController 生命周期关键点?
答:loadView/viewDidLoad/appear/disappear;布局相关在 viewDidLayoutSubviews。
问:Responder Chain 有何用?
答:事件传递与未处理动作上行;便于解耦(target-action、键盘等)。
问:Auto Layout 的 intrinsic size、Hugging/Compression?
答:内在尺寸提供默认大小;Hugging 抵抗变大,Compression 抵抗变小。
问:updateConstraints vs layoutSubviews?
答:约束变化放 updateConstraints;几何调整放 layoutSubviews。
问:自适应 cell 实现要点?
答:内容视图约束完备、优先级正确、estimatedSize 配置。
问:DiffableDataSource 的优势?
答:基于快照的线程安全 diff,避免不一致崩溃。
问:离屏渲染的原因与优化?
答:圆角、遮罩、阴影易触发;用 rasterization、路径裁剪、预渲染图片优化。
问:UI 必须在主线程的原因?
答:UIKit 非线程安全;布局/绘制需主线程。
问:Safe Area 与 Content Insets 区别?
答:Safe Area 是系统保留区域边界;Content Insets 是滚动内容的内边距。
问:大图滚动卡顿的优化?
答:异步解码、按需下采样、缓存、预取与占位。
八、网络
问:URLSession 常见任务类型?
答:data、download、upload、stream、WebSocket。
问:Codable 解码日期与键策略?
答:配置 dateDecodingStrategy、keyDecodingStrategy;或自定义 CodingKeys。
问:重试与退避策略?
答:指数退避 + 抖动;对幂等请求安全重试。
问:网络状态检测?
答:NWPathMonitor 代替旧 Reachability;仅作提示,不等同业务可用性。
问:HTTP 缓存与条件请求?
答:URLCache + ETag/If-None-Match 或 Last-Modified;合理 Cache-Control。
问:证书/公钥绑定(SSL Pinning)?
答:在认证回调校验证书或公钥指纹;注意证书更新与降级攻击防护。
问:后台传输的要点?
答:使用 background URLSession,系统代管,配合 BGProcessingTask。
问:用 async/await 包装 URLSession?
答:调用 data(from:) async API;或用 continuation 桥接旧回调。
九、数据持久化
问:UserDefaults/Keychain/File/Core Data/SwiftData 取舍?
答:偏好小量数据用 Defaults;敏感凭据用 Keychain;文件大对象;关系型/查询用 Core Data/SwiftData。
问:Core Data 上下文并发模型?
答:主队列与私有队列上下文;通过 perform/performAndWait 串行化访问。
问:轻量迁移 vs 自定义迁移?
答:字段/实体简单变更可轻量;复杂变更需映射模型与迁移策略。
问:NSPersistentContainer 的作用?
答:封装栈初始化、加载存储、提供背景上下文。
问:SwiftData 核心概念?
答:@Model 标注、@Query 自动获取、ModelContext 管理事务。
问:文件加密与保护等级?
答:NSFileProtectionComplete 等;敏感数据在设备锁定时不可访问。
问:App Group 共享数据?
答:使用 containerURL(forSecurityApplicationGroupIdentifier:) 指向共享目录。
问:iCloud 同步注意点?
答:冲突合并、离线策略、隐私与数据体量控制。
十、架构与工程实践
问:MVC 痛点与 MVVM/Redux/Clean 的改进?
答:MVC 容易 Massive-VC;MVVM 分离视图状态;单向数据流可控性强;Clean 分层解耦。
问:依赖注入的方式?
答:构造注入优先;属性注入/服务定位器次之;SwiftUI 可用环境注入。
问:模块化的收益与手段?
答:并行开发、编译加速、重用;用 SPM/多 target/二进制框架。
问:路由/导航协调器(Coordinator)模式?
答:抽离导航逻辑,降低 VC 复杂度与耦合。
问:特性开关与远程配置?
答:解耦发布与上线,灰度与 A/B;注意缓存与兜底。
问:SOLID 在 iOS 实践?
答:接口隔离、单一职责、里氏替换、依赖倒置,配合协议/组合。
问:线程安全的数据层设计?
答:不可变模型、串行化访问、actor 或队列屏障。
问:错误与日志策略?
答:区分可恢复/不可恢复;结构化日志与打点埋点。
问:国际化本地化要点?
答:String Catalogs、文案长度/排版、RTL、时区/日历。
问:可观测性与诊断?
答:统一日志、signpost、崩溃收集、性能监控指标。
十一、性能与调优
问:冷启动优化思路?
答:减小可执行体与依赖、延迟初始化、减少 ObjC 元数据/类别、优化 Storyboard。
问:Time Profiler 看什么?
答:热路径、符号化、反向调用树,找出最高自耗时与总耗时函数。
问:内存峰值与泄漏定位?
答:Allocations 看驻留对象;Leaks/Memory Graph 找循环引用。
问:滚动掉帧定位?
答:Core Animation FPS、长任务、离屏渲染、图片解码。
问:图片优化策略?
答:按需下采样(CGImageSource)、预解码、合适像素格式与缓存策略。
问:主线程卡顿排查?
答:主线程看门狗、符号化堆栈、避免同步 IO/锁竞争。
问:能耗优化?
答:批量网络、后台计划、避免频繁唤醒与定位;Energy Log 验证。
问:Swift 编译时间优化?
答:简化泛型/类型推断、减少大文件、启用增量构建、模块化。
问:二进制体积降低?
答:移除未用架构、LTO/Link Dead Code Stripping、资源切分与按需加载。
问:线程爆炸问题?
答:限制并发度、使用任务组/队列 QoS、避免无限递归异步。
十二、测试与持续集成
问:XCTest 单元 vs UI 测试区别?
答:单元快而稳定;UI 测试端到端但脆弱,需良好可测性与稳定定位符。
问:异步测试怎么写?
答:XCTestExpectation 或 async 测试 + await;设置合理超时。
问:依赖注入与可测试性?
答:通过协议与构造注入替换实现为假对象或记录器。
问:快照测试注意点?
答:控制环境一致性(字体/尺寸/主题);审慎更新基线。
问:代码覆盖率意义与局限?
答:衡量到达率非正确性;关注关键路径与分支。
问:CI/CD 常见方案?
答:Xcode Cloud、GitHub Actions + Fastlane;自动化构建、签名、测试与发布。
问:签名与配置文件基础?
答:证书 + Provisioning Profile(开发/测试/发布);Bundle ID/Entitlements 匹配。
问:崩溃符号化与回溯?
答:保留 dSYM,集成崩溃平台,符号化后分析堆栈热点。
十三、应用生命周期、后台与通知
问:App 状态与回调?
答:not running/inactive/active/background/suspended;App/Scene Delegate 生命周期。
问:后台模式有哪些?
答:音频、定位、VoIP、蓝牙、后台获取、后台处理任务等,需声明 Capabilities。
问:BGTaskScheduler 用法?
答:注册标识、提交 BGAppRefreshTask/BGProcessingTask、设置最早开始时间、注意时限与电量策略。
问:APNs 推送流程?
答:设备向 APNs 注册获取 token,服务端发推送,系统交付到 App;生产/沙盒证书或基于 token 的鉴权。
问:UNUserNotificationCenter 本地通知?
答:请求权限、创建触发器、添加请求、处理回调与分类动作。
问:前台通知显示策略?
答:实现 willPresent 回调自定义 alert/badge/sound。
问:Universal Links 处理?
答:apple-app-site-association 配置;在 Scene/SwiftUI onOpenURL 处理跳转。
问:状态恢复与深度链接一致性?
答:统一路由层,编码/解码导航状态。
十四、安全与隐私
问:Keychain 适用场景与注意点?
答:存储敏感凭据;访问组、同步、项级别访问控制;避免明文。
问:ATS 是什么?
答:App Transport Security 强制安全网络(HTTPS);例外需说明理由。
问:隐私权限最佳实践?
答:按需请求、清晰用途描述、失败兜底、尊重用户选择。
问:剪贴板/传感器隐私提示?
答:最小化访问并明确用户操作触发;系统会显示访问提示。
问:加密与签名建议?
答:使用 CryptoKit,高层 API 优先;需要时用 Secure Enclave。
问:生物识别策略?
答:LAContext 评估策略、回退口令、错误处理与 UI 提示。
问:日志脱敏?
答:避免记录 PII/密钥/Token;按需采样与加密。
问:反破解与完整性?
答:Jailbreak 检测有限;重在后端校验、API 限流与风控。
十五、工具链与依赖管理
问:SPM/Pods/Carthage 取舍?
答:SPM 官方优先、集成轻;Pods 生态广但引入工作区;Carthage 二进制/预编译控制更细。
问:XCFramework 的优点?
答:统一多架构与平台分发,替代 fat frameworks。
问:Build Configuration/Scheme 的作用?
答:区分 Debug/Release/自定义环境;配合编译标记与配置文件。
问:App thinning/ slicing 与 bitcode(已弃用)的现状?
答:App Thinning 仍有效;Bitcode 已被弃用,专注资源与架构裁剪。
问:符号与日志的等级管理?
答:OSLog 分类/级别,控制生产环境开销与隐私。
问:依赖库集成后是否还需构建?
答:需要。依赖解析/编译/链接发生在构建期,才能运行与打包。
十六、常见“手撕”与思考题
问:设计一个图片缓存组件要考虑什么?
答:内存+磁盘缓存、LRU、下采样、并发下载合并、缓存键、失效策略、可观测性。
问:实现去抖与节流?
答:基于 DispatchWorkItem/Task 或 Combine/AsyncSequence;去抖延迟执行、节流限频。
问:线程安全的计数器/队列如何实现?
答:actor/串行队列/锁;权衡吞吐与公平性。
问:避免 TableView 重用错位?
答:cellForRowIdempotent、取消旧请求、使用 index 变化检测与占位。
问:图片瀑布流的性能优化?