Start by clarifying requirements and constraints, then describe the core data structures: a hash map for O(1) access and a doubly linked list for LRU ordering, with each entry storing a TTL timestamp. Explain how expiration is handled lazily on access and proactively during eviction, ensuring expired entries are never returned and are evicted before valid LRU entries.
Pro tip: Mention that using a steady clock (e.g., std::chrono::steady_clock) avoids issues with system time changes, and consider discussing trade-offs between lazy and active expiration.
Ask about expected cache size, TTL precision, thread-safety needs, and whether TTL is per-entry or global. Confirm that expired entries must be removed before LRU eviction.
Propose a hash map (unordered_map) mapping keys to nodes in a doubly linked list. Each node stores key, value, TTL timestamp, and pointers for list operations. The list maintains LRU order (most recently used at front).
For get: check if key exists and if entry is expired; if expired, remove it and return miss; else move node to front and return value. For put: if key exists, update value and TTL and move to front; else insert new node at front, and if capacity exceeded, evict.
During eviction, first scan the list from the back (LRU end) to remove any expired entries. If still over capacity, remove the least recently used valid entry. Also, consider periodic cleanup or lazy removal on access.
Explain that get and put are O(1) average due to hash map and list operations. Discuss trade-offs: lazy expiration may leave expired entries until accessed, but proactive eviction ensures capacity is freed. Mention potential need for synchronization if thread-safe.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.