定律或称法则,可以指导我们并让我们在同伴的错误中学习。这篇文章中,我将介绍我每次设计或实现软件时出现在我脑海的五大定律。其中有些和开发有关,有些和系统组织有关。它们可以帮助你成为合格的软件工程师。

墨菲定律

“凡事可能出错,就一定出错。”

“凡事可能出错,就一定出错。”这条定律来源于 Edward Murphy —— 一名航天工程师在 50 年代初对火箭测试失败的回应。这条定律给我们的启示是永远在系统关键地方使用防御性设计,因为系统某些地方总会出错!这条定律很容易引入软件工程领域。当你将软件暴露给终端用户,他们会创造性地输入一些出人意料的内容,使系统宕机。所以你需要让你的软件足够健壮,能够检测并警告非预期行为。

当你在机器上运行软件时,任何地方都有可能发生问题 —— 从硬盘上的系统到数据中心的电力供应。所以你必须确保你设计的架构在每个层级都可以应对故障。我曾经有机会领略过几次墨菲定律。

举个例子,我曾经在一个批处理框架中使用字符串“null”来表示空值,我并不认为这有问题,直到有个名字叫“Null”的用户提交了一个交易订单,我们的报表流程中断了几个小时…… 还有一次,在另一个项目中。

当所有东西都准备好部署到生产环境了,突然 Azure 基础设施故障导致我们运行自动化脚本的服务器宕机了。现实世界中的经验教训提醒着我生活的艰难 —— “凡事可能出错,就一定出错”。所以,心中牢记墨菲定律,设计健壮的软件。

Knuth定律

“在(至少大部分)编程中,过早优化是万恶之源。”

“在(至少大部分)编程中,过早优化是万恶之源。”这条定律也是 Donald Knuth 的经典语录之一,它告诫我们不要过早优化应用程序中的代码,直到必须优化时再优化。

的确,简单易读的源码可以满足 99% 的性能需要,并能提高应用的可维护性。最开始使用简单的解决方案也让后期性能出现问题时更容易迭代和改进。垃圾自动回收的编程语言中,字符串的连接常常是过早优化的例子。

在 Java 或 C# 中,String 对象是不可变的,我们学会使用其他结构动态创建字符串,比如 StringBuilder。但事实上直到你分析完个应用程序前,你并不知道 String 对象创建了多少次并对性能的产生多大影响。所以首先编写尽可能整洁的代码,之后在必须的时候再优化,往往这样做更有意义。

然而,这条规则并不应该阻止你去学习编程语言的性能权衡和正确的数据结构。并且,正如所有其他性能问题,你在优化前要测量开销。

North定律

“每一个决定都是一次权衡”

好吧,我承认这是取自 Dan North 的演讲 Decisions,Decisions,它目前还不是公认的定律。但这条语录影响了我做的每个决定,所以我把它放在这。

开发者日复一日的生活中,我们每天都做无数个大大小小的决定。从命名变量到自动化(手动)任务,再到定义平台架构。

这条语录强调无论你做的选择是什么,你总会放弃一个或多个选项

但这不是最重要的。最重要的是理智地做出决定,了解其他选项,清楚你为什么不选择它们。你要始终根据当前你掌握的信息来权衡并做出决定。

但是如果后来你了解到新的信息,并发现之前的决定是错误的,这也没关系。关键是记清楚你为什么做出那个决定,重新评估新的选项之后再做出新的理智的决定。

重复一遍: 每一个决定都是一次权衡

大家应该知道计算机优化的2大常用办法:

  • 用空间换时间:譬如缓存
  • 用时间换空间:譬如压缩

每个功能都有其侧重点,譬如追求性能,或者追求内存/存储空间最小化,很多时候,我们只能在这两者之间做取舍、平衡。

所以,做出选择并对所有选项心知肚明。

Conway定律

“系统设计的架构受限于生产设计,反映出公司组织的沟通架构”

“系统设计的架构受限于生产设计,反映出公司组织的沟通架构”在 60 年代,一位名叫 Melvin Conway 的工程师注意到公司组织结构影响到他们开发的系统的设计。他用一篇论文描述了这个观点,并命名为“Conway定律”。

这条定律很适用于软件开发领域,甚至体现到代码层面上。交付软件组件的各个团队组织结构直接影响到组件的设计。

举个例子,一个集中式的开发者团队会开发出各组件耦合的整体应用。另一方面,分布式的团队会开发出单独的(微)服务,每一部分关注点分离清晰。这些设计没有好坏之分,但它们都是受到团队沟通方式的影响。在全球有大量独立开发者的开源项目,通常是模块化和可重用库,这就是很有说服力的例子。如今,将大的集成应用解耦成微服务已成趋势。这很棒,因为这可以加速交付使用项目。

但你也应该牢记 Conway定律,在公司组织构建中投入与技术开发同样多的工作。

琐碎定律(帕金森琐碎定律)

“组织中的成员往往会把过多的精力花费在一些琐碎的争论上,而真正重要的决议反而可以轻松过关”

这条定律论点是在会议中花费的时间与事情的价值成反比。的确是这样,人们更愿意把注意力和观点放在他们熟悉的事物上,而不是复杂的问题上。

帕金森给出一个例子,一场会议中,成员们讨论两件事:为公司建核反应堆和为员工建车棚。建反应堆是一件巨大而复杂的任务,没有人能完全掌控全局。他们完全信赖流程和系统专家,并很快接受了项目。

另一边,建车棚是一般人都可以做的,每个人都可以对颜色有意见。事实上,每个会议成员都会表达自己的意见,使得建车棚的决议所花费的时间远远超过建反应堆的。

这条定律在软件行业十分出名,这个故事随后也被称为车棚效应

举个例子,开发者会花费更多时间到讨论正确缩进或函数命名,而不是讨论类的职责或应用架构。这是因为每个人都能认知几个字符的变动,但项目架构的变动则需要巨大的认知负载

你能注意到的车棚效应的另一个例子是 Scrum 演示。不要误会我,我喜欢演示,我认为这是一个很好的机会来面对用户并获得对应用程序的反馈。但通常 Scrum 演示过程中的讨论会转向琐碎问题,而不是审视全局。这些讨论也很重要,但你应该注意权衡更重要更复杂的问题。

一旦你了解这种规律,你将在会议和交流中发觉这种行为。我并不是让你在每次讨论中避免“小”问题,提高你的意识可以帮助你关注真正的问题,并为这些会议做好准备。

每个程序员都应该知道的5个定律相关推荐

  1. 使用Mono平台前,请牢记产品观点(所有.Net程序员都建议知道的)

    技术领域有很多让人深感困惑的地方,不管是架构师.设计师还是程序员,在完成任务之余,偶尔都有自责的地方:程序员在使用新技术完成任务的时候,有时会觉的自己旧技术都没有完全掌握,使用新技术有些好高骛远:设计 ...

  2. 每个程序员都应该知道的10件事!

    如果你已经编程了一段时间,并且想学习编程,那么你可能在想什么才是一个好的程序员?计算机科学与技术专业毕业生能做些什么,来为软件开发职业生涯做准备? 在本文中,我将分享10件我认为每个程序员都应该知道的 ...

  3. 每个程序员都应该知道的GitHub Repos

    GitHub是领先的Git存储库托管服务,其中包含许多代码存储库,库等的源代码. 在本文中,我将为每个开发人员介绍GitHub存储库从播客到免费书籍再到学习路线图 1.Awesome Resource ...

  4. 每个程序员都必须知道的 8 种数据结构

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 快速介绍8种数据结构 数据结构是一种特殊的组织和存储数据的方式,可 ...

  5. 网优谷程序员都需要知道的8个冷知识

    想要成为一名成功的程序员,我们除了了解不同编程语言的设计思路,也应当了解编程的发展历史,从而判断未来的编程技术将走向何方.接下就为大家普及下计算机发展历程中的8个冷门小知识! 01 第一台电脑为蒸汽驱 ...

  6. 程序员都需要知道的8个冷知识

    " 想要成为一名成功的程序员,我们除了了解不同编程语言的设计思路,也应当了解编程的发展历史,从而判断未来的编程技术将走向何方.接下就为大家普及下计算机发展历程中的8个冷门小知识! " ...

  7. 每个程序员都应该知道的8个Linux命令

    为什么80%的码农都做不了架构师?>>>    摘要:Linux里有很丰富的各种命令,有些是很难用的.然而,学会了前面说的这8个命令,你已经能处理大量的log分析任务了,完全不需要用 ...

  8. 优秀的程序员都应当知道的11个警句

    1. 技术只是解决问题的选择,而不是解决问题的根本 我们可以因为掌握了最新的 JavaScript 框架 ahem.Angular 的 IoC 容器技术或者某些编程语言甚至操作系统而欢欣雀跃,但是这些 ...

  9. 小黄鸭调试法,每个程序员都要知道的

    花了一下午(或一天)在试图解决某个 Bug,后来才知道解决方案很简单,当时就是没有想到. 有个同事正好路过,看到你愁眉苦脸的,问你"怎么了呀?" "噢,是这样的.我遇到了 ...

最新文章

  1. oracle导入中文数据出现乱码
  2. android竖直和横向,如何在android中为纵向和横向模式定义不同的控件
  3. 软件测试的现实和理想
  4. 解决在TP5中无法使用快递鸟的即时查询API
  5. 183.从不订购的客户
  6. python html表格模版,python-如何使用模板(例如Jinja2)将列值列表呈现到表中
  7. 江苏计算机二级c语言考试范围,江苏省计算机二级C语言考试大纲
  8. 多个ai文件合并成pdf_AI打开多页PDF教程.pdf
  9. springboot办公OA考勤请假系统java
  10. ORA-00932: 数据类型不一致: 应为 -,但却获得 -
  11. Python 实验二 tkinter 版小学数学口算题生成器设计与实现
  12. 【C语言】十进制转换二进制
  13. web前端网页制作思路(只是思路)
  14. 为何说张三丰是个优秀的程序员?
  15. 基于Docker的frp内网穿透
  16. 智慧城市服务平台硬件采购清单(参考)
  17. 毛星云opencv之SHi-Tomasi角点检测综合程序
  18. 信号完整性之眼图(eye)理解(一)
  19. 论计算机叫兽们与林纳斯·托瓦兹
  20. 微透镜阵列的主要应用_阵列的应用

热门文章

  1. 在PS中如何进行图文互排,且层的使用……
  2. SQL 2000 中如何 纵表变横表
  3. 《深入理解Android:卷III A》一一第3章 深入理解AudioService
  4. MyBatis学习总结(4)——解决字段名与实体类属性名不相同的冲突
  5. Screen Saver(屏幕保护设置) in Cocoa
  6. Close2Tray将程序关闭到系统栏
  7. vsftp 简易部署使用
  8. 怎么用程序实现调用Android手机的拍照功能
  9. SQL Servr 2008空间数据应用系列一:空间信息基础
  10. oracle trunc()函数用法