views:

571

answers:

15

I'm "just" a hobbyist programmer, but I find that as my programs get longer and longer the bugs get more annoying--and harder to track. Just when everything seems to be running smoothly, some new problem will appear, seemingly spontaneously. It may take me a long time to figure out what caused the problem. Other times I'll add a line of code, and it'll break something in another unit. This can get kind of frustrating if I thought everything was working well.

Is this common to everyone, or is it more of a newbie kind of thing? I hear about "unit testing," "design frameworks," and various other concepts that sound like they would decrease bugginess, make my apps "robust," and everything easy to understand at a glance :)

So, how big a deal are bugs to people with professional training?

Thanks -- Al C.

+1  A: 

The prevailing wisdom seems to be that the average programmer creates 12 bugs per 1000 lines of code - depends on who you ask for the exact number, but it's always per lines of code - so, the bigger the program, the more the bugs.

Subpar programmers tend to create way more bugs.

Newbies are often trapped by idiosyncrasies of the language, and lacking experience tends towards more bugs too. As you go on, you will get better, but never will you create bug-free code... well I still have bugs, even after 30 years, but that could be just me.

Software Monkey
+21  A: 

The problem of "make a fix, cause a problem elsewhere" is very well known, and is indeed one of the primary motivations behind unit testing.

The idea is that if you write exhaustive tests for each small part of your system independently, and run them on the entire system every time you make a change anywhere, you will see the problem immediately. The main benefit, however, is that in the process of building these tests you'll also be improving your code to have less dependencies.

The typical solution to these sort of problems is to reduce coupling; make different parts less dependent on one another. More experienced developers sometimes have habits or design skills to build systems in this manner. For example, we use interfaces and implementations rather than classes; we use model-view-controller for user interfaces, etc. In addition, we can use tools that help further reduce dependencies, like "Dependency injection" and aspect oriented programming.

All programmers make mistakes. Good and experienced programmers build their programs so that it is easier to find the mistakes and restrict their effects.

And it is a big deal for everyone. Most companies spend more time on maintenance than on writing new code.

Uri
Hehe as a support engineer, I'd amend that to "most companies *should* spend more time on maintenance than writing new code" ;) unfortunately, new features sell product, so they get priority in my experience
Jay
The answer is good. The amendment is awesome too!
batbrat
+2  A: 

This is a common newbie thing. As you get more experience, of course, you'll still have bugs, but they'll be easier to find and fix because you'll learn how to make your code more modular (so that changing one thing doesn't have ripple effects everywhere else), how to test it, and how to structure it to fail fast, close to the source of the problem, rather than in some arbitrary place. One very basic but useful thing that doesn't require complex infrastructure to implement is to check the inputs to all functions that have non-trivial precondtions with asserts. This has saved me several times in cases where I would have otherwise gotten weird segfaults and arbitrary behavior that would have been near impossible to debug.

dsimcha
+3  A: 

Obviously, bugs are a big deal to any programmer. Just look through the list of questions on Stack Overflow to see this illustrated.

The difference between a hobbyist and an experienced professional is that the pro will be able to use his experience to code in a more "defensive" way, avoiding many types of bugs in the first place.

Thomas
As a hobbyist programmer, I don't think I'm any more or less "defensive" - even when you just do something for fun you can still try to do it well. Not all hobbyists are inexperienced.
Chris Lutz
You're right -- a better distinction would be "inexperienced" versus "experienced". (Heck, even though I nearly have a master's degree in computer science, I have never coded a single line for money in my life -- yet I wouldn't call myself inexperienced.)
Thomas
I agree with Thomas, except for, as noted, the unfortunate choice of words. There are some terrible, terrible professionals out there! :-)
Carl Seleborg
+4  A: 
  1. There are two ways to write error-free programs; only the third one works. ~Alan J. Perlis

  2. The only way for errors to occur in a program is by being put there by the author. No other mechanisms are known. Programs can't acquire bugs by sitting around with other buggy programs. ~Harlan Mills

Learning
I've never heard that Perlis quote before -- it's going in my favorites collection.
slothbear
Although Harlan's quote is kind of accurate, its not so much nowadays with software depending on so many external components, its quite likely to acquire bugs by sitting around with other buggy programs IMHO.
Robert Gould
+1  A: 

Nasty bugs happen to everyone from pros to hobbyists. Really good programmers get asked to track down really nasty bugs. It's part of the job. You'll know you've made it as a software developer when you stare at a nasty bug for two days and in frustration you shout, "Who wrote this crap!?!?" ... only to realize it was you. :-)

Part of the skill of a software developer is the ability to keep a large set of interrelated items straight in his/her head. It sounds like you're discovering what happens when your mental model of the system breaks down. With practice you will learn to design software that doesn't feel so brittle. There are tons of books, blogs, etc. out there on the subject of software design. And Stack Overflow of course for specific questions.

All that said, here's a couple of things you can do:

  1. A good debugger is invaluable. Often you have to step through your code line by line to figure out what went wrong.
  2. Use a garbage-collected language such as Python or Java if it makes sense for your project. GC will help you focus on making things work instead of getting bogged down by maddening memory errors.
  3. If you write C++, learn to love RAII.
  4. Write LOTS of code. Software is somewhat of an art form. Lots of practice will make you better at it.

Welcome to Stack Overflow!

Kristo
+1  A: 

If bugs weren't a problem then I'd be able to write a 100,000 line program in 10 minutes!

Your question is like, "As an amateur doctor, I worry about my patients' health: sometimes when I'm not careful enough, they sicken. Is patients' health a problem for you professional doctors too?"

Yes: it's the central problem, even the only problem (for any sufficiently all-inclusive definition of 'bug').

ChrisW
+13  A: 

Are you automating your tests? If you do not, you're signing up creating bugs without finding them.

Are you adding tests for bugs as you fix them? If you do not, you are signing up for creating the same bugs over and over.

Are you writing unit tests? If not, you are signing up for long debugging sessions when a test fails.

Are you writing your unit tests first? If not, your unit tests will be hard to write when your units are tightly coupled.

Are you refactoring mercilessly? If not, every edit will become more difficult and more likely to introduce bugs. (But make sure you have good tests, first.)

When you fix a bug, are you fixing the entire class? Don't just fix the bug; don't just fix similar bugs throughout your code; change the game so you can never create that kind of bug again.

Jay Bazuzi
Great answer. I think it gives the zen of testing right!
batbrat
This answer is a little too (religiously?) focused on unit testing and test-driven design. These practices just make it more likely that the code does what you intended it to do, but not that your software is correct in the end.
Carl Seleborg
I agree with both the OP and the two above comments. While I'm a big fan of TDD, it's not a silver bullet, and I think it's important to balance the usefulness of test suites and the sanity of real life. Otherwise you end up with code that is impossible to change without significant work.
Nik Reiman
Remember this guy is a hobbyist.
bingle
@Nick: what conclusion do you draw from him being a hobbyist? Perhaps that, since he doesn't have a tester, he has to find all his bugs himself, so he needs good automated tests.
Jay Bazuzi
+4  A: 

Bugs are a big deal to everyone. I've always found that the more I program, the more I learn about programming in general. I cringe at the code I wrote a few years back!! I started out as a hobbyist and liked it so much that I went to engineering college to get a Computer Science Engineering major (I am in my final semester). These are the things that I have learned :

  1. I take time to actually design what I am going to write and document the design. It really eliminates a lot of problems down the line. Whether the design is as simple as writing down a few points on what I am going to write or full blown UML modeling (:( ) doesn't matter. Its the clarity of thought and purpose and having material to look back at when I come back to the code after a while that matter the most.

  2. No matter what language I write in, keeping my code simple and readable is important. I think that it is extremely important not to over complicate the code and at the same time not to over simplify it. (Hard learned lesson!!)

  3. Efficiency optimizations and fancy tricks should be applied at the end, only when necessary and only if they are needed. Another thing is that I apply them only If I really know what I am doing and I always test my code!

  4. Learning language dependant details helps me keep my code bug free. For instance I learned that scanf() is evil in C!

  5. Others have already commented on the zen of writing tests. I would like to add that you should always do regression tests. (i.e. Write new code, test all parts of your code to see if it breaks)

  6. Keeping a mental picture of code is hard at times, so I always document my code.

  7. I use methods to make sure that there is a bare minimum dependence between different parts of my code. Interfaces, class hierarchies etc. (Decoupled design)

  8. Thinking before I code and being disciplined in whatever I write is another crucial skill. I know people who don't format their code so its readable (Shudder!).

  9. Reading other peoples source to learn best practices is good. Making my own list is better!. When working in a team, there must be a common set of them.

  10. Don't be paralyzed by analysis. Write tests, then code, then execute and test. Rinse wash repeat!

  11. Learning to read over my own code and combing it for mistakes is important. Improving my arsenal of debugging skills was a great investment. I keep them sharp by helping my classmates fix bugs regularly.

  12. When there is a bug in my code, I assume its my mistake, not the computers and work from there. That is a state of mind that really helps me.

  13. A fresh pair of eyes aids in debugging. Programmers tend to miss even the most obvious errors in their own code when exhausted. Having someone to show your code to is great.

  14. having someone to throw ideas at and not be judged is important. I talk to my mom (who is not a programmer) , throw ideas at her and find solutions. She helps me bounce my ideas back and forth and refine them. If she is unavailable, I talk to my pet cat.

  15. I am not so be discouraged by bugs anymore. I've learned to love removing bugs almost as much as programming.

  16. Using version control has really helped me manage different ideas I get while coding. That helps reduce errors. I recommend using git or any other version control system you might like.

  17. As Jay Bazzuzi said - Refactor code. I just added this point after reading his answer, to keep my list complete. All credit goes to him.

  18. Try to write reusable code. Reuse code, both yours and from libraries. Using libraries which are bug free to do some common tasks really reduces bugs (sometimes).

I think the following quote says it best - "If debugging is the art of removing bugs, programming must be the art of putting them in."

No offense to anyone who disagrees. I hope this answer helps.

Note
As others Peter has pointed out, use Object Oriented Programming if you are writing a large amount of code. There is a limit to code length after which it becomes harder and harder to manage if written procedurally. I like procedural for smaller stuff, like playing with algorithms.

batbrat
+1  A: 

If you're not well organized, your codebase will become your very own Zebra Puzzle. Adding more code is like adding more people/animals/houses to your puzzle, and soon you have 150 various animals, people, houses and cigarette brands in your puzzle and you realize that it just took you a week to add 3 lines of code because everything is so inter-related that it takes forever to make sure the code still executes how you want it to.

The most popular organizational paradigm seems to be Object Oriented Programming, if you can break your logic down into small units which can be constructed and used independently of each other, then you will find bugs far less painful when they occur.

too much php
+3  A: 

All the other answers are great. I'll add two things.

  1. Source control is mandatory. I'm assuming you're on windows here. VisualSVN Server is free and maybe 4 clicks to install. TortoiseSVN is also free and it integrates into Windows Explorer, getting around the VS Express limitations of no add-ins. If you create too many bugs, you can revert your code and start over. Without source control, this is next to impossible. Plus you can sync your code if you have a laptop and a desktop.
  2. People are going to recommend many techniques like unit testing, mocking, Inversion of Control, Test Driven Development, etc. These are great practices, but don't try to cram it all into your head too quickly. You have to write code to get better at writing code, so work these techniques slowly into your code writing. You have to crawl before you walk and walk before you can run.

Best of luck in your coding adventures!

Ben Robbins
+2  A: 

Bugs are common to everyone -- professional or not.

The larger and more distributed the project, the more careful one must be. One look at any open source bug database (ex: https://bugzilla.mozilla.org/ ) will confirm this for you.

The software industry has evolved various programming styles and standards, which when used right, make wrong code easier to spot or limited in its impact.

Therefore, training has a very positive on code quality... But at the end of the day, bugs still sneak through.

Alterlife
A: 

the kind of bugs you describe are a symptom of a lack of decoupling among modules, i.e. everything depends on everything else, so a one-line change breaks things that have worked for years

experience helps, but usually because after pounding your forehead against monolithic systems for a while you're willing to learn anything new and different that might reduce the problems ;-)

seriously, TDD and OOP will definitely help

Steven A. Lowe
+2  A: 

If you're just a hobbyist programmer, learning full bore TDD and OOP may involve more time than you're willing to put in. So, going on the assumption that you don't want to put in the time on them, a few easily digestible suggestions to cut down on bugs are:

  1. Keep each function doing one thing. Be suspect of a function more than, say, 10 lines long. If you think you can break it into two functions, you probably should. Something that will help you control this is naming your functions according to exactly what they are doing. If you find that your names are long and unwieldy then you function is probably doing too many things.

  2. Turn magic strings into constants. That is, instead of using:

    people["mom"]

use instead

var mom = "mom";
people[mom]
  1. Design your functions to either do something (command) or get something (query), but not both.

An extremely short and digestible take on OOP is here http://www.holub.com/publications/notes_and_slides/Everything.You.Know.is.Wrong.pdf. If you get this, you've got the gist of OOP and are quite frankly ahead of a lot of professional programmers.

bingle
A: 

What really changed my odds against code complexity and bugs was using a coding standart - how to place brackets an so on. It may seem like just boring and useless thing but it really unifies all the code and makes it much easier to read and maintain. So do you use a coding standart?

sharptooth