How does one improve as a programmer when they are already at an intermediate level? There are plenty of resources on “learning to program” that will get someone from 0 to novice (although the quality of most of these resources is pretty dubious), but what are the practices that will elevate someone from intermediate to expert? How can I build the mental models that allow me to write code at a high level?
In this post I’ll go over some of the theory around general performance improvement, then go over some methods programmers use to practice (and my thoughts on these practices), and then my conclusion on the best way to improve as an intermediate or better programmer.
A quick note on general performance improvement
I’ve been reading a lot about performance improvement lately, and most of the literature uses K. Anders Ericsson’s research as the starting point. He is the pre-eminent face of performance research, and is cited in almost every book that touches on the subject. His book released this year, Peak: Secrets from the New Science of Expertise, condenses his 30+ years of research into a digestible format, and it’s the single best resource I would recommend the most to a newcomer to the subject.
To summarize briefly for context:
- Improving at performing a task comes from developing better mental models through deliberate or purposeful practice.
- To be able to achieve improvement, one must be able to define what constitutes improved performance and break down the steps to achieving that.
- Practice and performance are different, and the best way to practice is almost never performance. For example: a baseball player who wants to improve his hitting spends 30 minutes taking 200 pitches at the batting cages (practice), not 2 hours seeing 15 pitches in a game (performance).
Methods to improve
I’ve found that most of the ways people recommend improving at programming are just performance-based. Read code, read about code, write code, do projects, talk about code, etc… A programmer will almost certainly improve if they do these things outside of their own work, but it doesn’t seem very efficient.
What if I want to get better at programming, but only want to spend a couple hours per week of my own time doing it? What’s the most efficient way to build better mental models so that I make better decisions? One of the go-to examples of deliberate practice in Peak is musicians. There are defined, regimented ways to improve at a particular instrument or to learn a new piece of music; including an example of a musician learning a new piece of music over the course of a couple of months with just 5 minutes of daily deliberate practice. With programming, we don’t have the luxury of that kind of well-defined goal or measures of improvement (ie: number of mistakes on a certain segment of a musical piece), but I also haven’t found anything that’s even relatively close.
So how do we get a feedback loop on our own performance as programmers? Yes, we get a feedback loop on a particular piece of code, whether it works or not, how performant and robust it is, etc. And we have a longer feedback loop on the robustness of systems as they fall over under load or become unwieldy overtime. But we don’t often get real-time feedback of our approaches to a problem.
Here are the methods I’ve used to study programming, where they’ve been ok, and how they’ve fallen short:
Practicing via programming challenges
I enjoy doing programming challenges, but in general I’ve found they’re not worth much past getting exposure to a new programming language. They offer a weak feedback loop - your program either produces the correct output or doesn’t - and doesn’t give you feedback on your design process. This method may introduce you to a new algorithm or new features of a language you’re not familiar with, but in terms of practice, it’s pretty weak. It’s much closer to “performance” than “practice,” and you’re dealing with contrived problems rather than real ones.
The one exception I’ve found is Advent Of Code by @ericwastl. The programming problems simulate real-life ones pretty well (requirements are well-defined, but edge cases are not written into the spec and must be implied), and there is immediate feedback on how well-designed your solution was, because there’s a part 2 to every problem that throws in extra requirements or some other wrinkle, meaning you have to reevaluate how well-designed your original solution was. It’s not perfect, but I’ve enjoyed seeing my solutions challenged, and have often had to re-think the structure and design of my solution when I get to part 2.
Doing side projects
Doing side projects, if you have one in you, can be a great way to get extra programming hours in; it doesn’t feel like work if you’re doing something you like. Unfortunately, depending on the project, you might not actually learn anything. If your side project aligns with something you want to learn programming-wise, it can be a good choice, but otherwise it’s just another version of practicing via performance. Even in the best-case scenario, if the main goal is producing something, it means practice and learning takes a back seat.
Reading books about programming practices
Reading programming books can be a fantastic way to increase knowledge at a high rate, and I think it should be a part of pretty much any “improve programming” regimen. It is not, however, anywhere close to a silver bullet. Pure knowledge acquisition can help you know what options are available when you approach a certain problem, but knowledge is not a substitute for better mental models.
Unfortunately, I haven’t been able to come to a concrete conclusion myself. Maybe the answer is that one needs to have a programming coach or mentor that can give pointed feedback and specific practice suggestions. Maybe the discipline is still too young to have formalized ways of performance improvement like classical music training or sports training.
Send me an email at firstname.lastname@example.org with your thoughts. I’d especially love to hear from people who have produced high level programmers via teaching/coaching/mentoring, or people who have studied under one such teacher.
I will certainly write a follow-up post if I get any clearer ideas on performance improvement for programmers. Thanks for reading.