it-swarm.cn

编码时如何减少错误数量?

没有人能做到完美,无论我们做什么,我们都将不时产生包含错误的代码。在编写新软件和更改/维护现有代码时,有哪些方法/技术可以减少产生的错误数量?

30
GSto

避免花哨的编码。代码越复杂,出现错误的可能性就越大。通常在现代系统上,编写清晰的代码将足够快且足够小。

使用可用的库。没有编写实用程序例程的错误的最简单方法是不编写实用程序。

学习一些更复杂的东西的正式技巧。如果情况复杂,请用笔和纸钉住它们。理想情况下,了解一些证明技术。如果我能证明代码正确,那么除了容易解决的大而笨拙的明显错误外,几乎总是好的。显然,这只是到目前为止,但是有时您可以正式地推理一些小而复杂的事情。

对于现有代码,请学习如何重构:如何经常使用自动化工具对代码进行小的更改,使代码在不更改行为的情况下更具可读性。

不要做得太快。花一点时间做正确的事情,检查您所做的事情,并思考您所做的事情,可以在以后获得大量的回报。

编写代码后,请使用所需的功能使其变得更好。单元测试很棒。您通常可以提前编写测试,这可能是一个很好的反馈(如果始终如一,这是测试驱动的开发)。编译警告选项,并注意警告。

让其他人看一下代码。正式的代码审查很好,但是可能不方便。拉取请求,如果您的scm不支持请求,则类似。好友检查可能不太正式。配对编程可确保两双眼睛观看所有内容。

58
David Thornley

单元测试使您减少第二次弹出的错误的数量。如果您在代码中发现错误,则编写单元测试将确保以后不会再次出现。 (此外,有时很难考虑所有情况并预先编写成千上万的单元测试)

30
Ryan Hayes

尽管我的主要语言是C++和Python,但我已经开发了一种相当实用的编程风格。我发现,如果将所有上下文传递给该函数完成其工作所需的函数(或方法),并返回我要查找的有意义的数据,则我的代码将变得更加健壮。

隐性状态是敌人,根据我的经验,错误是第一大漏洞来源。此状态可以是全局变量或成员变量,但是如果结果取决于未传递给函数的内容,则您会遇到麻烦。显然,消除状态是不可行的,但是将其最小化会对程序可靠性产生巨大的积极影响。

我还想告诉我的同事,每个分支(如果同时存在?:)都是可能的错误。我不能说这个bug的表现是什么,但是您的代码所具有的条件行为越少,仅由于执行期间的代码覆盖范围将更加一致这一事实,就越有可能实现无bug。

顺便说一句,所有这些都对性能也有积极影响。赢得!

9
dash-tom-bang

在两个单元测试注释上均为+1。

除此之外,设置编译器提供的最高警告级别,并确保将警告视为错误。错误通常隐藏在那些“错误”错误中。

同样,投资于在编译时运行的静态分析工具(我将其视为编译器警告的额外级别)。

9
Alan

除了提到的内容:

  • 不要忽略错误代码-例如不要以为您得到了有效的结果,是否已经成功创建了文件,等等。因为有一天,会发生一些事情。
  • 不要以为您的代码永远不会输入某些条件,因此“忽略该条件是安全的”。
  • 测试您的代码,然后让其他人对其进行测试。我发现我是测试我自己的代码的最糟糕的人。
  • 休息一下,然后重新阅读代码,看看您是否“错过了明显的事情”。经常发生在我身上。

我目前忘记的许多其他事情,但其他人肯定会想到。 :)

9
MetalMikester
  • 编写更少的代码,做更多的事情。
  • 考虑一下低层次的含义和高层次的后果
  • 考虑在代码中创建的抽象。
  • 如果可能,仅写出基本的复杂性。
8
Paul Nathan

少一些技术性的答案:在您累了(每天9小时/天),醉酒或“烤”时不要编程。当我累了的时候,我没有足够的耐心来编写干净的代码。

8
Alexandru

编写单元测试集成测试

7
ysolik

这里有一些关于单元测试和工具的很好的答案。我唯一可以添加给他们的东西是:

尽早让您的测试人员参与

如果您有测试团队,请不要陷入将他们视为代码质量的守门人并为您发现缺陷的陷阱。相反,与他们合作并尽早让他们参与进来(在敏捷项目中,这将从项目开始就开始,但是如果我们真的尝试的话,我们总是可以找到更早让他们参与的方法)。

  • 找出他们的测试计划是什么。与他们一起检查他们的测试用例-您是否用代码覆盖了它们的全部?
  • 要求他们了解要求。和你一样吗
  • 给他们早期的工作版本进行探索性测试-您会对他们建议的改进感到惊讶。

与测试人员保持良好的工作关系意味着您可以尽早发现错误的假设和缺陷,然后再对他们造成任何损害。这也意味着测试人员有足够的能力来协助产品设计并在有时间修复它们时发现可用性问题。

5
Paddyslacker

静态分析工具

诸如 FindBugs 之类的插件和应用程序会抓取您的代码并查找存在potential bug的地方。没有初始化和使用变量的地方,或者只是疯狂的事情(十分之九),这些地方使错误更容易产生。像这样的工具可以帮助我阻止骨头走下坡路,即使这还不是bug。

附注:请记住要经常研究为什么工具会告诉您一些不好的东西。永远不会伤害学习(并非在所有情况下都适用)。

4
Ryan Hayes

代码检查或其他形式的对等检查,例如配对编程。

结构化代码审查,例如Fagan检查 至少可以和单元测试一样有效和高效 ,甚至在某些情况下甚至被证明比单元测试更好。检查也可以在软件生命周期的早期使用,并且可以与代码以外的工件一起使用。

Karl Wiegers撰写的《软件中的同行评论》 是一本关于这一主题的好书。

3
Michael

除了此处的所有其他建议外,将所有可能的警告设置为最高灵敏度并将其视为错误。还可以使用该语言具有的所有整理工具。

您会惊讶可以通过警告捕获多少简单错误,以及有多少简单错误转化为代码中的真正错误。

2
greyfade

这里有很多好的答案,但我想补充一些内容。确保您真正了解该要求。当用户认为需求指的是X而程序员认为需求指的是Y时,我已经看到了许多错误。请后退以澄清较差或模棱两可的需求。我知道我们每个人都喜欢加入代码,但是花在确保理解上的时间越多,返工和错误修复就越少。

了解您所支持的业务后,您经常会发现需求中缺少的东西,或者需要进一步的解释。知道如果您按照说明执行任务Y,它将破坏现有功能Z。

了解您的数据库结构。许多错误是由于语法正确的查询导致的,但返回错误的结果。了解如何识别结果有趣的时候。如果我要编写一个复杂的报告查询,那么在我将结果标记为可以使用之前,我总是会找一位技术专家来审查我的结果,他们不可避免地会在我错过的数据中看到一些东西。然后记下自己发现他们没有发现的内容,并记住下次您进行类似的操作。

2
HLGEM

我遵循Test-Code-Test而不是Code-test-code-test的做法。这可以帮助我考虑用例并适当地构建逻辑

1
viv

令人惊讶的是,尚未提及以下三个非常重要的点:

  • 自由使用断言。您应该一直问自己的问题不是“我应该断言吗?”但是“我有什么要断言的吗?”

  • 选择不变性。(自由使用final/readonly。)您所拥有的可变状态越少,出错的地方就越少。

  • 不要过早地进行优化。许多程序员在性能问题上一头雾水,使他们不必要地卷积代码,使设计混乱,甚至没有事先知道性能是否会成为问题。首先,不管性能如何,以学术方式构建您的软件产品;然后,看看它是否表现不佳; (可能不会。)如果存在任何性能问题,请在一个或两个位置上可以提供尼斯和正式的算法优化,以使您的产品满足其性能要求,而不必对整个代码库进行调整和修改。在这里和那里挤压时钟周期。

1
Mike Nakis

使用诸如 ReSharper 之类的代码检查工具或诸如 IntelliJ IDEA 之类的IDE来警告许多复制粘贴错误以及其他警告例如指出“已写入但从未读取”的变量。节省了我很多时间。

1
DonJoe

我认为最重要的技术是花点时间。如果您觉得需要两天的时间来编写一个新模块,但是老板强迫您只在一天之内进行编码,那么您的代码可能会出现更多错误。

我前一段时间读过的一本书中说过,您不应该忍受破窗,因为人们不会在乎别人是否破……编码是一样的,每个人都会在乎是第一个做某事的人不好但很快,但没人会在乎hell code,有很多错误,而且设计和样式很差。

1
greuze