RecallDeck
Направление

Подготовка к собеседованию — Full-Stack разработчик

Колода из 716+ карточек с вопросами для собеседования по направлению «Full-Stack разработчик» — по темам и уровню сложности, с возвратом ровно перед тем, как вы забудете. Посмотрите несколько карточек ниже, затем выберите доступ, чтобы учить всё направление по расписанию в стиле Anki (SM-2).

716 карточек21 тема
Посмотреть цены и начать

7 дней бесплатно на месяц или год · все функции включены.

Что внутри

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

Python

122 карточки
Ядро языкаМодель данных и внутренностиКонкурентность и asyncStdlib, типизация и тесты

Базы данных

104 карточки
Основы SQLВнутренности Postgres и оптимизацияNoSQL и Redis

Бэкенд

169 карточек
HTTP и REST APIАрхитектура и масштабированиеАутентификация и безопасностьDjango и FastAPIORM и SQLAlchemy

Фронтенд

146 карточек
Ядро JavaScriptReactTypeScriptCSS и рендеринг браузера

Основы CS

76 карточек
Структуры данных и алгоритмыСети

DevOps и инфраструктура

35 карточек
Docker, CI/CD и Linux

Системный дизайн

29 карточек
Системный дизайн

Поведенческое интервью

35 карточек
Поведенческое интервью

Примеры вопросов

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

Чем отличаются изменяемые (mutable) и неизменяемые (immutable) типы?

Короткий ответ: Изменяемые объекты можно менять «на месте» без создания нового объекта (list, dict, set, bytearray), неизменяемые — нет (int, float, str, bytes, tuple, frozenset, bool, None). Любое «изменение» неизменяемого создаёт новый объект.

Подробно: Изменяемость — это про то, может ли объект поменять своё содержимое, сохранив тот же id() (адрес в памяти).

# Неизменяемый: операция создаёт НОВЫЙ объект
s = "hello"
print(id(s))
s += " world"      # создаётся новая строка
print(id(s))       # id поменялся — это другой объект

# Изменяемый: меняется тот же объект
lst = [1, 2, 3]
print(id(lst))
lst.append(4)      # меняем на месте
print(id(lst))     # id тот же

Почему это важно:

  • Хешируемость. Только неизменяемые (по содержимому) объекты можно класть в dict-ключи и set. Если бы ключ менялся, его хеш «уехал» бы, и его нельзя было бы найти.
  • Безопасность при шаринге. Неизменяемый объект можно безопасно расшарить между потоками/функциями — никто его не испортит.
  • Аргументы функций. Python передаёт ссылку на тот же объект: функция может изменить содержимое изменяемого аргумента, но локальное переназначение параметра не меняет переменную вызывающего кода.

⚠️ Ловушка: tuple неизменяем, но если в нём лежит list, этот список можно поменять:

t = ([1, 2], 3)
t[0].append(99)   # OK! список внутри мутабелен
print(t)          # ([1, 2, 99], 3)
# t[0] = [...]    # вот ЭТО — TypeError, переприсвоить элемент нельзя

А ещё hash(([1,2], 3)) упадёт — кортеж нехешируем, если внутри есть нехешируемый элемент.

Что делает SELECT и в каком порядке выполняются части запроса?

Короткий ответ: SELECT извлекает строки из таблиц. Логический порядок выполнения НЕ совпадает с порядком написания: сначала FROM, затем WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, LIMIT.

Подробно:

Порядок написания (синтаксический):

SELECT   DISTINCT col1, agg(col2)
FROM     t
WHERE    cond
GROUP BY col1
HAVING   agg_cond
ORDER BY col1
LIMIT    10 OFFSET 20;

Логический порядок исполнения:

1. FROM / JOIN      -- какие таблицы, как соединить
2. WHERE            -- фильтр строк ДО группировки
3. GROUP BY         -- группировка
4. HAVING           -- фильтр групп ПОСЛЕ агрегации
5. SELECT           -- вычисление выражений, алиасов
6. DISTINCT         -- удаление дублей
7. ORDER BY         -- сортировка
8. LIMIT / OFFSET   -- срез

⚠️ Ловушка: алиас из SELECT нельзя использовать в WHERE (т.к. WHERE выполняется раньше SELECT), но можно в ORDER BY и часто в GROUP BY (зависит от СУБД). Пример ошибки:

SELECT salary * 12 AS annual FROM emp WHERE annual > 100000; -- ОШИБКА
SELECT salary * 12 AS annual FROM emp ORDER BY annual;        -- ОК
  1. Что такое HTTP и как устроен цикл запрос-ответ?

Короткий ответ: HTTP (HyperText Transfer Protocol) — текстовый прикладной протокол клиент-сервер поверх TCP (в HTTP/3 — поверх QUIC/UDP). Клиент отправляет запрос, сервер возвращает ответ; соединение без сохранения состояния между запросами (stateless).

Подробно:

Запрос состоит из стартовой строки (метод + путь + версия), заголовков и опционального тела:

POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Content-Length: 38

{"name": "Анна", "email": "a@ex.com"}

Ответ состоит из строки статуса (версия + код + reason phrase), заголовков и тела:

HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/42

{"id": 42, "name": "Анна", "email": "a@ex.com"}

⚠️ Ловушка: «HTTP работает только поверх TCP» — неверно для HTTP/3, который использует QUIC поверх UDP. И reason phrase («OK», «Created») носит чисто информативный характер — клиенты должны опираться на числовой код, а не на текст.

  1. Типы данных: примитивы vs объекты?

Короткий ответ: В JS 7 примитивных типов (string, number, boolean, null, undefined, symbol, bigint) и один ссылочный тип — объект (включая массивы, функции, даты). Примитивы иммутабельны и копируются по значению, объекты — по ссылке.

Подробно:

// Примитивы — копируются по значению
let a = 10;
let b = a;
b = 20;
console.log(a); // 10 — a не изменилось

// Объекты — копируются по ссылке
let obj1 = { x: 1 };
let obj2 = obj1;
obj2.x = 99;
console.log(obj1.x); // 99 — обе переменные указывают на один объект

// Примитивы иммутабельны: "изменить" строку нельзя, можно только создать новую
let str = "hello";
str[0] = "H";
console.log(str); // "hello" — не изменилось

// bigint — для целых чисел больше 2^53 - 1
const big = 9007199254740993n;
console.log(big + 1n); // 9007199254740994n

// symbol — уникальный идентификатор
const id = Symbol("id");

Примитивы хранят значение напрямую. У них «есть методы» благодаря автоупаковке (autoboxing): "abc".toUpperCase() временно оборачивает строку в объект-обёртку String.

⚠️ Ловушка: typeof function(){} возвращает 'function', хотя функция — это объект. А typeof []'object', поэтому для массивов используйте Array.isArray([]).

Что такое Big O нотация?

Короткий ответ: Big O описывает, как растёт время работы или потребление памяти алгоритма при увеличении размера входных данных n, отбрасывая константы и младшие члены. Это верхняя оценка скорости роста.

Подробно:

Big O отвечает на вопрос «что произойдёт, когда n станет очень большим?». Нас не интересует точное число операций, а только характер роста. Поэтому O(2n + 100) упрощается до O(n), а O(3n² + n) — до O(n²).

Основные классы роста (от лучшего к худшему):

# O(1) — константа: не зависит от n
def first(arr):
    return arr[0] if arr else None

# O(log n) — логарифм: каждый шаг делит задачу пополам (бинарный поиск)
def binary_search(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

# O(n) — линейная: один проход
def total(arr):
    s = 0
    for x in arr:        # n итераций
        s += x
    return s

# O(n log n) — эффективные сортировки (merge, quick, Timsort)
def sort_it(arr):
    return sorted(arr)

# O(n^2) — квадрат: вложенный цикл
def has_dup_naive(arr):
    for i in range(len(arr)):
        for j in range(i + 1, len(arr)):
            if arr[i] == arr[j]:
                return True
    return False

# O(2^n) — экспонента: наивный Фибоначчи, перебор подмножеств
def fib_naive(n):
    if n < 2:
        return n
    return fib_naive(n - 1) + fib_naive(n - 2)

Ориентир по росту при n = 1 000 000: O(1) — 1 операция, O(log n) — ~20, O(n) — миллион, O(n log n) — ~20 млн, O(n²) — триллион (уже слишком), O(2^n) — нереально даже при n = 50.

⚠️ Ловушка: Big O — это про асимптотику (поведение при больших n), а не про реальное время. O(n) алгоритм может быть медленнее O(n²) на маленьких данных из-за больших констант. Также путают: Big O (верхняя граница, Ω — нижняя, Θ — точная), в собесах под «O» обычно подразумевают Θ.

Что такое Docker и какую проблему он решает?

Короткий ответ: Docker — это платформа контейнеризации, которая упаковывает приложение вместе со всеми его зависимостями, библиотеками и конфигурацией в изолированный, переносимый образ. Решает проблему «у меня на машине работает, а на сервере нет».

Подробно:

Классическая боль: разработчик написал код на своём ноутбуке (Python 3.11, конкретная версия libpq, переменные окружения), а на сервере другая версия ОС, других библиотек нет, переменные не выставлены — приложение падает. Docker фиксирует всё окружение в образе, и этот образ одинаково запускается локально, в CI и на проде.

Что даёт Docker:

  • Воспроизводимость — один и тот же образ везде. Окружение описано кодом (Dockerfile), его можно версионировать в git.
  • Изоляция — контейнеры не мешают друг другу (зависимости, порты, процессы).
  • Переносимость — образ работает на любой машине с Docker, независимо от хостовой ОС.
  • Быстрый старт — контейнер поднимается за секунды (в отличие от VM).
# Собрать образ из Dockerfile в текущей директории
docker build -t myapp:1.0 .

# Запустить контейнер из образа, пробросить порт, в фоне
docker run -d -p 8000:8000 --name myapp myapp:1.0

# Посмотреть запущенные контейнеры
docker ps

# Зайти внутрь работающего контейнера
docker exec -it myapp bash

# Логи контейнера
docker logs -f myapp

⚠️ Ловушка: Docker не «виртуализирует железо» и не запускает полноценную ОС. Контейнеры используют ядро хоста. Поэтому Linux-образ нативно не запустится на ядре Windows — на Windows/macOS под капотом работает лёгкая Linux-VM (через WSL2 или гипервизор), и уже в ней крутятся контейнеры.

Готовы закрепить навсегда?

Первая сессия — меньше минуты. Ваше будущее «я» на собеседовании скажет спасибо.

Вопросы об этом направлении

Как готовиться к собеседованию на «Full-Stack разработчик»?

Учите концепции, которые придётся объяснять, а не только те, что умеете кодить. Направление «Full-Stack разработчик» в RecallDeck даёт 716+ отобранных вопросов и возвращает каждый по расписанию в стиле Anki (SM-2) ровно перед тем, как вы забудете — чтобы на собеседовании ответы были под рукой.

Какие темы охватывает направление «Full-Stack разработчик»?

Направление «Full-Stack разработчик» разбито на ключевые области, которые реально проверяют на таких собеседованиях, — по темам и уровню сложности (Concept, Junior, Middle, Senior). Полный план и примеры вопросов можно посмотреть выше до входа.

Помогает ли интервальное повторение в подготовке к «Full-Stack разработчик»?

Да. Активно вспоминать ответ и честно себя оценивать — куда прочнее для памяти, чем перечитывать заметки. RecallDeck планирует каждую карту «Full-Stack разработчик» так, чтобы она вернулась перед моментом забывания: ежедневных повторений становится меньше, а знания держатся.

Можно попробовать направление «Full-Stack разработчик» до оплаты?

Да. Месячный и годовой варианты включают семь пробных дней со всем направлением «Full-Stack разработчик», полным планировщиком SM-2, статистикой, гибким темпом и блиц-режимом. Отменить можно онлайн до первого списания.

Другие направления

RecallDeckПодготовка к собеседованию на интервальных повторениях