Preparation + tips for the System design interviews

The system design interview is standard for Senior+ software engineer candidates. It often even holds more weight than the coding interview.

How does one do well in a system design round?  A lot of sweat and failures went into me figuring out what really matters and what doesn’t. My current preparation strategy, successfully applied in 2023 job search cycles included the following elements:

(A) Work through a great System Design course,
(B) Sharpen the story-telling skills,
(C) Do lots of practice,
(D) Omit what doesn’t help.

Let’s discuss them in detail.

(A) Several paid system design courses are currently available, but not all of them are equally good. Common pitfalls are going into too much detail + reproducing the actual system instead of making generic design choices. I loved the first iteration of “Grokking the System Design” course on educative.io, but the current 2023 iteration suffers from the above pitfalls. “System Design Interview” guide by Alex Xu, on the other hand, is concise and to the point.

(B) System design interview is all about telling a story. First, you single in on a story line by asking clarifying questions. Then, you methodically add the necessary components tying them to the story line. For example: “We send notifications to users based on their subscriptions. Therefore, we need a subscription service to capture user preferences.” Don’t forget character development: “Red riding hood didn’t have much money, but she didn’t need to maintain foreign key relationships and had a simple schema. Therefore, she went for MongoDB instead of MariaDB to store data about her trips through the forest.” Do write your story down alongside drawing the diagram.

(C) A good storyteller is made and not born. It does help to some extent to listen to the others explaining their design (https://www.youtube.com/@SystemDesignInterview and https://www.youtube.com/@TechDummiesNarendraL are especially good). However, the main benefit comes from you doing it. Good news: there are only about ~30 distinct system design problems. Given sufficient time, one can implement them all and write a story for each. Do maintain your library of those designs, e.g. with draw.io diagrams stored in Google drive. Bad news: story-telling skills atrophy without practice. Redo at least some of those designs before each interview cycle.

(D) I found some pieces traditionally included in the study guides to be almost never needed. First, you don’t need to draw many boxes on the path from the client to the target microservice. A single box encapsulating Load Balancer + API gateway + GraphQL API is sufficient. Going into too much detail early on will easily derail the interview.

Second, doing scale estimates is often counterproductive to telling a story. Just make sure to create a scalable design + mention the scalability.

I started omitting the API design. The list of actions supported by the target system is more general (e.g. poll against a 3rd party service is not an API) and covers the APIs very well too.

How to prepare for the Coding interviews.

How does one do well in the coding interviews? The best results are achieved with a systematic approach:

(A) learn and review the fundamentals,
(B) work through common algorithms and their variations,
(C) do targeted practice,
(D) nail the other pieces.

What do these involve? Here is my take from my coding interviews in early 2023.

(A) How does one learn the fundamentals? 
Learn the “Algorithms” from Sedgewick and Wayne. A combination of the classic book and the  Coursera courses (part I and II) is perfect for building a solid foundation from scratch.
A shorter and a very applied resource is the Data Structures and Algorithms (DSA) course on Leetcode https://tinyurl.com/LEETDSA. Well worth the money.

(B) How does one source and work through common algorithms and their variations?
The aforementioned DSA course on Leetcode is truly amazing. Its text format is the best for reviewing right before the interviews. The variations of the common algorithms are mostly sourced by working through reference problems. Do write your own implementations for several reference problems per topic to have a very clear picture of how you will implement it in an interview. Figure out all decision points, e.g. recursive DFS for backtracking, BFS for shortest path, return type vs parameters for tree traversal, where and how you mark the visited graph nodes, TreeSet vs PriorityQueue usage in Java, your implementation for Tries and Disjoint Sets. Identify easy-to-implement solutions, which don’t sacrifice the time complexity.

Mastery of collections API for your language of choice really helps with correctness / clarity. computeIfAbsent, merge, remove(key, value), Map.of for Maps in Java save you time and debugging headaches.

Ironically, the array-based problems can be the simplest and the hardest. Learn array-specific algorithms like dynamically changing the iteration limits (LC 1326), forward + backward pass technique (LC 42).

(C) Solve at least 2 new medium / hard problems on Leetcode every day. Read through solutions to more problems. Leetcode premium enables access to the lists of problems marked by the company. Glassdoor provides some insight into coding problems for the smaller companies. I was “lucky” with both tools. Consistency is your friend here: don’t stop preparing till the day / time of your interview.

(D) The algorithm / implementation is only 50-70% of the score. Ever wondered why you wrote  a working solution in 10 minutes and got poor feedback? You probably missed out on the remaining 30-50%, which includes:

  • asking many clarifying questions, identifying and handling the edge cases,
  • talking through your intentions and major implementation parts,
  • correct time / space complexity,
  • modularity = utility methods / classes, no repeated code,
  • clean code = all constants defined, lines split into shorter pieces, cohesive parts split into methods (do read “Clean Code” book),
  • overall near production quality code.

Last but not least, you need to enjoy it, at least somewhat! Otherwise you’re going to be miserable in the process, will give up easily, and not realize your full potential.

How to prepare for the behavioral interview.

Almost every company hiring software engineers conducts a dedicated assessment of candidate soft skills known as a behavioral interview. Unlike coding and design interviews, the behavioral interviews have other names: “leadership skills”, “culture fit”, “just talking to the hiring manager – no need to prepare”. Except… you always need to prepare. Talking to Netflix too early in my 2023 interview cycle got me rejected even before the technical phone screen! 

How does one prepare? One needs to:

(A) Internalize the STAR method.
(B) Find a representative set of behavioral questions + leadership principles,
(C) Write down stories from professional life.
(D) Illustrate the questions with the stories.

(A) Interviewing the candidates or even asking hiring managers questions as a candidate I can immediately see the stark difference between the people who internalized the STAR method vs the ones who didn’t. The STAR method turns every example into a mini-story by setting the stage, describing what you did, and how it influenced the team / project / company. If the outcome is negative, then the learnings must be included as well.

(B) Where do you get those behavioral + leadership questions? The behavioral questions are quite generic and can be sourced even from non-technical prep guides. Over the years, I used “Knock’em Dead” series by Martin Yate. In turn, the most extensive set of leadership principles I’ve seen was written by Amazon https://www.amazon.jobs/en/principles. A sample Google search also turns up quite a bit of behavioral questions. My personal set contains ~100 in total.

(C) Remembering the stories and writing them with the STAR method is the most labor-intensive part. But the more stories, the better. With stories spanning a substantial breadth of situations, you are more likely to find answers to curve-balls questions like “Tell me about the time, when you made a product impact through others without being directly assigned to”. I personally identified 20 stories from Twitter + 14 stories from Bandwidth w/ 10 more from other employers and personal projects. Not all stories are good for the interview, as they might not project the target image (maybe you were burnt out and couldn’t finish the project), but I found the stories with the negative outcome and substantial learnings to be the most powerful. After all, the path to success is paved with failures.

(D) After the stories are written and the questions are sourced, it’s time to tie the two with a brief explanation of how the story illustrated the question. In his books Martin Yates also describes the image one needs to project. Make sure to select the stories supporting that image.

Maintaining the many-to-many relationship between the stories and the questions makes it easy to reconnect between them as needed + illustrate multiple questions with the same story. (Relational schema in real life!)

Good luck with your interviews!

Coding interviews as a proxy for SWE job performance

Coding interviews are administered by companies as a proxy for the future job performance of software engineering candidates. However, it is highly uncommon for a software engineer to be writing tree traversals and graph algorithms from scratch on the day job. The day job focuses more on correct business logic, good software design, and clean code with often incremental additions and improvements. So, are coding interviews a good proxy for job performance? My answer is still “yes”.

First, the coding interviews are deeply testing the project management and execution skills, which are the core to any software job. Preparation to the coding interviews is a project, which needs to be handled with care. The topics covered by the project: how to learn and practice the set of coding problems per company, how to gain a working knowledge of fundamentals and a muscle memory on how to apply them, how to be efficient with practice and review, and how to be consistent in your efforts. Great execution of this project invariably leads to stellar interview performance and shows that you can get things done.

Secondly, there are the elements of clean code and good software design, showcased and judged in the coding interviews. Executing the preparation project well often gives a candidate the confidence and the extra time to write clean well-encapsulated code. Doing these always impresses both your interviewer and your code reviewers on the day job: separating constants, splitting lines, splitting independent pieces of logic into their own methods, proper method naming.

In third, a new wave of coding interview practices and tools (e.g. CoderPad.io) encourages reaching correct business logic, which tests the debugging skills. Debugging is a critical part of a coder’s day job. Almost all companies in 2023 (apart from Google) want you to run your code and pass a basic set of test cases. It is very important to learn to quickly reverse engineer from an observed failure to a bug in your business logic, especially on the day job.

Fourth, software engineering is a team effort with collaboration and communication skills being as important as coding itself. Those soft skills are easily assessed during the interview. A structured approach of writing down the functional requirements, checking your algorithm against interviewer’s expectations, and discussing the implementation waypoints + the tradeoffs show, especially for the senior candidates, their clarity of thought, flexibility, stakeholder communication, and mentorship skills. You need to be great to work with.

So much to unpack! Did the text make you rethink your preparation strategy? Please, leave your thoughts in the comments.