mobile · git:20260908.a2a662c · 2026-09-08 · sha256 4af09a267a89dfbe

mobile git:20260908.a2a662cA

Immutable. This exact content is served forever at /api/v1/blob/4af09a267a89dfbe.

---
name: mobile
description: 移动端领域出题(平台无关):应用生命周期与状态、UI 渲染与性能、网络与缓存、离线与同步、包体与启动、发布与灰度、跨端选型。目标岗位是移动端/客户端/App 开发时加载;Android/iOS/Flutter 细节交给对应 stack 包。
keywords: [移动端, 客户端, app开发, mobile, 客户端开发, android, ios, flutter, react native, 跨端, 启动优化, 包体积, 灰度发布, 移动开发]
layer: domain
---

## 岗位职责与考察重点

移动端工程师(也叫客户端开发、App 开发、Mobile Engineer,国内大厂常按 Android/iOS 分岗但基础架构团队要求双端)的日常是把产品需求变成能在成千上万种设备上稳定运行的应用:写页面与交互、对接网络与本地存储、管理应用生命周期与后台行为、盯启动速度和包体积、处理崩溃与 ANR/卡顿、走审核与灰度发布、在合适的场景引入跨端方案。真实面试里平台无关的部分越来越重:面试官会问"用户切后台再回来页面状态丢了怎么办""弱网下列表怎么保证可用""发版后崩溃率涨了怎么止血",这些问题在 Android 与 iOS 上答案不同但思路一致。面试官最在意三件事:一是有没有线上问题的排查闭环(崩溃、卡顿、耗电、包体、启动各有一套归因方法与工具),二是对设备与网络不确定性的敬畏(低端机、弱网、系统杀进程、权限变更),三是发布与质量意识(灰度、热修、回滚、AB 实验、审核规则)。

校招侧重语言基础与平台基本概念:生命周期、线程模型、内存管理、常见 UI 组件与布局、网络请求与 JSON 解析;社招侧重架构与线上经验:模块化与组件化、启动与包体治理的数字、崩溃率与 ANR 率的治理过程、动态化与跨端框架的选型判断、以及在大团队里怎么推动质量指标。一线大厂客户端面试普遍会有"手撕算法 + 平台原理 + 线上问题排查 + 架构设计"四段,这个包负责后三段里平台无关的部分。

## 主题

### 应用生命周期与状态恢复
- 阶梯:应用从冷启动到前台、切后台、被系统杀死各经历什么状态 → 前后台切换时页面与数据的保存与恢复机制、进程被杀后重建与冷启动的差异、后台任务的系统限制 → 用户从相机返回 App 后填了一半的表单丢了,或者后台回到前台页面空白、数据错乱怎么定位与修 → 状态保存的粒度(内存、磁盘、服务端)与实现成本,什么状态值得持久化、什么可以重建
- 好题:用户在发布页写了 500 字并选了 9 张图,切到微信回复消息再回来后内容全没了,这在 Android 与 iOS 上分别可能是什么原因?你会怎么设计恢复方案、恢复到什么程度算够?
- 危险信号:只能背某一个平台的生命周期回调而说不出系统为什么杀进程;认为切后台不会丢状态;不知道低内存杀进程与用户手动杀的差别
- 期望信号:区分内存态、进程重建态与冷启动;有草稿自动保存的实践;知道后台执行时间限制与保活手段的边界;能说出恢复方案的测试方法(开发者选项"不保留活动"或模拟内存警告)

### UI 渲染与卡顿排查
- 阶梯:为什么要求 16ms(或 8ms)一帧、掉帧用户怎么感知 → 主线程负责什么、布局/测量/绘制的流程、渲染管线与 GPU 的分工、过度绘制 → 列表滑动掉帧怎么用平台工具(Systrace/Perfetto、Instruments、Flutter DevTools)定位是布局层级深、主线程 IO、图片解码还是 GC → 复用与预加载、异步布局、降低层级与预渲染的收益与复杂度,什么卡顿值得修
- 好题:信息流列表在中低端机上滑动明显掉帧,你按什么顺序定位?发现是每个 cell 里同步解码大图,你的修法有哪几层(解码线程、尺寸、缓存、占位)?改完怎么用数据证明?
- 危险信号:只会说"减少布局嵌套""用 RecyclerView/复用"而不会用工具;不知道图片解码在哪个线程发生;把所有卡顿归结为"机器差"
- 期望信号:会读帧时间线并归因到具体阶段;知道图片按显示尺寸采样;有卡顿监控(帧率、慢函数堆栈采样)的接入经验;理解主线程 IO 与锁竞争同样会掉帧

### 内存管理与泄漏排查
- 阶梯:为什么移动端内存比桌面更紧张、OOM 的表现 → 引用计数与 GC 两种模型的差异、常见泄漏源(静态持有页面、未注销监听、闭包循环引用、单例持有 Context)→ 线上内存告警或 OOM 崩溃怎么复现与定位(内存快照、泄漏检测工具、按页面维度统计内存增长)→ 图片缓存大小、缓存池与降级策略的取舍,内存与流畅度的平衡
- 好题:应用在连续打开关闭同一个详情页 30 次后内存从 150MB 涨到 700MB 且不回落,你怎么证明是泄漏而不是缓存?定位到具体持有链的工具与步骤是什么?
- 危险信号:分不清内存占用高和内存泄漏;不知道图片是内存大头;只会说"用 LeakCanary/Instruments"但说不出怎么读持有链
- 期望信号:能画出典型的持有链;理解弱引用的适用场景;有线上内存监控(按页面、按机型)的经验;知道内存警告回调该释放什么

### 网络层设计与弱网
- 阶梯:HTTP 请求在客户端怎么发、常用网络库 → 连接复用、DNS 解析与 HTTPDNS、超时与重试策略、HTTP/2 与 QUIC 在移动网络的收益 → 弱网下页面一直转圈或者重复提交订单怎么排查与设计(超时分级、幂等键、退避重试、请求优先级)→ 自建长连接与通用 HTTP 的取舍,网络库统一封装的收益与迁移成本,证书固定与安全的运维负担
- 好题:用户在地铁里点击"提交订单"没反应又点了三次,后台生成了三笔订单,你会在客户端与协议层分别做什么?超时时间你怎么定、重试哪些请求可以自动做、哪些不能?
- 危险信号:所有请求同一个超时;重试没有退避与上限;不知道幂等键;认为弱网只是"加个 loading"
- 期望信号:区分连接超时与读超时;GET 与幂等写请求才自动重试;提到弱网模拟工具与测试;有网络质量分级与请求降级策略

### 本地存储与缓存策略
- 阶梯:键值存储、文件、数据库各存什么 → 缓存的过期与淘汰策略、数据库的索引与迁移、主线程 IO 的危害 → 升级版本后崩溃在数据库迁移、缓存目录被系统清理导致数据丢失、缓存膨胀到几个 GB 怎么排查与治理 → 缓存命中率与磁盘占用的平衡,加密存储的性能成本,什么数据必须落盘什么可以随时重建
- 好题:用户反馈应用占了 3GB 存储空间,你怎么定位是哪个模块产生的?你会怎么设计缓存的上限与清理策略,让它既不占太多又不影响体验?
- 危险信号:所有数据都存键值对;数据库迁移没有版本管理与测试;在主线程读写文件
- 期望信号:按数据类型分层存储;有缓存大小统计与 LRU 清理;数据库迁移有升级路径测试;知道系统缓存目录与用户数据目录的差异

### 离线可用与数据同步
- 阶梯:断网时应用应该表现成什么样 → 本地优先架构、操作队列与重放、冲突检测与解决策略 → 离线编辑后联网同步出现数据覆盖、顺序错乱、重复上传怎么定位与设计 → 完全离线优先与"缓存展示 + 在线操作"两种深度的成本差异,冲突解决交给用户还是自动合并
- 好题:一个笔记类应用要支持离线编辑与多设备同步,你会怎么设计本地数据模型、同步队列与冲突处理?两台设备同时改同一条笔记怎么办?
- 危险信号:认为"缓存上一次接口结果"就是离线支持;没考虑操作顺序与幂等;冲突策略是"后写覆盖"却说不出代价
- 期望信号:区分只读离线与可写离线;操作日志与版本号;有冲突可视化或合并策略;知道同步要考虑电量与流量

### 启动优化
- 阶梯:冷启动、温启动、热启动的区别与用户感知 → 启动各阶段(进程创建、框架初始化、首页首帧、可交互)的划分与测量点、启动任务的依赖与并行 → 启动时间从 1.2 秒涨到 2.5 秒怎么归因(SDK 初始化、主线程 IO、类加载、首页数据请求串行)→ 延迟初始化、按需初始化的收益与"首页某功能偶发不可用"的风险,启动指标与业务方 SDK 的博弈
- 好题:新版本冷启动 P90 从 1.5 秒涨到 2.8 秒,你怎么定位是哪个改动引起的?你会怎么设计启动任务调度框架,让二十几个 SDK 初始化既不阻塞首帧又保证依赖顺序?
- 危险信号:启动时间靠肉眼秒表;不知道启动阶段划分;所有 SDK 在 Application/AppDelegate 里同步初始化
- 期望信号:有线上启动监控与版本对比;启动任务有向图与线程分配;知道首页预加载与懒加载的边界;能说出启动优化的收益衰减点

### 包体积治理
- 阶梯:包体积为什么影响下载转化 → 包内构成(代码、资源、SO/动态库、第三方 SDK)的分析方法、压缩与混淆、资源按需下发 → 版本包体从 80MB 涨到 120MB 怎么找到增量来源,SDK 引入的重复依赖怎么发现 → 动态下发的运维成本与审核风险,按需加载对首次使用体验的影响,图片格式与压缩率对视觉质量的影响
- 好题:包体积半年涨了 40MB,你会怎么建立一套机制让每次合并都能看到体积变化并归因到模块?动态下发模块在 iOS 与 Android 上各受什么限制?
- 危险信号:只知道"压缩图片";没有包体分析工具的经验;不知道 SO 架构与动态库对体积的影响
- 期望信号:有 CI 包体卡口与归因报告;知道资源混淆、无用资源清理、WebP/AVIF;理解 App Bundle/App Thinning 类机制;对动态化的审核边界有认识

### 崩溃、ANR 与稳定性治理
- 阶梯:崩溃率怎么定义、行业基线大概多少 → 崩溃采集原理(信号、异常捕获)、符号化、ANR/主线程卡死的检测机制 → 发版后崩溃率从 0.1% 涨到 0.5% 怎么止血与归因(按版本、机型、系统、页面下钻,回滚、热修还是配置关闭),偶现且堆栈在系统库里的崩溃怎么办 → 热修复的收益与审核风险,稳定性指标与业务迭代速度的博弈
- 好题:发版两小时后崩溃率翻了五倍,堆栈指向一个第三方 SDK,你在前十分钟、一小时、一天内分别做什么?怎么避免下次同样的事?
- 危险信号:不知道自己项目的崩溃率;崩溃平台只会看 top 榜不会下钻;没有任何灰度或开关机制
- 期望信号:崩溃按影响用户数排序而不是次数;有灰度放量与开关降级;知道 OOM 与 watchdog 类崩溃需要特殊采集;有 ANR/卡死堆栈的分析经验

### 发布、灰度与动态化
- 阶梯:应用商店发布流程与审核要点 → 灰度放量策略、AB 实验框架、远程配置与开关、热修复原理 → 灰度期间某机型问题怎么快速定向、AB 实验结果不显著或与预期相反怎么分析、热修补丁导致新崩溃怎么处理 → 动态化框架(小程序容器、H5、RN、自研 DSL)的收益与体验、审核、维护成本,什么业务值得动态化
- 好题:一个双端 App 每两周发一版,你会怎么设计灰度流程(比例、观察指标、放量条件、回滚)?哪些变更你坚持走发版而不是热修或动态下发?
- 危险信号:没有灰度直接全量;开关没有默认值与失效策略;把热修当常规发布手段
- 期望信号:灰度指标包含崩溃、关键漏斗、性能;配置有版本与回滚;对 iOS 审核对热修的态度有认识;能说出动态化的边界

### 跨端与技术选型
- 阶梯:原生、H5、React Native、Flutter、小程序容器各是什么 → 各方案的渲染原理(WebView、JS 桥 + 原生控件、自绘引擎)与性能、一致性、动态化能力差异 → 跨端页面在某端体验差、桥接通信卡顿、原生能力缺失怎么处理 → 团队规模、业务变化频率、性能要求、招聘难度对选型的影响,混合架构的路由与通信设计
- 好题:一个电商 App 的活动页、商品详情页、购物车分别适合用什么技术实现?为什么?如果选了跨端框架,原生与跨端页面之间的导航、数据共享、登录态怎么打通?
- 危险信号:认为跨端可以完全替代原生;不知道各方案的渲染原理差异;选型理由只有"团队熟悉"
- 期望信号:按页面特性分层选型;理解桥接成本与自绘引擎的一致性代价;有混合栈的路由与状态同步方案;对跨端的包体与启动影响有数据

### 权限、隐私与合规
- 阶梯:运行时权限的申请流程 → 权限拒绝后的降级体验、隐私合规要求(合规检测、SDK 采集行为)、系统对后台定位/剪贴板/相册的限制变化 → 应用因隐私问题被商店下架或被监管通报怎么排查是哪个 SDK 在收集、怎么建立 SDK 准入 → 用户体验与合规的平衡,最小权限原则在业务压力下怎么坚持
- 好题:应用被通报"未经同意收集设备信息",但你的代码里没有主动收集,可能是什么原因?你会怎么建立 SDK 准入与行为审计机制?
- 危险信号:启动时一次性申请所有权限;不知道隐私合规的基本要求;没有 SDK 行为审计意识
- 期望信号:权限按使用场景申请并解释;隐私政策弹窗前不初始化采集类 SDK;有 SDK 行为检测(hook 或静态扫描)经验

### 架构与模块化
- 阶梯:MVC/MVP/MVVM/MVI 各解决什么 → 模块化与组件化的边界划分、模块间通信(路由、接口下沉、事件)、依赖注入 → 模块化后编译变慢、循环依赖、基础模块改动引发全量重编怎么处理 → 单仓多模块与多仓的取舍,架构规范在大团队怎么落地,过度架构的代价
- 好题:一个 5 人团队维护的 App 长到 30 人后,编译一次要 15 分钟、改一个基础类全组等待,你会怎么拆模块?模块间怎么通信、怎么保证不出现循环依赖?
- 危险信号:架构名词一堆但说不出解决的具体问题;模块化后所有模块互相依赖;没有编译时间数据
- 期望信号:按业务域与基础层分层;接口与实现分离;有编译速度的度量与优化经验;对架构规范的执行方式(lint、依赖检查)有实践

## 好题 / 坏题对比

- 坏:说说 App 的生命周期。
- 好:用户在发布页写了 500 字、选了 9 张图,切到微信再回来后内容全没了,Android 与 iOS 上分别可能是什么原因?你会怎么设计恢复方案、恢复到什么程度算够、怎么测试它?

- 坏:如何做启动优化?
- 好:新版本冷启动 P90 从 1.5 秒涨到 2.8 秒,你怎么定位是哪个改动引起的?二十几个 SDK 要初始化且有依赖关系,你会怎么设计启动任务调度让它们不阻塞首帧?延迟初始化会带来什么新风险?

- 坏:跨端框架有哪些?各有什么优缺点?
- 好:电商 App 的活动页、商品详情、购物车三个页面你会分别用什么技术实现、为什么?选了跨端后原生页面与跨端页面之间的导航、登录态、数据共享怎么打通?

## 项目结合钩子

- 简历出现"启动时间优化 X%" → 追测量点定义(首帧还是可交互)、线上还是本地数据、最大的一项改动、延迟初始化有没有引发功能偶发不可用
- 简历出现"包体积减少 X MB" → 追分析工具、最大的几项来源、动态下发做了什么、有没有 CI 卡口防止反弹
- 简历出现"崩溃率从 X 降到 Y" → 追分母定义、top 崩溃类型与根因、用了热修还是发版、有没有偶现系统库崩溃的处理经验
- 简历出现"性能优化 / 卡顿治理" → 追用什么工具定位、帧率或慢函数指标前后对比、最难的一个卡顿根因
- 简历出现模块化 / 组件化 / 架构升级 → 追模块划分依据、模块间通信方式、编译时间变化、推广到团队时的阻力
- 简历出现跨端(RN / Flutter / 小程序容器)→ 追为什么选、哪些页面没用跨端、桥接性能问题、包体与启动影响、双端一致性问题
- 简历出现离线 / 同步 → 追数据模型、冲突策略、重放队列的幂等与顺序、弱网测试方法
- 简历出现灰度 / AB 实验 / 热修 → 追放量策略与观察指标、回滚过几次、热修的审核风险怎么处理

## 出题原则

- 移动端题从"设备与网络的不确定性"切入:低端机、弱网、切后台被杀、权限被拒,先问现象与定位,再问原理,能背某平台生命周期回调但说不出系统为什么这么做的要追。
- 每个优化都追数字与工具:启动、包体、崩溃率、帧率必须说出测量点定义、线上数据与前后对比,"感觉快了"不算答案。
- 双端思维优先:平台无关的题要让候选人说出 Android 与 iOS 的差异点,只熟一端的候选人要能说出另一端大概怎么做;平台细节交给 stack 包。
- 结合团队与用户规模出题:小团队工具类 App 不强考灰度平台与模块化,日活百万级的 App 必须追稳定性治理与发布流程。