Cloud, DataOps & CI/CD — DE Interview PrepCloud, DataOps & CI/CD — Подготовка к DE-интервью

Fast-revision cheatsheet for Data Engineering interviews. Tailored for Senior/Lead Data Engineer roles.

Шпаргалка для быстрого повторения перед Data Engineering интервью. Заточена под Senior/Lead Data Engineer.

Personal anchors: GCP + BigQuery + Snowflake + dbt (McMakler / Career.io), Azure OpenAI (IU Group), AWS/Azure exposure, dbt code-review standards institutionalised, Airflow CI.

Личные якоря: GCP + BigQuery + Snowflake + dbt (McMakler / Career.io), Azure OpenAI (IU Group), опыт AWS/Azure, внедрённые стандарты code-review для dbt, CI для Airflow.

dbt Snowflake BigQuery Airflow Terraform Docker GCP / AWS / Azure Data Catalog / Lineage
1

What DataOps Actually IsЧто такое DataOps на самом деле

One-line definitionОпределение одной строкой

DataOps = applying DevOps + Agile + Lean manufacturing ideas to the data lifecycle so that analytics and data products ship fast, repeatably, and with quality guarantees. It is the union of four pillars applied to data:

DataOps = применение идей DevOps + Agile + Lean manufacturing к жизненному циклу данных, чтобы аналитика и дата-продукты выкатывались быстро, воспроизводимо и с гарантиями качества. Это объединение четырёх столпов, примененных к данным:

  • CI/CD — automated build, test and deploy of pipelines, transforms and infra.
  • Automated testing — code tests and data tests (freshness, volume, schema, business rules).
  • Observability / monitoring — freshness, volume, distribution, lineage and incident alerting (the "data downtime" idea).
  • Collaboration & governance — version control, code review, environments, catalog, documentation, ownership.
  • CI/CD — автоматизированные сборка, тестирование и деплой пайплайнов, трансформаций и инфраструктуры.
  • Автоматизированное тестирование — тесты кода и тесты данных (свежесть, объём, схема, бизнес-правила).
  • Наблюдаемость / мониторинг — свежесть, объём, распределение, lineage и алертинг при инцидентах (концепция «data downtime»).
  • Коллаборация & governance — контроль версий, code review, окружения, каталог, документация, ownership.

Why it matters for an econ-data team

Почему это важно для команды экономических данных

Economic indicators (CPI, payrolls, GDP) are high-trust, point-in-time series consumed by clients and trading systems. A bad revision, a late landing, or a silent schema change is a credibility incident. DataOps is how you make correctness and timeliness systematic rather than heroic.

Экономические индикаторы (CPI, payrolls, GDP) — это высокодоверенные, точечные во времени серии, которые потребляются клиентами и торговыми системами. Плохая ревизия, задержка поступления или тихое изменение схемы — это инцидент доверия. DataOps — это способ сделать корректность и своевременность систематическими, а не героическими.

My storyМоя история

At McMakler/Career.io I treated dbt as the unit of change: every transform was version-controlled, reviewed against a standard I authored, and tested in CI before it could reach prod. That is DataOps in practice — not a tool, a discipline enforced by the pipeline.

В McMakler/Career.io я относился к dbt как к единице изменений: каждая трансформация была под контролем версий, проходила ревью по стандарту, который я написал, и тестировалась в CI перед тем как попасть в прод. Это DataOps на практике — не инструмент, а дисциплина, обеспечиваемая пайплайном.

DevOps vs DataOps — the key differenceDevOps vs DataOps — ключевое отличие

DimensionDevOpsDataOps
Artifact under testCode + binariesCode and the data flowing through it
Failure modeService crashes / bugSilent wrong numbers ("data downtime")
StateMostly stateless deploysStateful: history, backfills, revisions
TestsUnit/integration of code+ data quality, contracts, freshness, anomaly
RollbackRedeploy old binaryRedeploy + possibly reprocess/restate data
АспектDevOpsDataOps
Тестируемый артефактКод + бинарникиКод и данные, которые через него текут
Режим сбояПадение сервиса / багТихие неправильные цифры («data downtime»)
СостояниеВ основном stateless-деплоиStateful: история, backfill-ы, ревизии
ТестыUnit/integration кода+ качество данных, контракты, свежесть, аномалии
ОткатПередеплой старого бинарникаПередеплой + возможная переобработка/restate данных
Interviewer will probeО чём спросит интервьюер

"How is testing data different from testing code?" → Code tests are deterministic given input; data tests assert on values you don't control (the data is the variable). You test properties (not-null, unique, ranges, referential integrity, row-count deltas), not exact outputs.

«Чем тестирование данных отличается от тестирования кода?» → Тесты кода детерминированы при заданном вводе; тесты данных проверяют значения, которые ты не контролируешь (данные — это переменная). Проверяешь свойства (not-null, unique, диапазоны, референциальную целостность, дельты числа строк), а не точные выводы.

2

Version Control for Data & CodeКонтроль версий для данных и кода

Git workflow for data teamsGit-процесс для дата-команд

Everything that defines the pipeline lives in git: dbt models, SQL, Airflow DAGs, Terraform, schema/contract files, tests, docs. Common lightweight flow:

Всё, что определяет пайплайн, живёт в git: dbt-модели, SQL, Airflow DAG-и, Terraform, файлы схем/контрактов, тесты, доки. Типичный лёгкий процесс:

# trunk-based with short-lived feature branches
git checkout -b feat/cpi-seasonal-adjust
# ... edit dbt model + add tests ...
git commit -m "[econ_de] Add seasonally adjusted CPI model + freshness test"
git push origin feat/cpi-seasonal-adjust
# open PR -> CI runs lint + unit + data tests on a sandbox/CI schema
# review (enforced standard) -> squash merge to main -> auto-deploy to stage

Environments: dev / stage / prod

Окружения: dev / stage / prod

  • dev — engineer's sandbox; dbt builds into a personal schema (dbt_amal), cheap, fast, dirty.
  • stage — production-shaped, fed by main branch, full test suite, used for validation and integration tests.
  • prod — only reached by promoted, tested, reviewed code. No manual edits.
  • dev — песочница инженера; dbt строит в личную схему (dbt_amal), дёшево, быстро, грязно.
  • stage — как продакшн, питается из main-ветки, полный набор тестов, используется для валидации и интеграционных тестов.
  • prod — доступен только для промоушен-кода, протестированного и пройденного ревью. Никаких ручных правок.

"Version control for data" — three flavours«Контроль версий для данных» — три вкуса

What you versionHowTooling examples
Transform logicGit on SQL/dbt/DAGsgit, dbt, Airflow
Schema / contractsVersioned schema files, contract checks in CIdbt contracts, JSON Schema, Avro/Protobuf
Data itselfSnapshots, time-travel, table cloning, data versioningSnowflake Time Travel + Zero-Copy Clone, BigQuery snapshots/time-travel, dbt snapshots, lakeFS / Iceberg branches
Что версионируешьКакПримеры инструментов
Логика трансформацийGit на SQL/dbt/DAG-ахgit, dbt, Airflow
Схемы / контрактыВерсионированные файлы схем, проверки контрактов в CIdbt contracts, JSON Schema, Avro/Protobuf
Сами данныеСнапшоты, time-travel, клонирование таблиц, data versioningSnowflake Time Travel + Zero-Copy Clone, BigQuery snapshots/time-travel, dbt snapshots, lakeFS / Iceberg branches
My storyМоя история

For econ series specifically, dbt snapshots are how you version data: they capture slowly-changing dimensions / revisions as type-2 history, so you can reconstruct "what did CPI look like as published on 2026-03-10?" — point-in-time correctness, which is everything in economic data.

Для экономических серий в частности, dbt snapshots — это способ версионирования данных: они захватывают медленно меняющиеся измерения / ревизии как type-2 историю, так что можно восстановить «как выглядел CPI на момент публикации 2026-03-10?» — точность на момент времени, что является всем в экономических данных.

Branching for data

Ветвление для данных

Modern pattern: each feature branch gets an isolated data environment. In Snowflake you zero-copy clone prod into a branch schema (instant, cheap, no storage duplication) so CI tests run against realistic data without touching prod. Iceberg/lakeFS expose git-like branch/merge on the data itself.

Современный паттерн: каждая feature-ветка получает изолированное окружение данных. В Snowflake ты делаешь zero-copy clone прода в ветку-схему (мгновенно, дёшево, без дублирования хранилища), так что тесты CI идут на реалистичных данных без касания прода. Iceberg/lakeFS предоставляют git-подобное ветвление/слияние на самих данных.

GotchaПодводный камень

Never commit credentials, service-account keys, or large data files to git. Data belongs in the warehouse/object store; git holds code and config. Use a .gitignore + secret scanning.

Никогда не коммить credentials, ключи сервисных аккаунтов или большие файлы данных в git. Данные принадлежат хранилищу/object store; git хранит код и конфиг. Использовать .gitignore + сканирование секретов.

3

CI/CD for Data PipelinesCI/CD для дата-пайплайнов

CI/CD-for-data pipeline (ASCII)CI/CD-пайплайн для данных (ASCII)

   DEV                          CI  (on Pull Request)                       CD (on merge)
 ┌───────┐    git push   ┌──────────────────────────────────┐    merge   ┌──────────────────────┐
 │ branch│ ────────────► │ 1. LINT     sqlfluff / dbt parse │ ─────────► │  build artifacts     │
 │ +tests│               │ 2. UNIT     macro / py unit tests│            │  (dbt manifest, DAG, │
 └───────┘               │ 3. BUILD    dbt build --select   │            │   docker image)      │
      ▲                  │             state:modified+      │            └──────────┬───────────┘
      │ fix              │ 4. DATA     dbt test (not_null,  │                       │ deploy
      │                  │             unique, accepted_*,  │                       ▼
      │                  │             relationships, fresh)│            ┌──────────────────────┐
      │   FAIL ◄─────────│ 5. CONTRACT schema/contract check│            │  STAGE  full run +   │
      │                  │ 6. INTEG    e2e on cloned prod   │            │  full test suite     │
      └──────────────────│             schema (zero-copy)   │            └──────────┬───────────┘
                         └──────────────────────────────────┘                       │ promote (green)
                                                                                     ▼
                                                                          ┌──────────────────────┐
                                                                          │  PROD   blue/green or │
                                                                          │  canary; auto-rollback│
                                                                          │  on data-quality gate │
                                                                          └──────────────────────┘
      
   DEV                            CI  (при Pull Request)                      CD (при merge)
 ┌───────┐    git push   ┌──────────────────────────────────┐    merge   ┌──────────────────────┐
 │ branch│ ────────────► │ 1. LINT     sqlfluff / dbt parse │ ─────────► │  сборка артефактов   │
 │ +tests│               │ 2. UNIT     macro / py unit tests│            │  (dbt manifest, DAG, │
 └───────┘               │ 3. BUILD    dbt build --select   │            │   docker image)      │
      ▲                  │             state:modified+      │            └──────────┬───────────┘
      │ fix              │ 4. DATA     dbt test (not_null,  │                       │ deploy
      │                  │             unique, accepted_*,  │                       ▼
      │                  │             relationships, fresh)│            ┌──────────────────────┐
      │   FAIL ◄─────────│ 5. CONTRACT schema/contract check│            │  STAGE  full run +   │
      │                  │ 6. INTEG    e2e на клоне прода   │            │  полный набор тестов │
      └──────────────────│             (zero-copy)          │            └──────────┬───────────┘
                         └──────────────────────────────────┘                       │ promote (green)
                                                                                     ▼
                                                                          ┌──────────────────────┐
                                                                          │  PROD   blue/green   │
                                                                          │  / canary; auto-     │
                                                                          │  rollback на DQ gate │
                                                                          └──────────────────────┘
      

What runs in CI (and why)Что запускается в CI (и зачем)

  • Lint / static checkssqlfluff, dbt parse, ruff/black for Python DAGs. Catches style + parse errors in seconds, free.
  • Slim / state-aware buildsdbt build --select state:modified+ only builds models that changed and their downstream. Fast PRs, low compute cost.
  • Unit tests — dbt unit tests (mock inputs → assert outputs) and Python unit tests for custom logic / operators.
  • Data tests — generic + singular dbt tests run against the built models.
  • Contract checks — fail the build if output schema/types drift from the declared contract.
  • Integration / e2e — full DAG/dbt run on a cloned-prod CI schema to catch cross-model and dependency issues.
  • Lint / статические проверкиsqlfluff, dbt parse, ruff/black для Python DAG-ов. Ловят стиль + parse-ошибки за секунды, бесплатно.
  • Slim / state-aware сборкиdbt build --select state:modified+ строит только изменённые модели и их downstream. Быстрые PR-ы, низкая стоимость вычислений.
  • Unit-тесты — dbt unit tests (мок входов → проверка выходов) и Python unit-тесты для кастомной логики / операторов.
  • Тесты данных — generic + singular dbt-тесты на построенных моделях.
  • Проверки контрактов — фейлить сборку, если выходная схема/типы отклоняются от декларированного контракта.
  • Интеграционные / e2e — полный DAG/dbt run на клоне прода CI-схемы для выявления кросс-модельных и dependency-проблем.

Build & deploy of DAGs and dbt models

Сборка & деплой DAG-ов и dbt-моделей

  • dbt: CI produces the manifest.json artifact; CD deploys compiled models + runs them in the target env. The manifest also powers slim CI via state comparison.
  • Airflow: DAG files are version-controlled; CI validates them (DagBag import test catches broken DAGs before they hit the scheduler); CD syncs them to the Airflow environment (git-sync / dags volume / image bake).
  • dbt: CI производит артефакт manifest.json; CD деплоит скомпилированные модели + запускает их в целевом окружении. Manifest также питает slim CI через сравнение состояния.
  • Airflow: файлы DAG-ов под контролем версий; CI валидирует их (тест импорта DagBag ловит битые DAG-и до того как они попадут в планировщик); CD синхронизирует их в Airflow-окружение (git-sync / dags volume / image bake).
My story — Airflow CIМоя история — Airflow CI

I added a CI gate that imports every DAG (DagBag test) plus a cycle/owner/SLA check, so a syntactically broken or owner-less DAG can never reach the scheduler. Combined with dbt slim-CI it cut PR feedback from "wait for the nightly run" to a few minutes.

Я добавил CI-гейт, который импортирует каждый DAG (DagBag-тест) плюс проверку цикла/owner-а/SLA, так что синтаксически битый или без owner-а DAG никогда не дойдёт до планировщика. В сочетании с dbt slim-CI это сократило обратную связь на PR-ах с «жди ночного запуска» до нескольких минут.

Deployment strategies for dataСтратегии деплоя для данных

StrategyHow it works for dataWhen to use
Blue/greenBuild new version into a parallel schema/table (green), validate, then atomically swap (rename / view repoint / clone). Old (blue) stays for instant rollback.Schema or large logic changes to consumed tables
CanaryRoute a slice (one partition, one market, small % of downstream) to the new logic, compare metrics vs control, then ramp.Risky transform/model changes
Audit-then-swap (WAP)Write-Audit-Publish: write to staging, run DQ audit, publish only if green.Default for critical published series
Auto-rollbackIf a post-deploy DQ gate fails (row count drop, null spike, freshness miss), revert the swap / re-point view to last-good.Always, as a safety net
СтратегияКак работает для данныхКогда использовать
Blue/greenСтроить новую версию в параллельную схему/таблицу (green), валидировать, затем атомарно переключить (rename / переточить view / clone). Старая (blue) остаётся для мгновенного отката.Схемные или крупные логические изменения в потребляемых таблицах
CanaryНаправить кусочек (одна партиция, один рынок, малый % downstream) на новую логику, сравнить метрики с контролем, затем расширять.Рискованные изменения в трансформ/модели
Audit-then-swap (WAP)Write-Audit-Publish: писать в staging, запускать DQ-аудит, публиковать только если зелёный.По умолчанию для критических публикуемых серий
Auto-rollbackЕсли пост-деплой DQ-гейт фейлится (падение числа строк, скачок null-ов, пропуск freshness), откатить переключение / переточить view на last-good.Всегда, как подстраховка
Interviewer will probeО чём спросит интервьюер

"How do you do blue/green when the artifact is a table other systems query?" → You don't redeploy a binary, you repoint the consumer abstraction: build into table_v2, validate, then swap the view/alias or atomic RENAME so consumers never see a partial state. Snowflake zero-copy clone makes the "green" copy free.

«Как делать blue/green, когда артефакт — это таблица, которую запрашивают другие системы?» → Ты не передеплоишь бинарник, ты переточишь абстракцию потребителя: строишь в table_v2, валидируешь, затем меняешь view/alias или атомарный RENAME, так что потребители никогда не видят частичное состояние. Snowflake zero-copy clone делает «зелёную» копию бесплатной.

4

The Testing Pyramid for DataПирамида тестирования для данных

                /\            E2E / pipeline      (few, slow, expensive)
               /  \          full DAG run on cloned prod, output vs golden
              /----\
             /      \        Integration         (cross-model, sources, deps)
            /--------\
           /          \      Contract             (schema/type stability, freshness)
          /------------\
         /              \    Data-quality tests   (not_null, unique, ranges, ref-integ)
        /----------------\
       /                  \  Unit tests           (many, fast, cheap)
      /____________________\ dbt unit tests + py logic, mocked inputs
      
                /\            E2E / pipeline      (мало, медленно, дорого)
               /  \          полный запуск DAG на клоне прода, вывод vs эталон
              /----\
             /      \        Интеграционные      (кросс-модельные, sources, deps)
            /--------\
           /          \      Контракты            (стабильность схемы/типов, freshness)
          /------------\
         /              \    Тесты качества данных (not_null, unique, диапазоны, ref-integ)
        /----------------\
       /                  \  Unit-тесты           (много, быстро, дёшево)
      /____________________\ dbt unit tests + py-логика, моки входов
      
LayerWhat it assertsExample
UnitTransform logic given mocked inputsdbt unit test: a SA-CPI macro returns expected value for fixed fixture rows
Data qualityProperties of real datanot_null, unique, accepted_values, custom range test on inflation %
ContractOutput shape/types are stabledbt model contract: column set + types enforced at build
IntegrationModels fit together; sources behaverelationships test; source freshness; full dbt build
E2EWhole pipeline output correctRun DAG end-to-end on cloned prod, diff vs golden/reconciliation total
УровеньЧто проверяетПример
UnitЛогика трансформации на замоканных входахdbt unit test: макрос SA-CPI возвращает ожидаемое значение для фиксированных строк-фикстур
Качество данныхСвойства реальных данныхnot_null, unique, accepted_values, кастомный range-тест на инфляцию %
КонтрактСтабильность выходной формы/типовdbt model contract: набор колонок + типы enforced при сборке
ИнтеграционныеМодели подходят друг другу; sources ведут себяrelationships test; source freshness; полный dbt build
E2EВывод всего пайплайна корректенЗапустить DAG end-to-end на клоне прода, diff vs эталон/итого сверки

Data-quality gates in CIГейты качества данных в CI

# dbt schema.yml — declarative data tests + contract
models:
  - name: fct_cpi_monthly
    config: { contract: { enforced: true } }
    columns:
      - name: period
        data_type: date
        tests: [not_null, unique]
      - name: cpi_yoy_pct
        data_type: numeric
        tests:
          - not_null
          - dbt_utils.accepted_range: { min_value: -20, max_value: 50 }
    # freshness so a stale upstream feed fails CI/monitoring
sources:
  - name: bls_raw
    freshness: { warn_after: {count: 26, period: hour}, error_after: {count: 48, period: hour} }
  • Block the merge on test failure — a failing data test is a red CI = no deploy.
  • Severity: warn for soft anomalies, error for hard gates. Tune to avoid alert fatigue.
  • Reconciliation tests — assert totals match the source-of-truth (e.g. sum of components = published headline).
  • Блокировать merge при фейле теста — фейлящий тест данных = красный CI = нет деплоя.
  • Severity: warn для мягких аномалий, error для жёстких гейтов. Настраивать, чтобы избегать усталости от алертов.
  • Тесты сверки — проверять, что итоги совпадают с источником истины (например, сумма компонентов = опубликованный headline).
GotchaПодводный камень

Don't run heavy data tests on full prod volume in every PR — it's slow and costly. Use slim CI (only changed models + downstream) on a sampled or cloned schema; save full-volume suites for stage / nightly.

Не запускать тяжёлые тесты данных на полном объёме прода в каждом PR — это медленно и дорого. Использовать slim CI (только изменённые модели + downstream) на сэмплированной или клонированной схеме; оставить полнообъёмные наборы для stage / ночных запусков.

Interviewer will probeО чём спросит интервьюер

"A test fails at 2am for a published series — what happens?" → Pipeline halts at the DQ gate (WAP: never publishes bad data), alert fires to oncall with the failing test + lineage of impacted downstream, last-good version stays served, you triage. Quality gate protects the consumer first.

«Тест фейлится в 2 часа ночи для публикуемой серии — что происходит?» → Пайплайн останавливается на DQ-гейте (WAP: никогда не публикуется плохой датасет), алерт срабатывает на oncall с фейлящим тестом + lineage затронутого downstream, last-good версия остаётся отдаваемой, ты разбираешься. Гейт качества защищает потребителя в первую очередь.

5

Infrastructure as Code, Docker & OrchestrationInfrastructure as Code, Docker и оркестрация

Infrastructure as Code (Terraform basics)Infrastructure as Code (основы Terraform)

IaC = declare infra in version-controlled config so environments are reproducible, reviewable, and diff-able. Terraform is declarative + cloud-agnostic.

IaC = декларировать инфраструктуру в версионированном конфиге, чтобы окружения были воспроизводимыми, reviewable и diff-able. Terraform декларативен + облачно-агностичен.

# declare a warehouse + dataset; plan -> review -> apply
resource "snowflake_warehouse" "transform" {
  name           = "WH_TRANSFORM"
  warehouse_size = "SMALL"
  auto_suspend   = 60          # suspend after 60s idle = cost control
  auto_resume    = true
}
resource "google_bigquery_dataset" "econ" {
  dataset_id = "econ_marts"
  location   = "EU"
}
  • Core verbs: initplan (preview diff) → apply. plan in CI on every PR = no surprise infra changes.
  • State lives in a remote backend (GCS/S3) with locking, so the team shares one source of truth.
  • Modules = reusable building blocks; workspaces/var files parametrise dev/stage/prod.
  • Idempotent & declarative: you describe desired state, Terraform computes the delta.
  • Основные команды: initplan (preview diff) → apply. plan в CI на каждом PR = нет внезапных изменений инфры.
  • State живёт в remote backend (GCS/S3) с блокировкой, так что команда разделяет один источник истины.
  • Модули = переиспользуемые строительные блоки; workspaces/var-файлы параметризуют dev/stage/prod.
  • Идемпотентный & декларативный: ты описываешь желаемое состояние, Terraform вычисляет дельту.
GotchaПодводный камень

Never edit infra in the cloud console by hand once it's under Terraform — that causes state drift. Either import it or change it through code.

Никогда не редактировать инфру в консоли облака вручную, если она под Terraform — это вызывает state drift. Либо импортировать её, либо менять через код.

Containerization + orchestration (high level)Контейнеризация + оркестрация (высокий уровень)

  • Docker packages code + dependencies + runtime into one immutable image → "runs the same on my laptop, CI, and prod". For data: a pinned dbt/Python image kills "works on my machine" version drift.
  • Image as artifact: CI builds and tags the image; CD deploys that exact tag → reproducible runs and easy rollback (deploy previous tag).
  • Orchestration (Kubernetes / managed runners): schedules and scales containers, restarts on failure, handles secrets/config injection. Airflow's KubernetesPodOperator runs each task in its own container.
  • Airflow itself is the workflow orchestrator (dependencies, schedules, retries, backfills, SLAs); Kubernetes is the container orchestrator underneath.
  • Docker упаковывает код + зависимости + runtime в один неизменяемый image → «запускается одинаково на моём ноутбуке, CI и проде». Для данных: закреплённый dbt/Python image убивает «работает на моей машине» версионный дрейф.
  • Image как артефакт: CI строит и тегирует image; CD деплоит этот точный тег → воспроизводимые запуски и лёгкий откат (деплой предыдущего тега).
  • Оркестрация (Kubernetes / managed runners): планирует и масштабирует контейнеры, рестартует при падении, обрабатывает инъекцию секретов/конфига. Airflow KubernetesPodOperator запускает каждую задачу в своём контейнере.
  • Сам Airflow — это оркестратор workflow (зависимости, расписания, ретраи, backfill-ы, SLA); Kubernetes — оркестратор контейнеров под ним.
Interviewer will probeО чём спросит интервьюер

"Why containerize a dbt run?" → Pin dbt + adapter + Python deps to an exact, tested version so CI and prod are byte-identical; isolate per-task deps; make rollback = redeploy old image tag. Reproducibility is the whole point.

«Зачем контейнеризировать dbt run?» → Закрепить dbt + adapter + Python deps на точной, протестированной версии, чтобы CI и прод были побайтово идентичны; изолировать зависимости на задачу; сделать откат = передеплой старого image tag. Воспроизводимость — вся суть.

6

Cloud Data Platform Building BlocksСтроительные блоки облачной дата-платформы

The five layersПять слоёв

LayerRoleGCPAWSAzure
Object storageCheap durable landing/raw zoneGCSS3ADLS / Blob
Warehouse / lakehouseQuery + transform engineBigQueryRedshift / AthenaSynapse / Fabric
ComputeElastic processingDataproc / BQ slotsEMR / GlueDatabricks / Synapse
OrchestrationSchedule + dependenciesCloud Composer (Airflow)MWAAData Factory
Catalog / governanceMetadata, lineage, accessDataplex / Data CatalogGlue Catalog / DataZonePurview
СлойРольGCPAWSAzure
Object storageДешёвая надёжная зона landing/rawGCSS3ADLS / Blob
Warehouse / lakehouseДвижок запросов + трансформацийBigQueryRedshift / AthenaSynapse / Fabric
ComputeЭластичная обработкаDataproc / BQ slotsEMR / GlueDatabricks / Synapse
ОркестрацияРасписания + зависимостиCloud Composer (Airflow)MWAAData Factory
Каталог / governanceМетаданные, lineage, доступDataplex / Data CatalogGlue Catalog / DataZonePurview

Snowflake sits cross-cloud as a managed warehouse/lakehouse that runs on top of GCS/S3/Blob — which is why my GCP→Snowflake migration was about moving the engine, not the storage paradigm.

Snowflake сидит кросс-облачно как управляемый warehouse/lakehouse, который работает поверх GCS/S3/Blob — поэтому моя миграция GCP→Snowflake была о переносе движка, а не парадигмы хранения.

Warehouse vs LakehouseWarehouse vs Lakehouse

Data WarehouseLakehouse
DataStructured, schema-on-writeStructured + semi/unstructured, schema-on-read+write
StorageProprietary/managed columnarOpen formats on object store (Parquet + Delta/Iceberg/Hudi)
StrengthBI/SQL, governance, performanceML + BI on one copy, open, cheap storage
ACIDNativeVia table format (Delta/Iceberg)
ExamplesBigQuery, Snowflake, RedshiftDatabricks, Snowflake (Iceberg), Fabric
Data WarehouseLakehouse
ДанныеСтруктурированные, schema-on-writeСтруктурированные + полу-/неструктурированные, schema-on-read+write
ХранениеПроприетарное/управляемое колоночноеОткрытые форматы на object store (Parquet + Delta/Iceberg/Hudi)
Сильная сторонаBI/SQL, governance, производительностьML + BI на одной копии, открыто, дешёвое хранение
ACIDНативныйЧерез табличный формат (Delta/Iceberg)
ПримерыBigQuery, Snowflake, RedshiftDatabricks, Snowflake (Iceberg), Fabric

Snowflake vs BigQuery at a glanceSnowflake vs BigQuery кратко

SnowflakeBigQuery
Compute modelVirtual warehouses (sized, you start/suspend)Serverless slots (auto / reservations)
PricingPer-second credits by warehouse sizePer-TB scanned (on-demand) or flat-rate slots
CloudMulti-cloud (AWS/GCP/Azure)GCP-native
ScalingResize / multi-cluster for concurrencyFully managed, automatic
Killer featuresZero-copy clone, Time Travel, data sharingServerless, BQML, cheap storage, GIS
Cost leverRight-size + auto-suspend warehousesPartition/cluster to scan less; cap with reservations
SnowflakeBigQuery
Модель computeВиртуальные warehouses (размерные, ты start/suspend)Serverless slots (авто / резервирования)
ЦенообразованиеПо секундам кредитов по размеру warehouseЗа TB сканирования (on-demand) или flat-rate slots
ОблакоMulti-cloud (AWS/GCP/Azure)GCP-native
МасштабированиеResize / multi-cluster для конкуренцииПолностью управляемо, автоматически
Убийственные фичиZero-copy clone, Time Travel, data sharingServerless, BQML, дешёвое хранилище, GIS
Рычаг стоимостиRight-size + auto-suspend warehousesPartition/cluster, чтобы сканировать меньше; cap с резервированиями
My story — GCP → SnowflakeМоя история — GCP → Snowflake

I led/contributed to migrating transforms from BigQuery to Snowflake. The mindset shift: BigQuery cost = bytes scanned (so partition + cluster aggressively), Snowflake cost = warehouse uptime (so right-size warehouses + auto-suspend, and exploit zero-copy clones for cheap CI/dev environments). Same dbt models, different cost-optimisation playbook.

Я вёл/участвовал в миграции трансформаций с BigQuery на Snowflake. Сдвиг мышления: стоимость BigQuery = сканируемые байты (поэтому партиционируй + кластеризуй агрессивно), стоимость Snowflake = uptime warehouse (поэтому right-size warehouses + auto-suspend, и используй zero-copy clone-ы для дешёвых CI/dev-окружений). Те же dbt-модели, разный плейбук оптимизации стоимости.

7

Metadata Management, Catalog & LineageУправление метаданными, каталог & Lineage

Metadata management & the data catalogУправление метаданными & каталог данных

Metadata = data about the data: schemas, owners, descriptions, freshness, quality scores, classifications (PII/sensitivity), usage. A data catalog is the searchable inventory of all that — so people can find, trust, and understand data without asking the original engineer.

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

Metadata typeExamples
TechnicalSchema, types, partitions, row counts, location
OperationalLast run, freshness, job status, SLA
BusinessDefinitions, owner, glossary terms, certification
GovernancePII tags, access policies, retention, classification
Тип метаданныхПримеры
ТехническиеСхема, типы, партиции, число строк, расположение
ОперационныеПоследний запуск, свежесть, статус задачи, SLA
БизнесовыеОпределения, владелец, термины глоссария, сертификация
GovernanceТеги PII, политики доступа, хранение, классификация

Tools: dbt docs (descriptions + auto DAG), Dataplex/Data Catalog, Snowflake's metadata views + Horizon, DataHub, OpenMetadata, Collibra, Purview.

Инструменты: dbt docs (описания + авто-DAG), Dataplex/Data Catalog, Snowflake metadata views + Horizon, DataHub, OpenMetadata, Collibra, Purview.

Data lineage — technical vs businessData lineage — технический vs бизнесовый

 bls_raw.cpi ─┐
              ├─► stg_cpi ─► int_cpi_seasonal ─► fct_cpi_monthly ─► dashboard / API / client export
 fred.weights─┘                                         │
                                                        └─► alert: if this breaks, ALL downstream is impacted
      
 bls_raw.cpi ─┐
              ├─► stg_cpi ─► int_cpi_seasonal ─► fct_cpi_monthly ─► dashboard / API / клиентский экспорт
 fred.weights─┘                                         │
                                                        └─► алерт: если это сломается, ВСЕ downstream затронуты
      
Technical lineageBusiness lineage
GranularityTable/column-level, system-derivedConcept/report-level, human-readable
Answers"Which columns feed this field?""Which business reports use CPI?"
SourceParsed from SQL/dbt/queriesCurated + glossary mapping
Primary userEngineersAnalysts, governance, stakeholders
Технический lineageБизнесовый lineage
ГранулярностьУровень таблицы/колонки, выводится системойУровень концепта/отчёта, читаемый человеком
Отвечает на«Какие колонки питают это поле?»«Какие бизнес-отчёты используют CPI?»
ИсточникПарсится из SQL/dbt/запросовКураторский + маппинг глоссария
Основной пользовательИнженерыАналитики, governance, стейкхолдеры

Why lineage matters

Почему lineage важен

  • Impact analysis — before changing a model, see every downstream table/dashboard/consumer that breaks. (dbt: dbt ls --select fct_cpi_monthly+.)
  • Root-cause — when a number looks wrong, walk lineage upstream to find the bad source/transform.
  • Governance & compliance — prove provenance of a published figure; trace PII propagation; audit "where did this number come from".
  • Trust — column-level lineage + tests + freshness = a data product clients can rely on.
  • Анализ влияния — перед изменением модели увидеть каждую downstream-таблицу/дашборд/потребителя, которые сломаются. (dbt: dbt ls --select fct_cpi_monthly+.)
  • Root-cause — когда число выглядит неправильно, пройти lineage upstream, чтобы найти плохой source/transform.
  • Governance & compliance — доказать происхождение опубликованной цифры; проследить распространение PII; аудит «откуда взялось это число».
  • Доверие — lineage на уровне колонок + тесты + свежесть = дата-продукт, на который клиенты могут положиться.
My storyМоя история

dbt gives column-level lineage for free from the model graph, and my code-review standard required descriptions + tests on every new model — so the catalog/lineage stayed accurate as a side-effect of how we shipped, not as a separate documentation chore.

dbt даёт column-level lineage бесплатно из графа модели, а мой стандарт code-review требовал описания + тесты на каждой новой модели — поэтому каталог/lineage оставались точными как побочный эффект того, как мы выкатывали, а не как отдельная обязанность по документации.

Interviewer will probeО чём спросит интервьюер

"A client reports a wrong CPI value — walk me through it." → Lineage upstream from fct_cpi_monthly to find which source/transform; check freshness + DQ test history at each hop; reproduce with time-travel/snapshot for the published point-in-time; fix + add a regression test; impact-analyse downstream via lineage to notify affected consumers.

«Клиент сообщает о неправильном значении CPI — пройди меня через это.» → Lineage upstream от fct_cpi_monthly, чтобы найти какой source/transform; проверить freshness + DQ test history на каждом хопе; воспроизвести с time-travel/snapshot для опубликованного момента времени; пофиксить + добавить регрессионный тест; провести impact-анализ downstream через lineage, чтобы уведомить затронутых потребителей.

8

Cost & Performance in Cloud WarehousesСтоимость & производительность в облачных хранилищах

BigQuery (pay per scan)

BigQuery (плата за сканирование)

  • Partition on date (e.g. period) → prune scans.
  • Cluster on common filter cols (market, series).
  • Avoid SELECT *; select only needed columns (columnar = scan = $).
  • Materialize heavy repeated subqueries; use incremental models.
  • Set bytes-billed limits + cost alerts; flat-rate slots for predictable load.
  • Партиционировать по дате (например period) → прунинг сканов.
  • Кластеризовать по частым фильтр-колонкам (рынок, серия).
  • Избегать SELECT *; выбирать только нужные колонки (колоночное = скан = $).
  • Материализовать тяжёлые повторяющиеся подзапросы; использовать инкрементальные модели.
  • Ставить лимиты bytes-billed + алерты стоимости; flat-rate slots для предсказуемой нагрузки.

Snowflake (pay per warehouse uptime)

Snowflake (плата за uptime warehouse)

  • Right-size warehouses; bigger ≠ always cheaper, but faster can be.
  • auto_suspend (e.g. 60s) + auto_resume.
  • Multi-cluster only for concurrency, not single big jobs.
  • Use result cache + clustering keys on big tables.
  • Zero-copy clone for dev/CI = no storage cost.
  • Right-size warehouses; больше ≠ всегда дешевле, но быстрее может быть.
  • auto_suspend (например 60s) + auto_resume.
  • Multi-cluster только для конкуренции, не для одной большой задачи.
  • Использовать result cache + clustering keys на больших таблицах.
  • Zero-copy clone для dev/CI = нет стоимости хранения.

Universal levers

Универсальные рычаги

  • Incremental models (dbt incremental) — only process new/changed rows, not full refresh.
  • Slim CI — only build changed + downstream models.
  • Tag & attribute compute by team/pipeline for showback/chargeback.
  • Monitor query/warehouse cost dashboards; kill runaway queries.
  • Инкрементальные модели (dbt incremental) — обрабатывать только новые/изменённые строки, не full refresh.
  • Slim CI — строить только изменённые + downstream модели.
  • Тегировать & атрибутировать compute по команде/пайплайну для showback/chargeback.
  • Мониторить дашборды стоимости запросов/warehouse; убивать убегающие запросы.
Interviewer will probeО чём спросит интервьюер

"How would you cut warehouse cost without hurting freshness?" → Profile the most expensive queries; switch full-refresh models to incremental; tighten auto_suspend; right-size the warehouse to the workload; move dev/CI to zero-copy clones on a small warehouse; partition/cluster the hot tables. Measure before/after in the cost dashboard.

«Как бы ты сократил стоимость warehouse, не навредив свежести?» → Профилировать самые дорогие запросы; переключить full-refresh модели на инкрементальные; ужесточить auto_suspend; right-size warehouse под workload; перенести dev/CI на zero-copy clone-ы на маленьком warehouse; партиционировать/кластеризовать горячие таблицы. Измерить до/после в дашборде стоимости.

GotchaПодводный камень

Incremental models drift: a bug in the incremental logic silently accumulates. Schedule periodic full-refresh reconciliation and a row-count/sum reconciliation test to catch silent divergence.

Инкрементальные модели дрейфуют: баг в инкрементальной логике тихо накапливается. Планировать периодическую full-refresh сверку и тест сверки row-count/sum, чтобы ловить тихое расхождение.

9

Environment Promotion & Secrets ManagementПромоушен окружений & управление секретами

Promotion pathПуть промоушена

 commit ─► PR (CI: lint+tests on dev/CI clone) ─► merge ─► STAGE (full run+tests)
        ─► manual/auto gate (green only) ─► PROD (blue/green swap, monitored, rollback-ready)
      
 commit ─► PR (CI: lint+tests на dev/CI clone) ─► merge ─► STAGE (full run+tests)
        ─► ручной/авто-гейт (только зелёный) ─► PROD (blue/green swap, мониторится, готов к откату)
      
  • Same code, different targets: dbt targets / Airflow connections swap the schema/warehouse/project per env — no code forks.
  • Promotion = moving the artifact (manifest/image/DAG), never re-writing logic per env.
  • Gate on green: a promotion can only happen if the prior stage's tests passed.
  • Immutable artifacts: prod runs the exact image/manifest that passed stage.
  • Тот же код, разные таргеты: dbt targets / Airflow connections меняют схему/warehouse/проект на окружение — никаких форков кода.
  • Промоушен = перемещение артефакта (manifest/image/DAG), никогда не переписывать логику под окружение.
  • Гейт на зелёном: промоушен возможен только если тесты предыдущего stage прошли.
  • Неизменяемые артефакты: прод запускает точный image/manifest, прошедший stage.

Secrets managementУправление секретами

  • Never in git or code. Use a secrets manager: GCP Secret Manager, AWS Secrets Manager, Azure Key Vault, Vault.
  • Inject at runtime as env vars / mounted secrets / Airflow connections+variables (backed by a secrets backend).
  • Least privilege service accounts per env; prod creds never reachable from dev.
  • Rotation + audit logging; prefer short-lived/federated identity (workload identity, OIDC) over long-lived keys.
  • Secret scanning in CI (pre-commit / detect-secrets) to block accidental commits.
  • Никогда в git или коде. Использовать менеджер секретов: GCP Secret Manager, AWS Secrets Manager, Azure Key Vault, Vault.
  • Инжектить во время выполнения как env vars / mounted secrets / Airflow connections+variables (backed секрет-бэкендом).
  • Least privilege сервисные аккаунты на окружение; прод-креды никогда не достижимы из dev.
  • Ротация + audit logging; предпочитать short-lived/federated identity (workload identity, OIDC) вместо long-lived ключей.
  • Сканирование секретов в CI (pre-commit / detect-secrets) для блокировки случайных коммитов.
# dbt profiles use env vars, not literals
prod:
  type: snowflake
  account: "{{ env_var('SF_ACCOUNT') }}"
  user:    "{{ env_var('SF_USER') }}"
  password: "{{ env_var('SF_PASSWORD') }}"   # injected from Secret Manager at runtime
My storyМоя история

Across IU Group's Azure OpenAI work and the GCP/Snowflake stacks, the same rule held: credentials lived in the cloud secret store, were injected at runtime by service identity, and CI failed on any committed secret. Promotion moved code; secrets stayed bound to the environment.

Через работу IU Group с Azure OpenAI и GCP/Snowflake-стеки действовало одно правило: credentials жили в облачном хранилище секретов, инжектились во время выполнения сервисной идентичностью, и CI фейлился на любом закоммиченном секрете. Промоушен перемещал код; секреты оставались привязаны к окружению.

Interviewer will probeО чём спросит интервьюер

"How do you stop a dev job from touching prod data?" → Separate service accounts/roles per env with least privilege; prod credentials only in the prod secret store; env-scoped connections in Airflow; network/role isolation so dev identity literally cannot authenticate to prod.

«Как остановить dev-задачу от касания прод-данных?» → Отдельные сервисные аккаунты/роли на окружение с least privilege; прод-креды только в прод-хранилище секретов; env-scoped connections в Airflow; сетевая/ролевая изоляция, чтобы dev-идентичность буквально не могла аутентифицироваться в прод.

Self-Quiz — Flip to RevealСамопроверка — Нажми чтобы открыть

Tap any card to reveal the answer.

Нажми на любую карточку, чтобы открыть ответ.

Q1 · DataOpsВ1 · DataOps
How is testing data fundamentally different from testing code?Чем тестирование данных фундаментально отличается от тестирования кода?
tap to flipнажми чтобы перевернуть
Code tests are deterministic given input — the data is fixed, you assert exact output. Data tests assert on values you don't control: the data is the variable. So you test properties (not-null, unique, ranges, referential integrity, freshness, row-count deltas, reconciliation), not exact equality. Failure mode is silent-wrong-numbers, not a crash. Тесты кода детерминированы при заданном вводе — данные фиксированы, ты проверяешь точный вывод. Тесты данных проверяют значения, которые ты не контролируешь: данные — переменная. Поэтому ты тестируешь свойства (not-null, unique, диапазоны, референциальная целостность, свежесть, дельты числа строк, сверка), а не точное равенство. Режим сбоя — тихие неправильные цифры, а не падение.
Q2 · CI/CDВ2 · CI/CD
What is "slim CI" in dbt and why use it?Что такое «slim CI» в dbt и зачем его использовать?
tap to flipнажми чтобы перевернуть
Using the previous manifest.json as state to build/test only changed models + their downstream (--select state:modified+). Gives fast PR feedback and low compute cost instead of rebuilding the whole project on every commit. Full-volume suites move to stage/nightly. Использование предыдущего manifest.json как состояния для сборки/тестирования только изменённых моделей + их downstream (--select state:modified+). Даёт быструю обратную связь на PR и низкую стоимость вычислений вместо пересборки всего проекта на каждом коммите. Полнообъёмные наборы переходят на stage/ночные запуски.
Q3 · DeploymentВ3 · Деплой
How do you do blue/green when the artifact is a queried table?Как делать blue/green, когда артефакт — запрашиваемая таблица?
tap to flipнажми чтобы перевернуть
Build the new version into a parallel table (table_v2), validate with DQ tests, then atomically repoint the consumer abstraction — swap the view/alias or RENAME — so consumers never see a partial state. Old version stays for instant rollback. Snowflake zero-copy clone makes the green copy effectively free. Построить новую версию в параллельную таблицу (table_v2), валидировать DQ-тестами, затем атомарно переточить абстракцию потребителя — поменять view/alias или RENAME — чтобы потребители никогда не видели частичное состояние. Старая версия остаётся для мгновенного отката. Snowflake zero-copy clone делает зелёную копию эффективно бесплатной.
Q4 · CostВ4 · Стоимость
BigQuery vs Snowflake — what's the cost lever in each?BigQuery vs Snowflake — в чём рычаг стоимости в каждом?
tap to flipнажми чтобы перевернуть
BigQuery bills per bytes scanned → partition + cluster + select-only-needed-columns + incremental models to scan less. Snowflake bills per warehouse uptime → right-size warehouses + aggressive auto_suspend + zero-copy clones for dev/CI. Same dbt models, different optimisation playbook — the core of my GCP→Snowflake migration. BigQuery билит за сканируемые байты → партиционировать + кластеризовать + выбирать-только-нужные-колонки + инкрементальные модели, чтобы сканировать меньше. Snowflake билит за uptime warehouse → right-size warehouses + агрессивный auto_suspend + zero-copy clone-ы для dev/CI. Те же dbt-модели, разный плейбук оптимизации — ядро моей миграции GCP→Snowflake.
Q5 · LineageВ5 · Lineage
Why does lineage matter, and what are the two kinds?Почему lineage важен, и какие два вида?
tap to flipнажми чтобы перевернуть
Technical lineage (table/column-level, parsed from SQL/dbt) for engineers; business lineage (concept/report-level, curated) for analysts & governance. It powers impact analysis (what breaks if I change this), root-cause (walk upstream to the bad source), compliance/provenance, and trust. Технический lineage (уровень таблицы/колонки, парсится из SQL/dbt) для инженеров; бизнесовый lineage (уровень концепта/отчёта, кураторский) для аналитиков & governance. Он питает анализ влияния (что сломается, если я изменю это), root-cause (пройти upstream к плохому source), compliance/происхождение и доверие.
Q6 · SecretsВ6 · Секреты
Where do secrets live and how do they reach a job?Где живут секреты и как они достигают задачи?
tap to flipнажми чтобы перевернуть
In a secrets manager (Secret Manager / Key Vault / Vault), never in git or code. Injected at runtime via env vars / Airflow connections / mounted secrets, scoped by least-privilege per-env service identity (prefer short-lived OIDC/workload identity over long-lived keys). CI runs secret scanning to block accidental commits. Promotion moves code; secrets stay bound to the env. В менеджере секретов (Secret Manager / Key Vault / Vault), никогда в git или коде. Инжектятся во время выполнения через env vars / Airflow connections / mounted secrets, с scope по least-privilege per-env сервисной идентичности (предпочитать short-lived OIDC/workload identity вместо long-lived ключей). CI запускает сканирование секретов для блокировки случайных коммитов. Промоушен перемещает код; секреты остаются привязаны к env.

30-second framing for the interview30-секундный фрейминг для интервью

"I think of DataOps as DevOps for data products: version control + CI/CD + automated testing + observability + a catalog/lineage layer, all enforced by the pipeline rather than by discipline. Concretely, at McMakler/Career.io I version-controlled every dbt model, ran lint + unit + data tests in CI (with slim CI and a DagBag gate for Airflow), promoted immutable artifacts dev→stage→prod, and used a code-review standard I authored to keep tests, contracts and lineage accurate as a side-effect of shipping. On the platform side I migrated transforms GCP/BigQuery→Snowflake and re-tuned the cost model from bytes-scanned to warehouse-uptime."

«Я думаю о DataOps как о DevOps для дата-продуктов: контроль версий + CI/CD + автоматизированное тестирование + наблюдаемость + слой каталога/lineage, всё обеспечиваемое пайплайном, а не дисциплиной. Конкретно, в McMakler/Career.io я держал каждую dbt-модель под контролем версий, запускал lint + unit + data tests в CI (с slim CI и DagBag-гейтом для Airflow), промоутил неизменяемые артефакты dev→stage→prod и использовал стандарт code-review, который я написал, чтобы тесты, контракты и lineage оставались точными как побочный эффект выката. Со стороны платформы я мигрировал трансформы GCP/BigQuery→Snowflake и перенастроил модель стоимости с bytes-scanned на warehouse-uptime.»