System design співбесіди лякають більшість розробників, бо задача необмежена. «Спроєктуй Twitter». «Спроєктуй URL-shortener». «Спроєктуй розподілений кеш». З чого взагалі починати?
Після 100+ технічних співбесід та менторства інженерів для FAANG і MAANG я звів процес до повторюваного фреймворку. Ось він.
6-кроковий фреймворк
Крок 1: Уточніть вимоги (5 хвилин)
Ніколи не починайте проєктувати без цих питань:
- Масштаб: Скільки користувачів? Read-heavy чи write-heavy? Очікувані QPS (запити в секунду)?
- Consistency vs availability: Чи нормально віддавати трохи застарілі дані? Чи можемо втратити запис?
- Географія: Один регіон чи глобально?
- SLA: Яка допустима latency? Вимога до uptime?
Більшість кандидатів це пропускають і одразу малюють квадратики. Інтерв’юери помічають. Senior спочатку ставить запитання.
Крок 2: Визначте API-контракт
До будь-якої інфраструктури — що система віддає назовні:
POST /urls
Body: { "long_url": "https://example.com/very-long-path" }
Response: { "short_code": "abc123", "short_url": "https://short.ly/abc123" }
GET /{short_code}
Response: 301 Redirect to long_url
Це змушує думати про користувацький контракт до деталей реалізації.
Крок 3: Оцініть масштаб (back-of-envelope)
Рахуйте вголос:
- «100M URL на день = ~1 200 записів/сек»
- «Співвідношення read/write 10:1 = 12 000 читань/сек»
- «Середній URL ~500 байт, 100M/день × 365 днів × 500 байт = ~18ТБ/рік»
Точні числа не потрібні. Треба показати, що мислите порядками величин.
Крок 4: Спроєктуйте data model
SQL vs NoSQL — майже завжди перше реальне рішення:
| Фактор | На користь SQL | На користь NoSQL |
|---|---|---|
| Потрібна strong consistency | ✅ | ❌ |
| Складні join’и / звіти | ✅ | ❌ |
| Горизонтальний масштаб 100M+ рядків | Складніше | ✅ |
| Схема стабільна | ✅ | Будь-яке |
| Access pattern — key-value | Будь-яке | ✅ |
Для URL-shortener простий key-value (Redis або DynamoDB) для lookup — правильний вибір. Метадані (час створення, click-аналітика) — у PostgreSQL.
Крок 5: Компоненти системи
Малюйте квадратики й пояснюйте кожен:
Client → CDN/Load Balancer → API Servers (stateless)
→ Redis (short_code → long_url кеш)
→ PostgreSQL (метадані, аналітика)
Потім розбирайте складне:
- Генерація short_code: Base62 від auto-increment ID, або hash + обробка колізій
- Cache invalidation: TTL на записах Redis, write-through на створенні
- Rate limiting: per-IP, алгоритм token bucket
Крок 6: Bottlenecks і trade-offs
Тут senior відрізняється від mid’а. Проактивно обговорюйте:
- Single points of failure: «БД — SPOF; додамо read-репліки і primary failover»
- Гарячі партиції: «Якщо short URL вірусний, один Redis-нод б’ється; consistent hashing розподіляє навантаження»
- Вартість vs продуктивність: «CDN-кешування економить 90% звернень до origin, але додає ризик stale-редиректів для видалених URL»
Що інтерв’юери реально оцінюють
- Комунікацію: Можете пояснити думки вголос?
- Системну декомпозицію: Розбиваєте задачу на частини?
- Awareness trade-off’ів: Розумієте, що ідеальної відповіді немає?
- Production-mindset: Думаєте про failure modes, не тільки про happy path?
Не перевіряють, чи пам’ятаєте напам’ять архітектурні діаграми. Перевіряють, як ви думаєте.
Єдина практична вправа, яка працює
Візьміть будь-який застосунок, яким користуєтесь щодня (Slack, Netflix, мобільний банк). За 20 хвилин на папері накидайте:
- Які основні сутності?
- Яке співвідношення read/write?
- Де bottlenecks?
- Як масштабувати в 10× до поточного навантаження?
Зробіть це 20 разів. І біла дошка перестане лякати.
Мислення system design ми розбираємо в курсі Backend Architecture Foundations — де навчають думати як senior до того, як ним станеш.