Loading...
Loading...
Browse 16 real-world technical and behavioral interview questions about Caching. Review scenarios, edge cases, and architectural best practices.
Production runs several worker processes, and each has its own interpreter, its own imported modules and therefore its own copy of that dictionary. Requests land on whichever worker is free, so a write in one is invisible to the others and every restart discards the lot. Use this wsgi asgi answer to show the decision, trade-off, and evidence rather than a memorised definition.
A cache stampede happens when one hot key expires and every concurrent miss rebuilds the same value. Let one request rebuild while the rest wait or serve stale, then prevent repeats with stale-while-revalidate, jittered TTLs and refresh-before-expiry. Use this caching answer to show the decision, trade-off, and evidence rather than a memorised definition.
Revoke once in the authorisation store, then propagate to the index ACLs, every cache holding text or results, any derived summaries and embeddings, and the conversation transcripts still carrying passages. Answers already delivered cannot be recalled, so the guarantee you offer is a bounded window rather than erasure.
Ask the index directly whether the old text is still there, because that single check splits the problem into change detection, queue or write failure, a retire step that left duplicate chunks, or a downstream cache. Then fix the reason you learned about it from a user rather than an alert.
A cynical look at global cache invalidation, the necessity of origin shielding, and why relying on manual purges is an architectural anti-pattern. Use this distributed systems answer to show the decision, trade-off, and evidence rather than a memorised definition. It also connects caching to the point an interviewer is testing.
Clarify scale first, then size it: 100M new links a day at a 100:1 read ratio gives roughly 1.2k writes/s and 116k redirects/s, needing 7-character base62 keys. Generate keys from leased counter blocks scrambled by a bijection, serve reads from cache and CDN, and redirect with 302 rather than 301.
Stream a server-rendered shell, virtualise the dense views and draw high-density charts to canvas, keep server cache separate from UI and URL state, coalesce socket messages into one commit per frame, give every widget its own empty, error and stale states, and enforce a byte budget per pull request.
Pick a write policy that matches your consistency requirement rather than treating invalidation as an afterthought, then defend against the three failure modes that only appear under load: stampede on expiry, staleness from lost invalidation messages, and unbounded growth from missing eviction.
Break the budget into its parts first, because feature fetching usually costs more than the model does. Then parallelise and cache the fetches, shrink the model with quantisation or distillation, set a timeout shorter than the budget, and define a degraded path that answers without the model.
Build a dependency graph of the repository's build targets, diff the changed files against it to compute the affected subset, and run only that subset; the graph's correctness, not the diff itself, is what determines whether the speedup is trustworthy.
Cache hashed assets for a year and never cache the entry document, retain several previous builds so a stale tab can still fetch its chunks, and treat a failed dynamic import as the signal to prompt a reload rather than as an error to swallow.
Get the method's safety, idempotency and cacheability right, use the status code intermediaries and clients act on rather than a generic 200 with an error body, pair Cache-Control freshness with ETag or Last-Modified validators, and be honest that most APIs called REST are resource-shaped HTTP without hypermedia.
A TTL is an upper bound on how long a resolver may cache a record, not a promise about when clients will notice a change. Lowering it only takes effect after one old TTL has elapsed, negative answers are cached under a different rule, and pooled connections keep using an address they resolved hours ago.
The key must contain every request input that changes the response — identity, scope, locale, device class, active flags — because anything left out silently merges two different responses into one entry. An unkeyed input is both a correctness bug and an injection surface.
Decoration runs once, at definition time, so it happens on import rather than on call. Stacked decorators apply bottom-up and execute outermost-first, and each wrapper replaces the function's identity unless functools.wraps restores it, which is what breaks introspection and framework registration.
Choose the layer by who else can reuse the same bytes and how tolerable staleness is that far from the user, then size it from the working set rather than the dataset. Watch the miss rate, not the hit rate: origin load is proportional to misses, so 99 percent falling to 95 is a fivefold traffic increase.