Перейти к содержанию
Данные и AI

9 вопросов по теме «Data Engineering: Хранение и форматы» на собеседовании

В этом материале — 9 вопросов из русской колоды RecallDeck по теме «Data Engineering: Хранение и форматы». Сначала сформулируйте короткий ответ сами, затем откройте подробный разбор и проверьте примеры, ограничения и отказные случаи.

9 мин чтения9 подробных ответовПроверено 24 августа 2026
Главная мысль

Сначала зафиксируйте grain данных, допущения, метрику и риск leakage, затем обсуждайте модель, инструмент или инфраструктуру.

Вопросы и ответы

9 подробных ответов

01

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

Короткий ответ: В строковом формате значения одной записи лежат рядом, в колоночном — рядом лежат все значения одной колонки. Для аналитических запросов (агрегаты по нескольким колонкам из десятков) колоночный формат читает только нужные колонки, лучше сжимается и поддерживает предикатный пушдаун — отсюда меньше 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) эффективнее.

02

Как устроен Parquet изнутри — row groups, column chunks, кодирование — и как он делает predicate и projection pushdown?

Короткий ответ: Parquet — колоночный формат, где файл разбит на горизонтальные row groups, внутри каждого данные хранятся по колонкам (column chunks), а колонка — из страниц (pages). В футере лежат схема и статистики (min/max, счётчики null) по каждому column chunk, за счёт которых движок пропускает лишние данные.

Подробно:

  1. Row group — горизонтальный срез (обычно 128–512 МБ), единица параллелизма: разные воркеры читают разные row groups.
  2. Column chunk — данные одной колонки внутри row group; читаются только колонки из проекции.
  3. Pages — колонка бьётся на страницы (~1 МБ) со своими статистиками и кодированием (dictionary, RLE, bit-packing) поверх сжатия (Snappy/Zstd).
  4. Footer — метаданные в конце файла: схема, смещения, min/max по chunk. Читается первым, поэтому фильтр отсекает row groups до чтения данных.
Parquet file
┌──────────────────────────────────────────┐
│ Row Group 0                                │
│   col A chunk [page|page|...] (min/max)    │
│   col B chunk [page|page|...] (min/max)    │
│ Row Group 1                                │
│   col A chunk ...   col B chunk ...         │
├──────────────────────────────────────────┤
│ Footer: schema + row-group/column stats    │
└──────────────────────────────────────────┘

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

03

Parquet, ORC, Avro, CSV/JSON — в чём разница и когда какой формат выбирать?

Короткий ответ: Parquet и ORC — колоночные форматы для аналитики (сжатие, пушдаун). Avro — строковый бинарный формат для стриминга и обмена сообщениями с сильной эволюцией схемы. CSV/JSON — текстовые форматы для обмена и отладки, но не для аналитики на объёме.

Подробно:

Формат Тип Схема Сильная сторона Когда брать
Parquet колоночный встроена сжатие, projection/predicate pushdown аналитика, data lake, Spark/Trino
ORC колоночный встроена сжатие + встроенные индексы экосистема Hive
Avro строковый отдельная (JSON) эволюция схемы, компактность Kafka, стриминг, обмен между сервисами
CSV строковый текст нет простота, читаем глазами ручной обмен, мелкие выгрузки
JSON строковый текст нет вложенность, гибкость API, логи, отладка
  1. Аналитика по колонкам — Parquet или ORC: читаешь мало колонок из многих, статистики отсекают блоки.
  2. Стриминг и обмен сообщениями — Avro: пишешь запись целиком, схема эволюционирует без переписывания данных.
  3. Текстовые CSV/JSON — удобны и переносимы, но нет типов, статистик и эффективного сжатия — для больших таблиц дорого.

⚠️ Частая ошибка: держать аналитический слой в CSV или «сыром» JSON. На объёме это кратно больше I/O и денег, чем тот же датасет в Parquet.

04

Открытые табличные форматы: Apache Iceberg, Delta Lake, Hudi — что они дают поверх «сырого» Parquet?

Короткий ответ: Табличный формат — это слой метаданных над файлами Parquet/ORC в объектном хранилище, который превращает набор файлов в таблицу с ACID-транзакциями, атомарными коммитами, time travel, эволюцией схемы и партиций. Iceberg, Delta и Hudi решают одно и то же, различаясь деталями движка и экосистемы.

Подробно:

  1. ACID и атомарные коммиты — читатели видят либо старую, либо новую версию таблицы, без «полусырых» файлов на середине записи.
  2. Time travel — снапшоты по версии/времени: можно прочитать таблицу «как было» и откатиться.
  3. Эволюция схемы и партиций — добавить/переименовать колонку и даже сменить схему партиционирования без переписывания данных.
  4. Hidden partitioning (Iceberg) — партиция выводится из значения (например, из timestamp), пользователю не нужно вручную фильтровать по колонке-партиции.
Формат Модель метаданных Особенность
Iceberg manifest-файлы, снапшоты hidden partitioning, движко-независимость
Delta Lake транзакционный лог _delta_log тесная связка со Spark, MERGE
Hudi таймлайн коммитов upsert-и и incremental pull из коробки
-- time travel в Iceberg: читаем таблицу на конкретный снапшот
SELECT * FROM orders
FOR SYSTEM_VERSION AS OF 3821550127947089009;

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

05

Как партиционировать данные в объектном хранилище и какие ловушки у мелких файлов и переизбытка партиций?

Короткий ответ: Партиционирование — раскладка данных по директориям вида col=value, чтобы запрос по фильтру читал только нужные партиции (partition pruning). Выбирайте колонку с умеренной кардинальностью, по которой реально фильтруете; избегайте слишком мелких партиций и переизбытка партиций.

Подробно:

  1. Партиция = префикс пути — движок видит year=2026/month=06 и пропускает остальные партиции без чтения данных.
  2. Выбор ключа — брать колонку из частых WHERE (дата, регион) с умеренной кардинальностью; высококардинальные ключи (user_id) плодят миллионы партиций.
  3. Размер файла — целитесь в файлы 128 МБ–1 ГБ; много крошечных файлов = проблема мелких файлов и медленный листинг в S3.
  4. Не переусердствовать — тысячи партиций по паре файлов дают дорогой листинг метаданных и почти не ускоряют чтение.
s3://lake/events/
  year=2026/
    month=06/
      day=30/
        part-0001.parquet   (≈256 МБ)
        part-0002.parquet   (≈256 МБ)
    month=07/
      day=01/
        part-0001.parquet

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

06

Кодеки сжатия Snappy, Zstd, Gzip: как выбирать между скоростью и степенью сжатия и почему важна splittable-разбиваемость?

Короткий ответ: Кодек — это компромисс между скоростью и степенью сжатия. Snappy — быстрый, но слабее жмёт; Gzip жмёт сильнее, но медленный и не splittable в сыром виде; Zstd даёт лучший баланс с настраиваемым уровнем. Для аналитики важна разбиваемость, чтобы читать файл параллельно.

Подробно:

  1. Скорость vs степень — Snappy оптимизирует CPU (частое чтение), Gzip — размер (архив/выгрузка), Zstd покрывает диапазон уровнем сжатия.
  2. Splittable-разбиваемость — можно ли читать разные части файла параллельно. Сырой Gzip неразбиваем: один воркер тянет весь файл, теряя параллелизм.
  3. Спасение внутри Parquet — в Parquet/ORC сжатие идёт по страницам/чанкам, поэтому даже Gzip внутри Parquet читается параллельно по row groups.
  4. Практика — Snappy как дефолт для «горячих» данных, Zstd когда важнее хранение при приемлемом CPU.
Кодек Скорость Степень Splittable (сырой)
Snappy очень высокая средняя нет (сам по себе)
Zstd высокая, настраиваемая высокая нет (сам по себе)
Gzip низкая высокая нет
внутри Parquet да (по row groups)

⚠️ Частая ошибка: класть большой .csv.gz как единый несплитируемый файл — весь гигабайт читает один воркер, и параллелизм кластера простаивает. Дробите на файлы или используйте Parquet.

07

Что такое эволюция схемы и как безопасно добавлять, переименовывать и удалять колонки в Avro и табличных форматах?

Короткий ответ: Эволюция схемы — изменение структуры данных без переписывания уже записанных файлов и без поломки старых читателей/писателей. Безопасность зависит от совместимости: добавление колонки со значением по умолчанию обычно безопасно, удаление и переименование — рискованны. Avro решает это через разрешение схем (schema resolution), табличные форматы — через отслеживание колонок по стабильным id.

Подробно:

  1. Добавление колонки — безопасно при наличии default: старые файлы читаются, отсутствующее значение подставляется дефолтом.
  2. Удаление колонки — безопасно для читателей нового кода, но старый читатель, требующий поле, сломается — нужна обратная совместимость.
  3. Переименование — самое опасное «в лоб»: по имени это удаление + добавление. Avro решает через алиасы, Iceberg — через стабильные column id, а не имена.
  4. Совместимость — backward (новая схема читает старые данные), forward (старая схема читает новые данные), full — обе сразу; в Kafka её стережёт Schema Registry.
Операция Avro Iceberg/Delta Риск
Добавить колонку default в схеме безопасно, id новый низкий
Удалить колонку reader игнорирует помечается удалённой средний
Переименовать алиас по column id, не по имени высокий без поддержки

⚠️ Частая ошибка: переименовать колонку в «сыром» Parquet-датасете по имени — старые файлы под старым именем перестают читаться как новая колонка, и данные молча пропадают из выборок.

08

Объектное хранилище (S3/GCS) как основа data lake: чем оно отличается от HDFS/POSIX и что важно знать про консистентность и стоимость?

Короткий ответ: Объектное хранилище — это плоское key-value хранилище объектов по HTTP, а не файловая система: нет настоящих директорий, нет дешёвого переименования, оплата идёт за хранение и за запросы. В отличие от HDFS/POSIX оно отделяет хранение от вычислений и масштабируется практически безгранично, но переименование папки — это копирование всех объектов.

Подробно:

  1. Плоское пространство ключей — «директории» это лишь префиксы в имени объекта; листинг идёт по префиксу, а не обходом дерева.
  2. Нет атомарного rename — переименование/перемещение = copy + delete по каждому объекту, поэтому коммит через переименование папки (как в HDFS) дорог; отсюда committers и табличные форматы.
  3. Консистентность — современный S3 read-after-write строго консистентен, но исторически была eventual consistency; закладывайтесь на возможные задержки в старых системах.
  4. Модель стоимости — платите за GB хранения, за GB трафика и за количество запросов (GET/PUT/LIST) — отсюда штраф за миллионы мелких файлов.
Свойство Объектное (S3/GCS) HDFS/POSIX
Модель key-value по HTTP файловая система
Rename папки copy+delete (дорого) атомарный, дешёвый
Масштаб/стоимость почти безграничный, платишь за запросы ограничен кластером
Хранение vs compute разделены связаны с узлами

⚠️ Частая ошибка: относиться к S3 как к POSIX-ФС и делать много LIST/rename на миллионах ключей — счёт за запросы и латентность листинга неожиданно становятся узким местом пайплайна.

09

В чём проблема мелких файлов, почему она убивает производительность и как её лечить компакцией?

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

Подробно:

  1. Откуда берётся — частые микро-батчи и стриминг, слишком мелкие партиции, много воркеров, каждый пишет свой крошечный файл.
  2. Почему больно — на каждый файл: запрос к S3, чтение метаданных, отдельный split/таск планировщика; тысячи файлов = тысячи открытий и медленный листинг.
  3. Компакция (compaction) — фоновая задача читает мелкие файлы и переписывает их в крупные (целимся в 128 МБ–1 ГБ); в Iceberg/Delta есть встроенные операции (OPTIMIZE, rewrite_data_files).
  4. Профилактика — писать реже и крупнее, дозагрузка батчей, разумная гранулярность партиций, не плодить лишние партиции.
До компакции:  [f1][f2][f3][f4][f5]...[f999]   ← 999 файлов × ~1 МБ
                     tiny files problem
                          │  compaction

После:         [ big-0001.parquet ][ big-0002.parquet ]  ← 2 файла × ~256 МБ

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

Источники

Источники и редакционная политика

Материалы RecallDeck сопоставлены с официальной документацией и открытыми публикациями компаний, когда первичный источник доступен. Мы не связаны с упомянутыми работодателями, не публикуем конфиденциальные задания и не продаём места в подборках. Формат найма может меняться — уточняйте его у рекрутера.

От чтения к воспроизведению

Отрепетируйте полный цикл интервью.

RecallDeck возвращает сложные темы по расписанию и помогает удерживать в памяти язык, SQL, архитектуру и поведенческие истории.

Начать подготовку

Продолжить подготовку

Библиотека собеседований RecallDeck

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

RSS