March 02, 2003

Interviewing programmers

Erik Barzeski has some interesting commentary on interviewing programmers, which was largely inspired by an article entitled "How to Interview a Programmer" that Slashdot pointed to last week.

Erik's comments are mostly about the problems with being asked to write code in the middle of an interview -- it's a high-pressured situation, it's easy to make mistakes, you don't have language references or a compiler around, and you might be writing in a language that you haven't used in a long time. He mentions that Apple interviewers tend not to ask candidates to write code, but Microsoft interviewers often do.

I have to say that from the perspective of someone doing the hiring, I like Microsoft's interview process much more than Apple's (and if I ever end up being a manager at Apple, my team's going to do interviews differently). I can't talk about the details of either company's process, but I'll mention that I really like having candidates write code. If I'm hiring a programmer, I want to know that they know at least one programming language well enough to solve difficult problems in it quickly, and the best way to determine that is to ask them to write something.

As an interviewer, I couldn't care less about details of syntax or even what programming language they're using. When I ask a question, I'll just present a problem and ask the candidate to solve it. If they want to write the answer in C, Java, Perl, or even Objective-C, that's fine. They'll be able to show me their best solution if they're using a language that they're comfortable with. And if they leave out semicolons or misspell variable names, I don't care. The compiler would catch that.

What I'm looking for, though, is a sense of whether they can come up with a good design and then implement it correctly. I don't even expect the best solution first -- I like asking questions that have a simple solution that can then be improved to be more efficient or modified in interesting ways when the constraints of the problem change. Assuming the candidate comes up with the simple solution, I'll then ask them to do one or more of the modifications. At each stage I'm interested in the algorithms they choose and the reasons behind their decisions, since that will tell me much more about their abilities than anything I might ask about C++ intricacies. Anyone who can design good code can write good code in any language, but not everyone who knows a particular language in depth has any sense of good code design.

Erik quotes a passage from "How to Interview a Programmer" that says that writing code on paper is silly because programmers have auto-completion, macros, context-sensitive help, refactoring, and so on. That may be true for some positions, but it certainly hasn't been true for most of my coding. I'm used to having to write code in vi because emacs isn't available (to say nothing of BBEdit or Visual Studio!). I'm often in a position where I have to understand code that I haven't written, which calls APIs that I don't know, and which might even be in some random macro language that I've never seen. When I hire someone, I want them to be comfortable with situations where they don't have all of the whizzy features of modern IDEs to help them out. Those are a huge help, certainly, and everyone should use them whenever they can, but you have to be able to write code when they're not around.

I should also mention that most of those features are specific to certain libraries or APIs. When I ask a programming question, I don't require the candidate to use any particular library or API, and I won't ask questions that would be much harder in languages that don't have certain APIs. I won't ask a question that requires hash tables, for example, because anyone who chooses to use C will be at a significant disadvantage to anyone who uses Java. On the other hand, I might ask someone to implement a hash table, or I might tell someone to assume that they have a certain hash table API that they can use. Along the same lines, if someone I'm interviewing is trying to use an API but they can't remember its name, I'll tell them what it is, and I'll tell them the order of parameters, too. I don't mind being the documentation to the candidate, as long as it's something that they'd easily find on their own.

One last thing: Both Erik and the person he quotes, Matt Gerrans, suggest asking candidates to write code ahead of time and bring it in. I'd never do that, for the simple reason that there's no way to ensure that the candidate wrote the code. Sure, I can ask them detailed questions about it, but I don't know if they were given the solution and then studied it hard enough to be able to answer my questions. I'd much rather have them write code in front of me. Perhaps just as importantly, if they only write code ahead of time I can't lead them through a series of problems to see how they think or whether they can adjust their solution as constraints change in interesting ways. I don't want to hire someone who's going to be asked in a meeting, "Will things change if we need to handle twice as much data" and respond with "I'll get back to you in a few days" (unless, of course, the question really is so complex that it can't be determined any faster). In other words, I want people who understand the design decisions inherent in writing software, and I can determine a lot of that by asking them to write code to answer design-centric questions.

I should mention that I've mostly done systems programming. I'm sure people writing applications in which architecture and performance aren't as important as the user interface and basic functionality will have different priorities for the candidates they interview. When you're looking for a job, it's important to make sure that your knowledge can translate into what your prospective team does. As I learned the hard way with one unfortunate candidate who completely failed to write a memory allocator for me a few months ago ("Here's a whiteboard and a marker. Implement malloc."), not everyone thinks of that before sending in a résumé. In his case, he was applying for a lead developer position on a systems programming team, but he'd never contemplated how a memory allocator worked. He might have been a terrific programmer, but not for that team, and certainly not in a lead's role.