Направление

Подготовка к собеседованию — Дата-инженер

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

450 карточек19 тем
Посмотреть цены и начать

Новым подписчикам месяца или года может быть доступен бесплатный пробный период 7 дней. Условия и сумму подтвердит страница оплаты.

С чего начать

Нужно писать простой код на Python и SQL и понимать устройство таблиц и файлов. На этих основах строятся Spark, стриминг и архитектура; практикуйтесь на небольшом пайплайне.

Первый проход: Python → Основы CS. Начните с базовых вопросов в этих модулях, затем продолжайте по плану. К сложным и senior-вопросам возвращайтесь по требованиям вакансии; все карточки доступны с самого начала.

Общие темы могут входить в несколько направлений и сохраняют одну историю повторений. План ниже отмечает общие основы и профильные модули; выбирайте глубину под свою вакансию.

Что внутри

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

Python

102 карточки

Общие основы

Ядро языкаКонкурентность и asyncStdlib, типизация и тесты

Основы CS

53 карточки

Общие основы

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

Базы данных

82 карточки

Общие основы

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

Моделирование данных и хранилища

12 карточек

Профильный модуль

Моделирование данных

ETL/ELT и пайплайны

18 карточек

Профильный модуль

ETL и пайплайны

Хранение и форматы файлов

13 карточек

Профильный модуль

Хранение и форматы

Spark и распределённая обработка

13 карточек

Профильный модуль

Spark

Стриминг и Kafka

14 карточек

Профильный модуль

Стриминг

Kafka и очереди

21 карточка

Общие основы

Kafka и очереди

SQL и оптимизация запросов

10 карточек

Профильный модуль

Оптимизация SQL

ClickHouse

8 карточек

Профильный модуль

ClickHouse

Качество данных и оркестрация

10 карточек

Профильный модуль

Качество данных

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

47 карточек

Общие основы

Docker, CI/CD и LinuxGit

Архитектура данных и системный дизайн

9 карточек

Профильный модуль

Архитектура

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

38 карточек

Общие основы

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

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

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

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

Короткий ответ: Изменяемый объект можно менять на месте (list, dict, set), неизменяемый — нельзя (int, str, tuple). Перепривязка переменной и изменение объекта — разные действия.

items = [1, 2]
alias = items
items.append(3)
assert alias is items and alias == [1, 2, 3]

text = "hello"
original = text
text += " world"
assert original == "hello"  # исходная строка не изменилась

Подробно:

  • id() идентифицирует объект и постоянен в течение его жизни. То, что это адрес памяти, — деталь реализации CPython.
  • В кортеже нельзя заменить элементы, но вложенный список может изменяться. Неизменяемость не означает автоматически глубокую неизменяемость или потокобезопасность.
  • Ключ словаря и элемент множества должны быть хешируемыми: хеш остаётся стабильным, а равные объекты имеют равные хеши. Кортеж со списком нехешируем. Изменяемый экземпляр пользовательского класса может хешироваться по идентичности: хешируемость не синоним неизменяемости.
  • Функция получает ссылки на объекты. Мутация аргумента может быть видна вызывающему коду; перепривязка локального параметра не перепривязывает переменную снаружи.

Источники: Хешируемость Python, идентичность объектов.

В чём разница между concurrency и parallelism?

Короткий ответ: Конкурентность — это про структуру программы (управление несколькими задачами, которые прогрессируют, но не обязательно одновременно). Параллелизм — это про физическое одновременное выполнение на нескольких ядрах.

Подробно:

  • Конкурентность (concurrency) — задачи переключаются и продвигаются «по очереди», создавая иллюзию одновременности. Один повар готовит 3 блюда, переключаясь между ними. Может быть и на одном ядре.
  • Параллелизм (parallelism) — задачи реально выполняются в одну и ту же физическую секунду. Три повара, каждый готовит своё блюдо. Требует нескольких ядер/процессоров.
Конкурентность (1 ядро):   Параллелизм (2 ядра):
CPU: A B A B A B            CPU0: A A A A
                           CPU1: B B B B

В Python:

  • asyncio и threading (из-за GIL) дают конкурентность, но не настоящий параллелизм для CPU-кода.
  • multiprocessing даёт настоящий параллелизм.

💡 «Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.» — Rob Pike.

⚠️ Ловушка: многие путают и говорят «потоки в Python работают параллельно». Для CPU-bound кода это не так из-за GIL.

Зачем нужны type hints, если Python динамический?

Короткий ответ: Аннотации типов не проверяются интерпретатором в рантайме — они нужны для статического анализа (mypy, pyright), автодополнения в IDE, документации и раннего обнаружения ошибок до запуска кода. Python остаётся динамическим, hints — это «контракт», который проверяют внешние инструменты.

Подробно:

Type hints (PEP 484) не влияют на выполнение программы. Интерпретатор их игнорирует — можно передать строку туда, где ожидается int, и код не упадёт сам по себе.

def add(a: int, b: int) -> int:
    return a + b

# Python НЕ проверяет типы — это выполнится без ошибок:
print(add("a", "b"))  # "ab" — конкатенация строк!

# Но mypy выдаст ошибку ДО запуска:
# error: Argument 1 to "add" has incompatible type "str"; expected "int"

Зачем тогда нужны:

  1. Раннее обнаружение ошибок — mypy/pyright ловят несовпадения типов до прода.
  2. Автодополнение и навигация в IDE (PyCharm, VS Code).
  3. Документация — сигнатура def f(x: list[int]) -> dict[str, int] понятнее комментария.
  4. Рефакторинг — при изменении типа инструмент покажет все места, где он используется.
  5. Контракты в больших командах — снижают «неявные» договорённости.
# Без hints — непонятно, что ожидается:
def process(data, config): ...

# С hints — самодокументируемо:
def process(data: list[dict[str, int]], config: "Config") -> bool: ...

⚠️ Ловушка: Аннотации — не валидация: def f(x: int) не запретит передать строку в рантайме. Для проверки входных данных нужны pydantic или явные проверки с raise — не assert, который при запуске с python -O удаляется.

Что такое 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)

Как оценивать код: последовательные шаги складываются, и остаётся старший член (O(n) + O(n log n) = O(n log n)); вложенные циклы перемножаются (O(n·m), при m = n — O(n²)); отбрасывание половины задачи с постоянной работой на шаге даёт O(log n). Если входов два, сохраняйте обе переменные: O(n + m) нельзя сокращать до O(n), пока не известно, что m ≤ n.

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

Что делает 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;        -- ОК

Что такое индекс и зачем он нужен?

Короткий ответ: Индекс — это отдельная структура данных, которая хранит значения одной или нескольких колонок в упорядоченном/организованном виде вместе с указателями на физическое расположение строк (TID — tuple identifier), чтобы база могла находить строки без полного сканирования таблицы.

Подробно: Без индекса PostgreSQL вынужден читать всю таблицу (Sequential Scan) и проверять каждую строку. Индекс позволяет за O(log n) (для B-tree) найти нужные TID и потом сходить за самими строками в heap (основную область хранения таблицы).

CREATE INDEX idx_users_email ON users (email);

-- Теперь запрос ищет по дереву, а не по всей таблице
SELECT * FROM users WHERE email = 'a@b.com';

Физически таблица в Postgres хранится в виде heap — неупорядоченного набора страниц по 8 КБ. Индекс — это «оглавление» к этому heap. У одной таблицы может быть много индексов.

⚠️ Ловушка: Индекс ускоряет чтение, но замедляет запись (каждый INSERT/UPDATE/DELETE должен поддерживать индекс актуальным). Индекс на каждую колонку «на всякий случай» — антипаттерн.

Готовы лучше запоминать?

Посмотрите пример, выберите направление и настройте регулярную практику под свою подготовку.

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

Как готовиться к собеседованию на «Дата-инженер»?

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

Какие темы охватывает направление «Дата-инженер»?

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

Помогает ли интервальное повторение в подготовке к «Дата-инженер»?

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

Можно попробовать направление «Дата-инженер» до оплаты?

Новым подписчикам месячного или годового тарифа может быть доступен пробный период 7 дней со всем направлением «Дата-инженер» и всеми функциями. Право на него и сумму подтвердит страница оплаты; при повторной подписке списание может быть сразу. Отмените подписку онлайн до конца пробного периода, чтобы избежать первого списания. У вечного доступа пробного периода нет.

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