Longest bugs are one-liners. After 4 hours debugging, fix is almost guaranteed to be single line. Insidious bugs come from inaccurate assumptions - we're looking in code when problem is in our understanding. Variable named 'block' meant both physical and logical block numbers.
Chelsea Troy spent three hours with three programmers last week doing only debugging. Debugging is not the exception to a normal day - it's most of her work time. Most programmers spend the majority of their time reading error messages or combing over code to determine why something isn't working. We treat this practice that occupies the majority of our work time as an exception. We don't have unified praxis or pedagogy for debugging and we don't think we need one. Each programmer builds their own anecdotal library out of bugs they've individually seen. What a waste.
Troy noticed a pattern: the longer she spends chasing a bug, the more likely the fix is a one-liner. By the time she's sunk about four hours, it's almost guaranteed to be a one-liner. She used to think this was psychological bias, like it only rains when you didn't pack an umbrella. But the reason is clear now. Insidious bugs come from inaccurate assumptions. More than that, insidiousness as a characteristic of bugs comes from inaccurate assumptions. You're looking in the code when the problem is rooted in your understanding. It takes an awfully long time to find something when you're looking in the wrong place.
John Ousterhout from Philosophy of Software Design describes the most challenging bug he ever fixed. The file system code used the variable name block for two different purposes. In some situations block referred to physical block number on disk, in other situations block referred to logical block number within a file. At one point there was a block variable containing a logical block number, but it was accidentally used in a context where a physical block number was needed. As a result, an unrelated block on disk got overwritten with zeroes. Several people read over the faulty code and never noticed the problem. When they saw the variable block used as a physical block number, they reflexively assumed it really held a physical block number.
When you name things, you're not just encoding your understanding - you're creating your understanding. How you name things shapes how you understand them and also how you name things is influenced by how you understand them. It's hard to detect when your assumptions about a system are wrong because it's hard to detect when you're making assumptions at all. Assumptions describe things you're taking for granted, all the details you're not putting thought into. High risk assumptions make great hiding places for bugs: What are the units for this variable? Are boundary conditions inclusive or exclusive? If a null value is permitted, what does it imply? Who is responsible for freeing resources? Are there certain properties that are always true for the variable? These information points are things you know to be one way that some other programmer is going to think they know to be some other way, or is going to not think about at all.
Check out the full stdlib collection for more frameworks, templates, and guides to accelerate your technical leadership journey.