布鲁克斯定律
它是由弗雷德·布鲁克斯 (Fred Brooks) 在 1975 年出版的《人月神话》一书中提出的。他说“为后期的软件项目增加人力会使其更晚交付”。
这个想法非常出乎意料,因为当一个项目落后于计划时,一个明显的策略是尝试增加来自组织其他部门的人员或新员工来帮助支持这项工作。
事实上,增加团队成员会增加沟通成本,因为新员工会通过以下一些方式培养技能并对现有员工提出要求:检测错误、解释代码、阅读设计文档等。
康威定律
大约 50 年前,Mel Conway 在 Datamation 上发表了一篇名为“委员会如何发明?”的论文,其中探讨了组织结构与最终系统设计之间的关系。这个想法是系统的架构将由公司的沟通和组织结构决定。
菲茨定律
“获取目标的时间是到目标的距离和目标大小的函数”,这被称为菲茨定律。根据他的定律,由于速度与精度的权衡,快速移动和小目标会导致更大的错误率。
1978 年,施乐的员工使用菲茨定律来发现哪种输入设备最适合他们的计算机系统。您可能需要执行以下一些操作以将菲特定律应用于您的用户界面设计:
避免将任何按钮设置得太小,并且应该将重要的按钮设置大以便易于点击。
在光标位置弹出菜单有助于减少移动距离,从而减少移动时间。
希克定律
希克定律说,“用户做出决定所需的时间取决于他们拥有的可能选择的数量”。该定律声称,用户从一个包含 10 个项目的菜单中做出选择要比从两个包含 5 个项目的菜单中更快地做出选择。
该定律还指出,做出决定所需的时间受以下两个因素的影响:
用户对选择的了解,例如来自重复使用。
选择的形式是声音还是文字、视频或按钮?
霍夫施塔特定律
认知科学家 Douglas Hofstadter 创造了 Hofstadter 定律:
它总是比您预期的要长,即使您考虑了霍夫施塔特定律。
当然,没有任何定律规定一切都必须枯燥、乏味、枯燥或乏味。但是当执行时,一切都会出错,而且花费的时间比我们预期的要长。
克尔科夫斯原理
Kerckhoffs 原理指出,“密码系统的安全性必须仅在于其密钥的选择,其他一切(包括算法本身)都应该被视为公共知识”。
这是公钥密码学的主要原理。它被广泛接受并暗示算法必须有许多可能的密钥,密钥空间必须非常大。
莱纳斯定律
该定律由 Eric S. Raymond 在他的论文和著作 The Cathedral and the Bazaar (1999) 中提出,并以 Linus Torvalds(Linux 操作系统的首席开发人员)的名字命名。
如果有足够的眼球,所有的错误都是浅薄的。
他认为,通过尽可能多的人来识别并随后更正错误,可以最好地修复错误。
梅特卡夫定律
梅特卡夫定律指出“系统的价值大约随着系统用户数量的平方增长”。
整个网络的连接总数为 (N·(N − 1))/2~N²
换句话说,如果你认识的人数增加一倍,你的网络价值就会增加四倍。
摩尔定律
这条以英特尔创始人戈登摩尔命名的定律预测,半导体晶体管的数量每 18 到 24 个月就会翻一番。
今天,硅芯片上安装的晶体管增加一倍,几乎每 18 个月而不是每 24 个月。专家们一致认为,计算机应该在 2020 年代的某个时候达到摩尔定律的物理极限。
帕累托原则
帕累托法则,也就是 80/20法则 ,你听说过吗?这反映了“80% 的影响是 20% 原因的产物”。
大多数人倾向于将大约 80% 的时间花在任务上,以产生 20% 的结果。
这一原则可以普遍适用于商业领域,并可以在社会各个部门找到。我们甚至可以在日常生活的大部分领域使用它。例如,20% 的员工产生 80% 的工作,或 20% 的产品产生 80% 的利润。
罗斯定律
每一个决定都是一次权衡。
取自 Dan North 的演讲Decisions,Decisions,它目前还不是公认的定律。
开发者日复一日的生活中,我们每天都做无数个大大小小的决定。从命名变量到自动化(手动)任务,再到定义平台架构。
这条语录强调无论你做的选择是什么,你总会放弃一个或多个选项。
但这不是最重要的。 最重要的是理智地做出决定,了解其他选项,清楚你为什么不选择它们。你要始终根据当前你掌握的信息来权衡并做出决定。
但是如果后来你了解到新的信息,并发现之前的决定是错误的,这也没关系。关键是记清楚你为什么做出那个决定,重新评估新的选项之后再做出新的理智的决定。
奥卡姆剃刀
这句广为人知的格言可以追溯到十四世纪一位名叫威廉奥卡姆的哲学家和修士。奥卡姆剃刀通常被表述为:
在相互竞争的假设中,应该选择假设最少的假设。
我们能回忆起 600 多年前的格言的全部原因是它运作良好,这并不奇怪。奥卡姆剃刀原理是如此基础,如此基本,以至于在两种相互竞争的理论之间做出决定时,它应该是我们首先考虑的事情。
汉隆剃刀
有时我觉得用户是故意要惹我生气。他们按不应该按的按钮,发现了他们不应该看到的缺陷(因为它们对我来说不是),并且通常使我生活中的大部分事情变得比原本更困难。
不过,我尽量记住,人们所做的绝大多数看似恶意的行为并非故意如此。相反,这是因为他们不知道更多。这是一句名为Hanlon's Razor的格言的关键,它指出:
永远不要把可以用愚蠢充分解释的事情归咎于恶意。
不要假设人们是恶意的,假设他们无知,然后帮助他们克服无知。大多数人想要学习,而不是为了好玩而刻薄。
邓宁-克鲁格效应
研究人员大卫·邓宁和贾斯汀·克鲁格在 1999 年进行了一项实验,观察到了一种后来被称为邓宁-克鲁格效应的现象:
不熟练的人往往会错误地认为自己的能力比实际能力强得多。
稳健性原则(又名 Postel 定律)
软件开发中的基本思想之一,特别是 API 设计等领域,可以用鲁棒性原则简洁地表达:
在自己所做的事情上要严格, 在接受别人的事情上要宽容。
这个原则也被称为互联网先驱Jon Postel 的Postel 定律,他最初将其写成RFC 760 的一部分。值得记住的是,除了温和的提醒之外,最好的代码通常是根本没有代码。
通常应用于服务器应用程序开发中,该原则指出,你发送给其他人的内容应尽可能最小且符合要求,并且处理不符合要求的输入。
该原则的目标是构建稳健的系统。如果可以理解意图,它们可以处理不良的输入。但是,接受错误格式的输入可能存在安全隐患,特别是此类的输入未经过充分测试。
伊格森定律
曾经远离一个项目很长时间,然后回到它并想知道“什么白痴写了这个废话?” 才发现那个白痴是你?
伊格森定律非常准确地描述了这种情况:
任何你六个月或更长时间都没有看过的你自己的代码也可能是由其他人编写的。
请记住,下次您重新加入一个您已经离开数月的项目时。代码不再是你的代码,你现在的任务是改进别人的。
彼得原理
可以适用于管理人员(任何领域,而不仅仅是软件)的基本定律之一,是由加拿大教育家劳伦斯·J·彼得制定的彼得原则:
一个职位的候选人的选择是基于候选人在当前角色中的表现,而不是与预期角色相关的能力。
彼得原理揭示的问题是,员工往往会根据他们目前的表现得到评估,而他们的上级认为这些员工也能胜任不同的角色,即使他们目前的角色和预期的角色可能不一样。最终,此类晋升会将不合格的候选人置于权力的高位,在特别糟糕的情况下,您最终可能会在组织层级的每一步都出现尖头发的老板。
呆伯特原理
谈到尖头发的老板,漫画家斯科特·亚当斯(出版漫画《呆伯特》)提出了彼得原理的一个负面变体,他将其命名为呆伯特原理。彼得原理假设被提拔的工人实际上能胜任他们目前的职位,这就是他们首先获得晋升的原因。相比之下,呆伯特原则假设最不称职的人晋升最快。呆伯特原则通常是这样表述的:
不称职的员工将被提升到胜任员工之上的管理职位,从而将他们从实际工作中移除,并最大限度地减少他们可能造成的损害。
90-90 法则
因为事情总是会出错,而且人们在估计自己的技能水平方面是出了名的糟糕,1980 年代贝尔实验室的工程师 Tom Cargill 提出了一个最终被称为90-90 规则的东西:
前 90% 的代码占了前 90% 的开发时间。其余 10% 的代码占了其他 90% 的开发时间。
也许这解释了为什么这么多软件项目最终会超出预算并缺少功能。
帕金森定律
可以应用于估算艺术的最精明的观察可能来自英国海军历史学家CN Parkinson。他开玩笑地提出了一句叫做帕金森定律的格言,最初的理解是:
工作扩大以填补完成的可用时间。
在工作能够完成的时限内,工作量会一直增加,直到所有可用时间都被填满为止。
基于官僚机构的研究背景,该定律被应用于软件开发中。该理论认为,团队在截止日期之前效率低下,然后在截止日期前赶紧完成工作,从而使实际截止日期变得随意。
下次填写估算值时请记住这一点。
赛尔定律
经济学家兼教授Charles Issawi提出了一个后来被称为赛尔定律的想法,以哥伦比亚大学一位教授的名字命名。Issawi 对这条定律的表述如下:
在任何争议中,感情的强度与所涉问题的价值成反比。
简而言之,越不重要的事情,人们就会越激烈地争论它。
帕金森琐碎定律(AKA Bikeshedding)
赛尔定律直接适用于另一条适用于会议的定律,在这里我们再次遇到 CN Parkinson 的想法。帕金森琐碎定律指出:
花在任何议程项目上的时间将与所涉及的资金总额成反比。
帕金森设想了这样一种情况:一个委员会的任务是设计一个核反应堆。然后,该委员会花费了不成比例的时间来设计反应堆的自行车棚,因为任何普通人都有足够的生活经验来了解自行车棚应该是什么样子。显然,反应堆的“核心”功能更为重要,但它们是如此复杂,以至于普通人无法深入了解所有这些功能。因此,时间(和意见)被花在每个人都能理解但显然更微不足道的想法上。
墨菲定律
如果你担心那里出现问题,那里就会出错。
Murphy 定律在项目管理,软件开发和一般生活的所有领域都是可见的。在软件开发中,墨菲定律突出了一个关键:计算机做的是你告诉他们要做的事情,而不是你想要他们做什么。
古德哈特定律
当衡量标准成为目标时,它就不再是一个好的衡量标准。
Goodhart 软件开发定律的一个例子是代码行数。代码行数提供了一种衡量软件产品大小的方法。但是,当用作目标时,代码的质量会下降。
应该根据软件本身的结构进行精炼或分离,而不是一个混乱的意大利面条式代码。
加尔法则
一个复杂的系统可以从一个有效的简单系统发展而来。而从头开始构建的复杂系统也许将无法工作。
我们在许多生命的复杂系统中看到这个定律,例如,生命本身从单细胞生物开始,变得复杂。软件开发也不例外。
Gall 法则如果成立(它似乎是成立的),是用最小可行产品(MVP)开始软件产品开发的一个很好的理由。
扎温斯基定律
每个程序都会尝试扩展,直到它能够读取邮件。那些无法扩展的程序被那些可以扩展的程序所取代。
说到复杂性,Zawinski 定律表明,一旦建成,产品将继续扩大。他们添加了更多功能,直到它们不再扩展为止。
特征蠕变的实例反应了 Zawinski 在软件开发中的应用。随着更加简化的选项,臃肿的程序很快就会被淘汰。
卢巴尔斯基定律
还有一个错误。
对于所有编程最佳实践,更新和维护,总会有一个 bug 需要修复。或者还有一件事要调整,添加或学习。毕竟,程序员的工作从未完成。
所以,请记住,在软件开发方面,完成比完美更好。
软件开发的许多规律,无论是定律,原则还是模式,每个软件开发方法都有不同之处。这可能是一个有趣的见解,一个有用的教训,或一个简单的兴趣点。
阿姆达尔定律
阿姆达尔定律是一个显示计算任务潜在加速能力的公式。这种能力可以通过增加系统资源来实现,通常用于并行计算中。它可以预测增加处理器数量的实际好处,然而增加处理器数量会受到程序并行性的限制。
举例说明:如果程序由两部分组成,部分 A 必须由单个处理器执行,部分 B 可以并行运行。那么向执行程序的系统添加多个处理器只能获得有限的好处。它可以极大地提升部分 B 的运行速度,但部分 A 的运行速度将保持不变。
下图展示了一些运行速度的提升潜能的例子:
可以看出,50% 并行化的程序在使用大于 10 个处理单元之后的速度提升收效甚微,而 95% 并行化的程序在使用超过一千个处理单元之后仍然可以显著提升速度。
随着摩尔定律减慢,单个处理器的速度增加缓慢,并行化是提高性能的关键。图形编程是一个极好的例子,现代着色器可以并行渲染单个像素或片段。这也是现代显卡通常具有数千个处理核心(GPU 或着色器单元)的原因。
邓巴数字
邓巴数字是对一个人能够保持稳定社会关系的人数的认知极限——在这种关系中,一个人知道每个人是谁,也知道每个人与其他人的关系如何。而对这一数字的确切值则有着一些不同意见。邓巴指出,人仅能轻松地维持 150 个稳定的关系。这样的关系在一个更社会化的背景中,便是当你碰巧在酒吧里碰到这些人时候,你不会因为加入他们而感到尴尬。邓巴数字的估计值一般在 100 至 250 之间。
和人与人之间稳定的关系一样,开发人员与代码库的关系也需要努力维护。当面对大型、复杂的项目,或许多项目的归属权时,我们会依赖于约定、策略和建模过程来进行扩展。邓巴数字不仅在办公室规模的扩大的过程中举足轻重,而且在设置团队工作范围,或决定系统何时应该注重于辅助建模和组织管理开销自动化的工具时,也是非常重要的。将邓巴数字放入工程内容中进行类比,那就是您能加入并有信心随叫随到进行轮换的项目数(亦或是单个项目的规范化复杂性)。
技术成熟度曲线
我们倾向于过高估计技术在短期内的影响,并低估长期效应。—— 罗伊·阿马拉
技术成熟度曲线是高德纳咨询公司对技术最初兴起和发展的视觉展现。一图顶千言:
简而言之,这个周期表明,新技术及其潜在影响通常会引发一阵浪潮。团队快速使用这些新技术,有时会对结果感到失望。这可能是因为该技术还不够成熟,或者现实应用还没有完全实现。经过一段时间后,技术的能力提高了,使用它的实际机会会增加,最终团队也可以提高工作效率。罗伊·阿马拉简洁地总结了这一点:我们倾向于高估技术短期内的影响,并低估长期效应。
隐式接口定律
当 API 有足够多的用户时,你在契约中的承诺已不重要:你系统的所有可观察行为都将被某些人所依赖。 —— 海伦·赖特
隐式接口定律表明,当你的 API 有足够多的用户时,API 的所有行为(包括那些未囊括在公共说明中的一部分)最终都会被其他人所依赖。一个简单的例子是 API 的响应时间这种非功能性因素,还有一个更微妙的例子是:用户使用正则表达式判断错误信息的类型时,即使 API 的公共说明没有说明消息的内容,来指示用户错误的类型,一些用户也可能会使用并更改该消息,而这实际上会破坏 API 的使用。
过早优化效应
过早优化是万恶之源。—— 高纳德
在高纳德的《goto 语句的结构化编程》论文中,他写到,程序员花了大量的时间思考和担心非关键部分的速度,这些尝试在调试以及维护时会产生强烈的副作用。我们大约 97% 的时间浪费在小效率上。过早优化是万恶之源。我们应该关注 3% 的关键部分。
然而,在我们真正需要优化时,过早优化可以定义为优化。
普特定律
技术由两类人主导,一类是纯粹的管理人员, 一类是纯粹的技术人员。
普特定律常常遵循普特推论:
每一个技术层次,假以时日,能力将逆转。
这些结论表明,由于各种选择标准和群体组织的趋势,技术组织的工作层面将有一些技术人员,以及一些不了解复杂性和挑战的管理人员。这种现象可能是由于 The Peter Principe 或 Dilbert's Law 造成的。
但是,应该强调的是,诸如此类的定律是一种广泛的概括,可能适用于某些类型的组织,而不适用于其他组织。
复杂性守恒定律
系统中的某些复杂性是无意的。这是由于结构不良,错误或者糟糕的建模造成的。这种无意的复杂性可以减少或者消除。然而,由于待解决问题固有的复杂性,某些复杂性是内在的。这种复杂性可以转移,但不能消除。
该定律有趣的一点是,即使简化整个系统,内在的复杂性也不会降低。它会转移到用户,并且用户必须以更复杂的方式行事。
抽象泄漏定律
在某种程度上,所有非平凡的抽象都是有泄漏的。—— 乔尔斯·波尔斯基
该定律指出,通常用于简化复杂系统的抽象,在某些情况下将底层系统泄漏出来,使得抽象表现出意外的行为。
例如加载文件并读取其内容。文件系统 API 是较低级别内核系统的抽象,它们本身是与磁盘(或 SSD 的闪存)上的数据更改相关的物理过程的抽象。在大多数情况下,处理文件(如二进制数据流)的抽象将起作用。但是,对于磁盘驱动器,顺序读取数据将比随机访问快得多(由于页面错误的开销增加)。但对于 SSD 驱动器,此开销不会出现。需要理解基础细节来处理这种情况(例如,数据库索引文件的良好结构可以减少随机访问的开销),开发人员需要合理的抽象,来处理不同的细节。
当引入更多的抽象时,上面的例子会变得更复杂。Linux 操作系统允许通过网络访问文件,但在本地表示为普通文件。如果存在网络故障,这种抽象将会泄漏。
描述该定律的文章表明,过度依赖抽象,加上对底层过程的理解不足,实际上使得问题在某些情况下更加复杂。
Unix 哲学
Unix 哲学指软件组件应该很小,并专注于做一件特定的事情。将小而简单以及定义良好的单元组合在一起,而不是使用大而复杂的多用途程序,可以更轻松地构建系统。
像微服务架构这种现代实践可以认为是这种哲学的应用,其中服务很小,集中于做一件特定的事情,由简单的构建块组成复杂的行为。
Spotify 模型
Spotify 模型是团队和组织结构的一种方法,已被 Spotify 实验室推广开来。在此模型中,团队围绕功能而非技术进行组织。
Spotify 模型还普及了部落、行会以及章节的概念,这些是组织结构的其他组成部分。
沃德勒定律
任何语言设计中,讨论下面列表中某个要素所花费的总时间与其位置成正比。
语义 (Semantics)
语法 (Syntax)
词法 (Lexical syntax)
注释语法 (Lexical syntax of comments)
简而言之,在语义上花费一个小时,就要在注释语法上花费八个小时。
与帕金森琐碎定理类似,沃德勒定律指出,在设计语言时,与这些特征的重要性相比,花在语言结构上的时间过多。
第二系统效应
第二系统效应(second-system effect),又称第二系统症候群(second-system syndrome),由佛瑞德·布鲁克斯在《人月神话》中提出的经验概括。它认为,在完成一个小型、优雅而成功的系统之后,人们倾向于对下一个计划有过度的期待,可能因此建造出一个巨大、有各种特色的怪兽系统。第二系统效应可能造成软件专案计划过度设计,产生太多变数,过度复杂,无法达成期待,并因而失败。