Хакатон MAX 2026 · этап отбора

Отборочный тест: вопросы и ответы

Снято 4 сентября 2026 с hackaton-max.testograf.ru. Верные варианты сервер не отдаёт, ответы и пояснения ниже — наши. Порядок вариантов в реальном тесте перемешивается.

15вопросов в трёх блоках
21балл максимум
3 × 3множественных, по 3 балла
25 минзаявлено, платформой не проверяется

Разработка

вопросы 1–5
1один вариант1 балл

В карточке мероприятия есть действие «Добавить в избранное». Оно меняет состояние карточки через JavaScript, не открывает другую страницу и не должно отправлять форму. Какой элемент лучше использовать?

  1. <a href="#favorite">Добавить в избранное</a>
  2. <span role="button">Добавить в избранное</span>
  3. <input type="submit" value="Добавить в избранное">
  4. <button type="button">Добавить в избранное</button>

ПочемуКнопка без type="submit" ничего не отправляет и не переходит по ссылке; span и a — семантически не кнопки, input submit отправит форму.

2один вариант1 балл

На странице есть несколько элементов <div class="status--error">Ошибка оплаты</div>. Нужно сделать красным текст только у элементов с классом status--error. Какой CSS-селектор корректно выберет все необходимые элементы?

  1. #status--error { color: red; }
  2. .status--error { color: red; }
  3. status--error { color: red; }
  4. div > status--error { color: red; }

ПочемуТочка — селектор класса. Без точки это селектор тега, решётка — id, а «div > status--error» ищет несуществующий тег.

3один вариант1 балл

В приложении загружается список заказов:

async function loadOrders() {
  try {
    const response = await fetch('/api/orders');
    const orders = await response.json();
    renderOrders(orders);
  } catch (error) {
    showError('Не удалось загрузить заказы');
  }
}

Сервер может вернуть статус 500 и JSON с описанием ошибки. При этом вместо сообщения об ошибке приложение пытается передать ответ в renderOrders. Что необходимо исправить?

  1. Убрать await перед response.json(), чтобы обработка ответа не блокировала интерфейс
  2. Перенести вызов fetch() за пределы try, поскольку catch должен обрабатывать только ошибки разбора JSON
  3. После fetch() проверить response.ok и при значении false прервать обработку с ошибкой до вызова renderOrders
  4. Заменить response.json() на JSON.parse(response), поскольку объект Response нельзя разобрать напрямую

Почемуfetch не бросает исключение на HTTP-ошибки, поэтому catch не сработает. Нужно явно проверить response.ok.

4один вариант1 балл

Нужно разместить индикатор загрузки точно по центру контейнера и по горизонтали, и по вертикали. Какой набор свойств подходит для контейнера?

  1. display: block; text-align: center; vertical-align: middle;
  2. display: flex; justify-content: center; align-items: center;
  3. position: static; margin-left: 50%; margin-top: 50%;
  4. float: center; align: middle;

ПочемуFlex-контейнер с justify-content и align-items центрирует по обеим осям. text-align/vertical-align и float: center так не работают.

5несколько вариантов · ровно 3 верных3 балла

После загрузки данных в контейнер #orders динамически добавляются элементы списка:

<div class="order" data-order-id="125">
  <button class="remove">
    <span>Удалить</span>
  </button>
</div>

Нужно обрабатывать удаление элементов без повторного назначения обработчиков после каждого обновления списка. Какие действия необходимо выполнить?

  1. Один раз назначить обработчик события click на контейнер #orders, который существует на странице до загрузки данных
  2. Внутри обработчика использовать event.target.closest('.remove'), чтобы определить нажатую кнопку, даже если пользователь нажал на вложенный элемент
  3. По найденной кнопке определить соответствующий элемент .order или его data-order-id, чтобы удалить именно выбранный заказ
  4. После каждого обновления списка заново находить все кнопки .remove и назначать каждой отдельный обработчик
  5. Использовать CSS-состояние .remove:active, чтобы запускать удаление элемента без обработчика JavaScript
  6. Назначить обработчик объекту window и при любом клике удалять последний элемент списка

ПочемуДелегирование: один обработчик на живом контейнере, closest для поиска кнопки при клике по вложенному span, data-order-id для адресного удаления.

Продуктовые навыки

вопросы 6–10
6один вариант1 балл

Команда выбирает событие активации для мини-приложения по поиску и бронированию мероприятий. Событие должно происходить в первой сессии, зависеть от завершенного действия пользователя и означать получение основной ценности — гарантированного места на мероприятии.

За прошлый месяц D7 retention составил:

  • после открытия каталога — 13%;
  • после открытия карточки — 18%;
  • после начала бронирования — 29%;
  • после подтвержденного бронирования — 43%.

Какое событие следует выбрать в качестве активации?

  1. Первое открытие каталога мероприятий
  2. Первое открытие карточки мероприятия
  3. Начало заполнения формы бронирования
  4. Получение подтверждения успешного бронирования

ПочемуЕдинственное событие в первой сессии, завершённое пользователем и означающее ценность (место гарантировано). D7 после него максимальный — 43 %.

7один вариант1 балл

48% пользователей, открывших не менее пяти карточек мероприятий, не переходят к бронированию. В интервью большинство из этих пользователей говорят, что подходящие события находятся слишком далеко. Команда располагает двумя неделями разработки и сможет проверить только одно изменение. Какую гипотезу следует проверить первой?

  1. Добавление фильтра по району сократит число нерелевантных по расстоянию вариантов и повысит конверсию из каталога в бронирование
  2. Добавление карты сделает изучение каталога удобнее и повысит среднюю продолжительность пользовательской сессии
  3. Добавление персонального баннера увеличит число переходов в карточки среди пользователей, ранее добавлявших события в избранное
  4. Увеличение размера карточек на мобильных устройствах повысит конверсию из каталога в просмотр мероприятия

ПочемуГипотеза строится на озвученной пользователями причине (далеко) и метрике, которую надо сдвинуть (конверсия в бронирование).

8один вариант1 балл

Команда проверяет, повышает ли новый текст кнопки долю завершенных оплат. Один пользователь может несколько раз возвращаться на страницу тарифа и открывать ее с разных устройств. Какой дизайн эксперимента даст наиболее однозначный вывод?

  1. Рандомизировать каждый просмотр страницы, измерять CTR кнопки и остановить тест после первого дня преимущества нового текста
  2. Рандомизировать пользователей, закрепить вариант на весь период, заранее выбрать завершенную оплату основной метрикой и установить правило остановки
  3. Показать новый текст мобильным пользователям, а старый — пользователям десктопной версии, затем сравнить долю завершенных оплат
  4. Показывать старый текст в первую неделю, а новый — во вторую, сохранив одинаковые настройки рекламного трафика

ПочемуЕдиница рандомизации — пользователь, вариант закреплён, метрика заранее выбрана, правило остановки исключает подглядывание. Остальные варианты дают смещения.

9один вариант1 балл

Код подтверждения действует 60 секунд. Обычно сообщение приходит быстро, но у части пользователей время отклика сервиса доставки превышает 60 секунд. Уже через 20 секунд пользователь может запросить новый код, после чего предыдущий код становится недействительным.

В результате пользователь, не дождавшись первого сообщения, запрашивает код повторно. Позже он получает оба сообщения и может ввести первый код, который уже был аннулирован.

Какое изменение следует проверить в первую очередь, чтобы повысить успешность входа?

  1. Уточнить текст ошибки, чтобы пользователь видел, какой из полученных кодов уже недействителен
  2. Изменить логику повторной отправки так, чтобы новый запрос не делал недавно отправленный код неожиданно недействительным
  3. Сократить код до четырех цифр, чтобы пользователи могли быстрее вводить его после получения сообщения
  4. Сделать повторный запрос доступным раньше, чтобы пользователь быстрее получил дополнительное сообщение

ПочемуКорень проблемы в логике аннулирования кода, а не в тексте ошибки или длине кода. Ускорение повторного запроса только усилит эффект.

10несколько вариантов · ровно 3 верных3 балла

Маркетплейс соединяет заказчиков и исполнителей. Команда заинтересована не только в оценке общей активности пользователей, но и прежде всего в измерении долгосрочной ценности, создаваемой платформой:

  • доводятся ли заказы до результата;
  • сохраняется ли качество взаимодействия;
  • возвращаются ли стороны к повторному сотрудничеству.

Какие метрики следует использовать совместно?

  1. Количество завершенных заказов на активную пару «заказчик — исполнитель»
  2. Доля заказов, завершившихся отменой или спором
  3. Доля пар «заказчик — исполнитель», совершивших повторный заказ в течение 30 дней после первого завершенного заказа
  4. Среднее количество просмотров карточек заданий за одну сессию
  5. Открываемость уведомлений о новых заданиях
  6. Среднее количество откликов исполнителей на одно опубликованное задание

ПочемуТри вопроса команды — доводятся ли заказы, качество взаимодействия, повторное сотрудничество — закрываются этими тремя метриками. Просмотры, отклики и уведомления — активность, а не ценность.

Аналитика

вопросы 11–15
11один вариант1 балл

После запуска новой системы рекомендаций среднее время одной сессии выросло с 7 до 11 минут. Команда сделала вывод: «Рекомендации стали полезнее, потому что пользователи проводят в приложении больше времени». Как следует оценить этот вывод?

  1. Вывод корректен: увеличение времени сессии всегда означает рост полезности продукта для пользователя
  2. Вывод преждевременный: время сессии могло вырасти как из-за большей вовлеченности, так и из-за того, что пользователям стало сложнее находить нужное
  3. Вывод неверен: время сессии нельзя использовать для анализа поведения пользователей ни в каких продуктовых сценариях
  4. Вывод корректен только в том случае, если одновременно с длительностью сессии выросло общее число зарегистрированных пользователей

ПочемуВремя сессии — двусмысленная метрика: растёт и от пользы, и от путаницы. Нужны метрики результата.

12один вариант1 балл

Из 750 пользователей 300 открыли карточку тарифа, 90 начали оплату, 72 завершили ее. В отчете показатель 72 / 750 назван конверсией оплаты. Какое описание корректно?

  1. 9,6% — конверсия от всех пользователей до оплаты, 24% — из карточки в оплату, 80% — из начала оплаты в успешную оплату
  2. 9,6% — из начала оплаты в успешную, 24% — от всех пользователей, 80% — из карточки в оплату
  3. 24% — от всех пользователей до оплаты, 80% — из карточки в оплату, конверсию от начала оплаты посчитать нельзя
  4. 80% — от всех пользователей до оплаты, 9,6% — из карточки в оплату, 24% — из начала оплаты в успешную

Почему72 / 750 = 9,6 %; 72 / 300 = 24 %; 72 / 90 = 80 %.

13один вариант1 балл

В понедельник команда обнаружила резкое падение числа оформленных заказов. Аналитик также заметил, что в этот день значительно снизилось число пользователей, дошедших до страницы оплаты. Какое действие наиболее разумно выполнить первым?

  1. Сразу сделать вывод, что проблема находится на странице оплаты, поскольку именно перед ней уменьшилось число пользователей
  2. Проверить воронку по этапам и сравнить изменения трафика, переходов и технических ошибок, чтобы определить, на каком шаге началось отклонение
  3. Сразу вернуть предыдущую версию страницы оплаты, поскольку падение заказов чаще всего связано с последним этапом воронки
  4. Подождать несколько недель и анализировать только среднемесячные значения, поскольку дневные изменения не позволяют находить продуктовые проблемы

ПочемуСначала локализовать шаг, где началось отклонение. Выводы и откаты без диагностики преждевременны, ждать недели — поздно.

14один вариант1 балл

Сумма дневных уникальных пользователей за неделю равна 9000, а WAU — 4300. Как интерпретировать расхождение и что проверить?

  1. Показатели противоречат друг другу. WAU нужно заменить суммой семи дневных значений
  2. Дневные показатели нельзя считать уникальными. Вместо них следует использовать число сессий
  3. Расхождение объясняется только часовыми поясами. Достаточно пересчитать все даты в UTC
  4. Пользователи повторяются между днями. Нужно проверить правила дедупликации и распределение числа активных дней на пользователя

ПочемуСумма DAU за 7 дней считает одного человека столько раз, сколько дней он заходил. Расхождение ожидаемо, проверить надо дедупликацию.

15несколько вариантов · ровно 3 верных3 балла

Команда хочет рассчитать единый MAU сервиса за июнь. Сейчас в мобильном отчете активным считается пользователь, совершивший любое событие, а в веб-отчете — только пользователь, выполнивший целевое действие. Один человек может пользоваться обеими платформами под общей учетной записью.

Какие действия необходимо выполнить, чтобы корректно рассчитать единый MAU?

  1. Согласовать единое определение активного пользователя для мобильной и веб-версий
  2. Зафиксировать единые границы отчетного периода и часовой пояс
  3. Объединить данные по общему идентификатору пользователя и удалить межплатформенные дубли
  4. Сложить MAU мобильной и веб-версии, поскольку активность на разных платформах учитывается отдельно
  5. Рассчитать среднее значение между мобильным и веб-MAU, чтобы сгладить различия в методологии
  6. Считать пользователей по уникальным устройствам, поскольку один человек может использовать несколько платформ

ПочемуЕдиный MAU требует одного определения активности, одного периода и часового пояса и объединения по общему идентификатору. Складывать или усреднять MAU нельзя.

Оценка: одиночные вопросы по 1 баллу, множественные по 3, итого 21. Ответы отражают наше понимание правильного решения; официальный ключ организаторы не публикуют. Поддержка теста: support@hackathon-max.vk.company.