Сначала зафиксируйте grain данных, допущения, метрику и риск leakage, затем обсуждайте модель, инструмент или инфраструктуру.
Вопросы и ответы
9 подробных ответов
01Какие есть измерения качества данных и как проверять каждое из них?
middle
Короткий ответ: Классические шесть измерений — полнота, точность, согласованность, своевременность, уникальность и валидность. Под каждое пишется конкретный тест, а не абстрактное "данные хорошие": проверяется отсутствие NULL там, где их быть не должно, соответствие бизнес-правилам, отсутствие дублей по ключу и попадание значений в допустимый диапазон.
Подробно:
- Полнота (completeness) — нет пропусков в обязательных полях, приехали все ожидаемые строки/партиции.
- Точность (accuracy) — значения соответствуют реальности и бизнес-логике (сумма заказа не отрицательная).
- Согласованность (consistency) — одно и то же значение совпадает между витринами и системами.
- Своевременность (timeliness) — данные приезжают в рамках SLA по свежести.
- Уникальность (uniqueness) — нет дублей по естественному или суррогатному ключу.
- Валидность (validity) — значения соответствуют схеме, типам и допустимому диапазону.
| Измерение | Что проверяет | Тест |
|---|---|---|
| Полнота | нет пропусков | not_null, count партиций |
| Точность | бизнес-правила | amount >= 0 |
| Согласованность | совпадение источников | сверка сумм между витринами |
| Своевременность | свежесть | max(loaded_at) > now() - 3h |
| Уникальность | нет дублей | unique по ключу |
| Валидность | схема и диапазон | accepted_values, тип, regex |
⚠️ Частая ошибка: говорить "мы проверяем качество данных" без привязки к измерениям и конкретным ассертам — на собеседовании ждут, что вы назовёте измерение и сразу приведёте проверку под него.
02Как тестировать пайплайны данных: где уместны схемные проверки, dbt-тесты и Great Expectations?
middle
Короткий ответ: Схемные/ограничительные проверки ловят нарушения структуры и типов на уровне БД; dbt-тесты (not_null, unique, relationships, accepted_values) декларативно проверяют бизнес-инварианты прямо в трансформациях; Great Expectations даёт более богатый набор ассертов и профилирование там, где данные приходят вне dbt (сырые файлы, ingestion, ML-фичи).
Подробно:
- Схемные/constraint-тесты — NOT NULL, PK/FK, CHECK на уровне варехауса. Дёшево, но покрывают только структуру.
- dbt-тесты — живут рядом с моделью в
schema.yml, запускаются в CI и по расписанию, отлично для целостности между витринами (relationships). - Great Expectations / Soda — expectation suites, профилирование распределений, валидация на входе в лейк до трансформаций.
# schema.yml — dbt-тесты рядом с моделью
models:
- name: orders
columns:
- name: order_id
tests: [unique, not_null]
- name: customer_id
tests:
- relationships:
to: ref('customers')
field: customer_id
- name: status
tests:
- accepted_values:
values: ['new', 'paid', 'shipped', 'cancelled']
⚠️ Частая ошибка: тестировать только финальные витрины и не ставить проверки на входе — тогда мусор из источника едет через весь пайплайн, и падает уже далеко от причины.
03Что такое наблюдаемость данных и как заметить тихие проблемы раньше стейкхолдеров?
senior
Короткий ответ: Наблюдаемость данных (data observability) — это непрерывный мониторинг четырёх столпов: свежести, объёма, схемы и распределения. Тесты проверяют известные инварианты, а наблюдаемость ловит неизвестное: аномалии, дрейф и тихие поломки, которые не нарушают ни одного явного правила, но означают, что с данными что-то не так.
Подробно:
- Свежесть (freshness) — когда таблица обновлялась в последний раз; отставание от SLA — первый сигнал.
- Объём (volume) — число строк/партиций против исторической базовой линии; резкое падение = недогруз.
- Схема (schema) — появление/пропажа/смена типа колонок вверх по потоку.
- Распределение (distribution) — доля NULL, кардинальность, среднее/квантили; их дрейф выдаёт логическую поломку.
наблюдаемость данных
┌───────────┬──────────┬─────────┬──────────────┐
│ свежесть │ объём │ схема │ распределение│
└─────┬─────┴────┬─────┴────┬────┴──────┬───────┘
▼ ▼ ▼ ▼
отставание недогруз/ добавили/ рост доли
от SLA всплеск убрали NULL, дрейф
строк колонку кардинальности
└──────────┴─── алерт ДО того, как ──┴──► стейкхолдер
заметит бизнес
⚠️ Частая ошибка: полагаться только на явные тесты и узнавать о проблеме из письма аналитика "почему цифры за вчера просели" — без мониторинга распределения и свежести бизнес находит протухшие данные первым.
04Как строить надёжные пайплайны: идемпотентность, ретраи и атомарная запись без частичных данных?
senior
Короткий ответ: Задача должна быть идемпотентной — повторный запуск за тот же период даёт тот же результат без дублей (delete+insert или MERGE по ключу партиции, а не слепой append). Запись делается атомарно: пишем в стейджинг и только потом одним движением подменяем (rename/partition swap), чтобы читатели никогда не видели полузаписанные данные.
Подробно:
- Идемпотентность — перезапуск не плодит дубли: перезаписывайте партицию целиком или MERGE по ключу.
- Ретраи — задачи должны безопасно повторяться; побочные эффекты (уведомления, инкременты) выносим за пределы ретраев.
- Атомарная запись — write→stage→rename: читатели видят либо старую, либо новую версию, но не половину.
- Оркестрация — детерминированные окна по данным (ds/execution_date), а не now(), чтобы бэкфилл был воспроизводим.
write stage swap (atomic)
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ compute │ ───► │ _tmp/dt=... │ ──► │ rename → dt/ │
└──────────┘ └──────────────┘ └──────┬───────┘
▼
читатели видят старую ИЛИ новую партицию,
никогда — частично записанную
⚠️ Частая ошибка: писать напрямую в целевую партицию и падать на середине — потребители читают полупустые данные; плюс слепой INSERT при ретрае удваивает строки.
05Зачем нужен линидж данных и каталог, и как делать анализ влияния при изменении источника?
middle
Короткий ответ: Линидж (происхождение данных, lineage) — это граф зависимостей от источника через трансформации до витрин и дашбордов. Он нужен для анализа влияния (impact analysis): когда меняется источник, вы сразу видите, какие модели и отчёты вниз по потоку сломаются, и кого предупредить. Каталог добавляет к этому описания, владельцев и семантику.
Подробно:
- Обратный линидж (upstream) — от подозрительной цифры к источнику: разбор инцидентов и root cause.
- Прямой линидж (downstream) — от источника к потребителям: кого затронет изменение схемы или бэкфилл.
- Каталог — владельцы, описания, теги PII, уровень доверия к таблице.
- Автоматизация — dbt строит граф из
ref(); OpenLineage/Marquez собирают линидж на уровне джобов.
source.orders ─┐
├─► stg_orders ─► fct_orders ─► dash_revenue
source.users ──┘ │
└────────► ml_churn_features
меняется source.orders.status →
impact: stg_orders, fct_orders, dash_revenue, ml_churn_features
⚠️ Частая ошибка: менять схему источника, не посмотрев downstream-линидж, — и узнавать о поломанном дашборде от финансов, а не из анализа влияния.
06Как определять SLA/SLO на данные и гарантии свежести, и как алертить об опоздании датасета?
middle
Короткий ответ: SLA — это обещание потребителям (например, "витрина продаж готова к 8:00 за вчера"), SLO — измеримая внутренняя цель под него (свежесть < 3 часов в 99% дней). Гарантия свежести задаётся как порог на max(loaded_at); алерт срабатывает, когда данные опаздывают или протухли, до того как это заметит бизнес.
Подробно:
- SLA — договорённость с потребителем на языке бизнеса: к какому времени и с какой полнотой.
- SLO — числовая цель (свежесть, полнота, доля успешных прогонов) с окном измерения.
- Error budget — сколько нарушений допустимо; когда бюджет исчерпан, приоритет уходит на надёжность.
- Алерт свежести — проверка порога, а не только факта "джоб упал": данные могут опоздать и при зелёном пайплайне.
-- ассерт свежести: датасет протух, если последняя загрузка старше 3 часов
SELECT
max(loaded_at) AS last_load,
now() - max(loaded_at) AS lag,
(now() - max(loaded_at)) > interval '3 hours' AS is_stale -- → алерт
FROM analytics.fct_orders;
⚠️ Частая ошибка: ставить алерт только на падение задачи. Джоб может завершиться "успешно", но не привезти свежие данные — без проверки max(loaded_at) SLA нарушен молча.
07Как аккуратно обрабатывать изменения схемы вверх по потоку: контракты и совместимость?
senior
Короткий ответ: Нужен контракт данных (data contract) между источником и потреблением и правила совместимости: обратно совместимые изменения (добавление nullable-колонки) безопасны, ломающие (удаление колонки, смена типа) требуют версионирования и согласования. При нарушении контракта пайплайн должен падать громко, а не молча дропать данные.
Подробно:
- Контракт данных — явная схема, типы, обязательность и владелец; изменения проходят ревью.
- Обратная совместимость (backward) — новый продюсер, старые потребители: добавляй nullable-поля, не удаляй и не переименовывай.
- Прямая совместимость (forward) — старый продюсер, новые потребители: игнорируй неизвестные поля.
- Fail loudly — при несовместимом изменении карантин строк и алерт, а не тихое отбрасывание.
| Изменение схемы | Совместимость | Действие |
|---|---|---|
| Добавить nullable-колонку | обратная | безопасно, катим |
| Удалить/переименовать колонку | ломающее | новая версия + депрекация |
| Сменить тип (int→string) | ломающее | контракт-тест падает, карантин |
| Добавить enum-значение | зависит | расширить accepted_values заранее |
⚠️ Частая ошибка: ловить изменение схемы через try/except и молча дропать несовпавшие строки — потери данных никто не видит, пока не разойдутся цифры. Падать громко лучше, чем терять тихо.
08На что алертить в пайплайнах, чтобы ловить проблемы, но не утонуть в алерт-фатиге?
middle
Короткий ответ: Алертьте на то, что требует действия человека: падения задач, нарушение SLA по свежести и аномалии числа строк. Всё остальное — в дашборды и логи. Каждый алерт должен быть actionable, адресован владельцу и настроен с порогами/дедупликацией, иначе команда перестаёт на них реагировать.
Подробно:
- Actionable, а не FYI — если по алерту ничего не делают, это не алерт, а шум.
- Пороги и базовые линии — сравнение с историей (± отклонение), а не жёсткое "< 1000 строк".
- Severity и маршрутизация — критичное будит дежурного, остальное идёт в чат/дайджест.
- Дедупликация и группировка — один инцидент = один алерт, а не сотня писем.
| Событие | Алертить? | Почему |
|---|---|---|
| Задача упала | да, сразу | пайплайн стоит |
| Нарушен SLA свежести | да | потребители получат старые данные |
| Аномалия числа строк | да, по базовой линии | тихий недогруз/дубли |
| Разовый скачок латентности | нет, в дашборд | само выровняется |
| Прошёл ретрай и всё ок | нет | действий не требует |
⚠️ Частая ошибка: алертить на каждую мелочь. Наступает alert fatigue — команда глушит канал и пропускает настоящий инцидент среди шума.
09Какие основы data governance ведёт дата-инженер: PII, маскирование, доступы и удаление по GDPR?
middle
Короткий ответ: Инженер отвечает за то, чтобы PII/ПДн были помечены, замаскированы или зашифрованы, доступ выдавался по принципу минимальных привилегий (RBAC/row/column-level), а данные хранились и удалялись по политике retention. Под GDPR/удаление нужен механизм точечного стирания субъекта из лейка и варехауса.
Подробно:
- Классификация PII — тегируем чувствительные колонки (email, телефон, ПДн) в каталоге.
- Маскирование/шифрование — токенизация, хеширование, dynamic masking; аналитик видит замаскированное.
- Контроль доступа — RBAC, column- и row-level security, аудит обращений.
- Retention и удаление — TTL на партиции; право на забвение — удаление субъекта по всем слоям.
| Механизм | Что делает | Пример |
|---|---|---|
| Классификация | помечает PII | тег pii:email в каталоге |
| Маскирование | скрывает значение | a***@mail.com, хеш |
| RBAC / RLS | ограничивает доступ | роль видит только свой регион |
| Retention/TTL | удаляет по сроку | партиции > 2 лет дропаются |
| Right to erasure | стирает субъекта | удаление user_id из всех слоёв |
⚠️ Частая ошибка: тащить сырые PII через все слои без маскирования и без карты, где они лежат, — тогда запрос на удаление по GDPR невозможно выполнить, а утечка становится вопросом времени.
Источники
Источники и редакционная политика
Материалы RecallDeck сопоставлены с официальной документацией и открытыми публикациями компаний, когда первичный источник доступен. Мы не связаны с упомянутыми работодателями, не публикуем конфиденциальные задания и не продаём места в подборках. Формат найма может меняться — уточняйте его у рекрутера.
От чтения к воспроизведению
Отрепетируйте полный цикл интервью.
RecallDeck возвращает сложные темы по расписанию и помогает удерживать в памяти язык, SQL, архитектуру и поведенческие истории.