- 文档
- 知识库
- 教程
【免费下载链接】hacker-laws
🧠 Laws, Theories, Principles and Patterns for developers and technologists.
hacker-laws 是一个面向开发者与技术从业者的开源参考仓库,系统整理了软件工程领域中人们常挂在嘴边的"定律、理论、原理与模式",其法语译本 translations/fr.md 是内容最完整的本地化文档之一。本文以该法文译本为骨架,逐条精读其收录的 28 条定律与 17 条原则,并结合仓库配套资源(图解、eBook 生成脚本)进行深化讲解,帮助你在架构设计、代码评审、团队管理与技术决策中准确理解并使用这些经典概念。
项目概览:hacker-laws 是什么
hacker-laws 的英文 README(README.md)将其定位为"开发者和技术从业者会发现的定律、理论、原理与模式"集合,而法语译本 translations/fr.md 完整继承了这一脉络:从计算性能(阿姆达尔定律、摩尔定律)到组织管理(布鲁克斯定律、彼得原则),从分布式系统(分布式计算的八条谬误)到面向对象设计(SOLID),再到沟通协作(惠顿定律、坎宁安定律),覆盖面极广。
需要特别强调的是,仓库在引言中明确声明:它只是解释这些定律、原理与模式,并不"倡导"其中任何一条。它们是否适用于你的项目,始终是一个值得讨论的问题,且高度取决于你所处的具体工作场景。这是阅读本手册时最重要的前提——所有的定律都是一把"思考的尺子",而不是必须遵守的教条。
仓库的配套资产
除了核心文档,仓库还提供了若干配套资源:
- 图解资产:
images/目录下存放了阿姆达尔定律、炒作周期、菲茨定律(Fitts' Law)与希克定律(Hick's Law)等示意图; - 网站页面:
assets/site/目录包含多版首页(index.html、index2.html 等),说明项目同时维护着 Web 呈现; - eBook 生成脚本:
scripts/prepare-markdown-for-ebook.sh可将 README 加工为带 YAML 元数据(title、author、subtitle、version)的电子书 Markdown,并通过sed清理 emoji、翻译区块等内容。
从脚本用法可以看出项目的发布流程:以./scripts/prepare-markdown-for-ebook.sh README.md hacker-laws.md的形式调用,要求设置VERSION环境变量,并用DATE(缺省为当天日期)填充版本信息。
第一部分:定律(Lois)
定律部分收录的是软件工程世界中关于"不可避免的现实"的观察与论断。以下逐条精读。
阿姆达尔定律(Loi d'Amdahl)
阿姆达尔定律是一个展示计算任务"潜在加速比"的公式:通过增加系统资源所能获得的加速,受限于程序可被并行化的程度。它通常用于并行计算领域,可预测增加处理器数量的实际收益。
用一个经典例子说明:假如一个程序由两部分组成——部分 A 必须由单个处理器串行执行,部分 B 可以并行化——那么给系统增加多个处理器只能带来有限的收益:它可能大幅加速部分 B,但部分 A 的速度丝毫不会改变。
图中可以清楚看到:一个只有 50% 可并行化的程序,在超过 10 个处理单元之后几乎不再获益;而 95% 可并行化的程序,即使使用超过一千个处理单元,仍能获得显著的加速提升。
在 摩尔定律 趋缓、单核处理器频率提升放缓的当下,并行化成为性能改进的关键。图形编程就是绝佳的例子——基于现代 Shader 的渲染计算中,每个像素或片元都可以独立并行渲染,这正是现代显卡动辄拥有数千个计算核心(GPU / Shader Units)的原因。
实践启示:做性能设计时,先评估代码中可并行化与必须串行的部分,再决定投入多少资源做并行化改造——盲目堆核数对串行瓶颈毫无帮助。
关联阅读:布鲁克斯定律、摩尔定律。
破窗理论(Théorie de la vitre brisée)
破窗理论认为:环境中可见的犯罪(或无人照料的痕迹)迹象,会诱发更多、更严重的犯罪(或环境的进一步恶化)。
这一理论被移植到软件开发中:低质量的代码(或者说技术债)会让团队成员产生"改进代码质量的努力不被重视、甚至被完全忽视"的认知,从而放任质量进一步下滑,形成恶性循环,导致代码质量随时间急剧劣化。
实践启示:在代码评审与日常维护中"修好每一扇破窗"——哪怕只是清理一个命名混乱的变量、补上一段缺失的注释,也能传递"质量是被珍视的"信号,遏制熵增。
布鲁克斯定律(Loi de Brooks)
向一个已经延误的软件项目增加人力,只会让它更加延误。
这条定律指出:在很多情况下,试图通过"加人"来加速一个已经滞后的项目,反而会让交付更晚。布鲁克斯本人也明确承认这是一个高度简化,但其背后的推理是:新成员需要磨合期(ramp-up time),同时沟通开销随之增加,因此在短期内团队的交付速度不升反降。更关键的是,很多任务不可分割——无法简单地分配到更多人头上,这进一步压低了潜在的速度提升。
"九个女人无法在一个月内生出一个婴儿"这句广为流传的话,正是对布鲁克斯定律的生动诠释:某些工作本质上不可拆分、不可并行。
这也是经典著作《人月神话》(The Mythical Man Month)的核心主题之一。
实践启示:项目延期时,先诊断瓶颈是"人力不足"还是"任务不可拆分/沟通内耗";加人之前,先评估磨合成本与沟通成本。
康威定律(Loi de Conway)
康威定律认为:系统的技术边界会反映生产它的组织结构。它经常在组织改进的讨论中被引用——如果组织被划分为许多互不相连的小单元,其产出的软件也会是零散的;如果组织围绕功能或服务构建"纵向"的竖井结构,软件系统也会同样呈现这种形态。
实践启示:当你想让软件架构变成某种理想形态(例如微服务)时,往往需要先调整组织结构;"架构追随组织"是设计团队结构与服务拆分时的第一性原理。
关联阅读:Spotify 模型。
坎宁安定律(Loi de Cunningham)
在互联网上获得正确答案的最佳方式,不是提出一个问题,而是发布一个错误的答案。
据 Steven McGeady 回忆,Ward Cunningham 在 1980 年代初对他说过这句话;McGeady 将其命名为"坎宁安定律",尽管坎宁安本人否认这一归属,称其为"误引"。这条定律最初描述的是 Usenet 上的互动现象,如今被广泛用来解释 Wikipedia、Reddit、Twitter、Facebook 等在线社区的运作机制——错误答案会迅速引来纠错者,从而更快地汇聚出正确答案。
实践启示:在技术社区提问时,先摆出自己当前的(可能是错误的)理解,往往能比干巴巴地提问更快获得高质量的纠正与讨论。
邓巴数(Nombre de Dunbar)
"邓巴数是一个人能够同时维持稳定社会关系的最大人数上限"——即一种"知道每个人是谁、以及每个人与其他人的关系"的人际关系。关于具体数字并无统一共识:"……[邓巴]提出人类只能舒适地维持约 150 段稳定关系。"他还给过一个更生活化的描述:"你在酒吧偶遇对方时,不会觉得尴尬而拒绝与对方同桌喝一杯的人数。"学界对数字的估计通常在 100 到 250 之间。
在工程语境中,开发者与代码库的关系就像人际关系一样需要投入精力去维护。面对庞大复杂的项目或同时拥有多个项目时,我们会借助约定(convention)、策略(policy)与标准化的流程(modeled procedure)来规模化。邓巴数不仅在公司规模增长时值得牢记,在设定团队努力的边界、或者决定系统是否该投入工具来建模与自动化后勤开销时同样重要。从工程角度量化,它可以理解为"你有信心加入其 on-call 轮值去支持的项目的数量"(或单项目的归一化复杂度)。
实践启示:为团队划定服务/项目归属时,注意不要让单人或单团队"拥有"超出认知负载的项目数量;工具化、流程化是突破 150 这条"关系上限"的手段。
关联阅读:康威定律。
高尔定律(Loi de Gall)
一个能正常运转的复杂系统,几乎总是从一个能正常运转的简单系统演化而来的。一个从零开始完整设计的复杂系统永远不会运转,也无法靠修补让它运转起来。你必须从一个能运转的简单系统重新开始。 ——(John Gall)
高尔定律意味着:试图一次性"设计"出高度复杂的系统,失败概率极高。高度复杂的系统很少一步到位,而是从更简单的系统逐步演化而来。
最经典的例子是万维网(World Wide Web)。它当前是一个高度复杂的系统,但最初只是被定义为在学术机构之间共享内容的一种简单方式。在成功达成这一目标之后,系统才随时间推移不断变得复杂。
实践启示:不要试图"大爆炸式"地设计复杂架构;先交付一个能跑通核心场景的简单系统,再依据真实需求演化。这与 KISS 原则一脉相承。
关联阅读:KISS 原则。
古德哈特定律(Loi de Goodhart)
任何被观测到的统计规律性,一旦被施加控制压力,就会趋于崩塌。 —— Charles Goodhart
更常见的表述是:
当一个衡量指标变成了目标,它就不再是一个好的衡量指标。 —— Marilyn Strathern
这条定律指出:基于指标(KPI)的优化可能会导致指标本身失去价值。将一套过度精简的指标盲目套用到流程上,会产生扭曲的效果——人们倾向于局部"钻空子"(gaming the system)去满足特定指标,而忽视自身行为对系统的整体影响。
文中的两个具体例子极具代表性:
- 通过编写不做任何断言(assert-free)的测试,可以轻松刷到任意的代码覆盖率——尽管指标的本意是"让软件得到充分测试";
- 用"提交的代码行数"衡量开发者绩效,会导致代码库无意义的膨胀。
实践启示:设定指标时,要时刻警惕"指标反噬"——指标应该服务于目标,而不是取代目标;组合多维度指标、定期审视指标与真实意图的偏差,是缓解古德哈特定律的常用手段。
汉隆剃刀(Rasoir de Hanlon)
永远不要把可以用愚蠢充分解释的行为,归因于恶意。 —— Robert J. Hanlon
这一原则提示我们:导致负面结果的行为,未必源于恶意;更可能的原因是行为本身及其影响没有被充分理解。
实践启示:代码评审、跨团队协作中,先假设对方是"不知道"而不是"故意使坏",能显著降低沟通摩擦,把精力集中在澄清事实与改进方案上。
霍夫斯塔特定律(Loi de Hofstadter)
事情总是比预期花更长时间,即使你已经把霍夫斯塔特定律考虑在内。 —— Douglas Hofstadter
你会在估算某项工作所需时间时听到这条定律。软件开发的常识是:我们非常不擅长估算一个项目的完成时间。这条定律出自《哥德尔、艾舍尔、巴赫:集异璧之大成》(Gödel, Escher, Bach: An Eternal Golden Braid)。
实践启示:在做工期估算时,为不确定性预留缓冲;霍夫斯塔特定律的递归性提醒我们——任何"已经考虑了这条定律"的估算,本身仍然会偏乐观。
赫特伯定律(Loi de Hutber)
改善即恶化。 ——(Patrick Hutber)
这条定律认为:对系统某一部分的改进,会导致其他部分的恶化,或者掩盖其他的恶化,最终从整体上造成系统状态的退化。
例如:降低某个端点(end-point)的响应延迟,可能在更下游引发吞吐量与容量问题,波及一个完全不同的子系统。
实践启示:任何"优化"都要放到全链路去看——局部最优不等于全局最优;上线性能优化前,评估其对下游队列、缓存、限流等环节的连带影响。
技术炒作周期与阿马拉定律(Cycle du hype & Loi d'Amara)
人们倾向于高估一项技术在短期内的影响,而低估它在长期内的影响。 —— Roy Amara
炒作周期(Hype Cycle)是对一项技术随时间推移的吸引力与发展的可视化描述,最初由 Gartner 提出。
用大白话来说:新技术通常会出现一个"兴奋峰值",团队纷纷快速采用并寄予厚望,随后却往往对结果感到失望——可能是因为技术成熟度不足,也可能是因为技术落地的具体场景尚未被充分掌握。经过一段时间后,应用机会与能力增长到足以让团队真正高产。Roy Amara 的名言更简洁地总结了这一点:"高估短期、低估长期"。
实践启示:技术选型时,理性评估新技术所处的周期阶段;把"炒作峰值"与"生产力平台期"区分开,避免在期望膨胀期做出过重的承诺。
海勒姆定律(Loi d'Hyrum,隐式接口定律)
当一个 API 的用户数量足够多之后,无论接口承诺了什么,系统的所有可观察行为都会有人依赖。 —— Hyrum Wright
海勒姆定律描述了这样一个事实:当一个 API 拥有足够多的用户时,API 的所有行为——包括那些并未在公共规格中定义的行为——都会被某些人依赖。一个琐碎的例子是 API 的非功能性表现,比如响应时间;一个更微妙的例子是:有人用正则表达式匹配错误消息来判断错误的类型。即使 API 规格对消息内容只字未提,某些用户仍会依赖这些消息——一旦消息内容变更,对这些用户而言就等同于 API 被破坏。
实践启示:维护公共 API(尤其是大用户量的)时,任何"看似无足轻重"的细节变化(错误消息文案、时序、日志格式)都可能构成破坏性变更;变更前应评估隐式契约,或者主动将关键行为显式化。
关联阅读:泄漏抽象定律、分布式计算的谬误。
克尼汉定律(Loi de Kernighan)
调试代码比编写代码难一倍。因此,如果你在编写代码时已经尽可能地"聪明",那么按定义,你就不够聪明去调试它。 —— Brian Kernighan
克尼汉定律以 Brian Kernighan 命名,源自他与 Plauger 合著的《编程风格要素》(The Elements of Programming Style)中的名句:"人人都知道调试比最初编写程序难两倍。所以如果你在编写时已尽可能狡猾,那你又如何能调试它呢?"
虽然略带夸张,但克尼汉定律论证了这样一个观点:简单代码优于复杂代码——因为复杂代码中出现的任何问题,都将是代价高昂甚至无法调试的。
实践启示:写代码时把"可调试性"作为一等公民;刻意追求精巧(clever)的写法,最终付出代价的往往是调试者(通常就是几个月后的你自己)。
关联阅读:KISS 原则、Unix 哲学、奥卡姆剃刀。
梅特卡夫定律(Loi de Metcalfe)
网络的价值与用户数量的平方成正比。
这条定律基于系统内部"两两之间"连接数量的计算,与里德定律高度相关。Odlyzko 等人提出过反驳:里德定律与梅特卡夫定律没有考虑人类智力的认知极限,因而高估了系统的价值——参见邓巴数。
实践启示:评估平台型、网络型产品(通讯工具、市场、社交网络)时,梅特卡夫定律是解释"网络效应"与"赢家通吃"的理论起点,但也要警惕对规模的盲目信仰。
关联阅读:里德定律、邓巴数。
摩尔定律(Loi de Moore)
集成电路中的晶体管数量大约每两年翻一番。
这条定律常被用来形容半导体与芯片技术演进之快。Moore 的这一预测在 1970 年代至 2000 年代被证明相当准确。不过近年来这一趋势已经放缓,部分原因是元器件微型化触及了物理极限(如量子隧穿效应)。尽管如此,并行化方面的进步,以及半导体与量子计算领域潜在的颠覆性变化,或许仍能让摩尔定律在未来数十年继续"延续"。
实践启示:在"免费午餐"(单核频率提升)终结的背景下,软件性能工程的重心正转向并行、异构(GPU/NPU)与专用硬件;架构选型时不再默认"硬件升级就能解决性能问题"。
墨菲定律 / 索德定律(Loi de Murphy / Loi de Sod)
凡是可能出错的事,就一定会出错。
由 Edward A. Murphy Jr. 提出的墨菲定律指出:如果一件事可能出错,那它就会出错。这是开发者耳熟能详的"公式"——意外总在开发、测试甚至生产环境中不期而至。该定律还可以与英国英语中更常见的索德定律(Sod's Law)联系起来:
凡是可能出错的事,就一定会出错——而且是在最糟糕的时刻。
这些"定律"常以幽默的口吻被使用。然而,认知偏差——例如确认偏差与选择偏差——可能让人们过分重视这些定律(多数时候事情正常运转时我们不甚留意;一旦出问题,它就格外显眼并引发讨论)。
实践启示:墨菲定律的真正工程价值在于"防御性设计"——为失败预留路径(重试、回滚、熔断、降级),把"会出错"当作默认假设,而非小概率事件。
奥卡姆剃刀(Rasoir d'Occam)
如无必要,勿增实体。 —— William of Ockham
奥卡姆剃刀告诉我们:在多个可能的解决方案中,最可能的是那个附带最少概念与前提假设的方案。它最简洁,能在解决问题时不附带引入额外复杂性与潜在的负面后果。
实践启示:方案评审时,"哪个方案引入了最少的新概念/新依赖"是重要的决策维度;奥卡姆剃刀与 YAGNI、精益软件开发中"消除浪费"的思想同源。
关联阅读:YAGNI。
帕金森定律(Loi de Parkinson)
工作会膨胀,直至填满所有可用的完成时间。
在原始语境中,这条定律基于对行政机构的研究。它可以被应用到软件开发项目中:理论认为团队在临近截止日期前会低效运转,然后赶工以赶上期限——这让截止日期变得或多或少有些武断。
如果把这条定律与霍夫斯塔特定律叠加,会得到一个更加悲观的前景:工作膨胀到占据所有可用时间,并且最终仍然比预期耗时更久。
实践启示:帕金森定律是"截止日期设计"的警示——没有明确验收标准的宽松排期,往往会诱发效率下降;反之,把大任务拆成有明确边界的小里程碑,可以对抗时间的"膨胀效应"。
过早优化效应(Effet d'optimisation prématurée)
过早优化是万恶之源。 ——(Donald Knuth)
在 Donald Knuth 的文章《Structured Programming With Go To Statements》中,他写道:"程序员会把大量时间浪费在思考或担忧程序中非关键部分的速度上,而这些追求性能的尝试,在计入调试与维护成本后,实际影响是强烈负面的。我们应该忘掉微小的效率提升,可以说 97% 的情况下:过早优化是万恶之源。然而,我们也不应该放过那关键的 3% 中的机会。"
过早优化也可以更简单地定义为:在还不确定是否需要优化之前就进行优化。
实践启示:先用 Profile 数据说话,再动手优化;把优化投入集中在真实热点(那"关键的 3%")上,而不是在冷路径上雕花。
普特定律(Loi de Putt)
技术被两类人支配:理解自己并不管理的东西的人,以及管理自己并不理解的东西的人。
普特定律常伴随其推论出现:
任何技术层级,迟早都会发展出一种能力倒置(inversion of competence)。
这些论断暗示:由于群体组织方式中的各种筛选标准与倾向,一家技术公司里往往存在两类人——技术上胜任但不在管理岗的员工,以及身处管理职位但对技术复杂性与难度理解不足的管理者。这可以归因于彼得原则或迪尔伯特原则等现象。
需要说明的是,这类定律属于概括(generalizations),只适用于某些组织类型,而非全部。
实践启示:在技术团队中建立"技术决策需由技术负责人背书"的机制,可以在一定程度上对冲管理岗与技术岗之间的能力落差。
关联阅读:彼得原则、迪尔伯特原则。
里德定律(Loi de Reed)
大型网络(尤其是社交网络)的效用,随网络规模的增大呈指数级增长。
这条定律基于图论:网络效用随着"可能形成的子群(sub-groups)数量"而增长。Odlyzko 等人提出反驳:里德定律没有考虑人脑的认知极限,因而高估了网络效用——参见邓巴数。
实践启示:社交型产品、社区型产品的价值不只来自"点对点连接",更来自"可形成的子群体"——这解释了为什么"兴趣小组/圈子"类功能往往带来超线性增长。
关联阅读:梅特卡夫定律、邓巴数。
复杂度守恒定律(Loi de Tesler)
这条定律指出:系统中存在一部分无法被减少的复杂度。
系统复杂度的一部分源于疏忽——不良的结构、错误、或对问题的错误建模所致。这类复杂度可以被削减甚至消除。但另一部分复杂度是内在的(intrinsic),来自问题本身的性质,它只能被转移,而无法被消除。
这条定律最有趣的启示是:即使你把整个系统简化了,内在复杂度并不会消失,而是被转嫁给了用户——由用户来承担这部分补偿成本。
实践启示:API 与产品设计中的"简化",本质上是在系统复杂度与用户复杂度之间做转移决策;承认"复杂度必须存在",才能理性地决定它应该待在系统里还是用户侧。
泄漏抽象定律(Loi des abstractions qui fuient)
所有非平凡的抽象,都会或多或少地泄漏其底层细节。 ——(Joel Spolsky)
这条定律指出:计算机科学中用来简化复杂系统使用的"抽象",在特定情境下会把一部分底层系统泄漏出来。
以文件读取为例:文件系统 API 是对底层内核机制的一种抽象,而内核机制本身又是对磁盘(或 SSD 的闪存)物理读写过程的抽象。大多数情况下,"把文件当作二进制数据流处理"这一抽象会按预期工作。但在机械磁盘上,顺序读取会显著快于随机读取(因为磁头寻道代价高昂),而在 SSD 上这种额外代价并不存在。由此可见,为了高效处理这类场景,开发者必须理解底层细节(例如数据库的索引文件会按特定结构组织,以降低随机访问的开销)——抽象"泄漏"了部分实现细节,而开发者可能需要了解它们。
上述例子在存在额外抽象层时会变得更加复杂。例如 Linux 操作系统允许程序通过网络访问文件,却把它们在本地表现得"平平无奇"。一旦网络出问题,这一抽象就会泄漏:如果开发者把这类文件当作"普通文件"处理,而完全无视它们可能面临网络延迟或失败,软件就会运行失常。
Joel Spolsky 的文章还指出:对抽象的过度依赖,叠加对底层过程理解的匮乏,会让问题在某些情况下变得更难处理。
文中还给出了一个真实案例:
- Photoshop 启动缓慢:作者曾遇到的真实问题——Photoshop 启动极慢,有时需要数分钟。根因是软件在启动时会读取默认打印机的信息,而当该打印机通过网络连接时,这一读取极其耗时。抽象把"网络打印机"伪装得与"本地打印机"无异,正是它给网络状况不佳的用户带来了困扰。
实践启示:使用抽象(框架、中间件、云服务)时,务必保留对底层关键行为的认知模型;"泄漏点"往往就藏在性能、时延、一致性等非功能特性里。
关联阅读:海勒姆定律。
琐碎定律(Loi de futilité)
这条定律认为:组织会把大量时间与注意力投入到琐碎或表面化的细节上,而忽视那些根本性的、困难的问题。
最常被引用的虚构例子是:一个审批核电站建设计划的委员会,把大部分时间花在讨论"自行车棚"上,而不是核电站本身的设计。原因在于:对宏大而复杂的议题,没有深厚专业背景或充分准备的人很难做出有价值的参与;但人们又希望显得自己在有效参与,于是倾向于把焦点放在那些"容易讨论但无关紧要"的细节上。
这个例子催生了术语 "Bike Shedding"(自行车棚,指在琐碎细节上浪费时间)。另一个相关术语是 Yak Shaving(剃牦牛毛),指一项看似无用的活动,它实际上是通往主任务的漫长前置链条中的一环。
实践启示:会议与评审中,主动为"高价值议题"分配明确的讨论时长上限;对"自行车棚级"细节,用默认决策或后续异步讨论快速收场,避免琐碎议题吞噬评审能量。
Unix 哲学(Philosophie d'Unix)
Unix 哲学的核心主张是:计算机程序应当小巧、只做一件事、并且把这件事做好。与构建庞大、复杂、多功能程序相比,通过组合小而边界清晰的基本单元来构建系统,通常更简单。
诸如微服务架构等近期实践,可以被视为这条哲学的一种应用:服务足够小、职责单一,从而允许用简单的积木组合出复杂的行为。
实践启示:模块/服务边界设计时,优先考虑"单一职责 + 可组合";这既是 Unix 哲学,也是微服务拆分的基本判据。
Spotify 模型(Modèle de Spotify)
Spotify 模型是一种由 Spotify 推广的公司与团队组织方法。在该模型中,团队围绕功能而非技术来组织。
Spotify 模型还推广了 Tribe(部落)、Guild(行会)与 Chapter(章节)等组织结构概念,作为其组织体系的组成元素。
实践启示:团队编排时,"围绕功能组建跨职能小队 + 用行会/章节保持技术专长横向流动"是一种被广泛验证的规模化敏捷组织形态;它与康威定律形成呼应——组织形态会塑造软件形态。
沃德勒定律(Loi de Wadler)
在任何语言设计中,花在讨论列表中某一项上的总时间,与该条目所处位置的 2 次幂成正比。
- 语义(Sémantique)
- 语法(Syntaxe)
- 词法语法(Syntaxe lexicale)
- 注释的词法语法(Syntaxe lexicale des commentaires) (通俗地说:每花 1 小时讨论语义,就会有 8 小时花在讨论注释的语法上)
与琐碎定律类似,沃德勒定律指出:在设计一门语言时,花在讨论不同方面上的时间,与这些方面的重要性成反比。
实践启示:在语言/DSL/API 设计评审中,警惕"讨论时长与重要性倒挂"——花最多时间争论的往往是最琐碎的表层问题(缩进、命名风格、注释格式),而真正决定成败的语义设计反而缺乏充分讨论。
惠顿定律(Loi de Wheaton)
别当混蛋(Don't be a dick)。 —— Wil Wheaton
由 Wil Wheaton(《星际迷航:下一代》《生活大爆炸》演员)提出的这条定律,简洁、凝练而有力,旨在提升职业环境中的和谐与尊重。它可以应用于与同事交谈、进行代码评审(code review)、反驳其他观点、提出批评,以及大多数人与人之间的交互场景。
实践启示:代码评审是最直接的落点——把批评指向"代码"而不是"人",用提问代替断言;惠顿定律是高效技术协作的最低社交契约。
第二部分:原则(Principes)
原则通常是与设计相关的指导方针。以下逐条精读。
迪尔伯特原则(Principe de Dilbert)
公司倾向于系统性地提拔无能的员工,以便把他们从工作流中移除。 —— Scott Adams
这是由 Scott Adams(漫画 Dilbert 的作者)提出的管理概念,灵感来自彼得原则。按照迪尔伯特原则,从未在工作中展现出能力的员工会被提拔到管理岗位,以限制他们可能造成的损害。Adams 最初在 1995 年的《华尔街日报》文章中阐述了这一原则,并在其 1996 年的著作《The Dilbert Principle》中展开了这一概念。
实践启示:在晋升与人才盘点机制中,明确区分"专家路线"与"管理路线",避免"把技术不行的人送上管理岗止损"成为默认路径。
关联阅读:彼得原则、普特定律。
帕累托原则(80/20 法则)
生活中的大多数事物都不是均匀分布的。
帕累托原则指出:在许多情形下,少数原因产生了多数结果。软件开发的典型例子包括:
- 一个软件的 80% 可以在 20% 的开发时间内完成(反过来,最难啃的 20% 要花掉 80% 的时间);
- 20% 的努力产出了 80% 的结果;
- 20% 的工作带来了 80% 的收入;
- 20% 的 bug 导致了 80% 的崩溃;
- 20% 的功能支撑了 80% 的使用量。
1940 年代,被广泛视为"质量控制之父"的罗马尼亚裔美国工程师 Joseph M. Juran 博士开始应用帕累托原则解决质量问题。
这一原则也被称为 80/20 法则、"关键少数定律"(The Law of the Vital Few)与"因子稀疏原则"(The Principle of Factor Sparsity)。
文中的真实案例:
- 2002 年,微软报告称:修复被报告最多的那 20% 的 bug,就消除了 Windows 与 Office 中 80% 的相关错误与崩溃。
实践启示:Bug 治理、性能优化、功能规划都可以先做 Pareto 分析——用数据找出"关键的 20%",把有限资源投在回报最高的那部分。
彼得原则(Principe de Peter)
在层级组织中,人们倾向于晋升到自己"不胜任的层级"(level of incompetence)。 —— Laurence J. Peter
彼得原则是 Laurence J. Peter 提出的管理概念:在工作中表现出色的人会被不断晋升,直到抵达一个他们不再成功的层级(即"不胜任层级")。到达这一层级后,凭借已有的资历,他们不太可能被解雇(除非表现特别糟糕),于是便会停留在那个自己可能并不擅长、但难以被替换的岗位上。
这一原则对工程师尤其有警示意义:很多工程师从深度技术的岗位起步,却逐渐转向管理岗位——而管理需要的是本质上完全不同的能力。
实践启示:职业规划中应把"晋升"与"能力匹配"分开评估;组织在晋升制度中引入"试点/带教/回退机制",可以减少彼得原则造成的双输。
关联阅读:迪尔伯特原则、普特定律。
鲁棒性原则(Postel 定律)
宽容地接收(be liberal in what you accept),严谨地发送(be conservative in what you send)。
该原则常被应用于服务端应用开发:你发送给别人的东西应当尽可能最小化、符合规范;但你应该愿意接收不规范的输入,只要它们可以被处理。
这条原则的目标是构建稳健的系统——只要输入"尚可理解",就能处理格式不当的输入。然而,接受格式不当的输入存在潜在的安全隐患,尤其是当对这些输入的处理没有得到充分测试时。
更长远地看,允许不合规的输入会削弱协议演进的能力:因为用户迟早会开始依赖这种宽容性(参见海勒姆定律)。
实践启示:在"宽容输入"与"严格校验"之间做显式权衡——面向公网的入口层通常需要更严格的 schema 校验,而协议内部实现可以适度宽容;对畸形输入的测试要覆盖充分。
SOLID
SOLID 是五个面向对象设计原则的首字母缩写:
- S:单一职责原则(Single Responsibility Principle)
- O:开闭原则(Open/Closed Principle)
- L:里氏替换原则(Liskov Substitution Principle)
- I:接口隔离原则(Interface Segregation Principle)
- D:依赖倒置原则(Dependency Inversion Principle)
这些原则是面向对象编程的基石,遵循它们可以帮助开发者构建更易维护的系统。以下分别精读。
单一职责原则
每个模块或类应当只有一个职责。
作为 SOLID 的第一条原则,它建议模块或类只做一件独特的事。换言之,对程序某功能的一个小改动,应当只要求改动一个组件。例如:修改密码校验方式的改动,应当只需要修改程序中的一个地方。
理论上,这会让代码更健壮、更易修改。知道自己正在修改的组件只有单一职责,也意味着测试这一修改会更容易。沿用上面的例子,修改密码校验组件应当只影响该功能;而修改一个身兼数职的组件时,要厘清影响范围则困难得多。
实践启示:划分类与模块时,以"改变的理由"为唯一标准——一个类应当只有一个"变更理由"。
开闭原则
实体应当对扩展开放,对修改关闭。
SOLID 的第二条原则:实体(类、模块、函数等)的行为应当可以被扩展,但已有行为不应被修改。
设想一个能把 Markdown 文档转换为 HTML 的模块:它可以被扩展——例如添加对某种新 Markdown 特性的支持——而不必修改其内部运作方式;同时它对修改是关闭的:使用者无法改变已有代码的写法。
这一原则对面向对象编程尤其重要:多数时候我们追求设计出"易于扩展、且已有行为不可被意外修改"的对象。
实践启示:优先通过继承、组合、策略、装饰器等机制做"扩展点",而不是直接改已有实现;对可扩展性敏感的场景(库、框架、公共模块),开闭原则是核心约束。
里氏替换原则
应当可以在不破坏系统的前提下,用子类型替换父类型。
SOLID 的第三条原则:如果某个组件依赖于一个类型,那么它应当能够使用该类型的任何子类型,而不会导致系统崩溃,也无需了解子类型的细节。
例如:假设有一个从"文件结构"中读取 XML 文档的方法。若该方法使用基础类型"文件",那么所有从"文件"派生的类型都应当能与该方法协作。如果"文件"支持从尾部向前搜索,而 XML 解析器恰好使用了这一能力,但派生类型"网络文件"并不支持从尾部搜索,那么"网络文件"就违反了该原则。
这一原则对面向对象编程尤其重要:类型层级必须被精心设计,以免让系统的使用者陷入困惑。
实践启示:检查继承层级时,用"行为契约"而不是"代码复用"来衡量——子类必须兑现父类的全部行为承诺(包括隐式承诺,参见海勒姆定律)。
接口隔离原则
任何客户端都不应依赖它不使用的接口方法。
SOLID 的第四条原则:组件的使用者不应依赖该组件中它们不会用到的功能。
沿用"从文件读取 XML"的例子:该方法只需要"读取字节、在文件中前进/后退"。如果当文件的一个无关功能(例如文件访问权限模型更新)变化时,该方法却需要跟着更新,那就违反了该原则。更好的做法是让文件实现一个 "seekable-stream"(可定位流)接口,并让 XML 读取器只依赖这个接口。
这一原则对面向对象编程尤其重要:接口、层级与抽象类型被用来最小化耦合;鸭子类型(duck typing)则通过消除显式接口来实践这一原则。
实践启示:接口按"调用方视角"切分,而不是按"实现方全貌"切分——小而专的接口比大而全的接口更容易演化。
依赖倒置原则
高层模块不应依赖低层实现。
SOLID 的第五条原则:高层组件不应需要知道其依赖的细节。
设想一个从网站读取元数据的程序:它有一个主组件,主组件知道一个负责下载页面内容的组件,以及一个能读取元数据的组件。依据依赖倒置原则,主组件应只依赖两个抽象:一个能下载二进制数据的抽象组件,以及一个能从二进制流读取元数据的抽象组件。主组件不必了解 TCP/IP、HTTP、HTML 等概念。
这一原则之所以复杂,是因为它看起来"颠倒"了系统内预期的依赖方向(这正是其名称由来)。实践上,它还意味着某个"编排者"组件必须确保抽象类型被正确实现(沿用上面的例子:某个东西必须给元数据读取组件提供一个 HTTP 文件下载器和一个 HTML 元标签读取器)。这就引出了控制反转与依赖注入等模式。
实践启示:让业务核心依赖抽象接口而非具体实现,配合依赖注入容器/组合根来装配实现;核心代码因此可独立测试、可替换实现。
DRY 原则
在一个系统中,每一条知识都必须有唯一的、无歧义的、权威的表示。
DRY 是Don't Repeat Yourself(不要重复自己)的缩写。该原则旨在帮助开发者减少代码重复,把信息保存在唯一的位置。它由 Andrew Hunt 与 Dave Thomas 于 1999 年在《程序员修炼之道》(The Pragmatic Programmer)一书中提出。
DRY 的反面是WET(Write Everything Twice 或 We Enjoy Typing,即"所有东西写两遍"或"我们喜欢敲键盘")。
实践中,如果你把同一信息放在了两个(或更多)地方,就可以运用 DRY 把它们合并,并在所有需要的地方复用这一唯一实例。
实践启示:重复的"知识"(业务规则、常量、校验逻辑)应当收敛到单一权威来源;但要注意——两段"碰巧长得像"但演化方向不同的代码,强行 DRY 反而制造耦合,需要结合语境判断。
KISS 原则
Keep it simple, stupid.(保持简单,笨蛋)
KISS 原则主张:大多数系统在"简单"状态下比在"复杂"状态下运行得更好。因此,简单应当是设计中的核心目标,任何不必要的复杂都应被避免。这一原则源自 1960 年代的美国海军,常被归于工程师 Kelly Johnson。
这个原则最好的例证是 Johnson 的故事:他给一队工程师一捧工具,要求他们设计一种战斗机——必须能让普通机械师在战场上仅凭这些工具就能完成修理。这里的"stupid"指的是"事物损坏的方式"与"可用于修理的工具之精巧程度"之间的关系,而绝非对工程师能力的贬低。
实践启示:设计评审时把"最简可行方案"作为默认基线,任何新增复杂度都必须当场说明其必要性;复杂度的"使用者"(维护者、运维者)决定了它是否值得。
关联阅读:高尔定律。
YAGNI
YAGNI 是YouAin'tGonnaNeedIt(你不会需要它的)的缩写。
只在真正需要的时候实现东西,而不是在"你认为以后可能会需要"的时候实现。 ——(Ron Jeffries)(极限编程联合创始人,《Extreme Programming Installed》作者)
这条源自*极限编程(Extreme Programming, XP)*的原则建议:开发者只实现当下必需的功能,避免试图"预测未来"而提前实现那些将来可能需要(但很可能不需要)的功能。
遵循这一原则,应当能减少代码库中未使用代码的数量,避免把时间浪费在不能带来价值的功能上。
实践启示:需求评审中的黄金问题——"这个功能现在的真实用户是谁?"——如果答案是"未来可能会",那就先不做;YAGNI 与过度设计的斗争是架构演进的第一道防线。
关联阅读:阅读清单中的《Extreme Programming Installed》。
分布式计算的谬误
也被称为网络计算的谬误,是一系列关于分布式计算的假设(或信念)清单,这些假设可能导致软件开发中的问题。八条假设如下:
- 网络是可靠的(The network is reliable)
- 网络延迟为零(Latency is zero)
- 带宽是无限的(Bandwidth is infinite)
- 网络是安全的(The network is secure)
- 网络拓扑不会变化(Topology doesn't change)
- 只有一个管理员(There is one administrator)
- 传输成本为零(Transport cost is zero)
- 网络是同构的(The network is homogeneous)
前四条由 Bill Joy 与 Tom Lyon 于 1991 年左右列出,并由 James Gosling 首次命名为"分布式计算的谬误"。 L. Peter Deutsch 补充了第 5、6、7 条;Gosling 在 1990 年代末补充了第 8 条。
这一清单的灵感来自 Sun Microsystems 当时的实践。这些谬误应当在设计健壮代码时时刻牢记:每一条都可能带来与现实脱节的认知偏差,从而低估分布式系统的真实复杂度。
实践启示:设计任何跨网络系统(微服务、云原生、边缘计算)时,把八条谬误当作"设计检查清单"逐条过一遍——例如重试与超时(对应 1、2)、幂等与压缩(对应 3、7)、安全默认(对应 4)、多集群与容灾(对应 5、6、8)。
第三部分:延伸阅读清单(À lire)
法文译本在正文之外,还给出了一个精选书单,供希望深入这些概念的读者继续研读:
- 《Extreme Programming Installed》——Ron Jeffries、Ann Anderson、Chet Hendrikson 合著,覆盖极限编程的基础原则,与 YAGNI 直接相关;
- 《人月神话》(The Mythical Man Month)——Frederick P. Brooks Jr. 著,软件开发的经典之作,布鲁克斯定律是其核心主题之一;
- 《哥德尔、艾舍尔、巴赫:集异璧之大成》(Gödel, Escher, Bach: An Eternal Golden Braid)——Douglas R. Hofstadter 著,一本难以归类的书,霍夫斯塔特定律即出自该书;
- 《The Dilbert Principle》——Scott Adams 著,以幽默视角审视美国企业界,迪尔伯特原则的出处;
- 《The Peter Principle》——Lawrence J. Peter 著,另一个以幽默视角审视管理与大企业挑战的著作,彼得原则的源头。
第四部分:多语言翻译与协作生态
作为开源项目,hacker-laws 依靠贡献者网络维护了多个语言版本。在当前仓库中,translations/ 目录下保存着下列本地化文档(均为仓库内真实文件):
- translations/pt-BR.md(巴西葡萄牙语)
- translations/fr.md(法语,本文主体)
- translations/es-ES.md(西班牙语)
- translations/it-IT.md(意大利语)
- translations/lv.md(拉脱维亚语)
- translations/tr.md(土耳其语)
- translations/id.md(印度尼西亚语)
- translations/jp.md(日语)
- translations/pl.md(波兰语)
- translations/vi.md(越南语)
从法文译本末尾的"Traductions"章节可以看到完整的协作机制:各语言版本由社区指定的维护者(moderator)负责,部分翻译通过 GitLocalize 平台进行持续同步与状态跟踪;更新现有翻译可以通过提交 PR 完成,而新增语言则通常需要先创建 issue 并接入翻译协作流程。
对内容本身,仓库欢迎两种贡献方式:创建 issue以建议新增条目或修改,或提交 Pull Request提出自己的文本。法文译本还提示:正式贡献前应阅读项目维护者发布的贡献指南与行为准则,以确保风格与内容符合项目要求。
总结:如何把"定律手册"变成决策工具
精读 translations/fr.md 之后,可以把这些定律与原则归纳为几个"决策工具箱":
- 性能与架构:阿姆达尔定律(并行化收益边界)、摩尔定律(免费午餐终结)、过早优化效应(用 Profile 说话)、复杂度守恒定律(复杂度只能转移);
- 团队与组织:布鲁克斯定律(加人不等于加速)、康威定律(架构追随组织)、邓巴数(认知负载)、帕累托原则(抓关键少数);
- 系统与接口设计:海勒姆定律(隐式契约)、泄漏抽象定律(抽象必有泄漏)、鲁棒性原则(宽容输入与安全权衡)、分布式计算的谬误(八条检查清单)、SOLID 五原则(可维护的面向对象设计);
- 协作与沟通:汉隆剃刀(先假设无知)、惠顿定律(评审礼仪)、坎宁安定律(社区求答之道)、帕金森定律与霍夫斯塔特定律(时间估算的现实)。
正如仓库引言反复强调的:这些定律与原则不是行为规范,而是观察透镜。结合项目 README.md 与各语言译本(translations/)交叉阅读,再回到你自己的项目语境中去验证——这才是 hacker-laws 真正的打开方式。
- 文档
- 知识库
- 教程
【免费下载链接】hacker-laws
🧠 Laws, Theories, Principles and Patterns for developers and technologists.
相关推荐
hacker-laws 全景解读:开发者与技术人必知的法则、理论与原则
hacker laws 全景解读:开发者与技术人必知的法则、理论与原则 本文以开源仓库 hacker laws 的日文翻译版 translations/jp.m
文档知识库教程Rich 日志处理详解:用 RichHandler 让 Python logging 输出彩色的终端日志
Rich 日志处理详解:用 RichHandler 让 Python logging 输出彩色的终端日志 导读 Python 标准库 logging 输出单调乏
文档知识库教程hacker-laws:软件工程师必知的定律、理论、原则与模式全解析
hacker laws:软件工程师必知的定律、理论、原则与模式全解析 本篇技术指南以开源仓库 hacker laws 的土耳其语译本 translations/
文档知识库教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考