This post describes (roughly) the aims and format of typical systems design interviews, and gives guidance on how to approach them.
The intended audience is systems and software engineers who are less familiar with this style of interview.
Context
The company
Many companies - large and small - include a "systems design" slot in their
on-site interviews, where the candidate is asked to design a relatively
large-scale system - typically involving multiple cooperating machines and
services.
The aim of the company in these interviews is to gauge the candidate's
experience with and intuition for the design of distributed systems.
It's also a good opportunity to see how well the candidate communicates ideas,
and what working with them would be like at a design level.
The interviewer
The interviewer shares the company's aims, more or less, and needs to:
- set the scene, laying out the systems design scenario to be covered;
- guide the interview, clarifying things and giving hints where necessary;
- inflect the direction the discussion takes depending on the candidate's
experience;
- ask questions and dig into concrete elements of the design to make sure the
candidate
- knows what they're talking about and
- can reason about and defend specific points, rather than talking
"abstractly" throughout the interview;
- assess the candidate's domain knowledge, problem-solving ability,
communications style, and culture fit.
Taken together, this is a fairly tall order, so usually interviewers in this
area have significant interviewing experience.
The candidate
Your aim is obviously to get an offer. ;o) In this case, that means you need
to:
- demonstrate good communication and problem solving skills;
- show that you can apply any knowledge you have that is relevant to the
problem domain and/or navigate the unfamiliar parts;
- dig into and solve design issues appropriate to your experience level.
Think of yourself throughout as a "future colleague" - taking a collaborative
approach to the discussion.
Guidance
Typically an interview like this comprises a single design question followed by
a long discussion. Roughly speaking, you can expect things to go like this:
- The interviewer sets up the scenario. Some examples:
- The interviewer gives some starting data to work from: user numbers, data
sizes, that sort of thing. It's important to note that this will be
incomplete. Do not try to work from the initial conditions in splendid
isolation. Instead,
- You clarify the scope of the problem, asking for any further data you feel
you might need to start on the design.
- You decompose the problem into sub-problems.
- You start tackling one, again asking for any data not already provided, or
deriving new data from what you've been given.
- The interviewer digs into concrete details, asks for clarifications, and
provides hints or further information where necessary.
- Go to step 4 and repeat until time runs out. :o)
Communication
Overcommunicate.
The interviewer wants to understand how you think, so staring at the whiteboard
for 5 minutes is not very useful to them. If you usually work in silence,
practice on paper before the interview, speaking aloud about what you are
doing.
If there's a whiteboard - there most probably is - use it for everything. If
there isn't, ask for paper. Write down design parameters given to you, or that
you derive. Draw system diagrams, data flow diagrams, API specifications. It
helps clarify your thinking, encourages useful decomposition of problems, and
makes it easier for the interviewer to follow and assess you.
Ask lots of questions. You are not expected to be able to just fly this without
interacting with your interviewer: treat them as a peer with whom you are
working through the design. If you are making an assumption (that you're aware
of), state it clearly and ask the interviewer if they'd like you to modify it.
Decomposition
Don't attack the problem as a monolith. As soon as you've clarified the initial
design parameters with the interviewer, think about the "relatively
independent" elements of a system that could meet the design goals and sketch
them out on the board.
In large-scale designs, this often suggests appropriate (initial) division of
the solution into
services which
can be designed independently, deriving their design parameters from those of
the overall problem.
Having sketched something, look over it critically and discuss it with your
interviewer: is there any major part of the original requirements that you
haven't addressed? Anything more loosely or tightly coupled than it should be?
Then, you can ask your interviewer which element they'd like you to tackle
first.
Estimation
One of the things your interviewer will be looking for is how you handle
concrete elements of the design. This is often about e.g. how many machines you
are going to need for some sub-service given the design parameters, or what
volume of data you expect to have in flight or at rest at any given time.
So you need to be ready to make estimates and do some simple arithmetic. If
it's not something you've often done, try taking "latency numbers every
programmer should
know" and
applying them to a problem or system you know well. See how the theory
compares to your practical experience. :o)
You might enjoy working through "computers are
fast" by Julia Evans and Kamal Marhubi
to sharpen your intuitions.
Back-of-the-envelope calculation like this helps constrain the solution space
and gives you a clearer idea of what might work. Note that an estimate can be
quite broad and remain useful: your objective is to determine "is this even
practical" rather than get (nearly) exact numbers.
Elements
There are some fundamental things we need to keep in mind when designing a
system distributed across multiple machines, and becoming familiar with them
should help you navigate the problem domain.
Jeff Hodges' notes on distributed systems for young
bloods
covers many of these and is worth internalizing. My own talk "Designing for
Brobdingnag" also
looks at building blocks and patterns in large-scale systems design and
includes a set of further resources on the last page of notes.
This is a big area, but in order to tackle a large-scale design it will help to
have at least some idea of your options for:
Mocks
If you have access to someone who runs interviews like this (and doesn't have a
conflict of interest), ask them to help you by running a mock interview & then
writing up
- feedback as though for an interview process and
- specific notes you can use to improve.
Psychology
Junior candidates sometimes get wigged out by these interviews and lock up. The
failure mode here is expecting too much of yourself: the interviewer knows your
experience and background (they've read your CV), so will already have a good
idea of the level they can expect. It's their job to appropriately assess the
discussion relative to your experience. So do your best, make a good stab at
the problem (see "Decomposition" above), try to have a good time, and above all
don't compare yourself to an "ideal, more experienced you".
Conversely, if you're a senior candidate with relevant domain knowledge, the
interviewer is justified in expecting a lot out of the discussion, and you may
find them digging pretty deep. Don't be shy about going into excruciating
design details if that's where the interviewer wants to go. They're trying to
assess your limits, and to get into concrete specifics: a sometime problem with
senior candidates is that they adeptly handwave these. :o)