Стройте ответ вокруг владения состоянием, лимитов, отказа и восстановления. Определение становится инженерным ответом только в конкретном production-сценарии.
Вопросы и ответы
33 подробных ответа
01Что такое модель OSI и какие у неё уровни?
junior
Короткий ответ: OSI — это эталонная (теоретическая) модель, разбивающая сетевое взаимодействие на 7 уровней, где каждый уровень предоставляет услуги вышестоящему и пользуется услугами нижестоящего. На практике используется реже, чем TCP/IP, но удобна для обсуждения и диагностики.
Подробно:
Уровни снизу вверх (мнемоника: «Please Do Not Throw Sausage Pizza Away»):
| № | Уровень | Что делает | Единица данных | Примеры |
|---|---|---|---|---|
| 7 | Application (Прикладной) | Взаимодействие с приложением | Data | HTTP, DNS, FTP, SMTP |
| 6 | Presentation (Представления) | Кодирование, шифрование, сжатие | Data | TLS, JPEG, ASCII |
| 5 | Session (Сеансовый) | Установка/управление сессией | Data | sockets, RPC |
| 4 | Transport (Транспортный) | Доставка между процессами, порты | Segment (TCP)/Datagram (UDP) | TCP, UDP |
| 3 | Network (Сетевой) | Логическая адресация, маршрутизация | Packet | IP, ICMP |
| 2 | Data Link (Канальный) | Передача в пределах сегмента сети, MAC | Frame | Ethernet, Wi-Fi, ARP |
| 1 | Physical (Физический) | Биты по среде передачи | Bit | кабели, радио, оптика |
Каждый уровень при отправке добавляет свой заголовок (инкапсуляция), при получении — снимает его (декапсуляция). Например, HTTP-данные оборачиваются в TCP-сегмент, тот — в IP-пакет, тот — в Ethernet-кадр.
Схема инкапсуляции:
[ Ethernet [ IP [ TCP [ HTTP-данные ] ] ] ]
L2 L3 L4 L7
⚠️ Ловушка: TLS/шифрование часто относят к уровню 6 (Presentation) в OSI, но в реальной модели TCP/IP его помещают между транспортом и приложением. Не путайте «теоретический» уровень с практикой. Также MAC-адрес — это L2, а IP-адрес — L3; их часто смешивают.
02Модель TCP/IP и её соответствие OSI
middle
Короткий ответ: TCP/IP — практическая модель из 4 (иногда 5) уровней, на которой реально работает интернет. Она проще OSI и объединяет несколько OSI-уровней в один.
Подробно:
| TCP/IP уровень | Соответствие OSI | Протоколы |
|---|---|---|
| Application | 5+6+7 (Session, Presentation, Application) | HTTP, DNS, TLS, SMTP, gRPC |
| Transport | 4 (Transport) | TCP, UDP, QUIC |
| Internet | 3 (Network) | IP, ICMP, ARP |
| Link / Network Access | 1+2 (Physical, Data Link) | Ethernet, Wi-Fi |
Главное отличие: OSI — это эталон «как должно быть устроено», TCP/IP — описание того, как реально работает интернет. В TCP/IP всё, что выше транспорта (сессии, представление, приложение), отдано на откуп самому приложению.
Поток данных при HTTP-запросе:
Браузер (Application) -> TCP-сегмент (Transport) -> IP-пакет (Internet) -> Ethernet-кадр (Link) -> провод
⚠️ Ловушка: На собеседовании могут спросить «на каком уровне работает роутер/коммутатор?». Коммутатор (switch) — L2 (по MAC), роутер — L3 (по IP), а L7-балансировщик/прокси — прикладной уровень. Путаница тут — частая ошибка.
03TCP vs UDP — в чём разница и когда что использовать?
junior
Короткий ответ: TCP — надёжный, упорядоченный, с установкой соединения и контролем перегрузки, но медленнее. UDP — быстрый, без соединения, без гарантий доставки и порядка. TCP для веба/файлов, UDP для видео/игр/DNS.
Подробно:
| Свойство | TCP | UDP |
|---|---|---|
| Соединение | С установкой (handshake) | Без соединения |
| Надёжность | Гарантирует доставку (ACK + retransmit) | Не гарантирует |
| Порядок | Упорядочивает сегменты | Может прийти не по порядку |
| Контроль потока/перегрузки | Есть | Нет |
| Скорость/overhead | Медленнее, больше overhead | Быстрее, минимум overhead |
| Заголовок | 20+ байт | 8 байт |
| Применение | HTTP, файлы, БД, почта | Видео, голос, игры, DNS, DHCP |
Заголовок TCP (упрощённо): порт источника, порт назначения, sequence number, acknowledgment number, флаги (SYN/ACK/FIN/RST/PSH/URG), window size, checksum. ~20 байт без опций.
Заголовок UDP: порт источника, порт назначения, длина, checksum. Всего 8 байт.
Когда что:
- Видеозвонок/стрим/игра: лучше потерять кадр, чем ждать его повторной передачи (задержка хуже потери) -> UDP.
- Файлы/веб/банковская транзакция: каждый байт важен, порядок критичен -> TCP.
- DNS: короткий запрос, повтор дешевле, чем держать соединение -> UDP (с откатом на TCP для больших ответов).
⚠️ Ловушка: «UDP не гарантирует доставку» не значит «UDP теряет данные». В нормальной сети UDP-пакеты доходят прекрасно; просто нет встроенного механизма повтора. Приложение само решает, нужна ли ему надёжность (например, QUIC реализует надёжность поверх UDP).
04TCP: трёхстороннее рукопожатие (3-way handshake)
middle
Короткий ответ: Перед обменом данными TCP устанавливает соединение тремя сообщениями: SYN -> SYN-ACK -> ACK. Это синхронизирует начальные порядковые номера обеих сторон.
Подробно:
Клиент Сервер
| ---- SYN (seq=x) ----------> | "хочу соединиться, мой ISN=x"
| |
| <-- SYN-ACK (seq=y,ack=x+1)- | "ок, мой ISN=y, подтверждаю x"
| |
| ---- ACK (ack=y+1) --------> | "подтверждаю y, поехали"
| |
| ===== соединение открыто =====|
- SYN: клиент отправляет сегмент с флагом SYN и своим начальным sequence number (ISN = x).
- SYN-ACK: сервер отвечает SYN (свой ISN = y) + ACK (подтверждает x+1).
- ACK: клиент подтверждает y+1. Соединение установлено.
Зачем три, а не два: обе стороны должны (а) согласовать начальные порядковые номера и (б) убедиться, что канал работает в обе стороны. ISN выбирается случайно для защиты от спуфинга и старых дублей.
Стоимость: handshake — это 1 RTT (round-trip) до отправки первых данных. Поэтому установка нового TCP-соединения недёшева — отсюда keep-alive и пулы соединений.
⚠️ Ловушка: SYN flood — атака, когда злоумышленник шлёт много SYN, не завершая handshake, переполняя очередь полуоткрытых соединений. Защита — SYN cookies. Также важно: первые данные нельзя послать раньше, чем завершится handshake (кроме TCP Fast Open).
05TCP: завершение соединения (4-way handshake)
middle
Короткий ответ: Закрытие требует четырёх сообщений, потому что соединение полнодуплексное и каждая сторона закрывает свою половину отдельно: FIN -> ACK -> FIN -> ACK.
Подробно:
Клиент Сервер
| ---- FIN ---------------> | "я закончил отправку"
| <--- ACK ---------------- | "принял"
| <--- FIN ---------------- | "я тоже закончил"
| ---- ACK ---------------> | "принял"
| (TIME_WAIT ~2*MSL) |
- Клиент шлёт FIN (закрывает свою сторону на отправку).
- Сервер подтверждает ACK (но может ещё досылать данные).
- Сервер шлёт FIN.
- Клиент подтверждает ACK и входит в состояние TIME_WAIT.
TIME_WAIT: инициатор закрытия ждёт ~2×MSL (Maximum Segment Lifetime), чтобы гарантированно «погасить» запоздавшие пакеты и корректно обработать повторный FIN. Поэтому на нагруженных серверах накапливается множество сокетов в TIME_WAIT.
⚠️ Ловушка: Много сокетов в TIME_WAIT на сервере, который инициирует закрытие, может исчерпать порты/память. Обычно соединение закрывает клиент. Также бывает «3.5-way» — когда ACK и FIN сервера объединяются в один сегмент.
06TCP: порядковые номера, ACK и повторная передача
middle
Короткий ответ: Каждый байт нумеруется sequence number; получатель подтверждает (ACK), какой следующий байт ожидает. Если ACK не пришёл за время RTO (timeout) — сегмент пересылается.
Подробно:
- Sequence number нумерует байты потока, не сегменты.
- ACK — кумулятивный: «получил всё до байта N, жду N». Если потерян сегмент в середине, ACK будет повторяться на старое значение.
- Повторная передача двумя путями:
- RTO (Retransmission Timeout): не пришёл ACK за расчётное время -> пересылаем.
- Fast retransmit: получение 3 дублирующих ACK означает, что сегмент потерян — пересылаем, не дожидаясь таймаута.
- SACK (Selective ACK): опция, позволяющая подтвердить выборочно полученные блоки, чтобы не пересылать уже доставленное.
Пример: отправлены байты 1–1000 в сегментах по 100. Потерян сегмент 301–400. Получатель шлёт ACK=301 на каждый последующий сегмент. После 3 дублей ACK=301 отправитель пересылает 301–400 (fast retransmit).
⚠️ Ловушка: RTO рассчитывается динамически по сглаженному RTT (алгоритм Jacobson/Karn), не фиксирован. Karn's algorithm запрещает измерять RTT по повторно переданным сегментам (неоднозначность, на какой ACK отвечают).
07TCP: контроль потока (flow control, sliding window)
middle
Короткий ответ: Flow control защищает медленного получателя от быстрого отправителя. Получатель в каждом ACK сообщает размер своего окна (advertised window) — сколько байт он готов принять. Отправитель не шлёт больше.
Подробно:
- У получателя есть буфер приёма. В поле
window sizeкаждого ACK он сообщает, сколько свободного места осталось. - Sliding window: отправитель может иметь «в полёте» (без подтверждения) не больше, чем размер окна. По мере прихода ACK окно «скользит» вперёд.
- Если буфер получателя заполнен, он рекламирует window=0, и отправитель приостанавливается, периодически шля window probe.
Окно отправителя:
[ отправлено+ACK | отправлено, ждёт ACK | можно отправить | нельзя ]
^----- window size -----^
Отличие от congestion control: flow control — про возможности получателя (rwnd). Congestion control — про возможности сети (cwnd). Реальный объём «в полёте» = min(rwnd, cwnd).
⚠️ Ловушка: Не путайте flow control (защита получателя) и congestion control (защита сети) — это два разных механизма с двумя разными окнами. «Silly window syndrome» — патология, когда окно открывается крошечными кусочками; лечится алгоритмами Nagle (на отправке) и Clark (на приёме).
08TCP: контроль перегрузки (congestion control)
senior
Короткий ответ: Congestion control не даёт отправителю перегрузить сеть. TCP постепенно наращивает скорость и резко снижает при признаках потерь. Ключевые фазы: slow start, congestion avoidance, fast recovery.
Подробно:
Поддерживается окно перегрузки cwnd. Реально в полёте = min(cwnd, rwnd).
- Slow start: cwnd начинается с 1–10 MSS и удваивается каждый RTT (экспоненциальный рост) до достижения ssthresh.
- Congestion avoidance: после ssthresh рост линейный (+1 MSS за RTT) — аккуратное прощупывание пропускной способности.
- Признак потери:
- 3 дубль-ACK -> fast retransmit + fast recovery: ssthresh = cwnd/2, cwnd = ssthresh (умеренное снижение).
- Timeout (RTO) -> серьёзная перегрузка: ssthresh = cwnd/2, cwnd сбрасывается в 1, снова slow start.
Алгоритмы: классические Reno/NewReno, современные CUBIC (по умолчанию в Linux, агрессивнее по линку с высокой задержкой), BBR (Google, моделирует пропускную способность и RTT, не реагирует на потери как на единственный сигнал перегрузки).
cwnd
| /\ /\
| / \ /
| / \ / slow start (экспонента) -> avoidance (линия)
| / \__/ \__ потеря -> снижение
+---------------------------> время
⚠️ Ловушка: В беспроводных сетях потеря пакета не всегда означает перегрузку (может быть помеха), но классический TCP трактует любую потерю как перегрузку и снижает скорость — отсюда деградация на Wi-Fi/мобильных. BBR частично решает это, не полагаясь только на потери.
09IPv4 vs IPv6: адресация
junior
Короткий ответ: IPv4 — 32-битные адреса (~4.3 млрд), записываются как 4 октета (192.168.1.1). IPv6 — 128-битные (практически неисчерпаемо), записываются в hex через двоеточия. IPv6 создан из-за исчерпания IPv4.
Подробно:
| IPv4 | IPv6 | |
|---|---|---|
| Длина | 32 бита | 128 бит |
| Запись | 192.168.0.1 | 2001:0db8:85a3::8a2e:0370:7334 |
| Адресов | ~4.3×10⁹ | ~3.4×10³⁸ |
| Заголовок | переменный, со checksum | фиксированный 40 байт, без checksum |
| NAT | широко используется | в основном не нужен |
| Автоконфигурация | DHCP | SLAAC + DHCPv6 |
IPv6 сокращения: группы нулей :: (один раз в адресе), ведущие нули в группе опускаются. 2001:0db8:0000:0000:0000:0000:0000:0001 = 2001:db8::1.
IPv6 убрал broadcast (есть multicast/anycast), упростил заголовок, встроил IPsec (изначально), убрал checksum (его делает транспорт/канал).
⚠️ Ловушка: IPv4 и IPv6 не совместимы напрямую — нужен dual-stack или туннелирование/трансляция. Адрес ::1 — это IPv6-localhost (аналог 127.0.0.1). Не путайте :: (любой адрес / wildcard) и ::1 (loopback).
10Подсети, маски, публичные/приватные адреса, NAT
middle
Короткий ответ: Маска делит IP на сетевую и хостовую части. Приватные диапазоны (10/8, 172.16/12, 192.168/16) не маршрутизируются в интернете; NAT транслирует их в один публичный адрес.
Подробно:
- CIDR-нотация:
192.168.1.0/24означает, что первые 24 бита — сеть, остальные 8 — хосты (256 адресов, из них 254 для хостов, плюс адрес сети и broadcast). - Маска /24 =
255.255.255.0. - Приватные диапазоны (RFC 1918):
10.0.0.0/8172.16.0.0/12192.168.0.0/16
- NAT (Network Address Translation): роутер заменяет приватный src-адрес на свой публичный и запоминает в таблице соответствие (с портом — это PAT/NAPT). Ответ приходит на публичный адрес, роутер по таблице возвращает его нужному внутреннему хосту.
ПК 192.168.1.5:54321 --NAT--> 203.0.113.7:60000 --> сервер
<--NAT-- <-- ответ
NAT — основная причина, почему IPv4 «дожил» до сих пор: тысячи устройств за одним публичным IP.
⚠️ Ловушка: NAT ломает входящие соединения «снаружи внутрь» (нужен port forwarding / NAT traversal — STUN/TURN/hole punching, например для P2P/WebRTC). Также: NAT — это не firewall, хотя побочно скрывает внутренние адреса.
11Порты, сокеты и well-known порты
junior
Короткий ответ: Порт (16 бит, 0–65535) идентифицирует процесс/сервис на хосте. Сокет — это пара (IP-адрес + порт). Соединение однозначно определяется четвёркой: (src IP, src port, dst IP, dst port).
Подробно:
- Диапазоны портов:
- 0–1023 — well-known (системные).
- 1024–49151 — registered.
- 49152–65535 — динамические/эфемерные (для клиентов).
- Well-known порты:
| Порт | Сервис |
|---|---|
| 20/21 | FTP |
| 22 | SSH |
| 25 | SMTP |
| 53 | DNS |
| 80 | HTTP |
| 110 | POP3 |
| 143 | IMAP |
| 443 | HTTPS |
| 3306 | MySQL |
| 5432 | PostgreSQL |
| 6379 | Redis |
| 27017 | MongoDB |
Соединение идентифицируется 4-tuple. Поэтому один сервер на порту 443 обслуживает тысячи клиентов — у каждого свой (src IP, src port).
⚠️ Ловушка: Клиент использует случайный эфемерный порт, сервер слушает фиксированный. «Address already in use» при рестарте сервера — обычно из-за сокетов в TIME_WAIT; лечится опцией SO_REUSEADDR. И помните: порт — это транспортный уровень (L4), а не сетевой.
12Что такое DNS и зачем он нужен?
junior
Короткий ответ: DNS (Domain Name System) — распределённая иерархическая система, переводящая человекочитаемые доменные имена (example.com) в IP-адреса. Это «телефонная книга интернета».
Подробно:
Люди запоминают имена, а машины маршрутизируют по IP. DNS делает этот перевод. Плюс DNS даёт:
- Уровень абстракции: можно сменить IP сервера, не меняя имя.
- Распределение нагрузки: одно имя -> несколько IP (round-robin), GeoDNS возвращает ближайший сервер.
- Сервисную информацию: MX (почта), TXT (верификация, SPF/DKIM) и т.д.
Работает в основном поверх UDP порт 53 (для больших ответов и зонных передач — TCP). DNS over HTTPS/TLS (DoH/DoT) шифрует запросы.
⚠️ Ловушка: «Зачем DNS, почему не ходить сразу по IP?» — потому что IP меняются (миграция, балансировка, CDN отдаёт разный IP по геолокации), а имена стабильны и читаемы. Привязка к IP сделала бы инфраструктуру хрупкой.
13DNS: иерархия и пошаговый резолв
middle
Короткий ответ: DNS-иерархия: root-серверы -> TLD-серверы (.com, .ru) -> authoritative-серверы домена. Рекурсивный резолвер опрашивает их по очереди от корня вниз и кэширует результат.
Подробно:
Иерархия читается справа налево: www.example.com. (точка в конце — корень).
Пошаговый резолв www.example.com:
1. Браузер/ОС: есть в кэше? -> если да, готово.
2. Запрос к рекурсивному резолверу (обычно провайдер или 8.8.8.8 / 1.1.1.1).
3. Резолвер -> ROOT-сервер: "где .com?" -> ответ: "спроси у TLD-серверов .com".
4. Резолвер -> TLD-сервер (.com): "где example.com?" -> "спроси authoritative ns1.example.com".
5. Резолвер -> Authoritative-сервер: "какой A-record у www.example.com?" -> "93.184.216.34".
6. Резолвер кэширует ответ (на время TTL) и возвращает клиенту.
Клиент -> Recursive Resolver -> Root -> TLD (.com) -> Authoritative (example.com)
^------- кэширует на каждом шаге --------|
- Рекурсивный резолвер делает всю работу за клиента и возвращает финальный ответ.
- Итеративные запросы — между резолвером и серверами иерархии (каждый отвечает «не знаю, спроси там»).
⚠️ Ловушка: Root-серверов логически 13 (a–m), но физически это тысячи машин по anycast. Клиент почти всегда делает рекурсивный запрос; итеративную работу выполняет резолвер. Также: первый резолв «холодный» (медленный), последующие берутся из кэша.
14DNS: типы записей и кэширование/TTL
middle
Короткий ответ: Записи описывают разные данные домена: A/AAAA (IP), CNAME (алиас), MX (почта), TXT (текст), NS (серверы имён). У каждой есть TTL — сколько секунд её можно кэшировать.
Подробно:
| Запись | Назначение |
|---|---|
| A | имя -> IPv4 |
| AAAA | имя -> IPv6 |
| CNAME | алиас на другое имя (www -> example.com) |
| MX | почтовый сервер домена (с приоритетом) |
| TXT | произвольный текст: SPF, DKIM, верификация владения |
| NS | authoritative name-серверы зоны |
| SOA | метаданные зоны (серийный номер, TTL) |
| PTR | обратный резолв IP -> имя |
| SRV | расположение сервиса (host+port) |
TTL и кэширование: TTL (в секундах) указывает, сколько резолверы/клиенты могут хранить запись. Низкий TTL — быстрое распространение изменений, но больше запросов. Высокий TTL — меньше нагрузки, но изменения «доходят» медленно.
⚠️ Ловушка: CNAME нельзя ставить на корень домена (apex, example.com) — там должна быть A/AAAA или специальные ALIAS/ANAME записи у провайдера. Также при миграции заранее снижают TTL, чтобы переключение прошло быстро. «Изменил DNS — но старый IP ещё отвечает» — это работающий кэш с недоистёкшим TTL.
15HTTP как протокол: stateless, поверх TCP
junior
Короткий ответ: HTTP — прикладной протокол запрос/ответ, работающий (в версиях 1.x и 2) поверх TCP. Он stateless: сервер по умолчанию не помнит предыдущие запросы; состояние держат cookies/токены.
Подробно:
- Stateless: каждый запрос самодостаточен. Сервер не обязан хранить контекст между запросами. Это упрощает масштабирование (любой запрос может уйти на любой инстанс).
- Поверх TCP: HTTP/1.1 и HTTP/2 используют TCP (надёжность, порядок). HTTP/3 — поверх QUIC/UDP.
- Состояние эмулируется через cookies, сессии, токены (Authorization header).
Сетевой аспект: одно TCP-соединение несёт текстовые HTTP/1.1 или бинарные HTTP/2 сообщения. Метод выражает намерение (GET безопасен, PUT идемпотентен, POST обычно нет), код статуса сообщает класс результата, а Cache-Control, ETag и условные запросы управляют повторным использованием ответа клиентом и прокси.
⚠️ Ловушка: «Stateless» относится к протоколу, а не к приложению — приложение хранит состояние (в БД/сессии). И HTTP/1.1 keep-alive не делает протокол stateful: соединение переиспользуется, но каждый запрос всё ещё независим.
Детали версий, методов и кодов статусов — в отдельном файле по HTTP.
16HTTPS/TLS: handshake подробно
senior
Короткий ответ: HTTPS = HTTP поверх TLS. TLS-handshake устанавливает шифрованный канал: стороны договариваются о шифрах, сервер предъявляет сертификат, обмениваются ключевым материалом через асимметрию, после чего переходят на быстрый симметричный сеансовый ключ.
Подробно (TLS 1.2, классическая схема):
Клиент Сервер
| -- ClientHello --------------------> | версии TLS, список cipher suites, random
| <-- ServerHello ------------------- | выбранный cipher, random
| <-- Certificate ------------------- | сертификат сервера (публичный ключ)
| <-- ServerHelloDone --------------- |
| -- ClientKeyExchange --------------> | pre-master secret, шифрован публ. ключом
| -- ChangeCipherSpec / Finished ----> | переходим на симметричный ключ
| <-- ChangeCipherSpec / Finished --- |
| ====== шифрованный обмен данными === |
Шаги:
- ClientHello: клиент шлёт версии TLS, поддерживаемые cipher suites, случайное число (client random).
- ServerHello + Certificate: сервер выбирает шифр, шлёт свой сертификат (с публичным ключом) и server random.
- Проверка сертификата: клиент проверяет цепочку доверия до доверенного CA, срок, домен.
- Обмен ключами: клиент генерирует pre-master secret, шифрует публичным ключом сервера (или через ECDHE — обмен параметрами Diffie-Hellman, подписанными сертификатом). Только сервер может расшифровать своим приватным ключом.
- Вывод сеансового ключа: обе стороны из (client random + server random + pre-master secret) выводят одинаковый симметричный сеансовый ключ.
- Дальше весь трафик шифруется быстрым симметричным алгоритмом (AES).
TLS 1.3 упростил handshake до 1 RTT (и 0-RTT для повторных), убрал устаревшие шифры, сделал ECDHE обязательным (forward secrecy).
Зачем асимметрия только для обмена ключом: асимметричное шифрование медленное, но решает проблему «как договориться о секрете по открытому каналу». Симметричное — быстрое, но требует общего секрета. Поэтому асимметрию используют один раз, чтобы безопасно установить симметричный сеансовый ключ, а дальше работают симметрично.
Что шифруется: тело и заголовки HTTP, путь, query-параметры, cookies. Не шифруется: IP-адрес назначения и имя хоста в SNI (в обычном TLS; ESNI/ECH это закрывают), сам факт соединения.
⚠️ Ловушка: TLS даёт forward secrecy только с эфемерным обменом ключей (ECDHE), где pre-master не передаётся, зашифрованный долгоживущим ключом. Со старой RSA-схемой утечка приватного ключа сервера позволяет расшифровать весь ранее записанный трафик. Также частая ошибка — называть это «SSL»: SSL устарел, используется TLS.
17Сертификаты, CA и цепочка доверия, MITM
middle
Короткий ответ: Сертификат связывает домен с публичным ключом и подписан удостоверяющим центром (CA). Браузер доверяет корневым CA из своего хранилища; цепочка подписей от сертификата сервера до корневого CA образует chain of trust. Это защищает от MITM.
Подробно:
Цепочка доверия:
Root CA (в хранилище ОС/браузера)
-> Intermediate CA (подписан root)
-> Сертификат сервера example.com (подписан intermediate)
Браузер проверяет: подпись каждого звена валидна, сертификат не истёк, домен совпадает (CN/SAN), сертификат не отозван (CRL/OCSP).
Как защищает от MITM: злоумышленник посередине может перехватить трафик, но не может подделать валидный сертификат для домена — у него нет приватного ключа сервера и нет подписи доверенного CA. Браузер покажет ошибку сертификата.
Когда MITM возможен: если в хранилище доверенных добавлен левый корневой CA (корпоративный proxy, малварь) — тогда перехват «легален» для системы. Поэтому corporate TLS inspection работает только с установленным корпоративным CA.
⚠️ Ловушка: Самоподписанный сертификат шифрует трафик так же надёжно, но не аутентифицирует сервер (нет доверенного CA) — отсюда предупреждение браузера. Шифрование ≠ доверие. Для критичных приложений применяют certificate pinning (жёсткая привязка к конкретному сертификату/ключу), чтобы защититься даже от скомпрометированного CA.
18HTTP/2 и HTTP/3 (QUIC), head-of-line blocking
middle
Короткий ответ: HTTP/2 мультиплексирует много запросов по одному TCP-соединению (бинарный протокол, сжатие заголовков), но страдает от TCP head-of-line blocking. HTTP/3 переносит всё на QUIC поверх UDP, устраняя эту проблему.
Подробно:
HTTP/1.1: один запрос за раз на соединение (или конвейеризация, которая на практике не прижилась). Браузеры открывали ~6 параллельных TCP-соединений к домену.
HTTP/2:
- Бинарный фрейминг, мультиплексирование: множество параллельных потоков (streams) по одному TCP-соединению.
- Сжатие заголовков (HPACK), server push (устарел).
- Проблема — TCP head-of-line blocking: если потерян один TCP-сегмент, ВСЕ мультиплексированные потоки ждут его повторной передачи, потому что TCP гарантирует порядок на уровне всего соединения.
HTTP/3 (QUIC):
- Работает поверх UDP, реализует надёжность, упорядоченность и контроль перегрузки сам.
- Потоки независимы: потеря пакета в одном потоке не блокирует другие (HoL blocking решён на транспортном уровне).
- TLS 1.3 встроен в QUIC; соединение устанавливается за 1 RTT (или 0-RTT).
- Connection migration: соединение переживает смену IP (Wi-Fi -> LTE) по Connection ID.
HTTP/2: [ HTTP streams ] -> один TCP (HoL blocking при потере)
HTTP/3: [ HTTP streams ] -> QUIC -> UDP (потоки независимы)
⚠️ Ловушка: HTTP/2 решает HoL только на прикладном уровне; на транспортном (TCP) блокировка остаётся — это и есть мотивация HTTP/3. Также QUIC шифрует почти весь транспортный заголовок, что усложняет работу фаерволов и иногда блокируется сетями (UDP/443).
19WebSockets: апгрейд, full-duplex
middle
Короткий ответ: WebSocket — протокол полнодуплексной двусторонней связи поверх одного TCP-соединения. Начинается как HTTP-запрос с заголовком Upgrade, после чего соединение «переключается» на ws-протокол и остаётся открытым.
Подробно:
Установка (handshake):
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
После 101 Switching Protocols соединение остаётся открытым; обе стороны могут слать сообщения в любой момент (full-duplex), без накладных расходов на новые HTTP-запросы.
- vs HTTP: HTTP — запрос/ответ (клиент инициирует). WebSocket — двунаправленный, сервер может пушить.
- Использует те же порты 80/443 (
ws:///wss://), что удобно для прохождения фаерволов. - Поверх TCP.
Когда: чаты, онлайн-игры, коллаборативные редакторы, торговые тикеры, live-уведомления — всё, где нужна низкая задержка и push от сервера.
⚠️ Ловушка: WebSocket — поверх TCP, поэтому ему тоже свойствен head-of-line blocking. И через прокси/балансировщики L7 нужно явно разрешать Upgrade и держать долгоживущие соединения (иначе их рвут по таймауту). Масштабирование требует sticky-сессий или общего pub/sub (Redis).
20Server-Sent Events и long polling для realtime
middle
Короткий ответ: Для realtime есть три подхода поверх HTTP: long polling (имитация push), Server-Sent Events (однонаправленный поток от сервера), и WebSockets (полнодуплекс). Выбор зависит от направления и частоты данных.
Подробно:
| Техника | Направление | Соединение | Когда |
|---|---|---|---|
| Long polling | сервер->клиент (с задержкой) | запрос висит, пока есть данные, потом переоткрывается | простой fallback, редкие события |
| SSE | только сервер->клиент | одно долгоживущее HTTP-соединение, text/event-stream |
новостные ленты, уведомления, прогресс |
| WebSocket | двунаправленный | постоянное TCP | чаты, игры, интерактив |
- Long polling: клиент делает запрос, сервер держит его открытым до появления данных или таймаута, отвечает, клиент тут же шлёт новый. Высокий overhead, но работает везде.
- SSE: браузерный
EventSource, автоматический реконнект, простой текстовый формат, только от сервера к клиенту, работает поверх обычного HTTP (и выигрывает от HTTP/2 мультиплексирования).
⚠️ Ловушка: SSE однонаправлен (нельзя слать от клиента к серверу по тому же каналу — нужен отдельный HTTP-запрос) и ограничен числом соединений на домен в HTTP/1.1 (~6). WebSocket двунаправлен, но тяжелее в инфраструктуре. Long polling прост, но расточителен по соединениям и задержке.
21Что происходит, когда вводишь URL и жмёшь Enter?
concept
Короткий ответ: Браузер парсит URL -> резолвит домен в IP через DNS -> устанавливает TCP-соединение -> делает TLS-handshake (для HTTPS) -> шлёт HTTP-запрос -> получает ответ -> рендерит страницу, подгружая ресурсы. Это классический «end-to-end» вопрос.
Подробно, пошагово:
1. Разбор URL и проверки браузера
- Браузер парсит
https://www.example.com/page?q=1: схема, хост, порт, путь, query. - Проверка HSTS (форсит HTTPS), кэш браузера (вдруг ответ уже есть).
2. DNS-резолв
- Проверка кэшей: браузер -> ОС -> hosts-файл -> рекурсивный резолвер.
- При промахе рекурсивный резолвер последовательно получает referral от root к TLD (
.com), затем адрес authoritative-сервера домена и уже у него запрашивает A/AAAA-запись. Ответ кэшируется на каждом уровне не дольше TTL.
3. Установка TCP-соединения
- 3-way handshake (SYN / SYN-ACK / ACK) с IP сервера на порт 443. ~1 RTT.
4. TLS-handshake (для HTTPS)
- ClientHello/ServerHello, проверка сертификата и цепочки доверия, обмен ключами, вывод симметричного сеансового ключа. ~1 RTT (TLS 1.3) или 2 RTT (TLS 1.2).
5. HTTP-запрос
GET /page?q=1 HTTP/2
Host: www.example.com
User-Agent: ...
Cookie: session=...
Accept: text/html
6. Обработка на сервере
- Балансировщик/reverse proxy/CDN -> приложение -> возможно БД -> формирование ответа.
7. HTTP-ответ
HTTP/2 200 OK
Content-Type: text/html
Set-Cookie: ...
Cache-Control: ...
<html>...</html>
8. Рендеринг в браузере
- Парсинг HTML -> построение DOM.
- Обнаружение ссылок на CSS/JS/изображения -> параллельные запросы (часто к CDN), каждый может потребовать свой DNS/TCP/TLS (или переиспользовать соединения).
- Построение CSSOM, дерева рендера, layout, paint, compositing.
- Выполнение JS, который может догружать данные (fetch/XHR).
9. Закрытие/переиспользование
- Соединения держатся открытыми (keep-alive) для последующих запросов; в конце закрываются (FIN).
URL -> DNS -> TCP -> TLS -> HTTP-запрос -> сервер -> HTTP-ответ -> рендеринг -> доп. ресурсы
⚠️ Ловушка: Хороший ответ упоминает кэши на каждом уровне (браузер, DNS, CDN), параллелизм запросов к ресурсам и то, что рендеринг — отдельный большой этап. Слабый ответ заканчивается на «получили HTML». Также стоит упомянуть, что современный браузер может предзагружать DNS/TCP (prefetch, preconnect).
22Latency vs bandwidth vs throughput, RTT
middle
Короткий ответ: Latency — задержка (время на путь, мс). Bandwidth — максимальная пропускная способность канала (бит/с). Throughput — реально достигнутая скорость передачи. RTT — время на путь туда-обратно.
Подробно:
- Latency (задержка): сколько времени данные идут от A до B. Складывается из задержки распространения (скорость света в среде), обработки, очередей, сериализации. Ограничена физикой (через океан ~их десятки мс минимум).
- Bandwidth (полоса пропускания): теоретический максимум канала, «ширина трубы» (например, 1 Гбит/с).
- Throughput (пропускная способность фактическая): сколько реально передаётся с учётом потерь, перегрузки, overhead протоколов. Всегда ≤ bandwidth.
- RTT (Round-Trip Time): время «туда и обратно». Критично для протоколов с handshake — каждый RTT добавляет задержку перед данными.
Аналогия: bandwidth — ширина трубы, latency — длина трубы, throughput — реальный поток воды.
Почему важно: TCP handshake (1 RTT) + TLS handshake (1–2 RTT) — это 2–3 RTT до первого байта данных. При RTT 100 мс это 200–300 мс «впустую». Отсюда CDN (сократить расстояние = latency), keep-alive, TLS 1.3, QUIC 0-RTT.
⚠️ Ловушка: Увеличение bandwidth не уменьшает latency. Толстый канал не ускорит «пинг». Для интерактивных приложений (игры, торговля) важна именно latency/RTT, а не гигабиты. Высокий «BDP» (bandwidth-delay product) требует больших TCP-окон, иначе канал недоиспользуется.
23Прокси: forward vs reverse, и CDN
middle
Короткий ответ: Forward proxy стоит со стороны клиента (скрывает/контролирует клиентов). Reverse proxy стоит перед серверами (скрывает их, балансирует, кэширует, терминирует TLS). CDN — географически распределённая сеть reverse-кэшей у края (edge) сети.
Подробно:
- Forward proxy: клиент -> proxy -> интернет. Применение: корпоративный фильтр трафика, анонимизация, кэш, обход ограничений. Сервер видит IP прокси, а не клиента.
- Reverse proxy: клиент -> reverse proxy -> внутренние серверы. Применение: балансировка, TLS-терминация, кэш, защита, единая точка входа (nginx, Envoy). Клиент видит прокси, а не реальные серверы.
Forward: [Клиенты] -> (proxy) -> [Интернет]
Reverse: [Интернет] -> (proxy) -> [Серверы]
CDN (Content Delivery Network): сеть edge-серверов по всему миру, кэширующих статику (и иногда динамику) близко к пользователю.
- Сетевой аспект: GeoDNS/anycast направляет пользователя на ближайший edge -> резко падает latency/RTT.
- Edge отдаёт кэш; при промахе идёт к origin.
- Снижает нагрузку на origin, гасит DDoS, ускоряет TLS (ближе = меньше RTT).
⚠️ Ловушка: За reverse proxy/CDN реальный IP клиента передаётся в заголовке X-Forwarded-For / Forwarded; приложение должно его читать, иначе все клиенты «выглядят» как прокси. Anycast (один IP в разных точках) — ключевой механизм маршрутизации к ближайшему edge.
24Load balancer: L4 vs L7
middle
Короткий ответ: Балансировщик распределяет трафик между серверами. L4-балансировщик работает на транспортном уровне (по IP/портам, не смотрит в содержимое). L7-балансировщик работает на прикладном уровне (видит HTTP — путь, заголовки, cookies).
Подробно:
| L4 (транспортный) | L7 (прикладной) | |
|---|---|---|
| Видит | IP, порт, TCP/UDP | HTTP-путь, заголовки, cookies, host |
| Решения | по 4-tuple/хешу | по URL, домену, методу |
| Скорость | быстрее, дешевле | медленнее, гибче |
| TLS | пробрасывает (passthrough) | может терминировать |
| Примеры | LVS, AWS NLB | nginx, HAProxy, AWS ALB, Envoy |
- L4: просто пересылает пакеты/соединения, не «понимает» HTTP. Очень быстро, минимум overhead.
- L7: разбирает HTTP-запрос, может маршрутизировать
/apiна одни серверы,/staticна другие, делать sticky-сессии по cookie, терминировать TLS, переписывать заголовки.
Алгоритмы: round-robin, least connections, hash по IP (sticky), weighted.
⚠️ Ловушка: L7-балансировка требует терминации TLS на балансировщике (иначе не видно HTTP) — это вопрос доверия и где лежат сертификаты. Для WebSocket нужна поддержка long-lived соединений и Upgrade. Health-check'и — обязательны, иначе трафик пойдёт на мёртвый бэкенд.
25Firewall кратко
junior
Короткий ответ: Firewall — система фильтрации сетевого трафика по правилам (адреса, порты, протоколы, состояние). Бывает stateless (по пакетам), stateful (отслеживает соединения) и application-layer (понимает протоколы).
Подробно:
- Stateless (packet filter): правила по src/dst IP, портам, протоколу; каждый пакет независимо.
- Stateful: помнит установленные соединения, пропускает ответный трафик автоматически (если запрос разрешён — ответ тоже).
- Application firewall / WAF: анализирует HTTP-трафик, блокирует SQL-инъекции, XSS и т.п.
Типичная политика: «запрещено всё, что явно не разрешено» (default deny). Например, открыть только 443 наружу.
⚠️ Ловушка: NAT ≠ firewall, хотя побочно скрывает внутренние хосты. И firewall на уровне портов не защищает от атак на прикладном уровне (для этого WAF). «Открыт только 443» не означает безопасность приложения за ним.
27HTTP методы и идемпотентность
junior
Короткий ответ: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. Идемпотентный метод даёт тот же результат при повторе (GET, PUT, DELETE), безопасный — не меняет состояние (GET, HEAD). POST не идемпотентен.
Подробно:
| Метод | Безопасный | Идемпотентный |
|---|---|---|
| GET | да | да |
| HEAD | да | да |
| OPTIONS | да | да |
| PUT | нет | да |
| DELETE | нет | да |
| POST | нет | нет |
| PATCH | нет | не обязательно |
- Идемпотентность важна для сетевых повторов: если ответ потерялся, повтор PUT/DELETE безопасен, повтор POST может создать дубликат.
⚠️ Ловушка: Идемпотентность — это про эффект на сервере, а не про одинаковый ответ. DELETE дважды: первый удаляет (200), второй — 404, но состояние то же -> идемпотентно.
Полная семантика методов, кодов статусов и REST — в файле по HTTP.
28gRPC поверх HTTP/2
middle
Короткий ответ: gRPC — RPC-фреймворк от Google, использующий HTTP/2 как транспорт и Protocol Buffers для сериализации. Выигрывает от мультиплексирования HTTP/2 и поддерживает стриминг в обе стороны.
Подробно:
- Транспорт: HTTP/2 — отсюда мультиплексирование (много вызовов по одному соединению), бинарный фрейминг, сжатие заголовков.
- Сериализация: Protobuf — компактный бинарный формат, описанный в
.proto-схеме (контракт). - Типы вызовов: unary, server-streaming, client-streaming, bidirectional streaming (последние возможны именно благодаря HTTP/2 streams).
- Эффективнее JSON/REST по объёму и скорости, строгий контракт.
⚠️ Ловушка: gRPC требует HTTP/2 end-to-end, а браузеры не дают полного доступа к HTTP/2-фреймам из JS — отсюда gRPC-Web (через прокси-транслятор, например Envoy). Прямой gRPC из браузера невозможен. Также промежуточные L7-прокси должны поддерживать HTTP/2.
29Идемпотентность сетевых повторов
middle
Короткий ответ: В сети ответ может потеряться, хотя запрос обработан — клиент не знает, дошло ли. Безопасный повтор возможен только для идемпотентных операций; для неидемпотентных (POST) используют idempotency key.
Подробно:
Проблема: клиент шлёт «списать 100₽», сервер списал, но ответ потерялся. Клиент повторяет -> двойное списание.
Решения:
- Делать операцию идемпотентной: PUT с полным состоянием, DELETE по ID.
- Idempotency key: клиент генерирует уникальный ключ, шлёт в заголовке (
Idempotency-Key). Сервер запоминает результат по ключу; повтор с тем же ключом возвращает сохранённый результат, не выполняя операцию заново. Так делают Stripe, платёжные API. - Дедупликация на сервере по бизнес-идентификатору.
⚠️ Ловушка: «At-least-once» доставка (повторы при сбое) почти всегда требует идемпотентности на стороне получателя. Распределённые системы по умолчанию дают at-least-once, а не exactly-once; exactly-once «эффективно» достигается именно идемпотентностью + дедупликацией.
30CORS на сетевом уровне (preflight)
middle
Короткий ответ: CORS — механизм браузера, контролирующий межсайтовые запросы. Для «непростых» запросов браузер сначала шлёт preflight-запрос OPTIONS, и только при разрешающих заголовках сервера выполняет основной запрос.
Подробно:
- Браузер по политике same-origin блокирует кросс-доменные запросы из JS, если сервер их явно не разрешил.
- Preflight: для запросов с нестандартными методами/заголовками браузер автоматически шлёт:
OPTIONS /api/data HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization
- Сервер отвечает разрешающими заголовками:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: PUT, GET, POST
Access-Control-Allow-Headers: Authorization
Access-Control-Max-Age: 86400
- Только после этого браузер шлёт реальный запрос.
Max-Ageкэширует preflight.
⚠️ Ловушка: CORS — защита браузера, а не сервера; curl/сервер-сервер запросы её игнорируют. И CORS не «разрешает» запрос, а лишь говорит браузеру отдать ответ JS-коду. Простые запросы (GET/POST с простыми заголовками) preflight не требуют.
Подробности безопасности CORS и same-origin policy — в файле по аутентификации.
31ICMP, ping, traceroute
junior
Короткий ответ: ICMP — служебный протокол сетевого уровня для диагностики и сообщений об ошибках. Ping использует ICMP Echo для проверки доступности и RTT. Traceroute показывает путь пакета через маршрутизаторы.
Подробно:
- ICMP не несёт пользовательских данных; шлёт сообщения вроде «хост недостижим», «время жизни истекло», «нужна фрагментация».
- ping: шлёт ICMP Echo Request, ждёт Echo Reply. Измеряет RTT и потери пакетов.
ping example.com. - traceroute / tracert: отправляет пакеты с возрастающим TTL (1, 2, 3...). Каждый маршрутизатор, уменьшая TTL до 0, возвращает ICMP «Time Exceeded» — так выявляется каждый хоп по пути.
traceroute:
TTL=1 -> роутер 1 отвечает "Time Exceeded"
TTL=2 -> роутер 2 отвечает ...
... -> цель отвечает Echo Reply / Port Unreachable
⚠️ Ловушка: Многие хосты/фаерволы блокируют ICMP, поэтому «ping не проходит» не всегда означает, что сервер недоступен — он может просто игнорировать ICMP, обслуживая при этом HTTP. Traceroute на Linux часто использует UDP, на Windows — ICMP; результаты могут различаться.
32Keep-alive и connection pooling
middle
Короткий ответ: Keep-alive (persistent connections) переиспользует одно TCP-соединение для нескольких HTTP-запросов, избегая повторных handshake. Connection pooling — клиентский пул заранее открытых соединений к серверу/БД.
Подробно:
- HTTP keep-alive: в HTTP/1.1 соединение по умолчанию persistent (
Connection: keep-alive). Несколько запросов идут по одному TCP — экономим RTT на TCP+TLS handshake для каждого. - Connection pooling: приложение держит набор открытых соединений (к БД, к внешним API) и переиспользует их вместо открытия нового на каждый запрос. Снижает latency и нагрузку (handshake — дорого).
- TCP keep-alive (отдельная вещь!): низкоуровневые пакеты, проверяющие, что соединение ещё живо, чтобы освободить мёртвые.
Зачем: установка TCP (1 RTT) + TLS (1–2 RTT) дорогая. Переиспользование убирает эти задержки для последующих запросов — критично при высокой частоте обращений.
⚠️ Ловушка: Не путайте HTTP keep-alive (переиспользование на прикладном уровне) и TCP keep-alive (проверка живости на транспортном). Пулы соединений требуют настройки таймаутов: слишком долгие висящие соединения могут быть закрыты фаерволом/балансировщиком, и приложение получит ошибку при попытке их использовать (stale connection).
33Концептуальные вопросы
concept
🔹 Зачем нужен TCP handshake? Чтобы обе стороны согласовали начальные порядковые номера (для упорядочивания и обнаружения потерь) и убедились, что канал работает в обе стороны до отправки данных. Без этого нельзя гарантировать надёжную упорядоченную доставку. Цена — 1 RTT задержки.
🔹 Почему UDP для видеозвонков, а TCP для веба? В видеозвонке задержка хуже потери: лучше пропустить устаревший кадр, чем ждать его повторной передачи и накапливать лаг. TCP стал бы ретранслировать и тормозить весь поток (HoL blocking). В вебе/файлах каждый байт критичен и порядок важен — нужна надёжность TCP. Реальный видео-стек (WebRTC) строит надёжность выборочно поверх UDP сам.
🔹 Как HTTPS защищает, если данные идут через много узлов? TLS даёт сквозное (end-to-end) шифрование между клиентом и сервером. Промежуточные узлы (роутеры, провайдеры) видят только зашифрованные байты и адреса (IP, SNI), но не содержимое. Сертификат + цепочка доверия гарантируют, что вы говорите именно с нужным сервером, а не с MITM. Подменить сертификат нельзя без приватного ключа и подписи доверенного CA. Поэтому «много узлов» не страшно — они лишь пересылают непрозрачный для них трафик.
🔹 Зачем DNS, почему не ходить сразу по IP? IP меняются (миграции, балансировка, CDN отдаёт разный IP по геолокации), а имена стабильны и читаемы для людей. DNS — слой косвенности: меняешь привязку имя->IP без изменения ссылок повсюду. Жёсткая привязка к IP сделала бы инфраструктуру негибкой и хрупкой, сломала бы CDN и отказоустойчивость.
⚠️ Ловушка: На концептуальных вопросах интервьюер хочет рассуждение о компромиссах (trade-offs), а не заученное определение. Всегда формулируйте «X лучше Y, когда..., потому что...».
Источники
Источники и редакционная политика
Материалы RecallDeck сопоставлены с официальной документацией и открытыми публикациями компаний, когда первичный источник доступен. Мы не связаны с упомянутыми работодателями, не публикуем конфиденциальные задания и не продаём места в подборках. Формат найма может меняться — уточняйте его у рекрутера.
От чтения к воспроизведению
Отрепетируйте полный цикл интервью.
RecallDeck возвращает сложные темы по расписанию и помогает удерживать в памяти язык, SQL, архитектуру и поведенческие истории.