你是否 diss 过别人的代码?| 怎样的代码才算优秀?

简介: 你一定在内心吐槽过他的代码太烂:没注释、逻辑混乱、到处都是 magic number、实现方案过时、耦合严重、一改就出 bug。 此时心中的怒火油然而生,仿佛自己是正义的化身。。。

你一定在内心吐槽过他的代码太烂:没注释、逻辑混乱、到处都是 magic number、实现方案过时、耦合严重、一改就出 bug。

此时心中的怒火油然而生,仿佛自己是正义的化身,要代表月亮消灭这样的代码,甚至拼写错误也可以成为你 diss 的点。稍等片刻,先抑制一下燃烧的小宇宙,你有没有认真想过“到底什么样的代码才算的上优秀?”

在看了 Gerald M. Weinberg 的《The Psychology of Computer Programming》后让我有了不一样的认识。不过我觉得这是一个开放问题,不同情况下会有不同答案,欢迎讨论。

这是代码人生系列的第一篇,文章目录如下:

  1. 你是否 diss 过别人的代码?—— 怎样的代码才算优秀?
  2. 程序员和领导对项目delay的理解是不是有偏差?
  3. 来自程序员老婆的吐槽
  4. 成功、瑜伽、黄晓明 | 中年程序员对成功的认真思考
  5. 一个码农对项目的非分之想

可行性

作者给出的第一个标准是“程序的可行性”,它是指对于任何一种约定的输入,程序都能给出期望的输出。毕竟可行的程序总比不可行的要好。在不满足可行性前提下的优越性能,高可扩展性都不值一提。

但不可否认的是,我们脑子里成天考虑的是这些次要问题。甚至会形成“不优雅就是垃圾”的价值观,好像只有这样才可以在内心自恃高人一等。获得这种莫须有的优越感的代价可能是写出了不可行的代码,捡了芝麻丢了西瓜。

引用一段原文:

如果程序根本无法正常运转,对其效率、适应性及生产成本的评估就毫无意义。无论如何,我们需要务实一些,需要承认:也许根本没有哪个完美的程序曾经被写出来过。每一个真正大型和重要的程序都必然包含很多个纰漏。所以对程序进行评估时,必须考虑到其不完美的一面。

按时性

作者给出的第二个标准是“按时性”。

即使不考虑可行性的问题,效率的问题仍然不是最重要的。程序开发中经常遇到一个问题是要符合开发的日程计划,推迟完成的程序常常没有意义。

我们不得不比较一下,到底是一个可能在未来完成的高效程序带来的潜在节省更大,还是没有一个程序损失更大。现实中,往往是后者的损失更大。

真正困扰人们的并非是预先估计的平均开发时间,而是实际消耗时间的标准偏差。就好比大多数人宁可每天早上花固定的10分钟等公交车,也不愿意每周有4天只等1分钟,而最后一天等26分钟,尽管就平均等待时间而言,后一种方案只需要6分钟,但由于某次无法预测的长时间等待就会打乱计划,这点好处无法弥补其损失。所以宁可承诺一个更留有余地的排期,然后按时完成。而不是承诺一个满打满算的排期,然后delay。

开发过程中遭遇的各种意外导致实际消耗时间和预估时间形成方差,这一问题是值得我们深入思考的。如何提前感知不确定性,如何快速解决意外,是一项需要不断提升的能力以减小方差。

适应性 & 效率

作者给出的第三个标准是“适应性”,即程序的可扩展性。紧跟其后的标准是“效率”,即程序运行的性能。

总算轮到了本以为重要的标准,作者的一席话描述地入木三分:

在软件生命周期内,多数程序都会被修改,无论其经验的多少,绝少有哪位程序员能反驳这一论断。既然如此,为什么在必须修改以前的程序时,我们总是觉得这项任务如此艰巨,以至于往往决定弃之不用,干脆自己从头写起呢?只要阅读过程序,我们就会透过这些程序发现:实际上,很少有哪位原作者会考虑可能的后续修改。

作者还提了两个问题来表达程序员的矛盾之处:

在编写程序时,你曾经有多少次想到过它在未来可能被别人修改?反过来,在修改别人程序时,你又曾经咒骂够几回?

之所以把适应性和效率放在一起讨论,是因为它们俩会此消彼长,作者用 Fisher 定理来证明这个观点:

Fisher定理:一个系统对某一特定环境适应性越强,它适应新环境的能力也就越弱。

如果强调的是程序的效率,那么我们往往会追求紧密式的代码,而如果在未来要对这些代码进行修改,那将会非常棘手。如果使用的是更高层的语言,那么为了使程序更高效,我们往往需要深入到机器语言层。这种做法至少抵消了原本用更高层语言编程的一个好处 —— 在不同机器之间的可移植性。其实际效果是,我们将被局限于特定的某台计算机或特定的某个实现。

回想设计模式,无一例外是通过增加一层抽象以达到可扩展的目的,这样的设计增加了类的数量,类的构建和类方法调用的都会消耗空间和时间的性能,降低了效率。而且它让功能的实现变得更加间接,也增加了理解成本,降低了沟通效率。

但作者认为性能问题不是问题:

运行效率正在成为计算中一个日益不明朗的问题,随着单位计算能力成本的逐年下降,以及单位程序开发成本的不断提高,在程序开发方面比在产品方面投资更多的典型做法,早已不合时宜。因此我们期望,随着岁月的推移,我们听到的关于效率的言论将会越来越少。

紧接着依然是两个耐人寻味的问题:

你是否曾经因为追求效率而延误了工作进度?反过来,是否曾经因为要赶时间完成而没有做到尽善尽美?

但有趣的是,面试时,极少有公司是按照上述的优先级来考察候选人的,通常的考察优先级正好相反,即使有算法笔试也是把重点放在实现方案的内存性能或时间性能上,并不会对程序的正确性进一步追究。

目录
相关文章
|
IDE 算法 开发工具
面向 CV 编程:COPY 了别人文章中的代码,想让代码能像作者一样跑通,应该注意什么呢?怎样才能让代码愉快地跑起来呢
一千个读者,一千个哈姆雷特,写代码也是如此,不同人,理解不同,逻辑不同,同一道题,代码各有千秋,所以出现的问题也是千奇百怪;预期结果就一个,解法却千千万。正如列夫托尔斯泰的安娜卡列尼娜中所说:幸福的家庭千遍一律,不幸的家庭各有各的不幸,但是主要不离题万里,错误基本能在一个常见的范围。 有人写代码是为了生计,有的人写代码仅仅是自己的兴趣使然。应该大多人都是第一种情况,我也一样,到了大学才拥有自己的第一台电脑,那时候智能手机刚出现,再往前倒推几年,手机都是个稀罕物,没有条件所以跟兴趣不沾边,唯一沾点边的是以前我喜欢刷竞赛题,锻炼逻辑,对学习算法有点帮助,但是作用有限。甚至有些人对自己所选的专业一无
1004 2
面向 CV 编程:COPY 了别人文章中的代码,想让代码能像作者一样跑通,应该注意什么呢?怎样才能让代码愉快地跑起来呢
|
SQL 存储 监控
聊聊那些年遇到过的奇葩代码
无论是开发新需求还是维护旧平台,在工作的过程中我们都会接触到各种样式的代码,有时候会碰到一些优秀的代码心中不免肃然起敬,但是更多的时候我们会遇到很多奇葩代码,有的时候骂骂咧咧的吐槽一段奇葩代码后定睛一看作者,居然是几个月以前自己的写的,心中难免浮现曹操的那句名言:不可能,绝对不可能。
聊聊那些年遇到过的奇葩代码
|
程序员
代码界10个最“牛叉”的代码注释
要说到代码注释这个东西吧,其实很神奇,因为不管写不写注释,其实对于代码的运行没有任何的影响,注释的长短也没关系,因为编译器会对于所有的代码注释都是过滤掉的,其实注释非常重要,对后期的代码维护和重构至关重要,但是其实很多程序员童鞋在写代码时往往并不注意注释,所以导致自己回头看自己的代码时也都忘了写的是什么,本文给出了 StackOverflow 网友针对“你看到过的最好的代码注释是什么样的?”这个问题给出的回答的前10条。
6288 0
|
Python
又烧脑又炫技还没什么用,在代码里面打印自身
又烧脑又炫技还没什么用,在代码里面打印自身
213 0
又烧脑又炫技还没什么用,在代码里面打印自身
|
编译器
为何代码没错,却出不来结果,你可能...
为何代码没错,却出不来结果,你可能...
137 0
为何代码没错,却出不来结果,你可能...
|
安全 Java
老爷子这代码,看跪了! (下)
老爷子这代码,看跪了! (下)
136 0
老爷子这代码,看跪了! (下)
|
Java 程序员
老爷子这代码,看跪了! (中)
老爷子这代码,看跪了! (中)
145 0
老爷子这代码,看跪了! (中)
|
Java
老爷子这代码,看跪了! (上)
老爷子这代码,看跪了! (上)
152 0
老爷子这代码,看跪了! (上)
|
Cloud Native Devops Java
被解救的代码 - 代码即服务时代来了!
人类对自由的追求从未停止,我们用战斗获得民族自由,我们用代码获得双手自由,同时代码作为服务器的奴隶,也开始蠢蠢欲动,革命已经开始,当代码翻身做主,作为开发者的我们又该如何适应新时代的到来?
|
Java 程序员 Apache
写完这段代码,就被开除了……
最近在Java技术栈微信公众号粉丝微信群里看到一张图,说是刚写完这段下面这段代码就被开除了。