标签 Unix 下的文章

“无聊”设计的终极奥义:为什么“做可能奏效的最简单的事”是最高法则?

本文永久链接 – https://tonybai.com/2025/08/31/the-simplest-thing-that-could-possibly-work

大家好,我是Tony Bai。

在我们解读了Github工程师Sean Goedecke关于“无聊即可靠”的系统设计API设计理念之后,他再次带来了一篇精彩的的文章——《Do the simplest thing that could possibly work》。这既是对前两篇文章思想的延续,更是将其核心哲学提炼为一条终极黄金法则:在软件设计的每一个环节,都应“做可能奏效的最简单的事”。

这条法则,在今天这个充斥着“无限扩展”、“优雅分布式”、“完美分层”等宏大叙事的时代,显得尤为重要。Goedecke认为,工程师们最大的误区,就是试图一开始就设计出那个“理想”系统,而忽略了当下最核心的问题。

本文将继续和大家一起来深入剖析Goedecke这篇文章,领略其提出法则的真谛,探讨它如何帮助我们对抗软件工程中三大根深蒂固的敌人:对“大泥球”的恐惧、对“简单”的误解,以及对“未来扩展性”的过度痴迷。对于追求务实与高效的Go开发者来说,这套思想武器库,无疑是构建健壮、可维护系统的最佳指南。

核心法则:先深入理解,再做最简单的事

Goedecke的核心论点可以概括为两步:

  1. 花时间去深度理解当前的系统和需求。
  2. 然后,做那件能够解决当前问题的、最简单的事。

这与许多工程师的直觉相悖。我们总是被教导要“高瞻远瞩”,要设计一个能够应对未来各种可能性的“完美”架构。但Goedecke认为,这恰恰是通往失败的错误路径。

让我们以他文中的Go应用场景为例:为一个现有的Go服务添加限速功能。

  • “理想系统”思维:马上想到引入Redis,实现一个精巧的“漏桶算法”,构建一套独立的、可水平扩展的速率限制微服务。这套方案技术上无懈可击,充满了“工程美感”。
  • 作者的“极简工作法”思维
    1. 最简单的一步是什么? 检查一下我们正在使用的边缘代理(如Nginx, Envoy)是否已经内置了速率限制功能?也许只需要几行配置就能解决问题。
    2. 如果不行,次简单的一步是什么? 能否在应用内存中维护一个计数器?“可是重启会丢失数据!”——那么,丢失这些数据对业务的实际影响是什么?真的那么致命吗?
    3. 如果还不行,再下一步呢? 如果数据不能丢失,且服务是多实例部署,那么引入外部依赖(如Redis)才成为那个“能奏效的最简单的事”。

这个思考过程的精髓在于,它强迫我们不断地质问自己:“真的有必要吗?” 直到我们确认,更复杂的方案是解决当前真实存在的约束的唯一途径时,才去实施它。这正是极限编程中“YAGNI”(You Ain’t Gonna Need It)原则的终极体现。

“简单”的真谛:少即是多,平庸即伟大

一个普遍的现象是,初级工程师热衷于使用他们新学会的各种工具——数据库、缓存、消息队列、代理——来构建复杂的系统,并在白板上画出纵横交错的箭头,这让他们感觉像在做“真正的工程”。

然而,软件设计的精髓,如同武学大师的境界,在于学习何时做得更少,而非更多

Goedecke指出,伟大的软件设计往往看起来平庸无奇(underwhelming)。它不会让你惊叹于其复杂精巧的结构。相反,当你面对一个伟大的设计时,你通常会感到惊讶:“哦,原来这个问题这么简单?”或者“太好了,我们实际上并不需要做那些复杂的事情。”

Unicorn web服务器是伟大的设计,因为它利用了Unix进程这一极其“无聊”但无比可靠的原语,就解决了请求隔离、水平扩展和崩溃恢复等核心问题。标准的Rails REST API是伟大的设计,因为它用最枯燥的方式,完美地满足了CRUD应用的需求。

对三大反对意见的深刻辩驳

当然,“做最简单的事”这一法则总会面临三个经典的质疑。Goedecke对这些质疑的回应,构成了文章最精彩的部分。

1. 反对意见一:“这难道不会导致‘大泥球’(Big Ball of Mud)吗?”

“做最简单的事”听起来像是鼓励走捷径、写“hack代码”。我们都见过那种由无数“hack”堆砌而成的、无法维护的“大泥球”系统。

Goedecke的反驳: “Hack”代码根本不简单!
- “Hack”只是“更容易想到”:一个临时的补丁或权宜之计,通常是我们能最快想到的方案,但这并不意味着它是最简单的。
- “Hack”增加了系统的认知负荷:每一个“hack”都为代码库引入了一个需要被“特殊记忆”的例外。随着“hack”的增多,系统的整体复杂性是在增加,而非减少。
- 真正的“简单”方案需要深度思考:找到一个正确的、优雅的修复方案,往往需要对系统有更深入的理解,并探索多种可能性。这个“正确的修复”通常比“hack”本身要简单得多。

结论:做“最简单的事”不是放弃工程,恰恰相反,它要求我们投入更多的精力去做真正的工程设计,以找到那个最根本、最简洁的解决方案,而不是用一个又一个复杂的“补丁”去掩盖问题。

2. 反对意见二:“‘简单’的定义是什么?这难道不是一个空洞的同义反复吗?”

如果“最简单”就等同于“好设计”,那么“做最简单的事”不就等于说“做好设计”这句废话吗?

Goedecke借鉴了Rich Hickey在著名演讲《Simple Made Easy》中的思想,对”简单“给出了一个直观的定义:

  1. 更少的“活动部件”:一个简单的系统,是你需要同时思考的东西更少的系统。
  2. 更低的内部耦合:一个简单的系统,是由具有清晰、直接接口的组件构成的。

基于这个定义,他给出了一个实用的决断法则简单的系统更加稳定。

如果在两个方案之间抉择,一个方案在需求不变的情况下需要持续的维护、监控和干预(比如部署和维护一个Redis集群),而另一个则不需要,那么后者就是更简单的。

因此,对于Go的速率限制例子,内存方案比Redis方案更简单,因为它减少了外部依赖、监控需求和部署复杂性这些“活动部件”。

3. 反对意见三:“难道我们不应该构建可扩展(scalable)的系统吗?”

这是来自大型科技公司工程师最常见的呐喊:“内存限流根本无法扩展!”

Goedecke的反驳: 对“扩展性”的痴迷,是SaaS工程领域最大的原罪。

  • 过早的扩展性设计通常是无效的:你无法准确预测一个非凡系统在流量增长几个数量级后,瓶颈会出现在哪里。为遥远的未来进行过度设计,往往是在解决一个根本不存在或被错误预测的问题。
  • 过早的扩展性设计会使代码库僵化:为了所谓的“独立扩展”,你可能会过早地将一个单体服务拆分为多个微服务。这引入了网络通信、分布式事务等一系列极其困难的工程问题,使得实现某些功能变得异常艰难。“我见过很多次这种拆分,但真正从中受益的,可能只有一次。”
  • 务实的扩展策略:最多为当前流量的2倍或5倍做准备。然后,保持系统的简单和灵活,以便在真正的瓶颈出现时,能够快速地识别和解决它。

在Go社区,我们经常看到关于“单体 vs 微服务”的讨论。Goedecke的观点为我们提供了清晰的指引:保持单体的简单性,直到拆分的必要性变得无可辩驳。 一个设计良好、简单的Go单体应用,其扩展能力远超大多数人的想象。

小结:拥抱当下,而不是预测未来

Goedecke在文末总结道,软件开发有两种基本方式:

  1. 预测未来:预测半年或一年后的需求,并为此设计一个“最佳”系统。
  2. 拥抱现在:为当前已知的、真实的需求,设计一个“最佳”系统。

他悲观地认为,我们人类作为一个集体,预测系统未来走向的能力非常有限。我们甚至很难完全理解一个系统当前的状态。因此,第一种方式往往导致糟糕的设计。

唯一的理性选择是第二种:做那个可能奏效的、最简单的事

这要求我们放弃作为工程师的某种虚荣心,不再追求构建那些看起来“令人印象深刻”的复杂系统。相反,我们应该拥抱“无聊”,致力于创造那些看似平庸,却异常健壮、稳定且易于理解和修改的系统。

这,或许就是从“优秀”走向“卓越”的工程师,其设计哲学的终极奥义。


想系统学习Go,构建扎实的知识体系?

我的新书《Go语言第一课》是你的首选。源自2.4万人好评的极客时间专栏,内容全面升级,同步至Go 1.24。首发期有专属五折优惠,不到40元即可入手,扫码即可拥有这本300页的Go语言入门宝典,即刻开启你的Go语言高效学习之旅!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

Go 比 Python 更懂“Python 之禅”?

本文永久链接 – https://tonybai.com/2025/07/19/go-understand-the-zen-of-python-better-than-python

大家好,我是Tony Bai。

最近,在国外的 Go 语言社区(Reddit r/golang)上,一个帖子引发了热烈的讨论。标题颇具“引战”意味:“Go似乎比Python更好地实现了Python之禅”。

这听起来像个悖论,甚至有点冒犯。用一个语言的哲学去评判另一个语言,就像用“太极”的理念去评价“咏春”,似乎风马牛不相及。但仔细看完社区的讨论,你会发现这并非无稽之谈,反而是一个极其刁钻又深刻的视角,能帮助我们重新审视 Go 语言设计的底层逻辑。

作为一名在 Go 的世界里摸爬滚打了多年的老 Gopher,我也不止一次有过类似的感觉。今天,我们就借着这场社区热议,一起聊聊这个有趣的话题。

重温“Python之禅”

首先,让我们重温一下那首著名的“Python之禅”(The Zen of Python)。在任何一个 Python 解释器里输入 import this,你都能看到它:

The Zen of Python, by Tim Peters
Python之禅,作者:蒂姆·彼得斯

Beautiful is better than ugly.
优美优于丑陋。

Explicit is better than implicit.
显式优于隐式。

Simple is better than complex.
简单优于复杂。

Complex is better than complicated.
复杂优于繁杂。

Flat is better than nested.
扁平优于嵌套。

Sparse is better than dense.
稀疏优于密集。

Readability counts.
可读性至关重要。

Special cases aren't special enough to break the rules.
特例不足以特殊到足以打破规则。

Although practicality beats purity.
虽然实用性胜过纯粹性。

Errors should never pass silently.
错误绝不能悄无声息地被忽略。

Unless explicitly silenced.
除非显式地使其沉默。

In the face of ambiguity, refuse the temptation to guess.
面对歧义,拒绝猜测的诱惑。

There should be one-- and preferably only one --obvious way to do it.
应该有且最好只有一种显而易见的实现方式。

Although that way may not be obvious at first unless you're Dutch.
虽然这种方式一开始可能并不那么明显,除非你是荷兰人。

Now is better than never.
现在优于永不。

Although never is often better than right now.
虽然,永不去做常常比“马上”动手要好。

If the implementation is hard to explain, it's a bad idea.
如果实现很难解释,那么它是个坏主意。

If the implementation is easy to explain, it may be a good idea.
如果实现很容易解释,那么它可能是个好主意。

Namespaces are one honking great idea -- let's do more of those!
命名空间是个绝妙的主意——让我们多多地使用它吧!

这不仅仅是代码风格指南,更是一种编程哲学的宣言。而奇妙的是,当我们手握 Go 这把锤子时,会发现很多钉子恰好就是按照这份宣言的图纸来设计的。

“显式优于隐式”:Go 的灵魂,Python 的妥协

这是“Python之禅”中最核心的信条之一,也是 Go 语言最引以为傲(或被吐槽)的特征所在。

想想 Go 语言里最经典的 if err != nil。新手可能会觉得它繁琐、重复,破坏了代码的流畅性。但在经验丰富的工程师眼中,这正是“显式”的极致体现。每一次函数调用,你都被迫直面其可能失败的现实,错误处理的路径清晰得如同一条直线,没有任何隐藏的控制流跳跃。

相比之下,Python 的 try…except 机制虽然优雅,却在某种程度上是“隐式”的。一个 try 代码块里可能有多行代码,任何一行都可能抛出异常,然后被远处的某个 except 捕获。这使得控制流变得不再那么一目了然。一位 Reddit 用户评论说:“自从我见过那些数据科学代码后,‘显式优于隐式’这条让我笑出了声。” 这虽然是句玩笑,却精准地指出了在复杂项目中,隐式处理可能带来的维护难题。

Go 通过把错误(error)设计成普通的值,而不是一个特殊的控制流机制,完美践行了“显式优于隐式”的原则。它是你必须亲手处理的返回值,而不是可以被忽略的“天外来客”。

“简单优于复杂”:Go 的克制与执拗

Go 语言的设计者们(Rob Pike, Ken Thompson 等)深受 Unix 哲学的影响,对“简单”有着近乎偏执的追求。

  • 语法克制:Go 只有一个循环关键字 for,没有 while 或 do-while。它没有类和继承,取而代之的是更纯粹的组合与接口。并发模型也异常简单——go 关键字启动一个 goroutine,chan 进行通信,大道至简。
  • 工具统一:gofmt 的存在,终结了所有关于代码格式的“圣战”。它体现了“Python之禅”中的另一条原则:“应该有且最好只有一种显而易见的实现方式”。在 Go 的世界里,代码风格不是一个需要讨论的问题,这极大地降低了团队协作的认知负荷。

反观 Python,随着其生态的繁荣和应用领域的扩张,语言本身不可避免地变得越来越复杂。从最初与 Perl、PHP 竞争的简洁脚本语言,到如今涵盖 Web 开发、数据科学、AI 的庞然大物,它引入了 async/await、复杂的元编程能力等。这并非坏事,而是语言成熟和演化的必然结果。但与诞生之初就目标明确(解决 Google 内部大规模工程问题)的 Go 相比,Python 在“保持简单”这条路上,显然背负了更沉重的历史包袱。

客观看待:Go 的“禅意”并非没有代价

当然,我们不能一边倒地吹捧。Reddit 的讨论中也充满了理性的声音。Go 为了实现这种“禅意”,也付出了相应的代价。

  • “优美优于丑陋”(Beautiful is better than ugly):美是主观的。很多人认为 Go 的语法过于朴素,if err != nil 更是“丑陋”的代名词。但正如一位评论者所言:“我喜欢它,正是因为它在美学上很中庸(aesthetically mid)。” Go 的美,更多是一种“工程之美”,是结构清晰、易于维护、性能可靠的美,而非语法糖堆砌出的“华丽之美”。
  • “模板代码”(Boilerplate):Go 的“显式”和“简单”,直接导致了更多的模板代码。这是为了可读性和可维护性做出的权衡。社区也意识到了这一点,因此 Go 在泛型等方面的引入,以及强大的代码生成工具生态,都是在弥补这一“短板”。

小结:源于血脉的哲学共鸣

那么,为什么 Go 会比它的“老师” Python 更像一个“禅宗信徒”呢?

答案可能在它的“血脉”里。Go 的设计者们是创造了 C 语言、Unix 和 UTF-8 的传奇人物。他们骨子里流淌的是系统编程的血液,追求的是在数十、上百乃至上千工程师协作的大型项目中,如何保证代码的长期可读性、可维护性和稳定性。

这种背景决定了 Go 的设计哲学必然倾向于:明确、简单、组合、正交

它不追求用最少的代码行数表达最复杂的逻辑(那是 Python 的强项),而是追求让任何一个中等水平的工程师都能在最短时间内读懂并安全地修改代码。

从这个角度看,Go 并非“碰巧”契合了“Python之禅”,而是它的核心设计目标——工程化与可维护性——恰好与“Python之禅”所倡导的清晰与简洁产生了深刻的共鸣。可以说,Go 是在用一种更底层、更工程化的方式,对“Python之禅”进行了重新演绎。

所以,回到最初的问题:“Go 比 Python 更懂‘Python之禅’吗?”

或许,更准确的说法是:Go,在它所专注的领域里,以一种更为决绝和纯粹的方式,活成了“Python之禅”希望的样子。

对此,你怎么看?欢迎在评论区留下你的想法。

资料链接:https://www.reddit.com/r/golang/comments/1m302i6/go_seems_to_accomplish_the_zen_of_python_way


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats