
2017年那会儿移动直播正是最火的时候欢聚时代YY作为老牌音视频厂商校招笔试的含金量在业内是出了名的。当时iOS岗的C卷拿到手第一感觉是“题量不大但每一道都扎在开发日常的痛点上”。不像有些公司喜欢考脑筋急转弯YY的题更偏向于“你平时到底有没有认真写代码、有没有踩过坑之后去翻源码”。这份C卷我印象比较深核心考察范围基本集中在Objective-C语言特性、内存管理、UIKit布局机制、多线程网络以及一批跟App性能相关的实战问题。很多题目放到今天来看依然很有价值尤其是iOS 11刚出、iPhone X引入刘海屏的那个时间节点适配问题已经开始大规模出现。这篇文章我就以C卷为线索把当年那批高频考点完整复盘一遍同时结合现在iOS开发里仍然绕不开的知识点做一次延伸对准备iOS面试或者想系统补基础的同学应该会有实打实的帮助。1. 笔试整体设计与命题思路解读1.1 2017年iOS岗校招命题的时代背景要理解这套题必须先回到2017年的技术语境。那时候Swift已经发布了三年但绝大多数商业项目的主力语言还是Objective-C尤其是像YY这种音视频业务极其复杂的App底层框架和核心模块几乎全是用OC写的。所以C卷的考察重点很明确OC的语言功底、Runtime机制、内存管理、多线程和网络。另一个时代特征是iOS 11刚发布不久。iPhone X的刘海屏、安全区域Safe Area、ARKit、Core ML都是那个时间节点的热点。笔试里出现“适配iPhone X”相关的题目几乎是标配考察你对UIWindow、SafeAreaInsets、布局约束这些底层概念是否真的理解到位。还有一个隐藏的背景直播业务对流畅度和稳定性要求极高。欢聚时代做的是音视频互动卡顿、内存暴涨、Crash率这些指标直接关系到用户体验。所以笔试题里会频繁出现性能优化方向的问题比如RunLoop卡顿检测、内存泄漏排查、图层渲染优化。这些不是单纯的八股文而是真实业务里每天都在面对的问题。1.2 C卷题型分布与考察能力地图复盘这套题整体结构大概是四类基础语言题、UI与架构题、多线程与网络题、性能与工程能力题。占比大约是3:3:2:2没有纯粹的概念默写每一道都有实际场景做载体。题型分类典型考察点命题意图OC语言基础属性修饰符、内存管理、Runtime、KVO筛选真正用过OC而不是只写过Swift的人UI与布局Auto Layout、UIStackView、屏幕适配判断日常开发是否理解布局引擎原理多线程网络GCD死锁、NSOperation、网络层封装考察并发编程的实操经验和踩坑深度性能优化RunLoop、卡顿检测、离屏渲染评估是否有线上问题排查经验这里有个很关键的信号YC卷几乎不考“概念解释题”比如不会问你“什么是代理模式”而是直接给你一段有内存泄漏的代码让你找问题。这说明他们想招的是能直接上手干活的人而不是背了两周面试题就来笔试的人。后面我逐题拆解的时候大家会明显感受到这个风格。2. 核心基础题解析内存管理、Runtime与KVO2.1 Objective-C内存管理必考三连问C卷第一部分是三道跟内存管理强相关的题。第一道是经典的“属性修饰符选择”题给你一个NSString属性和一个block属性问分别应该用assign还是weak、copy还是strong。这道题如果只是背过答案很容易在block那道翻车。NSString属性用copy而不是strong这个大多数人知道原理是为了防止可变字符串被外部修改。但很多人忽略了NSMutableString赋值给copy属性时返回的实际上是一个不可变副本immutable copy后续如果代码里对这个属性做了NSMutableString的专属操作比如appendString会直接crash。这种坑在笔试里不会直接告诉你而是给你一段代码让你推测运行结果。block属性用copy这一点在ARC下其实用strong也能工作因为ARC下编译器会自动对block做copy操作。但2017年的时候很多老项目还在用MRC兼容写法所以标准答案仍然是copy。更深一层的问题是block在栈上和在堆上的区别是什么为什么block要copy到堆上才能安全地在方法作用域之外使用如果理解不到位后面结合循环引用的题基本必错。第二道是地址类问题为什么 weak 修饰的变量在对象释放后会自动变成 nil。底层原因是Runtime维护了一个全局的weak表以对象地址为keyvalue是所有指向该对象的weak指针地址数组。对象释放时Runtime通过这个表把所有weak指针置为nil然后从表中移除记录。这道题很多人知道结果但答不出“全局weak表”这个底层机制面试官能立刻判断你是背的还是真懂。第三道是内存泄漏排查场景题给你一段在block里使用self的代码问你有没有问题怎么改。这题考核的就是循环引用的本质。用weakSelf能解决大部分问题但还有一个细节是weakSelf在block内多次使用时需要先转成strongSelf防止执行过程中self被提前释放。这个细节当年的标准教程里讲得少反而是在实际开发中踩了坑才真正理解。实操心得笔试里遇到这种改代码题不要只改一行就完事。尽量写出“为什么这样改”的注释或者用简短文字说明原理。批卷的人一眼就能看出来你是在背答案还是真的懂内存管理。2.2 Runtime消息机制与Method SwizzlingRuntime相关的题C卷考了一个很实际的问题Objective-C的方法调用在底层是怎么执行的。标准回答链路是objc_msgSend → 查找isa指针 → 沿着继承链找到方法列表 → 找不到时走消息转发流程。但光答这个还不够后面追问才是重点方法缓存method cache是怎么工作的为什么动态添加方法后第一次调用会慢。这里有一个很实用的考点class_addMethod和resolveInstanceMethod。当时直播App里大量使用JSPatch这类热修方案底层就是靠Runtime动态替换方法实现的。笔试题目给了一个场景线上Crash需要不下发版本就修复让你设计一个最小的热修方案。这就是在考察Method Swizzling的实际应用。Method Swizzling的核心是交换两个IMP指针。但很多人写Swizzling时会掉进一个坑在分类的load方法里做交换没有用dispatch_once保护导致交换了两次又换回去了。交换时要处理继承关系不能在父类和子类之间乱交换。这些细节在笔试的代码改错题里都是高频陷阱。还有一个很隐蔽的坑Swizzling Apple私有方法或者系统方法后回调里没有调用original实现会导致整个App所有用到这个方法的页面全部出问题。我在实际项目里见过有人Swizzle viewDidLoad之后忘了调原方法结果所有控制器都不走系统初始化流程页面直接白屏。这种经验类的东西笔试时如果能主动写出来会是非常大的加分项。2.3 KVO底层原理与常见坑KVO那道题给的场景是监听一个对象的属性变化但在dealloc里没有移除观察者问会有什么后果。很多人只知道“会Crash”但不知道Crash的触发条件是什么。实际上iOS 11之前观察者被释放后如果对象继续发通知会野指针Crash。iOS 11之后系统做了改进会在对象释放时自动清理KVO注册但这只适用于系统自动注册的情况手动注册的依然要手动移除。KVO的底层原理是动态生成子类。当你第一次对某个类启用KVO时Runtime会动态创建一个新类这个新类是原类的子类重写了被观察属性的setter方法在setter里插入willChangeValueForKey和didChangeValueForKey的调用然后把对象的isa指针指向这个新类。这就是为什么KVO触发的对象用class方法查到的类名会变得很奇怪比如NSKVONotifying_Person。笔试的加分回答是提到automaticallyNotifiesObserversForKey这个方法的用途。当你需要手动控制KVO通知时机时可以通过重写这个方法返回NO然后在合适的时机手动调用willChangeValueForKey和didChangeValueForKey。这在做连续动画、批量更新场景下极其有用因为默认的setter通知频率太高会导致不必要的UI刷新。注意KVO触发条件是setter方法被调用直接修改成员变量不经过setter不会触发通知。这个坑在笔试里经常以“修改成员变量后为什么UI没刷新”的形式出现。3. UI与布局从Auto Layout到UIStackView3.1 Auto Layout与Frame布局的选择题坑点UI部分的题有一道是让判断在viewDidLoad里拿到一个视图的frame返回的值是否准确。答案是“不一定准确”。因为Auto Layout布局是延迟执行的viewDidLoad阶段约束还没完全生效frame可能还是xib里的初始值。真正的布局完成要到viewDidLayoutSubviews或者layoutSubviews之后。这个知识点在2017年面试iOS岗时基本是必考的。还有一个高频选择masksToBounds和clipsToBounds有什么区别。答案是clipsToBounds控制的是视图自身内容是否超出边界被裁剪masksToBounds是CALayer的属性两者控制的是同一件事但一个是UIView层面一个是Layer层面。设置clipsToBounds本质上是设置了layer.masksToBounds。这道题看似简单但在涉及圆角性能优化时非常关键因为masksToBounds为true会触发离屏渲染影响滚动流畅度。C卷还考了一道布局优先级Content Hugging / Compression Resistance的实际应用题。场景是一个UILabel和一个UIButton放在同一行UILabel内容很长UIButton固定宽度问怎么设置约束让UILabel优先被压缩而不是UIButton被压缩。答案是提高UIButton的Compression Resistance Priority让它在内容放不下时抵抗压缩的能力更强。很多人知道这两个属性存在但不知道应用场景这道题就是专门筛这类人的。3.2 页面布局实战题聊天页输入框这是一道手写约束的实战题。场景是做一个聊天页面底部有一个输入框输入框包含UITextField和发送按钮要求键盘弹出时输入框跟着上移键盘收起时回到原位。这道题考察的点很多键盘通知的监听、UIWindow的frame变化、Auto Layout约束的动画更新。常规做法是监听UIKeyboardWillChangeFrameNotification在回调里取出键盘的endFrame然后用键盘的y坐标和屏幕高度算出键盘遮挡的高度修改输入框底部的约束constant。这里有一个很关键的细节键盘通知里的动画时长和动画曲线参数也要取出来放在UIView animate里保持动画节奏一致否则输入框的移动会和键盘动画脱节看起来非常生硬。还有一个容易踩的坑在iOS 11之后如果使用Safe Area布局输入框底部约束要相对于safeAreaLayoutGuide而不是view的底部否则在iPhone X上会被Home Indicator区域遮挡。这个适配问题是2017年iPhone X发布后几乎所有团队都遇到过的真实问题笔试里碰到说明命题人非常贴近一线。我当时给这道题的答案是使用约束加constant修改的方式同时把键盘的duration和curve都带上。批改标准里有一条备注如果使用约束且考虑了Safe Area可以得满分如果直接用代码计算frame并修改origin只能拿一半分因为键盘升降过程中frame的动画处理远不如约束来得干净。3.3 延伸考点UIStackView为什么值得掌握UIStackView虽然iOS 9就推出了但2017年很多项目还是用纯代码或xib做布局对这个类掌握程度普遍不高。C卷有一道加分题问UIStackView的设计目的和适用场景。答案是UIStackView不是用来替代Auto Layout的而是为了减少约束代码的复杂度。它通过axis、distribution、alignment、spacing四个属性把一组视图的约束关系自动化了。比如一排按钮的等宽布局如果用Auto Layout手写至少需要5条约束用UIStackView只需要设置distribution为fillEqually。延伸考点是嵌套StackView和 content hugging 的关系。StackView本身不提供固有内容大小它的尺寸由内部子视图决定所以子视图的Intrinsic Content Size必须正确。这就是为什么UILabel、UIButton这类系统控件在StackView里表现良好但自定义View如果不实现intrinsicContentSize就会出现布局混乱。实操心得UIStackView在动态增删视图的场景下非常强比如直播间的礼物面板、商品规格选择器。它是基于Auto Layout的大规模列表页里不要在cell上嵌套太多层StackView会显著增加布局计算成本。合理做法是静态布局用StackView动态列表用UICollectionView。4. 多线程与网络GCD、NSOperation与网络层设计4.1 GCD必考死锁、队列与信号量多线程的题C卷最经典的是那道“在主队列同步执行任务会怎样”的问题。标准答案是死锁。原因主队列是串行队列mainQueue上的任务必须等前一个执行完才能执行下一个而你在主线程执行的任务A里又同步追加了任务B任务B要等任务A完成才执行但任务A又要等任务B完成才能返回形成循环等待。这道题基本年年都有但很多人只知道“主队列同步死锁”而不知道为什么串行队列里同步派发也死锁。其实只要是在任意一个串行队列里向自身同步dispatch一个任务都会死锁。理解了这一点才能正确回答面试官后续的“全局并发队列里死锁吗”这个问题——是不同队列不会互相等待所以不死锁。C卷还考了信号量dispatch_semaphore的用法场景是控制并发请求数量。比如一个页面要同时请求10张图片但不想一次性开10个线程希望最多同时3个。标准做法是创建一个value为3的信号量每个任务开始前wait完成后signal。这里有一个很重要的细节信号量的wait不能放在主线程否则一旦信号量不够用主线程会被阻塞界面直接卡死。当年很多同学笔试时会在代码注释里写“信号量放主线程会卡”这就是区分有没有实战经验的地方。还有一道经典的坑题dispatch_async到主队列的block是在主线程执行的但如果主线程已经被某个同步操作阻塞了这个block会一直等。现在很多网络库都使用回调线程池如果回调里又做了主线程操作没写同步保护就会出现奇怪的数据错乱。笔试里给的排查场景正是这种偶尔出现UI在非主线程更新的Crash让你分析原因。4.2 网络层设计题直播业务请求怎么封装网络部分有一道设计题问怎么设计一个网络层框架给直播业务使用。这题没有标准答案但有几个考点是明确的请求的取消机制、请求的优先级、统一错误处理、数据解析的线程策略。我当时给了一个基于NSURLSession的方案。核心逻辑是每个请求对应一个NSURLSessionDataTask通过taskIdentifier维护一个字典取消时根据taskIdentifier找到对应的task调用cancel。为什么要维护taskIdentifier而不是直接保存task对象因为回调时NSURLSession只返回task不返回你自定义的请求模型必须有一个映射关系才能知道这个回调对应哪次请求。优先级处理是一个容易被忽略的点直播场景里的弹幕消息、礼物消息对实时性要求高普通聊天消息可以稍后。NSURLSession本身没有优先级参数只能通过NSURLSessionConfiguration里的httpMaximumConnectionsPerHost间接控制或者在上层做排队调度。严格的实时业务一般走长连接而不是HTTP轮询所以普通网络层只需要做到请求与业务解耦就够了。统一错误处理也是考察点之一。比如接口返回的业务码非200网络超时无网络三种错误类型需要区分处理。2017年流行的是在Manager层统一判断然后通过block回调一个带errorCode和errorMsg的模型。现在主流用PromiseKit或者Combine但核心思想没变底层回调上抛时必须把NSError正确转换为业务层能识别的错误模型。注意网络层最容易写崩的地方是回调线程。NSURLSession的completionHandler默认在子线程回调如果你在里面直接操作UI会触发“只在主线程操作UI”的Crash。标准做法是回调里先用dispatch_async切回主线程再刷新UI这是一个很基础但经常被忽略的点。4.3 延伸考点iOS抓包与网络调试这道题在C卷里没有直接出现但面试环节大概率会追问你在开发中怎么调试网络问题。2017年主流方案是Charles抓包。当年Charles还不需要处理HTTPS证书信任问题iOS 10之后ATSApp Transport Security强制开启HTTP明文请求默认被拦截所以开发阶段需要在Info.plist里配置NSAppTransportSecurity的NSAllowsArbitraryLoads才能抓包。后来iOS 10增加了NSAllowsArbitraryLoadsInWebContent这个key只对WebView放开。审核时的合规做法是只允许特定域名的HTTP请求。这种细节在当时很容易踩坑配置成全部放开上架审核被拒理由就是“使用了明文网络传输”。笔试中如果能在网络相关题目里提到“ATS配置”这个点会明显加分。现代开发里我建议用Charles或者Proxyman这类工具在调试阶段抓包但要特别注意抓包工具本质是在本地建立了一个代理手机上安装的是代理证书。如果手机上的证书是公司内部证书或者装了一些不可信的描述文件不建议在非调试设备上随意开启全局代理容易被中间人窃取数据。安全底线是调试环境只连自己的开发代理生产环境不配置任何代理。5. RunLoop与系统机制读懂App运行的心脏5.1 RunLoop常见模式与事件响应RunLoop在iOS面试题中的出现频率极高C卷直接考了一道讲一下RunLoop的几种运行模式Mode以及滑动TableView时为什么滚动会卡。这道题考察的深度在于很多人知道RunLoop有Default和Tracking两种模式但不理解Mode切换的机制。当前Mode决定RunLoop在哪个状态下处理哪些事件源如果把高耗时操作放在Default模式下用户开始滚动屏幕时Mode切换为Tracking高耗时操作不会立刻停止而是继续占用CPU导致滚动掉帧。延伸考点是NSTimer在TableView滚动时为什么暂停。因为NSTimer默认添加在DefaultMode下Tracking模式下不处理DefaultMode的timer事件。解决办法是把timer添加到NSRunLoopCommonModes下这样它在两种模式中都能被处理。另一个常考的是RunLoop的Observer。利用RunLoopObserver可以在每个runloop循环开始和结束时做一些事情比如AutoreleasePool的释放就是通过Observer实现的。C卷给的场景是想要实现一个“滑动时不加载图片停止滑动后再加载”的优化策略思路就是监听RunLoop在Tracking模式的进入和退出进入时暂停图片加载退出时重新开启。这个方案在当时的图片列表优化里非常常用现在SDWebImage等框架里也都留有类似的优化思路。5.2 卡顿检测与性能优化思路卡顿检测在2017年已经是很成熟的面试题。C卷有一道题是线上用户反馈App滑动卡顿但本地无法复现你怎么定位问题。核心方法是利用RunLoopObserver监控主线程的卡顿在mainRunLoop上添加一个Observer监听kCFRunLoopBeforeSources和kCFRunLoopAfterWaiting这两个状态记录两个状态之间的时间差如果超过阈值比如50ms就认为主线程卡顿采集当时的调用栈上报。这个方案当时已经是行业标配但笔试如果只答到这里只能算及格。加分的回答是提到符号化symbolicate线上收集到的是内存地址形式的调用栈需要用dSYM文件符号化才能还原成类和函数名。所以接入卡顿监控的同时必须建立dSYM符号表管理系统否则采集到的数据根本没法看。更深一层是离屏渲染Offscreen Rendering的理解。C卷问为什么设置圆角会卡顿怎么优化。原因是cornerRadius masksToBounds会让系统在离屏缓冲区先渲染一张带圆角遮罩的图再提交到屏幕这个过程触发GPU额外工作。优化方案有几个只对四个角中需要的角做mask或者用UIBezierPath做圆角裁剪或者直接使用带圆角的背景图片。2017年QQ音乐等团队已经常年在分享这些优化。还有一个性能点是Auto Layout的布局开销。复杂的视图层级约束计算会显著拖慢页面加载。笔试给的场景是一个cell里有20多个视图全部用Auto Layout滑动时明显卡顿。优化方案主要是减少约束数量改用frame布局或者把不变化的布局结果缓存起来。这个点当时很有时代背景后来iOS 12对Auto Layout做了大幅性能优化约束数量对性能的影响已经没那么恐怖了但面试官依然喜欢问因为考察的是你是否有通过布局层面做性能优化的意识。6. 工程能力题从真题到现代iOS开发的延伸6.1 自动化测试与持续集成C卷的收尾部分有一道开放题你所在的项目是怎么做版本管理的测试怎么做的如果让你搭一套持续集成流程你会怎么做。这道题对没接触过团队协作流程的应届生来说很有区分度。2017年移动端持续集成的主流方案是Jenkins fastlane。fastlane负责打包、签名、上传测试平台Jenkins负责定时触发和构建。我当时遇到的坑是证书管理团队多人开发时证书和描述文件放在同一个Apple Developer账号下经常出现“证书失效导致打包失败”的问题。fastlane的match工具就是为了解决这个问题把证书和描述文件统一版本管理到Git仓库。笔试的加分回答是提到“自动化测试的分层”单元测试用XCTestUI测试用XCTest UI或者KIF覆盖率检测用Xcode自带的Coverage功能。但真正线上的核心业务自动化测试更多覆盖的是数据层和逻辑层UI层由于变化频繁、维护成本高一般只覆盖关键路径。这个认知比单纯堆工具名称更能体现工程经验。6.2 签名、证书与上架流程2017年的C卷里有一道很现实的问题描述文件Provisioning Profile过期了怎么办App上架被拒了怎么办。很多人一看这种题就不想答觉得跟技术无关。但实际上凡是经历过上架流程的人都知道签名和证书问题是最耗时间的坑。iOS签名机制的核心是描述文件绑定了开发者证书和App ID打包时系统通过描述文件校验开发者的身份以及App的Bundle ID是否匹配。如果描述文件过期需要重新生成。如果证书失效要重新创建CSR请求。这套流程在今天依然一样。再说上架被拒最常见的原因是使用了私有API、权限描述文案不完整比如用了相机必须在Info.plist里写NSCameraUsageDescription说明用途、App内购买未走IAP。C卷给了一个真实场景App因为“iPad版本没有适配所有屏幕方向”被拒问怎么处理。解法是要么把iPad的supportedInterfaceOrientations设为全部支持要么声明仅支持竖屏。这个问题放到2025年已经没有那么严格了但理解“拒绝原因对应的技术修复”这个思路还是一样的。实操心得上架前用Xcode的Archive导出时按实际情况选“App Store Connect”还是“Development”。很多新人这一步选错导致导出包无法上传。另外iOS开发者账号最好单独申请一个企业邮箱不要用个人邮箱因为后续的所有审核通知都会发到注册邮箱。6.3 混合开发与跨端方案C卷有一道论述题你怎么看待Hybrid开发它和原生开发各自的优劣势是什么。2017年的主流混合方案是UIWebView/WKWebView加JSBridge核心逻辑是JS调用原生能力原生通过回调把结果返回JS。这题的高分回答需要拿出具体场景来对比。以YY直播为例直播间的礼物面板、弹幕协议是原生实现因为对性能和实时性要求极高而活动页面、运营配置页可以用H5实现因为更新频繁原生审核会耽误运营节奏。这个思路到今天依然成立有复杂交互和强性能要求的页面用原生纯展示类和运营活动类页面用H5。跨端方案的演进也是加分项。2017年React Native已经进入一些大厂的核心业务阿里Weex也在力推。C卷问如果选择React Native你担心什么问题。正确答案是长列表性能、复杂的原生交互、多端一致性问题。后来很多团队转投Flutter/自研跨端方案也验证了这些问题确实存在。所以现在的面试题如果还停留在“RN好不好”深度其实不如当年那批题因为经历了大规模落地和回退之后大家更关心的是“什么场景该用什么方案”。6.4 iOS分屏适配与多任务iPad分屏是iOS 9引入的能力2017年笔试里出现过一个适配题你的App支持分屏后布局为什么乱了怎么处理。核心是Size Classes的适配要针对compact宽度做布局压缩处理还有就是Safe Area的概念。iOS 11之后UIView的safeAreaInsets成为适配刘海屏和iPad分屏的关键属性。如果用frame布局需要手动处理safeAreaInsets变化如果是用Auto Layout把约束到superview的边距改成到safeAreaLayoutGuide。这里有个易错的点safeAreaInsets不是固定的在横竖屏切换、分屏启动时都会变化不能在viewDidLoad里死记一个值当常量用要在viewSafeAreaInsetsDidChange和viewDidLayoutSubviews里动态获取。延伸到现在iOS 26时代大家讨论的已经是灵动岛适配、外接显示器场景了但底层思路没有变任何系统级的UI环境变化都要有一套机制去感知和响应。掌握了这套响应机制不管系统怎么更新都能快速适配。实操心得分屏适配最省力的方式是全部使用Auto Layout Safe Area不要用绝对坐标计算。有些老项目大量使用frame做布局分屏场景下很容易出现视图错位。如果项目确实无法改造成约束布局那就只能声明不支持分屏多任务在Info.plist里配置UIRequiresFullScreen为YES。这在功能交付和开发成本之间做一个取舍很多时候是可以接受的方案。7. 常见问题与排查技巧实录7.1 内存问题排查速查表笔试里考了内存管理和泄漏实际开发中排查内存问题的思路比背概念更重要。我整理了几年下来最实用的排查路径把常见的现象、原因和解决手段列在一起方便对照常见现象可能原因排查手段解决方向内存持续上涨循环引用导致对象无法释放Instruments-Leaks / Allocations用weak修饰代理和block内self大块内存飙升图片未压缩、重复加载Allocations查看堆栈用ImageIO缩放、缓存复用内存Crash集合类越界、野指针Zombie Objects / Address Sanitizer检查数据源、空值保护写入过多日志导致内存上涨NSLog高频输出查看Console输出频率用条件编译控制Debug日志7.2 崩溃问题定位的实战流程还有一类高频场景是线上Crash率突然升高。2017年移动端崩溃监控的主流是Bugly和友盟定位流程基本是收集Crash日志 → 符号化 → 查看主线程调用栈 → 根据堆栈定位具体代码。有个非常隐蔽的坑很多OC的Crash是由NSString的nil插入导致的。比如NSMutableArray里插入nil会直接崩溃但很多人以为只是日志打错。在团队规模不大、没有全面空值保护机制的时代这种崩溃每天都能遇到。解决思路是在团队规范里强制要求集合类操作前做nil判断同时用Category给NSMutableArray加安全性保护。后来有人实现了YYKit里的Safe系列分类其实就是这个思路。另一个容易忽略的是主线程卡死导致的“假死”问题。这类问题Crash日志里往往没有记录需要靠卡顿监控才能发现。卡顿监控的上报时机要选在RunLoop卡顿持续超过阈值时一次性采集多帧调用栈而不是每卡一次就上报一次否则会把用户流量吃光。7.3 笔试中的答题技巧回到笔试本身最后分享一些实际经验。欢聚时代这类注重工程能力的公司批卷时会更看重你“能不能看出问题背后的原因”。所以答题时不要只写答案尽量把“为什么”写出来。比如问“block为什么要用copy”只写“防止栈上block被回收”只能算一半分如果能补充“block在栈上时作用域结束会被释放ARC下编译器会拷贝到堆上所以用copy更安全”分数会高很多。还有一个技巧是遇到开放题先分点再展开每一点用一个真实场景带出来。比如问“怎么做网络层设计”先列“请求管理、错误处理、线程策略”三个层面再对各层面写一两个关键细节。批卷人看到的是你的结构化思考能力不只是知识点堆砌。最后提醒一句笔试考的是基础但基础不是背出来的。iOS开发这么多年最核心的OC内存管理、RunLoop、多线程这些知识到现在依然是面试必考点。把原理理解透了不管题目怎么翻新你都能往深处答。我个人的体会是当年那道C卷的价值不只是帮我拿到了面试机会更是让我知道自己的短板在哪里——哪些东西只是“用过”而没“理解”哪些坑是踩过了才知道怎么躲的。