It’s summertime here in the Pacific Northwest, and seven months into the first year of this blog. After thirty weekly posts, I thought it would be a good time to consider the themes that have come up so far this year. If you’re a new reader, I hope you’ll find this to be a useful primer.
1. To become an expert, use deliberate practice.
There’s good news and bad news about becoming an expert. The good news is that psychologists who study the process of gaining expertise have found an effective way to develop it. The bad news is that they haven’t found any shortcuts.
I wrote post #1 of this blog on the deliberate practice debate, an update on the latest research into how nature and nurture affect differences between individuals. In post #3, I proposed a deliberate practice process for software developers.
If I reduced this blog to a single question, it would be:
What is the process that, if followed diligently, will turn you into an expert programmer?
The answer may be different for you than it is for me. In fact, the details are almost guaranteed to be different (especially if you’re from another planet). My goal is to provide some ideas about the process, as well as some suggestions for creating your own customized version of the process.
2. The reward for becoming an expert is the chance to work on important problems.
At Bell Labs around the middle of the last century, mathematician Richard Hamming had the habit of asking his lunchtime colleagues a series of marvelously rude questions beginning with: “What Are the Important Problems of Your Field?” Ever since I encountered those questions in a Paul Graham essay, I have been fascinated by the implications of using them to choose what to work on.
The only way to either get paid to work on important problems, or at least have a chance of making progress, is to become an expert in some area. So you could see the chance to work on important problems as the reward you receive in exchange for the hard work of becoming an expert. That opportunity is followed by more hard work as you work on the problems themselves. But that work is combined with the satisfaction of knowing that you’re working on something meaningful, as well as the motivational benefits of interesting work.
3. Build your own productivity system.
I believe in productivity habits, especially when it comes to completing a large project with no external pressure to finish. I also think that people who write about productivity systems can provide worthwhile ideas to experiment with. But ultimately you have to build your own system. People have different personalities and circumstances. Advice is just a starting point that you can use to create and adjust the process that works best for you.
4. You have more to learn about coding.
It is fashionable to disparage “coding” in favor of “software development” or “software engineering.” You may hear that software developers are valuable mainly based on how well they can communicate with people, or that software engineers are responsible for providing solutions to problem, not just a bunch of code. Those are both completely reasonable assertions. Nevertheless, if your job requires you to spend some part of your day typing code into a text editor, there is some minimum level of programming proficiency that you need in order to do that job effectively.
So maybe the real point of contention is what that minimum level is. I think it’s fairly high. Therefore, I am using this blog to unapologetically focus on coding: learning to code (while working around the drawbacks of the online learning platforms), mastering a programming language, coding faster, coding better, and generally solving problems through code.
5. Programming puzzles can teach you things that you don’t learn in school or on the job.
A Computer Science degree can give you a strong foundation in the field and some basic programming skills, not to mention a liberal arts education. A programming job can teach you how to work with others on a software development team, what programming “in the large” means in practice, and how to run a software system used by real people.
There are also unique skills that you can learn by solving programming puzzles, skills that are difficult to get through academic or project work. The reason for this is that academic and project work have specific goals:
- The purpose of a CS degree is to establish a theoretical foundation, provide an introduction to a few application areas (operating systems, graphics, etc.), and teach enough about the mechanics of programming to prepare students for an entry-level job. Students have about four years to accomplish this, and once that time is up, they are sent out to work on projects, ready or not.
- The purpose of project work is to complete a software system that people will use and/or pay for. Programmers only get paid if someone is making money as a result of their work. This provides focus to their work and limits the time they can spend on activities that are strictly designed to improve performance.
Compared to academic and project work, there are some advantages to the puzzle approach to coding mastery:
- It’s a way to get involved in competitive programming, which has benefits of its own.
- It helps develop fluency in a programming language. Like becoming fluent in a natural language, this allows you to focus more on semantics (what you want your program to do) and less on syntax (how you should express yourself to the compiler). Puzzles don’t have to be difficult for you to realize this benefit.
- You can create and improve a repeatable process for solving and learning from programming problems. As I mentioned in item #1 at the top of this post, finding such a process is the big question that this blog is concerned with, and is one of the key steps in benefiting from the deliberate practice approach to learning.
- You can improve your performance in the dreaded coding interview, for which a CS degree, curiously enough, doesn’t seem to be very good preparation.
- You can continue to learn about algorithms and math after your formal education is over. On that note:
6. Math and algorithms are cool.
Although math and algorithms are core parts of the Computer Science curriculum, not all programmers are interested in those topics for their own sake. There’s nothing wrong with that. Algorithms in the most general sense are required to write any kind of program. But what people mean when they say they’re not interested in algorithms is that they aren’t interested in learning standard algorithms such as those covered in a college textbook. For most programming jobs, this is not a problem. Many standard algorithms are implemented in libraries, and the others aren’t often used in day-to-day programming work.
I happen to be interested in math and algorithms, so some of my posts will cover those topics. They also happen to be useful for programming puzzles.
7. To make progress on a long-term goal, create a project.
A project is a standard way to organize work. Often you are assigned a project if you’re in school or working for someone else. But you can also assign yourself a project. This blog is based around a project that consists of solving a particular set of programming puzzles. The puzzles are a learning tool, like the problem sets in a college class, and they also leads to topics that can be covered in blog posts.
When you have time to do some work, a well-designed project answers the question: “What should I do next to get closer to my goal?” Combined with a good set of habits (see item #3), it can help keep you on track over a period of time.
8. Reinvent the wheel.
Programmers love to warn against reinventing the wheel. Generally they have a good point. If you find a software component that meets your technical and licensing requirements and is actively supported, it makes sense to use it.
But when it comes to working on learning-type projects, you do want to reinvent some of the wheels that you encounter. Students are constantly reinventing wheels to learn how they work. As a rule of thumb, it makes sense to reinvent any wheel that you want to learn from the ground up. For example, to learn how sorting works, you can implement Quicksort. Once you do that once, there’s no need to continue reinventing it. You can just use
Collections.sort or the equivalent.
Programming competitions are like huge wheel reinventing parties. From a project management perspective, it’s crazy to have thousands of developers independently implement the solution to the same problem, which itself is likely based on a problem that has already been solved. But from the perspective of the participants, it makes sense. Each person gets the benefits of thinking through and implementing a solution. And after the contest, they can learn even more by perusing editorials and code solutions from the other participants.
9. Publish your results.
Teaching others what you have learned is a way to solidify your understanding of a topic. It’s also part of competitive programming culture. Sites that emphasize real-time contests, like TopCoder and CodeForces, often publish contestants’ code submissions automatically. For sites like UVa Online Judge that focus more on archiving past contests, it’s still common to find editorials and solution code on blogs and GitHub.
Here on Red-Green-Code, it isn’t my goal to write up every Project 462 problem that I solve. But I do write posts about problems that have particularly worthwhile lessons that I think will be generally applicable. Here are the posts so far that fall into that category:
- The Bathtub Puzzle
- Solving UVa 11340 in Java
- Why is Java I/O Slow?
- Implementing a Fast Solution to UVa 732
- Profiling Java Programs with VisualVM
I’ll also be writing a series of posts whenever I finish a uHunt chapter. Here they are for Chapter One:
- Lessons from uHunt Chapter One
- Lessons from Competitive Programming 3 Chapter One
- Java Lessons from uHunt Chapter 1
The Road Ahead
That concludes this tour through the first seven months of Red-Green-Code. Stick around to see how it all turns out!
(Image credit: A summer view out the window at Red-Green-Code World Headquarters)