标签 编码 下的文章

只对代码无法表达的东西写注释

本文翻译自”Comments Only What the Code Cannot Say“,来自于《程序员应该知道的97件事》一书中的某个章节。

我们知道理论与实践之间存在差异。在实践中,这个差异远大于其在理论中所描述的那样 – 一份对注释(comments)的观察数据也证实了这一点。理论上,通常的注释代码的想法听起来是值得的:它可以为读者提供更多的细节,可以解释发生了什么事情。有什么能比自我帮助更具可帮助性的呢?然而在实践中,注释却经常变成一个破坏因素。与其他书面形式一样,编写好的注释也是有技巧的。这个技巧的主要内容是知道何时不写注释。

如果代码书写得不合乎语法规范,那么编译器、解释器以及其他一些工具会提出异议。如果代码在某方面功能不正确,评审、静态分析、测试以及在产品环境下的日常使用会发现绝大多数Bug。然而对于注释呢?在《The Elements of Programming Style》一书中KernighanPlauger曾指出“如果注释是错误的,那么它带来的价值就是零(甚至是负值)”。可是就是这样的注释却经常以一种编码错误所不能的方式散布并存活于代码库中。它们会持续不断地分散你的注意力,提供误导信息,细微但却持续地影响着程序员的思维。

那些在技术上没错,但却没有给代码带来任何价值的注释怎么样呢?这类注释简直就是噪音。重复描述代码含义的注释没有为读者提供任何额外价值 – 先用代码表达,再用自然语言复述不能让其看起来更加真实。被注释掉的代码不是可执行代码,所以无论对读者还是对代码运行时它都无法起到任何有用的效果。它自身也会很快地变得陈旧。版本相关的注释以及被注释掉的代码试图解决有关代码版本和历史的问题。但这些问题已经被版本控制工具(更加有效地)解决了。

代码库中普遍存在的噪音类注释以及错误注释助长了程序员们忽略所有注释的行为,他们要么略过注释,要么采取积极措施将注释隐藏起来。程序员是足智多谋的,他们会绕过任何被认为可能会造成破坏的事物:将注释折叠起来;更换颜色样式,使得注释的颜色与背景色相同;编写脚本过滤掉注释。为了使代码库免遭程序员们滥用聪明才智所带来的破坏,降低因忽视真正有价值的注释所带来的风险,我们应该像看待代码那样看待注释。每条注释都应该为读者带来一些价值,否则这些注释就是无用的,应该被删除或重写。

那么,什么才是有价值的呢?注释应该表达那些代码没有表达以及无法表达的东西。如果一段注释被用于解释一些本应该由这段代码自己表达的东西,我们就应该将这段注释看成一个改变代码结构或编码惯例直至代码可以自我表达的信号。我们重命名那些糟糕的方法和类名,而不是去修补。我们选择将长函数中的一些代码段抽取出来形成一些小函数,这些小函数的名字可以表述原代码段的意图,而不是对这些代码段进行注释。尽可能的通过代码进行表达。你通过代码所能表达的和你想要表达的所有事情之间的差额将为注释提供了一个合理的候选使用场合。对那些代码无法表达的东西进行注释,而不要仅简单地注释那些代码没有表达的东西。

By Kevlin Henney

使用正确的算法和数据结构

本文翻译自”Use the Right Algorithm and Data Structure“,来自于《程序员应该知道的97件事》一书中的某个章节。

一家拥有多个分行的大银行抱怨说他们为出纳员新买的计算机运行得太慢了。这件事儿发生在电子银行以及ATM机使用普及程度远不及现在的那个年代。人们更多的是亲自到银行办理业务,这些运行超慢的计算机使得大家排起了长队。因此,这家银行威胁计算机供货商要结束他们之间的供货合同。

计算机供货商派出了一个性能分析和调优专家查找计算机运行缓慢的原因。这个专家很快就发现了一个运行在终端的特定程序几乎消耗掉了CPU的所有处理能力。他使用了一个程序分析工具将程序展开,并找到了那个导致计算机运行缓慢的罪魁祸首。其源码如下:

for (i = 0; i < strlen(s); ++i) {

    if (… s[i] …) …

}

这里的字符串s的平均长度有上千个字符。这段代码(由这个银行编写的)很快被修正了,并且这家银行的出纳员自从那以后工作得很开心…

难道程序员不应该做得更好一些并且不去使用那些无用的二次阶复杂度算法吗?

每次strlen调用都会遍历字符串中上千个字符里的每个字符以找到字符串的结尾null字符。不过,这个字符串永远不会改变。如果事先得到该字符串的长度,这个程序员本可以节省数千次对strlen的调用(以及数百万次循环的执行):

n = strlen(s);

for (i = 0; i < n; ++i) {

    if (… s[i] …) …

}

每个人都知道这句格言:“首先使其能工作,然后再考虑让其更高效地工作”,这可以避免微小优化导致的缺陷。不过上面的例子几乎可以让你相信这个程序员遵循的是权谋家的节拍“首先使其缓慢地工作”。

这种草率的事情你可能不止遇到过一次。这不仅仅是一件“不要重新发明轮子”的事情。有些时候新手程序员在没有仔细考虑的前提下就开始写代码,然后突然意外地“发明”了冒泡排序。他们甚至可能为其自夸一番。

选择正确算法的另外一方面是数据结构的选择。这会导致很大的差异:用一个链表表示你要搜索的一个具有百万项元素的集合-与用一个哈希数据结构或一个二叉树相比-这会对用户对你的编程能力的评价产生较大影响。

程序员不应该重新发明轮子,并且应该尽可能地使用现有的库。但是为了能避免类似上面银行发生的问题,他们应该进行一些有关算法以及算法规模评估的培训。难道这只是现代文本编辑器中的华而不实才使得他们运行起来就像是上世纪80年代的老程序一样缓慢吗,比如WordStar?许多人说编程中的重用是最为重要的。不过,最重要的是,程序员应该知道何时重用、重用什么以及如何重用。为了做到这些,他们必须拥有问题域以及算法和数据结构的知识。

一个优秀的程序员也应该知道何时使用一个性能较差的算法。比如,如果问题域规定永远不会多于五个元素(就像是在掷骰子游戏中骰子的个数),你知道始终最多对5个元素进行排序。在这种情况下,冒泡排序实际上也许才是进行排序的最高效的方式。每个人都有得意的那天。

所以,阅读一些好书 – 并且确保你理解了书中所讲的内容。如果你真地读过Donald Knuth的“计算机编程艺术”,你也许甚至很幸运:找到一处作者犯下的错误都可以得到Donald Knuth的面额为2.56美元的支票。

By JC van Winkel

 

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats