← DoorDash Interview Insights

DoorDash·Software Engineer·Onsite - System Design / Architecture·Senior

SeniorPrefer not to say
Apr 2026

Summary

DoorDash system design round for a software engineering role. The whole session was basically one big LRU cache question that kept expanding into concurrency territory, which I wasn't fully prepared for.

Questions Asked (3)

Q1

Design an in-memory LRU cache for a single machine. Walk through how you'd use a hash map and doubly linked list to achieve O(1) get and put, and explain how you handle capacity limits, eviction, and key updates.

Algorithms & Data StructuresSystem Design
Author's notes

I knew this one cold, or thought I did.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (capacity, thread-safety, eviction policy) and then describe the data structures: a hash map for O(1) key lookup and a doubly linked list to track recency. Explain how get and put operations manipulate the list and map to maintain O(1) time, and how eviction occurs when capacity is exceeded.

Pro tip: Mention that you would use a sentinel head and tail node to simplify edge cases in list manipulation, and discuss how you would make the cache thread-safe if needed (e.g., using locks or concurrent data structures).

1. Clarify Requirements

Ask about expected capacity, whether the cache needs to be thread-safe, and if there are any constraints on key/value types. Confirm that the eviction policy is LRU.

2. Design Data Structures

Propose a hash map (dictionary) that maps keys to nodes in a doubly linked list. The list maintains the order of usage, with the most recently used at the head and least recently used at the tail.

3. Implement get(key)

If the key exists, retrieve the node from the map, move it to the head of the list (mark as most recently used), and return its value. If not, return null or -1.

4. Implement put(key, value)

If the key exists, update its value and move the node to the head. If not, create a new node, add it to the head, and add to the map. If capacity is exceeded, remove the tail node (least recently used) from both the list and the map.

5. Analyze Complexity and Edge Cases

Explain that both get and put are O(1) because hash map operations are O(1) and list insertions/deletions are O(1) with direct node references. Discuss edge cases like updating an existing key, evicting when capacity is 1, and handling null values.

Key Points to Mention

  • Hash map provides O(1) access to nodes, and doubly linked list allows O(1) removal and insertion given a node reference.
  • Use of sentinel head and tail nodes to avoid null checks and simplify list operations.
  • Eviction policy: remove the least recently used item, which is the tail of the list (before sentinel).
  • Updating an existing key should also update its recency (move to head).
  • Thread-safety considerations: if needed, use a lock (e.g., synchronized methods) or a concurrent hash map with additional synchronization.
  • Time complexity: O(1) for both get and put; space complexity: O(capacity).

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Now make your LRU cache thread-safe. Compare global locking versus segmented or per-bucket locking, discuss readers-writer locks, and talk through lock-free approaches. How do you prevent race conditions and keep memory safe under concurrency?

System DesignTechnical Trade-offs
Author's notes

This is where things got uncomfortable.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the concurrency requirements and the expected read/write ratio, then systematically compare locking strategies (global, segmented, readers-writer) and lock-free approaches, highlighting trade-offs in throughput, latency, and complexity. Conclude with a recommendation tailored to the scenario, emphasizing race condition prevention and memory safety.

Pro tip: Mention that you would measure contention and choose the simplest correct solution first, then optimize based on profiling—this shows pragmatism and avoids over-engineering.

1. Clarify requirements and constraints

Ask about expected read/write ratio, latency SLAs, and whether the cache is in-memory or distributed. This determines the appropriate concurrency strategy.

2. Compare locking strategies

Discuss global locking (simple but low concurrency), segmented/per-bucket locking (higher concurrency with more complexity), and readers-writer locks (good for read-heavy workloads but writer starvation risk).

3. Explore lock-free approaches

Explain lock-free techniques like atomic operations, CAS loops, and concurrent data structures (e.g., ConcurrentHashMap in Java). Highlight challenges like ABA problem and memory reclamation.

4. Address race conditions and memory safety

Detail how to prevent races via atomicity, ordering, and visibility (e.g., using volatile, memory barriers). Discuss safe memory reclamation (e.g., hazard pointers, epoch-based reclamation) to avoid use-after-free.

5. Recommend and justify

Choose a strategy based on trade-offs, e.g., segmented locking with read-write locks for read-heavy workloads, and mention fallback to global lock for simplicity if contention is low.

Key Points to Mention

  • Global locking: simple but serializes all operations, limiting throughput.
  • Segmented/per-bucket locking: reduces contention by partitioning the cache, but requires careful hash distribution and resizing.
  • Readers-writer locks: allow concurrent reads but can cause writer starvation; consider fair implementations.
  • Lock-free approaches: use atomic CAS and concurrent data structures, but complex and may not always outperform locks.
  • Race condition prevention: ensure atomicity of compound operations (e.g., get-and-update) and use memory barriers for visibility.
  • Memory safety: employ safe memory reclamation techniques (hazard pointers, RCU) to avoid use-after-free in lock-free designs.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

What are the time and space complexity tradeoffs of your design, and what are the major pitfalls someone might run into when implementing this in production?

System DesignTechnical Trade-offs
Author's notes

Felt more comfortable here.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clearly stating the time and space complexity of your design's core operations, then discuss the tradeoffs between different approaches you considered. Finally, highlight production pitfalls such as scalability bottlenecks, data consistency issues, and operational overhead, and explain how you would mitigate them.

Pro tip: Tie the tradeoffs back to DoorDash's specific scale and latency requirements—showing you understand their business context makes your answer stand out. Also, mention monitoring and observability as key to catching production issues early.

1. State Complexities

Clearly articulate the time and space complexity of your design's key operations (e.g., read/write, search) and explain how you arrived at those bounds.

2. Discuss Tradeoffs

Compare alternative designs (e.g., indexing vs. no indexing, caching vs. no caching) and explain why you chose your approach, focusing on the balance between time and space.

3. Identify Production Pitfalls

List major pitfalls such as hot partitions, thundering herd, data skew, network latency, and failure modes, and describe how they manifest in production.

4. Propose Mitigations

For each pitfall, suggest concrete mitigation strategies (e.g., sharding, rate limiting, circuit breakers, backpressure) and explain their impact on complexity.

5. Tie to Business Context

Relate your choices to DoorDash's scale, latency requirements, and cost constraints, showing that you understand the practical implications for their system.

Key Points to Mention

  • Time and space complexity of core operations (e.g., O(1) vs O(log n) vs O(n))
  • Tradeoffs between different data structures or algorithms (e.g., hash maps vs trees, caching vs no caching)
  • Scalability bottlenecks such as hot partitions, data skew, and single points of failure
  • Consistency and availability tradeoffs (CAP theorem) and their impact on user experience
  • Operational overhead: monitoring, alerting, deployment, and rollback strategies
  • Cost implications: storage, compute, and network costs at scale

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.