ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

B站iOS校招笔试真题解析:从Runtime到内存管理的核心考点

B站iOS校招笔试真题解析:从Runtime到内存管理的核心考点 做了这么多年iOS开发和校招辅导我一直觉得笔试是候选人最容易被误判的一环。代码能力在线但基础概念含糊或者刷题刷得太泛没抓到重点都会在笔试卷上直接暴露出来。B站2020校园招聘的这套iOS方向笔试卷二属于典型的大厂移动端校招笔试风格覆盖了Objective-C与Swift底层机制、内存管理、多线程、网络、UI事件传递、架构设计等核心模块。这篇文章就专门拆一拆这套卷子背后的考察意图、高频考点和解题思路给正在准备iOS校招笔试的人一份可以直接照着复习的清单。这套卷子适合谁看主要是两类人一类是准备投递B站或其他中大型互联网公司iOS岗位的应届生另一类是工作一两年后想系统梳理iOS基础、准备跳槽的初级开发。不管你是哪种只要把下面这些考点吃透笔试环节基本不会翻车。1. 从一张笔试卷看B站的校招筛选逻辑1.1 这套卷子到底想筛什么样的人先聊一个很多人忽略的问题B站这类公司的校招笔试卷并不是为了考倒你而是为了在几千份简历里快速定位“基础扎实、有工程思维、能直接上手干活”的人。所以你看这套iOS卷子题目虽然覆盖范围广但每一道题背后都对应着一个实际开发中会遇到的场景。比如内存管理这块考察循环引用和Auto Release Pool对应的是日常开发中写闭包、使用NSTimer、处理图片加载时最容易埋的坑。再比如多线程部分考察死锁对应的是主线程同步操作、并发队列嵌套这类线上事故高发场景。也就是说笔试卷本质上是在模拟“一个新人入职后会不会写出让线上崩溃的代码”这件事。明白了这个逻辑复习方向就清晰了不是去背零散的知识点而是要理解每个考点在真实业务里的触发条件。这样即使题目换个马甲你也能一眼看穿它考的是哪块知识。1.2 题型分布与答题节奏建议根据B站这套笔试卷二的常见结构题目大致分三类单选多选、简答题、编程题。选择题考察的是知识面广度和概念准确性简答题考察表达能力和原理理解深度编程题则直接检验手写代码的基本功。我建议的答题节奏是选择题控制在25分钟内遇到拿不准的不要死磕先标记跳过。简答题每道控制在10分钟左右核心是“结论先行、再说原因、最后补个例子”。编程题留足40分钟先理清思路再动笔哪怕不能完整跑通也要把关键逻辑和边界条件写清楚。这里有一个很重要的心得校招笔试的阅卷人通常是iOS组的技术骨干他们看卷子时最在意的是“这个人有没有自己的思考”而不是“答案和标准答案一字不差”。所以简答题千万不要只写一句话哪怕你对这个知识点只有七八成把握也要把相关的上下文、触发场景、解决思路都铺开写让阅卷人看到你的分析过程。2. 核心考点拆解语言机制与内存管理2.1 Objective-C与Swift的底层差异这套卷子的语言基础部分十有八九会围绕Objective-C和Swift的差异展开。常见考法有两种一种是直接问“你如何理解Swift中的值类型与引用类型”另一种是给出一个混合工程场景让你分析OC和Swift桥接时的注意事项。先说值类型与引用类型。Swift里Struct是值类型Class是引用类型这个几乎所有候选人都知道。但笔试想考察的是更深一层值类型在赋值、传参时会触发拷贝而Swift为了保证性能引入了Copy-on-Write机制也就是只有真正修改数据时才发生拷贝。很多答案只写到了“Struct是值拷贝”没有点出COW这就丢掉了一个加分项。再说OC和Swift桥接。实际工程中OC代码调用Swift类需要在头文件里引入#import Target-Swift.h而Swift调用OC代码则需要通过Bridging Header。笔试如果出这个知识点通常会埋一个坑Swift类如果要被OC使用必须继承自NSObject否则桥接后OC无法正确识别这个类的方法调用。2.2 Runtime机制与消息转发流程Runtime是iOS笔试的钉子户考点B站这套卷子大概率也会涉及。最基本的是消息发送机制objc_msgSend根据对象的isa指针找到类对象再通过SEL在method_list里查找IMP。如果找不到会走消息转发流程。消息转发的完整链路是动态方法解析resolveInstanceMethod→ 快速转发forwardingTargetForSelector→ 完整转发methodSignatureForSelector和forwardInvocation。笔试常考的场景是你有一个对象调用了未实现的方法程序为什么没有崩然后让你描述整个查找过程。准备这个考点时我建议你多问自己一个“为什么”——为什么需要快速转发和完整转发两层设计快速转发是直接把消息转发给另一个能处理的对象性能开销小完整转发需要生成NSInvocation开销大但更灵活。理解了这层设计意图题目怎么变你都能应对而且这种“为什么这么设计”的思路恰恰是阅卷人最想在卷子上看到的。另外KVC和KVO也是Runtime的常见延伸考点。KVO的底层原理是动态生成子类并重写setter方法这个子类会重写class方法让外部感知不到类型变化。笔试很可能接着追问手动触发KVO怎么实现答案是调用willChangeValueForKey和didChangeValueForKey这两个方法。2.3 内存管理从ARC到循环引用内存管理部分每年都是重头戏B站的卷子自然也不例外。ARC虽然是编译器自动插入retain/release但面试官真正想考的是你知不知道哪些场景会造成循环引用以及怎么定位和解决。最常见的循环引用场景有三个Block捕获self、NSTimer持有target、Delegate使用strong修饰。笔试给出的代码片段往往就是这三种之一让你分析是否有循环引用并写出解决方案。Block捕获self的解法是用__weak修饰self但在Block内部如果需要长期持有self比如异步任务完成后的回调单纯使用weak可能导致对象提前释放。这种场景的正确姿势是在Block外部用weakSelfBlock内部再声明一个strongSelf来保证执行期间self不会被释放同时避免执行过程中self被置nil导致的逻辑异常。NSTimer的坑在于Timer会强持有target如果target又强持有Timer通常作为属性就形成了循环引用。iOS 10之后推荐使用block版本的timer方法在deinit里主动调用invalidate。如果你回答的是“使用weakSelf”阅卷人一眼就能看出你只是背了答案因为weakSelf并不能打破Timer对target的持有关系。还有一个笔试高频陷阱是autoreleasepool。很多候选人只知道autoreleasepool是自动释放池但不知道为什么for循环大量创建临时对象时要用它包裹。答案是大量临时对象比如循环读取图片数据如果都往当前runloop绑定的autoreleasepool里注册会持续占用内存直到RunLoop进入休眠才释放。手动添加一个局部的autoreleasepool可以及时释放降低峰值内存。3. 并发编程与网络层基础3.1 GCD核心概念与死锁陷阱GCD是iOS并发编程的基础这套卷子在这块的考察通常集中在几个方向队列与任务的组合方式、死锁的产生条件、线程安全的实现手段。先明确基本概念串行队列和并发队列决定任务的执行方式同步和异步决定任务的分发方式。笔试常考的组合包括并发队列同步任务不会开新线程串行队列异步任务也只有一个线程。很多人在这里记混我建议你死记一个结论只有“并发队列异步任务”才会真正并发开辟多个线程。死锁是选择题和简答题都爱考的点。最经典的陷阱就是在主队列上执行sync操作这时主队列被当前任务占用sync又去等这个任务完成就形成了互相等待。我在辅导时经常让候选人记住一句话不要在已经处于某个串行队列的环境里再对这个队列执行sync操作。还有一道B站当年考过的变体题在一个自定义串行队列里异步执行任务AA内部又对同一个串行队列执行sync操作。结果同样会死锁原因和主队列死锁一样——串行队列同一时刻只能执行一个任务sync在等前面的任务结束而前面的任务又被sync阻塞了。3.2 锁的选型与线程安全方案线程安全这块考点从重量级到轻量级依次排开NSLock、synchronized、信号量、atomic、以及无锁方案。笔试题经常给一个多线程读写同一个字典的场景让你选择最合适的方案。synchronized本质是对传入对象加了一个递归锁性能较差但使用简单适合低频的临界区保护。NSLock是标准的互斥锁但要注意lock和unlock必须成对调用否则会死锁。dispatch_semaphore是处理“资源并发数限制”的利器设置初始value为1就等价于一个互斥锁设置为更大的值则可以实现流量控制。OC属性的atomic修饰也经常被拿来考察。很多人以为atomic就是绝对线程安全这是最大的误解。atomic只保证属性的getter和setter是原子操作但如果你先读取字典、再修改其中某个key对应的值这整个复合操作并没有被原子化多条线程仍可能产生数据竞争。笔试如果想拿高分要在答案里主动点出这个“atomic不等于线程安全”的结论并且补充说明真正安全的方式是使用并发队列加读写栅栏或者用NSLock把整个读写逻辑包裹起来。3.3 网络层考点HTTP、HTTPS与TCP网络基础也是校招笔试的常客。三次握手和四次挥手基本是必考但光背状态码和标志位是不够的你需要能结合开发场景解释为什么是三次而不是两次。三次握手的核心作用在于确认双方的接收和发送能力都正常两次握手无法防止历史重复连接请求导致的资源浪费。HTTPS方面重点是TLS握手过程中证书验证和密钥协商的流程。笔试简答题如果问HTTPS为什么安全一定要从“机密性、完整性、身份验证”三个维度作答对称加密保证数据机密性、摘要算法保证完整性、数字证书保证服务端身份可信。只要从这三个角度展开得分率会高很多。B站作为视频平台面试中还可能顺带问CDN和弱网优化的基本思路。这里你得懂一点HTTPDNS可以绕过本地DNS的解析耗时和污染问题长连接和连接复用能减少频繁建连的开销弱网环境下可以通过降低图片清晰度、批量请求合并等手段优化体验。这些点不一定在笔试中出现但在同场面试里被追问的概率非常高建议一并准备。4. 架构设计、UI机制与性能优化4.1 从MVC到MVVM的架构演进B站的iOS客户端体量不小笔试对架构设计的考察往往不是让你默写定义而是给一个场景让你分析现有架构的问题并提出改进方案。最典型的就是MVC在大型项目中的困境。MVC本身是清晰的但App规模变大后Controller会越来越臃肿大量业务逻辑、网络回调、视图更新都堆在Controller里导致它既难测试也难维护。MVVM的核心变化是引入ViewModel来承接原本属于Controller的展示逻辑和业务逻辑Controller只负责视图绑定和生命周期管理。笔试如果让你写MVVM记得要提到数据绑定这一环。MVVM在iOS中有两种实现路线一是基于KVO或Block手写绑定二是引入ReactiveCocoa或RxSwift这样的响应式框架。手写绑定的代码量较大但能让阅卷人看到你对处理逻辑的理解深度如果你选择用RxSwift务必把关键操作符和线程切换写清楚。还有一个加分的角度是组件化。你可以把思路延伸到模块划分和依赖管理顶层是App壳工程中间是各个业务组件底层是基础组件库。组件间通信可以通过路由表或中间层完成避免模块间直接引用。这个角度能让你的答案脱颖而出因为大部分候选人只会聊MVC和MVVM的区别。4.2 事件传递机制与响应链UI事件传递是iOS笔试中区分度最高的一块。常见的考法是给出一个复杂的视图层级让你判断点击某个位置时事件最终由谁响应。完整的传递机制分两个阶段第一阶段是Hit-Test系统从UIWindow开始倒序遍历子视图调用pointInside:withEvent:和hitTest:withEvent:找到最合适的视图。第二阶段是响应链事件从第一响应者开始沿着nextResponder链条向上传递直到有对象处理这个事件。这个知识点的难点在于理解Hit-Test的逆向遍历顺序后添加的子视图会先被遍历因为它在层级里处于最上面。笔试还经常加一个变体——某个视图的userInteractionEnabled设置为NO或者alpha小于0.01或者hidden为YES这三种情况下该视图不会出现在Hit-Test的命中结果里事件会直接传给它的兄弟视图。准备这个考点时我建议你亲手写一个例子验证自定义一个UIView重写hitTest:withEvent:打印调用顺序和坐标判断能帮助你真正记住流程而不是背几个结论。4.3 RunLoop与UI卡顿排查性能优化方面RunLoop和卡顿排查是高频命题角度。RunLoop的基本逻辑是App启动后主线程始终处于一个循环中不断接收事件源并处理然后进入休眠等待新事件。这里要重点理解RunLoop的两种SourceSource0处理如触摸事件这样手动触发的源Source1处理基于端口的系统消息。定时器Timer则被注册在RunLoop的Timer模式下。关于UI卡顿核心结论是主线程的RunLoop在一个周期内要处理绘制、布局、点击事件等所有任务如果单个任务执行时间过长就会触发掉帧。笔试题经常给一段在主线程同步加载大图和数据解析的代码让你分析为什么卡顿并写出优化方案。优化的思路是把耗时操作放到子线程比如用异步队列处理图片解码和JSON解析然后回到主线程更新UI。这里有一个常见的坑就是子线程回到主线程如果使用sync操作在某些情况下可能造成死锁最好统一使用async。还有一个加分的进阶点预排版和预渲染。在子线程提前计算好文本的size和布局信息避免主线程在滑动时才做计算这是短视频和直播类App保障流畅度的重要手段。B站这类视频App对这种优化非常看重你如果能在答案里提到这个点很容易和阅卷人产生共鸣。5. 常见失分点与笔试实战技巧5.1 高频失分点速查表根据我这些年看到的校招笔试卷有些失分点几乎是统一的。整理成表格方便你复习时对照自查失分点错误表现正确思路选择题陷阱看到“原子性”就直接选线程安全atomic只保证getter/setter原子不保证复合操作安全简答题太过简短只写“会循环引用”不写原因要写出谁持有谁、为什么形成环、用什么方式打破死锁判断不完整只判断出主线程sync导致死锁要补充自定义串行队列的同类问题事件响应链答反以为事件从最上层视图先处理先Hit-Test确定第一响应者再沿响应链向上传递不会手写绑定只会口述MVVM概念至少能写出简单的Block回调或KVO绑定示例代码这份表格里的内容本质上是“概念记忆”和“机制理解”之间的差距。选择题可以靠背简答题和编程题只能靠实打实的理解。5.2 编程题的解题套路这套卷子的编程题通常不会太偏常见类型包括链表反转、二叉树遍历、字符串处理、简单的动态规划以及少量iOS相关的代码题如手写一个线程安全的单例、手写KVO的替代方案。手写单例几乎年年考。以OC为例正经的写法是保证两个层面安全一是用dispatch_once保证线程安全二是重写allocWithZone、copyWithZone等方法防止外部通过非shared接口创建新实例。很多候选人只写了dispatch_once漏掉了后一层保护这会被扣分。另外一个值得关注的题型是“给一段有Bug的代码找出问题并修复”。这种题考的其实是代码Review能力。答题时要按严重程度排序输出先说会导致崩溃的问题比如数组越界、空指针再说逻辑错误最后说性能和规范问题。这种分层的表达方式能让阅卷人一眼看出你具备工程思维。5.3 笔试前的复习节奏与心态调整最后聊一下备考策略。如果你还有两到三周的时间我建议按“广度优先、深度跟进”的节奏走第一周把所有基础考点过一遍做到每个概念都能用自己的话复述第二周集中刷题重点是在纸上手写代码不要只在IDE里敲第三周做模拟卷严格计时训练答题节奏。笔试前一天不要再学新知识把这份速查表和自己的错题笔记翻一遍就行。真正上了考场遇到不会的题不要慌先用排除法缩小范围再调动相关的上下文写点与分析过程相关的内容。校招笔试不是要求你满分而是要求你在有限时间里把自己会的都稳定输出。这一点比多背十个知识点更值钱。我自己的体会是准备B站这类大厂笔试卷最大的收获不是最后拿到Offer而是通过复习把iOS的知识体系真正串起来了。很多开发者在日常工作中只用到了UI搭建和接口联调对底层机制是模糊的但笔试卷会逼你把这块短板补上。这种系统性沉淀对后续的面试和实际开发都有长期帮助。还是那句话基础不牢地动山摇——别只盯着题目本身把每个考点背后的原理吃透你拿到的就不只是一份及格卷。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表