If I had to pick only one interview method to assess engineers, it would likely be system design. That's not because coding, behavioural, role-play or case interviews are less valuable – they are revealing and help to build a bigger picture of the candidate. If you have resources to create a process that will support diversity, a fair framework to avoid bias, and the time, people and training to run a multi-stage process it will likely reduce the propensity of false positives. Nonetheless, if I were constrained to pick just one, I'd pick system design.
I find the mix between subjective and objective criteria that the system design interview imposes very useful for assessing candidates from multiple angles. There is a reasonably well-set frame for technical assessment, but just coming up with a solid design is not necessarily a pass. Similarly, candidate behaviour has a vital role to play, but the lack of causal nexus and technical-ability can reveal lack of fit to the position quite clearly.
There's a lot of resources out there which are an excellent foundation for the more objective parts. I curated a few of my favourite ones in the appendix of this article. These deserve great focus when studying for an interview, as they are the most fundamental part of the assessment being made. However, having undergone some interviews recently and practicing it, I thought I'd write about a few points I have learned and that I believe can help on the subjective aspects of it, especially in regards to posture.
§Don't just communicate: collaborate with the interviewers
One of the things I find very helpful in technical interviews is turning it into collaboration rather than just an assessment. The role interviewers are trusted to play fundamentally is assessing whether a candidate is a good fit to be a colleague of theirs. I believe that when you achieve a collaborative atmosphere at the interview you are giving people a much better perspective to assess your fit fairly.
With that in mind, once the interviewer shares what the problem to be solved is, a technique which can help is rephrasing the objective in your own words. I find this helps to avoid situations where you presume understanding what is being asked. It is much better to clarify with the interviewer than design the right solution to the wrong problem. Ask questions as obvious as they can sound, and try to engage in gathering all the information you can before proceeding.
As the objective is better defined, it is essential to establish what is in scope and what is out. Narrowing down what are the scope boundaries for the interview problem will help you to focus on what matters the most for the design in question. Making compromises on scope early on will prevent you from spending the very little time you have on going deep in off-scope topics of the problem at hand.
When you infer information from what you are told, or when you reach to a conclusion voice your assumptions and conclusions. You need to bring your interviewers to see the problem from the angle that you are looking at to make a fair judgement if you are going off track and nudge you on the right direction if it needs to be.
Then, when working on the proposed solution, avoid turning the experience into a monologue by leaving spaces for feedback. Interviewers are usually fine to signal when you might be going off-track. Have them contribute to the discussion even if in a non-verbal way, regardless if it is about implications of the design decisions you are making and why, or if it is more specific such as whether you should split a component into two.
In summary, communication goes a very long way for technical interviews. Even further, actively seeking collaboration improves your chances of performing well in the interview, and also helps interviewers gauge whether they would like to work with you – and vice-versa.
§Go wide first and then deep afterwards
It is easy to go deep prematurely as design interview questions are unlikely to fit within the timespan available, conversely to a coding interview, for example, where the problem likely fits within the time available. Nobody will expect you to come up with the perfect solution for a system which is run by dozens, hundreds or even thousands of people – although ideally, you should have a rough sketch to solve the problem end-to-end.
As in real-life systems, the design will evolve. Done is usually better than perfect. Start simple before going complex by favouring extensibility rather than perfection. Put forward the most straightforward design which won't pose obvious scalability issues first, while keeping the interviewer informed of your strategy, and then as you cover the requirements, get into more in-depth optimisation.
A way I have found to frame the problem at the right level at the starting point is to put yourself in the shoes of the user of the system you are about to design. Basically, talk with the interviewer about the steps the user would take to use the product/system you are designing for the features in scope. Being mindful of the user's needs will help to clarify the characteristics of this system, for example, what are the capabilities which will need public-facing APIs, which components will have higher reads vs writes, or when to ebb on consistency over availability. Looking into the system from a user experience perspective usually hints what is fundamental and will help define a few whys further down the path.
Once you feel like you understood the whole picture, came up with a high-level design and have shown the interviewer you have a hold of the overall problem, pick the part which you are most comfortable with to go deep and explore it. Focus on your strengths rather than your areas for development. Most likely, the problem at hand has some exciting scale challenges for any discipline. Pick your favourite aspect of the problem that you can speak deeply of, regardless if it is client-side bandwidth optimisation, data model and partitioning, machine learning infra automation or whatever you want.
That said, resist the urge to get into the detail before you fully understand the problem. Attaining the conversation to motivations and expected outcomes first will help you make more assertive design decisions and make a few whys more evident to both you and the interviewer later.
§Talk about caveats and edge cases
What will happen if your system stops sending data to a downstream system? How do you notify upstream systems to rollback something which was mistakenly changed? How does the system work for the 99th percentile of your power users? These are all questions which can influence your design choices, so thinking of what could go wrong gives you either the opportunity to change it or to confirm that you made the right design decisions.
Especially in large scale distributed systems, you usually will have to optimise for specific characteristics. That inexorably introduces unwanted behaviours – which you need to be aware of to make the right decision. Talk about trade-offs you've made and why you chose an approach instead of all the other options you had.
Further, exploring failure scenarios and recovery options will show you understand the design that you have committed. This can get especially interesting when you can cover not only system failures but how users could abuse the system, which potential risks are introduced that you will have to accept, or even human error. When possible, talk about how you recover or prevent these from happening.
Talk about how to make things right when things go wrong. One example of this is a personal experience where I overestimated capacity in one interview – instead of going with 1GB storage for a free-tier product quota, I went with 1TB. I realised it later in the process, as storage and bandwidth started to feel absurd for the problem at hand with the volume the interviewer and I had committed to. After acknowledging something was wrong, I spoke about the steps I'd take to revert the mistake if this went live such as keeping users who signed up to the 1TB proposition with the benefits they paid for indefinitely, talking to teams responsible for advertising and intake about the mistake, and other damage control activities that could be done. I think this turned out to be an even more interesting conversation than it would be if I had calculated the right capacity at first.
In short, things will go wrong at some point – displaying readiness on walking the not-so-happy path will increase your confidence in your design choices, and if you made a wrong decision, you still have time to adapt and make it better or at least acknowledge it.
§Touch on adjacencies of the problem
Again, given the system design interview is extremely time-constrained, you need to be mindful of what you want to emphasise. Whilst it is great to have a narrow scope to work through, touching lightly on adjacent topics to the design itself can show even further breadth of knowledge. Here are some examples of subjects to cover, which might be off-scope but can increase the number of signals, thereby increasing your chances of performing well.
I believe most engineers appreciate that operating large scale systems is very hard. I personally like to cover operations, not only design. Especially at large companies, where you usually have dedicated infrastructure engineering functions, it is easy to take a lot of ops for granted. Briefly talking about subjects such as alerting, monitoring, tracing, observability can reveal problems on scaling a specific design.
Especially for highly regulated environments such as payments and abuse prevention, touching on security, compliance & regulatory constraints can be a plus. Some ideas of subjects to touch upon are data retention or data anonymisation for systems with personally identifiable information, or risk management by splitting components in different networks which are in scope for audits.
Maybe a subject more on the technical leadership or management side, design decisions will inherently dictate how teams will be mobilised for specific domains. A pretty large upside of microservices is making scaling independent – people and organisational design included. Talking about how the design will likely impact how you mobilise folks in the set of teams owning the design and showing awareness of scaling not only infra and systems but also organisations can spark engaging conversations.
My examples here are highly biased to my own experience, but making a short aside whilst you cover something within the scope of the interview can serve as an additional signal and increase the interviewer's confidence in you.
In closing, it is worth noting that all of these tips are based on my own experiences and preferences. Different organisations will focus on different things, and your best starting point is understanding the expectations of the company you are applying to. I believe incorporating the topics above to my posture when interviewing has helped me, and I hope it will help you too.
Below I've added a small appendix for some resources on the technical side of things. I hope you like it!
- Grokking the System Design Interview course by Design Gurus at educative.io;
- Designing Data-Intensive Applications book by Martin Kleppmann;
- System Design Primer by Donne Martin;
- High Scalability blog;
- How the Web Works by @vasanthk;
- SuccessInTech's YouTube channel;
- TechDummies' YouTube channel;
- How we've scaled Dropbox video;
- Amazon's DynamoDB paper;
- Google's MapReduce paper;
- Google's Hypertextual Web Search Engines paper;
- Google's GFS/Google File System paper;
- Facebook's Cassandra paper;
- Facebook's TAO, a social graph data store paper;