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

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

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

Вопросы 1115 из 20

11В мобильном приложении события могут копиться офлайн и отправляться позже. Какие поля времени лучше заложить в логирование, чтобы корректно строить путь пользователя и контролировать задержки?
AХранить только `received_at`: серверное время точное и проще используется в отчётах, восстановления порядка действий не требуется
BХранить `event_time` и `received_at` вместе: первое отражает момент действия пользователя, второе фиксирует момент приёма сервером
CХранить только `event_time`: момент действия достаточен для воронок, серверное время в отчётах считается дублирующим полем
DХранить порядок поступления событий и `user_id`: этого хватает для восстановления последовательности без отдельного поля времени
Ответ: Для качественной аналитики нужны и время действия (`event_time`), и время поступления (`received_at`) для контроля лагов.

В офлайн-сценариях события могут лежать в буфере устройства часами и приходить позже, поэтому одного времени недостаточно. `event_time` фиксирует, когда действие произошло (его берут для построения пути и воронок), а `received_at` показывает момент приёма сервером и позволяет считать задержку доставки и контролировать офлайн-буфер. Только `received_at` ломает порядок действий пользователя при поздних отправках, только `event_time` не даёт измерить задержку, а отказ от времени делает анализ невозможным при перемешанных пакетах.

Подробный разбор →
12События иногда приходят на сервер не в том порядке, в котором пользователь совершал действия. Как правильнее строить путь пользователя и при этом мониторить качество данных?
AИспользовать порядок поступления `received_at` как корректный серверный порядок для построения путей пользователя
BУдалять события с поздним `received_at` для сохранения корректной последовательности шагов в воронке когорты
CСортировать шаги по `event_time`, а `received_at` использовать для контроля лагов и алертов по задержкам и потерям
DОтказаться от воронок и путей при нарушенном порядке: безопаснее, чем работать с возможно искажёнными `event_time`
Ответ: Для логики пути важен `event_time`, а `received_at` нужен для мониторинга задержек и сбоев доставки.

В мобильной среде сеть нестабильна, события могут буферизоваться и отправляться пачками. Если опираться на `received_at`, вы исказите последовательность и время действий. Использование `event_time` позволяет восстановить реальный порядок, а сравнение с `received_at` даёт метрики задержек и качества доставки. Это типичная практика для устойчивого инструментирования и контроля качества данных.

Подробный разбор →
13В корзине пользователь может добавлять товар и менять количество. Какой дизайн схемы событий обычно удобнее для аналитики и контроля качества данных?
AОдно событие `cart_updated` с полем `cart_json` и `user_id`, куда передаётся вся корзина одной большой строкой при каждом изменении
BТолько клики `plus_click` и `minus_click` с `user_id`, без `product_id` и `quantity`, чтобы зафиксировать сам факт нажатия
CАтомарные события `cart_item_added` и `cart_item_removed` со свойствами `cart_id`, `product_id` и `quantity_delta`
DСнимки `cart_state` с полями `items_json` и `user_id` раз в день, без отдельных событий по добавлению или удалению товаров
Ответ: Атомарные события с понятными свойствами проще валидировать и использовать в воронках, чем огромные снимки состояния.

События с `quantity_delta` позволяют считать добавления, удаления и итоговые количества без тяжёлых парсингов. Их проще контролировать через инварианты: обязательные поля, разумные диапазоны, отсутствие пустых идентификаторов. Полный снимок корзины строкой ухудшает логирование, усложняет джойны и может ломаться при изменениях формата. Для аналитики пути пользователя атомарные события обычно дают более прозрачную картину.

Подробный разбор →
14Вы заметили, что часть событий имеет `event_time` в будущем относительно `received_at`, особенно у пользователей из разных стран. Что наиболее вероятно и как это исправлять?
AСкорее всего `event_time` пишется в локальном времени без таймзоны: лучше отправлять в UTC или вместе с `timezone_offset` и валидировать диапазон
BВременные поля не нужны, поэтому стоит просто удалить `event_time` из логирования и оставить только время сервера в момент приёма события
CНужно округлять `event_time` до дня и сравнивать только календарные даты, тогда расхождение между клиентом и сервером перестанет влиять на отчёты
DНужно переводить `received_at` в локальную зону пользователя и использовать только это поле, отказавшись от клиентского `event_time` целиком
Ответ: Сдвиги времени часто возникают из-за локального времени устройства без таймзоны, поэтому важно стандартизировать `event_time` и хранить смещение.

Если разные клиенты пишут время по-разному, путь пользователя ломается, появляются события «из будущего» и неверные дневные отчёты. Решение — единый стандарт времени (например, UTC) и явное поле смещения или зоны, чтобы при необходимости восстанавливать локальный контекст. Полезны инварианты: например, проверка, что разница `received_at - event_time` не выходит за разумный коридор. Это повышает доверие к данным и ускоряет поиск проблем в инструментировании событий.

Подробный разбор →
15Пользователь проходит онбординг до логина, а логин делает позже. Какой подход к инструментированию событий лучше, чтобы сохранить полный путь пользователя и качество атрибуции?
AНе логировать события до логина: `user_id` присваивать после авторизации, события `app_open` до логина игнорировать
BИспользовать только `device_id` в качестве `user_id` без события `identify`: пользователя на разных устройствах считаем разными
CДо логина отправлять `anonymous_id`, после логина добавить `user_id` и событие `identify` для склейки двух идентификаторов
DПривязывать события только к `session_id` без сквозного идентификатора, и каждая новая сессия начинается с чистого листа
Ответ: Связка `anonymous_id` до логина и `user_id` после логина плюс событие `identify` помогает сохранить непрерывный путь пользователя.

Стандартный паттерн user identity — анонимный идентификатор до логина и явный alias после. До логина события идут с `anonymous_id`, после логина клиент шлёт событие `identify`, которое связывает `anonymous_id` с `user_id`. Так аналитика склеивает путь от первого открытия до подписки. Если не логировать события до логина — теряется онбординг и атрибуция. `device_id` как `user_id` навсегда не объединяет пользователя на разных устройствах. `session_id` без сквозного идентификатора не даёт строить когорты и удержание.

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

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

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

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

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

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