Interviewing Programmers

Back in the early 1990’s I blew a job interview at Papyrus Studios in Cambridge, Massachussetts. If you’re a gamer, and into racing games, then you surely know the automotive simulation powerhouse that Papyrus became. Their Nascar Racing series was the definitive racing game for nearly ten years, noted for its realistic graphics, and impressive simulation of the physics of 3000 pound cars hurtling around an oval track. If you ever got bored with actually competing, you could always turn the car around and drive the wrong way at 160 miles per hour, and then enjoy the resulting chaos when you smacked into the lead cars of the pack on the back straight. Smoke, flames, cars spinning off the track, chunks of debris flying every which way. It was a blast. Unfortunately, while I loved playing the game, I didn’t get to work at Papyrus, which closed its doors for good in May of 2004. I’m sure those things are not related.

But I would have made a pretty good employee. When I interviewed with founder David Kaemmer in 1992 the company was still very much in startup mode, though they had been in business since 1988. Located in a loft not far from MIT, the company gave off exactly the intellectual, creative vibe I was looking for. It would have been my first real programming job. I had been working in technical sales since the late 80’s, and had been programming since 1975, when I started writing BASIC programs on a time-shared teletype terminal attached to an HP3000 mainframe. By 1989 I had become a C++ and OO freak, and was both writing software, and writing about writing software, in journals such as Computer Language, Software Development, Dr. Dobbs, and Jeff Dunteman’s PC Techniques. I met most of the editors of these journals on the Computer Language forum of Compuserve. Another forum I hung out on was the Gamers Forum, and that’s where I met Chris Lampton.

Working with Chris I had helped to write a crude 3D flight simulation used as an example for his book “Flights of Fantasy.” Chris is a great writer, whose work spanned just about every known genre, from Hardy Boys detective novels to nanotechnology and simulation programming. We fell out of touch around 1995, but he has been hard at work since. The reason I mention Chris is that the simulation we wrote for Flights was one of the things I brought with me to that late afternoon meeting with Mr. Kaemmer in Cambridge. I hoped that the code for that program, written in C++ and assembler, along with some citations of my articles (one of which, for DDJ, was an early examination of the use of BSP trees in searching partitioned multi-dimensional spaces, for example a color cube) would convince him that I was skilled enough and creative enough to join his team.

The meeting was after five, and David was late. A few years afterward I became an entrepreneur myself, and helped to grow a $15 million banking technology company, so I understand now, in retrospect, why he appeared so tired when he finally made his way down to the conference room. By the time of our meeting they had been at it four years, and had yet to really break through and get some traction. As it turned out, like many startups of this type, they were waiting for platform technology to catch up with what they wanted to do.

David began by talking about their core value proposition, which was in the detailed physical model they had developed. He showed off some demos, and they were indeed impressive. As I watched I was getting less eager to show off the pitifully crude (in comparison) demo program from the book. After the demos and some general technical discussion, David asked me to write a function on the whiteboard to convert a number into its ascii representation. In other words, to write _itoa(). Now this is an easy function, since the delta between a numeric digit and its ASCII character index is 32, but I froze. I’m just not one of those people who can write code in demonstration mode, under pressure and the watchful eye of an interviewer. After watching me fumble about for a few minutes David gave me the answer. Things were not going well.

He then asked me to sit down and write a function on paper to insert a node into a linked list. This time he left the room. It’s an easy function, and he wasn’t watching me anymore, but again I froze. It took me half an hour to cobble out something that was functionally correct but hardly elegant. I’m sure that was a half hour during which David was thinking largely about how to get me the hell out of the office so he could go home. The problem was the same: I don’t write code on paper. I sometimes rough out designs on paper, and create object models on paper, but I write code the way everyone else does, which is to say, using an interactive editor and sculpting out what I need.

I usually start by writing the method signature, then begin to fill in the parts between the curly braces. High-level flow control and branching logic comes first, followed by the details that implement the algorithm in each block. How do you do this on paper? You can’t. Instead you have to think your way through the function in your head, and then write it down. This ought to be possible, especially for a well-known algorithm like a linked list insertion, but for some people it is damned hard, and I’m one of them.

The interview, needless to say, was over. David was gracious enough to look at my stupid little demo, and even complimented me on the smoothness of the control algorithms, which used a logarithmic scale to dampen control inputs from the joystick. But he had no intention of making me an offer, and I knew it. “But…. but… what about all this assembly code? And what about my article on BSP trees? I KNOW WHAT THE HELL I’M DOING!” I wanted to shout, but it was no use. He had his idea of what a programmer ought to be able to do in an interview, and I hadn’t done it. I ended up getting a great job with Semaphore, teaching C++ and OO techniques, and leading development teams on a consulting basis. The OO revolution was gathering steam, and I was riding it into a good career doing what I love. But I didn’t get the Papyrus gig, and I have always regretted that, even though I am sure I ended up making a lot more money than Kaemmer would have offered me.

I started thinking about all this again as I went through the process of interviewing programmers while helping to rebuild a ravaged IT department recently. Back in 2003 there was a flurry of discussion on Internet sites on exactly this topic, kicked off by an essay and round table discussion hosted by Bill Venners on Artima Developer. I went back and reread some of this content, and I was gratified to reacquaint myself with the tactics suggested there, many of which dovetailed with what I now found myself doing instinctively. Perhaps because of my early experience in the Papyrus interview, I have always avoided putting developers on the spot with detailed API questions or demands for performance function writing at the whiteboard. I don’t think those things help, for a number of reasons.

What I want in a developer is a very intelligent and motivated generalist. I want people who understand how computing and programs work at a deep and fundamental level. I want people who can, as Bruce Eckel suggested during the Artima discussion, describe the object model of a chicken. Tools have increased in sophistication to the point that I don’t value the fact that a programmer has memorized the method signature of SQLConnection::CreateCommand(). I would value more his or her knowing where in the overall scheme of things that method belongs, and how to quickly find a reference to it.

Programming is becoming a more abstract discipline, even for the system programming gurus who work at what the rest of us would perceive to be a very low level. People who are naturally curious, creative, and inventive, are worth more to me as a manager than someone who has made themselves into a specialist on the System.Data namespace. The most important and productive qualities, to me, are an ability to see patterns, identify abstractions, decompose problems into behavior and state elements, and see the system as a model with discrete and interoperable components. I tend to think that if a person has those qualities, and is currently developing in Java, for example, they’ll come up to speed on .Net quickly and be more valuable to me than someone who has never learned to do more than drill from a form on a page down to the database, and can recite the lifecycle events of a web control in meticulous detail.

I also, frankly, value a little grey hair. Many young programmers that I meet today have very shallow experience. They’ve learned Java, or .Net, and have developed forms-based web applications. Maybe they have created and implemented a database schema. Most have never written a stored procedure, integrated modules from different languages, executed a remote procedure call, or even designed and implemented a bubble sort. Many of them don’t know what a register is, or a call stack, or a function frame. I know that in the future programming will be even more abstract. In fact that’s one of the few things about the future that I know with certainty. But until I am proven wrong, I will continue to believe that real programmers are people who love computing, and come at the discipline of software development from many different angles. Smart generalists. That’s what I’m after.

Leave a Reply

Your email address will not be published. Required fields are marked *