ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

京东iOS面试题拆解:大厂核心考点与备战路线

京东iOS面试题拆解:大厂核心考点与备战路线 今年翻资料的时候又看到这份京东2019春招的iOS开发类试卷前前后后刷过几遍每次重看都有点新体会。这份卷子放在当时的大厂面试题里属于“看着不难、拿分不易”的类型题面不会故意刁难人但每道题往下深挖都能挖出好几层非常能反映面试官想招什么样的人。很多同学在准备大厂iOS面试时容易陷入题海背了一堆概念却答不到点上其实像京东这类电商公司出题每一道背后都站着真实的业务场景高并发访问、复杂的商品页、频繁的网络请求、秒杀和促销带来的流量洪峰。这篇文章我就借着这份试卷把大厂iOS面试真正在考的东西拆开讲一遍从知识版图、核心考点再到备战路线一次性说清楚。1. 先把试卷摊开看命题人到底想考察什么1.1 一套“偏实践、重基础、藏场景”的题我先按自己的理解把这份试卷的考点分布整理成一张表。虽然不是标准答案但基本能还原2019年前后京东iOS岗笔试和面试的真实考察范围。考察模块典型题目方向占比感受考察目标语言基础Objective-C特性、Runtime、内存管理较高验证底层功底是否扎实并发与多线程GCD、NSOperation、锁、线程安全较高判断是否处理过复杂并发场景UI与渲染列表优化、离屏渲染、自动布局中等考察实际开发中的性能意识网络与存储HTTP/HTTPS、缓存策略、数据持久化中等偏上电商场景的技术命脉架构设计MVC/MVVM、组件化、模块化中等筛选有工程化思维的候选人开放题与项目项目难点、系统设计、场景题必有综合评估真实解决问题的水平这份分布其实很“大厂”——不考那种死记硬背的语法细节而是把考点埋在实际开发最常见的场景里。比如内存管理不会只问“ARC和MRC的区别”而是会给你一段循环引用的代码让你现场分析问题网络题不会只问“GET和POST的区别”而是会把连接复用、DNS、弱网优化串在一起来问。1.2 电商场景如何渗透进每一道题京东App的核心业务就是“逛、选、买、查”首页信息流、商品列表、商品详情、购物车、下单支付、物流查询。每个环节对iOS工程师的能力要求都不一样这就决定了出题方向绝不能停留在写个页面、调个接口的水平。举几个例子你就明白了。商品列表页是典型的无限滚动场景列表流畅度直接决定用户体感所以TableView和UICollectionView的优化一定是高频考点购物车涉及大量本地数据读写本地持久化的选型就很容易被追问订单状态实时更新推送机制和App前后台状态切换会被拿来出场景题。也就是说面试官出的每一道题几乎都能在京东的业务模块里找到对应物。这给所有准备面试的人提了个醒不要孤立地背知识点要把知识点钉在业务场景里。你准备一个知识点时多问自己一句“这个在电商App里会出现在哪儿”答题的视角就会完全不一样。1.3 不会直接问、但一定会被隐性考察的能力除了明面上的技术题这份试卷和它背后的面试流程里还藏着几项不写进题面却非常关键的考察点。第一是工程习惯。比如题目涉及表视图优化时面试官会顺口问一句“你们项目里的Cell是怎么组织的”这其实是在看你的代码分层和复用意识。第二是排查问题的思路。面试官经常会用追问的方式模拟线上问题比如“列表滚动卡顿你会先看什么”答得有条理的人说明平时就有清晰的排查方法论。第三是学习能力和表达边界。遇到知识盲区时是诚实说不会、还是硬编一套面试官几轮追问下来看得明明白白。这三点在技术扎实的候选人之间往往才是拉开差距的地方。2. 语言与运行时Objective-C底层逻辑是分水岭2.1 消息机制从objc_msgSend到消息转发这份试卷里Runtime相关的内容几乎必考而消息机制又是Runtime的入口。很多人在简历里写“熟悉Runtime”但一被问到“方法调用过程中到底发生了什么”就卡壳。它最基础的答案是[obj doSomething]最终会编译成objc_msgSend(obj, selector(doSomething))然后在运行时走一遍完整的查找流程。一套高分答案应该按顺序说清楚这几个环节先从对象的isa指针找到所属类再在类的cache_t中查找方法缓存缓存没有命中就去class_rw_t的方法列表中找找到后拿到方法对应的函数指针跳转执行如果方法列表里也没有就会触发消息转发机制——先是动态方法解析resolveInstanceMethod再是快速转发forwardingTargetForSelector最后是慢速转发methodSignatureForSelector和forwardInvocation。光背流程还不够面试官会继续追问“这套机制在开发里有什么用”。这里面可以延伸的点很多比如利用动态方法解析实现懒加载、利用转发实现多重代理、利用method swizzling做AOP埋点。我当时回答时额外补充了一个点iOS开发中崩溃治理的很多方案本质就是在消息转发阶段做文章把找不到的方法拦截下来避免直接抛异常。这种答法能把底层机制和实际经验串在一起分量立刻不一样。2.2 循环引用一个考了十几年仍然高频的考点循环引用在2019年的试卷里出现了哪怕放到今天也依然是iOS面试的保留题目。高频是因为它太容易踩了尤其是Block和NSTimer。先说Block的循环引用。一个经典的坑是self持有blockblock里又调用了self的实例变量或者方法形成self - block - self的环。解决思路是__weak但有一种情况很多人会忽略——如果在block内部再用__strong修饰一下把weakSelf变成strongSelf那就要注意strongSelf的生命周期不能超出block本身否则又会在局部形成新的引用环。再说NSTimer这是公认的重灾区。 scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:这个方法target会强持有timertimer又会被runloop持有如果timer的target是self就形成了self - timer - runloop - timer - self的结构普通的__weak根本解决不了。正确做法是想清楚持有关系在合适的时机主动invalidate。iOS 10之后系统提供了block版本的timer方法配合__weak可以绕开这个结构但底层的持有关系不变答题时最好把这个逻辑链说透。我建议准备这类题目时不要只背结论要能把“谁持有谁”的引用计数变化画出来说清楚每一条引用链是怎么形成的、在哪个环节断开的面试官一听就知道你不是背的。2.3 从Block到GCD并发题目不是背概念Block和GCD常常连着考因为两者关系太紧密了。关于Block除循环引用外一个高频追问是Block有几种类型以及变量捕获的规则。这里要分清三种Block_NSConcreteStackBlock、_NSConcreteGlobalBlock、_NSConcreteMallocBlock在ARC下栈上Block会自动拷贝到堆上。捕获机制也容易踩坑局部变量是值捕获__block变量是引用捕获静态变量和全局变量走的是指针捕获。GCD的考察则更偏向实战。死锁问题几乎每次面试都会有人遇到我给一个最经典的例子dispatch_queue_t queue dispatch_get_main_queue(); dispatch_sync(queue, ^{ NSLog(不会执行到这行); });这段代码在主队列里同步派发任务到主队列任务永远等不到执行程序直接卡死。这题的底层原因涉及串行队列和同步派发机制回答时要能讲清楚“主队列是串行队列”“dispatch_sync会阻塞当前线程直到任务完成”“而当前线程正是主线程此时任务根本排不进去”这三点。更深入的追问会涉及线程保活、信号量dispatch_semaphore、栅栏dispatch_barrier和dispatch_group的使用场景。这类题目想答得比别人好靠的是平时真的用它们解决过问题比如用信号量控制并发请求数量用dispatch_group等待多个接口完成后再刷新UI。有真实场景支撑说出来的东西才有细节。3. UI与渲染电商App对流畅度的要求刻进DNA3.1 列表优化从Cell复用到预排版京东App信息流场景非常多列表优化这事在试卷里的出现频率极高。这题想答出层次不能只说“用reuseIdentifier复用Cell”那是最入门的一层。合理的作答要分几个层次展开。第一层是Cell自身的复用和注册方式包括纯代码注册和XIB注册的差异、dequeueReusableCellWithIdentifier:forIndexPath:与旧接口的区别。第二层是高度计算尤其是“只有内容没有固定高度”的复杂Cell要避免在heightForRowAtIndexPath里动态计算并频繁创建临时视图正确做法是提前计算并缓存高度或者使用UITableViewAutomaticDimension配合约束让系统缓存高度不过要注意约束的完整性和性能表现。第三层是异步绘制和预排版把文本的排版和绘制拿到子线程去做把结果缓存成一个ASDisplayNode风格的节点对象这种方式虽然实现成本高但优化效果非常明显。还有一个高分局是提prefetching。iOS 10之后UITableView和UICollectionView都有预取API可以提前加载下一页的数据并预热Cell。我面试答题时会顺带讲一个真实踩过的坑预取和滑动速度不匹配时容易造成网络请求的重复和浪费所以需要配合取消机制做控制。这种有细节的回答比单纯罗列API接口要有用得多。3.2 离屏渲染、图层混合与肉眼可见的卡顿离屏渲染是UI性能题里最能拉开区分度的考点。它问起来很简单——“什么情况下会触发离屏渲染怎么优化”但能真正讲透的人不多。最常见的触发场景是给视图设置圆角并配合masksToBounds YES系统为了得到这个圆角效果会先在离屏缓冲区里把图层画好然后再合成到屏幕上。这个过程的代价很高尤其是在TableView滚动时每一帧每个Cell都触发离屏渲染卡顿几乎必然出现。优化思路有三类第一类是尽量避免同时使用圆角加裁剪尤其不要在有大量图片的Cell上这么做第二类是使用UIBezierPath绘制圆角遮罩或者直接让设计出带圆角的图片第三类是把需要圆角的图层内容先绘制成一张位图然后只需要一次合成。注意shadow阴影同样属于离屏渲染的范畴但不是所有加阴影的情况都一定要优化关键是看它出现在什么位置、被复用的频率有多高。图层混合也是一个容易被忽略的点。UILabel如果背景色是透明的它和父视图之间就会发生混合计算不透明视图的opaque属性设为YES可以减少混合的开销。真实项目中给Cell的背景、文本标签都明确设置不透明的背景色滚动帧率往往会有立竿见影的改善。这题想答得漂亮最好能带上定位卡顿的工具和方法。iOS开发者日常常用的Instruments里的Core Animation调试工具、Time Profiler以及Xcode自带的“Color Blended Layers”和“Color Offscreen-Rendered”调试选项这些都是实战派最熟悉的排查手段。答题时把这些工具说清楚面试官基本能判断出你真刀真枪调过性能优化。3.3 启动时间与包体积第一印象工程App启动速度和包体积虽然不完全属于UI渲染范畴但在电商大厂的面试里非常容易被穿插着问这次试卷的开放题里也涉及了。启动时间分冷启动和热启动冷启动是重点它从main()之前就开始了。系统先加载动态库、执行各种初始化再到main()之后UIApplicationMain、AppDelegate回调、根控制器加载每一步都有文章可做。优化方向可以从两个维度展开。Objective-C相关的优化包括减少动态库加载数量、合并或者删减无用的类和方法、把不需要在启动阶段执行的代码延后比如放到dispatch_async或者load改到initialize、启动阶段的网络请求尽量并发。平时常用的工具是Xcode的DYLD_PRINT_STATISTICS环境变量可以看到动态链接阶段每个步骤的耗时。包体积优化的面试答法和启动优化类似核心思路就是“减、搬、压缩”删无用代码和无用资源、用资源目录按需加载、图片压缩、App Thinning和按需资源On-Demand Resources配合使用。我在项目里试过把包里的图片全部走Asset Catalog管理同时开启App Thinning整体包体积能下降不少这种真实数据拿出来说非常有说服力。4. 网络与数据连接用户与商品的命脉4.1 一道网络题从HTTP到TCP的三层答法电商App里网络模块就是生命线所以这份试卷里的网络题分量很重。一个最常见的题目是“说说HTTP和HTTPS的区别”但面试官要的肯定不只是“HTTPS更安全”这五个字。我会建议用分层递进的答法来回应这样覆盖面更全。第一层说协议差异HTTP是明文传输HTTPS在HTTP和TCP之间加了一层TLS/SSL加密协议。第二层说握手过程HTTPS的连接建立过程比HTTP多了TLS握手要经历客户端发送支持的加密套件列表、服务端返回证书、客户端验证证书、协商会话密钥、之后用对称加密传输数据。这一层是重点要能把RSA、DH或ECDHE这类密钥交换方式讲清楚。第三层说性能影响和优化TLS握手带来的往返时间增加可以通过会话复用Session Resumption、TLS 1.3的0-RTT等手段优化。追问还可能深入到TCP比如“为什么说TCP是可靠的”“三次握手和四次挥手的原因是什么”“TCP粘包和拆包是怎么回事”。这些问题在iOS面试里出现时通常不是为了考古而是为了看你对网络协议的理解是否能够支撑实际开发中遇到的疑难问题。比如断点续传、弱网下的请求重试、连接复用背后都是这些基础协议在起作用。回答网络题有个技巧一定要把自己做过的优化动作放进去。比如做过CDN配置、搞过DNS解析的优化、处理过Wi-Fi和蜂窝网络切换导致的连接断开。这些细节是让答案从“教科书”变成“实战经验”的关键。4.2 网络层设计超时、重试、缓存与安全大厂面试关于网络最出彩的回答通常是“我设计过一个网络层”。这题不用等面试官问你可以在项目介绍里主动抛出来。一个完善的iOS网络层要考虑的事情很具体。超时策略要区分连接超时和读超时不同接口和不同网络状态下超时时间应当不同。重试策略要设计退避机制Backoff避免在弱网条件下同时发起大量重试导致雪崩。缓存策略要根据接口特点区分某些数据可以使用HTTP缓存和本地缓存两级策略缓存要设置合理的过期时间服务端要能通过响应头控制。安全方面统一在底层做参数签名、时间戳校验、防重放攻击HTTPS的证书校验也要在客户端做实不能用简单的SSL Pinning开关替代需要设计好证书更新流程。日志与监控方面要自动记录每次请求的状态码、耗时、失败原因方便线上问题的回溯。聊到这里面试官通常还会提一嘴抓包调试。日常调试网络问题就离不开Charles这一类工具配置好SSL代理后就能看到HTTPS的明文请求和响应。但要注意如果线上App做了证书校验Charles抓包就需要先绕过或者注入证书这正好能反向验证你的网络安全设计是否到位。所以这道题你懂多少、做到什么程度一聊就露底。4.3 本地持久化与数据一致性数据怎么存是电商类App绕不开的话题。购物车需要本地暂存、用户偏好需要本地记忆、历史搜索需要本地保留这都涉及本地存储。iOS里常用的几个方案面试时要能按场景说清楚选型依据。NSUserDefaults适合存轻量级配置但它本质是plist文件不适合频繁写入或者存大量数据。NSCache适合做内存级缓存线程安全而且在内存紧张时会自动清理对象适合做图片或数据模型的内存缓存。Keychain适合保存敏感信息比如登录凭证它会在应用卸载后依然保留而且有系统级的加密保护。Core Data是个重量级选手适合复杂对象关系的数据模型但学习曲线陡坑也多。此外很多团队会用FMDB、Realm或者WCDB这类第三方数据库性能好、API易用。本地存储往往还要考虑和服务端的数据一致性。比如购物车本地修改后App进入后台或者网络恢复时要和服务端同步冲突怎么处理常见的策略是“本地优先服务端校验”客户端先把修改写入本地同时把操作记录下来联网后同步到服务端服务端返回冲突时再按时间戳或者业务规则合并。面试里说清楚这种一致性方案会让面试官觉得你不仅会调用API还理解业务和数据之间的关系。5. 架构与工程化从能写到会设计的进化路径5.1 MVC、MVVM还是VIPER怎么答不落俗套架构题几乎是所有大厂iOS面试的必考点这份试卷里也有涉及。很多人一上来就背MVC的缺点、MVVM的优点听起来太像模板。面试官真正想看的是你有没有在真实项目中做过架构选型和重构决策。MVC在iOS开发里是系统默认的架构Controller作为枢纽承担了太多职责最后变成“ Massive View Controller”这是它最大的问题但它依然是中小型项目最有效率的选择。MVVM通过引入ViewModel把视图状态管理和业务逻辑从Controller里抽出来配合ReactiveCocoa或者RxSwift数据绑定确实能减少很多样板代码但过度抽象也会提高调试成本毕竟响应式编程的链路追踪比传统写法要困难得多。VIPER把职责拆得更彻底适合大型团队中长期维护的模块但文件数量多、流程重用在简单页面里就是灾难。我的一个核心观点是架构没有银弹只有适合不适合。答题时最好能结合自己的项目经历讲一讲“我用MVVM重构成了一个商品列表模块解决了什么问题同时引入了什么新问题”这种真实重构成长的故事比任何理论都打动人。5.2 组件化实践大厂绕不开的话题2018年到2019年组件化在国内大厂iOS开发中是一个非常热门的方向。京东App这种超大规模App业务模块几十上百个如果所有代码都堆在一个工程里编译会越来越慢团队协作的冲突也越来越严重。组件化要解决的就是这个问题。组件化不是单纯把代码拆成几个文件夹它要解决的问题包括每个组件独立编译、组件之间通过路由通信、基础组件层和业务组件层分离、页面跳转统一由路由管理。实现方案上有基于Runtime的CTMediator方案有基于Protocol-Class注册的方案也有类似BeeHive这样完整的模块化框架。每个方案都有自己的权衡比如CTMediator通过performSelector动态调用灵活性高但牺牲了编译期检查Protocol方案编译期更安全但需要维护注册表。答这类题时不要只停留在方案比较。把组件化落地过程中的坑讲出来会更有价值比如组件之间的依赖怎么管理CocoaPods私有仓库的维护成本循环依赖的排查路由表被写乱后如何治理。我踩过的坑是组件化之后公共基础库升级时容易漏掉对旧组件的兼容测试所以后来我们给基础库加了严格的语义化版本管理和兼容性测试机制。5.3 跨端方案与iOS工程师的位置2019年前后跨端开发是一个绕不开的话题。当时大厂几乎都在投入跨端方向React Native势头正盛Weex也在阿里系内部大量使用小程序生态已经开始主导流量入口Flutter也进入了大众视野。这份试卷虽然没有直接问“你怎么看跨端”但面试官很大概率会在聊项目时顺带考察你对行业趋势的理解。对iOS工程师来说跨端技术是挑战也是机会。只会写OC和Swift的iOS工程师会感到压力因为业务团队可能会跳过原生直接用跨端写。但对底层能力扎实的工程师来说跨端框架的底层很多地方依然是iOS的Runtime、内存管理、渲染链路在支撑能看懂RN的Bridge机制、能优化Flutter和原生通信的性能这些反而成了稀缺能力。我推荐iOS开发者至少深入学习一种跨端方案不只是会用还要理解它的原理。比如React Native的JSBridge通信机制、Flutter的Skia渲染引擎如何和原生视图交互、小程序容器在iOS上的实现方式。这些知识会让你在未来几年技术浪潮里更有底气。同时苹果每次系统更新都会带来新能力比如iOS大量自动化、快捷指令、App Clips、Widget这些原生生态独有的优势恰恰是跨端难以替代的领域。6. 从试卷回到备战三个月冲刺路线与软实力6.1 按优先级排布复习计划如果你看到这篇文章时离面试还有两三个月别慌按优先级来。我根据这份试卷反映出的考点密度帮你排一份复习优先级表。优先级复习内容建议投入时间理由高优先级iOS底层原理Runtime、RunLoop、内存管理、多线程两周面试必考且能看出基本功高优先级网络基础与网络层设计一周半电商场景核心技术中高优先级性能优化列表、启动、包体积一周半大厂高频场景题中优先级架构设计与组件化一周区分“能写”和“会设计”中优先级项目梳理与系统设计题演练贯穿全程决定最终综合评分低优先级各类新兴API和第三方库穿插进行能体现学习能力但不是主菜这套计划背后有一个原则面试考的是“长期积累”不是“短期突击”所以排列顺序要把短期内无法速成的东西放在前面。底层原理是靠理解和大量使用堆积起来的真要补就得趁早网络和性能优化可以通过刻意练习在短期内补上来架构和设计能力则更需要项目实战的支撑。6.2 项目深挖与系统设计题的应答框架面试官一定会翻项目。项目讲得好不好直接决定面试的天花板。我见过技术不错但项目讲得平淡的人也见过技术中等但项目讲得极其出彩的人后者经常能拿到更好的评级。讲项目我建议按这个框架组织背景为什么做、方案怎么设计、落地怎么分工、排期、量化数据变化、复盘踩了什么坑、怎么解决、如果再做一次会怎么改。注意每个项目一定要有可量化的结果比如列表滚动掉帧率从多少降到多少、启动时间从多少秒优化到多少秒、崩溃率从多少降到多少。没有数字支撑的项目描述面试官很难判断你做的事到底产生了多大价值。系统设计题也有类似的答题框架京东这类电商公司很可能会出“如果让你设计一个购物车模块/商品详情页组件框架你会怎么设计”这类题。回答时应先收集需求、明确边界再拆分模块、设计数据流然后选型定方案最后讲风险和权衡。这套框架的价值在于它向面试官展示了你面对一个未知问题时有结构化的思考路径而不是东一榔头西一棒子。6.3 容易被低估的软技能最后想提醒一点技术之外有几个软技能非常影响面试结果。第一个是表达节奏回答问题不要一口气把所有细节倒出来而是先说结论、再展开解释、最后举例子。第二个是正视“不知道”没人什么都会遇到不会的题能坦诚说出“这块我没有深入用过但我的理解大概是……”比支支吾吾或者硬编一个答案要强得多。第三个是追问澄清很多面试题是有歧义的主动和面试官确认需求反而会让对方觉得你有真实的沟通习惯。还有一个经常被忽略的细节不要只展示技术宽度更要展示技术深度。面试官问到一个你熟悉的方向一定要抓住机会往下深挖讲出你的思考和独到经验。大厂面试的本质不是知识竞赛而是让人相信你有独立解决复杂问题的能力而这个能力靠的是深度而非广度。这份试卷也好每年的各类iOS面试题也好说到底都是同一个逻辑把日常开发中最常遇到的问题摆到你面前看你如何拆解、如何优化、如何取舍。我刷这套题最大的体会是能在面试中游刃有余的人往往不是刷题最多的而是平时写代码时就习惯多想一层的人。如果你现在还在备战阶段别只盯着题库多去研究自己项目里的难点多去思考每个技术选型背后的理由这才是最“省力”的备考方式。
返回列表