哪种编程技术可以帮助您在错误投入生产之前避免或解决错误

时间:2009-08-24 09:58:40

标签: c++ debugging design-patterns architecture

我不是指外部工具。我想到了架构模式,语言结构,习惯。我最感兴趣的是C ++

28 个答案:

答案 0 :(得分:32)

自动化单元测试。

答案 1 :(得分:20)

我喜欢称之为 QA团队的一种经常被忽视的技术,可以在错误到达生产之前清除错误。

这是我的经验(并且经常在教科书中引用),程序员不会做出最好的测试人员,尽管他们可能会想到,因为他们倾向于测试他们已经知道的编码行为。最重要的是,他们往往不擅长将主题放在最终用户的手中(如果是那种应用程序),因此可能会忽略UI格式化/对齐/可用性问题。

是的,单元测试非常重要,我相信其他人可以提供比我更好的技巧,但不要忽视你的系统/集成测试。 :)

..嘿,这是一种与语言无关的技术!

答案 2 :(得分:18)

答案 3 :(得分:16)

我发现以下内容非常方便。

1)ASSERT 2)可以输出到调试spew,控制台或文件的调试记录器 3)记忆跟踪工具。
4)单元测试。
5)智能指针。

我相信还有很多其他人,但我无法想到它们。)

答案 4 :(得分:15)

RAII以避免资源泄漏错误。

答案 5 :(得分:14)

  1. 争取simplicity and conciseness
  2. 永远不要将代码留给代码behavior is undefined
  3. 寻找利用类型系统的机会,并在编译时尽可能地检查编译器。只要您保持常识,模板和代码生成就是您的朋友。
  4. 尽量减少单例和全局变量的数量。
  5. 使用RAII
  6. 使用assertions
  7. 自动测试一些名义上和所有角落的情况。
  8. 避免像瘟疫这样的最后一刻改变。

答案 6 :(得分:13)

我用思考。

答案 7 :(得分:8)

将变量范围缩小到尽可能窄。外部范围内的变量较少 - 种植和隐藏错误的机会较少。

答案 8 :(得分:7)

我发现,在编译时完成和检查的越多,运行时可能出错的可能性就越小。所以我尝试利用允许在编译时进行更严格检查的技术。这是我进入模板元编程的原因之一。如果你做错了什么,它就不会编译,因此永远不会离开你的办公桌(从而永远不会到达客户)。

答案 9 :(得分:5)

在我开始使用

进行测试之前,我发现了很多问题

<强>断言

答案 10 :(得分:5)

从一开始就使用实际的实际数据进行测试。并且测试不仅在编写代码时是必要的,而且应该在设计阶段的早期开始。找出最糟糕的用例,并确保您的设计能够处理它。如果您的设计即使对这些用例感觉良好而优雅,它实际上也可能是好的。

自动化测试非常适合确保您编写的代码正确无误。但是,在编写代码之前,必须确保构建正确的代码。

答案 11 :(得分:5)

学习函数式编程有所帮助。 的 HERE
Learn you a haskell for great good.

答案 12 :(得分:4)

模型 - 视图 - 控制器,以及通常可以自动进行单元测试的合同和接口。

答案 13 :(得分:4)

我同意这里的许多其他答案。

特定于C ++,在可能的情况下使用'const'并避免使用原始指针(支持引用和智能指针)帮助我在编译时发现错误。

此外,制定“无警告”政策有助于发现错误。

答案 14 :(得分:3)

我发现同伴编程往往有助于避免许多愚蠢的错误,而且很多时候会产生揭示缺陷的讨论。此外,如果有人自由思考你为什么做某事,它往往会让一切变得更清洁。

答案 15 :(得分:3)

要求。

根据我的经验,拥有完整和完整的要求是创建无bug软件的第一步。如果你不知道它应该做什么,你就无法编写完整而正确的软件。如果你不知道它应该做什么,你就无法为软件编写适当的测试;你会错过很多你应该测试的东西。此外,编写需求的简单过程可以帮助您充实它们。在编写第一行代码之前,您会发现很多问题和问题。

答案 16 :(得分:2)

代码审查;我亲自在同事的代码中发现了很多错误,他们发现了我的错误。

早期和经常进行的代码审查将帮助您了解彼此的代码(这有助于维护),并发现错误。

越早发现错误就越容易修复。所以尽快做到。

当然,结对编程可以将其发挥到极致。

答案 17 :(得分:1)

雇用测试/验证您软件的人。

我们有一个人在我们的任何客户面前使用我们的软件。他发现我们的自动化测试流程找不到的错误,因为他认为客户不是软件开发人员。这个人也给我们的客户提供支持,因为他从客户的角度非常了解软件。的无价

答案 18 :(得分:1)

书籍建议:“代码完成”和“发布它”是关于此主题的两本必读书籍。

答案 19 :(得分:1)

这里已经提到了,但我会再说一遍,因为我认为这说不够:

不必要的复杂性是 良好工程的主要对手。

保持简单。如果事情开始变得复杂,请停下来问问自己为什么以及如何将问题分解为更小,更简单的块。

答案 20 :(得分:1)

整个项目的编码样式一致性。

不仅仅是空格与制表符问题,而是代码的使用方式。总有不止一种方法可以做。当同一件事在不同的地方以不同的方式完成时,它会使捕捉常见错误变得更加困难。

答案 21 :(得分:1)

除了已经提到的内容之外,我相信C ++ 0x引入的一些功能将有助于避免某些错误。我们会想到强类型枚举,for-in循环和删除对象标准函数等功能。

一般来说,强力打字是走向imho的方式

答案 22 :(得分:1)

使用像IntelliJ这样的IDE,在我编写代码时检查我的代码,并在编写代码时标记狡猾的代码。

答案 23 :(得分:1)

单元测试,然后是持续集成。

答案 24 :(得分:0)

各种'追踪'。

答案 25 :(得分:0)

尚未提及的东西 - 当甚至出现半复杂的逻辑时,尽可能准确地命名变量和函数(但不能太长)。这将使他们彼此之间的互动变得不协调,并且他们应该做的事情会更好地脱颖而出。你的大脑的“意义”或语言解析部分将有更多的东西可以抓住。我发现,通过模糊命名的东西,你的大脑会掩盖真实存在的东西并看到/应该/正在发生什么而不是实际发生的东西。

此外,使代码清洁,它有助于防止大脑变得模糊。

答案 26 :(得分:0)

测试驱动开发与结对编程相结合似乎可以很好地保持一些错误。尽早获得测试有助于解决一些设计问题,并在其他人必须使用代码时给予一些信心。

答案 27 :(得分:0)

创建类状态的字符串表示形式,并将其打印到控制台。 请注意,在某些情况下,单行字符串是不够的,您将不得不编写小的打印循环代码,这将创建类状态的多行表示。 一旦您以这种方式“可视化”您的程序,您就可以开始在其中搜索错误。当您知道哪个变量最后包含错误的值时,很容易将断言置于分配或修改此变量的任何位置。通过这种方式,您可以确定错误的确切位置,并在不使用逐步调试的情况下进行修复(这是一种非常慢的查找错误的方法)。

就在昨天发现一个非常讨厌的错误而没有调试一行:

vector<string> vec;
vec.push_back("test1");
vec.push_back(vec[0]); // second element is not "test1" after this, it's empty string

我只是继续放置断言语句并重新启动程序,直到程序状态的多行表示正确。