After reading Peak by K. Anders Ericsson and Robert Pool, I've been thinking a lot about how to apply their advice to software engineering and the craft of programming.
In sports like climbing, BJJ, or weightlifting there's quite a few structured training programs to choose from. Climbers have hangboarding and 4x4s. BJJ students have a common class format: warm ups, techniques/drilling, and rolling. Lifters can choose a program like Starting Strength, which dictates which exercises to perform at how many sets/reps and what weight to use.
As a software engineer, I have no idea how to practice to get better. Could we create a similar structured system? In this article, I'm mostly thinking out loud about how to become a better software engineer.
When you first start a new sport, game, or skill, you can get better just by participating. If you're completely new to chess, you'll improve just by playing more chess games.
Ericsson calls this naive practice. It's just blindly repeating the same tasks over and over again, without much strategic thought. There's no focus on specific skills you need to improve, no goal setting, and no overall planning. Naive practice will get a person to reach an acceptable level of performance — but additional years won't lead to improvement.
Naive practice is perfectly fine and sometimes even recommended! When we first start programming, simply picking up a tutorial and writing programs is enough to improve.
When you reach a plateau with naive practice, you'll want to start purposeful practice. This involves:
- breaking down the skill into chunks
- working on specific goals, especially to fix your weaknesses
- focusing intensely on improving a single chunk via practice (with full conscious attention)
- using an immediate/specific feedback system (ideally with quantitative measurements)
- continually push yourself to more challenging levels, outside your comfort zone
A baseball player's naive practice would be simply playing baseball games everyday. For Purposeful Practice, the player can pick a specific skill to improve — let's say batting. She can use an automated batting cage, record her swings on video for later feedback, keep statistics on her hits/misses, and keep a qualitative journal after each session. She can continually push herself by slowly increasing the speed of the pitch.
How can this be applied to software engineering and programming?
Focused practice — pick projects that will force you to develop your selected chunk. Since this is practice, your projects don't have to be used in production either. Commit to 100 Days of Code focused on your chunk. Use resources like books/screencasts to learn. Use resources like Execute Program, LeetCode, A Cloud Guru, Vim.so to practice.
Feedback system — I've found these systems apply to most programming skills: code reviews, pair programming, mentorship, and journaling. Code reviews from your teammates are a great way to gain valuable insight, just leave a short comment on your pull request asking for specific feedback. This works with pair programming sessions too. You can always ask your manager about how you can improve during your 1-on-1's. Keep a journal. Ask yourself what went well, what could have been done better, and record what you've learned.
Continually push yourself — pick projects that are more challenging than your previous. Look for projects that let you dip your toes into something you've never done before. Look for projects that will require learning from a book/screencast or some guidance from a teammate.
Deliberate practice is purposeful and also includes:
- an well defined field where the regimen for improving is known
- an expert coach mentoring on how to improve by giving you a plan and providing feedback
“Deliberate practice is purposeful practice that knows where it is going and how to get there.”
You can get far with purposeful practice. You can get further with deliberate practice. The world of sports is full of coaches and trainers, making it easier to achieve deliberate practice.
I'm not sure how to mimic this in the world of software engineering. Perhaps finding mentors at your company (including your manager), and asking for their advice/feedback. Be genuine about what skills you want to work on. Or you can use a service like Coding Coach.
On the career side, you should absolutely speak to your manager about what's expected of you and how you can deliver more. Also check out services like Pathrise or Exponent, which helps with interviewing and career advice.
The Hero's Journey
Several years ago at an internal developer conference, Derek DeVries gave a talk about the Hero's Journey and how it applied to developers. He's a very smart engineer, you can follow him @devrieda. I'll try my best not to butcher the talk here.
The Hero's Journey is a commonly used story template. It's usually broken into three acts. The departure, when the hero is called to adventure and leaves his familiar settings. The initiation, when the hero faces a series of challenging tasks until he defeats the enemy. Each obstacle is slightly out of his comfort zone, he must learn and grow to overcome them — with the help of his mentor. The return, when the hero returns to his familiar settings. He has achieved a new level of wisdom, gained from his experiences.
This same template can be applied to your tasks, projects, and career.
At the beginning of every sprint, I'd have a large column of stories to choose from. It's tempting to assign myself the easiest tasks — the ones I'm most familiar with and have done before. But doing so means I'll be refusing the call to adventure. I need to, occasionally, pick stories that are outside my skill set. With resources like books, Stack Overflow, documentation, or existing commits, I should be able to learn enough to complete these tasks.
The same applies to project selection, especially if you're leading the project. Pick projects that fall slightly out of your abilities. Work with your teammates, team lead, and mentors to overcome your knowledge gaps.
At a high level, this also applies to job selection. If you're looking to grow in your career, pick jobs with two qualities: it's slightly out of your comfort zone and work with teammates/mentors who can help guide you.
Thanks for reading this post! I'm a huge fan of learning how to learn. If you're interested too, check out these resources:
- Peak — a tactical view on how to practice skills
- Mastery — a more strategic view on how to master crafts
- A Mind for Numbers — learning strategies for subjects that don't come naturally to us
- Effective Engineer — how to make meaningful impact as a software engineer
- Pragmatic Thinking and Learning — the Dreyfus Model of Skill Acquisition and how to deliberately learn