PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates the ability to design efficient in-memory data structures and caching mechanisms, focusing on core key-value operations, eviction behavior, and performance constraints.

  • medium
  • Lyft
  • Coding & Algorithms
  • Software Engineer

Implement Cache and Key-Value Store

Company: Lyft

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

The interview report mentions coding tasks similar to the following: 1. **Bounded cache** Implement a cache with a fixed capacity. Support: - `get(key)` returning the stored value or a not-found result - `put(key, value)` inserting or updating a key Any successful `get` or `put` should make the key the most recently used item. If inserting a new key would exceed capacity, evict the least recently used key. Target `O(1)` average time for each operation. 2. **In-memory key-value store** Implement a simple in-memory key-value store supporting: - `put(key, value)` - `get(key)` - `delete(key)` After completing one working solution, discuss or implement a second valid approach with different trade-offs, and explain the advantages and disadvantages of each design.

Quick Answer: This question evaluates the ability to design efficient in-memory data structures and caching mechanisms, focusing on core key-value operations, eviction behavior, and performance constraints.

Part 1: Design an LRU Bounded Cache

Implement a fixed-capacity cache with Least Recently Used eviction. You must process a sequence of operations and return the results of all get operations in order. Supported operations are ('put', key, value) to insert or update a key, and ('get', key) to read a value. Any successful get and every put make that key the most recently used item. If inserting a new key would exceed capacity, evict the least recently used key first. Return -1 for a get on a missing key. Do not use collections.OrderedDict or functools.lru_cache for the core logic.

Constraints

  • 0 <= capacity <= 100000
  • 0 <= len(operations) <= 200000
  • Each operation is either ('put', key, value) or ('get', key)
  • -10^9 <= key, value <= 10^9

Examples

Input: (2, [('put', 1, 10), ('put', 2, 20), ('get', 1), ('put', 3, 30), ('get', 2), ('put', 1, 15), ('get', 1), ('get', 3)])

Expected Output: [10, -1, 15, 30]

Explanation: After get(1), key 1 becomes most recent, so putting key 3 evicts key 2. Updating key 1 changes its value to 15 and keeps it recent.

Input: (0, [('put', 1, 1), ('get', 1), ('put', 2, 2), ('get', 2)])

Expected Output: [-1, -1]

Explanation: Edge case: capacity is 0, so the cache can never store anything.

Input: (1, [('put', 5, 50), ('put', 5, 55), ('get', 5), ('put', 6, 60), ('get', 5), ('get', 6)])

Expected Output: [55, -1, 60]

Explanation: Updating an existing key should not evict it. When key 6 is inserted into a full cache of size 1, key 5 is evicted.

Input: (3, [])

Expected Output: []

Explanation: Edge case: no operations means no output.

Hints

  1. A hash map can give O(1) access to cache entries by key, but you also need O(1) updates to recency order.
  2. A doubly linked list with dummy head and tail nodes is a common way to move items to the front and remove the least recently used item in O(1).

Part 2: Build an In-Memory Key-Value Store

Implement a simple in-memory key-value store for string keys and integer values. Process a sequence of operations and return the outputs of all get and delete operations. Supported operations are ('put', key, value), ('get', key), and ('delete', key). For the coding part, implement the store from scratch using a hash table with separate chaining and resizing; do not use Python's built-in dict as the main storage structure. Return None for a missing get, and return True or False for delete depending on whether the key existed. Follow-up discussion: compare this design with a second valid approach such as keeping entries in a sorted list and using binary search. A hash table gives average O(1) operations but needs collision handling and does not keep keys ordered; a sorted list gives O(log n) lookup and ordered traversal, but O(n) insertion and deletion.

Constraints

  • 0 <= len(operations) <= 200000
  • Each key is a non-empty string with length <= 100
  • -10^9 <= value <= 10^9
  • Each operation is one of ('put', key, value), ('get', key), or ('delete', key)

Examples

Input: ([('put', 'a', 1), ('put', 'b', 2), ('get', 'a'), ('put', 'a', 3), ('get', 'a'), ('delete', 'b'), ('get', 'b'), ('delete', 'x')],)

Expected Output: [1, 3, True, None, False]

Explanation: Basic insert, update, lookup, successful delete, missing lookup, and failed delete.

Input: ([],)

Expected Output: []

Explanation: Edge case: no operations.

Input: ([('delete', 'ghost'), ('put', 'ghost', 7), ('get', 'ghost'), ('delete', 'ghost'), ('get', 'ghost'), ('delete', 'ghost')],)

Expected Output: [False, 7, True, None, False]

Explanation: Deleting a missing key returns False. After deletion, later get returns None.

Input: ([('put', 'k0', 0), ('put', 'k1', 1), ('put', 'k2', 2), ('put', 'k3', 3), ('put', 'k4', 4), ('put', 'k5', 5), ('put', 'k6', 6), ('get', 'k6'), ('get', 'k0'), ('delete', 'k3'), ('get', 'k3')],)

Expected Output: [6, 0, True, None]

Explanation: Several inserts force the table to handle more entries and still return correct values after updates and deletion.

Hints

  1. Use an array of buckets, where each bucket stores a small list of (key, value) pairs.
  2. If too many items are stored relative to the number of buckets, resize and rehash all existing entries to keep average operations fast.
Last updated: Apr 27, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement Grid Spread and Transactional Store - Lyft (hard)
  • Assign Minimum Workers to Jobs - Lyft (medium)
  • Solve substring and worker assignment - Lyft (medium)
  • Implement command-driven in-memory key-value database - Lyft (Medium)
  • Implement pagination and a time-versioned key-value store - Lyft (Medium)