Спроектируй мессенджер
Вопрос
Спроектируй веб-клиент мессенджера как в Telegram Web: список чатов, переписка, отправка текста и фото, статусы «отправлено/прочитано», «печатает». Пройди этапы: требования, оценка нагрузки, API, данные, компоненты, узкие места.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Требования: список чатов, история, отправка, статусы, «печатает», уведомления, офлайн и плохая сеть
Оценка: тысячи чатов, длинная история, в групповом чате десятки сообщений в секунду, долгоживущая вкладка
API: WebSocket для событий (message.new, typing, read), REST для истории с курсором вверх, загрузка файлов отдельно
Данные: сообщения по чатам с клиентским id, нормализация, IndexedDB для кеша и офлайн-очереди
Компоненты: ChatList, ChatWindow с виртуализацией в обратном порядке, Composer, MessageBubble
Узкие места: порядок и дедупликация, переподключение с догрузкой пропущенного, батчинг обновлений, утечки памяти, позиция скролла при подгрузке истории
Что могут спросить следом
- Как гарантировать порядок сообщений?
- Что будет при обрыве соединения на 10 минут?
- Как не дублировать сообщение при повторной отправке?
Разбор
Требования: список чатов с последним сообщением и счётчиком, история с подгрузкой вверх, отправка текста и фото, статусы, «печатает», работа на плохой сети. Масштаб: у активного пользователя тысячи чатов, в группе могут идти десятки сообщений в секунду, а вкладка живёт днями, поэтому важны батчинг и отсутствие утечек. API: WebSocket для событий в реальном времени, REST для истории по курсору, файлы загружаются отдельным запросом, а в сообщение уходит ссылка. Данные: каждое исходящее сообщение получает клиентский id, по нему делаю оптимистичный показ со статусом «отправляется», дедуплицирую при эхе от сервера и сопоставляю серверный id. Кеш последних чатов и очередь неотправленного храню в IndexedDB. Компоненты: ChatList с виртуализацией, ChatWindow с виртуализацией снизу вверх и сохранением позиции при подгрузке истории, Composer. Узкие места: при обрыве переподключаюсь с экспоненциальной задержкой и запрашиваю пропущенное с последнего известного id, обновления от сокета применяю пачками раз в кадр, «печатает» отправляю с троттлингом.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.