Become a Great Programming Through Deliberate Practice

Developing Greater Programming Skills

In this final article on using deliberate practice to become a great programmer, I discuss how and why programmers need to be continually working to improve their programming skills through specific practice.

Expert Performance is Based on Incremental Skill Development

To become an expert programmer, you must master the many skills programming requires. The first, and most important step, is to master the fundamental constructs of programming, including decision making constructs, repetition constructs, modularization constructs, data structures, and algorithms. These skills are all taught in the course of a four-year degree in computer science, though its possible for a self-taught programmer to learn them on their own. If that’s the case, the self-taught programmer will still need the advice of a wise, more experienced programmer to ensure that the learner is developing their skills in a proper, useful way.

As Anders Ericsson and Robert Pool state in their book, Peak: Secrets from the New Science of Expertise, the fundamental skills of a field must be taught properly, and learned properly, before moving on to more advanced skills because learning advanced skills necessarily depend on being able to perform the fundamental skills properly and if this is not the case, the programmer will have to go back are relearn the fundamentals before moving on.

Advanced Programming Skills Depend on Fundamental Programming Skills

Like many fields, advanced programming skills depend on the programming adequately learning more fundamental programming skills. For example, you can’t master even a basic sorting algorithm such as the shell sort or even the bubble sort if you haven’t mastered writing loops, since these algorithms rely on loops for their implementation. From there, you can’t go on to master a more advanced sorting algorithm, such as QuickSort, if you haven’t mastered the more fundamental skill of recursion, which is used in many implementations of QuickSort.

It’s really very simple – you can’t become an expert programmer until you master the fundamental skills of programming.

How to Master Fundamental Programming Skills

A recent paper by researchers at the University of Washington (UW) outlined a theory of sequenced instruction for learning computer programming. I have written previously on the best way to teach computer programming on my blog – How Introductory Computer Programming Should be Taught, where this a link to the original paper. We can apply these same techniques to learning computer programming fundamentals. The four steps outlined here should be performed for each new program construct being learned – from simple statement execution, through decision making, through looping, and through developing functions and subroutines. Skipping any of the four steps can lead to misconceptions concerning the construct being learned.

The first step is to learn how to read programming code. The best way to do this is by performing variable traces of existing programs. Tracing the values of variables teaches you how to follow the flow of a program by keeping up with the values of variables during program execution. Research has shown that students who can understand how a program works by tracing its variables will have an easier time learning to write code.

The next step after reading code is writing code. You learn this by taking a set of problem solving steps, either written in pseudocode or plain English, and translating them into a program. The student should be able to perform this step without considerable trouble if they have been adequately taught how to read code first.

The third step is to learn patterns of usage of the construct. This is often taught by presenting templates of usage to the student. An example of a template is variable swap. The template could look like this:

There are two variables whose values are to be swapped. Introduce a third variable, often called the temporary value and assign it the value of the first variable. Then assign the value of the second variable to the first variable. Finally, assign the value of the temporary variable to the second variable.

This looks like pseudocode and if the second step has been learned well, it is a straightforward exercise to translate the template into code. This step should be performed several times so that it is engrained as a pattern.

The last step is to then learn to apply the template to unique situations. An example given in the paper by the UW researchers is a scenario where a person has two flashlights, each one having a different specific use. The first flashlight is needed but its battery is weak compared to the second flashlight. The student is asked to write code to swap the batteries of the two flashlights. If the student understands the variable swap template, they can apply the template directly to write the code to swap the batteries in the two flashlights.

The UW researchers found that students in their classes who learned various Python programming constructs using this sequenced instruction performed better on tests than did students who were taught with a more traditional sequence of instruction.

Learning and Practicing Advanced Programming Skills

The key to becoming an expert through deliberate practice is to continually be working on harder problems just beyond your current capabilities. Once a programmer has mastered programming fundamentals, possibly including object-oriented programming if your language uses it as a primary paradigm, the next step is mastering data structures and algorithms.

The first step is to master the fundamental data structures of your language, whether it’s the array or the list. These data structures form the basis for many of the advanced data structures used in programming. You can find exercises you can use to practice your mastery of these data structures in any computer programming textbook or online at one of the many computer programming tutorial sites.

As you’re mastering these fundamental data structures, you should also be working to gain mastery over two fundamental algorithms that use arrays and lists – searching and sorting. Learning how to search through an array or list will help you later when you learn more advanced searching algorithms, such as heuristic search. The two fundamental searching algorithms you should learn first are linear search and binary search.

After searching, the next most common task to perform on a set of sequential data (the type of data typically stored in a list or array) is sorting. There are several elementary sorting algorithms that should be learned (insertion, bubble, shell) before moving on to the more advanced sorting algorithms (QuickSort and MergeSort).

These algorithms can also be found in any computer programming textbook and there are also several excellent online sources you can use to learn how to use these algorithms.

Once these fundamental data structures and algorithms are mastered, students should move on and master more complex data structures and algorithms. It would take too long to mention all the data structures specifically, but the general groups are trees, graphs, hash tables, and heaps. Each of these data structures has their own set of algorithms that are used to search the data stored in them.

Where to Find Problems to Solve

The best place to learn about advanced data structures and algorithms is initially in one of the many computer science textbooks written on these topics. The problem with these books is that, for the working programmer, the material is too theoretical. What the working programmer really needs to know is how is a data structure or algorithm used in practical applications and where do I find it in a particular language’s library, or if its not found in a library, how do I implement it for a practical application?

I have found that the best place to work on these skills is by working through a book on programming problems for job interviews. While the use of this type of problem solving in job interviews is controversial, the material the books cover is quite practical and can really help programmers gain more mastery over their craft.

Three of these books that I’ve found useful are: Programming Interviews Exposed by John Mongan and Noah Kindler; Cracking the Coding Interview by Gayle McDowell; and Daily Coding Problem by Lawrence Wu and Andrew Miller.

Here are two examples of problems from Daily Coding Problem, starting with a data structure problem followed by an algorithm problem:

Given a sorted array, convert it into a height-balanced binary search tree.

Given an array of strictly the characters, R, G, and B, segregate the values of the array so that all the Rs come first, the Gs come second, and the Bs come last. You can only swap elements of the array.

The beauty of books like Daily Coding Problem is that they not only provide you with challenging problems to solve and the solutions, but they also provide good explanations of the solutions so the reader can better use this information on a job interview. An important facet of deliberate practice is that the developing expert must have access to good, immediate feedback.

All programmers, even those not looking for new jobs, should be working out of one of these books on a regular basis.

Expertise is a Journey, Not a Destination

Becoming an expert computer programmer is an ongoing process. Regardless of where you are in your mastery of computer programming, there is always a next level you can, and should be, striving to obtain. If you think you can get to a point where your programming education is finished, you are wrong. The best thing you can do is recognize that to become a truly expert computer programming, you must embrace the fact that the journey never ends and learning to love the process of becoming an expert computer programmer is more important than achieving complete mastery, because complete mastery is impossible to obtain.