
2024年春招我投了小红书的iOS开发岗第一轮笔试的经历到现在还历历在目。线上笔试90分钟题量不小选择题、简答题、两道编程题混在一起。作为一个干了几年iOS开发的老油条我原本以为这种笔试无非就是算法加八股文真坐下来开始做才发现这套卷子的风格和市面常见的iOS面试题差别很大——很多题目背后都带着明显的业务影子不是光靠刷题就能应付的。这篇文章就围绕这场笔试把从投递、备考、实战到复盘的完整过程拆开讲讲。不管你是正在准备iOS校招的在校生还是想跳槽看看机会的同行只要对小红书的客户端技术栈和笔试风格感兴趣这篇文章应该都能给你一些有参考价值的东西。1. 简历投递与笔试通知2024春招的节奏和笔试形态1.1 春招时间线和岗位投递的实际情况2024年春招比往年启动得更早。小红书大概在2月底就陆续放出了春招岗位投递渠道包括官网招聘页和牛客网等平台。iOS开发岗的HC数量不算多但和算法、后端比起来客户端岗的竞争相对温和一些这是春招的一个特点——大量候选人集中在后端和算法方向客户端反倒是命中率更高的赛道。我是在3月初投的简历投完之后大概一周收到了笔试邀请邮件。整个过程没有笔试前的人工沟通完全是系统自动触发。邮件里写清楚了笔试时间窗口、时长和注意事项。值得提醒的是小红书春招的笔试通常分批次第一批笔试和后面批次的题目不完全一样所以越早投递笔试时间越早后面的面试流程也会更从容。我赶上了第一批整体流程确实比后面投的同学快了一截。1.2 笔试系统的使用体验与监考环境笔试使用的是第三方的线上笔试平台需要在电脑上完成同时要求手机端开启监控。开考前15分钟就可以进入系统第一步是环境检测——摄像头、麦克风、屏幕共享权限都要打开。这个环节千万不要跳过有些同学到点了才登录结果环境检测卡在摄像头权限上白白浪费了宝贵的答题时间。整个笔试过程中浏览器会锁定无法切到其他标签页即使使用手机查资料也会被后台监控系统记录下来。我个人的建议是开考前把桌面清理干净关掉所有无关应用尤其是IM工具。别抱着侥幸心理去切屏查资料一旦被标记为作弊整个招聘流程就结束了。系统界面上左侧是题目列表右侧是答题区域。编程题支持选择语言我这场提供了C、Java、Python和Swift但Swift的在线编译器版本相对老旧如果你对Swift的在线环境不熟悉建议编程题直接用C或Java写——这不是示弱而是求稳。笔试的核心是考察思路和代码能力不是考察谁更熟悉在线编译器的坑。1.3 90分钟的时间分配我是怎么做的这套卷子整体题量不大但每道题都需要动脑子时间分配非常重要。我自己的策略是这样的前15分钟快速把所有题扫一遍标记出选择题里涉及原理深挖的题、简答题里的设计题、编程题的输入输出复杂度。中间50分钟先做选择题和简答题因为这部分是确定性得分编程题如果卡住可以先放一放。最后25分钟集中写编程题至少把暴力解写出来保证有分。这里有个经验编程题不管你写得怎么样哪怕只过了样例也要把代码提交上去因为笔试平台的判分规则通常是按通过的测试点比例给分暴力解在数据量小的时候能拿不少分。2. 笔试考点地图从计算机基础到iOS专项的全面覆盖2.1 计算机基础仍然是一道硬门槛虽然投的是iOS岗但笔试里计算机基础的比例并不低。我这场至少有十道选择题在考数据结构和操作系统的基础知识。比如有一道题问的是哈希表在大量插入和删除操作下如何降低rehash的开销答案是预留容量和负载因子调优还有一道问进程和线程的区别但选项里埋了进程间通信一定比线程间通信慢这种绝对化的表述——这种选项就是典型的陷阱。操作系统里最常考的是死锁的四个必要条件、虚拟内存和页面置换算法。考场上有几道选择题我几乎是犹豫了很久才填的比如信号量初始值为3当前值为1有多少个进程在等待这个题如果背得不熟很容易选成2但正确答案是0——当前值为1说明资源还有剩余等待队列是空的。这种细节只有真正理解PV操作的人才不会搞错。计算机网络考了TCP三次握手和四次挥手、HTTP和HTTPS的区别、DNS解析过程。还有一道问在iOS应用的网络请求中哪些场景下需要配置ATS异常这些题目其实都是iOS客户端开发中真实会遇到的问题。2.2 iOS专项知识内存、多线程、UI布局一个不落iOS专项题是笔试的重头戏覆盖面也广基本把iOS开发的核心模块都犁了一遍。内存管理是必考区。题目的问答形式是在ARC环境下一个delegate属性用weak还是assign为什么这个问题的考点很清晰assign用于基本数据类型如果对象用assign修饰原对象释放后指针不会自动置nil继续访问会造成野指针崩溃weak在对象释放后会自动置为nil所以代理对象应该用weak。但很多选择题会在这里做文章比如给你一段代码让你判断在哪个时机对象被释放或者故意混用strong、weak、copy的语义来制造干扰项。多线程部分重点考察GCD和Operation。典型的题目包括dispatch_once的使用场景、dispatch_barrier_async的作用、dispatch_group_notify的调用时机。有一道题是问并行队列和串行队列的区别看似简单但它问的是如果在一个并行队列里同步提交两个任务会怎样——答案是一次只能执行一个任务因为同步提交会阻塞当前线程。这就是那种看起来简单、实际上绕了一个弯的题。UI布局部分考了AutoLayout和Frame的区别、UIStackView在复杂布局中的作用、TableView的复用机制。小红书的笔试特别爱考列表优化相关的内容比如复用池的工作原理、cell高度预计算的思路这显然是因为信息流是小红书的核心业务形态。2.3 架构与工程化不再只问怎么做而是问为什么这样选这套卷子的另一个特点是大量题目在考察架构选型和工程化能力。比如有一道简答题问MVVM和MVC在小红书信息流场景下各自优缺点你觉得哪种更适合。这种题没有标准答案考察的是你有没有真正在项目里思考过架构演进。我的答法是先简单梳理两种架构的核心思想然后落到具体场景信息流页面的数据状态复杂、UI刷新频繁MVC的Controller会越来越臃肿而MVVM配合响应式绑定可以让数据流更清晰但代价是调试成本上升。最后我说如果项目初期团队对响应式编程不熟MVC仍然稳妥但不建议页面状态膨胀到超过300行再去重构。这种回答方式让面试官看得出来你是真的在项目里权衡过不是背答案。工程化方面考了CocoaPods和SwiftPM的区别、二进制化方案、CI/CD流程、App签名和证书管理。其中一道选择题问iOS开发者证书更新后通过TestFlight分发的App需要重新上架吗答案是无需重新上架但开发者需要在开发者后台更新证书并重新打包上传。这个知识点偏实操平时没处理过证书问题的人基本不会知道答案。3. 真题复盘几道让我印象深刻的题目3.1 一道Runloop题看穿测试点背后的原理笔试里有一道Runloop的单选题可以说是整张卷子里最绕的一道。题目大意是在主线程执行以下代码后NSTimer是否会被正常触发- (void)viewDidLoad { [super viewDidLoad]; NSTimer *timer [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) { NSLog(timer fired); }]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; dispatch_async(dispatch_get_main_queue(), ^{ NSLog(async block); }); }这里有两个考点一个是timerWithTimeInterval:创建出来的timer必须手动加入Runloop而不是像scheduledTimerWithTimeInterval:那样自动加另一个是NSDefaultRunLoopMode和NSRunLoopCommonModes的区别。默认模式下当Runloop切换到UITrackingRunLoopMode比如用户拖动ScrollView时timer不会触发。但这道题真正的陷阱在最后那个dispatch_async——block执行后runloop立刻从唤醒状态进入处理流程timer依然在default mode下所以如果没有UI拖动timer是可以正常触发的但如果用户正在滑动页面触发时机就会变得不确定。这道题考察的是Runloop模式切换和事件循环的本质不是背两句话就能答对的。平时调试页面滑动卡顿时如果发现定时器停止工作九十是这个原因。3.2 一道GCD死锁题选择题里最容易被迷惑的选项还有一道选择题是这样的dispatch_queue_t queue dispatch_queue_create(com.example.test, DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{ dispatch_sync(queue, ^{ NSLog(hello); }); });问这段代码的运行结果是什么。四个选项分别是正常输出hello、死锁、崩溃、随机输出。答案是死锁——串行队列里同步提交任务到同一个队列会造成当前队列等待自己完成任务形成循环等待。这个知识点不难但选项里故意放了一个干扰项dispatch_sync会拷贝block到队尾所以可以正常执行很多人如果对队列的本质理解不透就会踩坑。我在复盘时把GCD的队列类型、任务派发方式、死锁场景做了一张对照表这种整理对后续的面试帮助特别大因为面试官喜欢围绕这类代码继续追问如果是并行队列呢如果在主队列主线程里呢。3.3 编程题信息流列表的懒加载与缓存设计两道编程题里第一道比较常规是字符串处理相关的题难度大概在LeetCode中等偏下用哈希表加双指针可以解决。关键是第二道题面很长场景感很强设计一个图片加载模块支持并发下载、内存缓存和磁盘缓存要求返回给调用方的UIImage按原始请求顺序回调。这道题在LeetCode上没有原题本质上是一道系统设计题披着笔试的外衣。我当时的思路是分三层来写第一层是缓存内存缓存用NSCache磁盘缓存用文件存储key是图片URL的MD5。第二层是下载调度并发队列控制同时下载的数量每个下载任务带一个标识符。第三层是回调顺序每个请求生成一个自增序号回调时按序号排序再统一分发。用Swift写的时候我特意用了DispatchGroup去处理并发回调的顺序问题但后来复盘发现其实更好的做法是用一个字典暂存结果等所有请求结束后按序号取避免group嵌套带来的复杂性。这道题考察的不只是代码能力还有对图片加载完整链路的理解——从网络请求到缓存策略再到线程安全每一步都有发挥空间。4. 小红书笔试的特殊之处业务视角贯穿始终4.1 内容消费场景图片加载和列表流畅度的明牌如果你刷过小红书应该能猜到这套笔试题里有一半以上和内容消费场景有关。小红书App的核心页面就是信息流图片加载快不快、滑动掉不掉帧直接决定用户体验所以笔试里反复出现相关知识点。比如有一道简答题问在信息流场景下图片加载框架需要处理哪些问题我把能想到的都列了图片压缩和采样、内存缓存淘汰策略、磁盘缓存容量控制、弱网超时重试、避免重复下载、列表快速滑动时的请求取消。这其实就是考你对整个图片加载链路的理解。市面上的SDWebImage和Kingfisher都实现了这些能力但笔试不是为了考你用哪个库而是考你是否理解每个环节为什么存在。我还遇到一道题问UITableView滑动过程中为什么cell的imageView设置图片会出现闪烁。这个问题的本质是cell的复用机制快速滑动时新cell复用旧cell如果旧图片还在显示而新图片还没下载好就会出现短暂错位。解决方案是把图片绑定到cell对应的model上在下载完成回调里判断cell是否还对应同一个model不对就不更新。这种细节没有实际做过列表优化的人很难答到位。4.2 图文发布链路从相册选图到后端上传的完整链路除了消费内容小红书也是内容生产工具发布笔记的链路同样是笔试关注的场景。有一道简答题让我们设计用户从相册选择多张图片到发布成功的整体流程中iOS客户端需要关注哪些问题。我把流程拆成了几个阶段相册选图与权限申请PHPhotoLibrary的访问权限、照片的iCloud同步状态、图片预处理压缩到合适的分辨率和质量、添加滤镜和水印、生成缩略图、上传管理断点续传、并发上传限制、失败重试、草稿箱持久化、发布状态更新发布中/成功/失败的UI反馈。每个阶段都可以展开讲我选了几个重点图片压缩策略、上传请求的失败重试机制、以及弱网下的用户体验设计。这道题没有标准答案但考察的是你对完整业务链路的把控能力。4.3 社区互动与消息推送的常见考点小红书的社区属性很强评论、点赞、关注、私信这些都是常见业务模块。笔试里有一道题问推送通知到达率低的原因有哪些这题看起来简单但展开来答的内容很多设备token获取失败、APNs证书过期、App前台状态未处理、用户关闭通知权限、网络原因导致推送延迟等。我当时还补充了一点——通知服务扩展可以在展示前对推送内容进行修改比如添加自定义表情面试官批注说这个点可以再展开。另外还考了IM和长连接相关的基础知识比如用WebSocket做消息推送和HTTP轮询的区别以及iOS端如何管理这些长连接的生命周期。这些其实都是客户端架构中非常实际的问题。5. 笔试之后的衔接从笔试题到面试的准备策略5.1 笔试复盘把估分变成查漏笔试结束后我在当天下午就把还记得的题目全部复盘了一遍并按知识点分类标注掌握程度。比如Runloop相关的题我虽然答对了但追问什么时候会用到CFRunLoopAddObserver时我卡壳了这就说明我对Runloop的理解还停留在表面。于是我专门看了一圈Runloop在不同业务场景下的真实用法比如监控卡顿、页面性能统计、线程保活。复盘的方式我推荐用表格记录题目、考点、我的答案、正确的思路、需要补的知识点。这个过程比笔试本身更能提升能力因为你是在主动暴露短板并补齐。5.2 简历项目怎么讲才不吃亏小红书笔试和面试的衔接很紧如果笔试通过简历里的项目经历会被面试官反复拿来提问。我自己的经验是项目经历不要只写做了什么功能要把技术挑战和思考过程写清楚。比如你写负责首页信息流优化这等于没写。你应该写通过分析滚动卡顿原因发现图片解码在主线程耗时过高后改为子线程预解码和图片尺寸压缩滑动帧率提升15%。有具体数字、有分析过程、有解决方案面试官才有话题可以追问。我在简历里写了一个独立项目是一个基于SwiftUI的RSS阅读器重点突出了我用UIStackView和LazyVStack处理不同高度cell的布局逻辑以及通过OperationQueue控制图片并发下载的细节。面试官在面试时的确顺着这条线一路深入问了很多SwiftUI生命周期和并发相关的底层问题好在笔试前复习得比较全面回答得还算顺利。5.3 结合笔试暴露的短板做针对性补强笔试和面试之间通常只有一周左右的时间在这段时间里最重要的是针对笔试暴露的短板做突击。我的短板主要在系统设计和架构问题上。通过笔试复盘我发现自己在为什么这么设计层面的思考还不够比如图片加载模块的缓存淘汰策略我知道LRU是什么但要让我设计一套支持高频访问的LRU缓存我写出来的代码可能漏洞百出。所以我用一周时间专门补了设计模式、缓存策略、线程安全这几个主题还手写了一个基于双向链表哈希表的LRU缓存这个练习对后面的面试帮助很大。另外我还针对小红书的业务场景准备了一些思路比如如何设计一个支持图文混合排版的编辑器如何保证大量图片批量上传时不卡死主线程。这些准备虽然没有直接押中原题但让我的思考方式更贴近对方的业务视角。关于笔试平台和iOS开发环境还有一个实用的经验日常练习时尽量在真机或Xcode模拟器上跑一遍写过的算法代码不要只在纸上写。iOS模拟器在Debug环境下有特殊的内存和CPU表现有些在模拟器上运行正常的代码在真机上可能会因为内存警告而崩溃。笔试前的模拟练习最好用真机跑一遍避免实战时因为环境差异出现低级失误。如果你正在准备iOS岗的春招笔试我的建议是基础知识点必须背熟但更重要的是理解每个知识点背后的原理和业务场景尤其是搜索引擎、算法、并发、UI性能优化这些与App体验强相关的模块。做题时遇到拿不准的题目可以先标记跳过去最后再回头做不要在一道题上死磕导致后面大题没时间写。笔试只是一个起点真正的考验是后续的面试和项目深挖。但一套认真做的笔试题确实是检验自己技术广度最好的镜子。