Programming is a journey of continuous learning. There is an immense collection of programming paradigms to be learned, many of which require a good amount of experience before they start making sense.
Still, one of the biggest lessons I’ve learned over time about my trade is not exactly on how to write code. It’s identifying what the problem actually is, before you start thinking about your solution.
An answer by Thomas A. Limoncelli at Quora to a common computer programming lesson — finding a number in an array — greatly illustrates this point. It dodges the original question by coming up with indirect solutions that are likely more effective in practice at solving the original problem than any perfect, on-spec solution would be.
(It is also better at explaining the common dissonance between problem and expected solution than I am, so I understand if you want to keep reading that answer rather than this post.)
When I started learning programming, I used to focus on making my code run as fast as possible. This was in the 90s, and speed was easily one of the biggest bottlenecks in any operation a computer had to perform.
One day I run into a Usenet discussion on Demo architecture and techniques. It was a critique of the “fastest putpixel” entry on the PC Demos FAQ. The original post is now long lost, but the gist of it is that the fastest putpixel doesn’t matter as much as most people normally assume, and the search for the fastest pure putpixel is a fool’s errand.
Obviously, the instinct of any programmer when they’re trying to implement a fast PC demo is to try and make the pixel operations as fast as possible. But what really matters once you look at what you’re actually building is all that you are doing prior to that putpixel, and how you are actually avoiding calling a putpixel entirely until necessary.
Granted, the current FAQ answer does take a little bit of that advice into account, in its last paragraph. Still, reading that comment was an eye opener to me at the time: it was when I started realizing you gave to look at the big picture when deciding on how to approach a problem.
Programming is normally taught via lessons on how to build a specific solution to a given problem. The lesson that normally goes untaught is knowing what not to build.
Most developers I know genuinely care about their work. Programming effective solutions require a good amount of effort, and it’s difficult to do good work just by winging it. Still, there is a difference between caring about solving a certain problem in a self-contained manner, and caring about what you’re building. At times, the solution to a given obstacle is not a complex algorithm, but circumventing the problem entirely.
Over time I learned that coming up with an elegant algorithm to solve an immediate problem can be a sign of immaturity. After all, it’s fun and interesting to come up with clever code. But it can also a sign of arrogance and self-importance. An elegant architecture that takes the whole picture into account trumps micro-cleverness.