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

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

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

312 карточек15 тем
Посмотреть цены и начать

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

Что внутри

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

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

11 карточек
Моделирование данных

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

11 карточек
ETL и пайплайны

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

10 карточек
Spark

Стриминг и Kafka

10 карточек
Стриминг

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

9 карточек
Хранение и форматы

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

10 карточек
Оптимизация SQL

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

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

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

8 карточек
Архитектура

Python

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

Базы данных

42 карточки
Основы SQL

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

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

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

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

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

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

Чем OLTP отличается от OLAP и почему аналитику не гоняют на боевой OLTP-базе?

Короткий ответ: OLTP обслуживает короткие транзакции — вставку и обновление отдельных строк с низкой задержкой, а OLAP отвечает на аналитические запросы, сканирующие миллионы строк. OLTP хранит данные построчно, OLAP — колоночно. Тяжёлую аналитику не гоняют на боевой OLTP-базе, потому что она конкурирует за ресурсы с транзакциями и роняет latency продакшена.

Подробно:

  1. Профиль нагрузки — OLTP: много мелких операций (INSERT/UPDATE по первичному ключу); OLAP: мало тяжёлых запросов с GROUP BY и агрегациями.
  2. Модель хранения — построчное хранение читает всю строку целиком (удобно для транзакций), колоночное читает только нужные столбцы и лучше сжимается (удобно для аналитики).
  3. Нормализация — OLTP нормализован (3NF) ради целостности при записи, OLAP денормализован ради скорости чтения.
  4. Изоляция ресурсов — аналитический скан забивает буферный кэш и диск, из-за чего транзакции начинают ждать.
Критерий OLTP OLAP
Задача транзакции аналитика
Операции чтение/запись строк агрегации по колонкам
Хранение построчное колоночное
Нормализация 3NF денормализация (звезда)
Метрика latency, TPS throughput скана

⚠️ Частая ошибка: гонять отчётность прямо по продакшен-базе. Данные выгружают в отдельное хранилище (ETL/ELT), чтобы аналитика не мешала транзакциям.

В чём разница между ETL и ELT, почему ELT победил с приходом облачных хранилищ и когда ETL всё ещё оправдан?

Короткий ответ: ETL трансформирует данные до загрузки (на отдельном движке), ELT сначала грузит сырые данные в хранилище, а трансформации выполняет уже внутри него на SQL. ELT стал стандартом, потому что облачные MPP-хранилища (Snowflake, BigQuery, Redshift) дёшево масштабируют вычисления и разделяют storage/compute.

Подробно:

  1. ETL — трансформация на промежуточном движке (раньше — дорогие ETL-серверы). В хранилище попадают только готовые, «чистые» данные. Минус: логика заперта в инструменте, а сырьё теряется.
  2. ELT — грузим сырой слой как есть, трансформируем через dbt/SQL. Плюс: сырьё сохраняется, трансформации версионируются в Git, масштабирование берёт на себя хранилище.
  3. Почему ELT победил — разделение storage/compute сделало вычисления в хранилище дешёвыми и эластичными; аналитику стало удобнее держать в SQL.
Критерий ETL ELT
Где трансформация На отдельном движке Внутри хранилища
Сырой слой Обычно теряется Сохраняется
Масштабирование Ограничено движком Эластичное (MPP)
Типичный стек Informatica, SSIS Fivetran + dbt + Snowflake

Когда ETL всё ещё нужен: тяжёлые преобразования до попадания в хранилище, маскирование PII/комплаенс (нельзя грузить сырьё), или источник, который проще привести к схеме на лету.

⚠️ Частая ошибка: думать, что ELT — это «без трансформаций». Трансформации никуда не делись, они просто переехали в хранилище и выполняются после загрузки.

Опишите архитектуру Spark: драйвер, экзекьюторы, cluster manager. Как задание разбивается на jobs, stages и tasks?

Короткий ответ: Драйвер строит план и координирует выполнение, cluster manager (YARN, Kubernetes, Standalone) выделяет ресурсы, а экзекьюторы на воркерах выполняют задачи и хранят данные в памяти. Каждый экшен запускает job, который планировщик режет на стадии по границам шафла, а стадию — на задачи по числу партиций.

Подробно:

  1. Драйвер — процесс с вашим кодом и SparkSession. Строит логический и физический план, DAG стадий, планирует задачи и собирает результаты. Падение драйвера убивает всё приложение.
  2. Cluster manager — договаривается о ресурсах: сколько экзекьюторов, сколько ядер и памяти на каждый. Сам вычислениями не занимается.
  3. Экзекьюторы — JVM-процессы на воркерах. Выполняют задачи, кэшируют партиции, отдают данные через shuffle. Живут всё время работы приложения.
  4. Иерархия работыJob (на каждый экшен) → Stage (границы по шафлу) → Task (одна задача на одну партицию, минимальная единица параллелизма).
            ┌──────────────┐
            │   Драйвер    │  план + DAG + планировщик
            │ SparkSession │
            └──────┬───────┘
                   │ запрос ресурсов
            ┌──────▼───────┐
            │Cluster Manager│  YARN / K8s / Standalone
            └──────┬───────┘
        ┌──────────┼──────────┐
   ┌────▼────┐ ┌───▼────┐ ┌───▼────┐
   │Экзекьютор│ │Экзекьютор│ │Экзекьютор│  задачи + кэш
   └─────────┘ └────────┘ └────────┘

⚠️ Частая ошибка: путать ядра экзекьютора с задачами — параллелизм ограничен число экзекьюторов × ядер, и если партиций меньше, чем слотов, часть ядер простаивает.

Как партиции и консьюмер-группы дают параллелизм, и как соотносятся число партиций и число консьюмеров?

Короткий ответ: Партиция — единица параллелизма: внутри консьюмер-группы каждую партицию читает ровно один консьюмер. Поэтому эффективный параллелизм ограничен числом партиций — лишние консьюмеры сверх этого простаивают.

Подробно:

  1. Консьюмер-группа — набор консьюмеров с общим group.id, между которыми партиции распределяются (rebalance). Каждая партиция закреплена за одним консьюмером группы.
  2. Порядок гарантируется только внутри партиции. Больше партиций → больше параллелизма, но нет глобального порядка по топику.
  3. Соотношение: консьюмеров ≤ партиций для полной загрузки. Если консьюмеров больше — избыток простаивает без работы.
  4. Масштабирование: партиции задают потолок. Их число легко увеличить, но не уменьшить, и это меняет распределение ключей по партициям.
Партиций Консьюмеров Итог
4 2 по 2 партиции на консьюмера
4 4 по 1 партиции — максимум параллелизма
4 6 4 работают, 2 простаивают

⚠️ Частая ошибка: добавлять консьюмеров ради ускорения, забыв, что потолок — число партиций. Сверх него консьюмеры сидят без назначенных партиций.

Чем колоночное хранение отличается от строкового и почему для аналитики быстрее и дешевле именно колоночный формат?

Короткий ответ: В строковом формате значения одной записи лежат рядом, в колоночном — рядом лежат все значения одной колонки. Для аналитических запросов (агрегаты по нескольким колонкам из десятков) колоночный формат читает только нужные колонки, лучше сжимается и поддерживает предикатный пушдаун — отсюда меньше I/O и ниже стоимость.

Подробно:

  1. Проекция колонок (projection pushdown) — запросу нужны 3 колонки из 50, и колоночный движок читает с диска только эти три. Строковый формат вынужден прочитать строку целиком.
  2. Сжатие — в колонке лежат однотипные значения (один тип, похожие данные), поэтому dictionary-, run-length- и delta-кодирование дают степень сжатия в разы выше, чем на разнородной строке.
  3. Предикатный пушдаун (predicate pushdown) — по хранимым min/max статистикам блока фильтр WHERE date = ... пропускает целые блоки, не читая их.
  4. Строковый формат выигрывает при точечных операциях: прочитать/записать запись целиком (OLTP, стриминг по одной записи).
Строковый (row):   [id=1,name=A,ts=..][id=2,name=B,ts=..][id=3,...]
                    └── запись 1 ──┘└── запись 2 ──┘

Колоночный (columnar):
  id:   [1, 2, 3, ...]        ← читаем только нужные
  name: [A, B, C, ...]           колонки, каждая
  ts:   [.., .., .., ...]        сжата отдельно

⚠️ Частая ошибка: считать колоночный формат universally лучшим. Для построчной записи и чтения записи целиком (стриминг, транзакционные апдейты) строковый формат (Avro) эффективнее.

Как читать план выполнения запроса (EXPLAIN) и на что смотреть в первую очередь?

Короткий ответ: План читают снизу вверх и изнутри наружу: листья — это доступ к таблицам (Seq Scan / Index Scan), выше идут джойны и агрегации. Ищут самый дорогой узел, полные сканы больших таблиц под фильтром и выбранный метод джойна.

Подробно:

  1. Направление чтения — от самых вложенных узлов (чтение данных) к корню (итоговый результат). В EXPLAIN ANALYZE сравнивают оценку (rows=) с фактом (actual rows): расхождение в разы выдаёт кривую статистику оптимизатора.
  2. Способ доступа — Seq Scan (полный скан) против Index / Index Only Scan. Полный скан большой таблицы под селективным фильтром — первый кандидат на оптимизацию.
  3. Метод джойна — Nested Loop, Hash Join, Merge Join (см. таблицу).
  4. Дорогой узел — с наибольшим cost/временем; на нём и концентрируют усилия.
Метод Когда выбирается Цена
Nested Loop малый внешний вход + индекс на внутреннем дёшев на малых объёмах, иначе O(N·M)
Hash Join большие несортированные наборы, эквиджойн строит хеш-таблицу в памяти
Merge Join оба входа отсортированы по ключу выгоден при уже готовой сортировке
EXPLAIN ANALYZE
SELECT o.id, c.name
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.created_at >= DATE '2026-01-01';

-- Hash Join  (cost=...  rows=...)        <- метод джойна
--   ->  Seq Scan on orders o            <- полный скан: фильтр не по индексу
--         Filter: (created_at >= ...)
--   ->  Hash
--         ->  Seq Scan on customers c

⚠️ Частая ошибка: смотреть только на итоговый cost и игнорировать расхождение rows vs actual rows — именно оно выдаёт устаревшую статистику и выбор плохого плана.

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

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

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

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

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

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

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

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

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

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

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

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

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