Implement queue-based rate limiter with multi-key limits
Company: Roblox
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates implementation and design skills around rate limiting, including rolling-window counters, multi-key constraints, and atomic updates, and falls under the Coding & Algorithms domain focused on practical application of algorithms and data structures.
Part 1: Rolling Window Queue Rate Limiter
Constraints
- 1 <= K <= 10^5
- 1 <= W <= 10^9
- 0 <= len(timestamps) <= 2 * 10^5
- 0 <= timestamps[i] <= 10^9
- timestamps is sorted in nondecreasing order
Examples
Input: (2, 5, [1, 2, 3, 6, 7])
Expected Output: [True, True, False, True, True]
Explanation: At time 3, the allowed requests at 1 and 2 are still inside the last 5 ms, so the third request is denied. By time 6, timestamp 1 has expired.
Input: (1, 3, [5, 5, 8, 8])
Expected Output: [True, False, True, False]
Explanation: Requests at the same timestamp count toward the same window. A request at time 5 expires when the current time reaches 8.
Hints
- Keep only allowed request timestamps that are still inside the current rolling window.
- A deque is a natural fit because expired timestamps always leave from the front.
Part 2: Atomic Multi-Key Rate Limiter
Constraints
- 1 <= Ku, Ke <= 10^5
- 1 <= W <= 10^9
- 0 <= len(requests) <= 2 * 10^5
- userId and experience are strings
- 0 <= timestamp <= 10^9
- request timestamps are sorted in nondecreasing order
Examples
Input: (1, 2, 5, [('u1', 'A', 1), ('u1', 'A', 2), ('u2', 'A', 2)])
Expected Output: [True, False, True]
Explanation: The second request is blocked by the per-user limit. Because the update is atomic, it does not consume experience A capacity, so the third request is still allowed.
Input: (2, 1, 4, [('u1', 'A', 1), ('u2', 'A', 2), ('u2', 'B', 2), ('u3', 'A', 5)])
Expected Output: [True, False, True, True]
Explanation: The second request is denied by the per-experience limit for A. At time 5, the earlier A request at time 1 has expired.
Hints
- Maintain one hash map of deques for userId counts and another for experience counts.
- Prune expired timestamps first, then check both limits, and append to both deques only if both checks pass.