ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

2023秋招小红书iOS笔试:考点分布、编程题思路与备考路线

2023秋招小红书iOS笔试:考点分布、编程题思路与备考路线 2023年秋招那会儿我投了小红书的iOS开发岗第一关就是笔试。小红书这批笔试是线上牛客网做的全程开着摄像头限时90分钟题量比我预期大不少客观题加编程题加起来接近四十道。考完之后我最大的感受是它不只是考你会不会写代码更是在筛你有没有完整的iOS知识体系以及对常见坑有没有实际踩过的认知。这篇文章就围绕2023年秋招小红书iOS开发岗第一批笔试把题型分布、知识点拆解、编程题思路和备考路线一次性讲清楚给后面准备校招iOS岗的同学做个参考。1. 笔试整体情况与考点分布1.1 笔试平台与流程安排先说流程。小红书秋招的笔试统一走牛客网收到邮件之后可以选时间段进入考试。第一批发卷时间一般在9月上旬每个批次题目不完全一样但考察范围和难度基本是一个量级。进入考试之后系统会要求打开摄像头、开启屏幕录制权限中途切出页面会有提醒切出次数多了会被标记异常所以考试前最好把手机通知全关掉浏览器只留一个标签页避免误触。整个笔试时长90分钟题型分单选、多选和编程题。客观题大概占一半以上编程题一般是两道到三道。客观题覆盖的范围很广不只是iOS还包括数据结构、操作系统、计算机网络这些计算机基础。我印象里iOS岗的笔试会把客观题分成两大部分一部分是通用计算机基础另一部分是iOS专项。通用部分主要靠平时算法和计算机基础功底iOS专项就是看你对OC/Swift语言、Runtime、RunLoop、内存管理、UI和系统框架这些内容掌握得够不够细。编程题的输入输出格式是牛客标准模式需要自己写输入解析。有些人LeetCode刷习惯了每题给的都是核心函数突然遇到这种要自己处理stdin的题目会有点慌这个在备考阶段一定要提前适应。1.2 客观题考点图谱我根据自己的记忆和一起笔试的同学反馈把客观题的考点整理成了下面这个表。当做一个“体检清单”用每个点都能说出个所以然笔试基本就稳了。分类具体考点常见出题角度OC/Swift语言属性关键字、block、KVO/KVC、Category、Swift可选型给一段代码问输出/是否编译通过内存管理ARC、weak/strong、循环引用、autoreleasepool判断引用计数变化、找循环引用系统框架RunLoop、GCD多线程、网络、UI生命周期、布局问你某种操作发生在哪个时机计算机基础数组/链表/树、排序、哈希、复杂度选择题综合考察操作系统进程线程、死锁、虚拟内存概念辨析类网络TCP三次握手、HTTPS流程、HTTP状态码流程排序、协议机制工程实践调试、性能优化、日志、崩溃分析给一个线上问题问排查思路这里有一个容易被忽略的趋势小红书这类内容社区App非常看重候选人对“列表流畅度”和“图片加载”这两块的理解。所以笔试里关于UITableView滑动卡顿、图片缓存策略的题并不少见。你要是只背了八股没实际调过性能碰到这种题就会觉得每个选项都对实际上它们考察的粒度完全不同。1.3 编程题的题型特点小红书的笔试编程题难度属于中上游不会出那种全场没人做出来的压轴怪题但也别指望送分。我遇到的题型大概是一道偏字符串/数组处理的题一道偏数据结构链表或二叉树的题再有一道可能是动态规划或贪心。很多同学容易犯的错是把编程题当成LeetCode原题来背实际上笔试出的题会有很强的“业务包装”。比如题干会写成“小红书有n篇笔记每篇有发布时间和点赞数需要按某种规则排序”之类的场景去掉包装之后核心还是排序或区间合并。读题时先把业务词汇剥掉抽成纯数据结构问题思路会清晰很多。2. iOS核心考点深度拆解2.1 内存管理从ARC到循环引用排查iOS笔试对内存管理的考察非常细致不是问“什么是ARC”这种概念题而是给你一段代码让你判断某个对象什么时候释放、引用计数是几、会不会造成循环引用。先说ARC。ARC是编译器在编译期自动插入retain/release/autorelease的机制它不是一个运行时垃圾回收器。这意味着编译器必须能静态分析出对象的持有关系分析不出来就会产生错误或泄漏。属性关键字里strong表示强持有weak表示弱持有且对象释放后自动置nilcopy会拷贝一份新对象assing对ObjC对象不安全对基本类型没问题。笔试里最常考的循环引用场景有三个。第一个是block对象持有blockblock又捕获了self就会形成self - block - self的环。解决办法是用__weak __typeof(self) weakSelf self; 在block里再用strongSelf判空。第二个是delegatedelegate属性要声明为weak而不是strong否则两个对象互相强持有就泄漏了。第三个是NSTimer或CADisplayLinktarget是self时timer会被runloop持有如果不invalidate就永远不释放。我还记得有一道题是拿__weak和__unsafe_unretained做对比很多人会忽略后者。__unsafe_unretained也是弱引用但对象释放后它不会自动置nil变成野指针访问就会crash。笔试里问“下列哪个关键字在对象释放后会产生野指针”答案就是它。2.2 Runtime与消息机制理解动态性的钥匙Runtime是iOS笔试的重头戏。ObjC是一门动态语言方法调用本质上是给对象发送消息也就是objc_msgSend。消息发送的流程是先查对象的isa指针找到类对象再在类的method_list里找method找不到就去父类找直到根类再找不到就走消息转发流程。笔试常考的一个点是消息转发的三个阶段动态方法解析resolveInstanceMethod、快速转发forwardingTargetForSelector、完整转发methodSignatureForSelector forwardInvocation。你可以把这个流程理解成一个员工找不到人处理任务先问自己能不能现场学再问有没有同事能帮忙最后还要把一个完整任务包发给别人。问你“哪个方法可以为类动态添加方法实现”答案就是resolveInstanceMethod它内部调class_addMethod。KVO的底层原理也是高频题。KVO通过isa-swizzling动态生成一个NSKVONotifying_XX子类重写被观察属性的setter方法在setter里调用willChangeValueForKey和didChangeValueForKey从而通知观察者。所以一个对象被KVO之后它的isa指针其实已经变了。考到“KVO为什么能生效”时答出这个派生类和isa-swizzling就够一半了。Method Swizzling也是常客。它利用Runtime在运行时交换两个方法的IMP。要注意的是交换应该在load方法里用dispatch_once包一层避免重复交换交换的是实例方法还是类方法要看获取Method时传的是class还是metaClass这些细节笔试经常挖坑。另外现在主流做法是尽量避免Swizzling用它要有完整的降级方案毕竟它牵扯到全局所有实例出了问题很难复盘。2.3 RunLoop、多线程与并发RunLoop是iOS开发者每天打交道又容易说不清的东西。RunLoop本质是一个事件循环iOS的App启动后主线程就进入一个runloop不停地接收触摸事件、定时器事件、网络事件空闲时就睡眠有事件就唤醒处理。笔试里常考RunLoop的Source/Timer/Observer三种输入源以及它和AutoreleasePool之间的关系。Source1是系统事件源触摸事件就是通过Source1发到App的Source0是自定义事件源需要手动唤醒线程Timer就是定时器。每次RunLoop循环结束时会自动释放当前AutoreleasePool这也是为什么主线程创建临时对象不会无限堆积内存。GCD部分考得最频繁的是队列和死锁。串行队列、并发队列、主队列这些概念必考dispatch_sync和dispatch_async的区别也是送分题。真正容易错的是死锁场景在主队列上调用dispatch_sync(主队列)就会死锁因为主队列是串行队列你在执行当前block的同时又向同一个串行队列提交一个需要等待的空block两个互相等待永远执行不完。类似地在一个串行queue里再dispatch_sync到它自己也会死锁。信号量dispatch_semaphore也值得复习它用来控制并发数量或做同步等待。笔试喜欢问“semaphore初始值为NM个任务并发最多同时执行几个”。这个理解源码就清楚了每次wait信号量减1为0时阻塞所以答案是N。还有dispatch_once保证block只执行一次内部也是用了信号量和原子操作。2.4 UI、系统框架与性能优化UI这部分的笔试题目通常在考察你是否真的理解布局和渲染而不是只会在Xcode里拖控件。UIStackView、Auto Layout、frame/muBounds的区别、UIView和CALayer的关系这些都要能说清楚。比如UIStackView在iOS 11以后有了很多改动stackView会根据axis、spacing、distribution自动管理子视图约束但它并不会自动解决所有布局问题子视图的intrinsic content size、压缩阻力和抗拉伸优先级都会影响最终效果。如果你不理解这些优先级遇到stackView里文字被截断的问题就没法排查。性能优化方面的考点更贴近小红书这类业务。列表卡顿的常见原因包括cell的layout重复计算、图片解码在主线程、离屏渲染过多、混用的图层合成开销过大。提高列表流畅度的常规手段有cell高度缓存、异步绘制、预排版、图片尺寸压缩、避免在cellForRow里做耗时操作。iOS 14开始UICollectionView的prefetching机制也是一个考点。还有系统框架的细节题比如CoreBluetooth的CBCentralManager的系统级蓝牙授权状态和App内蓝牙开关状态是两回事系统弹出授权弹窗后需要回调处理。iOS 13以后新增了CBManagerStateUnauthorized等状态App要在状态回调里统一处理。这类题表面上考蓝牙实际是看你对系统API的状态机有没有完整认知。电池优化也偶尔出现在校招笔试里。它主要涉及定位精度选择、后台任务、推送方式和屏幕刷新率。很多人不知道iOS的省电模式会限制CPU频率和网络请求行为导致后台任务表现不一致。这类题目一般不会很尖刻但你得能把优化方向和系统机制对应起来。3. 编程题实战与解题策略3.1 高频算法题型的解题框架小红书笔试题的算法难度约等于LeetCode中等题。我把几个高频题型和对应框架整理了一下这部分备考性价比最高。字符串和数组处理是每次笔试几乎必出的。常见思路是双指针、滑动窗口、哈希计数、区间合并。比如“找出最长不含重复字符的子串长度”用滑动窗口right指针不断右移用哈希表记录字符最后出现位置遇到重复时left跳到重复位置1过程中维护最大长度。笔试如果出这类题写出维护左右指针的循环再确认一下left取值逻辑基本就能过。链表题必背的是反转链表。迭代法用pre、cur、next三个指针滚动递归法的核心是先翻后面再让后面节点的next指向前一个节点。这两套代码顺手要能10分钟内写出来。二叉树常考层序遍历、前中后序遍历、最近公共祖先、路径和。层序遍历用队列做BFS每层循环前先拿到当前队列size就是这一层的节点数。这个模板在LeetCode 102里就是原题笔试时候直接套。动态规划和贪心对很多人来说是瓶颈。要是备考时间紧优先把背包问题、最长递增子序列、最大子数组和这几个经典模型吃透。比如最大子数组和用Kadane算法遍历时维护当前累加和cur和全局最大和maxcur小于0就重置为0最后max就是答案。这类题一旦理解状态转移方程反而比链表题好写。3.2 笔试环境下的应试技巧编程题在笔试环境里和在IDE里刷题完全是两种体验。首先是用例输入要自己处理。牛客的输入是一行或多行你要用NSString读取整行再按空格拆分成数组写完业务逻辑后还要记得输出换行。很多人因为输入解析写错全题白做特别可惜。我的做题顺序是先快速看全部编程题评估难度先把最有把握的写完再啃难题。每题先读一遍示例理解输入输出格式。然后不管是暴力解法还是最优解法先保证能跑通普通用例至少把部分分拿到再考虑优化。笔试判题一般是按测试用例百分比算分只过一半用例也有分千万别在一道题上死磕到没时间写别的。写代码时养成好习惯变量命名清楚核心逻辑边写边注释即使最终没有AC面试官看你的代码也会有一个好印象。有些公司笔试是系统自动评分但小红书这类注重工程化的团队在后续面试时可能会看到你的代码代码风格不拉胯本身就是加分项。4. 备考路线与工具链准备4.1 从基础到专项的复习规划针对小红书这种笔试我把备考路线分成三个阶段。第一个阶段是补计算机基础数据结构、算法、操作系统、网络这四门课有一个相对薄弱的笔试就很难过这个阶段大概两到三周每天固定刷算法题并复习一个操作系统或网络专题。第二个阶段是iOS专项突破。把上面提到的内存管理、Runtime、RunLoop、GCD、UI、网络、存储这些模块逐个过一遍每个模块不只是看文档要写demo验证。比如你学weak原理就在Xcode里创建一个对象用__weak引用它再把它置nil观察是不是自动变成nil学KVO就自己写一个派生类实现setter看看不触发KVO时手动调用will/didChangeValueForKey能不能生效。知识只有亲手验证过笔试遇到变体题才不容易慌。第三个阶段是真题模拟和节奏训练。用牛客网的真题模拟环境做两到三套题严格控制90分钟模拟考场状态。我建议把刷题和笔试平台操作分开练习代码在本地写完再贴到平台里也要跑一遍很多平台对函数的调用方式有区别提前适应能减少考场上的低级失误。4.2 高效工具链模拟器、抓包与调试iOS开发调试离不开模拟器和真机。模拟器现在可以模拟不同的设备尺寸、系统版本还能模拟网络状态弱网场景笔试里问到的很多系统行为差异都能在模拟器里验证。不过模拟器不能完全代表真机比如真实的内存压力、CPU调度、GPU渲染、传感器行为都有差异所以备考时常备一台真机很有必要。网络调试用Charles比较多。它做HTTPS抓包时需要安装并信任CA证书然后在手机上安装描述文件并开启“允许完全信任”。这套流程里最容易踩的坑是证书装好但系统版本升级后信任开关被重置导致抓包看到一堆SSLHandshake错误。如果你在备考阶段要分析一个App的网络请求用Charles辅助看请求头、参数、响应体能帮你更好地理解客户端和服务端的交互逻辑。开发和调试时要注意开发者模式和证书的管理。iOS开发者账号续费后证书需要更新描述文件要及时重新下载安装否则Xcode会提示“The provisioning profile is expired”。校招笔试不直接考这个但实习面试和在线测试过程中可能需要你打包一个Demo给面试官看如果这一步卡住会很尴尬。提前把开发者相关流程跑熟属于那种“平时用不上、用上就救命”的技能。4.3 原生iOS与跨平台技术的视野对比小红书技术栈以原生为主所以笔试重点是原生iOS。但作为iOS开发了解一些跨平台方案是有必要的因为你入职后可能要和做Android、前端的同事协作也可能会接触到混编业务。原生iOS和纯跨平台方案各有利弊。原生在系统API调用、性能、交互体验上优势明显尤其是复杂的动画和大量图片列表场景原生可以精确控制渲染细节。跨平台方案如Flutter、React Native、uni-app主打的是多端复用开发效率高适合业务快速迭代但遇到系统级能力和疑难性能问题还是得回到原生层去处理。笔试里如果出现“App需要同时支持iOS和Android你会怎么选型”这种开放题你要能说出来考虑团队能力、业务复杂度、性能要求和系统能力使用深度。Android和iOS开发的区别也是面试官喜欢问的。iOS内存管理用ARCAndroid用Java/Kotlin的GCiOS的UI是UIKit的响应链Android是View体系iOS后台任务限制严格Android有大量Service和广播机制。这类问题不要求你精通Android但能讲清本质区别会让面试官觉得你有对比思维和全局视野。5. 常见问题与踩坑实录5.1 笔试平台操作最容易翻车的几个点笔试平台的操作失误有时候比知识盲区更致命。我总结了几条身边同学真实遇到过的坑先写出来提醒大家。第一输入输出格式问题。有些编程题要求输出精确到小数点后两位有些要求最后没有多余空格这些细节不看清格式错了直接判错。写完之后一定自己构造一两组边界用例测试比如空数组、只有一个元素、数值上限。第二摄像头和屏幕共享异常。考试前检查摄像头是否被其他程序占用浏览器是否开启了多个标签页关闭所有弹窗和通知插件。如果考试中途摄像头断掉系统可能会在后台记录异常标记后续有可能被判定为作弊特别冤。第三网络波动导致代码没保存。牛客网的代码编辑器会自动保存但也有延迟别在最后五分钟大改代码提交前确认代码已经在编辑框更新了。如果提交时间很紧张优先保已通过用例的部分不要在最后时刻重构。5.2 iOS知识点的易错易混对照笔试和面试里有很多iOS概念容易混淆我把它们整理成一张速查表。表格里这些点几乎每年都有人错备考时候反复看几遍能有效减少失分。易混概念核心区别笔试常见考法weak vs assign vs unsafe_unretainedweak自动置nilassign通常用于基本类型unsafe_unretained不置nil会野指针选一个不安全的弱引用关键字synchronous vs asynchronoussync会阻塞当前线程async不会判断会不会死锁frame vs boundsframe是相对父视图坐标bounds是相对自身坐标旋转后frame变化而bounds不变的场景深拷贝 vs 浅拷贝指针复制 vs 内容复制判断copy/mutableCopy结果isKindOfClass vs isMemberOfClass前者判断是否属于类或子类后者必须精确匹配给继承关系判断True/Falsestrong vs copycopy会复制一份新对象可避免可变对象被外部修改NSString属性用copy的原因onViewDidLoad vs viewWillAppear vs viewDidAppear生命周期各阶段的触发时机和次数判断某操作在哪个时机执行堆 vs 栈堆需手动/ARC管理栈自动管理全局变量、局部变量的存储位置TCP vs UDPTCP可靠、面向连接UDP不可靠、无连接视频通话为什么用UDP除了这些概念题笔试中还经常给一段代码让你判断输出。比如“NSMutableArray *arr [NSMutableArray array]; arr nil; 会不会崩溃”答案是nil发消息在OC里是安全的不会崩溃。但如果是向野指针发送消息就会崩溃这两者很容易搞混。再比如“__block int a 0; 在block里修改a能否生效”这是可以的但block被拷贝时a的存储位置会从栈上搬到堆上所以用__block修饰的本质是让变量变成可以捕获和修改。5.3 出分之后的复盘动作笔试结束后别干等结果把做错的题和没答上来的知识点复盘一遍。牛客网一般能查看每个测试用例的通过情况结合自己的记忆整理出一份错题集。这份错题集会在后面的面试中起到很大作用因为如果笔试挂了简历可能被锁一段时间但如果笔试过了面试官大概率会看你的笔试答题情况你答得不好的题正好是面试时最可能被追问的点。我个人的习惯是给每个考点建一个note文件里面写三列考点、我的理解、验证方式。比如写KVO的知识点就先写下底层原理再粘贴一段自己写的demo代码再写“用instruments观察对象isa变化”的验证步骤。这样整理出来的笔记不是为了给别人看而是确保自己真的能复述和动手验证。笔试前的最后一周我只看这份note不再去搜那些零散的文章金句。写在最后的一些个人体会回过头来看这次2023秋招小红书iOS开发岗第一批笔试我最深的感触是笔试考的不是你临时背了多少面经而是你长期积累下来有没有形成一套完整的知识网络。iOS开发的知识面很宽从语言底层到UI渲染从并发编程到网络协议每一块都像是拼图缺少一块面试和笔试遇到关联问题就会卡壳。我自己的做法是把iOS的知识体系按“语言基础、内存管理、Runtime/消息机制、RunLoop、多线程、UI、网络、存储、性能优化、工程化”这十个模块去拆每做一个模块的知识点都会配套写一个几行的小Demo跑一遍。笔试前每天再花半小时过一遍易错对照表比临时刷题有效得多。最后分享一个小技巧遇到不会的笔试客观题别乱猜先用排除法把明显错误的选项去掉再用“iOS系统实际行为”去反推哪个更合理。iOS很多机制是有内在一致性的比如面向对象的继承决定了消息转发会逐级找父类既然isa链是自底向上的那么KVO通过动态子类来拦截setter也就顺理成章了。掌握这种底层逻辑比记住一百个零散结论更能帮你稳稳拿分。
返回列表