资源预览内容
第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
亲,该文档总共7页全部预览完了,如果喜欢就下载吧!
资源描述
http:/www.moliying.com磨砺营 IT 教育版权所有为什么程序出故障?虽然自世界上第一位女程序员艾达洛夫莱斯(Ada Lovelace)在上世纪第一次看到通用计算的潜力以来我们已取得了很大进展,但是我们编写的软件还是错误百出。这些年来,尽管我们开发出许多高级方法来确保代码的成功,但是程序还是不断的出故障。原因何在?原因何在?虽然这个问题的答案多种多样,但我们还是决定提供一个务实的答案。程序员难免犯错。他们有时马虎了事。他们并不总是使用最佳工具或最佳实践。我在加州大学伯克利分校教面向对象编程这门课,我在学校教优秀编程实践所花的时间与帮助学生理解代码本身所花的时间相比只多不少。我在课堂上看到许多常犯的错误,本文就介绍其中几个常见错误。我还联系上了西北理工大学工程学院的詹姆斯A康纳(James A. Connor)教授,请他介绍其学生常犯的一些错误。我先来说几个。第一个错误:糟糕的注释方法。第一个错误:糟糕的注释方法。注释是程序里面计算机并不执行的那部分文本。它们被程序员写成附注的形式,用来解释代码里面发生的情况。我的好多学生避免给代码添加注释,也想不明白为何要占用实际编码的时间去编写一些注释。我最实用的例子来自我自己的生活。早在世纪之交前,我编写了版本 1.0 的 ZENPRESS,这是最古老的内容管理系统之一。我预计它会带来好几年的文章。14 年过后,它仍在管理许多文章,准备好了 75000 篇文章和 26 亿页的内容。最后,它运行所依赖的那个平台过时了。我不得不回过头去研究代码。2009 年,我把代码从原始平台移植到现代平台。我最近不得不再次改动,因为 PHP 一个关键的语言特性在版本升级后完全消失了。http:/www.moliying.com磨砺营 IT 教育版权所有19 年过后,我根本记不起所有这些代码是怎么运行的,但是由于我对代码作了详细的注释,所以可以说有了一份路线图。我可以查看代码,查看嵌入在代码里面的注释,然后进行修改。你在团队工作时,或者你的软件不归你监管时,注释也很重要。你的职业生涯可能发生变化,别人可能需要过来了解你的代码。注释将大有帮助。第二个错误:糟糕的变量命名。第二个错误:糟糕的变量命名。我会继续探讨这个主题:通过语言让代码一目了然。我会用一个例子来表明这点。假设你驾驶一辆每加仑汽油跑 20 英里的汽车,开了 100 英里。请问你用掉了多少汽油?这是个简单的例子,但是适用于我们的用途。假设你遇到了 a = b/c 这一行。a 指什么?b 和 c 又指什么?它们与你的其余代码有何关系?在编写程序十分钟后,你会记得一干二净。更不用说别人过来修改代码或编写更新版了。现在看看这个表达式:加仑 = 英里/每加仑行驶英里数。每一个变量的具体用途就一目了然。一个代表加仑,一个代表英里,另一个代表每加仑行驶英里数。很清楚。想一想为变量赋予清楚的英语(或者其他任何母语)名称与注释之间的关系。假设你从别人那里接过了一段代码,看到 a = b/c。这代码用来干嘛?你有何头绪吗?务必以一种代表其功能的方式来命名变量。那样可以节省大量的时间,减少许多头痛的问题。第三个错误:没有实验笔记(第三个错误:没有实验笔记(lablab notesnotes)。)。我在 1997 年年中开始编写 ZENPRESS,它在 1998 年 1 月份上线。遗憾的是,我当时匆忙完成了项目,没有花时间为这第一个版本编写实验笔记。此后我懊悔多次。从 1999 年 6月份开始(当时我开始编写版本 2),我就经常做实验笔记了。http:/www.moliying.com磨砺营 IT 教育版权所有实验笔记是代码注释之外的记录。科学家一直在使用实验笔记,作为其研发过程的日志或对话内容。实验笔记用来证明科学发现归谁所有,因为研究过程常常记录在科学家用来记录进度的每天日志中。实验笔记对程序员来说同样是一种有效的工具。我为 ZENPRESS 编写的上一份实验笔记是在今年 3 月份编写的,当时我不得不把 ZATZ 归档从一家主机托管提供商迁移到另一家。我还经常对自己的其他项目做实验笔记,由于能够回过头去查阅笔记,好多次帮了大忙。如果你还没有做实验笔记,现在就开始做。记下你做的任何变化,你的理由,你考虑后丢弃的代码,参考的实用资源,以及将来帮助你的任何其他内容。你还能帮助将来的同事或接手人如果你需要证明归属权,实验笔记还能起到证明的作用。第四个错误:不用一种人类语言编写。第四个错误:不用一种人类语言编写。我的学生要考试过关,不仅仅要编程,他们还要编写讨论区帖子,证明他们熟知某些编程概念。我们提出这个要求出于两个原因。当然,首先是为了证明熟悉概念。但是更为重要的是需要所有专业人员都有编写能力。我在这方面遭到学生们的反对。每学期都有学生高喊:“我想成为程序员,而不是编写者。”但是编程、工程、IT 和几乎所有专业工作都不可能在真空状态下存在。你需要通过编写来解释概念、推销想法、获得资金、要求澄清、准备提议,或者甚至为拿到更好的分数据理力争。开源项目的参与者在非常庞大的团队协同工作,他们保持同步的唯一手段就是编写清楚的、易于理解的信息。结论很简单:如果你想要从事专业工作或从事任何重要的项目,就需要用一种人类语言(比如英语)来编写,而不仅仅是用一种编程语言来编写。第五个错误:糟糕的代码格式。第五个错误:糟糕的代码格式。http:/www.moliying.com磨砺营 IT 教育版权所有毫无疑问,这里的一个主题就是:让代码易于了解。代码维护起来极耗费时间和财力。坦率地说,这也不是很有趣。最好还是能够把宝贵的工作时间用来添加功能,而不是花几周来钻研旧代码,试图搞清楚你(或者交给你代码的那个人)想要完成什么任务。本人就遇到过这种事,不仅仅是来自我的旧代码,还来自从别人手里接过的代码。我接手被丢弃的 WordPress 开源插件作为一个副带项目。据我所知,我接手的插件比其他任何人都要多。每个插件都是由别人开发的,为了保持插件可以正常使用,我不得不钻研陌生人的代码。幸好,那些开发人员都是高手,深谙编程之道。要不然,我也就无法接手这些项目了。但即便如此,要尽快上手还是困难重重。你能想象要是他们编写的代码结构很糟糕,那会有多难吗?我所说的结构是指代码的布局方式。我为学生制作了这方面的一段视频。有兴趣的话,大家可以上 YouTube 观看(https:/youtu.be/0u-I016Hxlw)。想一想你在网上读到的文章。一些文章格式优美,每一个段落之间有一行,一切都保持一致。可是有些文章都用一个大大的 blob 来排列,没法看清。每个程序员(或项目)都往往有一种编程风格。你的风格是什么样不是同样重要,只要保持一致就行。你需要让代码格式来帮助引导。比如说,在我的代码中,我坚持代码段之间的空行不得超过一行。如果我看到一段更大的空白区,我立即就知道这一点:哪里出现了异常,这个空白区里面可能有错误。你在深入研究代码时,要关注贵企业有没有编程风格。考虑为你的所有程序员定义一种编程风格,坚持采用清楚、易于维护的那一种风格。第六个错误:糟糕的错误检查。第六个错误:糟糕的错误检查。某位著名的将军曾经说过,遇到敌人时,计划根本不管用。我在此基础上改动一下,遇到用户时,你的代码根本不管用。尽管你认为自己知道用户会如何使用代码,但你其实并不知道,相信我。用户会搞坏你的代码。正确的处理方式就是借助测试和错误检查。错误检查是指这种做法:检查代码中每一次操作的结果。确保它符合你的预期,或者确保你的代码可处理意外的结果。http:/www.moliying.com磨砺营 IT 教育版权所有比如说,我的学生经常有一项任务:阅读文件。几乎所有的学生编写代码时会调用文件读取例程。他们检查用户是否取消对话框,但是很少查看文件是否实际上被读入,或者是否存在某种类型的系统错误。要是他们试图编写文件,那就更糟糕了。他们几乎从不真正查看文件是不是实际上保存起来。真是要命。不难发现这会有多糟糕。为了对付这种情形,你总是要考虑能不能绝对预测行为,然后认识到你不能绝对预测行为。你需要测试。测试并不是仅仅指你自己运行代码。测试意味着让实际用户(即行为可能无法预测的那些人)运行你的代码。你会发现这会提供大量的信息。第七个错误:使用打印输出语句,而不是真正的调试器。第七个错误:使用打印输出语句,而不是真正的调试器。这些年来我发现,使用不同语言的程序员往往有不同的文化。总的来说,那是由于他们构建不同种类的解决方案、使用不同的工具。这方面的一个例子就是我的 C#编程学生和与我一起开发一些项目的开源 PHP 开发人员之间的区别。几乎没有一个 C#程序员会考虑不使用一种符号调试器来调试代码。那是由于,C#本身是使用 Visual Studio 作为编程环境来编写的,调试器内置在里面。相比之下,我见到许多 PHP 开发人员认为只要插入 echo 语句或 var_dump 就足以帮助自己调试代码了。这一方面是由于,大多数 PHP 程序员往往在编辑器里面编程,而不是在开发环境里面编程。两者之间的一大区别就是调试器。那么,调试器是什么东东?简而言之,这种工具让你可以在代码运行时查看代码内部的情况。它就好比是代码的 X 光、超声波或 MRI。可以指令调试器在某些点停止,检查所有变量的状态。还可以指令调试器在某些条件下停止。你可以更改值,可以查看和分析值(不过分析有时是另一种工具)。工作效率方面的差异很大。如果你想更快速、极其准确地完成工作,就要确保使用一种真正的符号调试器。http:/www.moliying.com磨砺营 IT 教育版权所有以上就是我所介绍的几个常见错误,下面看看詹姆斯康纳教授介绍的几个。第八个错误:使用魔数(第八个错误:使用魔数(magicalmagical numbernumber)。)。许多程序员认为,他们只要编写一次代码,代码就能完美无缺。然而,为了优化企业软件和工业软件的长期生命周期成本,有必要编写能够抵御不断变化的条件的代码。这方面的一个典例就是魔数这个想法。我所说的魔数是指程序员认为总能经受得住时间考验的数字。以可能基于客户的采购数量的佣金计算为例。截至截稿时,佣金比例可能是三个百分点,即 0.03。现在,设想一下会如何编写这段代码:佣金= .03 *销售额。在这个上下文中,这个魔数就是 0.03。由于程序员认为这会是永远神奇地有效,他将 0.03 这个数字硬编码到代码中。这一切很好,但是每年的佣金往往发生变化。如果下一年佣金涨了 0.5%,涨到0.035,那么就很难在成千上万行代码中找到它。切忌使用魔数,而是在一个地方定义变量或常量,让代码使用那些变量。如果你预先定义 commission_rate,那么 commission = commission_rate * sale 之类的代码就不需要改动。要考虑的另一个方面是,无论你在何处找到魔数,都应该找到想要提供给用户的选项,以便用户可以在偏好设置部分可以设置。第九个错误:马虎对待的日期和时间。第九个错误:马虎对待的日期和时间。这里有个难题:一年有几天?365 天也许是平常的回答,但今年当然有 366 天。一天会有 365.25 天吗?这不可能。但我的一些学生认为,既然闰年每四年就出现一次,所以每年平均下来因此是 365.25天。在进行日期计算时,他们使用这个平均值;因而,结果根本不正确。常常更好的办法是使用系统库来计算日期,因为你计算的日期可能不是西方日历日期。不妨看一下时间方面的类似问题。每几年,由于地球转速减慢,有一天会多出一秒来,通常是在 6 月 30 日或 12 月 31 日那天。这叫作闰秒,因而,时钟可能从 11:59:59 走到11:59:60 再走到 12:00:00。这是第二个时间挑战。在使用夏令时的地方,交易的进行有可能乱套。比如说,先置入交易 A
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号