一、内存管理专题:ARC机制下的循环引用破解
在百度二面中,内存管理是高频考点,尤其关注开发者对循环引用的处理能力。典型问题包括:
真题1:如何检测并修复UIViewController中的循环引用?
class MyViewController: UIViewController {var closure: (() -> Void)?override func viewDidLoad() {super.viewDidLoad()closure = { [weak self] inself?.view.backgroundColor = .red}}}
解析要点:
- 循环引用本质:当
self被强引用捕获时,若闭包又被self持有,则形成闭环。修复需通过[weak self]或[unowned self]打破强引用链。 - 检测工具:使用Xcode的Memory Graph Debugger可视化引用关系,或通过
malloc_history命令分析堆栈。 - 最佳实践:
- 默认使用
weak避免崩溃风险 - 在明确生命周期的场景下(如单例),可谨慎使用
unowned - 结合
deinit日志验证对象是否正确释放
- 默认使用
真题2:NSTimer导致的循环引用如何解决?
// 错误示例class TimerHolder {var timer: Timer?func startTimer() {timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [self] _ inprint("Tick")}}}
解决方案:
- 使用
weak属性持有timer -
通过
Target-Action模式重构:class TimerHolder {private weak var target: AnyObject?private var timer: Timer?func startTimer() {target = selftimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(handleTimer), userInfo: nil, repeats: true)}@objc private func handleTimer() {print("Tick")}}
二、多线程与并发编程:GCD高级应用
百度面试官常通过实际场景考察GCD的深层理解,例如:
真题3:如何实现一个线程安全的队列?
class ThreadSafeQueue<T> {private var queue = [T]()private let serialQueue = DispatchQueue(label: "com.example.serialQueue")func enqueue(_ element: T) {serialQueue.async {self.queue.append(element)}}func dequeue() -> T? {var result: T?serialQueue.sync {result = queue.firstif let result = result {queue.removeFirst()}}return result}}
关键点:
- 同步与异步选择:
dequeue使用sync保证数据一致性,enqueue可用async提升性能 - 性能优化:对于高频操作,可考虑
DispatchQueue(label: ..., attributes: .concurrent)配合NSLock实现更细粒度的控制 - 主流云服务商实践:类似需求在服务端开发中常通过分布式锁(如Redis实现)解决,移动端更强调轻量级方案
三、UI性能优化:从离屏渲染到预加载
百度对App流畅度的要求极高,相关问题包括:
真题4:如何系统性优化UITableView性能?
优化框架:
- 预计算与缓存:
```swift
// 示例:缓存cell高度
private var heightCache = IndexPath: CGFloat
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if let cachedHeight = heightCache[indexPath] {
return cachedHeight
}
let height = // 计算高度
heightCache[indexPath] = height
return height
}
2. **异步绘制**:对复杂视图使用`drawRect:`替代直接添加子视图,减少层级3. **预加载策略**:- 滚动停止时加载下一页数据- 使用`UITableView.prefetchDataSource`实现智能预取4. **离屏渲染规避**:- 避免使用`cornerRadius + masksToBounds`组合- 改用预渲染图片或`CAShapeLayer`实现圆角### 四、架构设计能力考察:模块化与解耦**真题5:如何设计一个支持热插拔的模块化框架?****设计思路**:1. **协议驱动**:```swiftprotocol ModuleProtocol {var moduleName: String { get }func start(with context: Any?)}
-
动态加载机制:
class ModuleManager {private var modules = [String: ModuleProtocol]()func registerModule(_ module: ModuleProtocol) {modules[module.moduleName] = module}func startModule(_ name: String, context: Any?) {modules[name]?.start(with: context)}}
- 依赖注入:通过构造器或属性注入方式解耦模块间依赖
- 主流云服务商借鉴:类似OSGi框架的模块生命周期管理,但移动端需简化实现
五、面试准备建议
- 代码实战:对每个知识点实现Demo,例如用
Instruments的Time Profiler分析性能瓶颈 - 系统原理:深入理解RunLoop、AutoreleasePool等底层机制
- 软技能提升:
- 使用STAR法则描述项目经验
- 准备”最具挑战的技术问题”等行为题答案
- 百度技术栈关注点:
- 了解其移动端开源项目(如动态化框架)
- 熟悉混合开发(H5+原生)的调试技巧
六、总结
百度深圳二面强调技术深度与工程能力的结合,既考察对iOS基础知识的掌握,也注重解决实际问题的能力。建议开发者通过以下方式提升竞争力:
- 构建知识体系:将碎片知识点串联成完整的技术图谱
- 实践驱动学习:通过开源项目或自研工具验证理论
- 关注行业趋势:了解服务端与移动端的协同优化方案
通过系统性准备和针对性练习,开发者能够更从容地应对技术面试,展现专业实力。