
先说个背景。每年秋招网易的笔试都算得上移动端岗位的“风向标”尤其是iOS开发工程师这套题。我身边好几个学弟学妹跑来跟我吐槽说选择题考得又细又偏编程题看起来不难但一上手就卡住。我后来专门把2020校招正式批的iOS笔试题翻出来配合当时参加过的同学回忆做了一个完整的复盘。这篇文章不打算贴“标准答案”而是想从题本身出发聊清楚网易到底想通过这套题筛选什么样的人以及你该怎么准备才能稳稳接住这种风格。1. 笔试整体结构与考察逻辑1.1 题型分布与分值结构2020网易iOS校招正式批的笔试题型上大体延续了互联网大厂校招的统一套路客观题加主观题混搭。客观题主要是单选题和多选题覆盖C语言、Objective-C、Swift、计算机基础操作系统、网络、数据结构大概40到50道主观题一般是两道编程题偶尔会加一两道简答题比如让你说说某个API的底层实现或某种架构方案的优缺点。从分值结构上看客观题占比通常在60%左右编程题占30%到40%。有点反常识的是网易的笔试并不是“编程题AC了就稳了”客观题单项分值虽然不高但架不住数量多错一片照样挂。我当时给朋友的建议一直是客观题的正确率要比编程题的完成度更优先保证因为编程题往往是“AC一道保底AC两道加分”而客观题是你跟别人拉开差距的地方。1.2 为什么网易要这么考网易的客户端团队尤其是网易游戏、网易云音乐、有道这些BU对iOS工程师的基本盘要求很明确底层基础扎实、代码能力过关、有排查问题的嗅觉。笔试不跟你玩虚的不考“你用过什么第三方库”也不考“你做过什么项目”而是直接拿语言特性、内存管理、并发模型这些硬通货来筛人。另外还有一个隐藏逻辑网易的iOS岗位笔试和面试是强关联的。笔试里出现的每一个知识点面试环节大概率会追着问“为什么”和“底层怎么实现”。所以如果你只是刷题背答案就算笔试过了面试也会露馅。反过来如果你能借着笔试题目把背后的原理吃透面试就是顺水推舟的事。2. 语言基础题拆解C/ObjC/Swift三语混考2.1 为什么一场笔试要考三种语言很多同学看到题目里C、Objective-C、Swift轮番出现第一反应是“网易是不是有病”。其实这是iOS开发岗位的特殊性决定的你日常写业务可能主要用Swift但读底层源码、看历史项目、跟Core Foundation打交道时全得靠C和ObjC。网易的笔试就是要确认你有没有“多语言切换”的能力而不是只会照着SwiftUI模板拖控件。C语言部分通常考指针、内存布局、位运算。Objective-C部分考消息机制、属性关键字、KVO/KVC。Swift部分则是从Swift 5.1的语法特性切入比如枚举关联值、协议关联类型、属性包装器等。重点说一下C语言里最阴的一个考点结构体对齐。题目会给你一个struct让你算sizeof四个字段类型分别是char、int、short、double如果你不懂对齐规则算出来一定是错的。实际规则是每个成员按自身对齐系数对齐整个结构体再按最大对齐系数补齐结构体总大小必须是最大成员大小的整数倍。你按这个规则把成员顺序调换一下sizeof结果都会变所以笔试里如果看到“调整成员顺序后结构体大小变化”这种题本质就是考内存对齐。Objective-C的题目则非常喜欢考property的修饰符排列组合。比如“atomic与nonatomic的区别”“copy与strong在什么场景下会产生差异”“weak底层是如何实现自动置nil的”。这些题表面上考语法实际考的是你对引用计数、锁、哈希表的理解。网易特别喜欢把“weak置nil”和“Runtime的SideTable哈希表”串起来考先问行为再问底层最后让你推演多线程下weak是否会崩。2.2 从真题看ObjC核心考点客观题里我印象最深的一道是__weak修饰的变量在ARC环境下访问它的时候会不会触发Retain这道题错的人非常多。正确答案是会对weak对象执行一次objc_loadWeakRetained相当于在访问期间临时强引用一下防止对象在读取过程中被释放访问结束后再释放这个临时强引用。很多人只记得“weak不增加引用计数”就以为访问不触发retain其实完全理解反了。Swift部分网易比较偏好考“Optional底层实现”和“闭包捕获列表”。Optional的底层是枚举.some(T)和.none这个大多数人都知道。但问到if let解包失败时编译器具体做了什么很多人就答不上来。闭包捕获列表更是高频网易会给出一个循环引用场景让你回答[weak self]和[unowned self]在什么情况下会崩溃。unowned的本质是“如果对象已释放访问它就会野指针崩溃”相比weak的自动置nilunowned更危险但在某些性能敏感路径上更快。笔试里常拿“self在闭包执行期间必然存活”作为unowned的适用前提。3. 内存管理与Runtime中高难度题的决胜区3.1 MRC到ARC的演进逻辑内存管理这块网易笔试的切入角度和其他厂不太一样。它不直接问你“ARC下什么时候会循环引用”而是给出几段代码让你判断是否存在内存问题并且要选“一定会崩”“可能会崩”“不会崩”。这种题想要做对光靠背结论是不够的你得在脑子里模拟引用计数的增减过程。先理清ARC的规则ARC只是编译器在合适的位置插入了retain/release/autorelease并没有改变引用计数的本质。所以只要存在循环引用ARC照样泄露。网易考过一道经典的NSTimer题目在一个UIViewController里用scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:创建了一个repeat定时器target是self然后在dealloc里invalidate。问这段代码有没有问题。陷阱在于NSTimer会强引用target而self又强持有timer形成循环引用导致dealloc永远不会调用invalidate永远不会执行。如果你只答出“循环引用”还不够网易还会追问“那怎么解决”。正确答案是用__weak代理对象包装target或者从iOS 10开始使用scheduledTimerWithTimeInterval:repeats:block:的block版本在block里使用[weak self]。但block版本同样有个细节block被timer持有timer被self持有如果不invalidateblock和timer会一起活到天荒地老所以需要在viewWillAppear或viewDidDisappear时做invalidate通常在viewDidDisappear里处理避免用户按Home键时定时器继续跑。3.2 ISA指针与消息转发机制Runtime部分网易考过不只一次“消息转发”的完整流程。简单说调用一个不存在的OC方法时系统会按顺序尝试三次挽救第一次是resolveInstanceMethod:或resolveClassMethod:允许你动态添加一个方法实现第二次是-forwardingTargetForSelector:允许你把消息转给另一个对象处理第三次是-methodSignatureForSelector:配合-forwardInvocation:以完整NSInvocation的形式做最彻底的消息转发。网易的题目经常会给你一个自定义类其中只实现了-forwardingTargetForSelector:问你调用不存在方法时会不会崩溃。实际上如果这个代理对象确实实现了被调用的方法就不会崩因为第二次挽救就把消息“拦截”下来了。但如果只实现了resolveInstanceMethod:且没有动态添加实现系统还是会走到后续步骤最终导致doesNotRecognizeSelector:崩溃。与消息转发紧密相连的是最近几年iOS面试越来越频繁考的ISA指针。网易笔试里有一道Swift相关题提到了ObjectIdentifier和ObjectIdentifier(_: AnyObject)其实是在隐晦地考察你对类对象本质的理解。你把对象在内存中的布局画出来对象首地址指向isaisa经过掩码操作指向类对象类对象里有方法列表、属性列表、协议列表还有指向父类的superclass指针。这些东西在Objective-C里已经考烂了但网易偶尔会换一身Swift的皮来考比如“Swift的类在运行时是否也有isa指针”——答案是有的Swift类在底层使用同样的对象模型以silgen为界有差异但本质相似只是隐藏得更深。4. RunLoop、多线程与网络性能考察的三件套4.1 RunLoop的Mode切换与卡顿排查RunLoop是iOS开发里“听起来都懂写起来全错”的知识点。网易笔试考RunLoop不仅考概念还考应用。最经典的一道题是NSTimer添加到NSDefaultRunLoopMode后在用户拖动ScrollView时定时器为什么不准了因为ScrollView滚动时主线程RunLoop切换到了UITrackingRunLoopMode而NSDefaultRunLoopMode下的Timer不被执行。要解决就把Timer加到NSRunLoopCommonModes这里的CommonModes是一个集合包含Default和Tracking两种模式所以滚动时定时器照样走。网易另一个RunLoop套路是结合卡顿监控来考。给你一段卡顿监控代码里面用了一个子线程持续监听主线程RunLoop的runLoopBeforeSources和runLoopAfterWaiting两个状态问你为什么能检测到卡顿。原理是主线程RunLoop在afterWaiting之后应该很快进入beforeSources或beforeTimers如果这两个状态的时间间隔超过阈值比如200ms说明主线程被某个耗时任务阻塞了。这种题目已经不只是考RunLoop本身还考性能监控方案的设计思路这正是网易客户端团队在云音乐、游戏App里真实在用的方案。4.2 多线程与死锁、竞态条件的经典陷阱多线程题在网易笔试里通常有两种考法一种是给你一段dispatch_sync和dispatch_async混用的代码问你输出顺序另一种是给你一段多线程访问可变数组的代码问你什么时候会崩。dispatch_sync的陷阱最好用一道题说清楚在主队列中调用dispatch_sync(dispatch_get_main_queue(), ^{})会发生什么答案是死锁。因为dispatch_sync会把block提交到主队列并等待执行但主队列是串行队列当前主线程正在执行的任务也就是这段代码本身还没结束新任务永远不会被调度形成互相等待。网易的所有死锁题万变不离其宗只要你理解了“串行队列 同步提交 互相等待”就可以推演出所有死锁场景。比如在一个自定义串行队列中调用sync提交block到同一个串行队列同样死锁但换成并发队列就不会死锁因为并发队列不需要等待前一个任务结束。多线程访问可变数组的考点也很清晰NSMutableArray不是线程安全的。两个线程同时往里addObject可能触发内存坏写导致崩溃。解法是加锁NSLock、os_unfair_lock、synchronized或者改用dispatch_barrier_async往并发队列里写数据。网易偏爱考dispatch_barrier因为它既不是普通并发执行也不是全串行而是“栅栏”——提交到并发队列后在此之前提交的block全部执行完才执行栅栏block栅栏block执行完才继续执行后续block。这种读写分离模型正好符合“多读单写”的业务场景。4.3 网络层的Socket与HTTP边界网易笔试题里网络部分喜欢考“连接层面的细节”。比如TCP三次握手为什么是三次而不是两次HTTP/1.1的keep-alive和HTTP/2的多路复用有什么区别iOS的NSURLSession相比NSURLConnection有哪些优势。其中有一道题让我印象很深HTTPS证书校验过程中客户端除了验证证书链之外还需要做什么答案是校验域名是否匹配以及可选的SSL Pinning证书绑定。很多人只记得CA证书链校验忽略了域名匹配这一步这就是被扣分的点。网易做云音乐和游戏对API安全非常敏感所以他们很看重你对HTTPS完整握手过程的理解尤其是iOS开发中还要接触URLSessionDelegate里的didReceiveChallenge方法这属于日常开发一定会碰到的技能。网络层另一个容易出题的角落是NSURLCache和ETag/Last-Modified组合出的缓存策略。网易会让你判断一段设置了Cache-Control: no-cache的请求是否会走本地缓存。正确答案是no-cache并不是“不使用缓存”而是“使用缓存前必须先到服务器验证”所以如果服务器返回304 Not Modified本地缓存依然可以用。5. UI布局、架构设计与工程化思维5.1 Auto Layout与iOS分屏适配2020年的笔试题已经明确体现出苹果推行iPadOS分屏的趋势。网易考了一道关于UIStackView的题目问的是在分屏环境下不同尺寸的traitCollection如何影响布局更新。iOS 11是分水岭从iOS 11开始支持Drag and Drop与Slide Over所以热词里那句“a支持iOS 11.0及以上”很有可能是当年岗位要求的一部分笔试也在配合这个门槛来出题。具体到Auto Layout网易的题目不像LeetCode那样绕但特别贴近工程实际。比如“两个UILabel并排左边label的内容长度不固定右边的label要始终贴在左边label右边且不能超出屏幕”这种题做多了就一个核心思路约束条件要给全优先级要分清。左边label的content hugging priority设高右边label的compression resistance priority设高然后在右边label和屏幕右边之间加一个的约束这样一个简单的自适应布局就出来了。5.2 MVC、MVVM与组件化到底怎么考架构题在笔试里通常以“简答”或“多选”形式出现网易的考核点很实际MVVM相比MVC解决了什么、引入了什么。很多人背了一堆概念一遇到实际场景还是不会选。网易给过一个典型场景一个页面有网络请求、数据解析、界面刷新、用户交互四件事。MVC写法会把网络请求放到Controller里数据解析也写在Controller里最后Controller变成几百行的“上帝类”。MVVM则把网络请求和解析逻辑下沉到ViewModelView持有ViewModel通过绑定KVO或闭包来刷新UI。这样做的目的是让Controller变薄让业务逻辑可测试。笔试选项里常出现的干扰项是“MVVM能完全替代MVC”“MVVM能解决循环引用”。这些都是错的。MVVM只是职责划分变了循环引用该有还是有比如闭包捕获self依然要weak。网易真正想考的是你不要把架构当银弹而要理解每种架构的适用边界。组件化同样如此网易问“组件化解决了什么问题”答案是“解决代码耦合与编译速度问题”不是“解决运行时性能问题”。如果你选了“提升App启动速度”那就是被概念带偏了。5.3 工程化与证书体系笔试里偶尔还会冒出一些“工程题”比如App签名的原理、描述文件的作用、添加了新的推送证书后需不需要更新描述文件。这类题对没上过架的同学来说有点吃亏但却是网易非常重视的实操能力。iOS开发者证书体系其实不复杂一个证书对应一个私钥一个描述文件绑定了App ID、证书和设备Development模式或App StoreDistribution模式。你要上新设备调试可以在开发者后台把设备UDID添加进去重新生成描述文件下到本地即可不用重新生成证书。网易甚至出过一道关于崩溃日志符号化的题拿到线上crash log0x1000c1234这种地址怎么解析出具体函数名。答案是用atos命令配合dSYM文件与CPU架构参数xcrun atos -o *.dSYM/Contents/Resources/DWARF/* -arch arm64 -l 0x1000c0000 0x1000c1234。这是一个平时不用、线上排查时能救命的技能网易把它放进笔试题说明他们要的不是纸上谈兵的开发者而是能处理线上问题的工程师。Uniapp打iOS测试包也是类似套路全流程无非是创建App ID、生成证书、创建描述文件、Xcode配置签名、导出ipa任何一个环节的证书过期或UUID没加进去都会导致真机安装失败。6. 编程题思路与备考路径6.1 真题风格的算法题解法网易笔试的编程题一般两道一道偏数据结构一道偏动态规划或贪心难度对标LeetCode中等偏下但偶尔会加一点“包装”。比如有一道题是“给定一个数组找出所有满足abc0的三元组”这是标准的双指针题先排序再固定一个数剩下两个数用双指针从两端逼近。你只要注意去重逻辑第一个数遇到相同值就跳过双指针移动时也要跳过相同值就能避免重复三元组。另外一道常见的是“最长回文子串”。这道题的正解是中心扩展法或Manacher笔试环境下能用中心扩展法写出O(n^2)已经足够Manacher属于加分项。网易的判题系统对暴力解比如把所有子串遍历一遍再判断回文O(n^3)会直接判超时所以你要学会根据数据范围估算复杂度。题目如果给出字符串长度不超过1000O(n^2)是安全线O(n^3)大概率超。还有一类网易特别爱出的编程题二叉树相关。比如“之字形打印二叉树”“最近公共祖先”。这类题考察的不是有多难的算法而是对队列、栈、递归的理解是否扎实。尤其注意迭代写法因为部分大厂笔试会有递归栈溢出的限制测试用例你只会递归不会迭代可能就被大样例卡死。6.2 从笔试到Offer的三个月复习路线如果你现在是大三或研二目标就是明年秋招的iOS岗我给你一条按周拆的路线亲测适合基础一般的同学。第1到2周补C语言基础重点是指针、结构体、内存布局、位运算。不要用大学教材硬啃直接看《C程序设计语言》KR的指针和结构体章节配合做20道指针相关的笔试题。如果指针题你一眼看不出输出结果说明还没过关。第3到4周系统过一遍Objective-C重点在属性关键字、内存管理、Runtime、Category、Block。这个阶段建议先看《Effective Objective-C 2.0》的前六章把每个条款的“为什么”搞清楚然后用Xcode写Demo验证比如写一个对象在dealloc里打印日志观察循环引用时dealloc不触发。第5到6周主攻计算机基础包括操作系统进程线程区别、死锁条件、虚拟内存、网络TCP/UDP、HTTP/HTTPS、DNS解析过程、数据结构数组、链表、哈希表、二叉树、堆。每天刷10道“牛客网iOS工程师”板块的客观题记录错题。第7到8周Swift语法和SwiftUI/UIKit底层原理重点在Optional、闭包、值类型与引用类型、属性包装器、Combine框架的基本使用。如果时间紧SwiftUI可以只掌握生命周期和数据流笔试里考得不多。第9到10周算法强化按LeetCode的“数组、字符串、链表、二叉树、动态规划、贪心”六大类刷题每天2到3道保持手感到考前。网易的编程题大概率从这三类里出排序/双指针、二叉树遍历、动态规划状态转移。第11到12周做历年真题和模拟题控制时间。网易笔试时长一般是90到120分钟你平时练习就要按这个时长限时客观题平均每题不要超过1分钟编程题每题控制在20分钟以内。6.3 复习资料与工具推荐资料我分成三档。第一档是必看《Effective Objective-C 2.0》、苹果官方的“Programming with Objective-C”和“The Swift Programming Language”。这三本能覆盖笔试80%的客观题考点。第二档是提升《Objective-C Runtime源码》和RunLoop相关的博客。不用全看重点读objc4源码里的objc_msgSend、retain/release、weak相关实现。第三档是刷题工具LeetCode高频100题、牛客网的iOS真题库、CSAPP的章节习题用于计算机基础补强。工具方面我在实际复习中发现一个特别好用但常被忽略的点用Xcode的“Address Sanitizer”跑自己的Demo它能直接帮你定位内存问题。笔试复习阶段多做这种“动手验证”比纯看博客有用得多。只要你把一个知识点从“听说过”变成“我亲手验证过”面试官一问就能感觉到差别。7. 常见问题与避坑心得我复盘完这套题之后总结出几个高频的坑提前写在这里供你们避雷。客观题部分最大的坑是“多选漏选”。网易的多选题通常五个选项至少两个正确选错、多选、漏选都不得分。策略只有一个不确定的选项宁可不选也不要选错。比如问你“以下哪些操作会导致循环引用”你能100%确认的只有两个那第三个虽然看着像也不要选稳稳保分。编程题最大的坑不是算法不会而是题目读不完整。网易的编程题题干经常带“如果存在多个解输出字典序最小的一个”这种附加条件一旦没注意样例过了但实际测试全挂。建议所有编程题先读三遍题把输入范围、输出格式、边界条件全部圈出来再动手写代码。运行环境方面网易笔试用的是自研在线OJ支持C/C/Java/Swift/Python但Swift的支持版本可能旧一点如果你的代码里用了some关键字或新式并发语法可能编译不过。保险起见编程题尽量用C或Python提交不跟编译器版本较劲。另外有个容易被忽略的点笔试结束后网易一般会在7到14天内发出面试通知但不会公布笔试分数。你如果觉得自己笔试发挥一般千万不要干等直接用网易云音乐或网易游戏App里的反馈入口找内推人打听进度或者去牛客网看看同一批人的讨论。主动跟进不会减分反而显得你很想进这个团队。最后再分享一个我自己的体会。大多数校招生准备iOS岗都喜欢追新框架、新语法但网易的笔试用一套非常扎实的题告诉你真正的分水岭永远是C语言、内存管理、并发这些底层能力。你可以不会最新的SwiftUI属性包装器但你不能解释不清楚weak是怎么自动置nil的。把这套底层能力练好不管秋招还是春招你都不会慌。