登录
转载

GitHub标星1.6W+,程序猿不得不知道的“黑魔法开发指南”又火了

发布于 2020-11-11 阅读 229
  • GitHub
  • 定律
  • 法则
转载

当程序员谈论开发设计时,常常会聊到非常多的定律,而 GitHub 上的一个名为「hacker-laws」的仓库收录了一些最常见的定律、原则等,获得了 16.5k 的 Star。

还记得所有AI教程必提的「奥卡姆剃刀原则」吗?即:如无必要,勿增实体。

这条原则也被收藏,还有一些不太常见的费茨法则、盖尔定律、康威定律等,都被一一收入囊中。

写代码累了困了?那就看看这些法则吧

定律

90-9-1 法则(1% 法则)

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

现实世界的例子:2014 年,对四个健康的数字社交网络进行的一项研究发现,排名前 1% 的人创造了 73% 的帖子,紧随其后的 9% 平均占 25%,其余的 90% 的人平均占 2%。

类似的,帕累托法则也指出:生活中大多数事情不是均匀分布的。这个原则也被称为二八法则,重要的少数法则和因素稀疏原则。

帕累托法则 (The Pareto Principle or The 80/20 Rule)

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

帕累托法则可以帮你认识到大多数结果来自少数投入:

  • 某个软件的 80% 代码只占了总分配时间的 20%(相反,最难的 20% 代码部分占用了 80% 的时间)
  • 20% 的努力产生了 80% 的结果
  • 20% 的工作创造了 80% 的收入
  • 20% 的错误导致了 80% 的崩溃
  • 20% 的功能导致了 80% 的使用量

在 20 世纪 40 年代,公认为质量控制之父的美国罗马尼亚工程师约瑟夫·朱兰博士,开始将帕累托法则应用于质量问题

这个原则也被称为二八法则重要的少数法则因素稀疏原则

现实的例子:

  • 微软 2002 年的报告表明,修复最常出现的 20% 错误,将消除 Windows 和 Office 中 80% 的 错误和崩溃。

彼得原理 (The Peter Principle)

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

这是由劳伦斯·彼得提出的一个管理概念。彼得原理认为,擅长工作的人会得到提升,直到他们达到不再成功的水平 (即他们所“无法胜任的水平”)。基于此,由于他们资历更高,被公司开除的可能性较小 (除非他们表现非常糟糕)。而且他们将继续担任几乎没有本职技能的职位,即使那些原本让他们成功的能力在新工作中并无必要。

有的工程师对此特别感兴趣,它们最初从事的是深度的技术工作,但走上了管理其他工程师的职业道路——这意味着需要一个完全不同的技能树。

技术成熟度曲线法则

技术成熟度曲线是高德纳咨询公司对技术最初兴起和发展的视觉展现。一图胜千言:

简而言之,这个曲线表明,新技术及其潜在影响通常会引发一轮浪潮。

团队快速使用这些新技术,但有时会对结果感到失望,这可能是因为该技术还不够成熟,或者现实应用还没有完全实现。

经过一段时间后,技术的能力提高了,使用它的实际机会会增加,最终团队也可以提高工作效率。

罗伊·阿马拉简洁地总结了这一点:我们倾向于高估技术短期内的影响,并低估其长期效应

破窗效应

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

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

没那么常见的法则,但也暗藏工作秘诀

阿姆达尔定律

阿姆达尔定律是一个显示计算任务潜在加速能力的公式。这种能力可以通过增加系统资源来实现,通常用于并行计算中。

它可以预测增加处理器数量的实际好处,然而增加处理器数量会受到程序并行性的限制。

举例说明:如果程序由两部分组成,A部分必须由单个处理器执行,B部分可以并行运行。那么向执行程序的系统添加多个处理器只能获得有限的好处。

它可以极大地提升部分 B 的运行速度,但部分 A 的运行速度将保持不变。

下图展示了一些运行速度的提升潜能的例子:

可以看出,50% 并行化的程序在使用大于 10 个处理单元之后的速度提升收效甚微,而 95% 并行化的程序在使用超过一千个处理单元之后仍然可以显著提升速度。

随着摩尔定律逐渐失效,单个处理器的速度增加缓慢,并行化是提高性能的关键。

图形编程是一个极好的例子,现代着色器可以并行渲染单个像素或片段。这也是现代显卡通常具有数千个处理核心(GPU 单元)的原因。

林纳斯定律

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

简单地说,能够看到问题的人越多,有人解决过相关的问题或事情的可能性就越高。

最初该定律是用来描述开源模型对于项目的价值的,并适用于任意的软件项目。同时它也可以扩展到开发流程之中——更多的代码审查、更多的静态分析和多重测试可以让问题更加明显和容易识别。

林纳斯定律的一个更正式的说法如下:

如果有足够大的测试员和联合开发人员基础,那么几乎每个问题都能很快被特征化,从而让以前遇到过类似问题的人解决。

德墨忒尔定律

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

该定律表明,软件的一个单元应该只与其直接合作者交谈。

比如对象 A 引用了对象 B,对象 B 引用了对象 C,则 A 可以直接调用 B 的方法,但不应直接调用 C 的方法。所以如果 C 有一个 dothing() 的方法,A 不应该直接调用,而是用 B.getC().doThis()。

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

墨菲定律 (Murphy’s Law / Sod’s Law)

凡是可能出错的事就一定会出错。

墨菲定律 说明了如果一件事有可能出错,那么就一定会出错。

这是一句开发人员间的俗语,在开发、测试甚至在生产中都有可能会发生一些令人意想不到的事情。而这一定律也可以参考在英式英语中更为常见的 索德定理 :

如果某件事可能出错,那么它一定会在最糟糕的时候发生。

奥卡姆剃刀 (Occam’s Razor)

如无必要,勿增实体。

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

坎宁汉姆定律

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

帕金森定理 (Parkinson’s Law)

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

基于官僚机构的研究背景,该定律被应用于软件开发中。该理论认为,团队在截止日期之前效率低下,然后在截止日期前赶紧完成工作,从而使实际截止日期变得随意。

将这个定理与侯世达定律相结合,则会获得更加悲观的观点:为了在规定时间内完成工作,工作将增多,花费比预期更长的时间。

职场相关的原则

除了以上的这些法则,该仓库还给出了很多的原则。

死海效应原则

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

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

通常情况下,技术好的工程师很容易在其他的地方找到工作,并且他们往往也会这样做。而技能过时或技术薄弱的工程师则会留在公司,因为其他地方很难找到工作。如果这些工程师在公司里获得了加薪,他们会更愿意留在公司,因为在其他地方找到同等薪酬的工作会很有挑战性。

呆伯特原则

公司会倾向于系统地将工作能力差的员工提升到管理层,以使他们脱离工作流程,从而限制他们所能造成的损害。

技术相关的原则

单一功能原则

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

SOLID 的第一个原则。这个原则表明模块或者类只应该做一件事。实际上,这意味着对程序功能的单个小更改,应该只需要更改一个组件。例如,更改密码验证复杂性的方式应该只需要更改程序的一部分。

理论上讲,这使代码更健壮,更容易更改。知道正在更改的组件只有一个功能,这意味着测试更改更容易。使用前面的例子,更改密码复杂性组件应该只影响与密码复杂性相关的功能。变更具有许多功能的组件可能要困难得多。

开闭原则

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

SOLID 的第二个原则。这个原则指出实体(可以是类、模块、函数等)应该能够使它们的行为易于扩展,但是它们的扩展行为不应该被修改。

举一个假设的例子,想象一个能够将 Markdown 转换为 HTML 的模块。如果可以扩展模块,而不修改内部模块来处理新的 markdown 特征,而无需修改内部模块,则可以认为是开放扩展。如果用户不能修改处理现有 Markdown 特征的模块,那么它被认为是关闭修改。

这个原则与面向对象编程紧密相关,让我们可以设计对象以便于扩展,但是可以避免以意想不到的方式改变其现有对象的行为。

里氏替换原则

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

SOLID 的第三个原则。该原则指出,如果组件依赖于类型,那么它应该能够使用该类型的子类型,而不会导致系统失败或者必须知道该子类型的详细信息。

举个例子,假设我们有一个方法,读取 XML 文档。如果该方法使用基类型 file,则从 file 派生的任何内容,都能用在该方法中。 如果 file 支持反向查找,并且 xml 解析器使用该函数,但是派生类型 network file 尝试反向查找时失败,则 network file 将违反该原则。

该原则与面向对象编程紧密相关,必须仔细建模、层次结构,以避免让系统用户混淆。

接口隔离原则

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

SOLID 的第四个原则。该原则指出组件的消费者不应该依赖于它实际上不使用的组件函数。

举一个例子,假设我们有一个方法,读取 XML 文档。它只需要读取文件中的字节,向前移动或向后移动。如果由于一个与文件结构不相关的功能发生更改(例如更新文件安全性的权限模型),需要更新此方法,则该原则已失效。文件最好实现 可查询流 接口,并让 XML 读取器使用该接口。

该原则与面向对象编程紧密相关,其中接口,层次结构和抽象类型用于不同组件的 minimise the coupling。 Duck typing 是一种通过消除显式接口来强制执行该原则的方法。

依赖翻转原则

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

SOLID 的第五个原则。该原则指出,更高级别的协调组件不应该知道其依赖项的详细信息。

举个例子,假设我们有一个从网站读取元数据的程序。我们假设主要组件必须知道下载网页内容的组件,以及可以读取元数据的组件。如果我们考虑依赖反转,主要组件将仅依赖于可以获取字节数据的抽象组件,然后是一个能够从字节流中读取元数据的抽象组件,主要组件不需要了解 TCP、IP、HTTP、HTML 等。

这个原则很复杂,因为它似乎可以反转系统的预期依赖性(因此得名)。实践中,这也意味着,单独的编排组件必须确保抽象类型的正确实现被使用(例如在前面的例子中,必须提供元数据读取器组件、HTTP 文件下载功能和 HTML 元标签读取器)。然后,这涉及诸如 Inversion of Control 和 Dependency Injection 之类的模式。

切斯特森围栏 (Chesterson’s Fence)

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

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

该原则的名字来源于一则故事。一个男人横穿马路中央的栅栏,他向市长抱怨这道栅栏没有用还挡路,并要求拆除它。市长问他为什么要在那里建栅栏,那个人回答说不知道。市长接着说:“如果你不知道它的用途,我肯定不会让你把它拆了。你去查查它的用途,之后我可能会允许你拆掉它。”

哲学意味的原则

鲁棒性原则

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

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

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

不要重复你自己原则

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

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

与 DRY 相反的是 WET(功能实现两次或者喜欢打字 Write Everything Twice or We Enjoy Typing)。

实际上,如果你在两个或更多的地方有相同的功能,你可以使用 DRY 原则将它们合并为一个,并在任何你需要的地方重复使用。

你不需要它法则

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

极限编程原则告诫开发人员,他们应该只实现当前所需的功能,并避免实现未来需要的功能,仅在必要时才实现。

遵守这一原则可以减小代码库大小,同时避免时间和生产力浪费在没有价值的功能上。

KISS原则

保持简单和直白。

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

这一原则的最好例证便是约翰逊给设计工程师一些实用工具的故事。那时的他们正面临着一个挑战,即他们参与设计的喷气式飞机必须能够让普通的机械师在战场上仅仅用这些工具进行维修,因此,“直白”这个词应指的是损坏的事物本身和修复用工具的复杂度两者之间的关系,而非工程师们自身的能力水平。

最后

还有很多的法则和原则没有一一指出,需要的小伙伴请点击下面的链接打开查看。

hacker-laws 中文地址:https://github.com/nusr/hacker-laws-zh

前端GitHub 地址:https://github.com/biaochenxuying/FrontEndGitHub

平时如何发现好的开源项目,可以看看这篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目

往期精文

觉得有用 ?喜欢就收藏,顺便点个赞吧,你的支持是我最大的鼓励!

作者:天明夜尽
链接:https://github.com/FrontEndGitHub/FrontEndGitHub/issues/3

评论区

我是搬运工2号,没人自称1号

1

0

0

举报