I'm a new programmer in college and was wondering if there are any bad habits to watch out for early on. Anything that you wish you knew to avoid when starting. Thanks.
Don't get hooked on just one programming language, learn what that language is good for and what its not. Learn to use the right tool for the job.
Think 100x longer about the code before you write it. Don't just start spewing spaghetti
Copy and paste programming is probably one of the worst habits that one can develop while starting to learn programming. Learning how to program is best achieved by writing code and understanding other people's code. If you copy/paste code without understanding what's going on, you are doing yourself more harm than good.
Comments. Comment everything you do. You will thank yourself later, and so will your teammates. Besides, it makes documentation writing easier/unnecessary.
Don't get too stuck into the computer mode of thought. It does you little good to brilliantly solve the wrong problem with elegant code.
Customers are smart people, but they don't speak our language. And they pay our salaries. We need to come to them and learn to translate their requirements.
This should set a bad example, while this is more positive (and serious).
learn these by heart so you know when you are repeating them http://en.wikipedia.org/wiki/Anti-pattern
If half-year later you'll think that you are "guru" in C++ (or java or any other language or technology) then it'll be you great mistake. Your should always know a little more than other but you should think that you still don't know anything. It's a key to success in programming. Learn, learn and learn again.
Don't optimise prematurely.
Donald Knuth made the following statement on optimization: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."
Refactor. Don't be afraid to re-do it. With proper design and good test coverage, this shouldn't be a problem. If it is, figure out why - you'll learn more from mistakes than successes.
[Edit] Er, don't be afraid to refactor I guess is how it should start :)
If you must optimize, don't be penny-wise-pound-foolish.
I've seen people sweat over which optimization level to use on the compiler, or whether ++i
is faster than i++
, on code full of function calls (i.e. p.c. never there) to multiple abstraction layers, sapping magnitudes of performance, while saving neither cycles nor dev. hours.
Not handling errors. Failing to check return codes, assert conditions or swallowing exceptions. Even in cases where it's "impossible", or "no one will ever use it again".
Don't create solutions that are too elaborately coded and overly feature-rich - Keep it Short and Simple
If existing classes or functions don't have quite the behavior you're looking for, modify them to include it. Don't rewrite new classes/fucntions yourself. Duplication is very bad.
When your code turns to spaghetti, spend some time rewriting it to make more sense.
Comment liberally.
Use sensible names for classes, methods, functions, variables, tables, etc. Use a standard naming convention for each (camelCase, underscores, whatever... just think about it and stick to it).
In OO languages, not knowing about high cohesion, low coupling. Or not caring about it (which means not constantly measuring).
Not adhering to YAGNI is a big mistake. (YAGNI = you ain't gonna need it). Build what you need, not what you think you might need.
It helps when retaining a focus on the important things and the bigger picture.
Even at an API level, the intent of some functionality can be obfuscated by having multiple redundant additional methods or method overloads. Noise in a code base is annoying to work with. E.g. if you only need to load something in memory, don't provide an overload to load it from a file path "just because" you might need it in future.
This is especially the case when it comes to bugs. Unit testing finds a lot of bugs, but some will lay hidden until the functionality is actually used by someone. If you have code that is not being run, the bugs won't get found so quickly. Furthermore, when the bugs are discovered, that code might be ancient and the person who wrote it may not remember it, let alone be at the company any more.
Don't assume anything - ask when you don't know, and comment your code when you do.
Pick a style of indentation that makes sense (if your professors are giving you lots of code samples, the easiest may be to just use whatever they use) and use it. When I try to help people in my classes I'm amazed by how some of them are totally unable to indent their code in an organized way. (I would say it usually means their thought process is equally disorganized.)
Learn other languages. If your classes are all in C++ or Java, go online and mess around with Python or Lisp or Prolog. It's fun!
One question i have always asked myself when doing code reviews and the like is, * Is this the result of being lazy, are there areas that could be improved ?*
By that i mean could the person have done better but skipped that bit because they
- Is documentations missing
- Could naming of variables, methods, classes be improved to be clearer ?
- Is it readable ?
- Are there tests covering all the possible code paths.
- Are input parameters tested for validness.
- Are there too many really really long - many screen methods ?
- Are there any helpers - often they cant be bothered to extract.
Many times there are many vital things missing, the completed polished product will not have these.
Writing monolithic routines is one of the worst things you can do.
Try to write small, dumb code. Its harder to write code that looks like something anyone could write - that takes real skill.
Not paying attention to details.
Programming is all about details, yet it amazes me how many times I come across code where the programmer just did a sloppy job. Cut and paste jobs, duplicate code everywhere, and inconsistency across the code base are inexcusable.
It really comes down to refactoring. You wouldn't expect any other professional to just walk away when they finally got something "working". I'd hope the surgeon would pull his gloves out of me and stitch me back up when he/she's done operating.
One side note...If Visual Studio gives you a warning, treat it as an error and fix it! Don't leave that variable there if its not used. You know who you are.
A mistake programmers often make at the beginning, is to try to write the Whole Program, then compile it and run it. They will be bombarded with 100 compile errors, and even when compiled their program probably won't do the right thing.
The way beginners should start a project, is to make a small part of the program, compile and test it, and once it is working, move on to write the next part. Continuously re-running and testing your application, while you add or change only small pieces of code, is a great way to isolate any new problems in the recently changed code.
Using all kinds of weird control structures to avoid one little goto
. Everyone knows that spaghetti code is a bad thing, but one goto
does not make spaghetti code. Everyone seems to believe that goto
causes cancer and should be removed from the language. Way too often I see code that would be much easier to read and understand if it used one little if(something) goto somewhere;
instead of things like do {... if(something) break; ... } while(0);
.
Putting off writing documentation until the last minute. This is one that bites me no matter how much I try to avoid it.
Not using source control.
There are a few instances where it is feasable to skip the source control. If you can count the number of characters in the source file on one hand, It's probably ok to skip the source control. Otherwise, you need it.
Jumping straight into writing code without thinking about what you're trying to achieve and how you're gonna do it usually leads to inconsistent code that needs to be re-written again and again.
Also, don't get too attached to a particular paradigm. There are many ways to approach a certain task and one of the most important things you can learn is to choose the right tool for the job. Don't be afraid to step outside your box.
Believing (without question) what you've been told, or "common wisdom".
What others tell you may be true, but often it is just an attractive idea that started somewhere and keeps traveling, like a virus.
Your brain is yours. Use it. Think for yourself.
- Always document your code
- Use correct tab spacing
- Name you variables and classes something of meaning
While it's true that thinking about a problem before approaching it is very important, if you're not a seasoned programmer, sometimes you just need to start writing code. You can't foresee everything, and going over concepts in your head only gets you so far.
If you're anything like me, you'll find out that the code evolves and validates in your mind as you write it. Sometimes something that made sense on paper will turn out to be a terrible idea as soon as you write a function implementing it.
If you don't want to risk breaking existing code, start a Test project and try out the ideas and concepts for solutions there. It's sort of like TDD, but for people who like to experiment first, and then plan.
Quick list (in no particular order, but make sure you read about Occam's Razor)
1)stressing out is the worst thing you can possibly do, read up on the neuroscience here: Stress makes programmers dumber and the original series The Programmers' Stone
2)just keep doing and learning iteratively. Don't get too discouraged early on. Make time to look for prepackaged solutions that you can easily understand (try not to reinvent whenever possible).
3)don't blindly copy (cut & paste) "Copy and paste programming is probably one of the worst habits that one can develop while starting to learn programming. Learning how to program is best achieved by writing code and understanding other people's code. If you copy/paste code without understanding what's going on, you are doing yourself more harm than good." (from tvanfossen
4)Always set enough time aside for testing each piece of code that your write or connect to ("unit testing") codetoglory
5)look for common pitfalls in logic (antipatterns from deviant)
6)use appropriate named variables, whether long or short hypoxide
7)great one, don't optimize code before you have to, unless you know for sure the inner most loop call and the code isn't IO/memory limited originally from rob-kam.
8)catch error states. Die gracefully when you need to, pass back an error state otherwise
(my personal far out web design top 10 designed them thinking about web content, but all are applicable to coding)
Functions & methods should only do one thing!
Avoid writing functions that are bigger than needed by breaking them into smaller pieces - look for duplicate code and place this in a helper function.
Try to break up functions & methods with more than a few dozen lines into smaller functions - this will greatly increase readability and make maintenance and testing easier.
If you run into something not working the way you expect, it is possible that it is the framework's fault, but not in your (or my) case, check, double check, and triple check your code, then sleep on it and then check your code again... see it was your code and not the framework :)
Be careful about charging ahead in your own direction when five minutes talking to somebody might save you a day of effort. It's usually worth just asking somebody.
Using the debugger (and ONLY the debugger) to fix bugs or code. It's really handy and easy to do this sometimes that you end up spending more time with the debugger than thinking about the design or logic.
Shotgun programming. That's where bugs are fixed by randomly changing things here and there hoping one of them will solve the problem. Shotgun programming takes many forms:
- If the compiler says you're missing a parenthesis, throw in a parenthesis. Anywhere. If you're especially observant, you'll read the rest of the error message and throw it in on the line the compiler mentions. Then re-compile right away.
- Same applies for any other syntax error: quotes, semicolons, braces, etc.
- If the program compiles but gives incorrect results, change an expression or calculation.
- If that doesn't work, add some more parentheses or braces. Or take some away.
- Still not working? Add some more variables. You can never have too many.
But never, never actually analyze your code. That takes too much effort. Just make changes and re-compile!
If you start a new programming task don't jump directly into the code. Great programming starts on paper (or in the UML-editor if you wish).
Think before you code - it will save you a lot of time by not having to throw away solutions that didn't work out.
- copy and paste
- ignoring error handling
- using PHP
- meaningless variable/function/method/class names
- lack of comments/documentation makes it difficult to find out the intent of the program
The one thing that has always been painful is failing to spend time designing the program before writing any code. I've regretted it every single time.
No matter what approach you take to writing a program, it will likely take longer than you originally anticipate, especially when you are new to it. Learn to budget your time.
I agree with many of the above, but I would like to add three more; the first from "Unix Principles" that were compiled back in the early days of computing which are amazingly pertinent to today. That is create each program to
Do one thing and do it well
Look at such things as grep or awk. Many programs today try to be all things to all people and they are difficult to figure out and probably horrible to debug. This does not mean that you have to apply it to the top level application, but apply it in functions, methods etc.
The second thing is
** Do some planning on paper before starting to write code, even if you have a hot idea in your head about how you are going to write it. **
The reason for this is that you will tend to think of modifications to the basic design as you are writing the code. This means that you have to step back and re-design some of the code that you have already written. A little design brainstorming will make the whole process go better.
Pre-factor before you re-factor
The third thing is: **
Don't use a database for just a few records of a simple data structure
**
If you are using a random access record file of say 10 or 100 or even 10,000 records of some simple structure that doesn't need to cross reference another database just "roll your own" random access file or use xml and then access the data through your own code. I have had to install database programs of different types just to handle some insignificant amount of data. Databases are great for businesses that have millions of customers and a lot of tables are involved that have to access one another. But they are bloat for a few thousand or less simple records of say "Name, Address, City, State, Zip code"
Not getting an agreed requirements/specification document (or similar), signed off before writing any code.
It will kill your enthusiasm for coding rapidly when you discover that you have not hit the objective and have to re-write everything.
Things to avoid to me :
- Not putting comments in code, this behaviour can become a dead end faster then you can imagine
- Avoid difficulties by writting an extended code that does the same : BAD! You better learn how to do it right the first time so the next time you'll do it well the first time and you won't have to refactor it.
- Do bread programming, explication : No indentation in code, everything is at the same level. You MUST put indentation in your code to help the comprehension, and also for other peoples who might get their hands on your code
Things I encourage :
- Don't be affraid of learning new technics, going further than what you learn at school will difinitely pay off on your grades
- Have a problem? Google is your friend. You can, with the good keywords, nearly solve every problem you can encountered with google.
This is my first tought on it, I might add some stuff later ;)
Hope this help you ;)
Realizing that as a developer, you're going to have expectations placed on you to solve problems that you have no clue of how to fix. You'll never stop learning new things.
Runner up: Model-View-Controller (MVC).
Also-- get used to having weeks and even months worth of dedicated hard work completely thrown away by your manager b/c she decided to change direction on a project just before its deadline.
Make sure that you get your code reviewed from your peers. It always helps!
Writing code that's hard to read and needs lots of comments is a bad habit to avoid. Instead, you should write code that documents itself and doesn't need comments.
Here's an (artificial) example:
BAD:
if(!node.GetChildren().Size()){ // leaf node
ProcessNode(node, false); // false means not internal node
}
else{
ProcessNode(node, true); // internal node
}
BETTER:
bool is_leaf = node.GetChildren().Size() == 0;
if(is_leaf){
ProcessLeaf(node);
}
else{
ProcessInternalNode(node);
}
Not programming deliberatly. Many programmers don't know what they are doing, they don't know why their code is working, and hence they don't understand when it suddenly doesn't work. Read "Pragmatic programmer" by Andy Hunt, it's full of good programming habits. This habit is from that book.
Coding first
This may sound obvious, but coding before thinking through a task/problem beforehand is still more common than you'd think. It may even be behind the lack of useful comments in code - they're harder to add later, except maybe throughversion control.
I've itched this scratch and suffered occasionally from it with logic errors that cost more time debugging since the code give results but solves the wrong problem or in the wrong way.
I'm not saying you should contemplate universal implications or have a formal definition of things, . But, a simple diagram or checklist helps provide a mental model to revisit and confirm. Mind mapping tools can help for many projects, for design as well as collaboration and documentation.
In programming exercises for beginner students, I usually recommend that they transcribe or paraphrase the homework problem text to serve as comments for their code.
This reminds me of recommendations for checklists in operating rooms because they significantly reduce surgical errors and patient mortality.
- If you are doing something really special then it has 90% chance to be a hack. Don't over complicate simple things.
- Use a pen and paper! Write down a short description of your original idea, then list the features one by one. Give priorities and schedules. After that you can use a UML program to design the components of your program. Only then code.
- Read about top-down and buttom up design. Choose what's best for the language you use.
- Don't relay on the internet as your only source of learning. Get books and read, they often elaborate more on your langauge.
- Get to know well with the standard library of the language you're using. Don't re-do what's already done for you. It is probably done better anyway.
- Take breaks between coding sessions, I often find that when I'm stuck doing something else helps a lot.
- Sleep! Some coders tend to be obsessed to solve a problem when their code isn't working. While you're sleeping your brain still process thoughts and problems, just think about your problem before you fall asleep. I had sereval occasions where I woke up in the morning with the solution for a bug or a new feature that I didn't know how to implement.
- Read about coupling, design patterns, coding standards.
- Read blogs of programmers, you learn great things from first hand.
Not writing unit tests for your code is a horrible habit to get into. Learn a unit testing framework for your language of choice and try out Test Driven Development for a couple of weeks you'll never go back. The tests help you design better APIs and actually change and improve your code without fear of breaking things.
Also, trying not to blatantly repeat the many good ideas above
Avoid global variables. Write every with reuse in mind. Identify common patterns and implement them as parameterized routines.
One terrible habit I still encounter in the companies I work for is the lack of will to extend their knowledge. Most programmers learn a specific technology and stay there. Don't evolve. Others think that the company should pay them to take a course to recycle their knowledge. I don't think that's the way to go. We, personally, must have a conscience that we need to continuous learn.
The bad habit is: don't ever stop learning!
Just because you have a shiny new hammer, doesn't make every problem a nail!
This is the one I perhaps the most guilty of. I add a new tool to by arsenal and then I start going looking for reasons to use it. Just because your language added a neat new feature like say, generics or anonymous types, doesn't mean you should use it everywhere! Tried and true methods are tried and true for a reason. Just because something is new, doesn't mean that way is better.
Now, if you will excuse me, I have to go recode all of my WebForm code into MVC!
things that might help you become a better coder (and that they forgotten to teach you in school).
Dont repeat yourself
Command-query separation (CQS)
Defensive programming
S.O.L.I.D.
Code Smell
Smells to Refactorings
Patterns & Anti-Patterns
Software Craftsmanship
Not planning things enough.
Sometimes even a pencil and paper is one of the best programming tools. Of course, UML and other techniques can be really helpful in big projects. Writting a summary of what you're about to do also helps. Doesn't matter if it's pseudocode, or just a regular descriptions.
Conclusion, you'll develop in a quicker and more efficient way if you REALLY know and understand what you're about to do.
Programming behaviour not matching the project-class, and in general lack of project management:
- Overengineering simple programs. People are often way to anxious to show-off what they have learned software engineering wise, and that they have read GoF. A 1000 line throwaway program is not the place to demonstrate these.
- Throwing together large apps. The opposite of the previous. Typically very slowly growing due to steadily growing requirements, without ever rediscussing the base assumptions etc of the project. It is always just that one feature more.
- Doing 2.0 rewrites that totally get out of hand. Always keep the scope of rewrites limited or their time to market will slip horribly. There is no Silver Bullet, also not in rewrites.
- Mixing in fashionable technogies without direct demand from the customer(s).
For Large Projects:
Avoid trying to 'push through' a project if you get stuck. Go do something completely unproductive. (joke?) Something else and get your mind off of the task at hand... sooner or later the answer will come to you. Breaks are sometimes the best programmers true friend.
I don't comment enough.
I know I do it, and I keep trying to fix it, but I keep coding too quickly and forgetting to comment!
I over-engineer....hence this question Ways to prevent over-engineering
For small functions, I use
int tempval = ...
and the like. I know I shouldn't, but sometimes I can't think of a descriptive name, and ... oh well.
I have a tendency to forge ahead with a poorly thought out implementation when a deadline approaches telling myself I'll go back and refactor... which, of course never, happens.
Definitely the lack of comments.
Also, I often find myself afraid of using "ugly" solutions, preventing me from getting work done. Of course, in itself, this isn't a bad thing, but somethings you just have to do something to keep on moving with the project.
I'm much too easily sidetracked. I want to write a program in Clojure, but first I'm going to create a Web site where the Cheat Sheet and API reference are cross-linked and extensible. But before I do that, I want to write a proxy so I can hear last.fm while I code yet another diversion...
try {
myCodeHere();
doSomethingElse();
} catch (Exception e) {
// TODO: Handle this intelligently later.
}
If I'm having a good day I might add e.printStackTrace();
.
I start far too many hobby projects, and seldom manage to complete any one -- or even reach an intermediate milestone.
When I tell myself, "Oh, I'm in a hurry so I'll write unit tests when I have some spare time", I never end up actually writing them. Which is why I've been forcing myself to write them first.
It's always easy to be wary of anything that's Not Invented Here.
I think Rands summed this up best:
NIH ("Not Invented Here")
Term to describe behavior where an engineering team will not consider working with anyone's code except their own. It's not that the external code is good or bad, it's just foreign which means it must be reviewed, reformatted... oh, what the hell. LET'S REWRITE THE WHOLE DAMNED THING. Billions of dollars have been lost to NIH. I mean it. Billions.
Spending too much time on StackOverflow instead of actually developing!
Being anal and formatting other developer's code because it isn't "pretty".
Thinking I know what the users want, without checking it often enough.
I feel I do not test my code enough, or that during testing, I let certain problems through out of a desire to move on.
Some of these come back to bite me later, which can be rather embarrassing. Iterative development is nice and all, but I wonder if I've found that fine balance between doing things 'good enough' (to meet a deadline), and doing things properly (to ensure you don't get embarrassed later).
One of my vices is more the opposite of the "Re-write everything" vice. At some point, legacy code should be thrown overboard. Perhaps not too soon, but it is possible to spend too much time trying to make something that is fundamentally broken, work again.
I always want to re-engineer everything I find "That can be done smarter" and "I can do better then that" till I end up with three different implementations of the same thing.
It's no wonder that young folk are queueing up to avoid IT courses and the IT industry if we are really as boring as this. Apart from Dirk Eddelbuettel's comment, none of the answers come close to my idea of a programming vice:
programming while drunk at the wheel of my Porsche 911;
programming while engaged in sexual activities with colleagues;
using recreational drugs to achieve the right frame of mind before starting work at about 45 minutes before heading off to the bar for the evening.
Please, colleagues, try a little harder
Sigh
Mark
Being too insistent on having a simple interface to things, no matter how much it complicates the implementation.
A general lack of consistency with my naming conventions.
I'm usually consistent enough when I'm focused on just one project. But my naming conventions tend to change slightly every year. So this can become annoying when I work on a project over a long period of time.
For example, did I name that database column CreatedDate or date_created? I just need to pick a convention and stick with it.
Not using a source control system like Subversion or Git even for toy or one-shot programs.
Telling yourself "I'll check it in later" is just like your pointy-haired boss telling you not to worry about all the technical debt because "We'll come back and fix it" which is right up there with "The check is in the mail" and "We're from the government and we're here to help".
I have the attention span of a goldfish if I'm not motivated. I'd rather dream about brewing beer than doing programming I have no interest in. I plan to carry this on until I ditch programming and open a brewery, where upon the day dreaming will probably flip back the other way...
Using very short abbreviations for variable and method names, a practice I picked up from my early days as a Fortran programmer.
I actually listen to what the user says he wants. I later realise he hadn't a clue.
Designing as I code. Part of this practice involves moving chunks of code off to their own functions as it's all coming together... except, sometimes I never get around to that "housekeeping" step, so I end up with lengthy functions and repeated code. Eventually, in all likelihood, I end up refactoring (cough throwing it all away and rewriting it).
Posting subjective questions on SO.com in the hopes of getting more SO rep when I should be working.
Answering othe people's subjective questions on SO.com in a slightly tongue-in-cheek, sarcastic manner, and hoping that other programmers upvote my somewhat dry ramblings, thereby generating more SO rep.
I think I see myself in so many answers here already!
My vice of late: Adding this comment: //TODO: Refactor this later and then never finding the time to return.
I buy domains and then don't use them, and then renew them :(
When I prototype
if(condition == true)
return;
instead of
if(condition == true)
{
return;
}
And of course I forget that I was the one who wrote it and chastise random people during code reviews.
I spend a lot of time tweaking my editor, my shell, my fonts, my colours etc. I do this because when my vim-fu is rocking, then programming is a tedium free romp. I always find time to do this, and I never think it is time wasted.
So really I have 2 vices here:
- See above.
- I lack remorse about my vices.
Care too much about what other people think about the subject.
Writing:
if(variable == true) variable = false;
else variable = true;
Instead of:
variable = !variable;
Or:
if(condition == true) ...
Instead of:
if(condition) ...
Or:
if(condition) {
// Do nothing
} else {
// Do something
}