第3章:架构设计核心问答
本章精选三个高频架构面试题,覆盖MVVM、组件化、网络层三大设计方向。掌握结构化回答框架,结合项目实例,避免“只背概念、不谈落地”的常见扣分点。先通过一张回答路径图建立通用表达逻辑,再逐一拆解每个问题。
核心架构模式对比
| 模式 | 核心思想 | 适用场景 | 主要优缺点 |
|---|---|---|---|
| MVC | Model-View-Controller 三层职责分离 | 中小型项目、快速迭代 | 简单直观,但Controller易膨胀 |
| MVVM | 数据绑定驱动 ViewModel 状态管理 | 复杂交互、需单元测试 | 解耦良好,调试复杂度上升 |
| 组件化 | 业务模块独立,通过路由通信 | 大型团队、多业务线并行 | 高复用、高并行,但初期投入大 |
面试问题:谈谈你对 MVVM 的理解,以及它相比 MVC 的优势和劣势?
面试官考察点:
- 是否真正理解数据绑定与双向驱动
- 能否客观分析优缺点,而非仅背诵教材
- 是否有实际项目中使用 Reactive 框架的经验
回答框架:
- 定义 MVVM 三要素(Model / View / ViewModel)
- 数据绑定的实现方式(KVO / ReactiveSwift / Combine)
- 优点:View 与 ViewModel 完全分离,可独立测试
- 缺点:绑定带来隐式调用,调试困难;简单场景过度设计
- 结合项目说明如何平衡(例如仅在核心业务模块使用 MVVM)
示例回答:
MVVM 通过数据绑定将 View 与 ViewModel 解耦,ViewModel 持有 Model 并暴露状态。在 XX 项目中,我们使用 RxSwift 实现登录模块 MVVM,使得 View 只响应状态变化,Controller 体积减少 60%。但调试时需跟踪绑定链路,容易产生内存泄漏。总体而言,MVVM 更适用于复杂表单和列表页,简单页面仍推荐 MVC。
可能追问:
- 你用过哪些绑定库?如何处理循环引用?
- ViewModel 之间如何通信?
- 如果 ViewModel 需要依赖多个 Service,如何管理?
避坑提醒: 不要只说“MVVM 比 MVC 好”,要展示权衡过程;避免只背概念,必须提到你实际踩过的坑(如调试困难、内存泄漏等);切忌夸大适用范围,否则面试官会认为你缺乏实践经验。
面试问题:如何设计一个高可复用的组件化架构?
面试官考察点:
- 对组件拆分粒度的认识
- 通信机制的选择(路由 vs 依赖注入)
- 组件间耦合的控制策略
回答框架:
- 确定组件划分原则(按业务域,非按功能)
- 定义路由协议与注册中心
- 依赖管理与接口下沉(基础库与中间件)
- 组件间通信采用 URLRouter 或协议接口
- 通过自动化工具(如 CocoaPods + 私仓)管理版本
示例回答:
我们采用“业务组件+基础组件”两层结构,每个业务组件通过 MGJRouter 注册路由,暴露协议接口而非具体类。组件间直接依赖仅允许基础组件(网络、存储、UI),业务组件之间只能通过路由或事件总线通信。使用 CocoaPods 私有源管理版本,并设置 CI 自动化打包,确保组件独立发布与隔离。
可能追问:
- 如何解决组件间循环依赖?
- 组件化后启动优化怎么做?
- 路由和协议接口各有什么优缺点?
避坑提醒: 切忌只谈理论不谈落地细节(如版本冲突、调试困难);不要只说“我用了组件化”,要说明组件粒度的具体划分依据;避免认为组件化能解决所有问题,需承认初期成本与兼容性负担。
面试问题:iOS 中如何进行网络层架构设计?
面试官考察点:
- 对网络请求生命周期管理的理解
- 错误处理与重试机制的实现
- 缓存策略与离线支持
- 是否考虑过 mock 与测试
回答框架:
- 封装基础网络库(基于 NSURLSession 或第三方)
- 构建请求拦截器(日志、认证、签名)
- 定义统一数据解析与错误转换层
- 加入重试、缓存、弱网策略
- 对外暴露协议接口,便于 mock 与单元测试
示例回答:
我们基于 Alamofire 二次封装,通过 RequestInterceptor 实现 刷新与签名。统一使用 Result 模式返回,并将业务错误码映射为自定义 Error。缓存层使用 URLCache + 磁盘缓存,根据接口特点区分强制缓存与协商缓存。最后通过依赖注入提供 Mock 实现,确保单元测试不依赖真实网络。
可能追问:
- 如何实现请求优先级与取消?
- 如何处理同时多个请求的 竞争?
- 缓存过期策略如何设计?
避坑提醒: 不要只讲“用了 Alamofire”,要说明你做了哪些二次封装;避免忽略错误处理的细节(如 401 自动重试、网络切换时的队列暂停);切记提及测试与 mock,这是架构师岗位的高分加分点。