The technical interview, is a crucial component of the interview loop for software engineers, that gauges the candidate’s ability to perform in the role under consideration. The skills required to successfully complete a technical interview at DoorDash include demonstrable knowledge in data structures and algorithms, and the ability to effectively communicate and problem solve.
Typically, an experienced engineer takes the role of interviewer, assessing the candidate’s strengths and weaknesses. While the technical interview may seem challenging, it’s important to remember that the interviewer’s honest goal is to find someone who can be a great contributor to a team working on projects that fulfill the company’s business goals.
As a member of a small team of engineers here at DoorDash who contribute to and vet the questions asked in our technical interviews, as well as an active interviewer, I’ll highlight some key pieces of our technical interview. Ultimately, we want excellent candidates who succeed in every part of our interview loop, find a place at DoorDash, and build a highly satisfying career.
Interviews are an attempt to make the best of a difficult situation. In a few short hours we need to figure out if a candidate can successfully contribute to their team and the company over what might end up being many years. As Lokesh Bisht, the Director of our Customer Analytics team, pointed out in his article on the data science interview, the technical interview is a means to mitigate the cost of bad hires by taking a snapshot of some of the candidate’s skills. Our interview questions need to be well-considered to give an unbiased assessment.
Interviewers can have different styles and expectations on what they expect to see in a successful candidate. By highlighting the general structure and process of our technical interview, we want to give candidates the best possible preparation for success.
Data structures and algorithms
Many tech companies stack their interviews with questions related to specific algorithms and data structures, and DoorDash is no different. Candidates should feel comfortable using, as well as understanding, the key differences and applications of the following data structures:
- Directed and undirected
- Cyclic and acyclic
- BST and BT (DAGs)
- Hash maps
This list doesn’t imply other data structures won’t be included in the interview, it just means the ones listed above tend to be more commonly covered. I also highly recommend candidates be well-versed with the worst, best, and average runtime complexities for inserting, removing, and finding elements in all data structures they feel comfortable using.
Candidates should also be well-versed in the following algorithms:
- Tree traversals
- Linked lists: being comfortable with manipulating a list and detecting edge cases
- Recursion: being able to think recursively
- Divide and conquer
- Base case(s) and recursive (inductive) case(s)
- Tail recursion -> not expected, but encouraged
- Dynamic programming solutions to recursive questions (identifying overlapping subproblems and optimal substructure) -> not expected, but encouraged
- Search and sort:
- Common sorting algorithms (merge, insert, bubble, etc) -> not expected to memorize, but understanding when to use them is recommended
- Binary search
- General comfort in complex searches and sorts in above data structures
Subscribe for weekly updates
The concept of having a communicative approach to solving problems isn’t always emphasized in academic settings. However, we use communication as a metric in determining the success of a candidate due to the importance of teamwork in our engineering organization. Below are some key points to keep in mind.
Keep the interviewer involved
Ideally, we want the candidate to complete the problem and all associated subproblems successfully without any help from the interviewer. However, we encourage candidates to keep the interviewer informed about what they are trying to accomplish. There’s no need for a constant, ongoing conversation, but it is important to describe key decision steps while answering a question.
Here are some examples:
- “We can use a stack for this solution because...”
- “We can use an in-order tree traversal for this question because…”
- “I may have missed some edge cases, let me take a closer look at my solution.”
- “I can think of a solution in O(N2) time doing X, but I think we can have a linear solution here. I’d like to take a minute to think through an approach.”
I wouldn’t expect a candidate to talk while coding or pseudocoding their solution (in fact, I find it hard to think and talk at the same time, so I prefer silence during those parts of the interview). Candidates should take time to collect their thoughts, but make sure the interviewer is following the process at key points, such as:
- Clarifying questions after being given the problem
- The approach to solving the problem
- Identifying potential flaws in the approach
- Changing direction to a new approach
The interviewer is there to gently guide the candidate to a final solution and to help them score the most points possible for that candidate’s knowledge and skill base.
It’s okay to think
Far too often technical interview tutorials and guides suggest that interviews consider long moments of silence as a negative, and can lead to losing points. There is absolutely nothing wrong with taking time to think about the interview question and in constructing a coherent solution. I’d encourage candidates to take a one or two minute pause in situations which warrant critical thinking.
Don’t expect constant feedback when solving a problem. An interviewer’s job is to help candidates stay on course toward a working solution, but only if they need it. Generally, candidates will lose points if the interviewer needs to steer them back towards a solution or give them large hints on something they missed. We train our interviewers to only step in when they believe the candidate has a higher chance of scoring better with their intervention.
Solving the question
Regardless of a candidate’s approach to solving technical interview questions, there are some steps that should usually be taken.
DoorDash engineers often find themselves solving questions with many unknowns and few clear paths to move forward. The interview process helps us assess this skill in candidates, which is needed to be successful here. We often make questions ambiguous on purpose, and it is the candidate’s responsibility to remove any ambiguity. A candidate may miss edge cases if they don’t clarify the problem.
In this linked example question, there are a few constraints specifically left out of the question description. If they aren’t accounted for in the solution, there may be some edge cases missed, resulting in a lower score.
In general I advise not to go with a brute force approach as a final solution. In every case where there is an optimal solution with significant complexity improvement, a typical brute force solution will result in a low score for the problem.
Constructing a solution
A perfect solution doesn’t need to be achieved instantly. Take some time to come up with a general approach and iterate on top of it until it works. I recommend creating a working solution and then running through a test case with the interviewer to find any bugs. We highly value debugging skills, and candidates won’t lose any points if they are able to find their own mistakes and rectify them without interviewer intervention. After coming up with a good solution, candidates can move forward with runtime analysis and follow-up questions (which are very common in our interviews).
Candidates should have a strong understanding of runtime and in-memory complexities for their approach. In general, candidates should be able to clearly explain every step of the solution and why they chose the approach. For example, why use a linked list in a solution instead of an array?
Although not expected for all questions, some questions will ask candidates to write their own unit tests. Be aware of industry standard testing practices and be able to construct meaningful, yet concise unit tests. Show clear thought and understanding in each unit test, avoiding repetition while still giving confidence to the solution.
I recommend books such as Clean Code and Code Complete 2 for theoretical knowledge on unit tests as well as other standard software engineering practices.
Preparation is key to tackling the technical interview. The ideal situation for candidates is to find themselves solving a problem very similar to problems they previously solved.
Consider the following resources:
- Data structure/algorithms practice tools, such as LeetCode
- One-on-one interview preparation tools, such as interviewing.io
- General flow and success in interviews, such as Cracking the Coding Interview
A great way to prepare for the technical interview involves practicing with a friend and on a whiteboard or remotely using a shared screen. Working out a sample problem in this manner will make the actual interview situation more familiar.
In addition to the general success of solving the questions asked, there are three main categories considered when assessing a candidate’s success:
- Understands common data structures and when to apply them
- Can perform time and space complexity analysis
- Arrives at correct and optimal (in time and space) solution
- Thinks about good abstractions for solving the problem at hand
- Writes well-organized code, with correct syntax, in their language of choice (there is no point difference for choice of language)
- Effectively tests and debugs code
- Asks clarifying questions to eliminate ambiguity
- Explains their thought process when coming up with a solution
- Receives feedback well, without getting overly defensive
While the above focuses on the algorithm/data structure portion of our technical interview, there are other modules of our interview loop. Which modules a candidate encounters depends on the nature and seniority level of the role the candidate is being interviewed for.
This part of the interview assesses whether a candidate can exemplify our DoorDash values, such as exhibiting a bias for action, getting 1% better every day, and making room at the table. Every candidate goes through this interview, which involves general questions about past challenges and successes, how they would cope with certain theoretical situations, and their career intentions. The candidate will also be afforded the opportunity to ask questions at the end of this interview to assess whether DoorDash feels like a place where they can do some of the best work of their career.
The system design interview is typically given to industry-level, as opposed to entry-level, candidates (L4-plus), and can be a major tool in assessing the candidate’s skill level. It is generally a more difficult interview to practice for. The question assesses a candidate’s ability to build a scalable system with well-thought-out design decisions. These questions are often left intentionally vague and use a real setting. This interview usually gives a deep-dive into one or two specific pieces of the design while taking a shallower glance at the other pieces.
To prepare, candidates are encouraged to research and reverse engineer common systems within their domain. Frontend candidates, for example, can practice using popular applications such as Gmail or DoorDash. Backend engineers can deep dive into specific areas within large systems such as Twitter or a messenger service.
The backend system design question is often grouped together with domain knowledge, but may also be separated into two rounds depending on which team has the open role. Chao Li, a backend engineer on our Ads and Promotions team, shares his thoughts below:
“This interview usually focuses on a couple of areas, with increased difficulty levels:
- The first part, which most candidates can get through with little difficulty, involves a breakdown of the problem requirements and suggesting basic components. This area requires steps such as understanding the problem statement, translating requirements into technical components, breaking down the data model, suggesting an API, and coming up with a database schema.
- Candidates should be prepared to dive deep into each component and talk about how different situations are handled. Typical examples include how a payment component handles double writes, or how a distributed queue handles surges and failures.
- Be ready to discuss details about their approach. For example, if a candidate mentioned using a message queue to solve the problem, we would expect justification for why a message queue is the best solution, what are the trade-offs for the specific product versus other products (i.e., AWS Kinesis over an on-premises Kafka cluster), what were some other potential solutions, what are the pros and cons, and what are the failure scenarios for this solution.
- The last part of this interview concerns scalability. We assess whether a candidate knows how to get from zero to a 1x solution, as well as a 1x to a 10x solution. In particular, the candidate should be able to suggest how the tech stack and architecture will need to evolve to achieve scale.“
The iOS interview, commonly referred to as the architecture interview, will dive into application design, which will later be implemented in a coding round. Tom Taylor, an engineer on DoorDash’s iOS platform team, shares his thoughts below:
“During the architectural interview, candidates are given a feature and design and expected to whiteboard an iOS system. No coding is required for this interview; we mainly talk about elements at a class, struct, or interface level. While we do not require every candidate to be expert software architects, it is important when designing a feature to consider testing, scalability, data flow, and techniques for managing code when working on a larger codebase. Also, candidates should understand how to design a system without relying on third-party libraries.”
The Android interview usually involves a dedicated portion to go over system design. As preparation, we recommend going through some common apps and being able to give a deep dive into, or reverse engineer, them. The question may not be to design an app doing a specific task, but could also involve designing a library that an app may use. For example, candidates may be asked to design an image loading library similar to Glide.
It’s important to have strong fundamentals, such as threading, caching, memory and battery consumption, network usage, scalability, app persistence, and interaction with the operating system to succeed in this interview.
This interview will typically go through developing a web application. Michael Sitter, tech lead for DoorDash’s Web Platform team, shares his thoughts below:
“We don't expect candidates to necessarily be able to describe solutions for scalability and fault tolerance, but the best candidates are able to include those qualities in their designs. Instead, we try to focus on things like the contracts between the web/client applications and the backend APIs. What data do we need to collect? How should the client app respond to various API responses? Synchronous or asynchronous? How do we handle cases where we have high or low latency?”
“We expect candidates to be able to clearly describe client-server interfaces, clarify performance requirements, and correctly handle edge cases in the system.”
The domain knowledge interviews test the candidate’s fundamentals in the platform they are applying for. They should be comfortable with basic terminology and applications within the given domain as well as demonstrate a strong understanding of the infrastructure they are using. This interview involves a deep dive into an example project in the domain area. We usually conduct this interview in a question-and-answer format, and it is occasionally combined with the system design interview. iOS candidates normally don’t go through this interview in their loop, as it is replaced with a debugging round explained in the Coding section below.
Some interview loops contain a coding round. This module usually follows a take-home project involving a real-world application and will ask the candidate to add or change a feature within their already built application. This interview is used to assess a candidate's proficiency in the language and platform they are working in as well as how they architect their code.
The iOS interview loop differs slightly from other platforms. Candidates will forgo the domain knowledge and coding interviews described above and instead go through two modified coding rounds. In the first round, the candidate will implement the design they have built in the system design/architecture interview. During the second round, they will receive an application in xCode with some errors and flaws, and are expected to debug the codebase into a working solution.
There is also no take-home project during iOS interviews. Instead, we ask candidates to participate in a technical phone screen where they will work with an iOS engineer in finishing a partially completed application. This module is done prior to any on-site interviews.
Interviewing can be an unnerving and sometimes challenging experience, but it gets much easier through repetition and practice. Along with a skill evaluation, however, candidates also get a chance to see how their prospective colleagues think and communicate as well as a glimpse into the types of problems we solve at DoorDash.
I hope to provide ample preparation materials in order to mitigate against some of the biases that come with interviewing and to let the process highlight the prospective connection between the interviewee and the company. I wish nothing but success to any future candidates and I hope we can be a great environment for candidates to advance their careers.
If you are interested in building a logistics platform that supports local economies, consider joining our team!
Header photo by Fotis Fotopoulos on Unsplash.