← Назад к курсу

Подготовка к собеседованию по «System Design» с примерами на Python: AI, CRM и веб‑приложения

1️⃣ Что такое system design?

System design — это высокоуровневый подход к проектированию больших, масштабируемых и надёжных программных систем.
Вместо деталей кода (low‑level) вы рассматриваете:

Аспект Описание Почему важен на собеседовании
Метрики Скорость (latency), пропускная способность (throughput), количество одновременных пользователей, отказоустойчивость (availability), консистентность (consistency), стоимость (cost). Позволяют оценить, насколько правильно вы понимаете trade‑offs.
Требования Functional (что должна делать система) и non‑functional (как должна работать). Помогают построить «constraints map».
Контекст Ограничения: технологии, бюджет, сроки, уровень доступности (SLA). Обосновывают выбор конкретных решений.
Типичные цели Обеспечить горизонтальную масштабируемость, эластичное расширение, быструю реакцию на события, простоту поддержки. Стандартные задачи на собеседовании: «design X service».

2️⃣ Ключевые принципы и trade‑offs

Принцип Описание Как реализовать в Python
Scale‑out (горизонтальная масштабируемость) Добавлять машины, а не мощность CPU. gunicorn + uvicorn + docker‑compose, Kubernetes.
High Availability (HA) 99,9‑99,99 % доступности → репликация, fail‑over. SQLAlchemy + Postgres streaming replica, Redis Sentinel.
Consistency vs Latency CAP‑теорема. Для большинства систем используют eventual consistency (если допустима небольшая задержка). Cassandra + DataStax Python driver, Kafka streams.
Caching Reduce DB load → latency. redis-py (LRU, TTL), Memcached.
Rate limiting Защита от DDoS, fairness. flask‑limiter, redis‑based token bucket.
Circuit breaker Предотвратить распространение сбоя. pybreaker, gRPC retry.
Observability Logging, metrics, tracing. Prometheus + Grafana, OpenTelemetry (Python SDK), ELK.
Security Auth, secrets, data encryption. OAuth2 (Authlib), JWT, Vault + python‑hvac.

3️⃣ Архитектурные стили

Стиль Когда выбирать Преимущества Недостатки
Monolithic Начальный проект, малый объём данных, низкие требования к масштабируемости. Простота разработки, отладки, deployment. Сложно масштабировать отдельные части.
Layered (N‑Tier) Порядок business‑logic → service → data layers. Чёткая ответственность, тестируемость. Тяжёлый inter‑layer communication.
Microservices Высокий трафик, независимые команды, разные языки/технологии. Гибкость, независимое развертывание. Сложность orchestration, data consistency.
Event‑driven Системы с множеством асинхронных процессов (рекомендации, analytics). Лучшая latency, decoupling. Труднее следить за состоянием.
Serverless (AWS Lambda, Azure Functions) Ephemeral, cost‑effective workloads, infrequent spikes. Автоматическое scaling, без ops. Cold start, vendor lock‑in, ограниченная длительность.
Hybrid Комбинировать несколько стилей (например, monolith + microservice). Оптимальный trade‑off. Усложняет архитектурную документацию.

4️⃣ Практический процесс проектирования

Шаг Действие Что спросить у интервьюера
1️⃣ Clarify requirements Определить functional (use‑cases, API) и non‑functional (latency, QPS, data volume). «Сколько пользователей одновременно?», «Какая SLA?»
2️⃣ Define constraints Технологический стек, бюджет, время, законы (GDPR, HIPAA). «Какой backend язык?», «Можем использовать только Python?»
3️⃣ High‑level design Нарисовать блок‑диаграмму: clients → CDN → load balancer → API gateway → service → DB → cache. «Надо ли использовать CDN?», «Какие базы данных?»
4️⃣ Deep dive Выбрать конкретные компоненты (type of DB, caching strategy, messaging, consistency). «Какие запросы к базе самые частые?», «Какой тип данных?»
5️⃣ Evaluation & trade‑offs Сравнить варианты, оценить cost/availability/latency. «Почему выбрали eventual consistency?», «Какой будет cost‑increase при sharding?»
6️⃣ Mock up Представить в виде схемы, Flow‑chart, или ASCII‑art. «Покажите пример маршрутизации HTTP‑запроса».
7️⃣ Prepare follow‑up Обеспечить roadmap: monitoring, CI/CD, security. «Как будете масштабировать в случае нагрузки?», «Как собирать метрики?»

Tip: На собеседовании обычно нужно только один‑два варианта. Если время ограничено — фокусируйтесь на основных компонентах (API gateway, load balancer, DB, cache, messaging) и trade‑offs.


5️⃣ Конкретные примеры из разных областей

5.1. Instagram‑like (фото‑рекомендация + AI)

Компонент Технология (Python) Пример
Front‑end React + FastAPI (REST) SPA, медиа‑запросы к CDN.
API gateway Nginx + FastAPI Пост‑фильтрация, rate limiting (flask‑limiter).
Upload service FastAPI + Celery (asynchronous) + S3 Загрузка фото, генерация thumbnails (Pillow).
Cache Redis (LRU) Хранилище популярных фото, Cache-Control header.
DB PostgreSQL (relational) + TimescaleDB (temporal) Таблицы: users, posts, likes.
Search / tags ElasticSearch (Python elasticsearch-py) Полнотекстовый поиск, сортировка по популярности.
Recommendation TensorFlow Serving (Python client) + recommendation model (collaborative filtering) recommendations = model.predict(user_id) → ответ в /v1/recommend.
Async pipeline Kafka + confluent‑kafka Обработка событий: post_created, like, follow.
Observability OpenTelemetry + Jaeger, Prometheus + Grafana Metrics: QPS, latency, error rate.
CI/CD GitHub Actions → Docker → AWS ECS Автоматический тест и деплой.

Пример кода – FastAPI endpoint, кэширование и авторизация

# main.py
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
import redis
import sqlite3
from typing import List
import uuid

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/login")
redis_client = redis.StrictRedis(host="redis", decode_responses=True)

def get_current_user(token: str = Depends(oauth2_scheme)):
    # простая проверка токена
    user = redis_client.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
    return {"user_id": int(user.decode())}

@app.post("/posts")
def create_post(post: dict = Depends({"title": str, "content": str, "tags": List[str]}), user: dict = Depends(get_current_user)):
    # генерация уникального ID
    post_id = str(uuid.uuid4())
    # сохранение в PostgreSQL
    conn = sqlite3.connect(":memory:")
    c = conn.cursor()
    c.execute(
        "INSERT INTO posts (id, user_id, title, content, tags, created_at) VALUES (?, ?, ?, ?, ?, datetime('now'))",
        (post_id, user["user_id"], post["title"], post["content"], json.dumps(post["tags"]),)
    )
    conn.commit()
    # кэшировать популярный пост в Redis
    redis_client.setex(f"post:{post_id}", 300, json.dumps(post))
    return {"id": post_id, "status": "created"}

Ключевые моменты:

  • OAuth2 через токен → микросервис авторизации (/auth/login).
  • Redis для кэша популярного поста (TTL 5 min).
  • SQLite в примере, но в продакшене PostgreSQL + PgBouncer (pooling).

5.2. CRM‑система (Тинкф‑банк‑style)

Компонент Технология Описание
User / Customer PostgreSQL + SQLAlchemy ORM Таблицы: customers, contacts, activities.
Activity stream Kafka + Redis stream Хранение событий: call, email, chat.
Search / Segmentation ElasticSearch + scikit‑learn (clustering) Сегментация по RFM, behaviour.
AI‑score HuggingFace Transformers + ONNX Предсказание churn, propensity to purchase.
Email/SMS SendGrid / Twilio (API) Автоматические рассылки, Celery + RabbitMQ.
API FastAPI (REST) + GraphQL (optional) Публичные endpoint: /customers/{id}, /segments.
Analytics ClickHouse (columnar) Оперативные запросы к огромным логов (post_impression).
Security OAuth2 + JWT + Vault Хранение секретов (API‑keys).
Observability Prometheus + Grafana (metrics), OpenTelemetry (tracing) Monitoring запросов, latency per endpoint.

Пример: модель churn prediction (Python)

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
import joblib
import requests
from typing import List

# Предобработанные данные из PostgreSQL
df = pd.read_sql('SELECT customer_id, total_spent, last_login, days_since_last_purchase FROM customers', engine)

# Показатели churn
X = df[['total_spent', 'days_since_last_login', 'days_since_last_purchase']]
y = df['churned']   # 0/1

rf = RandomForestClassifier(n_estimators=200, max_depth=12, random_state=42)
rf.fit(X, y)

# Сохраняем модель
joblib.dump(rf, 'model/churn_rf.pkl')

# API‑endpoint для inference
def predict_churn(customer_id: int):
    df = pd.read_sql(f"SELECT total_spent, days_since_last_login, days_since_last_purchase FROM customers WHERE id = {customer_id}", engine)
    if df.empty:
        raise ValueError("Customer not found")
    X = df[['total_spent', 'days_since_last_login', 'days_since_last_purchase']].to_numpy()
    prob = joblib.load('model/churn_rf.pkl').predict_proba(X)[:, 1][0]
    return {"customer_id": customer_id, "churn_probability": float(prob)}

Плюсы:

  • FastAPI быстро обслуживает запросы к модели.
  • Model versioning через mlflow (можно добавить mlflow.api).

5.3. Online video streaming (Netflix‑like)

Компонент Технология Описание
Сервис FastAPI + Celery Запись, транскодинг (ffmpeg).
Пре‑рендер AWS MediaConvert (SDK), Python → boto3.  
Тип хранилища S3 (cold) + CDN (Edge) Объекты в /video/{video_id}.
Play‑list Cassandra (high write) + Redis (playlist cache).  
DRM Widevine / FairPlay (API).  
Analytics Kafka + Spark Structured Streaming (Python pyspark).  
Observability OpenTelemetry + Datadog (traces).  

Python‑пример: ingest‑pipeline с Kafka:

from confluent_kafka import Consumer, Producer
import json, uuid

def ingest_video(topic='raw_video'):
    conf = {'bootstrap.servers': 'kafka:9092'}
    consumer = Consumer(conf)
    consumer.subscribe([topic])
    while True:
        msg = consumer.poll(timeout=1.0)
        if msg is None:
            continue
        payload = json.loads(msg.value())
        video_id = str(uuid.uuid4())
        payload["id"] = video_id
        # отправляем в Redis‑queue для транскодинга
        producer = Producer({'bootstrap.servers': 'kafka:9092'})
        producer.produce('transcode_queue', key=msg.key(), value=json.dumps(payload))
        producer.poll(0)

Ключевой момент: отделение потоков – raw video → transcode → CDN.


6️⃣ Полезные приёмы и шаблоны

Шаблон Когда использовать Пример в Python
Circuit breaker Ограничить количество запросов к падющим сервисам. pybreaker.CircuitBreaker(fail_max=5, reset_timeout=60)
Bulkhead Исключить «каскадный сбой» при overload. concurrent.futures.Semaphore для ограничения потоков.
Back‑pressure Постепенно отклонять запросы, чтобы не переполнять очередь. celery + RabbitMQ prefetch_count.
Idempotent API Чтобы запросы могли быть повторены без вреда. Добавление idempotency_key в header.
Read‑heavy service При большом количестве GET‑запросов. Cache aside pattern: cache.get(key) → DB fallback.
Write‑heavy service При множестве UPDATE/DELETE. Write‑behind cache + eventual consistency.
Data partitioning По размеру или географии. Postgres sharding + pg‑shard.
Message ordering Для финансовых транзакций. Kafka topic with exactly‑once semantics (enable.idempotence=true).

7️⃣ Как готовиться к собеседованию

7.1. Чек‑лист вопросов

Категория Пример вопросов Как отвечать
Расчёт масштабируемости «Сколько серверов нужно для 1 M QPS?» Показываете формулы: C = Q / (TPS per server).
Кэширование «Какой TTL для товаров в каталоге?» Обсуждаете trade‑off: read‑heavy → longer TTL, price‑volatile → short TTL.
Репликация «Как обеспечить eventual consistency?» Приводите пример: primary‑secondary, CRDT, Cassandra.
API design «Как проектировать endpoint для упоминаний (likes)?» Показываете POST /posts/{id}/like, GET /posts/{id}/likes/count, Pagination.
Security «Как защитить токены от XSS?» HttpOnly, Secure, SameSite cookie, JWT + refresh token rotation.
Observability «Как собирать метрики latency per endpoint?» OpenTelemetry + Prometheus + Histogram.
Testing «Как проверить микросервис при реал‑тайм нагрузке?» Locust + pytest + Chaos Monkey.
Cost «Как снизить стоимость Cloud?» Spot Instances, Serverless, Cold‑start mitigation.

7.2. Общие ошибки, которые надо избежать

Ошибка Как её заметить Как исправить
Слишком глобальный design (все сразу) Вопрос «Explain step‑by‑step». Делайте iterative: сначала API, потом storage, затем caching.
Не учитывать consistency Отсутствие обсуждения trade‑offs. Добавьте CAP сценарий, покажите где eventual.
Переоценка «single‑instance» Нет упоминания scaling. Укажите auto‑scaling groups / K8s HPA.
Забыть про security Нет ответов о auth, encryption. Включите OAuth2 + JWT, TLS, RBAC.
Отсутствие observability Нет monitoring, alerts. Prometheus + Grafana, Jaeger.
Не упомянуть CI/CD Отсутствие continuous delivery. GitHub Actions → Docker → K8s.

7.3. Как структурировать свой ответ

  1. Начните с блок‑диаграммы (текст или ASCII).
  2. Разделите на layers: Frontend → CDN → LB → API → Service → DB → Cache → Message Queue.
  3. Опишите каждый слой (технологии, роль, trade‑off).
  4. Оцените metrics: QPS, latency, cost.
  5. Обсудите возможные optimisation (sharding, read‑replicas, caching).
  6. Завершите план по monitoring и CI/CD.

8️⃣ Список полезных ресурсов (Python‑ориентировано)

Тема Ресурс Почему полезен
Общие книги Designing Data‑Intensive Applications – Martin Kleppmann Покрывает CAP, storage, stream processing.
  System Design Interview – An Insider’s Guide – Alex Xu 200+ реальных вопросов + примеры.
Курсы Grokking the System Design Interview (Educative) Интерактивные задачи.
  CS374 (Stanford) – System Design (YouTube) Детальные лекции, PDF.
Python‑конкретные FastAPI docs Примеры REST‑/GRPC‑service.
  Celery + RabbitMQ (official docs) Asynch processing.
  Redis‑py (github) Примеры TTL, pipelines.
  Prometheus + OpenTelemetry (Python SDK) Observability.
  Kafka‑Python (confluent‑kafka) Стресс‑тесты, partition.
  mlflow (model versioning) Для AI‑интеграции.
Практика LeetCode / Pramp – system‑design tag Реальные задачи с решением.
  Interviewing.io (mock interviews) Похожие на реальные.
  Kaggle – pipelines + notebooks Примеры data pipelines.

9️⃣ Финальные рекомендации

  1. Запоминайте формулировку: «We have X users, Y QPS, Z latency budget, A consistency requirement, B cost limit».
  2. Отвечайте только на основные части, детализируйте только если задают «follow‑up».
  3. Показывайте код только когда он нужен (примеры API, кэша, модели).
  4. Не перегружайте ответ – 5‑7 key пунктов + один‑два code‑фрагмента обычно хватает.
  5. Выбирайте одну технологию и объясняйте её глубже, чем 5‑6 поверхностных.
  6. Повторно проверьте метрики: «Что будет, если QPS вырастет в 10×? Какой будет новый cost?».

📚 Сводка готового «пособия»

  • Ориентировка на метрики, trade‑offs, constraints.
  • Архитектурные стили и их применение в реальных сценариях.
  • Примеры: Instagram‑like, CRM, видеоплатформы с AI‑компонентом.
  • Python‑конкретные реализации: FastAPI, Celery, Redis, Kafka, MLflow, ml‑pipeline.
  • Ключевые шаблоны (circuit‑breaker, cache‑aside, bulkhead).
  • Чек‑лист вопросов и типичные ошибки.
  • Ссылки к литературе и практике.

Этого должно хватить, чтобы получить полное и гибкое понимание system design, а также быстро готовить решения на собеседовании. Если нужны более детальные примеры по конкретной части (например, кэш‑эвалюатор, конфигурация K8s, построение recommendation‑pipeline), дайте знать — я подготовлю отдельные микро‑модули. 🚀