Rate limiter: AI coding interview practice
You’ve joined the API platform team. Every request to the public API passes through this rate limiter: one token bucket per API key, refilled at a steady rate, with idle buckets evicted so memory stays bounded. Three tickets are waiting for you.
Download the project (zip, 8 KB)
Java 17, Maven, JUnit 5. Covers token bucket, time and clocks in tests, per-key configuration, amortised cleanup.
What's inside
pom.xml README.md src/main/java/practice/ratelimit/Clock.java src/main/java/practice/ratelimit/LimitConfig.java src/main/java/practice/ratelimit/RateLimiter.java src/main/java/practice/ratelimit/TokenBucket.java src/test/java/practice/ratelimit/BaselineTest.java src/test/java/practice/ratelimit/FakeClock.java src/test/java/practice/ratelimit/Phase1Test.java src/test/java/practice/ratelimit/Phase2Test.java src/test/java/practice/ratelimit/Phase3Test.java
Run it
mvn -q test # phase tests fail until you solve them mvn -q test -Dtest=BaselineTest # what already works; keep it green
How to practise
- Set a 60-minute timer: about 10 minutes for phase 1, 25 for phase 2, 20 for phase 3 and 5 to review.
- Use an AI chat that can read the project files (or paste them in), but type every change yourself. Many AI-enabled rounds work this way: the AI explains and suggests, you edit.
- Say your plan out loud before you prompt, and check every AI answer against the code and the tests before you trust it.
- Run only the phase you’re on, then the whole suite, so you know you didn’t break what already worked.
The three tickets
Phase 1: Fix the bug
Support says clients that poll a little faster than once a second get throttled forever, even though they’re under the limit on average. Find the cause and fix it.
Check with mvn -q test -Dtest=Phase1Test
Hint
Run Phase1Test and read the numbers it prints. Then ask the AI to walk you through how a bucket refills, step by step, for two calls 600 ms apart.
Phase 2: Add the feature
Paid customers get their own limit. Implement RateLimiter.setLimit(key, config). An upgrade keeps the tokens a key has already spent, and a custom limit must survive idle eviction.
Check with mvn -q test -Dtest=Phase2Test
Hint
Decide where a custom limit lives before you write code. If it lives only inside the bucket, what happens when the bucket is evicted?
Phase 3: Make it fast
A launch brought 200,000 distinct keys in one burst and latency went through the roof. Make tryAcquire fast again without breaking idle eviction.
Check with mvn -q test -Dtest=Phase3Test
Hint
Count how much work one tryAcquire call does as the number of keys grows. Does eviction need to run on every call?
More practice projects
- Inventory reservations: A checkout service that holds stock while shoppers pay. Fix a double-counting bug, add all-or-nothing cart reservations, then make stock checks fast during a sale.
- Log insights: An on-call dashboard that reads gateway access logs. Fix a parsing bug, add an error-rate panel, then make refreshes fast with a day of traffic loaded.
Want to know what real rounds look like first? Read the candidate reports by company.