Build and Debug a Dasher-to-Order Assignment Service, Then Prepare It for Production
Company: DoorDash
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
This onsite round is billed as debugging, but most of it is building. You receive starter code for a service that assigns dashers (delivery drivers) to orders. Some methods are left for you to implement, and one of the methods already written contains a minor bug. You complete the implementation, fix the bug, write your own tests, and finish by discussing what you would change to run the service in production.
The report does not reproduce the starter code or the exact constraints in its problem statement. For practice, assume the class exposes these operations:
- `add_dasher(dasher_id)` registers a dasher who is now available.
- `assign_order(order_id)` gives the order to an available dasher and returns that dasher's id, or returns `None` when nobody is free.
- `complete_order(order_id)` marks the order delivered and makes its dasher available again.
- `dasher_for_order(order_id)` and `order_for_dasher(dasher_id)` return the current assignment, or `None`.
Assume each dasher carries at most one order at a time, and the dasher who has been available the longest receives the next order.
### Clarifying Questions
- Are dasher ids dense integers handed out by this service (0, 1, 2, and so on), or opaque ids that come from another system?
- Are order ids similar, and roughly how many dashers and open orders must one instance hold?
- What should happen when an order is completed twice, or when an unknown order or dasher id is passed in: raise, ignore, or return a status?
- Is the class used from a single thread for this exercise, or must it be safe under concurrent calls?
### Part 1 — Implement the missing methods and choose the storage
Implement the operations above with constant-time work per call. When you write down the structure that stores assignments, the interviewer interrupts and asks why you chose it. Compare a list (array) and a hash map for storing assignments on time complexity, memory and simplicity, and say under which conditions each one is the better choice.
```hint Look at the keys
Ask what each lookup is keyed by and what values those keys can take.
```
#### What This Part Should Cover
- Correct constant-time implementations of assignment, completion and both lookups
- A fair list-versus-hash-map comparison grounded in the id scheme
- Longest-waiting-first dispatch without duplicates in the pool of free dashers
- Defending a choice under challenge, including conceding where the other option is better
### Part 2 — Find the bug and test the class
Treat the provided methods as untrusted. Explain how you would hunt for the defect in one of them, then write the tests you would add for the whole class, including the edge cases that tend to break assignment bookkeeping.
```hint What must stay true
Write down the relationships between the free pool and the two lookup directions that every operation must preserve, then look for a call sequence that breaks one.
```
#### What This Part Should Cover
- Invariants tying the pool of free dashers and both mappings together
- Tests for the normal flow, an empty pool, repeated or unknown calls, and dispatch order
- A systematic way to narrow down a bug in code you did not write
- A minimal fix plus a regression test
### Part 3 — Prepare it for production
In the last part of the round the interviewer asks what you would do differently to deploy this as a real service, and how it would scale, at a high level.
```hint Many copies, one truth
Consider what breaks when two copies of this class run on different machines and both try to hand out the same free dasher.
```
#### What This Part Should Cover
- Moving state into a shared store, and how the chosen data structure maps onto it
- Atomic assignment, so that one dasher never receives two orders under concurrency
- Partitioning, durability and recovery after a crash
- Operational signals worth monitoring
### What a Strong Answer Covers
- Working code with clear method boundaries, plus the candidate's own tests
- A storage choice tied to the id scheme and honestly revisited when challenged
- Invariant-driven debugging rather than trial and error
- A production plan that covers concurrency, persistence and scaling without over-engineering
- Reasoning narrated throughout, including edge cases
### Follow-up Questions
- Dashers can now carry up to two orders at once. Which structures change, and how?
- Orders should go to the nearest available dasher instead of the longest-waiting one. What replaces the queue?
- A dasher goes offline while holding an order. How do you detect it and reassign the order?
- After a dispute, support needs to know who held an order and when. What would you record?
Overview: A DoorDash onsite exercise to finish and debug starter code for a service that assigns delivery drivers to orders. It tests constant-time bookkeeping, defending a list versus hash map storage choice, invariant-based testing, and how to make the service safe and scalable in production.
Read the full DoorDash Software Engineer interview experience this question came from