My alma mater, Northwestern University, holds the unfortunate distinction of being the only school in a major athletic conference to have never qualified for the men's NCAA basketball tournament. It's become so bad that our fans have come up with a simple slogan for the team. It simply reads:
Though it sounds like we're just poking fun at our own team, I've always found this slogan to be more poignant than funny. And, deep down inside, I think everyone else in our fan base feels the same way.
You can strategize all you want. Study film. Hit the weight room. Practice your jumper a thousand times a day. Prepare to your heart's content. But, as cruel as it sounds, you will only be judged by the shots you make and don't make during a game. You don't get a free pass because of all the hard work you put into a missed shot.
And so, if I had to sum up all of my programming experience into only one piece of advice, it would be something similar:
Make good decisions.
The best programmers I've ever worked with always do this one thing consistently. It's not that they knew a certain language or specific pattern or were the fastest to come up with a clever solution to an intricate problem. It was that, when faced with a challenge, they somehow always executed their solution beautifully. They made good decisions.
The tricky part about making good decisions is you don't know you've made them until you see the result. Just like you don't know you made a shot until it goes through the net. But, this is where repeated experience comes into play. The more attempts you try, the better you can assess yourself.
Experience isn't the only indicator though. The programmers that make good decisions also seem to master these traits:
- They treat small problems with as much deference as larger ones.
- They take justifiable shortcuts and clean up their debts appropriately afterwards.
- They take worthwhile risks and make sure they are as un-risky as possible.
- They look at any decision as a trade-off.
- They add more code while maintaining clean code.
- They know what's most important to customers, clients, and the codebase and find the right balance in between.
- They permanently plug code leaks rather than repeatedly mop up wet floors.
- They estimate delivery times with relative accuracy.
- They communicate their intent (both in code and to humans) clearly.
- They are enjoyable and reliable people to work with, particularly in the heat of the battle.
- They don't simply “take the blame” when something goes wrong. They own the problem.
- They're able to adjust course if small roadblocks get in the way.
Even with all of these traits, there still is no guarantee that a programmer will make a good decision every time. Just like the best basketball player will still miss a shot occasionally. There is always a small ounce of luck involved in any decision. But, as the Roman philosopher Seneca once said, “luck is what happens when preparation meets opportunity.”