Channels ▼
RSS

Design

Advice to a New Programmer


Every few months, I receive a request by a new programmer who, with commendable diligence, wants to know how best to become a really good programmer. I also see this question a lot on programmer forums, which is a heartening trend. The most thoughtful answers tend to follow in similar channels to my thoughts on the subject, which suggests that there is indeed a certain basic agreement on fundamental best practices. I hasten to add, therefore, that these counsels are not original, but perhaps the color I add will provide additional insight.

More Insights

White Papers

More >>

Reports

More >>

Webcasts

More >>

The beginner I have in mind has a basic understanding of how programming works, has written mostly small programs of varying complexity, and is heading off to either a career in the field or committed to excellence for his or own personal projects.

There is only one truly foundational activity in programming: writing code. To be good at it, you're going to have to write a lot of code. That big body of work can be a vehicle for growth, or an exercise in repeatedly practicing a limited set of skills. To avoid the latter, you need to:

Read a lot of code. Specifically, read a lot of code by excellent programmers. Not just good programmers, like the guy down the hall, but excellent ones. Due to the huge amount of open source today, this is easy to do. When I was learning Java, I read code from the Tomcat project and from the CI server, Cruise Control. I've read lots of good code since.

It might be tempting to look for main() and start from there, but you're likely to spend a lot of time just reading set-up code and command-line parsing. I prefer to scan the filenames to look for some activity that interests me and then dig into those files. It's not crucial to understand the whole project or the ins and outs of the entire design, you'll wear yourself out doing this. Read the code. Look at the comments, see what the authors are doing, and how they went about it.

Learn your tools thoroughly. I think the greatest loss of programming time is not in debugging or rewriting code, but in the innumerable seconds lost here and there by developers who don't really know their tools. I am referring to: the IDE, the language, the build system, and the VCS. Of these, the IDE and the language are by far the most important. You should, after a few weeks of practice, know almost every keystroke combo in the IDE, so that you touch the mouse only when it saves a lot of keystrokes. If you know the keystrokes, you know the commands. If you use the mouse only, you know only menus on which you tend to click on the same one or two entries. Knowing the IDE is pure discipline.

Knowing large languages, such as Java or C++, takes more than discipline. They're huge, as are their libraries. Reading is the best approach, in my view. Read code that uses features you don't know and you'll look for opportunities to use them. Books (rather than blogs) are another excellent source. Read about features that are on the periphery of what you use currently, and soon you'll find the periphery expanding. Knowing the VCS and build systems make you a desirable team member — who doesn't waste time due of ignorance of important operations.

Plan your code before you write it. I think this is the most difficult item on this list. In exchange, it probably delivers the most benefit. I'm not thinking of formal design — at your stage, that's unlikely to be necessary. But you do need to plan out the code in some manner other than carrying it around in your head. The simplest approach is to write up a small document (I frequently use a mind map): What are the requirements for this code? How will you implement it? What do I need to know that I don't know now? What are the objects I will need or need to create? And write this out. Only then begin to code, you'll find the code much easier to write, to document, and to get correct. Save your notes — they're great reference material.

Write lots of code and have it reviewed. If your site does not do code reviews, do them yourself. Find the best programmer who'll give you useful advice in a way that can be heard and understood. Don't be a pest, but don't avoid the process because you're shy, busy, or feel you're good enough, etc. Code reviews should be part of your programming life. Be creative. Try pair programming with someone more senior than you for an afternoon. The important thing is that you need feedback that you cannot give yourself.

Write tests as you code. This advice is perhaps the only controversial item here. It's not an endorsement of TDD. But it is an endorsement of knowing that your code works in most scenarios it will face. Start with unit tests and exercise new code with edge-case values. For example, does your function work if it is passed a negative value, or the maximum integer size? If not, does it throw an informative exception or just blow up? If not an exception, have you narrowed the range of inputs with asserts? If so, test the asserts. Use the planning you did earlier to write mocks, and then begin testing your new code with objects you still need to write. This will clarify design issues in your current code and the upcoming objects. Save your tests and run them prior to every check-in, so that they can be early warning systems for later code that breaks your current code.  

There's a lot more advice and many wise sayings that can be added to this list. But that's part of the problem: There's so much advice available that it's difficult to know exactly where to start. For that reason, I purposely limit my recommendations to just five points. If you apply them with diligence, you'll soon find two things: You'll be able to handle progressively larger and more important tasks, and you'll look back in embarrassment at code you wrote just a few months ago.

Both experiences are sure signs of progress. Good luck!

— Andrew Binstock
Editor in Chief
alb@drdobbs.com
Twitter: platypusguy


Related Reading






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Comments:

AndrewBinstock
2014-01-31T17:52:01

I don't share your way of talking about new programmers. The reason I wrote it for them is explained in the very first line--they're the ones who asked me.


Permalink
ubm_techweb_disqus_sso_-b1088c0e05c97acf5a376ba2563c349a
2014-01-31T10:08:33

Why is this type of advice always aimed at the wannabe code monkey? What if one wants to become an actual software engineer and be more than a glorified manufacturing worker?


Permalink
ubm_techweb_disqus_sso_-656f64b26b78cb3d3703f58f7f7de7b6
2013-09-05T23:31:19

Don't read bad code. Really, it's that simple. There is so much good code out there to read; code that has been documented and discussed and reviewed and fixed and expanded and fixed again, why would you want to pull up some random bad code? Pick code that is known to be pretty awesome, and has been extensively commented upon, and read the commentary as well as the code.

If you're in to operating systems, Linux, FreeBSD, and NetBSD have such long and rich histories, pick a piece of code that interests you and start there. Check out the history, how and when and why has the code changed? It's an education in and of itself. Plus you get to read code written by guys like Kirk McKusick and Sam Leffler and Alan Cox (either one) and that one Linus guy.

If you're interested in security, read the openssh code. Read the developer mailing lists. Find out what security concerns they have, and what they did to the code in response to them. Figure out when, how, and why new encryptors were introduced to the code. Read the mailing list archives and see why, and who did the work, then follow their work.

When you understand what it means to be Brucified, you're on the path to becoming an OK programmer.


Permalink
ubm_techweb_disqus_sso_-16d7c50d6c078abc2acbddb01ccf46d4
2013-08-27T18:58:28

Just bought/reading 2ed, 15 years after reading 1st ed (great book). So far, I like all the OO additions (e.g. what makes a class a good class, the first question I asked when learning C++ 20 years ago).


Permalink
ubm_techweb_disqus_sso_-2b8396b957bb1fb1c46f97fda5a16cf6
2013-07-30T14:37:59

Understand how the microprocessor works. While you don't need to know how a car works to drive, it really helps when something goes wrong. A good overview is at http://deepFriedCode.com/hmw but most colleges also have courses for CS majors. Learn whats under the hood.


Permalink
ubm_techweb_disqus_sso_-449371365e7fa3e8aa9544383282c8bf
2013-07-21T20:06:38

Actually, I was thinking more fundamental than that.

If your code is unreadable should it even be delivered at any time (on or off)? If code cannot run should it be delivered at all? And if the code doesn't run fast enough to be competitive should the customer accept it?

Take Ogilvie's advice to heart and you are one step closer to worrying about delivery schedules, QA issues and fixing the boss' kid's laptop.


Permalink
AndrewBinstock
2013-07-21T04:33:06

Completely agree.


Permalink
ubm_techweb_disqus_sso_-fb064d76b12350bf4e5a879d08bb6455
2013-07-20T18:08:40

The article and comments are fine as far as they go, but to give a new programmer a really good start, I would recommend giving him/her a copy of "Code Complete, Second Edition" by Steve McConnell (2009). Reading, learning, and inwardly digesting this work and its many references should produce a solid foundation for future years, and is not a bad idea even for those already practising their craft.


Permalink
ubm_techweb_disqus_sso_-678cac889be1915d41b06ac9548cbcc1
2013-07-20T12:26:10

Reading the code of other people to learn programming makes sense. But doing this when you are an experienced programmer could be a pain. In this case you have to learn to bash the problems in the code of others until they are able to write good code theirself and nobody dares to bothers you with his code any more. But in some rare cases you should also take your chance to add some layers of hidden complexity to such code, maintaining this stuff later may ensure your job. Every beginner should read "How To Write Unmaintainable Code" for getting a first clue about this. ;o)


Permalink
ubm_techweb_disqus_sso_-678cac889be1915d41b06ac9548cbcc1
2013-07-20T09:13:28

It seems to be a question of definition of 'good programmer' too. Does delivering in time or in budget count more than delivering high quality? May be in some rather rare situations. If this are not really rare situations than good programmers should know when to change the employer or simply stop trying to deliver software in the time and budget of unrealistic demands.


Permalink
AndrewBinstock
2013-07-18T00:51:06

Thanks for the thoughts, but it's not true that all other good advice flows from these three precepts. Important things like delivering on time and on budget are not covered directly or by implication.


Permalink
ubm_techweb_disqus_sso_-68e5f1ac8d9b7a72458d5ed5d0dd6d9f
2013-07-18T00:35:23

Spot on JulesMay!


Permalink
ubm_techweb_disqus_sso_-68e5f1ac8d9b7a72458d5ed5d0dd6d9f
2013-07-18T00:33:07

This advice has been provided in other comments, but just to reiterate. Read code. There's a lot more code out there to be read than you can possibly write, so you'll be exposed to many more ideas and techniques ( good and bad ) without having to create them yourself.

And in all honesty 99.99% of programmers are going to spend far more time reading and maintaining code that other people have written. Get good at that first!

Eventually try to learn what good and bad code look like. There are many helpful books in this regard. But when you've got to figure out how something works or why it doesn't work, you've got to be able to read the code whether its good or bad.

I wish I had spent more time reading than writing code when I was a new programmer.


Permalink
ubm_techweb_disqus_sso_-449371365e7fa3e8aa9544383282c8bf
2013-07-17T18:33:50

My favorite advice over the years for new programmers -- which is simple, concise and fundamentally important to all programmers -- comes from...

John W. L. Ogilvie*

"1) Make it readable.

2) Make it run.

3) Make it run fast if you have to."

All other (good) advice follows from this. Thanks John!

*Advanced C Struct Programming


Permalink
ubm_techweb_disqus_sso_-4124b309ed8223fe99361b41fa82ae3d
2013-07-17T15:11:09

"Learn your tools thoroughly" is particularly meaningful. Though over the years I seem to have become more of an OS or system's integration guy than software developer, it seems important to note how profoundly valuable the the incremental learning process is. Don't get hung up on trying to do this all at once, because that is not possible. It is amazing how much is gained by periodically speeding through manuals, references, and the like - not wasting time on the familiar or that which would require great expenditure of time to grasp without fulfilling a current need - always looking for clues when to slow down for the low down on expanding the perimeter of the known into the relevant areas in the realm of the unknown.

"Write tests as you code" seems to miss the difficult-to-overestimate value of expecting the unexpected or considering the run-time environment. It's easy to find coders that get the correct results in pointed tests that prove the algorithm, etc., in the equivalent of a clean-room environment. Being an integration guy for some time now, its been easy to see repeatedly and remarkably expensive it is when programmers fall prey to the belief that it is sufficient to test for "correct answers". The run-time environment tends to be remarkably well populated with unpleasant surprises that often result in upset people and a stressful job.

"Read lots of code" was a surprise to me. I'll have to think about that one, but probably would not have listed it first. Then again, as an iterative learner, knowledge comes by doing. Reading without doing tends to result in less throughput - with time wasted studying stuff of limited applicability to the needs of the moment. That's not to say I don't see value in expanding knowledge prior to seeing need to up the odds of quantum jumps in performance, etc., but these days it seems difficult to justify sitting around doing a lot of reading... but then perhaps that's a personal problem?

"... and have it reviewed" brings to mind "Check your egos at the door" and other wisdom expressed by Wiegers, Karl E. Peer Reviews in Software, Addison-Wesley, 2002.


Permalink
ubm_techweb_disqus_sso_-e1cb6d27ef8310898b3067f37a5a489f
2013-07-17T09:35:03

All good advice, and most of all there's no substitute for reading code, especially good code, wherever you may find it.

But I'd add two more. First: learn a new language every year. You can start of with variations on a theme (C#, Java, Ruby, Python) but don't leave it too long before pushing the envelope - try Haskell and Clojure and Eiffel for doing "proper" work, try vanilla C or FORTH or even ASM to really understand what's going on inside the machine, Try some exotic and specialist languages like yacc or Joy or Prolog just to see what a language can be. What you lean here will filter into your more conventional writing.

Second: learn algorithms. Algorithms to a programmer are like scales to a musician. Even if you never write your own sort routine, it's really helpful to have an understanding at the back of your mind of what the library is doing. But often, a hand-crafted solution to a specific problem can give spectacular results compared to the pre-fab ones.


Permalink
ubm_techweb_disqus_sso_-6516eb1e235d49fe49c2849143b4c255
2013-07-17T08:42:38

I'd suggest looking at bad code is an excellent way to learn as you can learn from other people's mistakes [as long as you recognise they are mistakes]. I believe any developer [new or old] would benefit from working in Support for 6 - 12 months fixing/amending other people's code. Most developers I know, who write well structured, maintainable code (which should be a key objective) have spent time in support. You get to find out what another developer needs and how to program maintainable code. You get valuable experience debugging, analysing and identifying root cause of bugs.

With regard to comments, I'd suggest you also need to comment on "why" you coded something the way you did; any decent programmer should be able to see what the code "does", it's the "why" that's important. For example, any assumptions you've made; do you trust the parameters provided are valid or do you need to re-validate? That would depend on the type/level of code you are writing; if someone writes a validation module and you develop an update module, you assume all data is valid so explain that and why [eg. as per specification].


Permalink
ubm_techweb_disqus_sso_-93821031f8f915d90048b8eef3708a20
2013-07-17T01:45:05

"Read books rather than blogs...." Wow. That's so 1990s, and still good advice. Charlie Babcock


Permalink
ubm_techweb_disqus_sso_-c1319b5c2a8b278ec6190de7d1d46918
2013-07-17T01:38:21

I agree with reading code, but most of it out there is examples of bad practice rather than good. Programmers should also get familiar with languages like Eiffel and Haskell, rather than arcane and flawed languages like C++.
Particularly relevant in Eiffel is its implementation of Design by Contract which goes much further than TDD and provides accurate documentation. It designs module interfaces not just on how they look, but on what they do, writing the tests at the same time to prove that they do what is claimed. That really is the kind of technique new programmers should be taught.
They should also be taught the basis of Structured Programming, that is very simple programming with proof concepts built in, and why side effects (++ operator), gotos, and pointers undermine this basis of good programming practice.
Programmers should also be taught computational paradigms of 'what not how', especially relational database theory and practice (SQL - although that is flawed).
Also to separate the concerns of computing and computers and understand why programming is about computing, not computers.


Permalink
ubm_techweb_disqus_sso_-678cac889be1915d41b06ac9548cbcc1
2013-07-16T22:51:28

You are right and I just wanted to add similar comments. Without good logging you can't find the errors that may happen on distant and possibly quite exotic systems around the world. If your software runs in production systems any bug can be really expensive and so you should be able to locate nearly all problems in nearly no time by reading the loggings only.


Permalink
ubm_techweb_disqus_sso_-eb143e6d5f6d149c968e253a5efe5875
2013-07-16T22:02:43

Learn the Unix way: lots of small programs communicating by text files each doing a small part of the whole, well.

Learn a modern scripting language such as Python

Write to throw one away: A good days programming can easily result in _less_ code than you started with!

Learn to push back. The feature requestor should be told the cost of every feature they add.


Permalink
ubm_techweb_disqus_sso_-2bb621dce7682e7fa6965b06c4ef8c0d
2013-07-16T21:52:59

1) Be aware of the 2 types of functions i.e. operational and detail. Operational functions call multiple detail functions to accomplish an overall goal. Detail functions are single-purposed and exist to accomplish a single task.

Example, user withdraws money from account.

Operational function

=================

ExecuteAccountWithdrawal

Detail functions called by ExecuteAccountWithdrawal

======================================

SelectAccountToWithdrawFrom
RetrieveAmountToWithdrawFromUser
ValidateAccountBalanceForWithdrawal
DisplayInsufficientFundsMessage
DeductCustomerAccount
DispenseMoney

So ExecuteAccountWithdrawal is an operational function. It calls multiple detail functions to accomplish an overall task of withdrawing money from an account. Each detail function is single-purposed and can be re-used across multiple operational functions.

2) Write short functions. A good start for newbies is to try and limit the length of your functions to 30 or 40 lines of code. Try to shorten the length as you get more experienced.

3) Don't repeat yourself (i.e. the DRY principle) - a good rule of thumb is that if you ever catch yourself copying code then that means you need to refactor that logic out into a detail function.

4) Single-purposed - touched on this already but worth repeating. Ensure your functions do one thing and one thing only. Your function shouldn't have side effects. DeductCustomerAccount should do that and only that - it shouldn't send an email letting them know that a withdrawal was just performed. You would create a separate function to handle the email.

5) Abstract business logic from UI - don't intermingle the UI code with the business logic. As you're coding, code as if your business logic would have to run as a nightly background process that receives it's input from a file instead of an end user. Should do the same for database logic but baby steps for now.

5a) Abstract business logic and technology frameworks - just something to keep in mind but again try to keep your business logic independent of specific frameworks. If your company decides to move from WCF to Web API you shouldn't have to re-write all of your business logic. The technology is changing not the business. So keep the two separate and distinct if possible.

6) Leave comments - you will be grateful when you come back to that code six months later that you did.

7) Write comments that explain the intent of your code; don't leave comments that explain the code line by line but write comments that explain in a common sense way what you are trying to accomplish.

8) use meaningful names for variables, functions, classes etc. Can someone look at that name and understand its purpose in life? Give thought to the names you use within your code.

9) Personal pet peeve and language specific but don't overuse the dot operator. IMHO if you have to use more than two then do an import or create an alias. I hate seeing a whole line of code with 5 or 6 dot operators just to declare a variable or call a single function!

10) Code for the programmer that will have to maintain the code and envision that they have no documentation than the code itself. How easy would it be for them to grasp the overall intent and purpose of your source code? Try to make their job easier cause more than likely that programmer will be you.

11) Spend a bit of time doing a post-mortem of your work at the end of your project. What did you do good/bad? For those good/bad points identified can you identify the steps that took place which brought them about? Learn to be your best/worst critic and always strive to improve.

Everything else will come with time.


Permalink
ubm_techweb_disqus_sso_-9795de5abb66e150e973e1fbf3ef755b
2013-07-16T21:49:34

A couple more to add:
1) Add comments as you are coding. Use meaningful comments to explain what is going on in the code. It will help you when you revisit a module months later, and it will help other people who have to modify your code.

2) Learn how to add logging (audit trail) to your code. It can help explain why your code acted a certain way based on some input. For example, you wrote a zip code validation function. A user says they typed in valid data yesterday, but your function didn’t handle it right. If you logged their input you could verify what they entered. If you also logged what your code did based on the input, you could see how you program worked as expected or needs adjusting. Logging is very helpful for programs that run overnight or in the background.


Permalink

Video