跳到主要内容

Software Engineering

移动开发工程师

移动开发工程师构建的应用,运行在别人的硬件上,运行在一个可能毫无预兆就把它挂起的操作系统里,运行在用户自己选择安装、并且可能永远不再更新的那个版本上。这三个事实塑造了整门学科。本指南说明这项工作在 iOS 与 Android 上包含什么、原生与跨平台的决策该怎么想,以及评估候选人时应当看什么。

移动开发工程师具体做什么?

移动开发工程师为 iOS、Android 或两者构建并发布应用——页面与导航、让应用在无网络时仍可使用的本地数据存储、与摄像头、定位、生物识别和通知等设备能力的集成,以及把一个构建版本送过商店审核、发布给用户的整个流程。这一角色还要对应用在受限硬件上的表现负责:启动时间、内存、耗电,以及在比开发机老得多的设备上的响应速度。

与 Web 工程的结构性差别在于:你无法控制正在运行的版本。一次 Web 修复在下一个请求就送达所有人;一次移动端修复必须经过构建、签名、提交、审核、批准、发布,然后由一个可能好几个月都不愿更新的人去安装。因此用户会同时运行许多个版本,服务端的每一次改动都必须与远早于它写成的客户端保持兼容。正是这一条约束,让移动团队在 Web 团队无需谨慎的地方格外谨慎,也正是 Web 团队被要求做一个 App 时最常低估的东西。

第二个差别是设备本身。操作系统可能为了回收内存而挂起或终止进程,后台执行受到限制且各平台不同,网络连接是断断续续而不是有或无,而应用做的每一件事都要记在用户正盯着的那块电量上。一个假定网络存在、假定自己进入后台后仍在运行、或者假定重新启动时会保持离开时状态的应用,在开发环境里工作得很好,到了真实用户手里就会表现得莫名其妙。

最后,两个平台的惯例确实不同——导航与返回行为、权限模型、排版与布局规范、生命周期、审核政策和发布工具链。跨平台框架减少了重复代码,但并没有消除理解两个平台的必要,因为抽象结束的地方,恰恰是用户会注意到的地方:手势、键盘处理、通知、深度链接、无障碍访问,以及任何触及硬件的能力。

Assessing the need

团队在什么情况下需要这项能力

移动工作经常被交给离前端最近的人,前提假设是“App 不过是换了个外壳的网站”。以下这些情形,就是这个假设开始变昂贵的时候。

  • Web 团队被要求做一个 App

    有能力的工程师通常都能把东西跑到设备上。他们往往缺的是发布工程、商店政策、平台导航惯例、后台执行限制,以及为“同时存在多个在用版本”而设计的习惯。第一次提交被拒,通常就是这件事显形的时刻。

  • 产品必须在没有网络时也能用

    外勤作业、物流、门店现场、仓库、出行、信号不稳的区域。本地持久化、离线动作排队、冲突解决,以及对同步状态的如实呈现,既是工程问题也是设计问题,事后是补不出可信效果的。

  • 设备能力本身就是产品

    拍照与扫码、精确或后台定位、蓝牙外设、生物识别、健康或传感器数据。这些都位于各平台不同、并且会随系统版本变化的权限模型之后,也是通用跨平台层最容易走到尽头的地方。

  • 发布质量已经开始产生代价

    崩溃集中在特定机型或特定系统版本上、商店评分下滑,或者某个已发布的缺陷无法迅速撤回。移动端没有面向已更新用户的快速回滚,因此质量必须在发布之前就守住,而不是发布之后再补救。

  • 真实设备上的性能开始被投诉

    冷启动慢、滚动卡顿、应用在后台被终止,或者明显耗电。这些要用平台的性能分析工具在有代表性的硬件上诊断,而在一台连着调试器的新旗舰机上,它们很少复现。

The discipline

核心能力

  • 平台熟稔度

    知道每个平台期待应用如何表现——导航与返回栈语义、Activity 与 View Controller 的生命周期、权限弹窗、系统排版与布局惯例。忽视这些的应用,用户通常在说得清原因之前,就先说它“别扭”。

  • 原生与跨平台的判断

    理解共享代码库究竟省下了什么、抽象在哪里会漏,以及漏的时候下沉到原生代码的代价。这个决定取决于产品有多少部分依赖设备集成、两个平台需要表现得多不一样,以及将来由谁维护。

  • 离线行为与本地数据

    选择本地存储、决定缓存什么以及缓存多久、把断网期间的操作排队、在数据回到服务端时解决冲突,并向用户展示真实状态而不是乐观状态。同步正是移动应用积累最棘手缺陷的地方。

  • 受限硬件上的性能

    冷启动时间、滚动与动画时的帧渲染、内存压力及其导致的终止、图片解码,以及消耗电量的后台活动。有意义的测量来自较老的中端设备,而不是办公室里最新的那台手机。

  • 发布工程

    签名与描述文件、构建变体、版本管理、Beta 分发、灰度发布、商店元数据,以及在某个客户端版本必须退役时强制升级的能力。移动端相当一部分运维风险住在这里,而不在应用代码里。

  • 商店审核与政策

    在各家商店执行的规则内工作——隐私声明、支付与订阅政策、权限用途说明、内容要求、账号注销——并且把设计做成让审核结果可预期,而不是每次都成为交付计划里的意外。

  • 通知与后台任务

    通过各平台服务进行推送投递、令牌生命周期、权限与用户授权、从冷启动深度链接到正确的页面,以及把后台任务写成能在一个会延迟、合并甚至取消它们的操作系统下依然成立。

  • 移动端无障碍访问

    VoiceOver 与 TalkBack 的屏幕阅读支持、有意义的标签与分组、尊重用户的字号与减少动效设置、足够大的点击区域和合理的焦点顺序。移动端无障碍有自己的一套惯例和测试工具,Web 上的知识部分可迁移,但覆盖不全。

  • 设备与版本碎片化

    决定支持哪些系统版本和屏幕类别,在有代表性而不是顺手的设备范围上测试,并在不写出一堆条件分支迷宫的前提下处理能力差异。

Context

技术生态

以下列出的是移动工程领域的常用技术。这描述的是该学科在业界的普遍实践,并非对某位工程师技能的说明。这里更有信息量的问题,是候选人在哪些平台上真正发布并长期维护过应用,因为商店、发布与生命周期方面的知识是与平台绑定的,而语言知识不是。

iOS

  • Swift
  • SwiftUI
  • UIKit
  • Xcode
  • Swift Concurrency
  • Combine

Android

  • Kotlin
  • Jetpack Compose
  • Android SDK
  • Android Studio
  • Coroutines

跨平台

  • React Native
  • Flutter
  • Expo
  • Kotlin Multiplatform
  • .NET MAUI

本地数据与同步

  • SQLite
  • Room
  • Core Data
  • SwiftData
  • Realm
  • WatermelonDB

设备端服务

  • APNs
  • Firebase Cloud Messaging
  • Crashlytics
  • Sentry
  • RevenueCat

测试

  • XCTest
  • Espresso
  • Maestro
  • Detox
  • Appium
  • Firebase Test Lab

构建与分发

  • Fastlane
  • Xcode Cloud
  • Bitrise
  • TestFlight
  • App Store Connect
  • Google Play Console

Working model

How this role works with your team

Engineers work inside your team, on your priorities, to your standards. You direct the work; Talent.ID carries the employment. The division below is the whole arrangement.

You keep

  • 产品
  • 业务优先级
  • 路线图
  • 架构
  • 冲刺优先级
  • 工程标准
  • 日常技术协作

Talent.ID handles

  • 雇佣关系
  • 薪资发放
  • 员工福利
  • 人才管理
  • 持续的员工关系

How an engagement works, step by step

Buyer guidance

评估候选人时应当考察什么

一个已上线的应用,是多数学科给不出的那种证据,但它只是表面的证据。它不会告诉你发布是怎么管理的、应用在弱硬件上表现如何,也不会告诉你网络断掉时会发生什么。要问的是这些。

发布经历,而不是构建经历

问他们把什么送过提交审核、并在之后持续维护过。做出一个应用,和跨越许多个版本运营一个应用,是两种不同的经历,而只有后者才能教会版本管理、灰度纪律,以及与已经在用户手中的客户端保持兼容。

  • 管理过签名、描述文件与商店元数据,而不只是接手现成的
  • 会使用灰度发布,并在扩大范围前观察无崩溃会话率
  • 能描述一次被拒,原因是什么、又是如何解决的
  • 对何时强制升级、以及如何先行提醒用户,有想清楚的立场

框架之下的平台深度

跨平台经验有价值,但它可能掩盖对底层平台的理解缺失。问他们:框架覆盖不到某个场景时,他们做了什么——答案能把认真发布过东西的人,和一直待在抽象层里的人区分开。

  • 在共享层不够用时写过或读过平台原生代码
  • 能解释至少一个平台的生命周期与后台限制
  • 知道两个平台在哪些地方确实需要表现得不一样

离线与同步的思考

问他们最近做的那个应用在完全没有网络时会怎样。弱的回答描述一条错误提示;扎实的回答会描述排队的操作、一个本地事实来源,以及在事情尚未完成时告诉用户什么。

  • 区分缓存读取与排队写入
  • 对冲突有明确处理思路,而不是假设它不会发生
  • 在界面上如实呈现待处理与失败的状态

用户真实持有的设备上的性能

问他们如何测量启动与滚动,以及在什么硬件上测。只在当代旗舰机上做性能分析的工程师,会持续错过其真实受众正在遇到的问题。

  • 使用平台性能分析工具,而不是凭印象
  • 有意在较老的中端硬件上测试
  • 能说出一个自己修过的具体掉帧或内存压力成因
  • 把耗电当作需要测量的东西,而不是靠推断

生产环境的崩溃分诊

移动端的故障,是以陌生人在你无法检查的设备上产生的堆栈形式送达的。问他们如何从一份崩溃报告走到成因,以及面对一整列报告时如何排定优先级。

  • 按受影响用户数和严重程度排序,而不是按原始次数
  • 会针对无法复现的问题有意补充面包屑或日志
  • 诊断过只出现在某一个系统版本或某个厂商机型上的故障

移动语境下的无障碍访问

问他们:开启屏幕阅读器、或者把字号调得很大时会发生什么。这是一个直白的问题,而相当比例的候选人从未想过,它也因此是衡量工艺水准的一个合理代理指标。

  • 真的用 VoiceOver 或 TalkBack 走过自己的应用
  • 能在大字号下不出现截断或布局错乱
  • 为纯图标控件提供标签,并尊重减少动效的偏好设置

对架构选择的推理

问他们什么时候会选原生而不是共享代码库,以及什么会让他们改变主意。你要找的是条件与取舍,而不是对简历上那个框架的忠诚。

  • 把这个选择与设备集成程度、团队构成和维护周期联系起来
  • 能为自己并不偏好的那条路线做论证
  • 意识到这个决定对用人的约束不亚于对工程的约束

Buyer guidance

值得一问的面试问题

这些问题是为了暴露候选人如何看待发布、设备,以及那些他触及不到的用户。请在您自己的面试流程中使用——谁进入您的团队,由您依据自己的评估来决定。

  1. 一个缺陷发布出去并到达了用户。从第一份反馈到修复真正到人们手上,你实际会做哪些事?

    What a strong answer shows

    他们是否理解移动端发布的不可逆性。扎实的回答会涵盖暂停或收窄灰度、可用的服务端缓解手段、提交审核所需的时间,以及一个现实:无论如何,总有一部分用户会停留在有问题的版本上。

  2. 要做一个新应用,你如何在原生与跨平台框架之间做决定?

    What a strong answer shows

    有条件的推理。要看他给设备集成程度、两个平台需要分化到什么程度、将来由谁维护、以及偶尔下沉到原生的代价各自赋予多少权重——而不是把一种笼统偏好当成结论抛出来。

  3. 说说你的应用在没有网络时会怎样,以及在某个操作进行到一半网络恢复时又会怎样。

    What a strong answer shows

    离线设计是否真实。有意思的部分在于重连:排队的操作被安全重放、重复提交被阻止、冲突按既定规则解决,以及告诉用户还有什么在等待处理,而不是一个转圈图标。

  4. 服务端团队想改一个 API 的响应结构,而线上还有若干旧版本的客户端。你会怎么跟他们说?

    What a strong answer shows

    兼容性纪律,这也是移动工程师区别于 Web 工程师最明显的习惯。要看增量式变更、带版本的契约、宽容解析,以及一套先行提醒、再让旧客户端退役的方案。

  5. 随着应用变大,冷启动明显变慢了。你怎么查清原因?

    What a strong answer shows

    先测量再动手。扎实的回答会用平台的追踪工具、把启动过程拆成若干阶段、找出启动时被急切执行而其实可以延后的工作,并在有代表性的硬件上而不是手边最新的设备上验证改进效果。

  6. 一次崩溃影响了少部分用户,集中在某一个系统版本上,而你无法复现。接下来怎么办?

    What a strong answer shows

    远程诊断能力。要看他是否认真读堆栈、按设备、版本与语言环境分段、有意识地补充观测手段,并形成一个能用数据验证的假设——而不是发一个凭猜测写的修复版然后干等。

  7. 如果我在你最近发布的那个应用上打开屏幕阅读器并把字号调大,会发生什么?

    What a strong answer shows

    无障碍访问是做过的,还是假定的。真正做过的人会说出具体的修复——为图标控件加标签、布局重排、模态框中的焦点顺序;没做过的人会回答“框架会处理”。

Illustrative engagement

What this looks like in practice

A hypothetical scenario, written to show how the working model applies. It does not describe a Talent.ID client or a completed project.

Challenge
某个团队在两个平台上维护同一个应用,同时还背着一份新功能路线图。崩溃报告集中在较老的机型上,离线行为需要重做,而每一次发布都在消耗团队本更愿意花在产品上的时间。
Approach
追加的移动工程能力在团队既有的实践内工作——他们选定的架构、他们的分支与评审约定、他们的测试方式,以及各家商店上的发布节奏。功能优先级和平台决策,仍然由拥有这个应用的团队来做。
What this adds to the team
维护与平台工作可以与功能交付并行推进,而不是彼此争抢。应用要变成什么样、以及如何构建,仍然由对它负责的人来主导。

Related disciplines

Common questions

Frequently asked questions

我们应该做原生还是跨平台?
取决于产品中有多少部分就是设备本身。主要由表单、列表和内容构成的应用,用共享代码库很合适,省下第二套实现的收益是实打实的。而围绕摄像头、传感器、后台定位、蓝牙外设或高要求图形构建的应用,会把这份节省花在桥接代码和平台例外上。决定成败的往往是两个非技术因素,而不是技术因素:将来由谁维护,以及两个平台是否需要在体感上明显不同。一位工程师背着一长串功能清单,通常指向共享方案;平台专才配上一个重设备的产品,通常指向原生。
Web 开发工程师能用 React Native 做移动应用吗?
他们通常能很快推进,因为组件模型和语言是相通的。真正麻烦的那部分不相通:签名与商店提交、权限模型、生命周期与后台限制、离线行为、推送投递,以及跨设备测试。一位 Web 工程师独自作战时,正是在这些地方把熟悉语法看似省下的时间又赔了进去;所以把 Web 的熟悉度,与一位真正发布并维护过移动应用的人结合起来,比指望框架填平这道沟更可靠。
我们需要分别配备 iOS 和 Android 工程师吗?
如果走原生路线,通常需要——工具链、语言、惯例和发布流程差别足够大,两边都有真正深度的人并不多见。如果走共享代码库,一个人可以覆盖两端,前提是有人对每个平台的理解足以处理框架覆盖不到的情况。无论哪种方式,都应当把两个平台当作需要各自测试、各自关注发布的对象,而不要因为代码共享就假定它们表现一致。
应用商店审核会怎样影响交付计划?
它在“改动完成”和“用户拿到”之间放进了一段长度不定、且不由你控制的延迟。会为此做规划的团队,会按可预期的节奏发布、在构建下一个版本时让上一个版本在审核中、并使用远程配置或服务端开关,让行为不必再提交一次就能调整。忽视它的团队,往往会在一次事故当中才认识到这条约束,而那是最糟糕的学习时机。
移动应用需要专门的后端工作吗?
几乎总是需要,而且通常比预期更多。客户端无法随时更新,所以 API 必须做版本管理并容忍旧调用方;通知需要一个存储令牌、处理投递的服务;离线同步需要为对账而设计的接口,而不是简单的读写。移动工程师对这些通常都有看法,很多时候也能实现,但它属于服务端工作,应当照此规划。
我们该如何衡量一个移动应用是否健康?
无崩溃会话率、在有代表性硬件上的冷启动时间、较新版本的采用率,以及授予通知与其他权限的用户占比。商店评分是滞后且嘈杂的信号,适合看方向而不适合做诊断。团队最常忽略的指标是版本采用率,因为它决定了任何一个缺陷会在线上停留多久,以及旧客户端多快才能安全退役。
移动开发工程师如何与现有的工程团队协作?
他们按您的方向工作:您的路线图、您的平台决策、您的评审流程和您的发布计划。日常的开发优先级和技术决策由您的团队掌握,技术所有权不会转移,技术团队扩展也不是把整个交付转交给外部团队的模式。Talent.ID 承担的是雇佣关系:薪资发放、员工福利、人才管理,以及与员工之间持续的关系。

Tell us what your team needs

Describe the gap — the work, the stack, the way your team runs — and we will tell you what we can support. If it is not something we can help with, we will say so.