Knowledge work like software engineering generally boils down to being able to creatively execute on a schedule. The question is: how does one develop these skills? I believe it requires three core things: doing lots of work, exercising creativity, and focusing. The goal is to go from beginner to practitioner.
What is a Practitioner?
Suppose one takes the typical path and graduates college. What are they? I like to think the model that medicine uses is appropriate. You graduate from college, you have a residency, followed by a fellowship. Being a practioner is the time when you are able to build and ship things to the world with little to no management above yourself.
Mastering the Beginner Phase
Volume, Volume, Volume
Beginners know nothing, so should they focus their efforts into trying to build one thing well? I think this is a mistake because their palette is limited. My philosophy is to try lots of things. Have an idea, and then quickly try to realize it as fast as possible. Make lots of stuff. Make lots of junk. Make, Do, Make, Do. Be fearless, and make a mess. Do. More. Make. Harder. Create.
Creativity is about trying things, then evaluating them. If you have an idea, then don't judge it. Simply accept the idea, and work on it. Once you realize the idea and bring it into reality, then judge it. Many times, it is easy (and lazy) to have an idea and dismiss it. Instead, embrace it, run with it. The beginners goal is to learn things.
Once you judge something, then you may realize it isn't good. That is great! The question is: what matters? This involves seeing what you can measure and then try to maximize that. Suppose you make a game, and it is slow. Focus only on speed. Don't worry about code quality or other non important metrics. Focus on hacking it until it is a blazing fast example of speed.
Suppose you make something that works well, but is hard to extend? Focus on generalizing, and don't worry about other things.
Maybe the game you made sucks, try to make it fun regardless of the plugin architecture.
Focusing is about putting all but one way to judge out of view.
Transitioning towards Practitioner
Once you have demonstrated that you can take a single idea and maximize a single variable (like performance or code quality), you can start the path towards practitioner.
Judgement and Priorities
I've picked on two things that you can (or kind of) measure: extensibility and performance. During the beginner phase, it is acceptable to have one thing right. As you transition away from pure beginner, you must focus on balancing and achieving multiple levels of high quality. Further still, the number of ways to measure things will increase. For instance, expand the above two things to:
- memory footprint
- code quality
- code extensibility (i.e. plugins)
- verbosity versus brevity
- infrastructure cost
- energy consumption (i.e. batteries)
- available labor market to maintain
- multiple device targeting (i.e. windows versus mac)
Wow! that is a great deal of variables (and I am leaving more out) to maximize, and it is hard. Transitioning towards practitioner means picking your battles and optimizing for what is truly important and focus on maximzing multiple variables at the same time.
Experimentation: Deliberate Practice
Once you recognized the sheer number of variables, you realize that you know very little. However, getting away from the beginner phase means you always understand the beginner phase and can repeat as needed.
Simply repeat the volume -> reserve judgement -> focus process (typically in a side project) until your grasp is enough to contribute meaningfully.
Arriving at Practitioner
Unfortunately, there is no graduation ceremony. Instead, I think for software, the graduation ceremony is the moment you have the confidence to
- start a project
- build a team
- ship to the world
and then achieve it.