Skip to content
back to the interview
Interview summary2023Fellow

Technical Interview: Architecture Section

At C++ Russia 2023 the host, Pavel, played the candidate while Alexander ran a system design interview and, after the announcements, walked through his assessment aloud. They designed a smart car park: find free spots nearby in an app, book one, drive in and out with no tickets and no payment kiosk. The host admitted he had suffered this himself, driving between three shopping centres.

C++ Russia 20239 min read

This summary is shorter than the full interview; examples and assessments reflect the participants’ experience and views.

The main thread of the material
01

Barrier, camera and the system boundary

The format was stated up front: a short list of requirements behind a link, a limited slot in which to invent an implementation and justify the choices made, and then a discussion of those choices with the interviewer. Before starting, the host plugged Alexander's Telegram channel of book write-ups, then called himself the victim, shared his screen and began drawing on a collaborative canvas. Alexander clarified that the car park is not especially smart, more a car park with a barrier: some number of bays, plus control over entry and exit. Two non-functional requirements caught the candidate's eye — car parks in different cities across Russia, and high availability, which already makes the system distributed and rules out a single data centre. He noted high concurrency separately, meaning a lot of users. Concrete request rates were left out: load may be modest today, but it will grow with the business, so room to scale should be designed in from the start.

Then the candidate started cutting scope. The back office, where new car parks are registered and paperwork is handled, went out of scope, and so did payment processing, which somebody else takes care of. Access control was declared external too: a barrier with a camera that reads the licence plate. Rather than design it, they agreed to consume two events — car in and car out — the plate number being enough to identify the driver. The candidate deliberately introduced a strong assumption: cars do not fly, and the only way in or out is past a camera that never misreads. The car park itself was simplified as well: no floor plan, no specific bay assigned, only a counter of free spots per car park — a semaphore, in effect. Alexander asked whether overbooking would be supported, as airlines do; they agreed it definitely would not, and that users are well behaved, one car per spot. Years in aviation showed: the candidate kept calling the spots seats, as on a plane.

02

Geo index, a semaphore and delayed events

The interviewer added a scenario the candidate had not reached: what people want to look at is not one car park but a rectangle on the map — a shopping centre and everything around it. That called for a query returning the nearest car parks together with their free-spot counts, and a geo index on GPS coordinates. Alexander pressed the point that such a query is heavy and fast-changing at the same time: a user drags the point around the map and refreshes, while the counters shift under him as other people book and drive in. The candidate agreed: the app can cache car park coordinates, since car parks appear and disappear rarely; caching free-spot counters is dangerous — arguable for reads, out of the question for writes. They were declared the bottleneck straight away and left uncached. Those same coordinates were named the natural partitioning key: nearby car parks live together, a nearest-first query collects its data from one partition, and counters need no synchronisation across partitions.

The core was one atomic operation: not read the value and write one less, but a decrement that refuses to go below zero and fails there — which the app renders as an apology that the spots were taken while you were deciding. Cancellation increments the counter back and deletes the record of the expected car. For a booking not confirmed by arrival within fifteen minutes the candidate introduced a queue of delayed messages — events for the future, read back with a lag; before a booking is dropped the arrivals table is checked and the user is notified through a second queue. Barrier events arrive as a separate stream from the access control system and go straight into the database: car in confirms the booking, car out returns the spot. On a refusal the updated counter can travel back with the error. The candidate settled on a store only with caveats: he remembered atomic counters for certain in MongoDB, proposed adding semaphore semantics with a script on the database itself, and admitted this was partly wishful thinking. Time ran out on the two counter replicas availability would need.

03

Debrief: PostgreSQL, geo balancing, diagram legibility

Ten minutes were left for the debrief. Alexander named scoping as the strength: candidates often bury themselves by agreeing to build everything at once, whereas here the interesting scenarios were picked — the user's interaction and the barrier system's. He also lowered the temperature around contention: while a car park has plenty of spots, exhausting them all at once is unlikely, and it only gets hot on the last couple of bays and at the morning and evening peaks. The main gap was an entity nobody had mentioned — the orders themselves, which Alexander steered towards with a question before the break. The candidate accepted it and added a booking history: the whole stream of user events with their statuses, what worked and what did not, essentially write-only, in a log-oriented store hooked up to a shared event bus. He pointed out the irony himself: he works in data science and usually scolds others for not collecting data, yet here he forgot to design the historical store.

Alexander's own solution went a different way. He would take a relational database — PostgreSQL — with a constraint keeping the counter non-negative; only simultaneous changes on the same car park would worry him. Read load on the map he would take off with a separate copy of the data, accepting the lag: a user sees the last free spot, then is refused at booking. Geographic distribution, in his view, is simpler at the traffic-balancing layer, across the regions worth a presence — Moscow and its region, Petersburg and the Leningrad region, the Far East; nobody books in Vladivostok and Moscow at once, though the seams between districts inside Moscow raise questions. An explicit order status model — created, paid, driver arrived, timer running — he considered mandatory, and he mixed synchronous operations with events on purpose: pick the tool the scenario calls for. A verdict from the break: without the author's narration the diagram is nearly impossible to follow. Legibility sits in the scoring matrix, but with thirty minutes instead of the usual forty-five or sixty Alexander was not holding it against him.

Takeaways

What to take away

  1. 01A free-spot count is a semaphore, not a number in a table: without an atomic decrement that refuses at zero, overbooking arrives through an ordinary race condition.
  2. 02Contention is uneven: while spots are plentiful nobody is fighting for them — it only gets hot on the last couple of bays and at the morning and evening peaks.
  3. 03Working tables get deleted as the flow proceeds, so the historical order store is designed from the start rather than reconstructed for statuses and analytics later.
  4. 04Geographic distribution need not be solved in the database: if nobody ever books in two regions at once, traffic and data can be localised at the balancing layer.

Sources