Home/Low-level design/LRU Cache

LRU Cache

Recency ownership and bounded cache state

Least recently used eviction couples a lookup table with a recency order. Hits and updates move one existing entry to the most recent end; misses do not invent recency. A cache entry is owned once even after repeated updates.

go
values := map[string]int{"offset": 0}
v, found := values["offset"]
fmt.Println(v, found) // zero remains a present value

A map plus doubly linked list can make lookup, refresh, and eviction O(1). A slice is a useful prototype but moving keys is linear. Capacity zero is a valid disabled cache. Read snapshots must not refresh entries. The Go variant uses an optional integer result and an explicit default argument, preserving the distinction between a cached zero and a miss.

Go models this service with a struct and pointer-receiver methods. Constructor functions return a pointer; validation failures return errors rather than panicking. Scalars in snapshot structs are copied by value. Maps, slices, and optional pointers still require detached copies when crossing the service boundary. Go maps do not have key iteration order; use ordered slices for ranked results. There are no threads, persistence, wall-clock reads, or external side effects in this exercise.

Put it into practice

Implement the exercise in a full-screen workspace, then run its tests.

Open practice
Next lessonRate Limiter