Граф знанийНастройки

Обновлено: 25 марта 2026 г. в 04:52

Система умной парковки

medium

Публичное интервью на C++ Russia 2023: распределённые блокировки и защита от double booking.

Системы бронирования редкого ресурса ломаются на конкурирующих попытках захватить один и тот же слот, а не на форме поиска.

Кейс помогает построить hold-confirm flow, TTL reservation, payment coupling, idempotency и защиту от oversell там, где ресурс физически ограничен и спрос приходит всплесками.

В интервью и design review он полезен тем, что проверяет понимание конкурентного доступа, временных блокировок и цены ошибки в пользовательском critical flow.

Business Correctness

Требуется корректное состояние заказа при конкурирующих запросах и ретраях.

User Experience

Надо защищать critical user flow при скачках трафика и частичных деградациях.

Transactional Boundaries

Явно задавайте, где нужна сильная консистентность, а где допустима eventual.

Evolution Path

Покажите, как архитектура растёт от MVP до multi-region масштаба.

Публичное System Design интервью на C++ Russia 2023, где интервьюер Александр Поломодов предлагает кандидату Павлу спроектировать систему умной парковки — классическую задачу на распределённые системы с высокими требованиями к консистентности и обработке конкурентного доступа к данным.

Источник

Оригинальный разбор

Этот разбор основан на публикации в Telegram-канале «Книжный куб».

Перейти на сайт

Видеозапись интервью

Полная запись публичного интервью (30 минут) доступна на YouTube.

Смотреть на YouTube

Постановка задачи

Smart Parking System

Система управления сетью платных парковок с контролем доступа через шлагбаумы. Пользователь бронирует место заранее через приложение, получает гарантию его наличия и использует автоматический въезд/выезд по госномеру.

Функциональные требования

Поиск парковок

Поиск по GPS с отображением свободных мест

Бронирование

Атомарный декремент счётчика свободных мест

Отмена по тайм-ауту

Авто-отмена брони через 15 минут неявки

Въезд/выезд

Автоматическое распознавание госномера через СКУД

Нефункциональные требования

High Concurrency

Пиковые нагрузки утром/вечером, особенно в ТЦ. Множество пользователей конкурируют за одни и те же места.

No Overbooking

Абсолютная недопустимость двойного бронирования. Требуется строгая консистентность данных.

Связанная глава

Hotspot systems

Паттерны работы с hotspots в geo-sharded системах.

Читать обзор

High-Level Architecture

Smart Parking: High-Level Map

reservation + access control + timeout automation

Booking Plane

Driver App
search + reserve
API Gateway
auth + routing
Booking Service
reserve/cancel
Inventory Lock
Redis semaphore
Booking DB
state + history

Access + Async Plane

ANPR/LPR -> Entry Service -> Gate Controller
plate check + barrier command
Event Bus -> Delay Queue -> Timeout Worker
TTL expiration pipeline
Notification
push/email

Общий контур 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-позиции требуется больше глубины в выборе технологий и численных оценках.

Связанные главы

Чтобы отмечать прохождение, включи трекинг в Настройки