The get and put parts are easy enough to describe but the O(1) eviction is where you have to actually think.
Start by clarifying requirements (capacity, eviction policy, thread-safety) and then propose a design using a hash map and a doubly linked list to achieve O(1) operations. Explain how the hash map provides direct access to nodes, while the linked list maintains recency order, and walk through the get and put operations step by step.
Pro tip: Mention that you would use a doubly linked list with sentinel nodes to simplify edge cases, and discuss how to make the cache thread-safe (e.g., using locks or concurrent data structures) since Google often cares about concurrency.
Ask about capacity, eviction policy (LRU), expected operation mix, and whether thread-safety is required. Confirm that both get and put must be O(1) average time.
Suggest using a hash map (for O(1) key lookup) and a doubly linked list (to track recency order). Explain that the hash map stores key -> node references, and the linked list stores nodes with key-value pairs.
For get: if key exists, move the node to the front (most recently used) and return value; else return -1. For put: if key exists, update value and move to front; else create new node, add to front, and if capacity exceeded, remove the least recently used node (tail) and delete its key from the hash map.
Discuss edge cases like capacity 0 or 1, and how to handle null values. If thread-safety is needed, mention using a mutex or a concurrent hash map with atomic operations, or a lock-free approach.
Confirm that both operations are O(1) average time due to hash map and linked list operations. Discuss trade-offs: memory overhead of pointers, potential for hash collisions, and alternative designs (e.g., using an array with timestamps but that would be O(n)).
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.