Knowledge is like a house of cards
Those first debugging sessions
Early in my career, I would often find myself scratching my head for hours when looking at a program, trying to understand why it didn't work the way I expected. I would add print statements everywhere, peeking at the state of every variable and every path the code might take. At some point, I started realizing that I was testing out very basic features of the language, like if the if
branch didn't go through, does it mean the else
would? Or is double negation just the original value?
Eventually, I realized that I was confused about Javascript's notion of truth. I read the docs on type coercion and truthy values and made sure that I understood the concepts. After some time, I started noticing that these debugging sessions got faster. I no longer found myself spending time testing out boolean operations and coercion to booleans. It felt like I was on to something...
Knowledge is like a house of cards
I started noticing that knowledge is like a house of cards. You build an imperfect model of how the world works. When your model contradicts reality, it's like taking a card from the house of cards. Not only will all the cards above fall, often several levels of cards below will also fall. The number of collapsing levels will be proportional to how weak your foundations are.
The difference between solid and weak foundations: removing the pointed card might bring the entire tower on the left to its grounds while the right tower will at least have one solid level.
Here is another interesting observation: a single "bad day" is enough to collapse an entire house of cards built with poor fundamentals. I've seen this happen once in my career. A so-called "senior" developer started screaming at the compiler, then at the IDE, then at the operating system, then at his colleagues. He was frustrated. He had built a very tall house of cards with weak foundations.
An algorithm for improving your debugging skills
The central point of this post is: The key to becoming better at debugging is to build solid foundations so that when you remove a card, the minimum number of levels will break.
There are two steps to this algorithm:
Step 1: Identify weak foundations
On your next debugging session, notice when your model breaks. Notice which concepts you don't understand well and write them down. Make sure to also note which layer in the stack broke (e.g. language, framework, library, module, function).
If there are multiple concepts that you don't understand, prioritize by lower-level first. These are your weak foundations.
Step 2: Strengthen the foundation
Go and read the documentation, preferably the official one. Make sure you really understand what's going on. Test your knowledge. Talk with a more experienced dev: hey, I want to test my understanding of X. Is this really how X works in this situation?
Conclusion
To build tall knowledge skyscrapers you need solid foundations. If your foundations are weak, your entire knowledge edifice is at risk of collapse when your understanding of a program doesn't match its behavior. Conversely, if your foundations are strong, you will be able to find bugs faster.
Many thanks to @timonbimon and @PetyakMi for reviewing and giving feedback.
If you found this article useful, consider following me on twitter. I write about once a month about software engineering practices and programming in general.
I'm also developing SynthQL. A type-safe HTTP client for PostgreSQL and I would love to get your feedback.
Other posts you may like...
Knowledge is like a house of cards
On the importance of building solid foundations. Read more.
Why read Dostoevsky? A programmer's perspective
On the limits of scientific knowledge and the importance of reading the classics. Read more.
Always use [closed, open) intervals
A short note on the dangers of using [closed, closed] intervals. Read more.