Design in-memory delivery billing core APIs
RipplingSoftware Engineer · OnsiteLast updated
This problem tests your ability to design an efficient in-memory service for managing delivery billing, requiring careful consideration of concurrency, precision in monetary calculations, and optimized aggregation of billable events.
Problem Statement
Design an in-memory billing engine for a delivery platform that processes high-frequency delivery events. The system needs to calculate total billable amounts for drivers and companies in real-time.
Functional Requirements
record_delivery(delivery_id, driver_id, company_id, amount_cents): Logs a completed delivery. If the delivery_id exists, update the amount.get_driver_total(driver_id): Returns the total earnings for a specific driver.get_company_bill(company_id): Returns the total amount owed by a specific company.
Non-Functional Requirements
- The system must be thread-safe.
- Operations should be optimized for sub-millisecond lookups.
- Precision is critical; monetary values are stored in cents as integers to avoid floating-point issues.
Constraints
- Number of drivers: 10^5
- Number of companies: 10^3
- Expected delivery events per second: 5,000
- High concurrency is expected during peak hours.
Example
# Workflow example
engine = BillingEngine()
engine.record_delivery("d1", "dr_1", "c_1", 500)
engine.record_delivery("d2", "dr_1", "c_1", 300)
print(engine.get_driver_total("dr_1")) # Output: 800
print(engine.get_company_bill("c_1")) # Output: 800
Edge Cases
- Updating a delivery that has already been billed.
- Handling empty IDs or zero-amount deliveries.
Hints
Hint 1
Use a hash map to track the current value of each delivery ID to handle updates correctly.
Hint 2
Maintain secondary hash maps or concurrent maps that store cumulative totals per driver and per company to avoid O(N) aggregation on every read.
Hint 3
Consider using fine-grained locking or atomic variables to ensure thread safety while minimizing contention during high-frequency writes.
Follow-up questions
- How would you persist this data to a database while ensuring the in-memory state remains consistent with the disk?
- If the billing logic changes (e.g., adding a platform fee percentage), how would you refactor your data structures to maintain performance?
- How would you handle a scenario where 'get_company_bill' needs to support a date range filter?
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.