|
2016年,Docker的容器调度器从Python重写为Go,性能提升了近10倍。这个决定不是拍脑袋——Docker创始人Solomon Hykes后来在访谈里说,他们需要处理海量并发连接,Python的GIL成了天花板,而Go的goroutine让每台机器能轻松扛住几十万个并发任务。这是Go最直接的用途:写高并发、高吞吐的服务端程序。 你每天用的东西,背后大概率跑着Go代码。Docker、Kubernetes、etcd、Prometheus——云原生基础设施这一整条技术栈,Go几乎是默认语言。Kubernetes有超过400万行Go代码,这不是因为它时髦,而是因为它需要同时管理成千上万个容器状态,Go的并发模型和垃圾回收机制刚好对路。 网络编程是Go的看家本领。标准库里的net/http直接能撑起一个生产级HTTP服务,不需要引入任何第三方框架。写一个能抗住压测的Web服务,代码量可能只有Java的三分之一。字节跳动早期的推荐API网关用Go重写后,单机QPS从几千涨到了几万。这不是语言魔法,是goroutine调度器把I/O等待时间榨干了。 但Go不只活在服务器里。Dropbox用Go重写了他们的同步引擎核心模块,因为原来的Python版本在百万级文件同步时内存暴涨。Go的编译速度快得离谱——一个中型项目从改代码到跑起来,通常不超过3秒。这种即时反馈让开发体验很舒服,尤其对比C++那种改一行等十分钟的节奏。 命令行工具也是Go的舒适区。Hugo静态网站生成器用Go写,能在几百毫秒内渲染完一个几千页的站点。GitHub CLI、fzf、lazygit这些开发者日常工具都是Go产物。编译出来就是一个静态二进制文件,扔到任何Linux机器上就能跑,不用装运行时。运维脚本用Go写,比Shell可靠,比Python部署简单。 有人拿Go写数据库。CockroachDB、TiDB、InfluxDB——这三个分布式数据库都是Go实现的。TiDB要处理跨节点事务和Raft一致性协议,Go的channel和select机制让这些复杂逻辑的表达清晰了很多。当然有人吐槽Go的泛型来得太晚,但写基础设施的人更在意可维护性,不是语言特性多炫。 嵌入式领域Go也开始冒头。TinyGo编译器能让Go跑在微控制器上,内存占用压到几十KB。有人拿它写无人机飞控、写键盘固件。虽然生态还远不如C,但至少证明了Go的运行时不是只能活在服务器里。 机器学习不是Go的主场,但推理环节它有用武之地。TensorFlow有Go绑定,ONNX Runtime也能在Go里调。实际场景是:你用Python训练模型,然后用Go写一个高并发的推理服务,避免Python GIL在并发请求下的性能塌方。Uber的Michelangelo平台就大量用Go做特征服务。 区块链项目也爱用Go。以太坊的Geth客户端、Hyperledger Fabric、Cosmos SDK——全是Go写的。原因差不多:需要处理P2P网络、需要并发执行交易、需要跨平台部署。Go的go-ethereum库几乎是链上交互的默认选择。 说点个人观察。Go的代码风格争议很大,if err != nil写多了确实烦。但换个角度,这种显式错误处理逼着你在每一层想清楚失败路径。大型项目里,这种笨拙反而降低了调试成本。我见过一个团队从Node.js迁到Go,bug率降了一半,不是因为Go更安全,是因为编译期就把类型问题拦住了。 Go不是银弹。写GUI很痛苦,写科学计算不如Julia,写脚本不如Python灵活。但如果你要构建一个需要长期维护、多人协作、部署在Linux服务器上的网络服务,Go的取舍恰到好处。它不追求让所有人满意,只服务好那一类问题:并发、网络、基础设施。 Google内部有个说法:Go是“少即是多”的语言。25个关键字,没有继承,没有异常,没有宏。这种克制让代码库在三年后还能被新人看懂。技术选型到最后,往往不是选最强的,是选最不容易出错的。 |