Middle, команда User Platform: авторизация, профиль, уведомления и пользовательские данные. Продуктовый подход, чистый код и автотесты.
Фишка: Горизонтальная культура без бюрократии: быстрые решения, удалёнка из любой точки мира, сильный продуктовый фокус. Команда User Platform отвечает за «лицо» пользователя — auth, профиль, уведомления — критичные для retention сценарии.
| Этап | Длительность | Что проверяют |
|---|---|---|
| HR-скрининг | 30–45 мин | Опыт 3+ лет, мотивация, удалёнка, зарплатные ожидания, знакомство с продуктом Авиасейлс |
| Техническое интервью | 60–90 мин | JavaScript, React, TypeScript, браузерные API, live coding или разбор кода, вопросы про тесты и оптимизацию |
| Интервью с командой | 45–60 мин | Опыт в auth/profile/уведомлениях, работа с QA, оценка задач, приоритизация, продуктовый подход |
| Финал | 30 мин | Культурный fit, вопросы кандидата о процессах и команде User Platform |
Обязательный минимум
Плюсом будет
Какие знаешь типы данных в JS?
7 примитивов (string, number, bigint, boolean, undefined, symbol, null) + object. typeof null === 'object' — исторический баг.
Как работает Event Loop?
Call stack → microtasks (Promise) → macrotasks (setTimeout). Render между macrotasks. async/await = синтаксический сахар над Promise.
В чём разница между стрелочной функцией и обычной?
Стрелочная не имеет своего this/arguments/constructor, лексически наследует this. Не использовать как методы объекта и конструкторы.
В чём разница между null и undefined?
undefined — переменная объявлена, но не инициализирована; null — явное «нет значения». typeof undefined → 'undefined', typeof null → 'object'.
Что такое чистая функция?
Одинаковый вход → одинаковый выход, без побочных эффектов и мутаций внешнего состояния. Основа предсказуемого React-кода.
Какие знаешь методы Promise?
then/catch/finally, Promise.all (fail-fast), Promise.allSettled (все результаты), Promise.race, Promise.any (первый успех).
Ловушка: На middle часто просят предсказать порядок вывода в задачах с setTimeout + Promise — отработай 5–6 типовых примеров.
Совет: Связывай ответы с User Platform: debounce для поиска в профиле, Promise.all для параллельной загрузки данных пользователя.
Что такое Virtual DOM и зачем он нужен?
JS-представление DOM. React сравнивает деревья (reconciliation), вычисляет минимальный diff, батчит обновления. Не «быстрее DOM», а предсказуемее и удобнее для декларативного UI.
Что такое useEffect?
Side effects после render: fetch, подписки, sync с внешними системами. Cleanup в return. Зависимости в массиве — контролируют перезапуск.
В чём разница между useEffect и useLayoutEffect?
useLayoutEffect синхронно после DOM-мутаций, до paint — для измерений/синхронного layout. useEffect — после paint, не блокирует отрисовку.
Что такое useMemo и useCallback?
useMemo кеширует результат вычисления, useCallback — ссылку на функцию. Нужны когда дорогие вычисления или передача stable ref в memo()-компоненты. Не злоупотреблять.
В каких случаях используется useCallback?
Когда функция передаётся в memo-компонент или в deps другого хука, и пересоздание вызывает лишние рендеры. Бесполезен без memo-потребителя.
Какие знаешь хуки?
useState, useEffect, useContext, useReducer, useMemo, useCallback, useRef, useLayoutEffect. React 19: use(), useActionState, useOptimistic.
Какие плюсы и минусы React?
Плюсы: экосистема, компонентный подход, SSR, DevTools. Минусы: boilerplate, нужно понимать рендеры, экосистема быстро меняется.
Фишка: User Platform — формы профиля и auth: частые re-render'ы при валидации. Покажи понимание controlled components и оптимизации без преждевременной мемоизации.
Ловушка: Типичная ловушка: useCallback с пустым deps, но замыкание на устаревший state. Всегда проверяй deps array.
Работал ли с TypeScript?
Расскажи про типизацию props, API-ответов, union types для состояний загрузки (idle/loading/success/error).
Что такое Generics?
Параметризация типов: function identity<T>(x: T): T. Используются в хуках, API-клиентах, компонентах-обёртках.
В чём разница между type и interface?
interface расширяется (extends), merge declaration. type — union/intersection, mapped types. Для объектов API чаще interface, для union state — type.
Совет: На продуктовых командах ценят типизацию API-контрактов профиля/авторизации — покажи пример типа UserProfile с optional fields.
Что такое CORS?
Cross-Origin Resource Sharing. Браузер блокирует cross-origin запросы без заголовков Access-Control-Allow-Origin. Preflight для non-simple requests.
Какие знаешь способы хранения данных в браузере?
localStorage (persistent), sessionStorage (tab), cookies (httpOnly для токенов — server-side), IndexedDB (большие данные). Не хранить sensitive data в localStorage.
Фишка: Auth в User Platform: refresh token в httpOnly cookie, access token в memory — безопаснее чем localStorage. Знай trade-offs.
Писал ли тесты?
Unit (Jest/Vitest + RTL): компоненты, хуки, утилиты. Integration: форма + API mock. E2E с QA: критические user flows (login, edit profile).
Как покрываете важную функциональность автотестами?
Пирамида тестов: много unit, меньше integration, минимум e2e на happy path + edge cases. Совместно с QA определяете critical paths.
Совет: В вакансии явно указана работа с QA над автотестами — подготовь пример, как вы договаривались о coverage критичных auth-сценариев.
Как бы реализовал форму редактирования профиля?
Controlled form, валидация (client + server), optimistic update или loading state, обработка ошибок, debounce для autosave, типизация полей.
Как организовать flow авторизации на frontend?
Redirect на IdP → callback с code → exchange на tokens → хранение (httpOnly cookie / memory) → refresh logic → protected routes → logout cleanup.
Как работать с уведомлениями (in-app / push)?
Polling vs WebSocket vs SSE. In-app: notification center + read/unread state. Push: Service Worker + permission API. Graceful degradation.
Фишка: Это ключевой домен вакансии — покажи понимание UX edge cases: expired session mid-edit, offline, race conditions при параллельных запросах.
Debounce
Написать функцию debounce(fn, delay), которая откладывает вызов fn на delay мс и сбрасывает таймер при повторном вызове.
function debounce(fn, delay) {
let timerId;
return function (...args) {
clearTimeout(timerId);
timerId = setTimeout(() => fn.apply(this, args), delay);
};
}Сложность: O(1) на вызов
Бесполезный useCallback
Исправь ошибки в коде с memo(Button) и useCallback — кнопка ререндерится, onClick не работает корректно.
1) onClick → onClick (camelCase в JSX)
2) useCallback deps: [isVisible] или functional setState
3) onClick={OnClick} → onClick={onClick} (регистр)
4) memo полезен только если props стабильны
const onClick = useCallback(() => {
setIsVisible(v => !v);
}, []);Сложность: —
Чтение кода: деструктуризация
Чему равняются foo и bar в 6 фрагментах с деструктуризацией, переименованием и вложенными значениями?
1) foo=1, bar=2
2) foo=2, bar=1 (переименование)
3) foo=[2], bar=1
4) foo={baz:3}, bar=1
5) foo=3, bar=1
6) foo=1, bar=3 (default value при отсутствии ключа)Сложность: —
Функция мемоизации
Написать memo(fn), которая кеширует результат вызова fn для одинакового аргумента.
function memo(fn) {
const cache = new Map();
return function (arg) {
if (cache.has(arg)) return cache.get(arg);
const result = fn(arg);
cache.set(arg, result);
return result;
};
}Сложность: O(1) lookup, O(n) первый вызов
Получение вложенного значения
Написать get(obj, path) где path — массив ключей, вернуть значение или undefined.
function get(obj, path) {
return path.reduce((acc, key) => acc?.[key], obj);
}
// или цикл:
let cur = obj;
for (const key of path) {
if (cur == null) return undefined;
cur = cur[key];
}
return cur;Сложность: O(d) где d — глубина path
Каркас ответа
3 дня
7 дней
14 дней
| Блок | Готов, если... |
|---|---|
| JavaScript Core | можешь объяснить Event Loop и предсказать порядок вывода в 5 типовых задачах |
| React | можешь объяснить когда нужен useMemo/useCallback, а когда это overhead |
| TypeScript | можешь типизировать API-ответ профиля пользователя с optional fields |
| Auth & Storage | можешь нарисовать OAuth flow и объяснить где хранить tokens |
| Live coding | можешь за 15 мин написать debounce или get(obj, path) без подсказок |
| Behavioral | есть 2 истории про продуктовую задачу и 1 про collaboration с QA |
В день собеседования