Ответ вслух Senior System design на фронте спрашивают часто обновлено

Спроектируй мессенджер

Вопрос

Спроектируй веб-клиент мессенджера как в 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 ошибок.