Extend an Existing Endpoint Cache and Prove It with Tests
Company: Pinterest
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
# Extend an Existing Endpoint Cache and Prove It with Tests
You inherit a service in which one endpoint already uses a shared cache interface and a similar read endpoint always calls its backing repository. Add caching to the uncached endpoint by following the established pattern.
Explain how you would inspect the existing implementation, choose a collision-safe key, preserve serialization and TTL conventions, handle hits, misses, backend errors, and mutations, and keep user- or tenant-scoped data isolated. Testing is the primary focus: propose tests that demonstrate externally observable cache behavior rather than merely exercising lines of code.
### Clarifying Questions to Ask
- Are responses global, tenant-scoped, user-scoped, or permission-dependent?
- What TTL, negative-caching, and stale-data policies does the reference endpoint use?
- Which mutations can invalidate or update the cached object?
- Does the cache interface distinguish a stored null value from a miss?
### What a Strong Answer Covers
- Reading the existing cache abstraction and conventions before adding a new mechanism.
- A versioned, namespaced key containing every dimension that changes the response.
- Correct hit, miss, population, error, and invalidation paths.
- Tests for call counts, key isolation, TTL behavior, serialization, and stale-data prevention.
- Consideration of concurrent misses and failures without hiding backend errors as valid data.
### Follow-up Questions
- How would you test that two tenants requesting the same object ID never share cached data?
- What strategy would limit a thundering herd when a popular key expires?
- When would deleting on mutation be safer than writing the new value through to the cache?
Quick Answer: Practice extending an existing endpoint cache while preserving the service's established abstraction and behavior. The answer emphasizes key isolation, hit and miss semantics, failures, invalidation, concurrent misses, and tests that prove repository call counts, tenant separation, TTL forwarding, and stale-data prevention.