尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

爱奇艺秋招iOS笔试题深度解析:KVO、Runtime与多线程核心考点全梳理

爱奇艺秋招iOS笔试题深度解析:KVO、Runtime与多线程核心考点全梳理 1. 整体出题思路与考察重点解析1.1 这套题到底在考什么每年的秋招笔试都是千军万马过独木桥爱奇艺这套iOS方向的笔试题A卷属于典型的“基础功筛查型”试卷。我翻过不少大厂的iOS笔试爱奇艺这套题的特点是不考偏题怪题但覆盖面极广从语言特性到运行时机制从内存管理到UI事件传递几乎是把你大学三年加实习一年积累的知识底子整个翻出来晒一遍。很多同学拿到试卷第一反应是“这些知识点我都见过”但真正下笔的时候才发现自己只是“知道”而不是“理解”。比如KVO键值观察怎么用大多数人能说出来但问到“KVO的底层实现是什么”“手动触发KVO怎么做”“嵌套Context有什么坑”就卡住了。这套题的狠劲就在这儿它不问你API怎么调它问你API背后发生了什么。整套题从能力考察维度来看可以分成四个层次第一层是语言基础考察OCObjective-C的核心特性有没有吃透第二层是运行时与内存管理考察对底层的理解深度第三层是UI与事件处理考察日常开发中会不会踩坑第四层是多线程与系统框架考察工程落地能力。从“爱奇艺2019秋招iOS方向笔试题A”这个标题就能看出这是秋招的第一轮筛选出题人的逻辑很清楚——基础知识不牢固的人后面项目经验聊得再嗨也是白搭。1.2 刷题之外更要建立知识网络我见过太多同学刷题的方式是背答案这道题选A那道题选C记住了就往下走。这套方法应付一般的学校考试也许有用但面对爱奇艺这种大厂笔试几乎必翻车。因为大厂笔试题有个特点它经常会换一个角度考察同一个知识点或者把两个知识点揉在一起考。你背的是答案它考的是逻辑对不上自然就懵了。所以正确的备考方式应该是每做一道题不要只停留在“选什么”而是把这个知识点相关的上下游全部梳理一遍。比如考到KVO你就应该顺着把KVO的原理、应用场景、常见坑点、与Notification的区别全部过一遍考到Block就要把Block的类型、循环引用、__block修饰符、Block的存储位置全部串联起来。这样做一道题等于复习了一整个知识模块效率比盲目刷题高得多。我在实际带新人的时候发现很多应届生对知识点的掌握是“点状”的东一个西一个连不成线。这样面试官一深挖就露馅。正确的状态应该是“网状”的任何一个知识点被问到你都能沿着它延伸到相邻的领域。这套题本身就是一个很好的知识网络索引顺着它梳理下去基本能把iOS面试的高频考点覆盖个大半。2. 核心细节解析与实操要点2.1 语言基础类考点与解题思路OC语言特性是这套题的重头戏尤其是那些OC独有的、跟Swift差异明显的机制。KVO和KVC键值编码基本是必考的而且考法每年都在变。KVO的核心机制你要能说清楚当你对一个对象添加观察者时Runtime会动态创建一个该类的子类重写被观察属性的setter方法在setter里调用willChangeValueForKey和didChangeValueForKey从而把变化通知给观察者。这个动态子类的过程很多人只是听过名字但不知道细节面试官一问“子类叫什么名字isa指针怎么变化的”就容易卡住。KVC的考察点则集中在setValue:forKey的查找顺序上。你要知道它的完整查找路径先找setKey方法如果没有再找_key、_isKey、key、isKey这些实例变量都找不到才会调用setValue:forUndefinedKey。这个顺序我建议每个准备面试的人都画一遍因为很多实战中的奇怪问题归根到底都是这个查找顺序引起的。Category与Extension的区别也是高频题。一句话总结Extension在编译期决定有源码才能添加添加的方法和属性是直接加在本类上的Category在运行时合并没有源码也能添加但不能直接添加实例变量可以通过关联对象实现。这里有个隐含考点就是Category的方法覆盖优先级——多个Category都实现了同一个方法时最后编译的那个会“生效”但本质上不是覆盖而是方法列表里排在前面被先找到。这个问题我在真实项目中就踩过坑两个库的Category都实现了同名方法结果调到的跟预期的不一样排查了很久。2.2 内存管理与Block内存管理在笔试里几乎从不缺席尤其是ARC自动引用计数相关的概念辨析。你需要搞清楚strong、weak、copy、assign这几个修饰符的本质区别。strong是强引用引用计数加一weak是弱引用不增加引用计数对象释放后自动置为nilcopy会拷贝一份对象修饰Block时会把栈上的Block拷贝到堆上assign通常用来修饰基本类型如果修饰对象类型对象释放后指针不会置空继续访问会野指针崩溃。这套题如果考到这些一般不会直接问“strong和weak有什么区别”而是给你一段代码让你分析引用计数变化和最终打印结果。这种题考察的是有没有真正理解ARC的机制而不是背修饰符的定义。我建议你做题的时候把每一行代码涉及的引用计数变化都在草稿纸上标出来养成这个习惯遇到再复杂的题都不怕。Block的循环引用问题已经是老生常谈了但考法也在升级。最基础的考法是在一个ViewController里Block捕获了self而self又强引用了这个Block造成循环引用用__weak typeof(self) weakSelf self解决。进阶考法是Block里用了weakSelf之后又在异步操作里访问weakSelf的某个属性这时候weakSelf可能已经被释放了需要在Block开头用__strong typeof(weakSelf) strongSelf weakSelf保底。这个“weak之后还要strong”的写法很多人理解不了为什么其实是保证Block执行期间对象不会被提前释放执行完再释放。2.3 Runtime底层原理Runtime是区分“会用iOS”和“懂iOS”的分水岭。这套题里凡是涉及Runtime的基本都是送分题和送命题并存。送分题是消息传递机制objc_msgSend的查找流程先从缓存里找找不到去类的方法列表里找再找不到去父类找一直找到NSObject都没有就进入消息转发流程。送命题是消息转发流程的三道防线动态方法解析resolveInstanceMethod、快速转发forwardingTargetForSelector、完整转发methodSignatureForSelector和forwardInvocation。这三道防线很多同学背不全或者搞不清楚顺序。结合实际开发来说动态方法解析常用于dynamic属性快速转发常用于代理瘦身完整转发可以用于AOP面向切面编程或者异常拦截。我在做崩溃治理的时候就用过完整转发把一些unrecognized selector的崩溃转成自定义的日志上报虽然不推荐在生产环境这么做但作为兜底方案确实能减少一些线上崩溃。关联对象AssociatedObject也是Runtime的常客。它的底层结构是AssociationsManager维护的一张全局哈希表以对象地址为key关联字典为value。用的时候要注意关联对象不会因为对象dealloc自动清理需要在dealloc里手动移除不然会有内存泄漏的风险。另一个坑是关联对象不参与对象的释放过程所以用weak策略关联时对象释放后关联值也会变成空这点跟实例变量的行为不太一样。3. 实操过程与核心环节实现3.1 UI事件传递与响应链UI部分考察频率最高的应该就是事件传递和响应链了。这套题如果出一个场景题一个Button嵌套在View里View嵌套在ViewController的View上点击Button事件是怎么传递和响应的很多同学能答出前半段——hitTest和pointInside的递归调用事件从UIApplication传给UIWindow再传给根视图一层层找最适合的响应者。但后半段容易漏——找到最适合的响应者之后事件沿着响应链从Button传到父View再传ViewController的View再传到ViewController一直到UIApplication如果每一层的nextResponder都没处理事件就丢弃了。真实开发中跟响应链相关的坑也很多。比如Button的点击区域太小你加了一个父View的点击手势来扩大响应区域结果Button的点击就失效了。原理是手势识别器比正常的触摸事件响应优先父View的手势识别器把触摸事件拦截了Button根本收不到touch事件。解决方法是实现手势识别器的delegate方法判断触摸点是否在Button范围内返回NO让事件继续传给Button。TableView的优化也是笔试和面试的高频题。基础答法是复用cell、高度缓存、避免在cellForRowAtIndexPath里做耗时操作、异步加载图片。深一层答法是预排版、预渲染、按需加载、避免离屏渲染。再深一层就是diff算法、异步绘制、滑动帧率监控。这套题如果考到TableView优化建议尽量往深处答因为出题人想看到的不是你会不会用UITableView而是你有没有做过大列表的性能治理。爱奇艺这种视频App信息流列表的流畅度直接影响用户体验所以这块几乎是必考的。3.2 不同iOS系统版本适配策略视频类App的系统适配是一个绕不开的工程问题。爱奇艺的题如果涉及系统版本适配考察重点肯定不是“怎么判断系统版本”而是“你的适配策略是什么”。我的经验是比较大的版本迭代比如iOS 11到iOS 12需要做全量回归小版本更新做定向验证就够了。但有一点要注意系统版本的兼容性测试不能只看UI表现还要关注API行为变化。举一个我实际踩过的例子iOS 13之后Apple改了KVC的取值行为直接通过KVC访问私有属性会触发NSGenericException异常原来很多第三方库用KVC修改UITextField的placeholder颜色等操作一下子全崩了。这类问题不真机测到光靠看文档是发现不了的。所以适配策略里一定要包含一个环节用真实设备跑一遍核心功能和关键页面模拟器替代不了。另外iOS 11的安全区域适配也算是个经典考点了。在iPhone X发布之后所有App都要处理刘海屏safeAreaInsets的获取、SafeAreaLayoutGuide的使用、导航栏和TabBar的高度适配都是必考内容。这种题考察的是你有没有真正经历过适配打磨这不光是代码问题更是产品体验问题。我在项目里通常的做法是统一封装一套布局基类把安全区域的边距都抽象成常量这样就算出了新机型也只需要更新这一个地方。3.3 多线程与并发编程多线程和并发编程是大厂笔试的重灾区因为这块既考概念又考代码还考实际踩坑的经验。GCDGrand Central Dispatch是考察重点你必须能说清楚串行队列和并发队列的区别同步任务和异步任务的区别以及任务和队列组合出来的各种效果。其中最容易出错的是死锁问题。经典的“死锁题目”是这样的在主队列上调用dispatch_sync会死锁。为什么因为主队列是串行队列同步提交一个Block到当前串行队列而这个Block要等前面的任务执行完才执行但前面的任务正在等这个Block执行完互相等待就死锁了。如果你在同步提交的Block里又嵌套了一层dispatch_sync提交到同一个队列同样是死锁。我在面试时经常出这道题能答对的应届生比例并不高。锁的选择也是一个很好的考察点。synchronized、NSLock、NSRecursiveLock、OSSpinLock、os_unfair_lock、dispatch_semaphore这些锁的性能和适用场景各不相同。OSSpinLock因为优先级反转问题已经被废弃了面试时如果你还推荐它会被扣印象分。现在的主流选择是os_unfair_lock做轻量级互斥dispatch_semaphore做信号量控制synchronized因为底层是递归锁性能最差但容错最好适合简单场景标保护。RunLoop也是这套题里经常出现的内容。考察点通常是RunLoop的Source、Timer、Observer三类事件源以及RunLoop的Mode切换。在iOS开发中RunLoop最经典的应用就是滑动TableView时暂停非紧急任务用Observer监听kCFRunLoopBeforeWaiting在空闲时执行预先分派的轻量级任务这样能显著提升滚动的流畅度。另外AFNetworking早期版本也有一道经典面试题就是为什么要在子线程里添加RunLoop因为NSURLConnection的代理回调需要RunLoop来驱动而主线程的RunLoop可能被UI操作阻塞。4. 常见问题与排查技巧实录4.1 笔试中常见的“陷阱题”类型我帮不少同学做过笔试复盘发现大家在爱奇艺这类笔试里栽跟头的地方往往出奇一致。第一种是“看似简单实则复杂”的题比如给你一段MemoryLayout相关的代码问打印结果很多人凭直觉就答了没注意深拷贝和浅拷贝的问题。第二种是“概念辨析”的题比如问“atomic一定线程安全吗”正确答案是不一定atomic只能保证属性的读写原子性不能保证业务逻辑的线程安全很多人一看到atomic就选安全这是典型的概念混淆。第三种是“读过没理解”的题比如考autoreleasepool的底层实现很多人知道它是通过AutoreleasePoolPage来管理的但问到对象什么时候真正释放就说不清了。面对这些陷阱题我的建议是下笔之前先画图。无论是一个对象引用的关系图还是一个事件的传递路径图画出图来逻辑就清楚了一半。另外遇到不会的题不要空着把能想到的相关知识点写上去有些笔试是人工阅卷的步骤分和思路分也是分。一条答题经验笔试不只是考察结果更是考察你的思考过程。4.2 从笔试到面试的高频追问点做好笔试只是第一步接下来面试官会根据你笔试的答案做深入追问。比如笔试考了KVO面试官就可能追问KVO注册的观察者在dealloc时没有移除会怎么样在iOS 11之后系统会在对象释放时自动移除观察者但在iOS 11之前不会析构时会崩溃。再比如笔试考了Block面试官会追问Block的截获变量是怎么实现的为什么局部变量默认是值捕获而static变量和全局变量不需要捕获这两个问题能答上来Block这块基本就是满分了。我的建议是做笔试准备的时候每道题都往深了问自己三个“为什么”。当你把一道题背后的三个“为什么”都弄明白的时候笔试那道题就算得分不高面试也一定能翻盘。因为面试官看重的不是你背了多少知识点而是你有没有自己的思考深度。我带过的一个学员就是这样笔试答得一般但面试时因为对RunLoop的理解特别深最终拿到了offer。4.3 实用的其他备考建议关于备考材料我建议不要只抱着那一两本iOS面试书死啃。比较好的组合是官方文档加源码加实际项目。官方文档看API设计思路源码看实现细节实际项目把理论应用一遍。三者缺一不可。看源码的时候我强烈建议从objc4和GCD的开源代码开始看这两个是iOS的基石也是面试官最喜欢深挖的地方。第一次看源码可能会比较吃力但你只需要关注跟面试相关的关键路径不必逐行读懂。刷题的时间安排也很有讲究。我见过不少同学是在投简历前两周才开始刷题这基本是来不及的。比较合理的安排是提前一到两个月每天固定刷十道题每道题连带把考点扩展一遍。这样到笔试前你已经建立起完整的知识网络而不是零散的知识点集合。另外我建议做一套自己的“错题本”不是抄题目和答案而是写清楚这道题考了什么知识点、我当时为什么错、正确的思考路径是什么。这个错题本在面试前翻一遍比盲目刷题有效得多。我个人的习惯是每做完一套真题都会花两倍于做题的时间去做复盘。先对着答案检查对错然后不看答案把每一道题的完整解题思路和涉及的知识点自己讲一遍讲不出来的地方就是知识盲区重点补。这个过程很费时间但效果也是最好的。准备笔试这件事没有捷径但找对了方法效率差距可以非常大。
返回列表