Собеседование по проектированию систем: спроектируйте Uber
«Спроектируйте Uber» — один из самых распространённых вопросов по проектированию систем, потому что он одновременно затрагивает геопространственную индексацию, потоковую передачу геолокации в реальном времени, мэтчинг и высокую пропускную способность записи. Интервьюер не ищет настоящую архитектуру Uber — он хочет увидеть, как вы определяете границы задачи, принимаете обоснованные решения и рассуждаете о масштабе вслух.
Разбирайте задачу в осознанном порядке: уточните требования, оцените масштаб, набросайте основные сущности и API, спроектируйте данные и путь мэтчинга, а затем обсудите узкие места и компромиссы. Разбор ниже следует этому порядку, чтобы вы тренировали структуру ответа, а не только сам ответ.
1. Уточнение требований
Разделите функциональные и нефункциональные требования и зафиксируйте объём задачи до начала проектирования. Пассажиры заказывают поездку и видят, как водитель приближается в реальном времени; водители выходят онлайн и получают близкие заказы; система сопоставляет их и отслеживает поездку до завершения.
- Функциональные: заказать поездку, найти подходящего водителя рядом, отслеживать поездку в реальном времени, расчёт тарифа, история поездок.
- Нефункциональные: мэтчинг с низкой задержкой (секунды), высокая доступность, обновления геолокации в реальном времени, консистентность — водитель назначается ровно одному пассажиру.
- Вне рамок (явно скажите об этом): внутренняя обработка платежей, рейтинги, ML для динамических тарифов — упомяните и отложите.
2. Оценка масштаба
Приблизительные цифры обосновывают дальнейшие решения. Предположим, что ~10 млн ежедневно активных водителей отправляют сигнал о местоположении каждые 4 секунды — это ~2,5 млн операций записи в секунду для данных о местоположении, нагрузка с преобладанием записи, которая сразу исключает использование наивной реляционной таблицы как горячего пути.
3. Основные компоненты и API
Набросайте сервисы и поток запросов. Держите путь мэтчинга независимым от долговременного хранилища поездок, чтобы каждый мог масштабироваться согласно своим собственным характеристикам.
- Сервис геолокации: принимает сигналы от водителей, хранит текущие позиции в геопространственном индексе в памяти.
- Сервис мэтчинга: при запросе поездки опрашивает близких онлайн-водителей и назначает одного.
- Сервис поездок: долговременная запись жизненного цикла поездки (запрошена → назначена → в пути → завершена).
- Уведомления/стриминг: передаёт пассажиру позицию водителя в реальном времени (WebSocket/long-poll).
4. Геопространственный мэтчинг — суть задачи
Это то, что интервьюер больше всего хочет услышать. Хранить сырые координаты (широту/долготу) и сканировать их — это O(n); нужен пространственный индекс. Объясните квадродеревья (quadtrees) или геохеширование: разбить карту на ячейки, чтобы «найти водителей рядом с этой точкой» превратилось в поиск по нескольким ячейкам, а не в полное сканирование.
Геохеширование кодирует область в короткую строку, где общие префиксы означают пространственную близость, превращая «рядом» в запрос по префиксу. Текущие ячейки водителей хранятся в хранилище в памяти (например, Redis) для быстрого чтения и частых обновлений; гранулярность ячейки — это настраиваемый компромисс между точностью и разветвлением запроса.
5. Масштабирование и узкие места
Назовите точки давления и способы их снятия. Поток из 2,5 млн записей геолокации в секунду является главным из них.
- Шардируйте индекс геолокации географически — водители и пассажиры одного города обрабатываются одним и тем же шардом, что сохраняет мэтчинг локальным.
- Поглощайте всплеск записи с помощью хранилища в памяти и асинхронных долговременных записей; не нужно, чтобы каждый сигнал попадал в долговременную БД.
- Гарантируйте связь «один водитель — один пассажир» с помощью атомарного назначения (блокировка или условное обновление), чтобы избежать двойного бронирования.
- Используйте очередь сообщений (Kafka) между приёмом геолокации и последующими потребителями, чтобы разделить всплески нагрузки.
6. Компромиссы, которые нужно озвучить
Завершите, назвав напряжённые моменты, которые ценит интервьюер: строгая консистентность против итоговой (назначение водителя должно быть строгим; отображение местоположения может быть итоговым), скорость в памяти против долговечности, и точность размера ячейки против разветвления запроса. Явное озвучивание этого — разница между проходным ответом и сильным ответом.
Потренируйтесь в проектировании системы Uber с помощью в реальном времени
Ассистент для собеседований по проектированию систем от Natively может помочь вам сохранять структуру во время живого собеседования — предлагая следующее измерение для рассмотрения и показывая компромиссы в реальном времени, всё на вашем собственном устройстве.
