It's an interesting question I've been pondering for several years now. For me, it's solving known problems (e.g., a web app, a data investigation app, etc.) and evolving the code based on best practices and what the language/framework/etc. allow.
It's a more complicated question than, say, learning a musical instrument, because there aren't hard-and-fast benchmarks beyond solving well-known itches. But I think solving those well-known itches goes a long way to formalizing what it means to deliberately practice development.
(I'd add that I've been doing development for a Pretty Long Time now, and the whole practice of knowing how to make code less smelly is fairly intuitive. I've been struggling with how to codify this to bring newer developers up to speed.)
I am employing a method this year that works around the question of "for programmers" and focuses on a cycle of clean, then practice, then apply, where as I go up each level, I aim to be in a more intensive state than the previous, and most crucially, I do this each time I sit down to do project work.
There is nothing stopping me from turning the practice phase into "work on problems from TAOCP" or something, but I've left it open to let me practice other things like 3D programs or music or other new software. Likewise the cleaning phase could mean "do dishes" or it could mean "uninstall software". The point is the mindset I'm bringing to the task and not the task.
EDIT: Originally written as a response to u/probinso, but got way too long. I'm a novice here, so any thoughts/anecdotes/(dis)agreements/anything are greatly appreciated.
+1 - I would like an invite too! Back to the article, this is probably the topic I've thought most about recently.
In the past year I have taken serious interest in jazz musicianship, specifically improvisation. I'd like to get significantly better at both programming and jazz improvisation as fast as possible, so relentlessly optimizing my practice, or "practicing practice", has been my #1 goal. I have a decent approach for music, but I'm still looking for one for programming.
Here are a few of my amateur approaches to "deliberate practice" regarding music:
- The first and most obvious thing I learned was that you can't improvise what you can't physically play. So clearly, deliberate practice is required to gain the ability to play anything. I've seen and heard this referred to as a musician's "chops". To develop this, I practice scales, arpeggios, chords, licks, songs I've transcribed, and other targeted exercises.
- To improvise an appropriate melody I have to 1) hear and understand the music outside the melody, 2) create a good melody over it in my head, then 3) translate and play the melody in my head. There is a lot of overlap in the practice for these three, which mostly sums to ear training, sight reading, sight singing, listening to a bunch music, transcribing and analyzing it, and repeated, concentrated attention to how the harmony + rhythm of songs work and how the melody fits over/in that.
- Learning lots of music theory + applied practice of it, with the ultimate goal of using knowledge intuitively rather than actively. The key assumption here is that my music knowledge has to be intuitive, because I won't have time to think about all this stuff when improvising. So I'm hoping that consuming thousands of resources (songs, books, talks, paid lessons), actively using learned information, and gaining lots of experience will make improvisation natural, subconsciously feasible, or at the very least much easier.
- Playing and improvising with others a lot.
I generally think of all of this as 1) developing fundamentals and technical skills 2) discovering and adding new things 3) applying knowledge 4) reviewing assumptions, making changes 5) iterating. Then, maybe enough iteration => experience, and enough creativity + experience will lead to the craftsmanship I need?
This basic approach to music is good enough for me right now, but I'd like to start the same process with making software. So finally, the question in the article - "What is deliberate practice for programmers?". I don’t have the answer but I’d sure like to know.
I could review all the knowledge I gained from CS in university. Implement a bunch of stuff, like DS, algorithms, apps, low level mechanisms? Read a bunch of highly rated technical books? Talk to people smarter and more experienced than me? Go work at a company that says it's invested in it's employees growth?
This is all great, but it doesn't seem like deliberate practice in the way that my practice for improvisation does. I would like to become a great programmer, but the problem is that I just want to be great at all things programming. I guess I have more specific end goal in terms of music. Maybe it's that I don't really know what I want in terms of programming? Perhaps I need to specialize, though it's a little early for me to know where. It's very frustrating knowing that I want to get better, am willing to "put in the work", but don't know what “work" I should be doing.
Programming chops aren't much different than music chops. Guitar? You understand your instrument. Using it is intuitive, right? You have programming tools (editor/IDE, language, libraries). You started off by learning scales--learn your dev tools until you don't have to think about what you're doing--it just happens. Find rough edges? Fix them (extend your environment, make keyboard macros, whatver it is you notice as a "hitch" in your process).
Music theory: how things (e.g., notes, chord progressions, etc.) relate to each other. Same thing with code: languages, libraries/frameworks, persistence mechanisms, messaging systems have similar relationships. Each solves a particular problem, often in very different ways (e.g., graph DBs vs key/value store vs RDBMS). Understand those relationships and how to take advantage of them--and just like improv, how the "rules" can be bent to solve a particular problem (HTF do I resolve this progression I've backed myself into).
I personally don't spend a lot of time anymore dealing with algorithms, but that's largely because the programming I do these days doesn't really require much deep thought at that low of a level (for better or worse). Data structures are always key, but for me, deep knowledge of them isn't necessary--only enough to understand what's more or less the "best" for a task is sufficient.
Understand different paradigms of programming languages, persistence, messaging, etc. just like you should have at least some understanding of alternate tunings, different musical structures (the best musicians I know have exposure to at least some level of a wide variety of musical traditions; have a go at some Indonesian gamelan, some Ghanian drumming, kotos or zhengs). Understanding the differences between things is often more important than having a deep understanding of those things.
Taking an idea that I've heard bout and implementing it myself. Say I read about a data structure or algorithm, I would implement it on my own to understand it more. Perhaps different variations. Lately for me, this has been more on design patterns. I deal with large systems, and I'm always thinking about relationships between different components, so I'll write small < 1,000 line code that represents a complex system while I think of how different parts interact. I stay away from libraries and external dependencies to constrain my thoughts towards the ideas that I'm exploring. This is how I practice in a deliberate manner. The funny thing about it is that if you look at the code I produce it might look a mess, but I'm not practice art of writing clean code at that moment. I already know how to do that.
10 comments
[ 2.8 ms ] story [ 29.5 ms ] threadIt's a more complicated question than, say, learning a musical instrument, because there aren't hard-and-fast benchmarks beyond solving well-known itches. But I think solving those well-known itches goes a long way to formalizing what it means to deliberately practice development.
There is nothing stopping me from turning the practice phase into "work on problems from TAOCP" or something, but I've left it open to let me practice other things like 3D programs or music or other new software. Likewise the cleaning phase could mean "do dishes" or it could mean "uninstall software". The point is the mindset I'm bringing to the task and not the task.
+1 - I would like an invite too! Back to the article, this is probably the topic I've thought most about recently.
Relevant background: Novice Guitarist + Junior Software Engineer
In the past year I have taken serious interest in jazz musicianship, specifically improvisation. I'd like to get significantly better at both programming and jazz improvisation as fast as possible, so relentlessly optimizing my practice, or "practicing practice", has been my #1 goal. I have a decent approach for music, but I'm still looking for one for programming.
Here are a few of my amateur approaches to "deliberate practice" regarding music:
- The first and most obvious thing I learned was that you can't improvise what you can't physically play. So clearly, deliberate practice is required to gain the ability to play anything. I've seen and heard this referred to as a musician's "chops". To develop this, I practice scales, arpeggios, chords, licks, songs I've transcribed, and other targeted exercises.
- To improvise an appropriate melody I have to 1) hear and understand the music outside the melody, 2) create a good melody over it in my head, then 3) translate and play the melody in my head. There is a lot of overlap in the practice for these three, which mostly sums to ear training, sight reading, sight singing, listening to a bunch music, transcribing and analyzing it, and repeated, concentrated attention to how the harmony + rhythm of songs work and how the melody fits over/in that.
- Learning lots of music theory + applied practice of it, with the ultimate goal of using knowledge intuitively rather than actively. The key assumption here is that my music knowledge has to be intuitive, because I won't have time to think about all this stuff when improvising. So I'm hoping that consuming thousands of resources (songs, books, talks, paid lessons), actively using learned information, and gaining lots of experience will make improvisation natural, subconsciously feasible, or at the very least much easier.
- Playing and improvising with others a lot.
I generally think of all of this as 1) developing fundamentals and technical skills 2) discovering and adding new things 3) applying knowledge 4) reviewing assumptions, making changes 5) iterating. Then, maybe enough iteration => experience, and enough creativity + experience will lead to the craftsmanship I need?
This basic approach to music is good enough for me right now, but I'd like to start the same process with making software. So finally, the question in the article - "What is deliberate practice for programmers?". I don’t have the answer but I’d sure like to know.
I could review all the knowledge I gained from CS in university. Implement a bunch of stuff, like DS, algorithms, apps, low level mechanisms? Read a bunch of highly rated technical books? Talk to people smarter and more experienced than me? Go work at a company that says it's invested in it's employees growth?
This is all great, but it doesn't seem like deliberate practice in the way that my practice for improvisation does. I would like to become a great programmer, but the problem is that I just want to be great at all things programming. I guess I have more specific end goal in terms of music. Maybe it's that I don't really know what I want in terms of programming? Perhaps I need to specialize, though it's a little early for me to know where. It's very frustrating knowing that I want to get better, am willing to "put in the work", but don't know what “work" I should be doing.
Programming chops aren't much different than music chops. Guitar? You understand your instrument. Using it is intuitive, right? You have programming tools (editor/IDE, language, libraries). You started off by learning scales--learn your dev tools until you don't have to think about what you're doing--it just happens. Find rough edges? Fix them (extend your environment, make keyboard macros, whatver it is you notice as a "hitch" in your process).
Music theory: how things (e.g., notes, chord progressions, etc.) relate to each other. Same thing with code: languages, libraries/frameworks, persistence mechanisms, messaging systems have similar relationships. Each solves a particular problem, often in very different ways (e.g., graph DBs vs key/value store vs RDBMS). Understand those relationships and how to take advantage of them--and just like improv, how the "rules" can be bent to solve a particular problem (HTF do I resolve this progression I've backed myself into).
I personally don't spend a lot of time anymore dealing with algorithms, but that's largely because the programming I do these days doesn't really require much deep thought at that low of a level (for better or worse). Data structures are always key, but for me, deep knowledge of them isn't necessary--only enough to understand what's more or less the "best" for a task is sufficient.
Understand different paradigms of programming languages, persistence, messaging, etc. just like you should have at least some understanding of alternate tunings, different musical structures (the best musicians I know have exposure to at least some level of a wide variety of musical traditions; have a go at some Indonesian gamelan, some Ghanian drumming, kotos or zhengs). Understanding the differences between things is often more important than having a deep understanding of those things.
Oh there's more. I could go on for hours.