FEATURED · 精选文章

顺丰科技iOS面试客观题解析:从内存管理到RunLoop的考点梳理

发布时间 / 2026/8/31 20:44:42
来源 / 创域科博编辑部
栏目 / 资讯中心
顺丰科技iOS面试客观题解析:从内存管理到RunLoop的考点梳理 看到“顺丰科技2019秋招iOS开发工程师客观题合集”这个标题时我第一反应是又有人开始考古了。说句实在话四年前的客观题放到今天确实有些答案已经变化尤其是Swift版本迭代带来的细节差异。但iOS面试的核心考点一直没变Objective-C的底子、内存管理、RunLoop、GCD、响应链、网络安全依旧是大多数公司筛选候选人基本功的首选顺丰科技作为物流行业里技术投入很大的团队也不例外。这套题集的真正价值不在于让你背下原题而是帮你画出一张iOS面试的准备地图。我自己刷过不少旧题结论很直接客观题是最公平的筛选器答案非黑即白一个知识点的模糊都藏不住。尤其像顺丰这种“物流移动端”的业务形态题目会稍微向地图定位、列表性能、弱网处理、蓝牙打印等场景倾斜但整体还是偏基础。所以如果你正准备投递iOS开发岗位不管目标是大厂还是垂直领域公司把这份2019年的题集认真过一遍对查漏补缺非常有用。下面这篇文章我会按考点模块拆开讲顺带给出一些我刷题时的易错点整理和答题思路。不承诺“原题复现”但保证这些方向到了面试场上依然能打。1. 这组合集到底在考什么先看清题目背后的筛选逻辑1.1 客观题不等于死记硬背它筛的是基本功很多人一看到“客观题合集”就觉得是背诵题其实恰恰相反。iOS开发的客观题大多是选择一个正确选项干扰项设计得很刁钻比如把“weak”和“assign”混在一起把“同步串行”和“异步串行”放在同一个选项里。这种题目一旦对底层理解不深很容易踩坑。我记得当年刷题时遇到一道题问“下面哪个属性修饰符在ARC下是默认的”选项里有assign、strong、weak、atomic。如果在MRC时代待过自然会想到默认是assign但在ARC下如果对象类型没有显式修饰符默认其实是strong而基本数据类型默认才是assign。这种题纯粹考基本功不靠理解根本做不对。所以客观题真正的作用是让面试官快速判断你有没有形成完整的知识框架。你能做对不一定说明你有多强但如果你做错基本可以确定某个模块是短板。反过来我们应该用客观题来给自己做“体检”而不是把它当成题库去背诵。1.2 顺丰科技的技术画像“物流移动端”的独特考点顺丰科技不只是一家物流公司的技术部门它承担了顺丰整体的信息系统建设包括快递员App、仓储管理、智能客服、地图轨迹等业务线。对iOS工程师来说这些业务意味着什么意味着你的代码要跑在大量中低端设备上要面对恶劣的网络环境要处理海量运单数据的列表刷新还要适配蓝牙打印面单等硬件交互。因此顺丰2019秋招的客观题里虽然大部分考点和通用iOS基础题重复但在应用场景上会有偏重。比如内存管理题目会包装成“某模块频繁创建对象导致内存暴增”多线程题目会包装成“批量上传运单轨迹需要控制并发数”列表优化题目会自然提到“大量包裹记录滚动卡顿”。这些都是物流场景下的常见工程问题。我刷完这套题最大的感受是单纯会背API定义不够你必须把知识点翻译成业务能力。面试官不指望你背出RunLoop的源码但希望你能说出“在快递员上报位置这种高频场景下怎样设计RunLoop逻辑才能省电”。这也是我后面几个章节会把考点和场景放在一起讲的原因。2. 核心考点拆解OC语言、内存管理与Runtime2.1 内存管理ARC与循环引用是必考题内存管理是iOS面试的“钉子户”顺丰科技2019年的客观题里也有一大半在考ARC、循环引用和block对变量的捕获。最经典的一个陷阱题我几乎每次提都有人中招就是下面这段代码到底会不会循环引用self.myBlock ^{ [self.view setNeedsLayout]; };答案是会循环引用。因为self持有myBlock而myBlock内部又捕获了selfblock被拷贝到堆上后strong持有self两个对象谁也释放不了谁。但如果这个block不是self的属性而是局部变量那就不构成循环引用因为block没有被self持有释放完作用域就结束了。很多人只记住了“block里用self会循环引用”却不去思考block的类型和存储位置导致面试官追问时当场卡壳。block在编译期主要有三种类型__NSGlobalBlock__、__NSStackBlock__、__NSMallocBlock__。只有捕获了变量的block被copy后存在堆上才会带来强引用问题。面试题如果问你“为什么用weak修饰block属性”正确答案不是为了“安全”而是为了打破循环引用不过现在ARC下大部分block都有一个“自动从栈拷贝到堆上”的过程所以属性里是否写copy更多是表达意图。另外还有一个高频组合题在block里用了weakSelf之后要不要在block体里面再写一个strongSelf这题在顺丰题集里出现过变体。我的看法是如果block是异步执行且执行时间不确定建议在block内部先__strong typeof(weakSelf) strongSelf weakSelf;防止执行过程中weakSelf被提前释放导致后续对self的连续调用出现半路nil的情况。如果只是单纯的回调里访问一次属性不写strongSelf问题也不大但作为面试答案讲出这层思考会更完整。2.2 Runtime消息发送、方法交换与isa指针Runtime是区分“会用iOS”和“懂iOS”的分水岭。顺丰2019年的客观题里直接考了objc_msgSend的执行流程、method_exchangeImplementations是否会影响父类方法以及class_addMethod能不能覆盖已有实现。这几个问题看起来零散其实背后都是同一套逻辑类对象如何存储方法、实例对象如何找到实现。objc_msgSend的执行流程可以简要概括为先取isa指针找到类对象然后查cache命中直接调用未命中则去方法列表里二分查找找到后填充缓存没找到就走消息转发流程。很多人会忽略cache这一步但面试官如果让你解释“为什么连续调用同一个方法第二次比第一次快”答案就是方法缓存。关于method_exchangeImplementations顺丰题集中有一道判断把类A的方法实现和分类B的方法实现交换会影响子类吗正确答案是如果子类没有重写这个方法那么子类继承到的实现也会交换因为交换的是类对象方法列表里的IMP指针。这个细节我当年踩过坑后来在项目中做AOP埋点时又体会了一遍。还有一道经典的“KVO底层用什么技术实现”答案是isa-swizzlingKVO在运行时动态生成一个子类重写被观察属性的setter方法然后修改实例对象的isa指向这个中间类。这题在多个版本的面试题里都出现过顺丰科技2019年的题集里也有一道类似选择。如果你能顺手说出“观察者移除不上会崩”这个坑面试观感会明显不同。2.3 KVC/KVO与属性修饰符容易被忽略的小陷阱KVC和KVO是Objective-C的招牌特性客观题考得也很细。比如KVC调用setValue:forKey:时底层查找顺序是先找setKey:方法再找成员变量_key如果都没有会调用setValue:forUndefinedKey:并抛异常。很多同学只背了结论没有理解查找顺序遇到“成员变量是key而不是_key”的题目就懵。KVO部分除了底层原理还喜欢考嵌套触发顺序。比如一个属性同时被两个对象观察改变属性值时观察回调的顺序是否固定。答案是不保证顺序因为通知机制用的是一个无序的集合存储观察者。这道题我在刷顺丰题集时遇到过正确答案是“无法确定观察回调的顺序”很多同学选了“按照添加顺序”结果错了。属性修饰符的小陷阱也很多。atomic并不能保证对象内容线程安全它只是保证属性的getter和setter是原子操作无法保证对象在遍历时不被其他线程修改。而weak和assign的区别更基础二者都不会增加引用计数但weak在对象释放后会自动置nilassign不会所以修饰对象类型用weak基本数据类型用assign。这种题目没有技术含量但很能说明基础扎不扎实。3. 多线程与RunloopiOS开发的送分题和丢分题3.1 GCD队列、任务与死锁判断多线程是iOS开发的常客GCD又是多线程里的重头戏。顺丰2019秋招客观题里有一道几乎是送分题但在每个班级里总有几个人会选错那就是“在主线程执行下面代码会死锁吗”dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(Hello); });答案是会死锁。原因很简单主队列是串行队列dispatch_sync要求把block放到主队列执行但当前线程就是主线程同步等待时主线程被占住无法去执行队列里的block形成互相等待。同样的道理在任何一个串行队列里如果又用dispatch_sync向这个队列提交任务也会死锁。但把它换成dispatch_async就不会死锁只是不会立刻执行。我还见过一类变体题先自定义一个串行队列然后在主线程里dispatch_sync(serialQueue, ^{ // do something })这个会不会死锁不会因为自定义串行队列不依赖主线程同步提交到后台线程执行主线程会等待它执行完。这个差别的本质是队列和线程之间的绑定关系而不是“看到sync就死锁”。GCD还有一个高频考点是栅栏方法dispatch_barrier_async和信号量dispatch_semaphore_t。顺丰物流场景下最常见的多线程需求是“并发请求多个接口全部回来后再刷新页面”经典实现是DispatchGroup配合dispatch_group_notify也可以用信号量把并发转成串行。客观题如果问“信号量初始值设为1代表什么”答案是同一时间只允许一个任务访问临界区相当于一个互斥锁。3.2 NSOperation与多线程选型不同场景的取舍很多同学过了GCD就觉得多线程稳了但顺丰2019题集偏偏还有一道题问“什么时候用NSOperation更合适”。我自己的判断标准是如果只是简单提交异步任务GCD哪怕一行代码搞定如果任务之间有依赖关系、需要取消、需要控制最大并发数NSOperation更省心。NSOperation和GCD的最大区别是Operation是一个“对象”能表达任务状态能建立依赖。比如快递员App里要上传“订单图片运单轨迹签名数据”这三个任务可能要在不同时间准备数据用Operation依赖可以写成signOperation依赖uploadImageOperationGCD就需要用DispatchGroup或者手动加信号量代码会散乱很多。另外NSOperation还内置了queue.maxConcurrentOperationCount可以限制并发数这在批量上传场景里是很实用的能力。顺丰题里如果问“如何控制同时进行网络请求的数量”答案可以参考信号量或者OperationQueue最大并发数。前几年还有一道判断“NSOperationQueue本质上是基于GCD实现的”这句话是对的虽然它暴露了更上层的API但底层依然依赖GCD。3.3 RunLoopApp启动后的事件循环真相RunLoop是面试里的深水区但在客观题里反而考得比较直接。最常见的一道题是把一个NSTimer添加到NSDefaultRunLoopMode然后滑动UIScrollView为什么定时器不走了答案是主线程在滑动时RunLoop切换到了UITrackingRunLoopMode只有NSRunLoopCommonModes下注册的源才能在两种模式下都能响应。顺丰科技2019年的题集里有道变体把NSTimer换成了dispatch_source_t问滑动时是否回调。dispatch_source不依赖RunLoop走的是内核事件源所以滑动时依然会触发。这个区别很值得记因为现代iOS开发里用GCD创建定时器越来越常见就是为了避免RunLoop mode切换带来的问题。RunLoop还有一道高频题如何让一个后台线程常驻不随任务结束而释放。答案是给这个线程的RunLoop添加一个Port源或者用runMode:beforeDate:循环运行。顺丰的多线程题里出现过类似选项问“用performSelector:onThread:往子线程派发任务为什么子线程不执行”大概率是这个子线程没有启动RunLoop。这个点很实际比如快递员App里要在一个后台线程持续处理定位数据如果线程跑完就退出后续回调全丢。4. UI与架构题从AutoLayout到响应链4.1 响应链与hitTest点击事件到底交给谁处理UI部分的客观题基本上离不开响应链。顺丰2019年的题集里有一道很典型的选择在父视图上叠了一个透明View透明View挡住了一个按钮点击按钮的位置事件最终由谁响应答案是透明View因为它处于响应链的最上层能响应用户点击按钮根本没机会收到触摸事件。完整的事件解析过程是系统将触摸事件交给UIApplicationApplication再交给UIWindowUIWindow通过递归调用hitTest:withEvent:找到命中视图。hitTest内部逻辑大致是先判断自身能不能接收事件、点的坐标是否在自身bounds内然后从最上层的子视图开始倒序遍历子视图只要子视图的hitTest返回非空就返回这个子视图否则返回自己。有一个非常实用的延伸是我在项目里经常用的重写某个View的hitTest:withEvent:来扩大按钮点击区域。比如一个20x20的小按钮实际点击热区要求是44x44你可以在hitTest里把触摸点做偏移判断或者重写pointInside:withEvent:扩大bounds。客观题不会直接考这个但面试官问“如何提升小按钮的点击体验”时能答出来会很加分。另外响应链还牵扯到“事件响应者链条”和“UIView与UIViewController之间的传递”。一道经典判断题“touchesBegan:默认会沿着响应者链向上传递吗”答案是如果当前响应者没有实现任何触摸方法事件会传递给nextResponder一旦实现了touchesBegan:默认不会自动传给下一个响应者除非手动调用super或显式调用nextResponder。这个细节在iOS事件处理里非常重要。4.2 列表优化顺丰场景的大列表性能与复用物流类App最不缺的就是列表。运单列表、轨迹列表、派件列表一屏塞几十条记录很常见滑动性能一旦掉帧用户体验立竿见影。顺丰科技2019年客观题里关于UITableView的题目主要集中在Cell复用、预估行高、离屏渲染和局部刷新上。先说复用。dequeueReusableCellWithIdentifier:forIndexPath:和没有forIndexPath的区别前者会保证返回非nil的cell并应用注册类或storyboard里的模板后者需要你自己处理nil的情况。很多人忽略了这道基础题但一旦面试官追问“复用池是怎么实现的”就涉及到表格视图内部按identifier维护一个可重用cell栈。再说行高。iOS 11之后自动布局加持下estimatedRowHeight成了默认打开的特性但预估行高如果设置得太离谱会导致滚动条跳动、卡顿。在顺丰这类数据量很大的列表里我一般会把固定高度Cell直接返回具体高度动态高度才用AutoLayout估算缓存计算结果。这个技巧对应到客观题就是哪种做法能减少列表卡顿答案是计算并缓存行高而不是每一行都动态计算。离屏渲染也是一个经典陷阱。iOS会在某些情况下把图层渲染到屏幕外比如使用了cornerRadius加masksToBounds、设置组阴影、使用drawRect:绘制。客观题喜欢考“以下操作中哪个可能触发离屏渲染”只需要记住一个原则任何需要额外合成但无法在当前屏幕空间直接画出来的效果都有触发风险。顺丰题集里有一道问“为什么设置cornerRadius会导致列表卡顿”正确切法是对需要圆角的视图直接使用圆角图片或者用UIBezierPath做裁剪减少离屏渲染开销。4.3 架构考察MVC、MVVM与组件化的边界iOS客观题也会考架构虽然不会让你现场写代码但会出判断题MVVM一定比MVC好吗正确答案显然不是。架构没有银弹MVC在简单页面上清晰直观MVVM在复杂交互和大量状态同步时更有优势。我理解顺丰科技考这类题核心是看候选人有没有架构意识。物流App里一个订单详情页可能要同时展示状态流转、运费明细、地图轨迹、客服入口如果全部塞进ViewController肯定一大坨。MVVM通过ViewModel把状态与视图绑定配合双向绑定或响应式框架可以显著降低控制器负担。但客观题不会让你写MVVM它可能这样问“下面哪种做法有利于大型App的维护”答案是模块化、组件化、减少全局单例。组件化不是把每个页面抽成一个pod而是要定义清晰的接口、避免循环依赖、通过路由解耦页面跳转。2019年顺丰题集里有一道关于路由的题问“Android和iOS混合场景下为什么需要统一路由”其实就是想考察你是否理解每个平台导航栈的差异以及跨端页面跳转如何统一管理。5. 网络与系统框架iOS开发者的底层素养5.1 HTTPS与网络安全证书校验的基础概念网络层是iOS面试里一个绕不开的点。顺丰科技2019年的客观题里有几道关于HTTPS和SSL/TLS的难度不高但很能看出候选人有没有真正做过安全方面的配置。HTTPS的核心在于“加密”和“身份验证”。它先使用非对称加密交换对称密钥后续通信用对称加密兼顾速度和安全。面试常问“HTTPS一定安全吗”答案是不一定如果你没有做证书校验中间人攻击依然存在。客户端只校验域名和证书链很容易被安装了伪造证书的代理工具拦截。iOS里做SSL Pinning是常见的安全手段。你可以把服务器证书内置到App里请求时校验服务器返回的证书是否匹配也可以只保存公钥减少证书过期带来的更新频率。2019年顺丰题集里有一道选择题问“AFNetworking中AFSecurityPolicy的作用”选项里有验证证书合法性、绕过证书验证、设置请求超时等。正确答案是验证证书合法性。你如果还能说清SSLPinning三种模式无验证、默认验证、公钥验证这一题的得分点就全拿满了。顺丰这样的物流科技公司在网络安全上会更敏感因为快递服务涉及用户地址、手机号等敏感数据。客观题如果给你一个“App内收集用户位置信息时应该怎么做”正确方向一定包括最小化采集、加密传输、明确隐私弹窗说明。这些点在高强度业务环境中面试官很看重。5.2 定位与电池优化快递员App的后台困境物流和定位几乎绑在一起顺丰科技自然很关心定位功能和耗电问题。2019年秋招的客观题里有几道关于CoreLocation和电池优化的题里面最容易错的是“如何做到后台持续定位但保持低功耗”。很多人第一反应是后台模式支持无限定位但实际上只要有后台定位权限App依然能收到locationManager:didUpdateLocations:回调只不过系统会限制频率。真正影响耗电的因素是定位精度、距离过滤器和更新频率。所以正确答案要围绕这几个维度把精度设置为kCLLocationAccuracyHundredMeters而不是kCLLocationAccuracyBest设置distanceFilter避免高频回调配合startMonitoringSignificantLocationChanges做重大位置变化监听。顺丰的快递员App会做“轨迹上报”如果每秒钟都在往服务器传坐标电量很快会被打穿。我在类似项目中常用的做法是前台时用高精度实时定位进入后台后降级为“围栏低精度批量上报”同时把批量打包压缩后再上传。这套思路即使不写代码也能在面试中讲清楚因为面试官更关心你对系统资源的理解。电池优化还有一个考点是“后台任务”。beginBackgroundTaskWithName:expirationHandler:并不是真的保持后台无限运行它只是给App一点额外时间完成短时任务。系统分配的时间有限时间到后必须结束。顺丰题集里有一道判断问“在后台任务中执行一个长耗时网络请求是否合理”答案是不合理正确处理是后台任务里只做轻量收尾长耗时工作应该放到系统后台模式或推送唤醒。5.3 CoreBluetooth蓝牙打印与设备状态管理物流现场有一个高频操作快递员用蓝牙热敏打印机当面单。所以iOS的蓝牙相關题目顺丰科技也会考但不会很深。最常见的一道题是“CBCentralManager的状态有哪些”包括unknown、resetting、unsupported、unauthorized、poweredOff、poweredOn。这里有个容易混淆的点系统级蓝牙状态和App级蓝牙授权状态要分开看。CBCentralManager.state表达的是手机蓝牙硬件和系统授权的综合状态而CBPeripheralManager也有自己的状态。App在本身没有申请蓝牙权限时调用蓝牙接口会得到unauthorized。题目如果问“App内能不能通过代码直接修改系统蓝牙开关”答案是不能只能引导用户去设置里开启。快递员用蓝牙打印面单还有一个高频问题为什么搜索不到某些蓝牙设备可能原因包括设备不是BLE协议、设备已被系统缓存、外设广播数据格式不兼容。iOS不像Android那样可以拿到所有蓝牙信息CoreBluetooth会过滤部分经典蓝牙设备。面试如果问“如何排查找不到蓝牙打印机”我会回答先看CBCentralManager状态再确认设备工作模式再看广播数据UUID是否匹配最后考虑距离和信号干扰。顺丰对这种硬件交互场景的稳定性特别重视所以这类排查思路也很加分。6. 刷题复盘与面试准备把题目变成自己的能力6.1 把错题变成知识卡片刷题的记录方法我见过太多人刷题刷完就忘因为只看了答案没有整理。客观题的正确打开方式是准备一个错题本但不要抄原题而是记录“考点易错点回答关键词”。我当年刷顺丰这套题时专门建了一个表格每道错题填一行慢慢就形成了自己的知识图谱。表格可以这样设计模块、题干缩写、正确答案、错误原因、核心结论、一句话记忆技巧。比如内存管理模块里“block循环引用”这题我记录的错误原因是“忘了block被copy后持有self”核心结论是“self持有blockblock持有self必须weak化”记忆技巧是“如果你在block外边看到self关键字先想有没有被block持有”。这个方法的深层价值不在于让你背结论而在于逼你主动输出。记录的过程本身就是一次复盘你必须用自己的话把答案说清楚才能写下来。很多知识点你以为自己懂了一旦落到纸面上就会发现说不通。所以别嫌麻烦刷一套题花两小时整理错题花三小时是很正常的也是性价比最高的投资。6.2 从做题到讲题表达能力才是面试关键客观题做得再好面试时不能把结论讲清楚分数照样拿不到。面试官不是让你做选择题而是让你当老师把知识点讲给一个“完全不懂的人”听。如果你能讲到对方点头说明你真的理解如果你只是背答案一追问就露馅。我建议你找一个朋友或者对着录音机练习讲题规则很简单随机抽一道客观题限时三分钟用自己的话解释清楚不许背原文。比如抽到“为什么NSTimer在滑动时不准”你要在开头10秒内给出核心结论RunLoop的mode切换导致timer没有回调。然后再花几十秒解释DefaultMode和TrackingMode的区别最后提一句解决方案。这样的表达结构面试官会听得很舒服。一个实战技巧是“先结论再展开”。很多人面试喜欢按时间线讲从原理讲到现象结果面试官听了30秒还没听到重点会失去耐心。正确的做法是像写技术方案一样第一句就给结论然后分点解释原因。举个例子面试官问“为什么用GCD创建定时器”你直接说“因为GCD定时器不依赖RunLoop避免被mode切换影响”然后再展开效果会好很多。6.3 客观题如何转化为项目亮点简历加分思路刷完客观题最终目标还是面试和项目。很多人会问“我刷了这些题简历上怎么写”我的建议是不要写“熟悉ARC和RunLoop”太像背八股。你要把这些知识点包装成项目成果让面试官觉得你是主动用技术解决过问题的人。比如你在项目里做过运单列表优化就可以写“基于Cell复用和行高缓存将列表滑动帧率从45FPS提升到60FPS”。面试官听到后自然会追问“你怎么定位性能瓶颈的”“你用了哪些Instrument工具”这个候客观题里的预排版、离屏渲染、异步绘制都能顺理成章地说出来。再比如快递员App需要后台上传轨迹简历上可以写“设计了一套低功耗定位上报策略在后台定位模式下通过降低精度和批量压缩上报日均耗电量下降20%”。这道题对应的知识点就是CoreLocation精度控制、后台任务限制、网络请求优化。这样的表达既具体又可信比单纯罗列技术名词强很多。所以我的建议是客观题刷完不要急着投简历先把自己做过的项目按“场景-难点-方案-结果”结构梳理一遍把刷到的考点填进项目故事里。你的面试表现会好很多因为你讲的每个结论都有实践支撑面试官也会觉得你是一个会思考的开发者。最后再分享一个小技巧遇到错题不要只改答案一定要把它讲给身边人听讲不出来就回去翻文档直到能顺畅解释为止。这套顺丰科技2019年的客观题合集虽然年份有点旧但考点都是经典我今天重新翻看时依然能发现一些容易模糊的细节比如KVO在多层继承下的触发顺序、自动释放池在事件循环里的释放节点。面试不是知识的终点而是查漏补缺的起点把每一道错题消化掉比刷十套新题都更值。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻