Love the Whiteboard

I’ve been hiring developers for a lot of years, and after you exhaust your personal network it’s really hard to get right. In the first place, you’re interviewing folks because you have work that needs to get done — so there’s always time pressure. Worse, there are about a hundred crap engineers for every great one, and resumes rarely correlate with quality in any significant way.

On the upside, our craft is pretty observable — if you watch somebody solve real coding problems in real life, you can pretty quickly figure out what’s up. It takes effort and experience to become a solid technical interviewer, but the payoff is well worth it. Nothing beats working with great people, and not much bites more than dealing with mediocre ones.

Look, I get that whiteboard interviews are high-stress and scary, and are extra-hard on folks with certain personality types (like, say, mine). As an interviewer you need to understand that, remember what it felt like on the other side of the desk, and do your best to make a distinctly unnatural situation feel as natural as possible. One way you can do that is by giving people a choice of medium — a whiteboard, a piece of paper, a live editor on a laptop, or online coding tools like CodeCollab. And never, ever do these interviews in a group — “cold war interrogation” is not the vibe you are going for.

I’ve been there too

Two memories, both from Microsoft. The first, as a college sophomore being interviewed for an internship by Ed Fries. He started out asking me details about Mouse Odometer, a little shareware Mac extension I’d built. Opening this way is great strategy — if the candidate is full of crap it’s immediately obvious; if not, explaining something they know well is a comfortable start. Ed then handed me a piece of paper and a pencil and said, “find and delete a node from a linked list.” I did, and holy crap I did it without bugs. Which was enough to make him suspicious and ask if I’d prepped the question, which I had not. I got hired, so presumably he believed me, but actually the implication still kind of pisses me off, Ed.

Second, interviewing for a spot on the MSN 1.0 team with Jeff Lill (creator of Microsoft Project). Jeff gives me a pen and a yellow legal pad, says “write malloc and free, I’ll be back in a bit” and leaves the room. Um, OK. All I remember about that half hour is writing smaller and smaller to jam code between existing lines. It was weird but effective — if you want to know if somebody can code, make them write code.

It has been awhile though! Until today … at the end of this article you’ll be treated to a one-shot sceencap video of me solving a linked list question in Java. Could be fun, could be embarrassing, we will see!

Minute by minute

For an actual developer interview you need an hour. For some reasons recruiters always want slots to be forty-five or even thirty minutes. No way. Break down your sixty minutes something like this:

Introduction (5 minutes)

Make sure the candidate has some water and doesn’t need a restroom break (if they do, email the next interviewer to tell them you are going to run late). Introduce yourself and provide a little context so that they know who you are and why you are talking to them.

Tell me about … (10 minutes)

Pick a specific project from their resume and ask them to describe it to you. Give them a minute for the high level, but then dive hard into details. The subject isn’t important; what matters is that (a) they can talk specifically and concretely and (b) they are enthusiastic and proud of their work.

If you are well-versed in the project domain, that’s great, but it’s not essential. If the area is new to you, ask the candidate to teach you. Ask questions along the way; it’ll be quite obvious if they don’t know what they’re talking about.

The candidate may tell you that they don’t remember the particular project you’ve chosen. That’s OK, have them pick another one. If they can’t, they’re probably a NO HIRE.

Coding (30 – 35 minutes)

At this point you’ve both settled in and it’s time to get into it. More on coding questions below, but as a general pattern it should play out like this:

  1. Explain the problem.
  2. Watch them solve it, answering questions or providing hints as needed.
  3. When they think it’s done, ask them to test the solution — the best sign here is if they start stepping cases through the code on their own (even better if they did so without you prompting). If you see bugs, try to get them to find them by suggesting test data.
  4. Make the problem harder and repeat steps 2-4 until they get stuck or you run out of time.

I always remind folks that their code has to work first — you can always build from that base to make it faster and better. It’s a big bummer for everyone when you go the full half hour and don’t even get to a solution for the simple case.

You’re not looking for perfect code on the first try. You’re figuring out if this person is adept with the patterns and tools involved in building solutions with code; if they are methodical in their approach; if they have fun and care and take pride in their work. Everyone writes bugs; the question is how folks find and fix them.

AMA (10 – 15 minutes)

Finish up by giving the candidate time to ask you anything. They might want to know about your product or the company. Especially for a startup, they may have questions about long-term viability. Remember they are assessing you as well, and — if they’re awesome — you want them to want the job.

Don’t skimp here, because this time benefits you as well — the questions people ask tell you a lot. Maybe the candidate just doesn’t like to work very much. Maybe they have a particular passion for the problem you’re solving and bring relevant ideas and experiences to the team. Be prepared for tough questions from good candidates; why did YOU bet your career on this place?

Coding questions

Why are linked list questions so popular? It’s not just because interviewers are lazy — linked lists are a sweet spot for a few reasons:

  • They are easily explained — if you don’t know what a linked list is you don’t belong in the room.
  • They aren’t heavily algorithmic — the “what” is pretty simple.
  • They are quite finicky — the “how” is not trivial to get right, especially at the edges.
  • They can be easily made incrementally more difficult — which both lets you push a candidate harder or ease up if they are struggling.

I consistently find that all of this is true even if (unlike me, Ed) the candidate has prepped for list questions. Sure folks can get through the obvious starter bits, but small variations easily amp up the complexity; you still can quite easily identify who is and is not awesome.

Still, it’s worth creating a portfolio of questions all your own. As you develop these, shop them with your colleagues. It’s fun to do and will help ensure that your problems work well in an interview setting. My all-time workhorse question is to implement this class:

public class Searcher {
    public Searcher(String[] targets) { }
    public boolean anyTargetInCorpus(String corpus) { }
}

The problem is to identify if any of the target strings appear in the corpus string, and performance matters. The targets are provided on construction because the anyTargetInCorpus method will be called multiple times for different corpus strings. Say a few dozen short target strings with corpuses a couple of megs in size. Purely character matching, case sensitive and no lexical issues like word breaks.

Depending on how you tweak it, the endgame for this problem is usually some sort of trie — a little more esoteric than the linked list, but still something good coders should be familiar with. It’s a pretty straightforward implementation, but with finicky edge cases. There are also many other ways to attack it, and tons of interesting heuristics that can be applied along the way. Good stuff.

Don’t be an a*hole

The worst interview questions are solved or not — black or white — with some flash of brilliance or tricky bit of logic. You don’t learn anything from these and they make for an awful experience. You’re bored, the candidate is freaking out because they’re stuck trying to move wolves and sheep across some bullsh*t river, and at the end of the day all you can do is tell them the answer. Might make you feel smart, but actually you’re just being an a*hole and not learning anything useful about the candidate.

Even with a great problem, a lot of folks are just going to crash and burn during the coding part of the interview. Most of them understand that this is happening in real time and it’s not fun for anyone, but there are a few things you can do that make the experience less of a bummer:

  • Make sure your problem has a naïve solution. If a candidate is really struggling, ease off requirements until they can be successful. For example, anyTargetInCorpus is implementable as a simple loop of calls to String.indexOf.
  • Once you know it’s over, don’t keep digging the hole deeper. You can eat up a lot of time with AMA and leave the candidate feeling positive about your company and the interview process. Candidates share their experiences with friends (and increasingly with strangers on Glassdoor and other sites) — don’t shoot yourself in the foot.
  • Have a plan to smoothly terminate a series of interviews early. Never tell a candidate exactly how many people they are going to talk to or when they will leave — this gives you the ability to ease a clear NO HIRE out of the process without slapping them in the face with it.

Let’s see how this goes….

It’s been a long time since I’ve been on the candidate side. Writing all this from the interviewer’s perspective, I thought that it seemed only fair to put myself out there a little. So I built some quick scaffolding for the classic “insert into a sorted linked list” problem and recorded myself solving it in real time (one take no cuts, kind of scary!). The video is below, and/or check out my code (and the scaffolding around it).

Good news: I got to correct code. Bad news: it took me almost 30 minutes! I think I would have been much faster on a whiteboard than in the editor — my typo rate was huge and I missed having the test cases in front of me in diagram form. Of course I could have used paper but that wouldn’t have made it into the recording. It was also nice to be able to run tests live, but this was very different than it would have been in a real setting, where I’d have used manual walkthroughs.

I struggled for a bit on the delete case, with a few stop/starts before I got it right. I feel ok about that though — not sure if it’s obvious listening to my commentary, but the early mistake actually helped me focus on the right edge cases. Pointer management is just finicky no matter how you slice it.

Lastly, there was a bug in my tests, whoops! As I was building cases I copied one block of tests (“delete from front”) and pasted it into a new section (“delete from end”). I was going to modify them, but got distracted with some other stuff. When I came back to it, I saw the comment and my brain just assumed they were done. I did some post-video testing to verify that the intended cases did work. So all good, but this is actually a great real-life example of something I always try to teach folks: COMMENTS LIE. I comment very sparingly because it is so very easy for the actual code to be/get out of sync with the comments, which causes exactly the problem I ran into here.

In any case … this was a fun experiment. Hope that the text is useful and the recording entertaining! Although really if you’re watching me write linked list code for a half hour you might want to reconsider your time management. Until next time!