Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

No one's perfect, and no matter what we do, we are going to produce code that has bugs in it from time to time. What are some methods/techniques for reducing the number of bugs you produce, both when writing new software and changing/maintaining existing code?


locked by maple_shaft Apr 17 '15 at 1:04

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

A good method is to do more upfront design (not too much, but enough to make your code more structured and easier to understand). – Giorgio Apr 2 '13 at 15:06

17 Answers 17

up vote 58 down vote accepted

Avoid fancy coding. The more complicated the code, the more likely there's bugs. Usually on modern systems, clearly written code will be fast and small enough.

Use available libraries. The easiest way to not have bugs writing a utility routine is to not write it.

Learn a few formal techniques for the more complicated stuff. If there's complicated conditions, nail them down with pen and paper. Ideally, know some proof techniques. If I can prove code correct, it's almost always good except for big, dumb, obvious bugs that are easy to fix. Obviously, this only goes so far, but sometimes you can formally reason about small but complicated things.

For existing code, learn how to refactor: how to make small changes in the code, often using an automated tool, that make the code more readable without changing the behavior.

Don't do anything too quickly. Taking a little time up front to do things right, to check what you've done, and to think about what you're doing can pay off big time later.

Once you've written the code, use what you've got to make it good. Unit tests are great. You can often write tests ahead of time, which can be great feedback (if done consistently, this is test-driven development). Compile with warning options, and pay attention to the warnings.

Get somebody else to look at the code. Formal code reviews are good, but they may not be at a convenient time. Pull requests, or similar if your scm doesn't support them allow for asynchronous reviews. Buddy checking can be a less formal review. Pair programming ensures two pairs of eyes look at everything.

x2 - what Ryan said. – JBRWilkinson Sep 28 '10 at 22:26
also most languages can be more or less picky. You want it to be as picky as possible. – user1249 Oct 17 '10 at 9:45
"Learn a few formal techniques for the more complicated stuff."... for instance? – Dan Rosenstark Dec 16 '10 at 19:07
@Yar: I expect something like the systems explained in this book:… ; although I have to say that specific book is exceedingly dry and dull, so there are probably much better ones out there (but it's the only one I've read). – Joeri Sebrechts Jul 4 '14 at 7:48

Unit Tests let you reduce the number of bugs that pop up a second time. If you find a bug in your code, writing a unit test will make sure it doesn't come back up later. (Plus, thinking of all the cases and writing thousands of unit tests up front is hard to get done sometimes)

"Thinking of all the cases up front" leads to clean, fully-specified interfaces, which can only be a good thing. Unit tests are only hard to write if you're retrofitting them to code that wasn't designed with testing in mind. – Mike Seymour Sep 28 '10 at 17:57
If you can, you should. Unfortunately, most place I've been see unit tests as something that costs more than just "fixing bugs really quick". So, if you can, then you should write tests up front, but if it's not seen as "cost-effective" then writing them alongside bug fixes helps you build it up over time without putting too much of the budget toward just writing unit tests. – Ryan Hayes Sep 28 '10 at 18:05
"Testing shows the presence, not the absence of bugs." - E. Dijkstra. That being said, automated tests are definitely a very useful way to maintain and increase software quality. – limist Sep 28 '10 at 20:02

+1 on both of the unit test comments.

Beyond that, set the highest warning level your compiler offers, and make sure warnings are treated as errors. Bugs often hide in those "erroneous" errors.

Similarly, invest in static analysis tools that run at compile time (I view these as an extra level of compiler warnings).

+1 for the static analysis comment. It is invaluable to get all that info for free :) – Morten Jensen Apr 2 '13 at 4:58

In addition to what's been mentioned:

  • Don't ignore error codes - e.g. don't assume that you got a valid result, that a file has been successfully created, etc... Because some day, something will happen.
  • Don't assume that your code will never enter some condition and that therefore "it's safe to ignore that condition".
  • Test your code, then have it tested by someone else. I find I'm the worst person to test my own code.
  • Take a break, then re-read your code and see if you "missed the obvious". Often happens to me.

Lots of other things I'm forgetting at the moment, but the others will surely think of them. :)

And if you're so sure that condition X will never happen... use an assert to make sure that when condition X happens, you'll know about it (through an exception, or logging, or whatever). – Frank Shearar Sep 28 '10 at 18:08
@MetalMikester: Unit tests are good. But with high level languages and good libraries, most of the hard bugs require integration and regression testing to nail. – Vector Apr 21 '13 at 2:27

I've developed a fairly functional style of programming, despite my primary languages being C++ and Python. I found that if I pass all of the context to a function (or method) that that function needs to do its job, and return the meaningful data that I'm looking for, that my code has become much more robust.

Implicit state is the enemy and in my experience is the #1 source of bugs. This state can be global variables or member variables, but if results are dependent on something that's not passed to the function you're asking for trouble. Clearly it is not feasible to eliminate state, but minimizing it has huge positive effects on program reliability.

I also like to tell my coworkers that every branch (if, for, while, ?:) is a likely bug. I can't say what the manifestation of the bug will be, but the less conditional behavior your code has, the more likely it is to be bug free simply due to the fact that the code coverage during execution will be more consistent.

Go figure, all of these things also have positive effects on performance too. Win!

In my experience it can quickly become tedious to pass around all the state for every call, if the methods are as small as they should be. This problem can be solved by using many small immutable classes with short object life-times. That way you can store the temporary state as fields and discard the object when you no longer need the state. :-) – Jørgen Fogh Jul 4 '14 at 15:00
Another consideration for that case of it becoming tedious is that perhaps you're trying to pass around too much state. :) – dash-tom-bang Jul 18 '14 at 0:04
In many cases that's true but it often isn't. Within some domains you need access to a lot of state, even if you don't have a lot of mutable state. I am currently working on a code generator where I need access to several symbol tables. I don't want to pass them around to each and every method. – Jørgen Fogh Jul 21 '14 at 13:25
  • Write less code that does more.
  • Think about the low-level implications and the high-level ramifications
  • Contemplate the abstraction you are creating in your code.
  • Write only the essential complexity if possible.
I was going to write a big post that sums up as "write less that does more" (IOW know and use the tools available to you). I'll just +1 this instead. – Kaz Dragon Sep 29 '10 at 9:08
But be careful not to get fancy code when trying to achieve less code. – gablin Sep 29 '10 at 20:23
@gablin: fancy is in the eye of the beholder in many respects. I can write and read code today that I would have been stupefied at 4 years ago. Haskell today is fancy to me. :) – Paul Nathan Sep 29 '10 at 21:47

A little less technical answer: don't program when you are tired (9h/day are enough), drunk or 'baked'. When I'm tired I don't have the required patience to write clean code.

It usually takes most programmers several years to realize this. It's an important point. – Jeff Davis Feb 7 '12 at 20:02

Write unit tests and integration tests.


Some great answers here regarding unit testing and tools. The only thing I can add to them is this:

Involve your testers as early as you can

If you have a test team, don't fall into the trap of treating them as the gatekeepers for your code quality and catching your defects for you. Instead, work with them and involve them as early as possible (on agile projects this will be from the project's beginning, but we can always find ways to involve them earlier if we really try).

  • Find out what their test plan is. Review their test cases with them - are you covering them all with your code?
  • Ask them for their understanding of the requirements. Is it the same as yours?
  • Give them early working builds to do exploratory testing on - you'll be amazed at the improvements they will suggest.

Having a good working relationship with your testers means that you can catch poor assumptions and defects really early on, before they can do any damage. It also means that the testers feel empowered to help with the product design and catch usability issues when there is time to fix them.


Static Analysis Tools

Plugins and apps like FindBugs crawl your code and find places where there are potential bugs. Places where variables aren't initialized and used or just crazy things that 9 times out of 10, make it way easier for bugs to arise. Tools like this help me prevent my bonehead moves down the road even if it's not a bug yet.

P.S.: Remember to always research why a tool tells you something is bad. Never hurts to learn (and not everything is right in all situations).


Code inspection or other forms of peer review such as pair programming.

Structured code reviews such as Fagan inspection can be at least as effective and efficient as unit testing and has even proved to be better than unit testing in some cases. Inspections can also be used earlier in the software lifecycle and with artifacts other than code.

Peer Reviews in Software by Karl Wiegers is a great book on this subject.


In addition to all of the other suggestions here, turn on all possible warnings to the highest level of sensitivity, and treat them as errors. Also use any linting tools the language has.

You would be amazed at how many simple mistakes can be caught by warnings and how many of those simple things translate into real bugs in your code.


A lot of good answers here, but a few things I wanted to add. Make sure you actually understand the requirement. I've seen lots of bugs when the user thought the requirement meant X and the programmer thought it meant Y. Push back for clarification on poor or ambiguous requirements. I know we all like to jump in and code but the more time spent up front ensuring understanding, the less rework and bug fixing there will be.

Get to know the business you are supporting, you will often see things in requirements that are missing or need further explanation then. Know that if you do task Y as stated, it will break existing feature Z.

Understand your database structure. Many many bugs are as a result of a query that is syntactically correct, but returns the wrong results. Learn how to recognize when your results look funny. If I am writing a complex reporting query, I always get a technical specialist to review my results before I mark it as ready to go, they will inevitably see something in the data I missed. Then make notes to yourself what they caught that you didn't and remember that the next time you do something simliar.


I think the most important technique is take your time. If you feel you need two days to code a new module, but you boss force you to code only in one day... your code will be probable more buggy.

One of the books I read some time ago, said that you shouldn't live with broken windows, because people won't care if anotherone gets broken... Coding is the same, everyone will care about being the first in doing something bad but fast, but none will care about one hell code, with lots of bugs, and very poor design and style.


I follow the practice of Test-Code-Test instead of Code-test-code-test. This helps me to think of use-cases and appropriately frame the logic


Use code inspection tools like ReSharper or IDEs like IntelliJ IDEA that warn about many copy-and-paste bugs and others by e.g. pointing out variables that "are written to, but never read". Has saved me a lot of time.


Surprisingly, the following three very important points have not been mentioned yet:

  • Use assertions liberally. The question you should always be asking yourself is not "should I assert this?" but "is there anything I forgot to assert?"

  • Opt for immutability. (Use final/readonly liberally.) The less mutable state you have, the fewer things can go wrong.

  • Do not optimize prematurely. Many programmers get side tracked with performance concerns, causing them to unnecessarily convolute their code and bastardize their designs without even knowing beforehand whether performance is going to be an issue. First, build your software product the academic way, disregarding performance; then, see if it performs poorly; (It probably won't.) If there are any performance issues, go find the one or two places where you can provide nice and formal algorithmic optimizations that will make your product meet its performance requirements instead of tweaking and hacking your entire code base to squeeze clock cycles here and there.


protected by Community Jan 27 '15 at 14:14

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.