写在前面

全篇内容还是来自Github上的hacker-laws库里的,想着一鼓气整理出来,原文标题为《对开发人员有用的定律、理论、原则和模式》,英文版目前已搜集了56项,中文版由Steve Xu同学翻译完成(少2条,本文有多处引用,在此作谢)。

事实上,网上也已可以搜索到相关的文章,但是存在一些问题,首先是内容仅有少数一部分,其次是缺少进一步的整理归类和分析,希望本文可以把这一块儿补上。

技术规律类

[微风]摩尔定律 (Moore's Law)

集成电路中的晶体管数量大约每两年翻一番。

直至21世纪后期,摩尔定律的预测被证明是非常准确的。后来,因为组件小型化遇到物理上的限制,这一趋势略有变化。近年来,随着并行化的发展,以及半导体技术和量子计算的潜在革命性变化,这条定律在未来几十年可能继续成立。

成为开发者需要具备哪些能力(对开发人员有用的定律)(1)

​[微风]技术成熟度曲线 (The Hype Cycle or Amara's Law)

我们倾向于过高估计技术在短期内的影响,而低估长期效应。

该定律是对技术炒作曲线的一种概况性说法,描述了人们在不同阶段对某种新技术的态度。

成为开发者需要具备哪些能力(对开发人员有用的定律)(2)

​[微风]​沃德勒定律 (Wadler's Law)

任何语言设计中,讨论下面列表中某个要素所花费的总时间与其位置成正比。

1、语义 (Semantics)

2、语法 (Syntax)

3、词法 (Lexical syntax)

4、注释语法 (Lexical syntax of comments)

比如,在语义上花费1个小时,就要在注释语法上花费8个小时。

该定律主要表达人们在非重要事项上花费了更多时间。

成为开发者需要具备哪些能力(对开发人员有用的定律)(3)

​[微风]​​​帕累托法则 (The Pareto Principle or The 80/20 Rule)

生活中大多数事情不是均匀分布的。

著名的80/20法则,大多数结果来自少数输入,至少可用于质量管理等领域。

成为开发者需要具备哪些能力(对开发人员有用的定律)(4)

​[微风]舍基原理 (The Shirky Principle)

各机构会努力保留他们拥有解决方案的问题。

舍基原理表明,对于拥有复杂问题解决方案的机构,可能会有意或无意地将问题永久化。

成为开发者需要具备哪些能力(对开发人员有用的定律)(5)

​[微风]​墨菲定律 (Murphy's Law / Sod's Law)

任何可能出错的事就一定会出错。

可以用在代码质量等很多地方。

成为开发者需要具备哪些能力(对开发人员有用的定律)(6)

团队组织类

​[微风]​​​​康威定律 (Conway's Law)

这个定律说明了系统的技术边界可以反应一个组织的结构,它通常会在改进组织时被提及。

康威定律表明,如果一个组织被分散成许多小而无联系的单元,那么它开发的软件也是小而分散的。如果组织是更多地围绕以功能或服务为导向的垂直结构,那么软件系统也会反映这一点。

成为开发者需要具备哪些能力(对开发人员有用的定律)(7)

​[微风]​​Spotify 模型 (The Spotify Model)

Spotify 模型是团队和组织结构的一种方法,已被 Spotify 推广开来。在此模型中,团队围绕功能而非技术进行组织。

需要注意,该模型是动态的过程,而不是固定的。

成为开发者需要具备哪些能力(对开发人员有用的定律)(8)

​[微风]​两个披萨规则(The Two Pizza Rule)

如果你不能用两个披萨喂饱一个团队, 那么它太大了。

源自亚马逊的该规则表明,无论公司规模多大,团队都应该小到可以两个披萨吃饱(大概6-10人)。其背后的原因是更大的团队因沟通成本的指数增长而带来更低的效率。

成为开发者需要具备哪些能力(对开发人员有用的定律)(9)

​[微风]​​惠顿定律 (Wheaton's Law)

不要像个傻子一样。

这条话在威尔 · 惠顿(曾出演过星际迷航:下一代、生活大爆炸)一次关于体育精神的演讲后开始流行(可能是因个别词汇导致的,纯属好玩),提倡不要成为一个不顾及别人感受的人,对别人好一点,这个简洁而有力的定律旨在专业组织内营造和谐和尊重的环境。它可以在与同事交谈、代码审查、反驳观点和批评的时候派上用场。而且通常情况下,人们之间的专业交互也同样适用。

成为开发者需要具备哪些能力(对开发人员有用的定律)(10)

​[微风]​​死海效应 (The Dead Sea Effect)

"... 那些更有才华,更有效率的 IT 工程师最有可能离开——消失 ... (而那些倾向于)留下来的“剩下的人”——是最没有才华和效率的 IT 工程师。"

死海效应表明,在任何一个组织中,工程师的技能、才华和效能往往与他们在公司的时间呈反比。

成为开发者需要具备哪些能力(对开发人员有用的定律)(11)

​​[微风]普特定律 (Putt's Law)

技术由两种类型的人主导,一种是精通但不管理的人(纯技术人),另一种是管理但不精通的人(纯管理人)。

​该定律描述了某些组织存在的一种技术官僚现象,即随着时间的推移,技术能力强的人继续负责实际技术,而不懂技术的人则走向了技术管理岗位。

成为开发者需要具备哪些能力(对开发人员有用的定律)(12)

​[微风]​​​呆伯特法则 (The Dilbert Principle)

公司会倾向于系统地将工作能力差的员工提升到管理层,以使他们脱离工作流程。

成为开发者需要具备哪些能力(对开发人员有用的定律)(13)

​[微风]彼得原理 (The Peter Principle)

在等级制度中,人往往会被提升到他们的“无法胜任的水平”。

成为开发者需要具备哪些能力(对开发人员有用的定律)(14)

​​​[微风]帕金森琐碎定理 (The Law of Triviality)

团体将更多的时间和注意力放在琐碎或表面问题上,而不是严肃和实质性的问题上。

如果没有大量的专业知识或者准备,很难给非常大的复杂主题讨论提供宝贵的意见。但是,人们希望看到更多意见。因此,他们倾向于将大量时间集中在很容易推敲,但不一定被看重的小细节上。

成为开发者需要具备哪些能力(对开发人员有用的定律)(15)

​[微风]​古德哈特定律 (Goodhart's Law)

当压力施于其上以进行控制时,任何观测到的统计恒性都倾向消散。

--查尔斯·古德哈特 (Charles Goodhart)

当一个措施本身成为目标时,它就不再是一个好的措施。

--玛丽莲·斯特拉腾 (Marilyn Strathern)

已见用于对通过代码行数、注释数作为绩效考核的批判。

成为开发者需要具备哪些能力(对开发人员有用的定律)(16)

产品设计类

​[微风]​​​​​90-9-1 法则 (90–9–1 Principle or 1% Rule)

90-9-1 法则表明,在诸如维基这样的互联网社区中,90% 的用户只看内容并不参与互动,9% 的用户会参与讨论,而只有 1% 的用户会创造内容。

成为开发者需要具备哪些能力(对开发人员有用的定律)(17)

​[微风]​​​​邓巴数字 (Dunbar's Number)

邓巴数字是对一个人能够保持稳定社会关系的人数的认知极限。在这种关系中,一个人知道每个人是谁,也知道每个人与其他人的关系如何。而对这一数字的确切值则有着一些不同意见。邓巴指出,人仅能轻松地维持 150 个稳定的关系。这样的关系在一个更社会化的背景中,便是当你碰巧在酒吧里碰到这些人时候,你不会因为加入他们而感到尴尬。邓巴数字的估计值一般在 100 至 250 之间。

和人与人之间稳定的关系一样,开发人员与代码库的关系也需要努力维护。当面对大型、复杂的项目,或许多项目的归属权时,我们会依赖于约定、策略和建模过程来进行扩展。邓巴数字不仅在办公室规模的扩大的过程中举足轻重,而且在设置团队工作范围,或决定系统何时应该注重于辅助建模和组织管理开销自动化的工具时,也是非常重要的。将邓巴数字放入工程内容中进行类比,那就是您能加入并有信心随叫随到进行轮换的项目数(亦或是单个项目的规范化复杂性)。

成为开发者需要具备哪些能力(对开发人员有用的定律)(18)

​[微风]​​​费茨法则 (Fitts's Law)

移动到目标区域所需的时间是到目标的距离除以目标宽度的函数。

费茨法则决定了在设计 UX 或 UI 时,交互元素应该尽可能大,而用户注意力区域和交互元素之间的距离应该尽可能小。这会对设计产生影响,例如将相近的任务进行归类分组等。

同时它还将“魔角 (Magic Corners)”这一概念正式化,即在角落放置关键的 UI 元素,从而使得用户可以通过移动鼠标轻松点击到。Windows 的开始按钮便位于魔角处便于选择,而有趣的是 MacOS 恰恰相反,它的“关闭窗口”按钮 不处于 魔角处,从而能有效减小被误点击的概率。

成为开发者需要具备哪些能力(对开发人员有用的定律)(19)

​[微风]​​​席克定律 (Hick's Law or Hick-Hyman Law)

决策时间和可供选择的选项数量呈对数增长关系。

成为开发者需要具备哪些能力(对开发人员有用的定律)(20)

​[微风]​​​梅特卡夫定律 (Metcalfe's Law)

在网络理论中,系统的价值约等于系统用户数的平方。

成为开发者需要具备哪些能力(对开发人员有用的定律)(21)

​[微风]​​里德定律 (Reed's Law)

大型网络,尤其是社交网络的效用会随着网络的大小呈指数级扩增。

这一定律基于图论,图论中的效用与可能的子组数量呈正比,并且该增长速度会比参与者的数量和可能的连接对数量要快。奥德利兹科 (Odlyzko) 和其他人认为,里德定律夸大了系统本身的价值,因为它们没有考虑到网络效应中人类认知的限制。

成为开发者需要具备哪些能力(对开发人员有用的定律)(22)

项目管理类

​[微风]​​布鲁克斯法则 (Brooks's Law)

软件开发后期,添加人力只会使项目开发得更慢。

这个定律表明,在许多情况下,试图通过增加人力来加速已延期项目的交付,将会使项目交付得更晚。布鲁克斯也明白,这是一种过度简化。但一般的论据是,新资源的时间增加和通信开销,会在短期内使开发速度减慢。而且,许多任务是密不可分的,换句话说,这样可以使更多的资源之间能轻易分配,这也意味着潜在的速度增长也更低。

成为开发者需要具备哪些能力(对开发人员有用的定律)(23)

​[微风]​​​​​​侯世达定律 (Hofstadter's Law)

即使考虑到侯世达定律,它也总是比你预期的要长。

工期估算的悖论

成为开发者需要具备哪些能力(对开发人员有用的定律)(24)

​[微风]帕金森定理 (Parkinson's Law)

在工作能够完成的时限内,工作量会一直增加,直到所有可用时间都被填满为止。

成为开发者需要具备哪些能力(对开发人员有用的定律)(25)

系统设计类

​[微风]​​​阿姆达尔定律 (Amdahl's Law)

阿姆达尔定律是一个显示计算任务潜在加速能力的公式。这种能力可以通过增加系统资源来实现,通常用于并行计算中。它可以预测增加处理器数量的实际好处,然而增加处理器数量会受到程序并行性的限制。

并行性也是有限制的。

成为开发者需要具备哪些能力(对开发人员有用的定律)(26)

​[微风]​​CAP 定理 (CAP Theorem or Brewer's Theorem)

CAP 定理由 Eric Brewer 所定义,它指出对于分布式数据存储来说,不可能同时满足以下三点:

1、一致性 (Consistency):在读取数据时,每个请求都会接收到 最新的 数据,或者返回错误。

2、可用性 (Availability): 在读取数据时,每个请求都会接收到一个 非错误的响应,但不能保证该数据是 最新的 数据。

3、分区容错性 (Partition Tolerance):当节点之间任意数量的网络请求失败时,系统能按预期继续运行。

成为开发者需要具备哪些能力(对开发人员有用的定律)(27)

​[微风]​​​​​​​邓宁-克鲁格效应 (The Dunning-Kruger Effect)

无能的人往往不会意识到自己的无能。而得出正确答案所需要的技能,正是你认识到何为正确答案所需要的技能。

随着对某一领域的理解和经验的增长,人们很可能会遇到另一种效应-虚幻的优越性 (Illusory superiority),即特定领域内的丰富经验使得他们更容易高估他人的能力,或低估自己的能力。总而言之,这些影响都归咎于认知偏差。当意识到偏差存在时,我们可以尽量提出意见来消除这些偏差,这样往往可以避免异议。

成为开发者需要具备哪些能力(对开发人员有用的定律)(28)

​[微风]​​​​​​盖尔定律 (Gall's Law)

一个切实可行的复杂系统势必是从一个切实可行的简单系统发展而来的。从头开始设计的复杂系统根本不切实可行,无法修修补补让它切实可行。你必须由一个切实可行的简单系统重新开始。

成为开发者需要具备哪些能力(对开发人员有用的定律)(29)

​[微风]​​​​奥卡姆剃刀 (Occam's Razor)

如无必要,勿增实体。

奥卡姆剃刀指出,在几种可能的解决方案之中,最有可能的解决方案便是概念和假设最少的那个。因为这个解决方案最为简单,只解决了问题,并且没有引入额外的复杂度和可能的负面后果。

成为开发者需要具备哪些能力(对开发人员有用的定律)(30)

​[微风]​抽象泄漏定律 (The Law of Leaky Abstractions)

在某种程度上,所有非平凡的抽象都是有泄漏的。

描述该定律的文章表明,过度依赖抽象,加上对底层过程的理解不足,实际上使得问题在某些情况下更加复杂。

成为开发者需要具备哪些能力(对开发人员有用的定律)(31)

​[微风]​​​​乔治·伯克斯定律 (All Models Are Wrong or George Box's Law)

所有的模型都是错的,但有些是有用的。

这一原则表明,所有的系统模型都是有缺陷的,但只要它们没有太多缺陷,那便有可能是有用的。这一原则源于统计学,同时也适用于科学和计算模型。

大多数软件的一个基本要求都是对某种特定系统进行建模。无论是计算机网络、资源库、社会关系图还是任何其他类型的系统,设计者都必须依据适当的细节程度来建模。过多的细节可能会导致太高的复杂度,过少的细节可能会使模型无法正常工作。

成为开发者需要具备哪些能力(对开发人员有用的定律)(32)

​​​​​[微风]得墨忒耳定律 (The Law of Demeter)

别和陌生人讲话。

得墨忒耳定律又称最少知识原则,是一条与面向对象语言有关的软件设计原则。

该定律表明,软件的一个单元应该只与其直接合作者交谈。比如对象 A 引用了对象 B,对象 B 引用了对象 C,则 A 可以直接调用 B 的方法,但不应直接调用 C 的方法。所以如果 C 有一个 dothing() 的方法,A 不应该直接调用,而是使用 B.getC().doThis()。

遵循这一定律可以限制代码更改的范围,使其以后更容易维护、更安全。

成为开发者需要具备哪些能力(对开发人员有用的定律)(33)

​[微风]​​​​Unix 哲学 (The Unix Philosophy)

Unix 哲学指软件组件应该很小,并专注于做一件特定的事情。将小而简单以及定义良好的单元组合在一起,而不是使用大而复杂的多用途程序,可以更轻松地构建系统。

成为开发者需要具备哪些能力(对开发人员有用的定律)(34)

​[微风]​​SOLID

这是一个缩写,指的是:

S:单一功能原则 (The Single Responsibility Principle)

每个模块或者类只应该有一项功能。

O:开闭原则 (The Open/Closed Principle)

实体应开放扩展并关闭修改。

L:里氏替换原则 (The Liskov Substitution Principle)

可以在不破坏系统的情况下,用子类型替换类型。

I:接口隔离原则 (The Interface Segregation Principle)

不应强制任何客户端依赖于它不使用的方法。

D:依赖反转原则 (The Dependency Inversion Principle)

高级模块不应该依赖于低级实现。

成为开发者需要具备哪些能力(对开发人员有用的定律)(35)

​[微风]​KISS 原则 (The KISS Principle)

保持简单和直白。

KISS 原则指明了如果大多数的系统能够保持简单而非复杂化,那么他们便能够工作在最佳状态。因此,简单性应该是设计时的关键指标,同时也要避免不必要的复杂度。这个短语最初出自 1960 年的美国海军飞机工程师凯利 · 约翰逊 (Kelly Johnson)。

成为开发者需要具备哪些能力(对开发人员有用的定律)(36)

​[微风]​不要重复你自己原则 (The DRY Principle)

系统中,每一块知识都必须是单一、明确而权威的。

DRY 是 Do not Repeat Yourself 的缩写。这个原则旨在帮助开发人员减少代码的重复性,并将公共代码保存在一个地方。最初由安德鲁·亨特和戴夫·托马斯在 1999 年出版的《程序员修炼之道》中引用。

成为开发者需要具备哪些能力(对开发人员有用的定律)(37)

产品质量类

​​​​​​​​[微风]破窗效应 (The Broken Windows Theory)

在破窗理论中认为,一些明显的犯罪迹象(或缺乏环保意识)会导致进一步的、更严重的犯罪(或环境的进一步恶化)。

破窗理论已应用于软件开发中,它表明劣质代码(或 Technical Debt)可能会影响后续优化的效率,从而进一步造成代码劣化;随着时间的推移,这种效应将会导致代码质量大幅下降。

成为开发者需要具备哪些能力(对开发人员有用的定律)(38)

​[微风]​​​​​​汉隆的剃刀 (Hanlon's Razor)

能解释为愚蠢的,就不要解释为恶意的。

恶果通常都是考虑不足所导致的,并非恶意。

成为开发者需要具备哪些能力(对开发人员有用的定律)(39)

​[微风]​复杂性守恒定律 (The Law of Conservation of Complexity or Tesler's Law)

该定律表明系统中存在着一定程度的复杂性,并且不能减少。

系统中的某些复杂性是无意的。这是由于结构不良,错误或者糟糕的建模造成的。这种无意的复杂性可以减少或者消除。然而,由于待解决问题固有的复杂性,某些复杂性是内在的。这种复杂性可以转移,但不能消除。

该定律有趣的一点是,即使简化整个系统,内在的复杂性也不会降低。它会转移到用户,并且用户必须以更复杂的方式行事。

成为开发者需要具备哪些能力(对开发人员有用的定律)(40)

​[微风]​​​​​哈特伯定律 (Hutber's Law)

改善即恶化。

‬这个定律说明了对一个系统的改进会导致其他部分的恶化;或者它会将其他的恶化隐藏起来,并导致系统整体状态的退化。

成为开发者需要具备哪些能力(对开发人员有用的定律)(41)

​[微风]​过早优化效应 (Premature Optimization Effect)

过早优化是万恶之源。

在高德纳的《goto 语句的结构化编程》论文中,他写到:“程序员们浪费了大量的时间去思考或者担心他们的程序中的非关键部分的速度。而在考虑调试和维护的时候,这些所谓提高效率的做法实际上十分不妥。我们应该放弃小的效率点,并且要在 97% 的时间提醒自己,过早优化是万恶之源。而且连那关键的 3% 也不能够放过。”

然而,过早优化 (简而言之)可以定义为在我们知道需要做什么之前进行优化。

成为开发者需要具备哪些能力(对开发人员有用的定律)(42)

​[微风]切斯特森围栏 (Chesterson's Fence)

在了解现有情况背后的原因之前,不应该进行改进。

该原则与软件工程中的消除技术负债 (Technical debt) 相关。程序的每一行最初都是出于某种原因编写的,因此根据切斯特森围栏原则,在更改或删除代码之前,即使看起来似乎是多余的或不正确的,也应该尝试完全理解代码的上下文和含义。

成为开发者需要具备哪些能力(对开发人员有用的定律)(43)

​​​​​[微风]林纳斯定律 (Linus's Law)

足够多的眼睛,就可让所有问题浮现。

代码评审、案例评审...等等

​​​

成为开发者需要具备哪些能力(对开发人员有用的定律)(44)

​​

编码开发类

​[微风]​童子军规则(The Scout Rule)

总是让代码比你开始看到它时更好。

及时重构。

成为开发者需要具备哪些能力(对开发人员有用的定律)(45)

​[微风]​​​​​​​​​​坎宁汉姆定律 (Cunningham's Law)

在网络上想得到正确答案的最好方法不是提问题,而是发布一个错误的答案。

成为开发者需要具备哪些能力(对开发人员有用的定律)(46)

​[微风]​​​​​​​隐式接口定律 (Hyrum's Law or The Law of Implicit Interfaces)

当 API 有足够多的用户时,你在合同中的承诺已不重要:你系统的所有可观察行为都将被某些人所依赖。

要注意接口定义的严谨性,避免被绑架。

成为开发者需要具备哪些能力(对开发人员有用的定律)(47)

​​​​​​​[微风]柯林汉定律 (Kernighan's Law)

调试在一开始就比编写程序困难一倍。因此,按照定义,如果你的代码写得非常巧妙,那么你就没有足够的能力来调试它。

简单的代码才便于调试。

成为开发者需要具备哪些能力(对开发人员有用的定律)(48)

​​​[微风]你不需要它原则 (YAGNI)

只有当你需要某些东西的时候,才去实现它们,而不是在你预见的时候。

避免过度设计、超前设计。

成为开发者需要具备哪些能力(对开发人员有用的定律)(49)

​[微风]​​​​​​鲁棒性原则 (The Robustness Principle or Postel's Law)

在自己所做的事情上要保守, 在接受别人的事情上要自由。

通常应用于服务器应用程序开发中,该原则指出,你发送给其他人的内容应尽可能最小且符合要求,并且处理不符合要求的输入。

该原则的目标是构建稳健的系统。如果可以理解意图,它们可以处理不良的输入。但是,接受错误格式的输入可能存在安全隐患,特别是此类的输入未经过充分测试。

成为开发者需要具备哪些能力(对开发人员有用的定律)(50)

​​​​​​​​[微风]分布式计算的谬论 (The Fallacies of Distributed Computing)

又称 网络计算的谬误,这是一系列关于分布式计算的猜想(或者看法),这些猜想可能会引起软件开发中的失败。这些假设是:

1、网络可靠

2、延迟为零

3、带宽无限

4、网络安全

5、拓扑恒定

6、单一管理员

7、运输成本为零

8、网络为同构的

在设计弹性代码的时候,应该仔细考虑这些谬误,并假设其中任何一个谬误都可能引起处理分布式系统的复杂性和现实性时的逻辑缺陷。

很多Bug其实是因为没有意识到这些问题导致的。

成为开发者需要具备哪些能力(对开发人员有用的定律)(51)

写在后面

好了,这些就是全部内容了,配图潦草,请不必过分纠结,有些项的分类可能不太适当,有些项可能适合很多场景,有些比较晦涩难懂,有些可能比较极端,不管怎么说,希望可以给我们带来一些启示和警醒就好,感谢阅读!!!

,