Ozonсобеседованиеаналитика данныхмаркетплейсSQLClickHouseGMVкарьера

Вопросы собеса в Ozon на аналитика 2026: 25+ реальных + разбор

2026-06-04 25 мин

Ozon — самый ClickHouse-heavy собес среди РФ-компаний. Если в Яндексе спрашивают «как ты бы оптимизировал PostgreSQL», в Ozon — «напиши efficient ClickHouse query с partition pruning». В этом гайде разберу 25+ реальных вопросов с 5 раундов собеса аналитика Ozon (Marketplace / Search / Fintech / Logistics) — с разбором сильного и слабого ответа.

Главное про Ozon
Ozon глубоко проверяет **product sense маркетплейса**: GMV decomposition, take rate, seller cohorts, search ranking. Технический стэк ClickHouse + Airflow + dbt. Готовься на маркетплейс-метрики, не общую аналитику.

Грейды аналитика в Ozon (2026)

ГрейдCompensation/мес РФОпытЧто спрашивают
Junior150-220K ₽0-1 годSQL базовый, Python pandas, простые продуктовые кейсы
Middle220-330K ₽1-3 годаClickHouse advanced, A/B-тесты, маркетплейс-метрики
Senior330-500K ₽3-6 летАрхитектура аналитики, ML-driven analytics, search/recsys
Lead500-700K+ ₽6+ летМногокомандные проекты, продуктовая стратегия, mentorship

5 раундов собеса в Ozon

РаундЧтоДлительность
1. HR-скринингМотивация, ожидания, продуктовый домен30 мин
2. SQL live (ClickHouse)2-3 задачи с фокусом на performance60 мин
3. Python + статистикаpandas, A/B-тесты, маркетплейс-кейсы60 мин
4. Продуктовый кейс«GMV упал, что делаешь» / search ranking60 мин
5. Финал с лидомBehavioral + system design45 мин

→ Полный гайд: 150+ вопросов собеса аналитика

8 SQL-вопросов с собеса Ozon (раунд 2, ClickHouse)

У тебя таблица orders в ClickHouse 5B строк. Найди топ-100 продавцов по GMV за последний месяц.

✅ Сильный ответ:

SELECT seller_id, sum(gmv) AS total_gmv
FROM orders
WHERE order_date >= today() - INTERVAL 30 DAY
GROUP BY seller_id
ORDER BY total_gmv DESC
LIMIT 100;

Senior follow-up уточнения:

→ ClickHouse практический гайд

Объясни AggregatingMergeTree и зачем он нужен.

✅ Сильный ответ:

«AggregatingMergeTree — engine который хранит intermediate aggregation states вместо raw rows.

Идея: вместо суммирования миллиардов строк на runtime, ClickHouse сохраняет state (например \sumState\, \uniqState\) и мёржит states в фоне.

Use case: dashboard «GMV по дням» на 5B rows. Без AMT — каждый запрос 30 сек. С AMT через materialized view → 50ms.

\\\sql

CREATE MATERIALIZED VIEW daily_gmv_mv

ENGINE = AggregatingMergeTree()

ORDER BY day

AS SELECT

toDate(order_date) AS day,

sumState(gmv) AS gmv_state,

uniqState(user_id) AS unique_users_state

FROM orders

GROUP BY day;

-- query

SELECT day, sumMerge(gmv_state), uniqMerge(unique_users_state)

FROM daily_gmv_mv

GROUP BY day;

\\\»

→ ClickHouse MV + Projections deep dive

Что такое skip index в ClickHouse и когда нужен?

✅ Сильный ответ:

«Skip index — secondary index для фильтрации внутри parts. Не для точечного поиска (для этого primary key/ORDER BY), а для пропуска granules где данных нет.

Типы:

Когда: WHERE на колонке которая НЕ в ORDER BY, но фильтр часто используется. Без skip index ClickHouse читает все granules; со skip index — пропускает 80-95% без чтения.»

Денормализация vs JOIN в ClickHouse — что выбираешь?

✅ Сильный ответ:

«ClickHouse оптимизирован под wide tables (денормализация), не под JOINs.

Денормализация (предпочтительно):

JOIN (когда нужно):

В Ozon обычно: orders денормализуется с user/seller/product info; dim-таблицы (categories, regions) через Dictionary.»

У тебя query медленный. Как профилируешь?

✅ Сильный ответ:

«Шаг 1: EXPLAIN PIPELINE — видишь stages, кто bottleneck (read / aggregation / sort).

Шаг 2: system.query_log — статистика по предыдущим прогонам (read_rows, read_bytes, memory_usage).

Шаг 3: system.parts — сколько parts читается, partition pruning работает?

Шаг 4: Если read_rows >> ожидаемого → проверь ORDER BY, добавь partition/skip index.

Шаг 5: Если memory_usage >> RAM → переписывай query (groupArrayDistinct → uniq, JOIN → IN, etc.).

Trick: \SET allow_introspection_functions = 1\ + \system.trace_log\ даёт flame graph выполнения.»

→ EXPLAIN ANALYZE PostgreSQL — как читать

Что такое projection в ClickHouse?

✅ Сильный ответ:

«Projection = column-store «индекс»: альтернативный ORDER BY/aggregation для той же таблицы. ClickHouse автоматически выбирает projection если query подходит.

\\\sql

ALTER TABLE orders ADD PROJECTION by_seller

(SELECT seller_id, sum(gmv), count() GROUP BY seller_id);

ALTER TABLE orders MATERIALIZE PROJECTION by_seller;

\\\

После этого \SELECT seller_id, sum(gmv) FROM orders GROUP BY seller_id\ — ClickHouse читает projection, не оригинальную таблицу.

Plus: transparent для query (не нужно менять SQL).

Minus: удваивает storage. Не для всех queries (только подмножество aggregation patterns).»

Self-join: топ-3 категории по GMV для каждой страны.

✅ Сильный ответ (Window function — даже в ClickHouse предпочтительнее):

\\\sql

WITH ranked AS (

SELECT country, category, sum(gmv) AS gmv,

row_number() OVER (PARTITION BY country ORDER BY sum(gmv) DESC) AS rn

FROM orders

GROUP BY country, category

)

SELECT country, category, gmv

FROM ranked

WHERE rn <= 3;

\\\

Уточнения:

→ Window functions deep dive

SAMPLE и approximate queries — когда использовать?

✅ Сильный ответ:

«ClickHouse поддерживает \SAMPLE\ для приближённых результатов на больших данных:

\\\sql

SELECT seller_id, sum(gmv) * 10 AS gmv_estimated -- умножение на 1/SAMPLE

FROM orders SAMPLE 0.1

WHERE order_date >= today() - 7

GROUP BY seller_id;

\\\

Use cases:

Не use cases:

5 Python-вопросов в Ozon (раунд 3)

У тебя CSV 30M строк продаж. Посчитай retention по дням signup.

✅ Сильный ответ:

\\\python

import pandas as pd

# Chunk-by-chunk если RAM ограничен

chunks = pd.read_csv('orders.csv', chunksize=500_000, parse_dates=['order_date'])

user_signup = {}

user_active_days = {}

for chunk in chunks:

grouped = chunk.groupby('user_id')['order_date']

for user, dates in grouped:

if user not in user_signup:

user_signup[user] = dates.min()

user_active_days.setdefault(user, set()).update(dates.dt.date)

# Retention per signup cohort

import datetime

cohort_retention = {}

for user, signup in user_signup.items():

cohort = signup.strftime('%Y-%m')

actives = user_active_days[user]

day_30 = signup.date() + datetime.timedelta(days=30)

cohort_retention.setdefault(cohort, {'total': 0, 'retained': 0})

cohort_retention[cohort]['total'] += 1

if day_30 in actives:

cohort_retention[cohort]['retained'] += 1

\\\

Senior follow-up: «Для production — лучше DuckDB или Polars, pandas+chunksize медленный. Или сразу в ClickHouse через materialized view.»

→ Polars vs Pandas

Реализуй ABC-анализ топ-N продуктов в pandas.

✅ Сильный ответ:

\\\python

import pandas as pd

# Аггрегация по продукту

prod_gmv = (df.groupby('product_id')['gmv'].sum()

.sort_values(ascending=False)

.reset_index())

# Кумулятивная доля

prod_gmv['cum_share'] = prod_gmv['gmv'].cumsum() / prod_gmv['gmv'].sum()

# ABC-классификация

def abc_class(share):

if share <= 0.80: return 'A' # топ 80% revenue

elif share <= 0.95: return 'B' # следующие 15%

else: return 'C' # хвост 5%

prod_gmv['abc'] = prod_gmv['cum_share'].apply(abc_class)

\\\

Senior follow-up: «Что если 20 продуктов = 90% GMV? Тогда классическая схема 80/15/5 не работает. Адаптируй пороги под business reality, или используй log-Lorenz curve.»

Сделай pivot: продажи по странам × категориям, проценты от total.

✅ Сильный ответ:

\\\python

pivot = df.pivot_table(index='country', columns='category',

values='gmv', aggfunc='sum', fill_value=0)

pivot_pct = pivot.div(pivot.values.sum()) * 100

print(pivot_pct.round(2))

\\\

Senior уточнение: «pivot.div() — что если хочешь % от строки/столбца? \pivot.div(pivot.sum(axis=1), axis=0)\ для row %, \axis=1\ для column %.»

Sessionization: события user_id с timestamp, объединить в сессии если перерыв < 30 минут.

✅ Сильный ответ:

\\\python

df = df.sort_values(['user_id', 'ts'])

df['prev_ts'] = df.groupby('user_id')['ts'].shift()

df['gap_min'] = (df['ts'] - df['prev_ts']).dt.total_seconds() / 60

df['new_session'] = (df['gap_min'].isna()) | (df['gap_min'] > 30)

df['session_id'] = df.groupby('user_id')['new_session'].cumsum()

\\\

Объяснение:

→ Sessionization в SQL

Memory optimization pandas — у тебя DataFrame 8GB, RAM 16GB.

✅ Сильный ответ:

«Шаг 1: проверить current usage: \df.info(memory_usage='deep')\

Шаг 2: downcast числовых типов:

\\\python

df['user_id'] = pd.to_numeric(df['user_id'], downcast='unsigned') # uint32 if max < 4B

df['gmv'] = pd.to_numeric(df['gmv'], downcast='float') # float32

\\\

Шаг 3: category для low-cardinality strings: \df['country'] = df['country'].astype('category')\ → может убрать 90% memory.

Шаг 4: select только нужные columns при загрузке: \pd.read_csv(usecols=[...])\

Шаг 5: если ничего не помогает → DuckDB / Polars / chunksize.»

5 A/B-тестов вопросов в Ozon (раунд 3 продолжение)

Search ranking A/B: как измеришь успех нового алгоритма?

✅ Сильный ответ:

«Метрики ranking-A/B (по приоритету):

Primary metric — Conversion Rate (CR от показа в search до покупки)

Secondary metrics:

Guardrail metrics:

Дизайн: 50/50 split по user_id, минимум 4 недели для стабильности, sample size — рассчитывается по MDE на CR.»

Каннибализация: запустили promoted listings, продажи органики упали — как измеришь чистый эффект?

✅ Сильный ответ:

«Это classic cannibalization проблема. Чистый эффект:

Подход 1: Geo/Time DiD

Подход 2: User-level A/B

Подход 3: Synthetic control

В Ozon обычно используют user-level A/B как основной метод.»

→ Caused inference + DiD методы (v25.7)

Marketplace metric: take rate упал на 1.2%. Что проверяешь?

✅ Сильный ответ:

«Take rate = Платформа-комиссия / GMV. Падение может быть от:

1. Mix shift к категориям с низкой комиссией

2. Изменение фричайл прайсинга / промо

3. Seller mix: новые крупные sellers получают лучшие условия

4. Технический баг — что-то с подсчётом изменилось

Action: декомпозировать take rate по category × seller_cohort × month, найти аномальный bucket.»

Sequential testing — что это, когда нужно?

✅ Сильный ответ:

«Sequential testing = методология которая позволяет «подглядывать» в результаты A/B без накопления Type I error.

Стандартный A/B: фиксированный sample size, peeking запрещён. Sequential: можно смотреть в любой момент, с правильной коррекцией.

Методы:

Когда нужно:

В Ozon — sequential на тестах что меняют core flow (checkout, search ranking).»

Что такое pre-experiment power analysis и зачем?

✅ Сильный ответ:

«Power analysis — расчёт необходимого sample size до запуска теста.

Формула: \n = (z_α/2 + z_β)² × 2σ² / MDE²\

Зачем:

В Ozon стандарт: каждое A/B имеет pre-experiment power analysis в design doc.»

→ Sample size калькулятор

5 продуктовых вопросов (раунд 4)

GMV маркетплейса упал на 8% за неделю. Что делаешь?

✅ Сильный ответ (фреймворк декомпозиции):

«Декомпозиция GMV:

GMV = #buyers × orders_per_buyer × AOV

Каждый компонент:

Action plan:

Bonus: проверь bot-traffic, может GMV не упал, а bots ушли (хотя bots не делают покупки обычно)»

NSM для маркетплейса — какую метрику предложишь?

✅ Сильный ответ:

«NSM (North Star Metric) должна:

Кандидаты для маркетплейса:

GMV — надуваем разовыми крупными покупками, скидками

DAU — можно нагнать ботами

Revenue — может расти за счёт margin compression

Active buyers per quarter — учитывает retention, не надувается ботами

Successful transactions per active buyer — combines engagement + monetization

✅ \GMV per active buyer\ (с фильтром на legitimate users)

Guardrails: margin%, NPS, time to delivery, search success rate.

В Ozon публично говорят про active buyers + GMV per buyer как key metrics quarterly review.»

Аналитика search ranking: какие метрики покажешь PM?

✅ Сильный ответ:

«Top-of-funnel:

Mid-funnel:

Bottom-of-funnel:

Quality signals:

Senior follow-up: «Какая главная? — Search-to-purchase rate как primary, остальные diagnostic.»

Recommendation engine упал по conversion. С чего начнёшь анализ?

✅ Сильный ответ:

«Структура анализа:

1. Sanity check данных:

2. Декомпозиция по surface:

3. По сегментам:

4. Model-side:

5. Action:

У нас Take Rate 8%, конкурент A 12%. Можем поднять? Как анализируешь?

✅ Сильный ответ:

«Не сразу повышай — анализируй elasticity:

1. Sellers' tolerance:

2. Customer impact:

3. Конкуренция:

4. Pilot:

5. Decision:

2 behavioral вопроса (раунд 5)

Расскажи случай когда защитил аналитическую рекомендацию против бизнес-стейкхолдера.

✅ Сильный ответ (STAR):

«Ситуация: PM маркетинга хотел запустить промо +30% к скидке на категорию X на 1 месяц, мотивация «нагоним GMV».

Задача: убедить что промо без guardrail metrics убьёт LTV категории.

Действие:

Результат: PM согласился на guardrail-версию. Промо запустилось, retention остался стабильным, GMV +12%. Сохранили долгосрочный LTV.»

→ Behavioral interview + STAR

Опиши случай когда твоё A/B провалилось — что вынес?

✅ Сильный ответ:

«Ситуация: запустили A/B нового recommendation алгоритма на product page. Hypothesis: ML-based recs дадут +5% к add-to-cart.

Действие: запустил 50/50 split на 6 недель, sample size = 2M юзеров (по power analysis на MDE 2%).

Результат: treatment effect -1.2% к add-to-cart, p-value 0.04. Recommendation: НЕ катить.

Learning:

Главный learning: оптимизировать на правильную downstream метрику с самого начала, не на proxy.»

Red flags на собесе Ozon (не делай)

Как готовиться к Ozon

Месяц 1: ClickHouse + маркетплейс-метрики

Месяц 2: продуктовые кейсы

Неделя до собеса: behavioral + моки

→ 30-дневный план подготовки к собесу

FAQ

Чем собес в Ozon отличается от Yandex?

Ozon глубже копает в маркетплейс-метрики (GMV decomposition, take rate, seller cohorts). Yandex глубже в технических деталях (CUPED, sequential testing, performance optimization). Готовь оба + специфику бизнес-домена.

ClickHouse — мастхэв для Ozon?

Да, для middle+. Junior могут пройти на базовом SQL, но middle+ обязан знать ClickHouse оптимизацию (partitioning, MV, projections). Без этого даже не зовут на тех раунд.

Есть ли в Ozon Python-тяжелые задачи?

Меньше чем в Яндексе. Pandas базовый достаточно. Senior знает Polars/DuckDB как альтернативу. Сложных алгоритмов не спрашивают.

Сколько раундов?

4-5 раундов, 6-8 часов суммарно растянутые на 2-3 недели.

Возможен ли pre-screening test перед собесом?

Да, часто. Кейс на SQL+анализ за 4-8 часов home work. Высылают результат + ревью на live.

Кто проводит финальный раунд?

Hiring manager + team lead. Focus на behavioral + system thinking. Для senior+ может быть VP.

Какие компании в Ozon самые конкурентные?

Ozon Marketplace (core business, самый высокий bar) и Ozon Fintech (банк, регуляторика). Ozon Travel и Ozon Pharma — менее жёсткие.

Что дальше

Сравнить Free и Pro → (1999 ₽/мес — безлимит мок-собесов)

Источники

Тренируй SQL/Python на 521+532 задачах
Тренажёр с авто-проверкой кода в браузере + 453 кейсов под маркетплейс. AI мок-собес как в Ozon. Первые 5 задач бесплатно.
Открыть тренажёр →