我不是指外部工具。我想到了架构模式,语言结构,习惯。我最感兴趣的是C ++
答案 0 :(得分:32)
自动化单元测试。
答案 1 :(得分:20)
我喜欢称之为 QA团队的一种经常被忽视的技术,可以在错误到达生产之前清除错误。
这是我的经验(并且经常在教科书中引用),程序员不会做出最好的测试人员,尽管他们可能会想到,因为他们倾向于测试他们已经知道的编码行为。最重要的是,他们往往不擅长将主题放在最终用户的手中(如果是那种应用程序),因此可能会忽略UI格式化/对齐/可用性问题。
是的,单元测试非常重要,我相信其他人可以提供比我更好的技巧,但不要忽视你的系统/集成测试。 :)
..嘿,这是一种与语言无关的技术!
答案 2 :(得分:18)
答案 3 :(得分:16)
我发现以下内容非常方便。
1)ASSERT
2)可以输出到调试spew,控制台或文件的调试记录器
3)记忆跟踪工具。
4)单元测试。
5)智能指针。
我相信还有很多其他人,但我无法想到它们。)
答案 4 :(得分:15)
RAII以避免资源泄漏错误。
答案 5 :(得分:14)
答案 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
我只是继续放置断言语句并重新启动程序,直到程序状态的多行表示正确。