前言
从 2024/5/30 到 2026/3/23,将近两年里,我在深圳小米公司担任操作系统架构师,负责澎湃 OS 基础设施研发和下一代移动 OS 形态探索。在这个过程中,我有幸与行业里的许多技术专家共事,包括前华为仓颉语言首席设计师、英特尔虚拟机专家、阿里云虚拟化专家,还有许多深耕安卓系统多年的高级工程师。我们一起打造新一代高性能安卓系统运行时,目标是打破传统安卓原生系统的性能瓶颈,提升整个小米生态产品的用户体验。
这篇文章会以碎碎念的形式,分享我在小米近两年里的一些经历和感悟,包括技术向和非技术向的内容,也算是记录个人职业生涯中的一段成长。
安卓与苹果的二十年党争
苹果 iOS 系统发布于 2007/6/29,安卓系统发布于 2008/9/23,可以说这两个系统见证了全球移动互联网行业的兴起和普及,而它们之间的党争从未停歇。我不是专业的产品经理或者投资人,这里只是站在消费者和曾经在安卓厂商工作过的技术开发者的角度,聊聊它们之间的区别。难免会有理解偏差,大家就当看个乐子。
先给一个数据:截至 2026 年 5 月 22 日,苹果公司的估值为 4.48 万亿美元,全球第三;华为公司估值为 3000 ~ 4000 亿美元;小米公司估值约为 1000 亿美元;OPPO 公司估值约为 40 亿美元。
大家可以看到,国内最大的三家安卓手机厂商,估值加起来不足苹果公司的十分之一,而且华为公司和小米公司并不只靠手机业务盈利。即便把华为云、小米汽车、智能家居等业务也算进去,苹果阵营和安卓阵营公司的估值差距仍然非常大。
出现这种现象的原因也很简单:1. 卖硬件不赚钱;2. 卖低端手机不赚钱。
苹果公司 2025 年的 iPhone 手机销售额为 2095.86 亿美元,单机利润率约为 36%,而通过 App Store 收税、订阅服务(iCloud、Apple Music)、广告等服务业务的收入毛利率为 75%+,是硬件业务的两倍多。所以苹果公司估值高的主要原因,在于它能“收税”:收开发者的税、收互联网厂商的税,也收 Google 搜索的税。
那国内的安卓厂商不能收税吗?本来很难,但在国内市场环境下逐渐变成可以了。安卓阵营的税收主要分为两部分:一是 Google 公司向安卓手机厂商收的税;二是 Google 公司向应用开发者收的税。安卓系统的源码(AOSP)是完全免费开源的,任何厂商都可以免费使用、修改和分发。厂商需要向 Google 公司支付的费用主要是 GMS 授权费,用于获得预装谷歌全家桶(Google Play 商店、Gmail、YouTube、谷歌地图等)的权利;应用开发者向 Google 公司交的税主要是 Google Play 应用商店的授权费,这和苹果公司的盈利模式是类似的。
但在国内,GMS 被禁止使用,于是大家会发现,华为、荣耀、小米、OPPO 手机上都是不同的应用商店,应用开发者如果想要上架华为/小米应用商店,就需要给对应的公司支付服务费(交税)。于是在国内市场,安卓手机厂商获得了收税的权利。但是在海外,华为/小米等手机产品依然需要向 Google 公司支付 GMS 授权费,也几乎不会有海外开发者愿意再为 Google Play 之外的应用商店支付服务费。
另外,大家会发现,大部分国产安卓手机都会自带一些系统应用(天气、相册,甚至游戏),更细心的同学会发现,其中许多系统应用会带广告。这也是国内安卓厂商应对“卖硬件不赚钱”的另一种做法:靠互联网业务填补利润。
那么,既然国内安卓厂商既能收税,又能打广告,为什么还是竞争不过苹果公司呢?这就要聊到另一个原因了:卖低端手机不赚钱。
“苹果高端,安卓低端”这一说法源于长期的价格差异和消费者认知,特别是小米手机,早期通过“性价比”打开了学生市场,但同时也被打上了低端的标签。这一说法甚至被延伸到“苹果人、安卓人”进而出圈。
由于存储芯片价格暴涨,物流、售后、生产等成本居高不下,低端用户的互联网服务变现能力弱,低端手机实际上卖一台亏一台。因此,华米 OV 近几年不约而同地加速高端化,我在小米内部的多个部门会、年终总结会上,已经不下五次听到领导表达类似“卖低端不赚钱,要做高端”的判断。
如果是站在消费者角度,我会选择苹果而非任何一款安卓手机,因为前者稳定、流畅、保质期长。我买过的每一款苹果产品,包括一款日版 iPhone 13、两台 Mac mini、一台 iPad、一台 MacBook,都没有出现任何质量问题,即使用了两三年,体验也依然像新设备一样顺手。而我买的一台 OPPO 手机和一台小米手机,都在使用一年后黑屏,无法继续使用。
如果是站在开发者角度,我更会选择苹果而非安卓。因为从技术视角看,所有安卓手机的系统代码都是从 Google 公司开源的 AOSP 项目中修改而来,但是国内的安卓厂商,往往只有能力做到修改,无法做到理解和掌控。直白一点讲,就是很容易改出 Bug。更可怕的是,这个现象与手机是否高端无关,也就是说,无论购买的是 100 元的安卓手机还是 10000 元的安卓手机,它们之间的软件差异不大,该出现的 Bug 依然会出现。更贵的安卓手机不代表更少的 Bug,可能只会带来更好的售后体验。繁重的售后工作又进一步提高安卓手机厂商的成本,压低毛利率。
操作系统与平台编程语言
一名优秀的 CS 专业毕业生可能会疑惑:“操作系统和编程语言不应该是互相解耦的关系吗?”如果从软件工程的角度看,确实是这样。编程语言解决的是如何提供一座介于自然语言和机器语言之间的桥梁,而操作系统解决的是如何提供一个操作硬件的平台,某个编程语言不应该绑定某个操作系统。但实际上,为了降低应用开发者的门槛,安卓、iOS 均提供了在操作系统内核之上的一层 Framework,提供一些通用基础能力,加快应用开发。而这些 Framework 往往是操作系统厂商基于某一种编程语言实现的,比如安卓是 Java,iOS/macOS 是 Swift,鸿蒙是仓颉。我们将这类语言称为“平台编程语言”,区别于 Rust/C++ 等“通用编程语言”。
据我的前同事、前华为编程语言实验室仓颉语言首席设计师描述,平台编程语言最大的一个特点是:与操作系统平台深度集成。比如 Swift 语言的介绍:“Swift is a powerful and intuitive programming language for all Apple platforms.” 平台编程语言的背后有一套深层逻辑。
- ABI 兼容性
在互联网大厂,特别是偏业务团队的同学可能会对这个词有点陌生:什么是 ABI?什么是 ABI 兼容性?我们来设想一个场景,假设我们有两个程序 A 和 B,它们编译后是两个不同的二进制产物,程序 B 调用了程序 A 的一个foo接口;现在发现程序 A 有一个 Bug 需要修复,于是我们修改程序 A 的代码,然后重新编译出一个新的二进制产物。那么如何保证产物 B 在不需要重新编译的情况下,能正常调用到程序 A 提供的foo接口呢?
这个问题的答案就是 ABI 兼容性。ABI,Application Binary Interface,它界定了不同二进制产物(可执行文件、库文件)之间如何调用函数和交换数据。事实上,如果我们不考虑 ABI 兼容性,以上场景非常有可能会出现 UB(Undefined Behavior,未定义行为)。非常多的编程语言,比如 Rust、Java、Python 等,并不保证 ABI 兼容。
这个问题之所以在互联网行业不被过于关注,是因为大部分情况下,实现一个上层应用时,所有模块都是一起编译、打包的。这样一来,所有二进制文件都会被锚定在同一个版本,不会出现接口之间 ABI 不兼容的问题。
但是如果要实现一个系统框架,情况就不一样了。无论是 iOS Swift Framework,还是安卓 Java Framework,它们都是与应用解耦、独立发布的二进制产物。也就是说,系统框架的实现方需要考虑系统 API 接口的 ABI 兼容性,需要保证新版本 Framework 发布后,能兼容旧版本应用。不仅要考虑 API 兼容性,还需要考虑 ABI 兼容性,前者可能导致应用崩溃,后者可能导致 UB。系统框架的开发者保证 API 兼容性,编程语言保证 ABI 兼容性。
在生产环境中,ABI 兼容性往往比 API 兼容性更加重要,因为 UB 相比一般的程序错误更加不可控、难以排查,UB 可能导致程序崩溃、泄漏数据和发射原子弹。
这样会有什么好处呢?举个实际的例子,Swift 5 之前,苹果应用的开发者需要将一个 Swift runtime 一起打包到 App 里面,这不仅会导致应用包体积增大,而且会导致程序运行的 PSS 内存增大,因为 iOS 系统上的每个应用都得单独运行一个 Swift Runtime。在 Swift 5 之后,ABI 稳定了,于是苹果就将系统框架放到了系统分区。这样一来,iOS 系统上只会运行一份 Swift Runtime,而这个 Runtime 的运行内存可以分摊到所有应用的 PSS 中,每个应用的 PSS 相较之前就有了较大的下降。
- API 兼容性
由于系统 Framework 和应用程序的发布节奏不同,Framework API 的实现方需要考虑 API 兼容性。假设 Framework 在 1.0 版本中提供了foo接口,在 2.0 版本中提供了bar接口,那么应用程序需要保证在 Framework 1.0 和 2.0 版本中都能正常运行,应该怎么做?通常会像下面的伪代码一样做“兼容性保护”处理:
1 | import os; |
可以看到,上面的代码会判断当前系统的版本号,只有大于等于 2.0 才会去调用bar接口。如果是一位经验丰富的软件工程师,很容易会挑出这里的问题:
- 性能上会多一次条件判断的开销。如果该接口的调用频率较高,这笔开销会非常可观;
- 从 2.0 版本开始,对于后续所有发布的新 API,应用程序在调用的时候都需要进行条件判断,这会带来非常大的工程复杂度。
先来说第二个问题,开发过安卓或者 iOS 的同学可能比较熟悉,这个问题是通过设置应用程序的“最低版本要求”来解决的,安卓是minSdkVersion,iOS 是MinimumOSVersion。应用程序的开发者通常会在发布前设置一个版本号,声明这个应用必须在高于或等于这个版本的系统上才能正常运行。如此一来,开发者只需要对这个版本之后的系统 API 进行兼容性保护即可。
回到第一个问题,实际上,这里并不是一次条件判断,而是两次。因为系统 API bar的实现方在接口内部必然也会进行条件判断,否则这个接口就是unsafe的,可能会出现 UB。系统 API 的实现方不仅需要保证接口功能的正确性,同时也需要保证接口在任何情况下被调用,即使是被错误调用,也不会出现 UB。因此bar接口的实现内部也必然会进行“兼容性保护”,以保证接口安全。那么有办法优化吗?有,把这个版本判断下沉到平台编程语言里。实际上 Swift 就是这么做的,它在编译器层面做了优化。以上面的代码为例,当进入到version >= 2.0成立的分支后,编译器会优化掉这个分支中所有系统 API 的版本判断,这样一来只需要承担一次条件判断的开销。
- 可掌控的生态
在讨论生态问题之前,我想先抛出一个问题:谁来决策一门编程语言迭代的方向和优先级?
现代编程语言,如 Rust、Swift、Java、Go 等,都在不断迭代,迭代方向包括性能优化、上面提到的 ABI 兼容性和易用性等。不同方向的取舍和优先级,一般由基金会或者执行委员会来决策。基金会中不同成员的话语权也存在差异,取决于对语言发展和项目资金的投入力度。
这里可以看到,如果一个公司可以在编程语言基金会中掌握话语权,那么就可以推动这门语言朝偏向公司业务的方向迭代。比如华为公司,核心业务覆盖操作系统、云计算等领域,看重 Rust 在系统级编程、安全可信软件领域的巨大潜力,因此成为了 Rust 基金会的五位初始白金成员之一,自 2021 年基金会成立以来一直保持最高级别的会员身份。
把话题拉回主线。对于操作系统平台提供者来说,拥有一门自己可掌控的平台编程语言非常重要。这不仅意味着能推动语言朝服务于自己公司业务的方向发展,还能促进编程语言针对特定平台进行深度优化。
因此,苹果公司大力推行自研 Swift 语言,与 iOS/macOS 系统深度融合,一套代码可以兼容多种设备,真正做到了“统一全生态”。此外,华为公司也自研了“仓颉”编程语言,服务于自研鸿蒙操作系统(实际上仓颉在华为公司内部也会在一些云计算场景使用)。
那么安卓平台的情况是什么样的?Google 公司是否在 Java 的基金会或者委员会里面掌握了较大的话语权?实际上 Java 语言主要由 OpenJDK 社区决策,我的直观感觉是 Google 公司在其中的话语权不算太大。但是,细心的同学可能会留意到,AOSP 里面使用的 Java 虚拟机并不是和 OpenJDK 一样的实现。AOSP 中现在使用的是 Google 自主研发的 ART 虚拟机(曾经是 Dalvik),其针对安卓平台的场景做了特殊设计和深度优化,比如采用了 AOT 为主、JIT 为辅的混合执行模型,加快了应用的运行速度,同时 GC 算法也针对移动设备内存、CPU 资源有限的场景进行了优化。
相信通过以上分析,已经足够说明了平台编程语言在生态中的作用。
安卓系统面临的困境与启示
作为一个有安卓系统底层框架开发和调优经验的开发者,这里从架构设计的角度分析一下安卓为什么没有 iOS 做得好,具体体现在哪些方面,以及有哪些解决思路。
笨重的 Java 虚拟机
Swift 和 Java 的最大区别是前者是静态语言,通过 LLVM 编译成二进制执行;后者是动态语言,通过 Java 虚拟机执行。毋庸置疑,理论上前者的性能比后者更好,原因是:
- 虚拟机不是“零成本”的,这意味着即使我们用 Java 开发一个 Hello World 程序,也必须要付出整个虚拟机的开销:加载所有的内存、执行所有的不必要逻辑;
- Swift 直接编译成机器码指令,可以直接发给处理器执行;Java 需要先被解释成机器码,多一层翻译的开销;
- Swift 通过引用计数管理内存,无 GC;Java 通过 GC 管理内存,GC 卡顿会影响应用的流畅性。
Google 架构师团队也为上面的问题伤透了脑筋,他们尝试通过AOT,也就是将 Java 代码提前编译成机器码来降低翻译的开销。这个思路是好的,但是落地后依然存在问题:
- AOT 会导致应用安装时间变长;
- ART 虚拟机 AOT 的机器码生成质量比不上 LLVM;
- 难以做到 100% AOT。
因此这个问题依然困扰着安卓系统的架构师和开发者们,且目前还没找到特别好的解决办法。
AIDL
没有安卓开发经验的同学可能会对这个词比较陌生,大家可以简单理解为一个数据传输协议,类似于protobuf。AIDL是我见过的工程性设计最差的数据传输协议,它简直是所有安卓系统开发者的噩梦,偏偏它又在安卓系统中无处不在。
你能想象一个数据传输协议,它的序列化/反序列化逻辑需要工程师手写、不保证向前兼容、一个类型有多种不同的序列化方式吗?
一个设计良好的数据传输协议,比如protobuf,我们定义一个类型之后,这个类型的序列化/反序列化实现代码都可以通过工具生成。但是AIDL并非如此,它需要开发者自己去做这部分工作。比如安卓系统在frameworks/base中定义了一个AIDL类型,那么如果我们想要在 Rust 代码里面通过这个AIDL类型和 Java 代码通信,就需要阅读 Java 源码,分析序列化/反序列化逻辑,然后再在 Rust 侧重新实现一遍。要知道,安卓系统里有几千个AIDL类型。
更加恶心的是,对于同一种AIDL类型,可能会有好几种不同的序列化/反序列化方式。比如FileDescriptor,就有writeFileDescriptor、writeParcelFileDescriptor等几种序列化方法,十分令人头大。
好在 Google 团队也认识到了这个问题的严重性,他们在尝试推动“结构化AIDL”,使用protobuf的方式来规范AIDL的使用,但是安卓系统中还是不可避免地遗留下来大量旧时代产物。
设备碎片化
安卓设备的碎片化是一个老生常谈的问题了。AOSP 是一个开源项目,任意厂商都可以基于它进行修改和发布产品,这就带来了碎片化问题:每个厂商,甚至单个厂商的不同安卓设备产品,都是不同的实现。比如小米的不同型号手机,如小米 17、红米等,每一个发布机型都可能对应一条单独的代码分支。
甚至,芯片型号也会带来代码分支差异。理论上,参考 Linux Kernel 的最佳实践,硬件差异应该由硬件抽象层抹平,抽象层之上的代码不应该区分硬件平台。但是国内的大部分安卓厂商不是这么做的,他们会通过代码分支区分平台,而每个平台的实现代码又各不相同。
设备碎片化会导致:
- 代码维护成本高:工程师需要维护大量分支的代码,而每当发布一款新产品,分支数量都会增加;
- Bug 无法收敛:一个型号上的 Bug,可能在另一个型号上也存在,但是由于代码分支太多,每个分支的代码都有差异,难以将所有分支的 Bug 都修复;
- 测试成本高:测试工程师需要负责大量型号手机的测试,但是国内手机厂商普遍没有在测试上投入过多人力,导致测试质量非常差。
大家也许能理解为什么安卓手机的 Bug 数量相较于 iPhone 手机要多得多了。
手机厂商在 AI 浪潮中的机遇
上面聊了很多技术相关的话题,这里放松一下,聊一些非技术向的内容。相信大家也都能感受到,自从 ChatGPT 问世以来,各种大模型、Agent 应用如雨后春笋般涌现,以 Claude Code 和 OpenClaw 为首的 Agent 产品打开了人们对 AI 的幻想:原来能让大模型帮我们做那么多事情,似乎科幻小说中描述的时代已经到来。傻子都能知道这是下一个风口,OpenAI 的估值已经到了 4000 亿美元,足以比肩坐拥微信、QQ、王者荣耀等多款爆品的腾讯帝国。
那么在这个 AI 浪潮中,手机厂商的机会在哪里呢?这个想法源于字节跳动发布的“豆包手机”。豆包手机在操作系统层面融合了大模型能力,用户不需要手动操作手机,只需要向豆包发布指令,即可完成订酒店、购物和点外卖等操作(当然短视频还是得自己刷^_^)。举个点外卖的例子,手机系统中内置的 Agent 会帮你点击和浏览应用界面,查看评分、多平台比价,并根据用户口味做选择,用户只需要进行最终的支付确认即可。
这就是手机厂商的机遇。纵观中国互联网行业的发展,所有产品(包括微信、抖音、支付宝等)的最终目的都是争夺流量入口。一开始互联网的流量入口是浏览器,于是百度是国内最强互联网企业;后来移动互联网兴起,微信成了大家日常使用最频繁的软件,于是成就了腾讯帝国;再后来短视频火爆全球,靠着抖音和 TikTok,字节跳动一跃成为全球顶尖企业。争夺流量入口是所有互联网企业背后的底层逻辑。这也解释了为什么微信、支付宝等产品大力推行小程序,因为如果它能做到“在一款应用内部即可打开另一个应用”,就相当于“偷”走了那款应用的一部分流量。而许多产品如百度网盘、美团会反复推荐大家下载客户端,也是一样的道理:不希望自己的流量被“偷”走。
豆包手机的形态,相当于将流量入口挪到了手机操作系统。想象一下,用户通过豆包手机的这种方式去点外卖,那么最终是在美团上点,还是在京东上点,点哪家外卖,是谁决定的?是操作系统,或者说是手机厂商。因为要实现类似豆包手机的功能,没办法通过写一个 App 来实现,必须改系统代码,在系统框架层实现,这个能力只有手机厂商有。否则字节就不会为了实现豆包手机,而大费周章地和 nubia 合作了。在将来,如果华为或者小米公司推出类似豆包手机的产品,那么很大程度上美团、京东这类互联网企业的生命线就会落到手机厂商手中:要想让我们的 Agent 优先推荐你们平台的外卖,那就交钱吧。谁交的钱多我就多偏向谁。
当然,这很有可能是手机厂商的最终幻想:美团、京东等互联网公司可以推出反 AI 政策,通过各种手段防止用户通过 Agent 来点外卖;从市场角度看,小米、OPPO 这类手机厂商的市值远低于一线互联网大厂,竞争上处于劣势;手机厂商普遍缺少自研大模型的底蕴和实力,如果需要通过第三方大模型服务来实现,那么最终流量入口可能会落在大模型厂商手里,而不是手机厂商手里。
成为技术专家的路上,什么是我们应该关注的
在小米,有幸与很多真正意义上的“技术专家”共事。在和他们的沟通中,我感受到了一些区别于“业务专家”的特质,同时也逐渐拼起了自己成为技术专家所需要的图景。
- 随时准备好迎接被“挑战”
毕业后第一年在飞书工作,这是一个偏业务的团队,我经常能听到类似的对话:
A 同学:“这块代码是不是可以再优化下,降低锁竞争的开销?”
B 同学:“可以是可以,但是这部分代码的并发量不高,优化的收益不大。我还有其他需求要赶,就先这样吧。”
先叠个甲,B 同学的做法完全没问题,在字节飞书这种高压的环境下,能按时交付,并且没有严重 Bug,就已经非常优秀了。
但是我想说的是:我们写的每一行代码,每一个技术决策,都可能被别人挑战:设计不优雅、实现不是零成本抽象、不符合编程语言规范。如果我们想要成为技术专家,就必须为每一行代码、每一个技术决策负责,要么做到极致,让别人没有挑战的余地,要么就接受平庸的事实,忍受被挑战的滋味。
“你可以主张某个不好的设计在业务场景里影响不大,我不会说你做得不好,但会觉得你很菜。”
- 不断提高自己的认知水平
技术专家和一般技术人员的主要区别在于认知水平的高低。如何理解?
对于一项技术,能做到学会并熟练应用,即可被称之为技术人员。
在此基础上,能主动了解这项技术的背景、理解它要解决的问题、系统性地指出这项技术的优势、缺陷和适用场景,并准确判断它在行业中的价值,则是技术专家的职业素养。
在 AI 时代,我认为某个个体的知识已经不再关键,但是技术专家的认知水平,仍然是非常稀缺的人才资源。AI 能帮我们实现某个技术细节,但是架构上的思考、价值的判断以及方向的决策,依然需要依靠人类的智慧。
- 需要有技术上的自信和坚持
人的社会性导致了等级制度的产生,等级制度也反过来规范和约束了人的社会性。在工作中,我们不可避免地会与自己的上级产生意见上的冲突。当发生技术上的意见冲突时,一般技术人员会选择顺从上级或者领导的意见,而技术专家会坚持自己的想法,并给出专业的论证。事实上,技术专家的核心价值是给企业提供专业、独到的技术见解。当我们认为一件事情是对的时,向管理者解释清楚,并引导他们作出正确决策,比一味顺从更能体现自己的价值。
为什么离开小米去创业
很简单,想要继续站在“时代中心”。
说是蹭热度也好、跟风也好,我都接受。我个人性格上,还是喜欢做一些前沿的东西。我在小米发展得不错,虽然资历尚浅,但我有信心说自己是架构团队的绝对核心。做手机操作系统是一个不错的选择,但是毕竟 Google、苹果和华为公司已经在这个领域深耕了多年,我们能做的东西最多也就是优化一下性能,或者走他们的老路继续开创一个新生态,都是相对确定的事情。
但 AI 不一样,这个行业还在非常早期的阶段,存在非常多的“未知”和“幻想”。我今年 26 岁,过完生日就 27 岁,希望在这个最好的职业生涯阶段,投入到一段充满“剑与魔法”(剑=工程技术,魔法=大模型)的冒险中,去讨伐一个不存在的魔王。结果不重要,只要过程不无聊即可。
“夢は逃げない、逃げるのはいつも自分だ。”
著者: SKTT1Ryze
リンク: https://ccc.neos.moe/2026/05/22/xiaomi/
この文章は CC BY-NC-SA 4.0 に基づいてライセンスされています。転載の際は原著者と出典を明記してください。