
2023年秋招小红书iOS开发岗的第三批笔试我是掐着时间点进在线考试系统的。整套题做下来最大的感受是它跟很多大厂那种“纯刷题机器筛选”不一样小红书这套笔试题明显想筛出“能干活、懂业务、有端侧优化意识”的iOS开发而不仅仅是“算法牛逼的人”。笔试里既有经典数据结构题也有大量跟iOS底层原理、性能优化、架构设计强相关的本地化问题。这篇文章不涉及具体题目原文我按记忆把题型结构、考点拆解、答题思路和踩坑教训整理出来给后面准备秋招或者打算跳槽大厂移动端的同学做一个参考。无论你是刚准备秋招的应届生还是想转iOS开发方向的社招候选人这套复盘都适用。我会把“当时我是怎么想的”“面试官大概想看什么”“哪些地方容易翻车”都讲清楚尽量还原一套笔试题背后的真实能力考察逻辑。1. 笔试整体印象与题型分布1.1 为什么小红书笔试题值得单独复盘小红书的App在iOS端一直以“复杂业务 强交互 高动态化”著称笔记信息流、视频播放、图文混排、直播、电商等大量业务塞在一个App里。这种产品形态决定了他们的客户端团队对以下能力极度敏感内存占用、首屏耗时、滑动流畅度、弱网体验、端侧治理、组件化程度。所以笔试题不会只考LeetCode老三样而是会把iOS特性、业务场景和工程经验揉进题目里。这一点在第三批笔试里体现得很明显纯算法题大概只占一半分值剩下的一半分布在iOS基础知识选择题、简答题和一道类似“架构设计”的开放题上。如果你只刷题不看iOS原理后面的半场基本是懵的。如果你只懂iOS开发、算法功底弱前面算法题又会卡得很痛苦。它考察的是一种“双线作战”能力。1.2 第三批笔试题型大致构成虽然不同批次题目会重新洗牌但第三批整体结构大概如下。我给一个分数占比和题型说明方便你感受题量分布模块题型大致比例考察目标基础知识单选/多选25%左右内存管理、多线程、Runloop、Runtime、网络等算法编程在线coding35%左右数据结构、边界处理、复杂度控制iOS专项简答文本作答25%左右性能优化、动态化方案、混合开发开放设计题文本作答15%左右架构设计、业务抽象、方案权衡能力从这个比例就能看出小红书iOS开发岗的人才画像不是“刷题机器”而是“具备扎实iOS功底、能写干净代码、能在业务复杂度里做技术决策”的人。后面我会按这个顺序逐个展开并把每部分的关键考点和答题策略讲透。2. 核心知识点拆解iOS 基础与底层原理2.1 内存管理、Runloop、多线程是必考三件套凡是iOS笔试内存管理相关题目几乎是铁打的必考题。当时考到的点包括ARC下对象生命周期、weak和assign的区别、自动释放池什么时候创建和销毁、循环引用的几种常见场景。这类题表面考概念实际考的是“你有没有在真机调试里被内存问题折磨过”。比如weak修饰的属性在对象被释放后会自动置nil这是它跟assign最本质的区别但如果问“weak表是怎么实现的”“SideTable里为什么用自旋锁”这就开始上难度了。Runloop也是高频点。很多候选人能背出Runloop有Source、Timer、Observer但一问到“卡顿检测为什么用Observer监听BeforeWaiting”“ScrollView滑动时Timer为什么不准”“performSelector为什么在子线程不执行”就露馅了。我当时的答题策略是先答主概念再补工程场景把每个知识点和实际线上问题绑定。比如回答Runloop时我会提到“主线程Runloop在BeforeWaiting阶段回调是卡顿监控的经典切入点”这样表达出来的是“我理解它而不是我背过它”。多线程同样是重头戏。GCD和NSOperation的区别、栅栏函数、信号量、死锁、队列和线程的关系这些都属于基础题。但有一道变体题让我印象很深它问的是“在主队列同步执行一个放到主队列的任务会发生什么”很多基础不牢的人直接答“没事”实际上这是必死型死锁。这种题其实就是在筛选有没有真正手写过并发代码的人。我建议复习时把所有并发问题都动手写一遍用Xcode跑一遍而不是靠脑子空想。2.2 性能优化与卡顿检测从原理到实战性能优化在小红书的业务场景里非常关键所以笔试题里专门有一道简答题给了一个线上卡顿场景让考生分析排查思路。这种题没有标准答案但答题框架一定要完整。我的表达思路是先确定问题现象再分Step定位。比如“列表滑动掉帧”可能的原因包括主线程做了耗时操作、Cell高度计算频繁、图片解码发生在主线程、图层混合过多、离屏渲染严重等。面试官想看的是你有没有一套完整的排查手段Instruments的Time Profiler、Core Animation调试、系统日志、自定义CFRunLoopObserver监控、二分法注释代码定位。千万不要只写“我用Instruments看看”那太单薄。还有一个很容易被忽略的考点CPU和GPU的平衡。Flutter、SwiftUI这些跨端/声明式方案进入视野后端侧性能优化已经不是简单的“别阻塞主线程”而是要理解渲染链路。笔试题里虽然没有直接问渲染管线但简答题方向明显在暗示“你对系统底层有多深的理解”。我建议准备时把“图像从解码到上屏”这条链路完整捋一遍包括ImageIO解码、位图内存占用计算、图层合成、离屏渲染等。2.3 动态化与混合开发小红书的必考方向小鸿书这类内容社区App对发版频率和业务迭代速度要求极高纯原生发版根本跟不上运营节奏所以动态化方案一直是团队重点。笔试简答题里出现了一道“你对iOS端动态化方案怎么看”的题目我觉得这不是随便问的而是直接呼应了他们的业务场景。答这类题不要只罗列JSPatch、React Native、Flutter、LuaView、自研容器这些名词而要说出“选型背后的成本与收益”。我当时是这样拆解的热修复类方案如JSPatch能快速修bug但审核风险高适合用在小范围应急React Native是重量级跨端方案适合承载中大型业务模块但JS桥性能、长列表优化、原生交互成本都是坑Flutter渲染性能好、UI一致性强但跟原生混合时内存和包体积需要治理至于自研容器则要投入大量人力建设。回答的落点应该是“我懂权衡而不是我只会站队”。混合开发还容易考到WebView相关知识点比如WKWebView和UIWebView的内存差异、JSBridge原理、URL拦截和MessageHandler的区别。我当时专门把JSBridge的“双端通信链路”画了一遍H5调用原生通过scheme拦截或MessageHandler原生调用H5通过evaluateJavaScript还要注意线程和时机问题。这一类题目非常适合用“把链路讲清楚”的方式得分。3. 算法题复盘从读题到 AC 的思路3.1 常见题型字符串、数组、链表与边界处理小红书第三批笔试里的算法题难度大概在LeetCode中等偏上没有到Hard竞赛题级别但很讲究边界处理和代码质量。第一道题是典型的“数组哈希”组合核心思路其实就是“用空间换时间”。这类题有一个共性读题后先确认数据范围、是否有序、是否有重复、空间复杂度限制再动笔。举个例子如果题目是“给定一个未排序整数数组找出最长连续序列的长度”标准解法是先把数组放入Set再遍历每个数字只从“自己没有前驱”的数字开始向Set里向后查找。很多人第一反应是排序后相邻比较复杂度O(n log n)但最优解用Set能达到O(n)。笔试时我一般先写出一个能跑通的版本再审视有没有更优复杂度如果时间不够就保留第一个AC版本但一定要在注释里说明优化思路。链表题也几乎是必考的。反转链表系列、链表中环的入口、合并两个有序链表、回文链表这些都是高频模板题。我当时遇到一个“链表分组反转”的变体题思路对但实现时因为指针边界写错调试了将近十分钟。这里有一条经验写链表题之前先把dummy节点的用法固定下来然后明确每一步指针的指向不要在脑内模拟三层以上指针变化直接画在草稿纸上。代码跑不跑得通是次要的关键是要在有限时间内保证思路清晰。3.2 一道典型的“业务场景算法题”怎么解小红书这类内容平台笔试里算法题偶尔会披上业务外衣。我记得有一道题大意是“根据用户的搜索结果统计Top K个高频词要求按频率降序、字典序升序输出”。本质是TopK问题但出题人加了一层“搜索词”语义让整个场景很贴近真实业务。解答TopK类题目第一反应可以考虑维护一个大小为K的小顶堆遍历数据流时间复杂度O(n log K)。如果不要求在线处理还可以用“哈希计数 排序”复杂度O(n log n)代码更短。我当时选择的是小顶堆方案因为题目明确要求“海量数据”场景堆方案的稳定性和内存表现都更好。这里有个细节容易被忽略当频率相同时要按字典序排序那么在堆比较器里要先比频率再比字符串。如果你对Swift/Python比较器的写法不熟很容易在这里翻车。这类题想拿高分光AC还不够最好在代码块上方写两行文字说明“我用堆是为了控制内存排序时先按次数后按字典序”。这一小步动作会让面试官觉得你有全局意识而不是拿到题就闷头敲。算法题做题页面一般支持切到Python如果你Swift写不熟练我建议优先用自己最稳的语言毕竟考察重点是解题能力不是语言掌握度。4. 设计题复盘架构与业务落地能力4.1 如果让你设计一个“笔记列表页”的架构第三批笔试里有一道开放设计题大意是“在一个内容社区App中设计一个笔记信息流页面请给出你的架构思路”。这种题没有标准答案但非常考验能不能把理论知识落成可执行的工程方案。我当时把回答分成了四层视图层、逻辑层、数据层、依赖层。视图层要回答“用什么方式组织UI”。UIKit时代我一般用UICollectionView FlowLayout配合高度的异步计算和缓存如果用SwiftUI则可以利用LazyVStack实现懒加载。逻辑层要回答“MVVM还是MVCViewModel怎么管理状态”。对小红书这种强交互页面我倾向于MVVM并用一个PageState枚举表达加载中、空态、成功、失败这些状态。数据层要回答“缓存怎么做”包括内存缓存、磁盘缓存、预加载策略。依赖层要回答“模块通信怎么解耦”例如用协议抽象网络层、图片加载层。我额外提了一个“分页与预加载”的细节当滚动到倒数第N条时触发下一页请求需要一个isFetching标记来防止重复请求同时把“下拉刷新”和“上拉加载”的状态机单独抽象出来。这个细节说明你是真正处理过列表业务的人而不是只会在面试里背MVVM概念。4.2 如何从笔试角度证明自己的工程能力开放设计题最怕的是“讲概念简单落方案空洞”。很多候选人写了一大堆名称什么Router、Clean Architecture、组件化但完全没有递进关系面试官根本看不出你的判断力。我的经验是回答一定要有“为什么”和“代价是什么”。我写笔记列表页架构时专门补了一段“关于图片加载的选型思考”。为什么图片要放在独立模块而不是直接调用SDWebImage因为列表页所有Cell都依赖图片而且图片内存占用极大一旦缓存策略失控Memory Warning会直接打爆体验。所以我会在架构里单独抽象一个ImageProvider协议底层可以自由切换SDWebImage或者自研的LRU缓存上层业务不需要感知。这种“面向接口编程”的表达方式在开放题里非常加分。如果题目允许画图不要画太复杂的架构图重点是清晰展示数据流和依赖方向。我当时用文字描述列出了“View → ViewModel → Repository → Network/Disk Cache”的单向依赖并在每条依赖旁边标注“为什么这样设计”。比如ViewModel持有Repository协议而不是具体类是为了单元测试时可以注入Mock数据。这些细节都是面试官在改卷时最想看到的工程直觉。5. 常见的坑与避坑经验5.1 时间分配算法题占据了大量时间第三批笔试总共时间有限我前半小时死磕一道链表边界题导致后面简答题和设计题写得比较赶。这是一个非常典型的失误。复盘时我给自己定了一个时间分配策略先花5分钟快速扫描所有题目给每道题标注难度和预期耗时算法题单题最多停留25分钟如果没AC就先写下核心思路和部分代码跳去拿其他模块的分数。你要明白算法题只占一部分分数而简答题如果空白基本等于送分给别人。在线笔试系统一般有切题记录长时间停留在一道题上还会暴露“时间感知差”。我个人建议你在练习时就给自己掐表每道题达到预设时间就强制停笔去写下一题。这跟真实考试一样追求总分的最大化而不是单题的最优解。5.2 代码风格和注释不要小看这些隐性分在线笔试虽然以AC为最优先但在候选人答案同样正确时代码风格、变量命名、边界处理会成为区分度。我交卷前会花两分钟检查这些地方是否用有意义的命名比如用userSearchResultList而不是arr1、是否处理了空数组和nil输入、循环是否可能出现死循环、资源对象是否释放。有些朋友觉得注释是多余的但我的经验是在关键逻辑上方加一行注释非常划算。比如写堆比较器时加一句“频率相同则按字典序升序”这能让阅卷人快速理解你的意图也在某种程度上弥补代码里可能存在的隐性bug。字体、缩进这些也要保持一致不要出现两个空格和四个空格混用的场面这种低级问题会严重影响阅读体验。5.3 笔试后的复盘方法错题本的价值大于继续刷题笔试结束后我做的第一件事不是刷下一套题而是打开备忘录把记忆中的题目和当时的卡点全部记下来。过了两天再回头看我发现自己很多“当场没想出来”的题其实并不难只是考试时紧张加上时间压力导致思维短路。把这些卡点整理成错题本后后续笔试和面试前我只看错题本效率比重新刷题高得多。整理错题时我会分三类第一类是知识点盲区比如对Runloop的Observer回调时机理解不到位第二类是算法题型不熟比如链表反转的变体题处理不熟第三类是表达问题比如设计题没有讲清楚“为什么”。每一道错题都对应写下一个“下次该怎么做”的行动项而不是只贴个答案。这样持续到面试阶段你会发现自己对iOS知识体系的掌控感越来越强因为错题本本质上就是在帮你建立个人知识图谱。我个人在准备秋招和校招笔试时还有一个习惯每套笔试结束后都假设自己是阅卷官给试卷打分然后再想想“如果我是面试官我会约这个人进面吗”。这套视角转换非常有用能直接帮你识别自己最薄弱的能力维度。希望这篇复盘也能帮你打开思路少走一些我走过的弯路。