Тестовое задание аналитика данных: 10 примеров с разбором

Зачем компании дают тестовые задания

Тестовое задание — этап отбора, на котором вас просят решить задачу, приближённую к реальной работе аналитика. Обычно его дают после HR-скрининга, но до технического собеседования.

Что проверяют:

  • Умение работать с данными (SQL, Python, Excel)
  • Понимание метрик и бизнес-логики
  • Способность делать выводы и оформлять результаты
  • Внимание к деталям и качество кода

Формат: CSV-файл или доступ к базе + 3–7 вопросов. Срок — от 2 часов до 3 дней.


Задание 1. Анализ воронки регистрации

Условие. Дан CSV с событиями регистрации: user_id, step (landing / signup_form / email_confirm / onboarding_complete), timestamp. Рассчитайте конверсию между шагами и найдите, где теряется больше всего пользователей.

Как решать:

  1. Посчитайте уникальных пользователей на каждом шаге
  2. Рассчитайте конверсию: шаг N → шаг N+1
  3. Визуализируйте воронку
  4. Сформулируйте гипотезы, почему происходит потеря
SELECT
  step,
  COUNT(DISTINCT user_id) AS users,
  ROUND(
    100.0 * COUNT(DISTINCT user_id) /
    FIRST_VALUE(COUNT(DISTINCT user_id)) OVER (ORDER BY
      CASE step
        WHEN 'landing' THEN 1
        WHEN 'signup_form' THEN 2
        WHEN 'email_confirm' THEN 3
        WHEN 'onboarding_complete' THEN 4
      END
    ),
    1
  ) AS pct_of_total
FROM events
GROUP BY step;

На что смотрит проверяющий: не только цифры, но и выводы. «Конверсия email_confirm → onboarding_complete = 45%» — слабо. «45% пользователей бросают после подтверждения почты, возможная причина — сложный онбординг, рекомендую A/B-тест упрощённого варианта» — сильно.

Подробнее о воронках: воронка конверсии.


Задание 2. Расчёт Retention

Условие. Таблица user_activity (user_id, activity_date). Рассчитайте D1, D7, D30 retention по недельным когортам за последние 8 недель.

Как решать:

WITH first_visit AS (
  SELECT user_id, MIN(activity_date) AS cohort_date
  FROM user_activity
  GROUP BY user_id
),
cohorts AS (
  SELECT
    f.user_id,
    DATE_TRUNC('week', f.cohort_date) AS cohort_week,
    ua.activity_date - f.cohort_date AS day_n
  FROM first_visit f
  JOIN user_activity ua ON f.user_id = ua.user_id
)
SELECT
  cohort_week,
  COUNT(DISTINCT user_id) AS cohort_size,
  COUNT(DISTINCT user_id) FILTER (WHERE day_n = 1) AS d1,
  COUNT(DISTINCT user_id) FILTER (WHERE day_n = 7) AS d7,
  COUNT(DISTINCT user_id) FILTER (WHERE day_n = 30) AS d30
FROM cohorts
GROUP BY cohort_week
ORDER BY cohort_week;

На что смотрит проверяющий: правильное определение когорты (по первому визиту), корректный расчёт retention (именно на N-й день, а не «в течение N дней»), визуализация трендов.

Подробнее: как считать retention, когортный анализ.


Задание 3. Анализ A/B-теста

Условие. Провели A/B-тест нового дизайна карточки товара. Группа A (контроль) — 10 000 пользователей, группа B (тест) — 10 000. Конверсия в покупку: A = 3.2%, B = 3.5%. Является ли разница статистически значимой?

Как решать:

  1. Сформулируйте гипотезы: H0 — разницы нет, H1 — конверсия в B выше
  2. Рассчитайте z-статистику для пропорций
  3. Найдите p-value
  4. Сделайте вывод

Ключевой расчёт:

  • Pooled proportion: p = (320 + 350) / 20000 = 0.0335
  • SE = sqrt(p * (1-p) * (1/10000 + 1/10000)) = 0.00255
  • z = (0.035 - 0.032) / 0.00255 = 1.18
  • p-value = 0.119

Вывод: p-value > 0.05, разница статистически незначима. Нельзя утверждать, что новый дизайн лучше. Рекомендация: продолжить тест с большей выборкой или отказаться от изменения.

Подробнее: A/B-тестирование на собеседовании, p-value простыми словами.


Задание 4. Сегментация пользователей (RFM)

Условие. Таблица orders (user_id, order_date, amount). Постройте RFM-сегментацию: Recency (давность последнего заказа), Frequency (количество заказов), Monetary (общая сумма). Определите самые ценные сегменты.

Как решать:

WITH rfm AS (
  SELECT
    user_id,
    CURRENT_DATE - MAX(order_date) AS recency_days,
    COUNT(*) AS frequency,
    SUM(amount) AS monetary
  FROM orders
  GROUP BY user_id
),
scored AS (
  SELECT *,
    NTILE(5) OVER (ORDER BY recency_days ASC) AS r_score,
    NTILE(5) OVER (ORDER BY frequency DESC) AS f_score,
    NTILE(5) OVER (ORDER BY monetary DESC) AS m_score
  FROM rfm
)
SELECT
  r_score, f_score, m_score,
  COUNT(*) AS users,
  ROUND(AVG(monetary), 0) AS avg_revenue
FROM scored
GROUP BY r_score, f_score, m_score
ORDER BY avg_revenue DESC;

На что смотрит проверяющий: выбор квантилей, интерпретация сегментов («чемпионы» — высокий RFM, «спящие» — низкий R, высокий FM), рекомендации по работе с каждым сегментом.


Задание 5. Кейс «метрика упала»

Условие. DAU приложения упал на 15% за последнюю неделю. Проведите анализ: найдите причину и предложите действия.

Как решать:

  1. Декомпозиция: DAU = новые + вернувшиеся. Какой сегмент упал?
  2. Срезы: платформа (iOS/Android), страна, источник трафика, версия приложения
  3. Внешние факторы: сезонность, праздники, технический сбой, обновление приложения
  4. SQL для анализа:
SELECT
  activity_date,
  platform,
  COUNT(DISTINCT user_id) AS dau,
  COUNT(DISTINCT user_id) FILTER (
    WHERE first_seen = activity_date
  ) AS new_users
FROM user_activity
WHERE activity_date >= CURRENT_DATE - 14
GROUP BY activity_date, platform
ORDER BY activity_date, platform;

На что смотрит проверяющий: структура мышления (не бросаетесь сразу в данные, а формулируете гипотезы), полнота анализа, конкретность рекомендаций.

Подробный разбор: кейс «метрика упала».


Задание 6. Анализ юнит-экономики

Условие. Рассчитайте LTV, CAC и Payback Period для подписочного сервиса. Данные: средний чек подписки 990 руб./мес., средний срок жизни клиента 8 месяцев, затраты на привлечение — 2 000 000 руб. на 500 клиентов.

Решение:

  • LTV = 990 * 8 = 7 920 руб.
  • CAC = 2 000 000 / 500 = 4 000 руб.
  • LTV/CAC = 1.98
  • Payback Period = CAC / ARPU = 4 000 / 990 = 4.04 месяца

Вывод: LTV/CAC < 3 — бизнес-модель работает, но с низким запасом. Рекомендации: увеличить retention (увеличит LTV) или снизить CAC за счёт органического трафика.

Подробнее: unit-экономика.


Задание 7. SQL: товары без повторных покупок

Условие. Найдите товары, которые покупают только один раз (нет повторных покупок того же товара тем же пользователем).

WITH purchase_counts AS (
  SELECT product_id, user_id, COUNT(*) AS purchases
  FROM order_items oi
  JOIN orders o ON oi.order_id = o.order_id
  GROUP BY product_id, user_id
)
SELECT
  p.product_id,
  p.name,
  COUNT(DISTINCT pc.user_id) AS buyers,
  AVG(pc.purchases) AS avg_purchases_per_user
FROM purchase_counts pc
JOIN products p ON pc.product_id = p.product_id
GROUP BY p.product_id, p.name
HAVING MAX(pc.purchases) = 1
ORDER BY buyers DESC;

На что смотрит проверяющий: правильность условия HAVING (MAX = 1, а не AVG = 1), понимание бизнес-контекста (почему такие товары важны).


Задание 8. Построение дашборда

Условие. Спроектируйте дашборд для менеджера e-commerce маркетплейса. Опишите: какие метрики включить, как визуализировать, с какой частотой обновлять.

Как решать:

Верхний блок — ключевые KPI:

  • GMV (Gross Merchandise Value) — числом + тренд за неделю
  • Количество заказов — числом + тренд
  • Средний чек — числом + тренд
  • Конверсия корзина→покупка — процент + тренд

Средний блок — динамика:

  • Линейный график GMV по дням (последние 30 дней)
  • Столбчатая диаграмма заказов по категориям
  • Воронка конверсии

Нижний блок — сегменты:

  • Топ-10 категорий по выручке
  • Распределение заказов по регионам
  • New vs Returning users

Обновление: ежедневно, данные за предыдущий день.

Подробнее: типы графиков для аналитика.


Задание 9. Анализ оттока (Churn)

Условие. Определите пользователей, которые «ушли» (не совершали действий более 30 дней). Рассчитайте churn rate по месяцам и найдите факторы, предсказывающие отток.

WITH last_activity AS (
  SELECT
    user_id,
    MAX(activity_date) AS last_date,
    MIN(activity_date) AS first_date,
    COUNT(DISTINCT activity_date) AS active_days
  FROM user_activity
  GROUP BY user_id
),
churned AS (
  SELECT *,
    CASE WHEN CURRENT_DATE - last_date > 30 THEN 1 ELSE 0 END AS is_churned
  FROM last_activity
)
SELECT
  DATE_TRUNC('month', last_date) AS churn_month,
  COUNT(*) FILTER (WHERE is_churned = 1) AS churned_users,
  COUNT(*) AS total_users,
  ROUND(100.0 * COUNT(*) FILTER (WHERE is_churned = 1) / COUNT(*), 1) AS churn_rate
FROM churned
GROUP BY churn_month
ORDER BY churn_month;

На что смотрит проверяющий: адекватное определение churn (не слишком строгое, не слишком мягкое), анализ факторов (активность в первую неделю, количество сессий), предложения по снижению оттока.

Подробнее: метрики продукта, retention.


Задание 10. Атрибуция маркетинговых каналов

Условие. Пользователь видит рекламу в нескольких каналах перед покупкой. Как распределить ценность покупки между каналами? Реализуйте модель last-click и linear attribution.

-- Last-click: вся ценность последнему касанию
WITH last_touch AS (
  SELECT
    o.order_id,
    o.amount,
    t.channel,
    ROW_NUMBER() OVER (
      PARTITION BY o.order_id
      ORDER BY t.touch_time DESC
    ) AS rn
  FROM orders o
  JOIN touchpoints t ON o.user_id = t.user_id
    AND t.touch_time <= o.order_time
)
SELECT channel, SUM(amount) AS attributed_revenue
FROM last_touch WHERE rn = 1
GROUP BY channel;

-- Linear: равномерное распределение
WITH touches AS (
  SELECT
    o.order_id,
    o.amount,
    t.channel,
    COUNT(*) OVER (PARTITION BY o.order_id) AS touch_count
  FROM orders o
  JOIN touchpoints t ON o.user_id = t.user_id
    AND t.touch_time <= o.order_time
)
SELECT channel, ROUND(SUM(amount / touch_count), 0) AS attributed_revenue
FROM touches
GROUP BY channel;

На что смотрит проверяющий: понимание разницы между моделями, ограничения каждой, рекомендация — какую использовать и почему.


Как оформлять тестовое задание

  1. Структура. Каждый вопрос — отдельный раздел с SQL-кодом, результатами и выводами
  2. Код. Чистый, читаемый, с CTE вместо вложенных подзапросов. Комментарии к сложным местам
  3. Визуализации. Графики вместо таблиц с 50 строками. Matplotlib, Seaborn или Google Sheets
  4. Выводы. После каждого анализа — 2–3 предложения с выводами и рекомендациями
  5. README. Кратко опишите подход, допущения и инструкцию по запуску

Читайте также

FAQ

Сколько времени дают на тестовое задание?

Обычно 2–3 дня. Некоторые компании дают 4–6 часов на задание поменьше. Если срок не указан — уточните у рекрутера и не тяните больше 3 дней.

Можно ли пользоваться интернетом при выполнении?

Да, тестовые задания выполняются дома без надзора. Но код должен быть ваш — проверяющие легко отличают копипаст из ChatGPT от самостоятельного решения по стилю кода и глубине выводов.

Что важнее — код или выводы?

Выводы. Код — это инструмент, а ценность аналитика — в интерпретации. Чистый SQL без выводов оценят ниже, чем средний SQL с точными бизнес-рекомендациями.

Тестовое задание не оплачивают — это нормально?

Для этапа отбора — да, это стандартная практика. Но если задание занимает больше 8 часов и выглядит как реальная рабочая задача компании — это повод задать вопрос рекрутеру.


Потренируйтесь решать аналитические задачи — откройте тренажёр с 1500+ вопросами.