swift 面试题

一、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 变化检测与占位。

问:图片瀑布流的性能优化?

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容