CS skills in the real world — debugging

This is the first episode of what I hope to be a mini-series in the practical uses of skills learned through computer science.

It’s August of 2008, and you’re playing around on the Internet. Maybe you’re on Miniclip playing flash games. (I mean, I hardly remember what I did on the Internet in 2008. Exponential growth, am I right?) Maybe you’re refreshing your Facebook news feed, since this was back before the days of AJAX updates. Either way, you’re surfing the web, and you see reports that Russia has invaded Georgia. I can’t really imagine why a high school world history class would teach anything about Georgia — so if you’re like me, you’re a bit puzzled as to how/why Russia invaded the U.S.

I'm twelve years old and what is this?

You don’t want to be Jessica B. Jessica B doesn’t know how to debug.

Debugging is a computer science term for discovering and fixing an error in your code. For those in the know, the word debugging conjures up demonic visions of NullPointerExceptions, application traces, and segfaults. Yes, all of us that have taken a systems programming class have spent hours chasing down a single memory leak the night before a homework was due.

However, my assertion is that the hours spent painfully isolating and correcting those reclusive little bugs gives you a valuable skill applicable throughout your entire life.

Proper use of reference materials

When we teach new CS students at Penn how to debug, we emphasize “Google it” more than anything else. Somebody out there has seen and solved your problem before, especially for large and interconnected frameworks like Rails and iOS. (The number of hours I spent last semester figuring out why it was so damn hard to do nontrivial things with a UITableView…unbelievable.)

I specifically remember hearing about the Russia-Georgia War of 2008, seriously wondering what beef Russia had with America, and Googling for Georgia to figure out that Georgia was indeed a Eurasian country that had nothing to do with the Braves and the Falcons.

CS also teaches you about more directed searches. Javadocs, man pages, and Hoogle are all incredible inventions that don’t get praised enough. Ever tried coding non-trivial Haskell without Wifi, and thus without access to Hoogle? You can’t do it.

Predictably, computer scientists understand the value of information. We use this in all walks of life, from scouring through electronics manuals to saving face when unfamiliar with a “common” fact.

Thinking outside of the box

I recently had a problem set due for a class in theoretical regression. One of the problems was to show that Cov(α-hat, β-hat) = -xbar/Sxx. Not a hard problem, but I kept getting that Cov(α-hat, β-hat) = -xbar*σ^2/Sxx, and I had no idea how to get rid of that extra sigma term.

Some students might have fudged the derivation, hoping that the TAs wouldn’t notice the mathematical gap. I personally refused to do this on principle. Other students might have gone to the teacher to ask for help. While I’m a big proponent of asking for help after immersing one’s self in a problem, this was at 1am the night/morning before the problem set was due. So, what would you do here?

Maybe, through my CS experience, I’m familiar with the problem of data being out-of-sync. I’ve got Apple-Shift-R (force-refresh, ignoring your browser’s cache) on muscle memory speed dial. For whatever reason, the first thought that jumped into my head was what if I’m looking at an old version of the problem set?

Sure enough, when I revisited the course website and checked the problem set PDF, the derivation in question had been changed to reflect the answer I was getting.

I couldn’t show that Cov(α-hat, β-hat) equals -xbar/Sxx because Cov(α-hat, β-hat)doesn’t equal -xbar/Sxx.

I wouldn’t have thought that I’d downloaded an incorrect version of the problem set without my background in CS. That was definitely an unorthodox way to figure out my issue.

This parallels computer science debugging in that programmers encounter really weird stuff all of the time. Programming languages and runtime environments are complicated pieces of engineering; not all bugs can be logiced out the standard way. Sometimes, one must be creative to fix a bug.

Inductive reasoning

A difficult, hidden bug is a riveting puzzle to solve, a true exercise in logic. Programmers maintain a mental list of likely reasons for the error and systematically check different symptoms to determine why the computer is not doing what they want.

This process and method of thought is similar to what a lawyer uses in oral argument or what a doctor uses in diagnosing a patient. (Extending the analogy even further, you could easily think of a patient’s sickness as a bug in their system that must be fixed.)

This may be the most powerful point in this blog because the mentality of inductive reasoning is not easily taught. The context of computer science and programming is one of the most effective ways to build true inductive reasoning skills, skills that transfer to almost any other profession.

My friends and acquaintances that have moved into investment banking (and, more generally, high finance) tell me that their computer science skills give them a huge leg up on their coworkers — not because banking necessarily requires coding skills, but because they know how to diagnose and solve an issue. They have the critical thinking skills that their finance and econ major brethren do not. Programming occurs in an open system, whereas one performs finance / econ problem sets in a closed system. Open systems introduce bugs that require these skills.

Consequently, those exposed to programming come armed with real-world abilities that give them a true competitive advantage in the workforce.

Conclusion

If everyone became a software engineer, the world would stop. Accordingly and obviously, this blog is not a call for everybody to enter the field of software engineering. However, you owe it to yourself to study programming — if not to gain a sense of technical literacy, to properly learn how to solve unexpected problems.