小米iOS开发面试4轮全记录:Swift+底层原理深度考察
3年iOS开发社招小米4轮面试全记录,含Swift内存管理、Runtime机制、Runloop原理、UI性能优化等真题详解,小米iOS面试经验2026最新分享。
背景介绍
先说下我的情况吧,3年iOS开发经验,之前在一家教育科技公司做iOS端,主要负责课程直播和作业批改两个核心模块。说实话在那边待了三年,技术上到了一个瓶颈期,业务也比较稳定没什么新挑战了,就开始看外面的机会。小米一直是我想去的公司,毕竟MIUI生态和iOS有很多可以借鉴的地方,而且小米在移动端的积累确实深厚。我是直接在小米官网投的简历,大概等了两周左右收到了HR的电话,约了第一轮面试。
整个面试流程一共4轮:一面技术基础、二面进阶原理+性能优化、三面架构设计+算法、HR面。从一面到拿到offer大概用了三周时间,整体节奏还算紧凑。下面我按轮次详细复盘一下。
一面:Swift基础与内存管理
面试官风格
一面的面试官是个看起来很年轻的小哥,后来知道是小米iOS团队的技术骨干。风格偏务实,不太寒暄,上来就开问,但追问的时候会给你一些提示,不会让你完全卡住。
Swift值类型 vs 引用类型
第一个问题就是Swift中值类型和引用类型的区别。这个我准备过,回答得比较流畅:值类型存储在栈上,赋值时是深拷贝;引用类型存储在堆上,赋值时是浅拷贝,多个变量指向同一块内存。面试官追问了一个我没想到的点:struct和class在方法调度上的区别。struct的方法调度是静态的,编译期确定;class的方法调度是动态的,通过vtable在运行时确定。这个点之前没深入想过,还好面试官给了提示,我顺着说了出来。
ARC原理与循环引用
接着问了ARC的工作原理。我讲了引用计数的基本机制,编译器在编译期自动插入retain/release/autorelease调用,当引用计数降为0时自动释放。面试官又问什么情况下会出现循环引用,我举了闭包捕获self的经典例子,以及delegate用strong修饰的问题。面试官追问:除了闭包和delegate,还有哪些场景?我想了想说Timer的target-action也会造成循环引用,因为Timer会强引用target,这个他点了点头。
weak和unowned的区别
这个是必考题了。weak是可选型的,对象释放后自动置为nil;unowned是非可选型的,对象释放后访问会崩溃。我补充了使用场景:weak用于对象生命周期可能不一致的情况(如delegate),unowned用于对象生命周期确定一致的情况(如闭包和self同生同死)。面试官追问了一个细节:unowned和unowned(safe)的区别,这个我确实不太确定,老实说了不太了解,面试官简单解释了一下,Debug模式下unowned(safe)会做检查,Release下和unowned(unsafe)行为一致。
Optional的本质
最后一个基础题:Optional的底层实现。我回答Optional是一个枚举,有两个case:some(Wrapped)和none。面试官追问为什么Swift要设计Optional,我讲了类型安全的角度,null引用是"十亿美元的错误",Optional强制开发者处理nil情况,从语言层面避免了空指针问题。
一面感受
一面大概50分钟,整体感觉还不错,基础题基本都答上了,unowned(safe)那个点没答上来但面试官态度很好。当天晚上就收到了二面通知。
二面:Runtime、Runloop与性能优化
面试官风格
二面的面试官明显资历更深一些,应该是团队负责人级别。问问题喜欢从场景出发,先给一个实际需求,然后一步步追问底层原理,压力比一面大不少。
Runtime消息转发机制
上来就问Runtime的消息转发机制。这个我背过,但面试官要求我结合实际场景讲。我说了完整的三步转发流程:动态方法解析(resolveInstanceMethod)→ 快速转发(forwardingTargetForSelector)→ 完整转发(forwardInvocation)。面试官追问:你在项目中用过消息转发吗?我讲了之前用forwardingTargetForSelector实现多继承效果的案例,以及用resolveInstanceMethod动态添加方法的场景。他似乎比较满意。
Runloop机制及应用
接着是Runloop的运行机制。我讲了Runloop的本质是一个事件循环,不断接收处理事件(Timer、Source、Observer)。面试官追问了几个深入的问题:
1. Runloop的Mode是什么?我回答Mode是Runloop的运行模式,不同Mode下只处理对应Mode的Source和Timer,比如滑动ScrollView时会切换到UITrackingRunLoopMode,此时NSDefaultRunLoopMode下的Timer不会触发。
2. Runloop在实际开发中的应用?我讲了三个场景:后台常驻线程(添加Port让Runloop不退出)、性能优化(在kCFRunLoopBeforeSources和kCFRunLoopAfterWaiting之间监控卡顿)、延迟加载(performSelector:withObject:afterDelay依赖Runloop的Timer)。
UI卡顿优化
面试官给了一个场景:一个页面滑动时明显卡顿,你怎么排查和优化?我按步骤回答:先用Instruments的Time Profiler定位耗时方法,再用CADisplayLink监控帧率,然后从几个方向优化——主线程耗时操作移到子线程、减少视图层级、避免频繁布局计算、图片异步解码预渲染。面试官追问:图片解码为什么要异步?我讲了UIImage在设置到UIImageView时才会触发硬解码,这个过程在主线程会阻塞UI,所以需要提前在子线程解码好。
UITableView性能优化
最后问了UITableView的优化方案。我列了几个:cell复用、高度缓存、异步绘制、减少subview层级、预排版预计算、按需加载。面试官追问了高度缓存怎么实现,我讲了用字典缓存cellHeight,在heightForRowAtIndexPath中先查缓存,没有再计算并缓存。
二面感受
二面大概1小时,被追问得有点紧张,尤其是Runloop的应用场景那块,有些细节没答好。但面试官一直在引导,没有让我完全卡住。三天后收到了三面通知。
三面:架构设计与算法
面试官风格
三面的面试官应该是技术总监,问的问题更宏观,关注架构思维和系统性思考,不像前两面那么抠细节。
项目架构设计
先让我介绍当前项目的架构。我讲了项目用的MVC架构,但存在Massive ViewController的问题,后来逐步引入MVVM。面试官追问:MVVM和MVC的核心区别是什么?我回答MVVM将业务逻辑从Controller抽到ViewModel,Controller只负责视图绑定和生命周期管理,ViewModel可测试性更强。面试官又问:你项目中MVVM的绑定方式是什么?我讲了用Combine框架做响应式绑定,以及之前用KVO的方式。
组件化方案
面试官问你对iOS组件化的理解。我讲了组件化的核心是解耦,通过中间层(Router或Protocol)实现模块间通信。我提到了三种方案:URL Router(蘑菇街方案)、Target-Action(CTMediator)、Protocol-Class注册(BeeHive),并分析了各自的优缺点。面试官追问:你们项目用的哪种?为什么?我讲了用的CTMediator方案,因为不需要注册表,运行时解耦更彻底,虽然硬编码字符串有风险但可以通过工具生成。
CI/CD流程
面试官问你们项目的CI/CD是怎么做的。我讲了用Jenkins + Fastlane搭建的自动化打包流程,包括代码检查(SwiftLint)、单元测试、打包分发(fir.im)、自动上传TestFlight。面试官追问:Fastlane的match命令是做什么的,我回答是统一管理证书和描述文件,避免多人协作时证书管理混乱。
算法题
算法部分两道题:
1. 二叉树的最大深度:递归解法,max(depth(left), depth(right)) + 1,几分钟就写完了。面试官让改成迭代解法,我用BFS层序遍历实现。
2. 链表排序:要求O(nlogn)时间复杂度和O(1)空间复杂度。我用了归并排序,先找中点(快慢指针),再递归排序,最后合并有序链表。写的时候有个小bug,合并时忘记处理剩余节点,面试官指出来了,我快速修正。
三面感受
三面大概1小时10分钟,架构部分聊得比较深入,算法题难度适中。整体感觉面试官更看重思路和思考过程,不是死抠答案。一周后收到了HR面通知。
HR面:动机与规划
HR面比较轻松,主要问了几个问题:
1. 为什么来小米?我讲了小米在移动端的积累深厚,MIUI和iOS有很多技术交叉点,而且小米的工程师文化我很认同,务实不浮夸。
2. 职业规划?我说短期希望在iOS底层技术上深耕,长期希望能带团队,从技术和管理两个维度成长。
3. 薪资期望?我给了一个合理的范围,没有狮子大开口,也表明了可以协商的态度。
4. 有没有其他offer?如实回答了有另一个在流程中的,但小米是首选。
面试真题汇总
Swift基础
1. 值类型与引用类型的区别?struct和class方法调度的区别?
2. ARC的工作原理?循环引用的场景有哪些?
3. weak和unowned的区别?unowned(safe)和unowned(unsafe)的区别?
4. Optional的本质是什么?Swift为什么要设计Optional?
底层原理
5. Runtime消息转发机制的完整流程?
6. Runloop的运行机制?Mode是什么?实际应用场景?
7. UI卡顿的排查和优化方案?
8. UITableView性能优化方案?高度缓存怎么实现?
架构与工程化
9. MVVM和MVC的核心区别?绑定方式有哪些?
10. iOS组件化方案有哪些?各自的优缺点?
11. CI/CD流程怎么搭建?Fastlane match的作用?
算法
12. 二叉树的最大深度(递归+迭代)
13. 链表排序(归并排序,O(nlogn)时间O(1)空间)
心得体会与建议
1. 基础要扎实,但更要理解原理。小米的面试不会只问你"是什么",而是会追问"为什么"和"怎么用"。比如Optional,大家都知道是枚举,但为什么要这样设计?这背后是语言设计的哲学思考。
2. 性能优化是加分项。二面的卡顿排查和UITableView优化,如果你能从监控→定位→优化的完整链路来讲,面试官会觉得你有实战经验,而不只是背八股文。
3. 架构设计要结合项目讲。不要只说理论,一定要结合自己项目中的实际案例,讲清楚为什么选择这个方案、遇到了什么问题、怎么解决的。
4. 算法不能丢。虽然iOS面试算法占比不高,但三面还是会考,而且要求不低。链表排序那道题空间复杂度要求O(1),直接排除了递归归并的写法,必须用迭代。
5. 面试心态很重要。二面被追问的时候确实有点紧张,但我发现面试官追问不是为了难为你,而是想看你的思考过程。答不上来的不要硬编,说"我不太确定,但我的理解是..."比瞎编要好得多。
常见问题FAQ
Q1:小米iOS面试看重项目经验还是基础原理?
两者都看重,但侧重点不同。一面偏基础原理,二面偏实战和性能优化,三面偏架构思维。项目经验是载体,基础原理是内核,缺一不可。
Q2:没有大厂经验,小米面试会被歧视吗?
不会。我之前也是中小公司,面试官关注的是你解决问题的能力和技术深度,而不是公司背景。把项目中的亮点讲清楚比公司名头更有说服力。
Q3:算法要准备到什么程度?
LeetCode中等难度为主,重点掌握链表、树、动态规划这几类。小米的算法题不会特别偏,但会要求你分析时间和空间复杂度,并且可能让你优化。
Q4:面试周期大概多久?
我整个流程大概三周,一面到二面3天,二面到三面3天,三面到HR面1周,HR面到offer 3天。不同部门可能不一样,供参考。
Q5:薪资大概什么水平?
3年经验iOS开发,小米给的薪资在行业内属于中上水平,具体就不透露了。建议面试前先了解市场行情,给自己定一个合理的期望范围。