Инструментация и качество данных: вопросы для собеседования (часть 2)

Трекинг событий, naming conventions, data contracts, валидация данных — от качества инструментации зависит качество всей аналитики. На собеседовании спрашивают, как спроектировать систему событий для нового фичи, что делать при расхождении данных между системами и как обнаружить проблемы с логированием.

A/B-тесты в продуктовой аналитикеОсновы продуктовой аналитикиВоронки, когорты и retentionРост, активация и онбордингМонетизация и юнит-экономикаNorth Star, KPI и иерархия метрикПриоритизация и RICEПостановка задачи и PRDСегментация и позиционированиеСторителлинг и alignmentИсследование пользователей и JTBD

Вопросы 610 из 20

6Вы проектируете схему событий для регистрации. Какой вариант сбора событий лучше всего подходит, чтобы считать конверсию в успешную регистрацию и понимать, через какой способ вошли?
AЛогировать `signup_completed` со свойствами `{method: email, platform: ios}` и отдельно `signup_failed` с причиной ошибки
BЛогировать `button_click` по кнопке «Зарегистрироваться» без свойств, без признака успеха, ошибки и метода регистрации
CЛогировать отдельные `signup_completed_email` и `signup_completed_phone` под разными именами без свойств и без причины ошибки
DЛогировать `info`-сообщения серверной части без идентификатора пользователя, метода регистрации и признака успешного завершения
Ответ: Хорошая схема событий фиксирует смысловое событие и ключевые свойства, а ошибки лучше отделять отдельным событием с причиной.

Событие `signup_completed` отражает факт успешного результата и удобно для воронки. Свойства вроде метода и платформы помогают сегментировать, не раздувая набор имён событий. Отдельный `signup_failed` позволяет анализировать причины падения конверсии без смешивания успеха и ошибок в одном событии. `button_click` без контекста не даёт уверенности, что регистрация завершилась.

Подробный разбор →
7На `iOS` свойство товара приходит как `productId`, а на `Android` как `product_id`. В отчётах часть событий не объединяется. Что правильнее сделать для качества данных?
AОставить расхождение и в каждом запросе писать оба варианта поля через `COALESCE`, чтобы быстрее закрыть задачу
BСчитать метрики по `iOS` и `Android` каждый раз отдельно, чтобы не смешивать платформы и не править схему
CПривести только `iOS` к названию `productId` без обновления контракта схемы событий на стороне `Android`
DЗафиксировать единый стандарт схемы (например, `product_id`) и привести инструментирование или ETL-нормализацию к нему
Ответ: Единая схема событий и нормализация свойств между платформами уменьшают ошибки логирования и упрощают аналитику.

Расхождение названий между платформами — это нарушение единой таксономии событий. Правильный путь — зафиксировать единый стандарт (snake_case как `product_id`), отразить его в контракте схемы и либо обновить инструментирование на проблемной платформе, либо нормализовать поле в ETL. `COALESCE` в каждом запросе размножает технический долг и ломается при добавлении новых полей. Считать платформы отдельно — отказ от кросс-платформенных метрик. Переименование на одной платформе без контракта приводит к тому, что следующий разработчик снова разойдётся.

Подробный разбор →
8Как лучше организовать таксономию событий для ошибок оплаты, чтобы аналитика быстро находила причины падения конверсии и не путала успех с ошибкой?
AЛогировать только системные сообщения устройства без отдельных событий `payment_*` со свойствами `stage` и `error_code`
BДелать разные имена событий под каждую причину ошибки: `payment_error_timeout`, `payment_error_3ds`, `payment_error_decline`
CЛогировать одно общее событие `payment_event` с булевым полем `is_success` без свойств `stage`, `error_code` и `provider`
DЛогировать `payment_succeeded` и `payment_failed` со свойствами `stage`, `error_code`, `provider` для агрегации причин и сводки по воронке
Ответ: Разделение успеха и ошибки на разные события и явные свойства делают качество данных и диагностику лучше.

Хорошая таксономия для оплат — два события (`payment_succeeded` и `payment_failed`) и набор свойств: `stage` (где упало), `error_code` (тип ошибки), `provider` (платёжный провайдер). Так аналитика быстро строит воронку и сводку причин падения конверсии. Разные имена событий под каждую причину дробят таксономию: каждое новое значение `error_code` требует нового события и обновления всех дашбордов. Одно общее `payment_event` теряет различие успеха и ошибки в названии и осложняет фильтры. Опираться только на системные сообщения устройства нельзя — они не содержат бизнес-контекста.

Подробный разбор →
9Вы включили семплирование 10% для высокочастотного события `scroll` (в инструментировании событий оно отправляется не всегда). Как сделать так, чтобы аналитика и качество данных не пострадали?
AНичего не делать: семплирование на больших объёмах не влияет на выводы и не требует поправок на стороне расчётов
BЛогировать `sample_rate` в свойствах события и применять веса в расчётах, а критичные для пути пользователя события не семплировать
CПрименять единую константу семплирования 10% ко всем событиям продукта, чтобы аналитика считала метрики без пересчёта весов
DСемплировать события по `user_id` хешу с фиксированной долей и не учитывать долю в расчётах: коэффициент примерно сократится в формулах
Ответ: При семплировании важно фиксировать `sample_rate` и не семплировать события, которые являются основой воронок и инвариантов.

При семплировании высокочастотных событий критично сохранить возможность правильно пересчитывать метрики. Поэтому в само событие кладут поле `sample_rate` (или эквивалент), а в SQL-агрегациях умножают `COUNT(*)` на обратный коэффициент. Критичные события (покупка, регистрация) не семплируют вовсе — они и так редкие. Делать единый коэффициент на все события — терять на критичных. Игнорировать долю в расчётах работает только для долей и средних, но ломается на абсолютных счётчиках, и в пересечении когорт даёт смещение.

Подробный разбор →
10После обновления SDK сумма по `purchase_succeeded` выросла почти в 2 раза, но платёжный провайдер этого не подтверждает. Что наиболее вероятно и какое действие по качеству данных самое уместное?
AПользователи стали покупать чаще после обновления SDK, и рост `purchase_succeeded` по `user_id` отражает реальный спрос в продукте
BСтоит подождать неделю: метрики `purchase_succeeded` и `revenue` «усреднятся» сами и расхождение с провайдером исчезнет без правок
CНужно удалить все события с одинаковым `event_time` в одном `user_id`, потому что такие совпадения почти всегда означают дубликат на стороне сервера
DВероятна повторная отправка событий (`at-least-once`); нужен уникальный `event_id` или `dedup_key` и дедупликация в пайплайне приёма событий
Ответ: Дубликаты часто возникают из-за повторной отправки при сетевых ретраях, поэтому нужна дедупликация через `event_id` или `dedup_key`.

Если источник истины (провайдер) не подтверждает рост, это сильный сигнал, что проблема в инструментировании или в обработке событий. Удаление по `event_time` опасно: реальные покупки могут происходить близко по времени, а часы на устройстве могут быть неточными. Правильнее закладывать дедупликацию на уровне идентификаторов события и транзакции. Затем инварианты по уникальности `order_id` помогут автоматически ловить повторения.

Подробный разбор →
1234

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать продукт в Telegram

Другие темы: Продуктовая аналитика

A/B-тесты в продуктовой аналитикеОсновы продуктовой аналитикиВоронки, когорты и retentionРост, активация и онбордингМонетизация и юнит-экономикаNorth Star, KPI и иерархия метрикПриоритизация и RICEПостановка задачи и PRDСегментация и позиционированиеСторителлинг и alignmentИсследование пользователей и JTBD