Define the APIs expected from the system. This is your chance to analyze and define the read and write paths so that you can come up with the high-level design...
I’ll separate read path and write path.
Read APIs
Search availability
GET /lots/{lotId}/availability?startTime=...&endTime=...&vehicleType=SUV
Response:
{
"lotId": "lot-123",
"available": true,
"spotTypes": [
{
"type": "SUV",
"count": 21,
"priceEstimate": 18.50
}
]
}
Get lot details
GET /lots/{lotId}
Get reservation
GET /reservations/{reservationId}
Get user reservations
GET /users/{userId}/reservations
Write APIs
Create reservation
POST /reservations
Request:
{
"userId": "u1",
"vehicleId": "v1",
"lotId": "lot-123",
"vehicleType": "SUV",
"startTime": "2026-04-14T09:00:00Z",
"endTime": "2026-04-14T12:00:00Z",
"spotPreference": "EV"
}
Response:
{
"reservationId": "r1",
"status": "PAYMENT_PENDING",
"amount": 18.50,
"paymentToken": "pay_abc"
}
Confirm payment / payment callback
POST /payments/callback
or
POST /reservations/{reservationId}/confirm-payment
Cancel reservation
POST /reservations/{reservationId}/cancel
Gate entry check-in
POST /gates/check-in
Request:
{
"lotId": "lot-123",
"gateId": "entry-1",
"plate": "ABC1234",
"qrCode": "optional",
"timestamp": "2026-04-14T08:58:12Z"
}
Response:
{
"allowed": true,
"reservationId": "r1",
"assignedSpot": {
"spotId": "B2-104",
"floor": "B2"
},
"message": "Welcome"
}
Gate exit check-out
POST /gates/check-out
Request:
{
"lotId": "lot-123",
"gateId": "exit-2",
"plate": "ABC1234",
"timestamp": "2026-04-14T10:40:00Z"
}
Response:
{
"allowed": true,
"sessionId": "s1",
"finalCharge": 0,
"refund": 3.00,
"message": "Thank you"
}
Mark no-show
Usually internal, event-driven:
POST /internal/reservations/{reservationId}/mark-no-show
Describe the overall system architecture. Identify the main components needed to solve the problem end-to-end. Use the diagramming tool to create a block diagram.
Main components:
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.
I’d deep dive into these 3:
This is the hardest core logic.
There are two models:
Pros:
Cons:
Example: reserve “SUV-compatible on floor B2”, assign actual spot when user arrives.
Pros:
Cons:
Best practical choice:
Use spot class reservation, then assign exact spot at check-in or shortly before arrival.
For premium/VIP/accessibility cases, exact spot reservation can still be supported.
At low scale, you can simply query DB rows for overlapping reservations.
At higher scale, better to maintain:
A spot can be assigned only if:
Two reservations overlap if:
new.start < existing.end AND new.end > existing.start
This is crucial.
Possible approaches:
SELECT ... FOR UPDATEPros:
Cons:
Pros:
Cons:
Instead of exact spot selection during booking:
(lot, spotType, timeSlot)Pros:
Cons:
Start with:
That is a strong, pragmatic answer.
Shard primarily by:
lotIdWhy?
For large deployments:
This is operationally critical.
This service must be very fast.
So I would keep:
If central backend is temporarily unavailable:
This is a strong real-world point.
Solutions:
Gate traffic is not internet-scale, but spikes can happen at event venues.
Example:
Still manageable with:
This is where distributed workflow correctness matters.
Reservation and payment involve multiple systems:
We need to avoid:
Flow:
PAYMENT_PENDINGThis is effectively a mini saga.
Because PSP is external and distributed 2PC is impractical.
Need it for:
For example, payment callback may arrive twice.
So we store:
externalPaymentRefBusiness rule options:
simple, good for operators
better UX, more complex
great compromise
I would say:
Flow:
Need a configurable grace period, e.g. 15 minutes.
Flow:
NO_SHOWThis can be implemented using:
I prefer delayed jobs because they are more targeted, but a periodic sweeper is simpler as backup.
Use PostgreSQL/MySQL for source of truth.
Why SQL?
(lot_id, start_time, end_time, status)(vehicle_id, start_time)(plate)(plate, status)(lot_id, type, status)Use for:
Kafka / RabbitMQ / SQS-like queue for:
For interview purposes, keep it simple.
Example:
That gives:
This is not massive for a modern SQL + cache + queue architecture.
Peak traffic is the real concern:
So design for: