← Lyft Interview Insights

Lyft·Software Engineer·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
May 2026

Summary

Lyft software engineer coding round, two questions back to back. Nothing too exotic but the second one had a twist I wasn't expecting where they wanted you to actually compare two designs out loud instead of just picking one and moving on.

Questions Asked (2)

Q1

Implement an LRU cache with a fixed capacity. It should support get and put operations, both running in O(1) average time, with least-recently-used eviction when the cache is full.

Algorithms & Data Structures
Author's notes

Classic problem, I've done this before, and yet I still fumbled the part where you have to keep the doubly linked list and the hashmap in sync on every operation.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use a hash map for O(1) key lookup and a doubly linked list to maintain recency order, with the most recently used at the head and least recently used at the tail. On get, move the accessed node to the head; on put, insert or update at the head and evict the tail if capacity is exceeded.

Pro tip: Mention that you can use a sentinel head and tail to simplify edge cases, and clarify that O(1) is average for the hash map due to potential collisions. Also, discuss thread-safety if the cache might be accessed concurrently, as Lyft's services often require it.

1. Clarify requirements and constraints

Ask about capacity bounds, key/value types, thread-safety, and whether O(1) is strictly required. Confirm that eviction should remove the least recently used item when full.

2. Choose data structures

Select a hash map for O(1) key access and a doubly linked list for O(1) insertion, deletion, and reordering. Explain that the list maintains recency order.

3. Design the operations

Detail get: if key exists, move node to head and return value; else return -1. Detail put: if key exists, update value and move to head; else create node, add to head, and if capacity exceeded, remove tail node and delete from map.

4. Handle edge cases and optimizations

Use sentinel nodes to avoid null checks. Discuss handling capacity 0 or 1, and consider thread-safety with locks or concurrent data structures if needed.

5. Analyze complexity and test

State that both operations are O(1) average time and O(capacity) space. Walk through a small example to verify correctness, including eviction order.

Key Points to Mention

  • Hash map provides O(1) average lookup, but collisions can degrade to O(n) worst-case.
  • Doubly linked list allows O(1) removal and insertion, essential for maintaining recency order.
  • Sentinel head and tail nodes simplify insertion and deletion logic by avoiding null checks.
  • Eviction always removes the tail node (least recently used) when capacity is exceeded.
  • Thread-safety considerations: use locks or concurrent data structures if the cache is shared across threads.
  • Space complexity is O(capacity) for storing up to capacity entries.

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

Q2

Build a simple in-memory key-value store supporting put, get, and delete. Then propose and compare a second implementation with different trade-offs, explaining the pros and cons of each approach.

System DesignTechnical Trade-offs
Author's notes

This is the one that got me.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (e.g., thread safety, persistence, expected operations) and then implement a simple hash map-based store. For the second implementation, choose a contrasting approach like a log-structured store or a tree-based store, and compare them on performance, memory, and complexity. Conclude with trade-offs and when to use each.

Pro tip: Mention that real-world systems often combine approaches (e.g., LSM trees with in-memory memtables) and that the choice depends on workload characteristics like read/write ratio and latency requirements.

1. Clarify Requirements

Ask about expected operations, data size, concurrency, persistence, and performance goals to scope the problem.

2. Implement First Approach

Code a simple hash map-based key-value store with put, get, and delete, discussing its O(1) average time complexity.

3. Propose Second Approach

Choose a contrasting implementation, such as a balanced tree (e.g., red-black tree) or a log-structured store, and outline its structure.

4. Compare Trade-offs

Analyze both approaches on time complexity, memory usage, concurrency, persistence, and scalability.

5. Summarize and Recommend

Conclude with when each approach is preferable and mention hybrid solutions if relevant.

Key Points to Mention

  • Time complexity: hash map O(1) average vs. tree O(log n) for operations
  • Memory overhead: hash map may have higher overhead due to load factor and resizing; tree has pointer overhead
  • Concurrency: hash map can use fine-grained locking or concurrent variants; tree may require more complex locking
  • Persistence: log-structured store offers durability and write optimization; hash map is in-memory only
  • Scalability: hash map struggles with range queries; tree supports ordered operations
  • Real-world examples: Redis (hash map + other structures), LevelDB (LSM tree)

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