Подготовка к собеседованию — Дата-инженер
Колода из 312+ карточек с вопросами для собеседования по направлению «Дата-инженер» — по темам и уровню сложности, с повторениями по вашим оценкам. Посмотрите несколько карточек ниже, затем выберите доступ, чтобы учить всё направление по расписанию в стиле Anki (SM-2).
Новым подписчикам месяца или года может быть доступно 7 дней бесплатно. Условия и сумму подтвердит страница оплаты.
С чего начать
Нужно писать простой код на Python и SQL и понимать устройство таблиц и файлов. На этих основах строятся Spark, стриминг и архитектура; практикуйтесь на небольшом пайплайне.
Первый проход: Python → Базы данных. Начните с базовых вопросов в этих модулях, затем продолжайте по плану. К сложным и senior-вопросам возвращайтесь по требованиям вакансии; все карточки доступны с самого начала.
Общие темы могут входить в несколько направлений и сохраняют одну историю повторений. План ниже отмечает общие основы и профильные модули; выбирайте глубину под свою вакансию.
Что внутри
Все темы направления, сгруппированные так, как вы будете их учить.
Python
122 карточкиОбщие основы
Базы данных
42 карточкиОбщие основы
Моделирование данных и хранилища
11 карточекПрофильный модуль
ETL/ELT и пайплайны
11 карточекПрофильный модуль
Хранение и форматы файлов
9 карточекПрофильный модуль
Spark и распределённая обработка
10 карточекПрофильный модуль
Стриминг и Kafka
10 карточекПрофильный модуль
SQL и оптимизация запросов
10 карточекПрофильный модуль
Качество данных и оркестрация
9 карточекПрофильный модуль
DevOps и инфраструктура
35 карточекОбщие основы
Архитектура данных и системный дизайн
8 карточекПрофильный модуль
Поведенческое интервью
35 карточекОбщие основы
Примеры вопросов
Несколько карточек из колоды — откройте ответ, затем выберите доступ, чтобы учить весь набор по расписанию.
Чем отличаются изменяемые (mutable) и неизменяемые (immutable) типы?
Чем отличаются изменяемые (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, идентичность объектов.
Что делает SELECT и в каком порядке выполняются части запроса?
Что делает 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; -- ОК
Чем OLTP отличается от OLAP и почему аналитику не гоняют на боевой OLTP-базе?
Чем OLTP отличается от OLAP и почему аналитику не гоняют на боевой OLTP-базе?
Короткий ответ: OLTP обслуживает короткие транзакции — вставку и обновление отдельных строк с низкой задержкой, а OLAP отвечает на аналитические запросы, сканирующие миллионы строк. Построчное хранение типично для OLTP, колоночное — для OLAP; это категории нагрузки, а не обязательные форматы хранения. Тяжёлую аналитику не гоняют на боевой OLTP-базе, потому что она конкурирует за ресурсы с транзакциями и роняет latency продакшена.
Подробно:
- Профиль нагрузки — OLTP: много мелких операций (
INSERT/UPDATEпо первичному ключу); OLAP: мало тяжёлых запросов сGROUP BYи агрегациями. - Модель хранения — построчное хранение читает всю строку целиком (удобно для транзакций), колоночное читает только нужные столбцы и лучше сжимается (удобно для аналитики).
- Нормализация — OLTP часто использует нормализацию для целостности записи, OLAP — размерные или денормализованные модели для анализа. Бывают гибридные решения.
- Изоляция ресурсов — аналитический скан забивает буферный кэш и диск, из-за чего транзакции начинают ждать.
| Критерий | OLTP | OLAP |
|---|---|---|
| Задача | транзакции | аналитика |
| Операции | чтение/запись строк | агрегации по колонкам |
| Типичное хранение | построчное | колоночное |
| Частая модель | нормализованная | размерная/звезда |
| Метрика | latency, TPS | throughput скана |
⚠️ Частая ошибка: гонять отчётность прямо по продакшен-базе. Данные выгружают в отдельное хранилище (ETL/ELT), чтобы аналитика не мешала транзакциям.
В чём разница между ETL и ELT, почему ELT победил с приходом облачных хранилищ и когда ETL всё ещё оправдан?
В чём разница между ETL и ELT, почему ELT победил с приходом облачных хранилищ и когда ETL всё ещё оправдан?
Короткий ответ: ETL трансформирует данные до загрузки (на отдельном движке), ELT сначала грузит сырые данные в хранилище, а трансформации выполняет уже внутри него на SQL. ELT стал стандартом, потому что облачные MPP-хранилища (Snowflake, BigQuery, Redshift) дёшево масштабируют вычисления и разделяют storage/compute.
Подробно:
- ETL — трансформация на промежуточном движке (раньше — дорогие ETL-серверы). В хранилище попадают только готовые, «чистые» данные. Минус: логика заперта в инструменте, а сырьё теряется.
- ELT — грузим сырой слой как есть, трансформируем через dbt/SQL. Плюс: сырьё сохраняется, трансформации версионируются в Git, масштабирование берёт на себя хранилище.
- Почему ELT победил — разделение storage/compute сделало вычисления в хранилище дешёвыми и эластичными; аналитику стало удобнее держать в SQL.
| Критерий | ETL | ELT |
|---|---|---|
| Где трансформация | На отдельном движке | Внутри хранилища |
| Сырой слой | Обычно теряется | Сохраняется |
| Масштабирование | Ограничено движком | Эластичное (MPP) |
| Типичный стек | Informatica, SSIS | Fivetran + dbt + Snowflake |
Когда ETL всё ещё нужен: тяжёлые преобразования до попадания в хранилище, маскирование PII/комплаенс (нельзя грузить сырьё), или источник, который проще привести к схеме на лету.
⚠️ Частая ошибка: думать, что ELT — это «без трансформаций». Трансформации никуда не делись, они просто переехали в хранилище и выполняются после загрузки.
Чем колоночное хранение отличается от строкового и почему для аналитики быстрее и дешевле именно колоночный формат?
Чем колоночное хранение отличается от строкового и почему для аналитики быстрее и дешевле именно колоночный формат?
Короткий ответ: В строковом формате значения одной записи лежат рядом, в колоночном — рядом лежат все значения одной колонки. Для аналитических запросов (агрегаты по нескольким колонкам из десятков) колоночный формат читает только нужные колонки, лучше сжимается и поддерживает предикатный пушдаун — отсюда меньше I/O и ниже стоимость.
Подробно:
- Проекция колонок (projection pushdown) — запросу нужны 3 колонки из 50, и колоночный движок читает с диска только эти три. Строковый формат вынужден прочитать строку целиком.
- Сжатие — в колонке лежат однотипные значения (один тип, похожие данные), поэтому dictionary-, run-length- и delta-кодирование дают степень сжатия в разы выше, чем на разнородной строке.
- Предикатный пушдаун (predicate pushdown) — по хранимым min/max статистикам блока фильтр
WHERE date = ...пропускает целые блоки, не читая их. - Строковый формат выигрывает при точечных операциях: прочитать/записать запись целиком (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) эффективнее.
Опишите архитектуру Spark: драйвер, экзекьюторы, cluster manager. Как задание разбивается на jobs, stages и tasks?
Опишите архитектуру Spark: драйвер, экзекьюторы, cluster manager. Как задание разбивается на jobs, stages и tasks?
Короткий ответ: Драйвер строит план и координирует выполнение, cluster manager (YARN, Kubernetes, Standalone) выделяет ресурсы, а экзекьюторы на воркерах выполняют задачи и хранят данные в памяти. Каждый экшен запускает job, который планировщик режет на стадии по границам шафла, а стадию — на задачи по числу партиций.
Подробно:
- Драйвер — процесс с вашим кодом и
SparkSession. Строит логический и физический план, DAG стадий, планирует задачи и собирает результаты. Падение драйвера убивает всё приложение. - Cluster manager — договаривается о ресурсах: сколько экзекьюторов, сколько ядер и памяти на каждый. Сам вычислениями не занимается.
- Экзекьюторы — JVM-процессы на воркерах. Выполняют задачи, кэшируют партиции, отдают данные через shuffle. Живут всё время работы приложения.
- Иерархия работы —
Job(на каждый экшен) →Stage(границы по шафлу) →Task(одна задача на одну партицию, минимальная единица параллелизма).
┌──────────────┐
│ Драйвер │ план + DAG + планировщик
│ SparkSession │
└──────┬───────┘
│ запрос ресурсов
┌──────▼───────┐
│Cluster Manager│ YARN / K8s / Standalone
└──────┬───────┘
┌──────────┼──────────┐
┌────▼────┐ ┌───▼────┐ ┌───▼────┐
│Экзекьютор│ │Экзекьютор│ │Экзекьютор│ задачи + кэш
└─────────┘ └────────┘ └────────┘
⚠️ Частая ошибка: путать ядра экзекьютора с задачами — параллелизм ограничен число экзекьюторов × ядер, и если партиций меньше, чем слотов, часть ядер простаивает.
Готовы лучше запоминать?
Посмотрите пример, выберите направление и настройте регулярную практику под свою подготовку.
Вопросы об этом направлении
Как готовиться к собеседованию на «Дата-инженер»?
Учите концепции, которые придётся объяснять, а не только те, что умеете кодить. Направление «Дата-инженер» в RecallDeck даёт 312+ отобранных вопросов и возвращает каждый по расписанию в стиле Anki (SM-2), основанному на ваших оценках — чтобы тренировать вспоминание и объяснение. Дополняйте повторения кодингом и пробными собеседованиями.
Какие темы охватывает направление «Дата-инженер»?
Направление «Дата-инженер» разбито на ключевые области, которые реально проверяют на таких собеседованиях, — по темам и уровню сложности (Concept, Junior, Middle, Senior). Полный план и примеры вопросов можно посмотреть выше до входа.
Помогает ли интервальное повторение в подготовке к «Дата-инженер»?
Да. Активное вспоминание и честная самооценка помогают закреплять знания. RecallDeck назначает повторения карт по направлению «Дата-инженер» на основе ваших оценок: знакомые карты возвращаются реже, а сложные получают больше практики.
Можно попробовать направление «Дата-инженер» до оплаты?
Новым подписчикам месячного или годового тарифа может быть доступен пробный период семь дней со всем направлением «Дата-инженер» и всеми функциями. Право на него и сумму подтвердит страница оплаты; при повторной подписке списание может быть сразу. Отмените подписку онлайн до конца пробного периода, чтобы избежать первого списания. У вечного доступа пробного периода нет.