As I was paging through Steve Yegge's voluminous body of work recently, I was struck by a 2005 entry on practicing programming:
Contrary to what you might believe, merely doing your job every day doesn't qualify as real practice. Going to meetings isn't practicing your people skills, and replying to mail isn't practicing your typing. You have to set aside some time once in a while and do focused practice in order to get better at something.
I know a lot of great engineers -- that's one of the best perks of working at Amazon -- and if you watch them closely, you'll see that they practice constantly. As good as they are, they still practice. They have all sorts of ways of doing it, and this essay will cover a few of them.
The great engineers I know are as good as they are because they practice all the time. People in great physical shape only get that way by working out regularly, and they need to keep it up, or they get out of shape. The same goes for programming and engineering.
It's an important distinction. I may drive to work every day, but I'm far from a professional driver. Similarly, programming every day may not be enough to make you a professional programmer. So what can turn someone into a professional driver or programmer? What do you do to practice?
The answer lies in the Scientific American article The Expert Mind:
Ericsson argues that what matters is not experience per se but "effortful study," which entails continually tackling challenges that lie just beyond one's competence. That is why it is possible for enthusiasts to spend tens of thousands of hours playing chess or golf or a musical instrument without ever advancing beyond the amateur level and why a properly trained student can overtake them in a relatively short time. It is interesting to note that time spent playing chess, even in tournaments, appears to contribute less than such study to a player's progress; the main training value of such games is to point up weaknesses for future study.
Effortful study means constantly tackling problems at the very edge of your ability. Stuff you may have a high probability of failing at. Unless you're failing some of the time, you're probably not growing professionally. You have to seek out those challenges and push yourself beyond your comfort limit.
Those challenges can sometimes be found on the job, but they don't have to be. Separating the practicing from the profession is often referred to as code kata.
The concept of kata, a series of choreographed practice movements, is borrowed from the martial arts.
If you're looking for some examples of code kata -- ways to practice effortful study and hone your programming skills -- Steve's article has some excellent starting points. He calls them practice drills:
- Write your resume. List all your relevant skills, then note the ones that will still be needed in 100 years. Give yourself a 1-10 rating in each skill.
- Make a list of programmers who you admire. Try to include some you work with, since you'll be borrowing them for some drills. Make one or two notes about things they seem to do well -- things you wish you were better at.
- Go to Wikipedia's entry for computer science, scroll down to the "Prominent pioneers in computer science" section, pick a person from the list, and read about them. Follow any links from there that you think look interesting.
- Read through someone else's code for 20 minutes. For this drill, alternate between reading great code and reading bad code; they're both instructive. If you're not sure of the difference, ask a programmer you respect to show you examples of each. Show the code you read to someone else, and see what they think of it.
- Make a list of your 10 favorite programming tools: the ones you feel you use the most, the ones you almost couldn't live without. Spend an hour reading the docs for one of the tools in your list, chosen at random. In that hour, try learn some new feature of the tool that you weren't aware of, or figure out some new way to use the tool.
- Pick something you're good at that has nothing to do with programming. Think about how the professionals or great masters of that discipline do their practice. What can you learn from them that you can apply to programming?
- Get a pile of resumes and a group of reviewers together in a room for an hour. Make sure each resume is looked at by at least 3 reviewers, who write their initials and a score (1-3). Discuss any resumes that had a wide discrepancy in scoring.
- Listen in on a technical phone screen. Write up your feedback afterwards, cast your vote, and then talk about the screen with the screener to see if you both reached the same conclusions.
- Conduct a technical interview with a candidate who's an expert in some field you don't know much about. Ask them to explain it to you from the ground up, assuming no prior knowledge of that field. Try hard to follow what they're saying, and ask questions as necessary.
- Get yourself invited to someone else's technical interview. Listen and learn. Try to solve the interview questions in your head while the candidate works on them.
- Find a buddy for trading practice questions. Ask each other programming questions, alternating weeks. Spend 10 or 15 minutes working on the problem, and 10 or 15 minutes discussing it (finished or not.)
- When you hear any interview coding question that you haven't solved yourself, go back to your desk and mail the question to yourself as a reminder. Solve it sometime that week, using your favorite programming language.
What I like about Steve's list is that it's somewhat holistic. When some developers think "practice" they can't get beyond code puzzles. But to me, programming is more about people than code, so there's a limit to how much you can grow from solving every obscure programming coding interview problem on the planet.
I also like Peter Norvig's general recommendations for effortful study outlined in Teach Yourself Programming in Ten Years.
- Talk to other programmers. Read other programs. This is more important than any book or training course.
- Program! The best kind of learning is learning by doing.
- Take programming classes at the college or graduate level.
- Seek out and work on projects with teams of programmers. Find out what it means to be the best programmer on a project -- and the worst.
- Work on projects after other programmers. Learn how to maintain code you didn't write. Learn how to write code so other people can effectively maintain it.
- Learn different programming languages. Pick languages that have alternate worldviews and programming models unlike what you're used to.
- Understand how the hardware affects what you do. Know how long it takes your computer to execute an instruction, fetch a word from memory (with and without a cache miss), transfer data over ethernet (or the internet), read consecutive words from disk, and seek to a new location on disk.
You can also glean some further inspiration from Pragmatic Dave's 21 Code Katas, or maybe you'd like to join a Coding Dojo in your area.
I don't have a long list of effortful study advice like Steve and Peter and Dave do. I'm far too impatient for that. In fact, there are only two movements in my book of code kata:
- Write a blog. I started this blog in early 2004 as a form of effortful study. From those humble beginnings it has turned into the most significant thing I've ever done in my professional life. So you should write blogs, too. The people who can write and communicate effectively are, all too often, the only people who get heard. They get to set the terms of the debate.
- Actively participate in a notable open source project or three. All the fancy blah blah blah talk is great, but are you a talker or a doer? This is critically important, because you will be judged by your actions, not your words. Try to leave a trail of public, concrete, useful things in your wake that you can point to and say: I helped build that.
When you can write brilliant code and brilliant prose explaining that code to the world -- well, I figure that's the ultimate code kata.