I’ve always been pretty good at math. Not trigonometry, or arithmetic, or whatever people are usually thinking of when they’re like, “Oh, you must be smart! I hate math!” But, combinatorics and graph theory and proving things and figuring out how to put hats on prisoners – I love that stuff. I went to three different high schools, and I did math team at all of them. When I was ten or eleven and my parents needed me to shut up at dinner parties, they bribed me with books of math puzzles. No joke.
During my sophomore year of college, I was dating a Computer Science major, and I took some CS classes out of curiosity. To my surprise, CS wasn’t different from math at all. I took my Intro class in Java, so there was some mumbo-jumbo that you put at the top of your programs that went “public something void main something something”, but once you got that nonsense out of the way, it was all sorting lists and putting stuff in matrices and traversing trees. Easy stuff. And once the CS department switched to Python, it got even easier.
So I became a math and CS double-major at my tiny liberal arts school in Minnesota, and my senior year, I started looking for jobs. Turns out, only actuarial firms want to hire people who are really good (but not, like, PhD good) at nothing except figuring out how many ways there are to distribute hats from a coat check so that everyone gets the wrong hat back. So, software engineering it was.
After some research and a couple bad interviews and no small amount of panicking, I found a startup in San Francisco that looked awesome. I interviewed, expecting the worst. But for some reason, my interviewer asked me to find the shortest path between nodes A and B in a graph. (Essentially. I think he said some stuff about Kevin Bacon.) I did so. He asked if I could do better if I knew that A and B were exactly six degrees apart. Yep! Breadth-first search from both ends. Oh wait, you should do that anyway, even if you don’t know how far apart the nodes are! Cool. They flew me out for a full-day onsite interview, where they asked me a bunch more questions that involved sorting things and memoizing things and traversing things, and then they gave me an offer. The entire interview process from beginning to end took six days, and I wrote exactly zero lines of actual code.
Some more relevant things they could’ve asked me, but didn’t:
How comfortable are you with Unix?
I can change directories, list things, and run Python programs. Oh! And rename files. Probably.
Describe how Ajax calls work.
Umm, isn’t that what Gmail uses? It’s like, refreshing the page without refreshing the whole page?
What version control systems are you familiar with?
Oh, we used SVN for our senior thesis project. I accidentally triggered a conflict one time. Someone fixed it for me.
How would you implement a [deck of cards, public garage, hotel reservation system] using object-oriented design?
Variables. Variables everywhere. With counts. And maybe some strings.
Absolutely anything at all about databases.
Huh?
Listen, the very last thing I want is to sound ungrateful. At that first job, I learned all of those things I listed, and more, because the senior engineers patiently sat with me and put up with my stupid questions and never got frustrated with me, even when I got frustrated with myself. But it took me more than a year. And I’ve worked at three jobs since then, and interviewed at many, many more places, and I’ve found that my first startup’s interview style wasn’t a weird fluke. It’s actually extremely common practice. People ask math puzzles to determine programming ability. Why?
In a particularly egregious example of this, when I was interviewing for my second job out of college, I was asked to come up with an algorithm to eventually sink a submarine with unknown (but integral) position and velocity that was somewhere on a number line. (Spoiler alert: to solve this problem, you need to know how to enumerate the rationals.) Once again, zero lines of code. Two weeks into my new job, they told me to write them a consumer iPhone app. Needless to say, I had never encountered Objective-C. I’d written perhaps twenty lines of C in a group project in my programming languages class in college, and all I remembered was that it was terrible and you had to do your own garbage collection or something. My new startup gave me a book called The C Programming Language, pointed me to where I could install the newest version of Xcode, and off I went. Three weeks later, my CTO had a talk with me where he was like, “You’re not getting up to speed as quickly as we expected.” I redoubled my efforts. A week after that, we had the same conversation, but harsher. And then there was a holiday break, and the day after it, I was fired.
I was pretty devastated. I mean, nobody had ever called me a slow learner before. And I had a ton of software engineer friends, and they could all do this stuff. How hard could it possibly be? Why couldn’t I get it?
I promptly repressed my experience at that second startup, talked to nobody about it, joined my third startup (they asked me something about Markov chains), and proceeded to quietly freak out every time I had a 1-on-1 with my new CTO, wondering if I was about to hear that I wasn’t contributing enough, that I’d somehow tricked them into hiring me, that they’d thought I’d be so much better at this.
And I kept struggling, although I did feel like I was learning, and it did get easier. Slowly. But still, I would run into entirely new concepts that I just didn’t have the context for. One time, a few of us got together to code for fun on a Sunday, and someone suggested using node.js, because it seemed like a cool thing to learn. And, looking at some example code, I encountered an anonymous function being passed into another function. I did not get it. Everyone else did! Right away! Even though backend Javascript was new to them, too! So they spent half an hour drawing diagrams with lots of arrows for me, and finally (relying on a lot of metaphors in my head at once), I managed to cobble together a cursory understanding. And then I watched them pass their callbacks around in their code, and it was still magic to me, and I felt so dumb.
Recently, a close friend of mine began learning to code, and I found myself explaining stuff to her. Pretty basic stuff, like the difference between static and instance variables, and how inheritance works. And it dawned on me that I was using all these words like “class” and “object” and “method”, and I knew what they meant, intrinsically, without having to think about it, because I’d been using those words and those concepts for years. But every time I said one of those words, I saw her trying to remember what it meant, what properties it had, and how it fit with what I was saying, because somebody had just written the definitions of all those things on a blackboard for her not two weeks ago. And I realized (it took me that long to realize) that I couldn’t just transfer three years of software engineering experience to her by building and building on stuff I’d already explained. Brains, apparently, don’t work that way. Not like codebases.
It seems like a lot of interviewers think that CS theory and problem-solving skills are the important things, the difficult things, and if you know them, everything else is easy. It makes sense that they think this, because a lot of them have been coding since they were twelve, and they get how to code the same way I get how to solve puzzles. And they probably didn’t learn the theory side of it until college. But me, I’ve been practicing problem-solving since I was ten. So I feel like I’m in a pretty good position to say: programming is fucking difficult. Just as difficult as problem-solving, if not more so. And just because I breeze through your common-elements-in-unsorted-lists and linked-list-cycles and paths-through-grids problems, doesn’t mean that I’ll learn all the new coding stuff I need to know in my first few weeks on the job.
I mean, I’m getting better at it. I feel like I’m finally on the other side of the sheer confusion in the beginning. But I’ve been doing this for over three years now. And there’s still a long, long way to go before I’m anywhere near as good at programming as I am at solving math puzzles. So please, future interviewers, ask me a coding question. You’re trying to figure out if I can code. And I’m not trying to trick you! I want you to know! So there is absolutely no reason for this roundabout nonsense.