In Making Sense of the Deliberate Practice Debate, I argued that deliberate practice is the best way to get better at a skill, even if you believe that innate ability (talent) plays a significant role in how people become experts. In the next few posts, I’m going to start investigating how software developers can apply deliberate practice to a specific skill: Writing correct, efficient, and maintainable code for a software component given well-defined requirements. But first, let’s take a closer look at that skill.
Objection, Your Honor!
If you’re a software developer, you’re probably thinking one of two things in response to that skill description:
- Well-defined requirements? I never get those!
- My job is more than just coding individual components. That’s the easy part. What about all of the other skills that a developer needs?
I know where those objections are coming from. However, it’s important to realize that practice is different from work or play. In particular, one of the principles of deliberate practice is that it’s more effective to practice a skill in isolation than as part of a larger job. A canonical example is the piano lesson. Casual piano students practice their skills by playing a complete piece over and over. Serious students engage in deliberate practice by playing until they reach a difficult spot, and then repeating that section of the piece until they master it. Similarly, the only practice that many software developers get is when they work on software projects, generally as part of their job. But this is not the most effective way to get better at a skill. When a developer is doing their job, or even working on a side project, their primary goal is to produce a result: a working system that a customer can use. After all, this is the reason people become software developers. And there are certainly significant learning benefits to building a software system from end to end. However, there are also essential programming skills that are best learned by breaking them down into pieces and practicing the pieces individually.
Consider a developer who is building a web application from scratch. At some point, they’ll need to build the components for retrieving data from the database. They’ll need to make a number of architectural decisions, such as how to handle caching and what type of database is most appropriate for the application. Once the data retrieval subsystem is complete, the developer will have gained some experience about that aspect of web application development, and will move on to build other parts of the system. But what if the goal of this work was not to complete the system, but rather to become more skilled in the area of data access for web applications? In this case, the developer might decide to re-write the data access layer using a different technology and compare it with their first attempt, or might implement the subsystem from scratch instead of using an off-the-shelf component. Each of these options would give them more insight into the details of data access. This is the difference between work, where the goal is to finish the project, and practice, where the goal is to become an expert. And this is why it’s worth defining a specific skill to practice, even if the skill seems overly simplistic in the context of regular work.
A Lower Bar for Coding Ability
One other objection from the list above is that coding is the easy part of being a developer. There’s a popular opinion in software development circles that coding is not very important compared to other software development tasks. Consider these observations from two well-known figures in the programming community:
The importance of the code we do write is absolutely dwarfed by everything else that goes on around it. … If nobody knows about your code, if nobody can understand your code, if for whatever reason your code doesn’t even ship.. then have you really accomplished anything by writing that code? — Jeff Atwood, Does Writing Code Matter?
When software-project surveys report causes of project failure, they rarely identify technical reasons as the primary causes. — Steve McConnell, Code Complete
Even Dale Carnegie weighed in on the subject:
Even in such technical lines as engineering, about 15 percent of one’s financial success is due to one’s technical knowledge and about 85 percent is due to skill in human engineering—to personality and the ability to lead people. — Dale Carnegie, How to Win Friends and Influence People
So why work on programming skills rather than skills related to marketing, communication, and leadership? One reason is that there is a lower bar of coding skill that a developer needs to clear before they can get anything useful done. Atwood and McConnell have also written about this topic. In Why Can’t Programmers.. Program?, Atwood writes about basic interview questions used to screen out applicants who “apply for a job without being able to write the simplest of programs.” A well-known example is the FizzBuzz test:
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
You can try your luck on the FizzBuzz test at CodeEval, where it has the honor of being Problem #1 in their list of programming challenges.
Sometimes people who can’t program get through the door anyway, despite the best efforts of interviewers. McConnell estimates that the “average company has something like 20% of its programmers that aren’t contributing anything meaningful to the business and whose compensation should really be zero.” (10x Productivity Myths: Where’s the 10x Difference in Compensation?). Clearly someone who hasn’t yet mastered the FizzBuzz test will benefit by improving their coding skills, assuming they’re serious about getting into the software development profession.
The Coding Skill Graph
FizzBuzz is a very low bar. Atwood calls the test “blindingly, intentionally easy.” It’s useful for determining if a candidate can program at all. What about developers who are far beyond that level of ability? How should they decide whether it’s worthwhile to focus on coding skills? In other words, how long after mastering FizzBuzz does coding practice continue to have a significant impact on a developer’s job performance? Maybe the relationship between programming ability and job performance follows an exponential decay rule, like the number of atoms in a lump of plutonium. If so, it might look something like this:
On the horizontal axis, we have the number of hours that our hypothetical developer has spent practicing programming. On the vertical axis is the contribution of this hard-earned programming skill to job performance, as measured by something like a review score or annual bonus. A contribution of 100% would mean we have locked this person in a room, and we communicate with them only in the form of git commit messages. None of their other skills have any impact on their job performance. A contribution of 0% would mean that they have finally been promoted to management and they no longer check in any code. Let’s assume that hour zero on the horizontal axis represents the point at which a hotshot young college graduate enters the workforce with a shiny new Computer Science degree. In the real world, even a new college hire has skills other than coding ability that can be useful in the workplace. Maybe they have a scintillating personality, or their great foosball skills make everyone want to work with them. Nevertheless, let’s assume that most of their value comes from that high-priced CS degree, so 90% of their overall effectiveness is due to their coding ability. As they put in hours at work, they get better at programming. But they also learn other critical work skills, like translating what customers say into what they actually want, playing well with difficult people, and sharing work with their teammates rather than trying to do it all in pizza-fueled all-nighters. By the time they hit the senior engineer ranks, their technical knowledge contributes much less to their financial success than it did when they first started working. Let’s assume it contributes 15%, which is Dale Carnegie’s estimate.
Crazy Productive Game Developers
For many developers, the prospect of having their hard-earned technical skills contribute less and less to job performance over time may be a bit depressing. The good news is that developers have some control over the value of their coding skills. One way to control this value is by picking the right company to work for. At a company where the main mission is to manufacture tires, but which also employs a few programmers, it’s likely that sophisticated coding skills won’t have a very high value. In other words, the coding skill vs. job performance graph will taper off quickly to a relatively low contribution percentage. At the other end of the spectrum, for Yahn Bernier working at Valve Software, the graph levels off at a much higher value. In the linked video, Gabe Newell, managing director of Valve, estimates that Bernier was at least one thousand four hundred and sixty times more productive (in the 1990s) than the median IBM programmer was in the 1980s. We can quibble about the productivity metrics Newell uses, but the point he is making is that Valve hires the best (and most expensive) programmers it can find, and gives them high-value work to do. If the guy who signs the paychecks believes that he has technical problems that require top programmers, and he is willing to pay for them, why argue?
What Kind of Programming Job Do You Want?
If you’re on a software development career path, it’s worth thinking about where you want to level out on the coding skill vs. job performance graph. Despite the importance of soft skills to job performance, there are good reasons to prioritize coding practice. One reason is simply being able to get the right job in the first place. Many software companies use short programming problems during interviews as a way to measure a candidate’s programming ability. Regardless of your feelings about the merits of those interview questions, you’ll have a wider range of job options if you get good at solving them. Beyond the interview, a habit of deliberate programming practice gives you more control over what type of work you get to do. It’s easy to reach a point where you’re good enough at your current job, but you don’t have a reliable process for getting better, or getting good at something new. Using the skill that I defined at the top of this post, my goal is to focus on software development fundamentals, and also to refine a process to learn other technical skills.
(Image credit: Jeff Golden)