Befriending the Machine
Freshman fall, thinking that Harvard's introductory CS course (CS50) would be too easy, I took Harvard's systems programming course, thinking it was the natural next step. It kicked my ass, and I learned only afterwarsd that despite it's low catalog number (61), many computer science majors find it more difficult than more advanced (in name) classes. In particular, I spent over 20 hours a week writing debugging C++. We covered the fundamentals of assembly, memory management, kernels, networking and concurrency, shells, and caching. My foggy memories of the class include mad-rushes to draw diagrams of cache heirarchies in an attempt to debug a p-set in which we were writing a cache, and deciding between a binary tree vs linked-list to implement my virtual shell that parses bash-like commands. And, of course, the famed binary bomb.
The class turned out to be more formative than I think I realized at the time. I always wondered why future software engineers would bother to learn systems programming (ie. how computers actually work on a low level) if they'd spend their lives writing react code or some other business logic for a company that is much less involved than the kind of programming that is done by systems experts. Of course, some engineers at Google write compilers and browsers and operating systems and high-performance distributed systems. But the vast, vast majority don't. So why practise or spend hundreds of hours learning such a thing in the first place?
The short answer is that systems programming, and classes that teach it, are mostly useful because not because they are teaching you about memory or assembly. They are mainly teaching you to debug subconciously before and while you write code, and to have unreasonable amounts of patience as you're doing so. It just so happens that discussing memory management or assembly representations happens to be a convinient way of imparting the real lesson (seeing through the computer, and being patient with it).
I like to think of it as "befriending the machine." The analogy goes something along the lines of what follows. Suppose you meet your high school sweetheart at age 16, then go on to fall in love and live through a happy marriage over the course of 30 years. This far into your marriage, you don't know everything about your partner, but the key is that you have faith that you're not missing anything substantial about them, either. You have laughed with them, cried with them, been bored with them, unclapsed the secret pieces of your heart to them. You have seen them scared, elated, moody, and naked. There is little they can do to utterly surprise you, and little they can do to intimidate you into thinking there is much more to them than you know.
In this analogy, learning systems programming is the wedlock process by which you become familiar with the machine. You are getting to see it naked. By spilling its guts and seeing its inner workings laid bare, you won't come away thinking you know everything there is to know about electronic computers, but you will come away feeling like you have a simple understanding of most everything that comes together in an electronic computer. That is to say, you'll never be intimidated by the machine, and you've learned that with patience, you can tease out of it all the answers that you're looking for. You have befriended the machine. And this marks the reversal of roles between master and emissary, where now you're actively aware that the construction of the machine is nothing more than a series of choices made by those engineers who came before you; choices made to optimize the manipulation of electrons that correspond to abstract logical symbols that make sense to humans.
And so, even though you may (likely) never end up having to wrangle bits in the way you learned in your compilers, databases, or operating systems class, the familiarity and comfort you build with the machine stays with you for life. Even years after you become an engineering manager or startup founder, years after writing your last line of code, if you need to get back in front of the keyboard and get shit done, this technical maturity will ensure that you're comfortable doing so. After all, how scary can an old friend be?