Вопросы по теме «Инструментация и качество данных»

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

Всего в этом разделе 20 вопросов. Каждый — с правильным ответом и кратким разбором теории. Разбито на 4 части по 5 вопросов.

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

Вопросы 15 из 20

1Вы логируете событие `experiment_exposure` для A/B-тестов. Какой инвариант наиболее полезен для контроля качества данных?
AРаспределение вариантов должно быть строго 50/50 каждый день, иначе данные `experiment_exposure` некорректны
BОдин пользователь за время эксперимента должен получать ровно один вариант, а ключевые поля `experiment_exposure` обязаны быть заполнены
CСобытие `experiment_exposure` отправляется при каждом открытии экрана: чем больше отправок, тем точнее доли вариантов
DСобытие `experiment_exposure` логируется только при первом запуске приложения и далее не повторяется в течение всего эксперимента
Ответ: Инварианты для `experiment_exposure` должны ловить противоречия в назначении варианта и обязательные поля, а не требовать идеальной пропорции.

Главный инвариант данных эксперимента — стабильность присвоения варианта на пользователя: один и тот же `user_id` не должен встречаться в логе с двумя разными значениями `variant`. Это ловит баги рандомизации, кросс-девайс склейки и кеширования. Заполненность ключевых полей (`experiment_id`, `variant`, `user_id`) проверяется параллельно. Жёсткое требование 50/50 каждый день нереалистично — небольшие SRM на коротких окнах нормальны. Отправка при каждом открытии экрана раздувает объём, а отправка только при первом запуске теряет переназначения и долгосрочные эксперименты.

Подробный разбор →
2Вы описываете схему событий для `purchase_succeeded`. Как лучше хранить сумму покупки в свойствах события, чтобы избежать проблем качества данных при агрегациях?
AХранить `amount='1990 RUB'` строкой с символом валюты: значение сразу читается человеком в отчётах и интерфейсах
BХранить `amount='1 990'` строкой с разделителями именно так, как сумма отображается пользователю в интерфейсе приложения
CХранить `amount_minor=1990` числом в минимальных единицах и `currency='RUB'` отдельным свойством для последующих агрегаций
DХранить `amount=1990.0` числом с плавающей точкой и без отдельного поля валюты, а валюту определять по стране пользователя
Ответ: Для аналитики лучше хранить числовое поле и валюту отдельно, чтобы избежать парсинга и неоднозначностей в свойствах события.

Суммы в событиях лучше хранить целым числом в минимальных единицах валюты (копейки, центы) и валюту класть отдельным полем. Это исключает ошибки округления `float`, упрощает агрегации `SUM` и фильтрацию по валюте, и не требует парсинга строк в ETL. Строковые форматы вроде `'1990 RUB'` или `'1 990'` ломают арифметические операции и зависят от локали. Хранение `float` без валюты вынуждает определять её по косвенным признакам, что приводит к ошибкам у мультивалютных пользователей.

Подробный разбор →
3Какой санити-чек лучше всего подходит для поля валюты в событиях покупок с точки зрения инвариантов и качества данных?
AПроверять, что валюта строго равна `'RUB'`, и считать любое другое значение ошибкой данных независимо от контекста
BРазрешить любые значения валюты без проверки списка кодов: чем больше форматов, тем шире охват рынков в логах
CУдалить поле валюты совсем и хранить только сумму в минимальных единицах, договорившись о единой валюте платежа
DПроверять, что поле непустое и входит в список допустимых ISO-кодов; алертить на новые или неожиданные значения валюты
Ответ: Инвариант для перечислимого поля должен проверять непустоту и допустимый набор значений, иначе ошибки будут скрыты.

Санити-чек на поле валюты обычно опирается на whitelist: непустое значение из списка ISO 4217 кодов, поддерживаемых продуктом, и алерт на любое новое или неожиданное значение. Так ловятся опечатки, баги клиентов и расширение рынков, о которых аналитика ещё не знает. Жёстко фиксировать одну валюту нельзя — продукт может работать в нескольких регионах. Разрешать любые значения — открыть путь мусору. Удаление поля валюты ломает мультивалютные расчёты и привязывает данные к одному рынку без явного контракта.

Подробный разбор →
4Какие свойства полезно добавлять почти ко всем событиям, чтобы быстрее диагностировать проблемы инструментирования событий после релизов?
AДостаточно одного `user_id` в свойствах события: остальные поля раздувают объём и усложняют разбор инцидентов после релиза
BДобавлять `app_version` и `platform` к каждому событию, чтобы локализовать баги по версиям и окружению пользователя продукта
CДобавлять только `country` и `language`: эти поля задают сегмент пользователя без необходимости знать версию сборки или платформу
DУбирать поле `app_version` из событий: данные становятся единым массивом без сегментации по сборкам и проще ложатся в отчёт
Ответ: Поля версии и платформы в логировании помогают быстро понять, где именно сломалось инструментирование событий.

Базовый набор служебных полей в каждом событии — версия приложения, платформа и версия SDK или номер сборки. Это позволяет в первые минуты после релиза увидеть, в какой именно сборке поломалась отправка или появилась аномалия в метрике, и не тратить часы на корреляцию с релиз-нотами. Только `user_id` не даёт разрезать данные по сборкам. Только страна и язык — полезные сегменты, но не помогают локализовать инцидент. Удаление `app_version` лишает аналитику ключевого инструмента диагностики после релизов.

Подробный разбор →
5Вы хотите логировать применение фильтров в каталоге. Какой вариант лучше для таксономии событий и последующей аналитики?
AСоздавать отдельные события `filter_applied_color`, `filter_applied_brand` и так далее под каждый тип фильтра.
BЛогировать общее событие `user_did_something` и складывать все детали фильтра в одно текстовое поле.
CЛогировать единое событие `filter_applied` с параметрами вида `{filter: 'brand', value: 'nike'}` в payload.
DЛогировать событие `filter_applied` без параметров, а конкретное значение фильтра восстанавливать по скриншотам интерфейса.
Ответ: Стабильное имя события и динамические параметры в полях обычно лучше, чем плодить отдельные события под каждое значение.

Динамические имена событий раздувают таксономию и усложняют запросы и контроль качества данных. Единое событие с параметрами позволяет добавлять новые фильтры без взрыва числа имён. Такой подход проще валидировать и сравнивать между платформами. Текстовые поля и скриншоты плохо подходят для надёжной аналитики и автоматических проверок.

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

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

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

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

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

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