Welcome to our version of the seemingly obligatory post about technical interviews. This topic has been covered by a lot of people already, so I’m going to do my best to not repeat all of the copious advice already out there.
Like many companies, we are looking for extremely talented technical people, and we have a challenging interview process that we think does a good job of selecting people who will do well here.
That said, we know that we miss lots of good people too. Some of that is because of the awkwardness of the interview process itself: time is short, the questions are weirdly artificial, and, of course, people get nervous. It’s made even worse by the fact that programming on a whiteboard, a web browser, or even just on a computer that isn’t yours is a bit like playing classical guitar with mittens on. It can put even an accomplished person off their game.
Missing out on good people makes us sad.
That’s what this post is for. We hope that by talking a bit about what we’re looking for, the ways people do poorly, and how we think you might be able to prepare, that we’ll reduce the mitten handicap – at least a bit.
What Are We Looking For?
From our perspective, the main thing we want to figure out when we interview someone is: are they someone we want to work with?
That seems obvious enough, but it’s a point that can get lost in the puzzles and whiteboard coding of an interview. Really, we think of our interviews as little simulations of what it’s like to work together with the candidate. And while at the time, it may seem to the candidate that the interview is all about solving the problem, it’s really not. We’re much more interested in learning about how you work than we are in whether you actually finish whatever problem we put in front of you.
It’s not that technical skill is irrelevant – far from it. But it’s only part of the story. Just as important to us is whether we can have a productive and fun discussion with the candidate.
To that end, we try to avoid algorithm bingo and puzzles with clever “aha” solutions. We prefer more open-ended problems that have no single right answer, since they give us more freedom to work together, and to see how the candidates’ thinking plays out.
That sounds nice enough, but it’s a bit high-level and hand-wavy. So here’s a more concrete list of suggestions that follow from our overall approach.
The smartest, best person in the world won’t get hired at Jane Street if they aren’t courteous and pleasant to talk to most of the time. Almost nothing will end your interview faster than being rude, pushy, or obnoxious.
Remember, we are looking for someone to work with, not just someone who can win an argument.
And by clear, we mean simple and to the point. Use words and examples that get the core idea across to the widest technical audience possible.
Avoid showy, highly technical or deeply obscure terms of art, especially if you don’t fully understand them. In the best case we’ll likely just ask exactly what you meant by “hylomorphism”, which wastes precious time. In the worst case it will become clear that you should have said “metamorphism” instead, which is just embarrassing for everyone involved.
Know what you don’t know
Naturally we like it when candidates are good at solving the problems we put in front of them. But just as important, perhaps more important, is their ability to think reasonably about their own level of understanding.
In other words, we really like people who can express appropriate levels of confidence: admitting ignorance when they’re unsure, and speaking confidently when they have the basis to do so. At a basic level this means being willing to say, “I don’t know” rather than guessing and hoping when we ask you about something you aren’t familiar with.
Know your language
Code is a wonderful language for communicating complex ideas because it provides a clear, concise and unambiguous way of expressing them. But, like any foreign language, it takes a lot of time and practice to get really comfortable.
We need you to be comfortable with it, because we communicate ideas in code a lot.
Now, comfortable doesn’t mean that you have to be the world’s best coder, or that you need to have memorized your favorite algorithms book. It means that you should be able to read and write code in at least one language without constant access to reference materials for common things, such as:
- Standard control structures (loops/if-then/etc.)
- Function, module, class, type, etc. definitions
- Common data types like arrays, lists, hash tables/maps/dictionaries
- Exceptions and other error handling techniques
Also, pick coding tools you understand well. Don’t pick a functional language to make us happy. We’d much prefer you use a language that you know well. Similarly, when picking which features of the language to use, pick the ones you understand best. We’re not going to be impressed with your elegant use of Python decorators if you don’t really understand the details of what they do.
In other words, pick a simple, clunky solution that you understand over a fancy, elegant one that you don’t.
Remember CS 101
We’ve hired plenty of successful people who didn’t have a traditional college background in CS, and we certainly don’t require a masters or a PhD. That said, we need you to have a solid working knowledge of core computer science concepts, including:
Abstraction layers like functions, objects, and modules
Basic algorithms and data structures, including binary search, sorting, hashing, breadth/depth first search, hashtables, binary trees and heaps.
Techniques for estimating CPU and memory costs, including big-O notation.
So if you can’t for the life of you recall what amortized analysis is, and you can’t nimbly bang out the code for a depth-first search it’s probably worth reviewing some of this material.
Think about real computers
Depending on your point of view it’s either a sad or beautiful fact that the most elegant code can only run on top of the giant, complex, odd stack of parts and abstractions that is a real computer. Since we need programs to actually run, we need people who understand the inner workings of that behemoth.
Now, this doesn’t mean that we quiz every candidate about deep kernel internals, or the differences between SDRAM vs SGRAM. But for some jobs in systems development we do expect a fair amount of detailed knowledge, and in general it’s a big plus if in your thinking you can take into account things like cache effects, IO patterns, memory representations, and the capabilities of real CPUs.
What We Don’t Look For
Perfection. Our questions are often designed to be open ended enough that even the best people we’ve seen couldn’t answer them fully in the time alloted. We want to keep the conversation going to learn everything we can, and we don’t expect that you’ll answer everything 100% perfectly.
We don’t ask developers mental math, or math olympiad questions despite what you might have read online. Dev interviews are about programming.
We don’t ask developers logic puzzles about pirates, people who only tell the truth, or which door the tiger is behind. Dev interviews are about programming.
How do people do poorly?
The most common issue is, of course, that some candidates just don’t have the background for the job they are applying for. The solution to that is to learn more, and practice more. But there are a few other less obvious reasons that interviews with otherwise technically good people can go awry.
One of the most common pieces of negative feedback from our interviewers is that the candidate was careless. This usually doesn’t mean that the candidate didn’t make progress, or didn’t have good insights. It means that the candidate didn’t think carefully and systematically about how their program might go wrong.
We care that you make progress, but we are rarely concerned about finishing a problem. In fact, many of the problems are designed to go on for far longer than the average interview length. It’s better to step back and check your work carefully before you claim that it is finished than to rush.
They talk more than they code
Some candidates do a good job of talking through the problem and explaining their thinking, but never quite get around to concretely answering the question. We want to hear your ideas, but we also want to see you produce concrete solutions, which almost always involves writing code. There are lots of things that we can’t learn about a candidate without seeing their code and talking through the details.
Take some time at the beginning to think about the solution and to talk about your plans, but make sure you start writing code – even if it isn’t the code you would write if you had more time.
They don’t generalize
We try to keep our interviews interactive, and we’ll often stop candidates to ask about something they have just done, or to point out something that we think might be confusing or incorrect. We understand that we’ve seen these problems over and over again, and that you are coming to them fresh, so you shouldn’t worry just because we’ve found a problem with your solution.
What you should do is generalize the advice. If we point out that you missed a case, consider other cases you might have missed. If we remind you of an invariant you forgot, find a way to protect yourself from making the mistake in other places in your code.
They say one thing and do another
We love it when a plan comes together, but it’s extra hard to watch when a good plan falls apart on execution. If you hear a question, and discuss a plan of attack with your interviewer, do what you claim you will do. Don’t change the plan in the middle, or drop it entirely in favor of a better idea without some discussion. You have a very limited amount of time to describe your solution in code, and executing a decent plan well is better than producing a Frankenstein’s monster of 3 different plans that doesn’t quite come to life.
If you do get partway through and start to lose faith step back and talk about it. Explain exactly why you are concerned, and whether you think it might be fatally flawed at the core, or just not ideal. If there really is a fatal flaw and you’ve seen it, we’ll help you get out of the jam, and we’ll appreciate that you articulated it. If it’s just not quite perfect we’ll likely encourage you to continue.
So, what can you do to prepare?
This part is short and sweet. Build something – from scratch – in a language you like. Don’t stop short. Build the whole thing.
Now, show it to the smartest people you know, get feedback, tear it down and build it again with what you’ve learned.
Repeat with a new problem.
We are looking for people to build real things with us, and practice really does make perfect.