没有人能做到完美,无论我们做什么,我们都将不时产生包含错误的代码。在编写新软件和更改/维护现有代码时,有哪些方法/技术可以减少产生的错误数量?
没有人能做到完美,无论我们做什么,我们都将不时产生包含错误的代码。在编写新软件和更改/维护现有代码时,有哪些方法/技术可以减少产生的错误数量?
Answers:
避免花哨的编码。代码越复杂,出现错误的可能性就越大。通常在现代系统上,编写清晰的代码将足够快且足够小。
使用可用的库。没有编写实用程序例程的错误的最简单方法是不编写实用程序。
学习一些更复杂的东西的正式技巧。如果情况复杂,请用笔和纸钉住它们。理想情况下,了解一些证明技术。如果我能证明代码正确,那么除了容易解决的大而笨拙的明显错误外,几乎总是好的。显然,这只是到目前为止,但是有时您可以正式地推理一些小而复杂的事情。
对于现有代码,学习如何重构:如何经常使用自动化工具在代码中进行小的更改,以使代码在不更改行为的情况下更具可读性。
不要做得太快。花一点时间做正确的事情,检查您所做的事情,并思考您在做什么,这可以在以后获得大量的回报。
编写代码后,请使用所需的功能使其变得更好。单元测试很棒。您通常可以提前编写测试,这可能是一个很好的反馈(如果始终如一,这是测试驱动的开发)。编译警告选项,并注意警告。
让其他人看一下代码。正式的代码审查很好,但是可能不方便。拉取请求(如果您的scm不支持它们,则类似)允许异步查看。好友检查可能不太正式。配对编程可确保两双眼睛观看所有内容。
通过单元测试,您可以减少第二次弹出的错误的数量。如果在代码中发现错误,则编写单元测试将确保以后不会再次出现。(此外,有时很难考虑所有情况并预先编写数千个单元测试)
在两个单元测试注释上均为+1。
除此之外,设置编译器提供的最高警告级别,并确保将警告视为错误。错误通常隐藏在那些“错误的”错误中。
同样,请投资在编译时运行的静态分析工具(我将其视为编译器警告的额外级别)。
除了提到的内容:
我目前忘记的许多其他事情,但其他人肯定会想到。:)
尽管我的主要语言是C ++和Python,但我已经开发了一种相当实用的编程风格。我发现,如果将所有上下文传递给该函数完成其工作所需的函数(或方法),并返回我要查找的有意义的数据,则我的代码将变得更加健壮。
隐性状态是敌人,根据我的经验,错误是第一大漏洞来源。此状态可以是全局变量或成员变量,但是如果结果取决于未传递给函数的内容,则您会遇到麻烦。显然,消除状态是不可行的,但是将其最小化会对程序可靠性产生巨大的积极影响。
我还想告诉我的同事,每个分支(如果同时是?:)都是一个可能的错误。我不能说这个bug的表现是什么,但是您的代码所具有的条件行为越少,仅由于执行期间的代码覆盖范围将更加一致这一事实,就越有可能实现无bug。
顺便说一句,所有这些都对性能也有积极影响。赢得!
这里有一些关于单元测试和工具的很好的答案。我唯一可以添加给他们的东西是:
尽早让测试人员参与
如果您有测试团队,请不要陷入将他们视为代码质量的守门人并为您发现缺陷的陷阱。相反,与他们合作并尽早让他们参与进来(在敏捷项目中,这将从项目开始就开始,但是如果我们真的尝试的话,我们总是可以找到更早让他们参与的方法)。
与测试人员保持良好的工作关系意味着您可以尽早发现错误的假设和缺陷,然后再对他们造成任何损害。这也意味着测试人员有足够的能力来协助产品设计并在有时间修复它们时发现可用性问题。
静态分析工具
诸如FindBugs之类的插件和应用程序会抓取您的代码,并查找可能存在错误的地方。没有初始化和使用变量的地方,或者只是疯狂的事情(十分之九)的地方,这使得更容易出现错误。像这样的工具可以帮助我阻止骨头走下坡路,即使这还不是bug。
PS:请记住要始终研究为什么工具会告诉您一些不好的东西。永远不会伤害学习(并非在所有情况下都适用)。
这里有很多好的答案,但我想补充一些内容。确保您真正了解该要求。当用户认为需求指的是X而程序员认为需求指的是Y时,我已经看到了很多错误。请后退以澄清较差或模棱两可的需求。我知道我们所有人都喜欢加入代码,但是花在确保理解上的时间越多,返工和错误修复就越少。
了解您所支持的业务后,您将经常看到需求中遗漏的东西,然后需要进一步的解释。知道如果您按照说明执行任务Y,它将破坏现有功能Z。
了解您的数据库结构。许多错误是由于语法正确而返回错误结果的查询的结果。了解如何识别结果有趣的时候。如果我要编写一个复杂的报表查询,我总是会找一个技术专家来审查我的结果,然后再将其标记为可以使用,他们将不可避免地看到我遗漏的数据中的某些内容。然后给自己做一个记录,让他们记下他们没有发现的东西,并记住下次您做类似的事情。
使用诸如ReSharper之类的代码检查工具或诸如IntelliJ IDEA之类的IDE ,它们通过指出“已写入但从未读取”的变量来警告许多复制和粘贴错误以及其他错误。节省了我很多时间。
令人惊讶的是,尚未提及以下三个非常重要的点:
自由地使用断言。您应该一直问自己的问题不是“我应该坚持吗?” 但是“我有什么要断言的吗?”
选择不变性。(自由地使用final / readonly。)您所拥有的可变性越少,出错的事件就越少。
不要过早优化。许多程序员都关注性能问题,这导致他们不必要地使代码复杂化并混搭了设计,甚至没有事先知道性能是否会成为问题。首先,不管性能如何,以学术方式构建您的软件产品;然后,看看它是否表现不佳;(可能不会。)如果存在任何性能问题,请转到一两个地方,您可以在这些地方提供漂亮而正式的算法优化,以使您的产品满足其性能要求,而不必对整个代码库进行调整和修改。在这里和那里挤压时钟周期。