Публичное System Design интервью на C++ Russia 2023, где интервьюер Александр Поломодов предлагает кандидату Павлу спроектировать систему умной парковки — классическую задачу на распределённые системы с высокими требованиями к консистентности и обработке конкурентного доступа к данным.
Источник
Оригинальный разбор
Этот разбор основан на публикации в Telegram-канале «Книжный куб».
Видеозапись интервью
Полная запись публичного интервью (30 минут) доступна на YouTube.
Смотреть на YouTubeПостановка задачи
Smart Parking System
Система управления сетью платных парковок с контролем доступа через шлагбаумы. Пользователь бронирует место заранее через приложение, получает гарантию его наличия и использует автоматический въезд/выезд по госномеру.
Функциональные требования
Поиск парковок
Поиск по GPS с отображением свободных мест
Бронирование
Атомарный декремент счётчика свободных мест
Отмена по тайм-ауту
Авто-отмена брони через 15 минут неявки
Въезд/выезд
Автоматическое распознавание госномера через СКУД
Нефункциональные требования
High Concurrency
Пиковые нагрузки утром/вечером, особенно в ТЦ. Множество пользователей конкурируют за одни и те же места.
No Overbooking
Абсолютная недопустимость двойного бронирования. Требуется строгая консистентность данных.
Заметка
Hotspot системы
Интервьюер особо отметил, что кандидат корректно выявил bottleneck — конкурентный доступ к счётчику свободных мест.
High-Level Architecture
Smart Parking: High-Level Map
reservation + access control + timeout automationBooking Plane
Access + Async Plane
Общий контур smart parking: онлайн-бронирование, контроль въезда/выезда и авто-освобождение мест по TTL.
Архитектура разделяет три независимых контура: онлайн-бронь, физический доступ и timeout-автоматизацию. Это позволяет изолированно масштабировать API, LPR-контур и фоновые воркеры.
Основные сущности
Parking
{
id: UUID,
gps_coordinates: {lat, lon},
total_capacity: int,
free_spots_counter: int, // семафор!
address: string
}Booking
{
id: UUID,
user_id: UUID,
parking_id: UUID,
car_plate: string,
created_at: timestamp,
expires_at: timestamp,
status: enum (pending, confirmed, cancelled, expired)
}Фидбек интервьюера
Кандидат изначально забыл сущность Booking, фокусируясь на операционных таблицах. Однако хранение заказов критично для аналитики, аудита и восстановления состояния.
Атомарный счётчик-семафор
Центральная техническая сложность — обеспечить атомарность декремента счётчика при бронировании. Нужна операция compare-and-swap с проверкой: счётчик не должен опускаться ниже нуля.
Redis: Lua-скрипт
Рекомендуется-- parking_book.lua
local counter = redis.call('GET', KEYS[1])
if tonumber(counter) > 0 then
return redis.call('DECR', KEYS[1])
else
return -1 -- Нет свободных мест
endПлюсы
Single-threaded, атомарность, >100k ops/sec
Минусы
Требует Redis Cluster для HA
PostgreSQL: UPDATE с F-expression
UPDATE parkings SET free_spots = free_spots - 1 WHERE id = $1 AND free_spots > 0; -- affected_rows = 0 → мест нет
Плюсы
Полная ACID-гарантия, CHECK constraints
Минусы
Row-level locks при высокой конкуренции
Рекомендуемый подход
Redis для временной блокировки (быстро, TTL) + PostgreSQL для финальной записи (ACID). Redis как "первая линия обороны", БД как источник правды.
Delayed Message Queues
Если пользователь забронировал место, но не приехал за 15 минут, система должна автоматически освободить место и отменить бронь.
AWS SQS Delay Queues
# При бронировании
sqs.send_message(
QueueUrl=timeout_queue,
MessageBody={"booking_id": "...", "parking_id": "..."},
DelaySeconds=900 # 15 минут
)
# Через 15 минут воркер проверяет:
# - Если машина не приехала → INCR счётчик, отменить бронь
# - Если приехала → ничего не делатьАльтернатива: RabbitMQ Delayed Message Plugin для self-hosted решений.
Geo-Sharding
Парковки естественно привязаны к географии, что создаёт идеальную возможность для location-based sharding.
Стратегия
- Shard key на основе geo-hash (msc_ для Москвы, spb_ для СПб)
- Запросы "найди ближайшие" обслуживаются из одного шарда
- Минимизация cross-shard операций
Hotspots: Популярные локации (центр Москвы) разбиваются на под-зоны + read replicas.
Ключевые выводы
Атомарный семафор
Центральная проблема — race condition при декременте счётчика. Redis + Lua или PostgreSQL с WHERE free_spots > 0.
Event Sourcing для аудита
Append-only лог событий (booking_created, car_arrived, car_departed) для полной аудитируемости.
Delayed Queues для TTL
SQS/RabbitMQ с задержкой 15 минут для автоматической отмены неиспользованных броней.
Geo-partitioning
Шардирование по геолокации минимизирует cross-shard операции и обеспечивает локальность данных.
Оценка интервьюера
✓ Сильные стороны
- Правильное определение scope
- Быстрое выявление bottleneck
- Полнота сценариев (success, failure, timeout)
- Учёт geo-распределения и NFR
⚠ Области для улучшения
- Забыта сущность Booking
- Не обсуждены конкретные RPS и sizing
- Финальный выбор БД не аргументирован
- За 30 минут охвачено ~60% объёма
Итоговая оценка: Hire с условием. Для senior-позиции требуется больше глубины в выборе технологий и численных оценках.
