Debug a Test-Driven C++ Project
AmazonSoftware Engineer · Online AssessmentLast updated
Tests your ability to design and implement a sliding-window rate limiter with deduplication and state cleanup, reflecting common logic and edge-case errors encountered when debugging test-driven C++ systems.
Problem Statement
You are tasked with building a resilient in-memory order processor component for an e-commerce platform. The system must filter out duplicate requests and enforce per-customer rate limits over a sliding time window.
Implement the OrderRateLimiter class with the following methods:
-
OrderRateLimiter(window_size: int, max_orders_per_customer: int): Initializes the rate limiter with a sliding window duration ofwindow_sizeseconds and an allowed maximum ofmax_orders_per_customersuccessful orders per customer in that window. -
process_order(order_id: str, customer_id: str, timestamp: int) -> bool: Attempts to process an incoming order attimestamp. An order is accepted (True) if and only if:- The
order_idhas not already been accepted within the current sliding window[timestamp - window_size + 1, timestamp]. - The customer has accepted strictly fewer than
max_orders_per_customerorders within the current sliding window[timestamp - window_size + 1, timestamp].
If either condition fails, the order is rejected and the method returns
False. Rejected orders do not consume capacity and should not block future retries if conditions change. - The
-
get_active_orders_count() -> int: Returns the total number of accepted orders currently within the active window relative to the most recenttimestampobserved across all calls toprocess_order. If no orders have been processed yet, return0.
Constraints
1 <= window_size <= 10^91 <= max_orders_per_customer <= 10^51 <= len(order_id), len(customer_id) <= 32(alphanumeric strings)0 <= timestamp <= 10^9- Calls to
process_orderare guaranteed to have non-decreasingtimestampvalues. - Up to
2 * 10^5total calls across all methods.
Examples
Example 1
limiter = OrderRateLimiter(window_size=10, max_orders_per_customer=2)
limiter.process_order("ord_1", "cust_A", 1) # returns True (window: [1, 1], cust_A count: 1)
limiter.process_order("ord_2", "cust_A", 5) # returns True (window: [1, 5], cust_A count: 2)
limiter.process_order("ord_1", "cust_A", 6) # returns False (ord_1 already accepted in window [1, 6])
limiter.process_order("ord_3", "cust_A", 7) # returns False (cust_A limit reached: 2 orders in window [1, 7])
limiter.get_active_orders_count() # returns 2 ("ord_1" and "ord_2" are active at t=7)
limiter.process_order("ord_4", "cust_A", 11) # returns True (window: [2, 11]; "ord_1" at t=1 expired, cust_A count drops to 1, then becomes 2)
limiter.get_active_orders_count() # returns 2 ("ord_2" and "ord_4" are active at t=11)
Example 2
limiter = OrderRateLimiter(window_size=5, max_orders_per_customer=1)
limiter.process_order("ord_1", "cust_B", 10) # returns True
limiter.process_order("ord_1", "cust_B", 16) # returns True ("ord_1" expired at t=15, so re-using the ID is allowed)
limiter.get_active_orders_count() # returns 1
Edge Cases to Consider
- Multiple orders occurring at the exact same timestamp.
- Ensuring expired orders are evicted before checking both deduplication sets and customer order counts.
- Rejected orders must not leave residual state that incorrectly triggers deduplication or counts against customer quotas.
Hints
Hint 1
Because timestamps arrive in non-decreasing order, a queue (FIFO) can track accepted orders alongside their timestamps to evict expired orders efficiently in amortized O(1) time.
Hint 2
Make sure to clean up state across all tracking structures (the queue, the active ID set, and the per-customer counts) before checking if the current order is valid.
Hint 3
Pay close attention to window inclusion: an order at timestamp `t` expires when the current timestamp satisfies `current_timestamp >= t + window_size`.
Follow-up questions
- How would you adapt this design if order timestamps could arrive out of order due to network latency?
- How would you make this class thread-safe in C++ for high-concurrency read and write access without creating a global lock bottleneck?
- If the window size is very large (e.g., 30 days) and tracking every raw order exceeds memory constraints, what approximate streaming algorithms would you use?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.