---
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 必须追稳定性治理与发布流程。
