Добавить в корзинуПозвонить
Найти в Дзене
Lyakhov Eugene

Twitter за 1 час: Как не провалить System Design Interview и завалить интервьюера аргументами

1. Блок Требования Первое, чему нас учит правильный Mock Interview — ничего не домысливать. Начинаем не с кода, а с вопросов к заказчику. Нам нужно: 2. База данных: Камень преткновения Здесь многие новички пишут одну таблицу tweets и успокаиваются. А на Mock-собеседовании вас спросят: «А что, если у нас 100 миллионов пользователей?» Мы выбираем NoSQL + SQL гибрид: Важная фишка для интервью: Мы не храним все твиты в одной куче. Мы партицируем (sharding) таблицу по user_id. Запрос "Показать твиты пользователя" отрабатывает мгновенно, потому что он идет в конкретную ноду. 3. Новостная лента (Timeline) — Где собака зарыта Тут есть два пути: Push и Pull. Как это выглядит: Подвох: А если у Инфлюенсера 50 миллионов подписчиков? Писать твит в ленту 50 млн раз — это долго. Тут мы говорим: «Для топ-1% пользователей мы включаем гибридный режим (Pull на запросе), а для всех остальных — Push». Интервьюер захлопает в ладоши. 4. Поиск и фильтрация (Самая хитрая часть) По условию у нас поиск по текст

1. Блок Требования

Первое, чему нас учит правильный Mock Interview — ничего не домысливать. Начинаем не с кода, а с вопросов к заказчику.

Нам нужно:

  • Авторизация (без нее никуда, но пусть будет простой JWT, не будем усложнять).
  • Лента (главная боль всех интервью).
  • Подписки (Follower/Following).
  • Поиск (по тексту твита и по пользователю, но БЕЗ картинок — это важно, мы облегчаем себе жизнь).
  • Блокировка (Ban) — пользователь А бандит пользователя Б, и Б пропадает из ленты А навсегда.

2. База данных: Камень преткновения

Здесь многие новички пишут одну таблицу tweets и успокаиваются. А на Mock-собеседовании вас спросят: «А что, если у нас 100 миллионов пользователей?»

Мы выбираем NoSQL + SQL гибрид:

  • Таблица пользователей (SQL/Postgres): Храним профили. Это святое.
  • Таблица подписок: Тоже SQL (отношения многие ко многим).
  • Таблица твитов: А вот тут начинается магия. Твиты отлично ложатся в Cassandra (широкие колонки). Почему? Потому что нам нужна сортировка по timestamp и запись "пачками". Это дает нам линейную масштабируемость.

Важная фишка для интервью: Мы не храним все твиты в одной куче. Мы партицируем (sharding) таблицу по user_id. Запрос "Показать твиты пользователя" отрабатывает мгновенно, потому что он идет в конкретную ноду.

3. Новостная лента (Timeline) — Где собака зарыта

Тут есть два пути: Push и Pull.

  • Pull (простой): Когда пользователь заходит, мы собираем твиты всех его подписок, сортируем и выдаем. Это работает, пока у вас 10 подписок. При тысяче — база ляжет.
  • Push (сложный, но правильный): Мы заводим хранилище Redis для "Домашней ленты" каждого пользователя.

Как это выглядит:

  1. Инфлюенсер написал твит.
  2. Этого твит отправляется в Message Queue (Kafka).
  3. Воркеры (Worker Services) берут список подписчиков инфлюенсера и кладут ID этого твита в ленту каждого подписчика в Redis (list/zset).
  4. Вы читаете свою ленту за O(1) из Redis по индексу.

Подвох: А если у Инфлюенсера 50 миллионов подписчиков? Писать твит в ленту 50 млн раз — это долго. Тут мы говорим: «Для топ-1% пользователей мы включаем гибридный режим (Pull на запросе), а для всех остальных — Push». Интервьюер захлопает в ладоши.

4. Поиск и фильтрация (Самая хитрая часть)

По условию у нас поиск по тексту и пользователю. Здесь нельзя использовать LIKE %слово% — это смерть для базы.

Мы внедряем Elasticsearch.

  • Когда твит создается, он дублируется в Elasticsearch.
  • Но! У нас есть условие: Сортировка по времени и фильтр по пользователю.

Здесь нужно вспомнить про CAP-теорему. Поисковая выдача может быть чуть-чуть устаревшей (консистентность в конечном счете). Мы строим индекс по полям text, user_id, created_at. Запрос в Elasticsearch формируем так:

  • Фильтр по user_id (если ищем у конкретного).
  • Поиск по тексту (match query).
  • Сортировка по timestamp.

Лайфхак для ответа: Мы не даем пользователю искать по картинкам, поэтому мы не используем тяжелые векторные модели. Это наш "кит" экономии ресурсов.

5. Бан (Ban) — Социальный аспект

Как сделать бан красиво? У нас есть таблица bans (blocked_by, blocked_to).

Когда мы формируем ленту, мы делаем проверку. Но делать проверку на каждый твит — накладно.

Решение на собеседовании:
Мы используем
Bloom Filter.

  • У каждого пользователя в кэше лежит "Список забаненных".
  • Когда алгоритм сборки ленты тянет твиты, он проверяет: есть ли автор твита в Bloom Filter текущего пользователя.
  • Если есть — твит отсекается до того, как попасть в финальную выдачу.

А если пользователь А забанил Б, то Б даже не видит профиль А при поиске. В поисковом Elasticsearch мы добавляем must_not условие, исключающее авторов, которых юзер забанил. Это работает быстро, потому что банят люди друг друга редко.

Итог: Что выносим из Mock IT?

Это упражнение учит нас главному: System Design — это не про код, а про компромиссы.

  • Мы пожертвовали строгой консистентностью ради скорости (Push/Pull гибрид).
  • Мы выбрали сложную архитектуру (Kafka + Cassandra + Redis), чтобы выдержать нагрузку.
  • Мы ограничили функционал (нет поиска по картинкам), чтобы упростить поисковый движок.

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

Вопрос к вам в комментарии:
Какой этап в проектировании соцсети вам кажется самым страшным? Поиск, лента или балансировка базы данных? Делитесь, разберем в следующем посте!

Страховка на собеседовании и поиск работы

Знание есть, но стресс мешает ?

Сообщество для прокачки карьеры и поиска работы в IT:

Платформа - https://itcareergym.tech/#home
Подпишись на -
https://t.me/IT_Interview_Partner_Bot
Подпишись на -
https://t.me/LyakhovEugene
Курс System Design Website -
https://stepik.org/a/279467
C4 + AI: документируем архитектуру быстрее и понятнее -
https://stepik.org/a/295262