一切都是历史和地域因素使然。

Go / Rust 兴起于字节崛起之前。在那个时间段,互联网公司主体业务的编程语言大体分布是这样的:
- 北京:以百度、滴滴、美团(早期做团购时)为代表的 PHP / C++ 流派
- 深圳:以腾讯为代表的 PHP / C++ 流派
- 杭州:以阿里为代表的 Java 流派
- 上海比较繁杂,陆家嘴搞金融、P2P 相关的 Java 派,还有各大厂在上海的分部,搞什么的都有
这也跟人才流动有很大的关系。阿里早年偏居杭州一隅,而新兴大厂滴滴、美团、字节都在北京发家,人才大多来自百度、腾讯北分、360 等等,从而奠定了早期的技术架构。
再往前追溯,其实是 C++ 与 Java 的竞争。只不过后来 PHP 的火爆让以开发效率至上的国内 C++ 大厂纷纷入局,用 PHP 来重写业务层,C++ 则实现一些底层服务(例如存储、中间件等)。甚至做了 SOA 之后,还有一部分半业务半服务模块也用 C++ 实现。
所以这个阶段你在百度、腾讯等公司能看到 PHP 代码中有浓厚的 C++ 风格。此时是 PHP 5 时代,虽然引入了 OO,但还未形成足够的 OO 编程范式,并未被广泛应用,大家仍将 PHP 当作纯脚本的方式使用。这个时候 PHP 的框架百花齐放:CodeIgniter、ThinkPHP、Yii 等等。
为什么 Java 大厂不入局 PHP?因为 C++ 本身的确有繁琐易错的内存管理,开发效率低,debug 耗时长等问题,而 Java 其实很大程度上已经解决了。Java 开发效率介于 C++ / PHP 之间,就有些纠结了:要迁移吧也有不少成本,收益也没有那么大。更重要的是 PHP 本身就是 C 系语言,甚至很多人称之为一个 C 框架——从 PHP 的各种函数命名上就能看出来,包括下划线函数、偏面向过程的使用方式,尤其是支持以 C / C++ 编写扩展来扩充使用场景,这些无不更加适合原本就使用 C/C++ 的大厂。
并且随着时间再推进,Spring 的日渐进化尤其是 SpringBoot 的出现,令 Java 的开发与部署效率也得到了极大进步。此时反观 PHP 7+ / Laravel 却是日渐向着 Java 发展,Laravel 也逐渐成为了 PHP 领域的 Spring。此时对于 Java 大厂而言就更没必要转型了。
这里不做过多编程语言之争,没有结论也不切题。从结果上看,PHP 加 C++ 与 Java 都能完整且较好地实现所有业务功能,且在开发效率与性能上达到一个平衡。
而 Go 的出现,其实就是进一步蚕食 C++ 的地位:接近 Java / PHP 的开发效率,接近 Java / C++ 的运行效率。这导致各大 PHP / C++ 生态的大厂又开始引入 Go——不仅是字节,百度、腾讯、美团、滴滴等大厂都在引入。无非是用 Go 替代一些业务层中偏固定、偏下层的业务,替代一些系统层中偏上层的服务。再就是逐步跨入云时代之后的 Docker / K8s 等相关业务。
Java 大厂为什么不大量引入 Go?Java 本身就是一门非常通用的语言,从前到后、从中间件到大数据、从业务 API 到安卓,无不能胜任。还是类似当时 PHP 的问题一样:从 Java 切到 Go,收益不够大,成本不够低。Go 几乎没有 OO 的设计理念,也是一个 C 系语言,从 Java 切换有巨大的编程方式转变,同时带来的内存消耗等收益对于大厂来说不值一提。再加上这十几年的 code base 积累,切换谈何容易?这种级别的积累,除非出现一门颠覆性的语言——比如开发效率和运行效率都高出 Java 一个数量级——才有可能引起重视。
这里插一句:开头我强调了是主体业务的语言应用。实际上对于大厂而言,哪个大厂不是啥语言都用的?BAT / TMD 都有 Java,都有 PHP,都有 C++,都有 Go,也都有 Rust,只是体量占比不同而已。做大数据基本离不开 Hadoop 生态,做底层存储、云计算基本离不开 C++。以阿里为例,最早也是 PHP,后来转 Java 这个就不说了;后来收购的虾米等也都是 PHP 的;阿里做云原生也有不少 Rust。但这些都影响不了大厂整体的技术基调。
再说 Rust,其实是 C++ 的平替,适合也仅适合替换 C++,因此本身在当前互联网大厂的适用场景就已经被压缩到很小了。那么对于传统的底层已经用 C++ 写好的大厂来说,替换为 Rust 的性价比太低、风险又大,很多模块还涉及到数据。
至于字节,因为最年轻,选型上没有系统包袱。字节的人才也大多来自原先北京帮的百度、美团、滴滴、360 之间互相流动,本身就是 PHP / C++ 的背景,选择 PHP/Python + Go 作为主力技术栈无可厚非(随着 PHP 日渐式微,后来新业务也基本全是 Go 了)。而 Rust 也可以用来实现很多新业务、新场景的底层模块,比如飞书客户端的通讯层应该就是 Rust 的。
说了那么多,其实无非就是:历史包袱、人员构成、迁移成本、迁移收益。
再补充说说历史包袱这件事。
之前有本书叫《淘宝技术这十年》,讲过这个故事:一开始淘宝是用 PHP 做的,后来用户量越来越大,PHP 顶不住了,于是淘宝就找人改成了 Java,甚至邀请了 Sun 的原厂支持。
后来 Oracle 数据库也顶不住了。Oracle 解决不了淘宝的亿级用户并发访问,原话是:"你这个需求,整个太阳系只有你需要。"倒逼淘宝去 IOE。
那个时候还是电脑时代,智能手机还没有普及。于是 Java 技术栈就一直用到了现在。
淘宝的业务需求是高并发。涉及大量资金交易,不容有失。抖音视频推荐可以胡乱推荐,即使推荐的视频不是你喜欢的也无所谓;但淘宝购物的购物车金额计算和支付宝转账金额差一块钱,客户能当场原地爆炸。
解释一下这个"亿级用户并发访问":指的是每天中午十二点的时候,有几千万人吃饱了没事干,上淘宝瞎看,而且啥也不买。每一个人的收藏夹里面有上百个商品,相当于同时有几亿甚至几十亿条数据被同时访问。这种功能,使用传统的关系型数据库例如 Oracle 根本无法实现,必须使用非关系型数据库,例如 Redis。
这个事情,还曾经给马老师气得不行。马老师说,这帮人就看,就看,就看,啥也不买,啥也不买,啥也不买,搞得服务器压力非常大。
类似的大厂技术选型与历史包袱话题,云栈社区上也常有讨论,感兴趣可以上去翻翻。