Вопросы для собеседования React Native разработчика
Готовый набор для интервьюера: 36 вопросов с тезисами эталонного ответа, задача, рубрика и план встречи.
На собеседовании React Native разработчика хорошо работает схема на 60 минут: 3-4 устных вопроса по стеку, одна задача на live coding, проектирование для middle и выше и вопросы кандидата. Ниже вопросы по грейдам из базы Техпрогона: у каждого тезисы, которые должен назвать сильный кандидат.
Всего в базе по этой роли 254 устных вопросов с чек-листом ответа.
Как построить техсобес на 60 минут
0-5 мин
Знакомство
Кто вы, формат встречи, кандидат коротко о себе и последнем проекте.
5-20 мин
Вопросы по стеку
3-4 устных вопроса из набора ниже. Сверяйте ответ с тезисами.
20-45 мин
Live coding
Одна задача. Смотрите на процесс по рубрике, а не только на ответ.
45-55 мин
Проектирование
Для middle и выше: система или решение целиком. Для junior: ещё вопросы.
55-60 мин
Вопросы кандидата
Что спросил кандидат, тоже сигнал: интерес к задачам и команде.
Junior: 12 вопросов
Основы: как устроено и зачем. Хватит 3-4 вопросов на встречу.
Объясните, на каких потоках выполняется RN-приложение и как это влияет на производительность.
Что хотим услышать
- JS-поток для React и логики, UI-поток для нативного интерфейса
- Блокировка JS: нет реакции на нажатия, JS-анимации стоят
- Блокировка UI: замирает всё, включая прокрутку
- Анимации на UI-потоке: native driver, Reanimated worklets
- Тяжёлое: разбить, отложить, вынести в натив
Если ответил, копните глубже
Чем отличаются var, let и const? Что из них вы используете и почему?
Что хотим услышать
varс функциональной областью,letиconstс блочнойvarподнимается сundefined,let/constпопадают в TDZvarможно объявить повторно,let/constнетconstзапрещает переприсваивание, но не изменение объектаvarна верхнем уровне скрипта становится свойствомwindow- По умолчанию
const,letдля изменяемых,varне использую
Если ответил, копните глубже
let в цикле for ведёт себя иначе, чем var?let?Почему any считают вредным и чем его заменить?
Что хотим услышать
anyвыключает проверку в обе стороны: на нём можно вызвать что угодно и присвоить его куда угодноanyзаразен: свойства и результаты вызовов на нём тожеany, ошибка уходит далеко от источника- Замена для неизвестных данных:
unknownс сужением или валидацией - Замена для «любого, но одного и того же»: дженерик
- Защита:
noImplicitAnyв strict и правило линтераno-explicit-any
Если ответил, копните глубже
any появляется неявно?any всё же оправдан?Как работает useEffect: когда запускается, зачем массив зависимостей и функция возврата?
Что хотим услышать
- эффект запускается после коммита и отрисовки
- пустой массив - один раз при монтировании
- без массива - после каждого рендера
- возвращённая функция - очистка, вызывается перед следующим запуском и при размонтировании
- зависимости сравниваются поверхностно через Object.is
- в StrictMode в разработке эффект намеренно запускается дважды
Если ответил, копните глубже
Объясни, что такое CORS и как он работает.
Что хотим услышать
- Same-origin policy: скрипт не может читать ответы другого origin (схема, хост, порт)
- CORS: сервер заголовками
Access-Control-Allow-*разрешает конкретным origin читать ответы - Проверяет браузер, сервер отвечает всегда; вне браузера CORS не действует
- Простые запросы уходят сразу, остальные после preflight OPTIONS
- С куками нужен
credentials: 'include',Allow-Credentials: trueи точный origin вместо*
Если ответил, копните глубже
Назовите ваши сильные стороны.
Что хотим услышать
- Две-три стороны, а не список из десяти
- Каждая подкреплена примером
- Стороны связаны с вакансией
- Нет пустых слов вроде «стрессоустойчивый, коммуникабельный» без доказательств
- Уверенно, без хвастовства
Если ответил, копните глубже
Вы фронтенд-разработчик и переходите на React Native. Какие отличия в вёрстке и компонентах важно знать?
Что хотим услышать
- Примитивы
View,Text,Image,Pressableвместо HTML; текст только вText - Стили это объекты JS в camelCase, без каскада, наследование только между
Text - Flexbox через Yoga:
columnпо умолчанию,flexShrink: 0 - Размеры в логических единицах без
px,useWindowDimensionsдля адаптивности - Платформенные различия:
Platform.select, тени, safe area, клавиатура
Если ответил, копните глубже
Как отменить сетевой запрос и зачем это нужно?
Что хотим услышать
- AbortController создаёт signal, который передаётся в fetch
- controller.abort() отклоняет промис ошибкой AbortError
- AbortError нужно отличать от настоящей ошибки при обработке
- в React отмена идёт в функции очистки useEffect
- без отмены получаем гонку: ответ на старый запрос перезаписывает новый
- один signal можно передать нескольким запросам сразу
Если ответил, копните глубже
Чем type отличается от interface и что вы выбираете в своём коде?
Что хотим услышать
- Оба описывают форму объекта и в большинстве случаев взаимозаменяемы
- Только
interfaceсливается при повторном объявлении (declaration merging), это нужно для расширения чужих типов - Только
typeописывает объединения, кортежи, условные и mapped-типы, псевдонимы примитивов - Расширение:
extendsу interface против пересечения&; конфликт полей приextendsдаёт ошибку, при&поле становитсяnever - Осознанное правило команды: например interface для публичных объектных контрактов, type для всего остального
Если ответил, копните глубже
Window?{ a: string } & { a: number }?type?Почему хуки нельзя вызывать условно?
Что хотим услышать
- хуки хранятся в списке, привязанном к порядку вызова
- React сопоставляет вызовы по индексу, а не по имени
- пропуск хука сдвигает весь список - состояние приезжает не туда
- вызывать можно только на верхнем уровне компонента или своего хука
- если первый рендер вернулся раньше хука, состояние молча теряется
- правило проверяет линтер react-hooks/rules-of-hooks
Если ответил, копните глубже
Чем отличаются GET и POST? Ответ «у POST есть тело» не засчитывается.
Что хотим услышать
- GET читает и безопасен, POST меняет состояние
- GET идемпотентен, POST нет: его нельзя молча повторять
- GET кешируется браузером и прокси, POST по умолчанию нет
- Параметры GET в URL: попадают в логи и историю, длина ограничена серверами
- GET можно добавить в закладки и prefetch, поэтому нельзя менять данные по GET
Если ответил, копните глубже
Какие у вас слабые стороны?
Что хотим услышать
- Назвал реальную слабость, а не штамп
- Слабость не критична для роли
- Рассказал, что делает, чтобы её компенсировать
- Есть пример прогресса
- Коротко, без самобичевания
Если ответил, копните глубже
Middle: 12 вопросов
Практика: почему так, какие компромиссы, что ломается.
Как вы выбираете способ реализации анимации в React Native?
Что хотим услышать
- Главный критерий: на каком потоке считаются кадры
- Простые
transform/opacity: Animated с native driver или Reanimated - Анимации раскладки и связанные с жестами: Reanimated + Gesture Handler
- Появление и удаление элементов: layout animations
- Сложные иллюстрации: Lottie или Rive
- Проверка на слабом устройстве в release
Если ответил, копните глубже
width через native driver?Объясни event loop: как браузер решает, что выполнять следующим.
Что хотим услышать
- JS однопоточный, есть стек вызовов
- макрозадачи: таймеры, события, сеть - по одной за цикл
- микрозадачи: промисы, queueMicrotask, MutationObserver
- после каждой макрозадачи очередь микрозадач вычерпывается полностью
- рендер происходит между макрозадачами, requestAnimationFrame - перед отрисовкой
- бесконечная генерация микрозадач заблокирует рендер
Если ответил, копните глубже
Напишите Pick и Omit своими словами и объясните, как они работают.
Что хотим услышать
Pick<T, K extends keyof T> = { [P in K]: T[P] }: mapped-тип по выбранным ключам- Ограничение
K extends keyof Tзапрещает несуществующие ключи Omit<T, K> = Pick<T, Exclude<keyof T, K>>: оставить все ключи, кроме указанных- У встроенного
Omitключ не ограниченkeyof T, поэтому опечатка проходит молча - Оба не распределяются по объединению и работают на верхнем уровне
Если ответил, копните глубже
Omit строгим?Omit для объединения?Pick сохраняет readonly и ??Как работает контекст и почему из-за него всё перерисовывается?
Что хотим услышать
- все потребители перерисовываются при смене значения провайдера
- сравнение идёт по ссылке на value
- объект-литерал в value меняет ссылку каждый рендер
- лечение: useMemo на value и разделение контекстов
- контекст - про передачу, а не про управление состоянием
- memo не спасает потребителя контекста
Если ответил, копните глубже
Чем отличаются сессии на куках и JWT? Что бы ты выбрал для обычного веб-приложения?
Что хотим услышать
- Сессия: id в куке, состояние на сервере (Redis/БД), отзыв мгновенный
- JWT: состояние в самом токене, проверка подписью без базы, сложно отозвать
- Для JWT нужна пара короткий access + отзываемый refresh
- Хранение: HttpOnly кука защищает от XSS, но нужна защита от CSRF (SameSite)
- Выбор по контексту: одно веб-приложение проще на сессиях, много сервисов и мобильные клиенты удобнее на токенах
Если ответил, копните глубже
Расскажите, как устроены слои в вашем мобильном приложении и зачем.
Что хотим услышать
- Presentation, domain, data и направление зависимостей внутрь
- Интерфейсы репозиториев в домене, реализации в data, связывание через DI
- Маппинг DTO и entity в доменные модели на границе
- Ошибки переводятся в доменные на границе data
- Use case только там, где есть логика или переиспользование
- Слои внутри фич, а не глобальные папки
Если ответил, копните глубже
Почему вы ищете новую работу?
Что хотим услышать
- Причина через цель, а не через бегство
- Ни слова негатива о текущем работодателе
- Показано, что на текущем месте был рост и результаты
- Связка с этой вакансией
- Коротко: до минуты
Если ответил, копните глубже
Чем новая архитектура React Native отличается от старой и что она даёт приложению?
Что хотим услышать
- Старый мост: асинхронные JSON-сообщения пакетами, узкое место
- JSI: прямые вызовы C++ из JS, синхронные при необходимости
- TurboModules: ленивая загрузка и типизированные спецификации через Codegen
- Fabric: C++ дерево теней, конкурентный React, синхронная раскладка
- Практический эффект: быстрее старт, отзывчивее жесты и анимации, меньше ошибок типов
- По умолчанию с 0.76, обязательна с 0.82; проверка библиотек
Если ответил, копните глубже
Как устроено наследование в JavaScript? Что происходит при обращении к свойству?
Что хотим услышать
- у каждого объекта есть ссылка на прототип - [[Prototype]]
- поиск свойства идёт вверх по цепочке до null
- proto - ссылка на прототип, prototype - свойство функции-конструктора
- class - синтаксический сахар над этой же схемой
- Object.create задаёт прототип напрямую
- изменение прототипа во время работы убивает оптимизации движка
Если ответил, копните глубже
Как типизировать функцию updateUser(id, patch), где patch может содержать любые поля пользователя, кроме id и createdAt?
Что хотим услышать
- Базовый тип
Userодин, остальные выводятся из него утилитами Partial<Omit<User, 'id' | 'createdAt'>>для patch- Отдельно
id: User['id'], чтобы тип id менялся вместе с моделью - Опасность
Partial: можно передать пустой объект, при необходимости требовать хотя бы одно поле - Нюанс:
Partialразрешает явныйundefined, флагexactOptionalPropertyTypesэто запрещает
Если ответил, копните глубже
Что такое stale closure в React и как это чинить?
Что хотим услышать
- колбэк запомнил значения того рендера, в котором был создан
- типично: setInterval из useEffect с пустыми зависимостями
- внутри навсегда остаётся начальное значение состояния
- лечение: функциональная форма setState
- лечение: честные зависимости и пересоздание эффекта
- лечение: ref для значения, которое нужно читать всегда свежим
Если ответил, копните глубже
Чем отличаются HTTP/1.1, HTTP/2 и HTTP/3? Какие проблемы решала каждая версия?
Что хотим услышать
- Семантика (методы, статусы, заголовки) одна, меняется транспорт
- HTTP/1.1: запросы по очереди в соединении, браузер держит около 6 соединений
- HTTP/2: бинарные фреймы, мультиплексирование, HPACK, одно соединение
- HTTP/2 упирается в head-of-line blocking TCP при потерях
- HTTP/3: QUIC поверх UDP, независимые потоки, TLS встроен, быстрее рукопожатие, миграция соединения
Если ответил, копните глубже
Senior: 12 вопросов
Глубина и опыт: границы подходов, решения в продакшене.
Спроектируйте ленту новостей: бесконечная подгрузка, pull-to-refresh, новые посты сверху, офлайн-кеш.
Что хотим услышать
- Курсорная пагинация: устойчива к вставкам новых постов
useInfiniteQueryили своя логика с флагами загрузки иhasNextPage- Склейка страниц с удалением дублей по id
- Pull-to-refresh: перезагрузить первую страницу, новые сверху без прыжка позиции
- Сохранение кеша на диск (персистер) и показ при старте
- Мемоизированные строки, FlashList, предзагрузка картинок
Если ответил, копните глубже
Как бы вы реализовали перебор всех записей постраничного API так, чтобы вызывающий код просто писал for await (const item of allItems())?
Что хотим услышать
async function*, внутри цикл по страницам сawait fetchyield*по элементам страницы илиyieldпоштучно- Условие остановки: нет курсора
nextили пустая страница - Ленивость: следующая страница грузится только когда потребитель дошёл до конца текущей
- Досрочный
breakу потребителя завершает генератор, запросы прекращаются;finallyдля очистки - Ошибки и отмена:
try/catchу потребителя,AbortSignalв параметрах
Если ответил, копните глубже
Объясните, как условный тип ведёт себя с объединением и когда это мешает.
Что хотим услышать
- Голый параметр в
T extends Uдаёт распределение по членам объединения - На этом построены
Exclude,Extract,NonNullable neverкак пустое объединение даётneverв результате- Отключение:
[T] extends [U], нужно дляIsNeverи проверок всего объединения - Распределение срабатывает только для параметра типа, а не для конкретного объединения, записанного прямо в условии
Если ответил, копните глубже
Exclude работает поэлементно?boolean extends true ? 1 : 2?Как бы ты загрузил данные в компоненте через useEffect, чтобы это было корректно? И почему в реальном проекте ты, возможно, сделал бы иначе?
Что хотим услышать
- Зависимости: всё, от чего зависит запрос, например id
- Гонки: в очистке AbortController или флаг ignore
- Состояния загрузки и ошибки, AbortError не считать ошибкой
- StrictMode в dev отправит запрос дважды, это нормально при корректной очистке
- Нет кеша, дедупликации, повторов и предзагрузки: каждый компонент грузит сам, возникают водопады
- В проекте: TanStack Query, SWR, загрузчики роутера или серверные компоненты
Если ответил, копните глубже
Как бы ты сделал надёжный клиент WebSocket для чата, который переживает обрывы сети?
Что хотим услышать
- Реконнект с экспоненциальной задержкой и джиттером, сброс задержки после успеха
- Heartbeat: ping/pong с таймаутом, при пропуске закрыть и переподключиться
- Нумерация сообщений: после реконнекта клиент сообщает последний id, сервер досылает пропущенное
- Очередь исходящих сообщений с клиентскими id, идемпотентность на сервере против дублей
- Реакция на
online/offlineи видимость вкладки, повторная авторизация при истёкшем токене
Если ответил, копните глубже
Как вы решаете, какие ответы API кешировать, где и на сколько?
Что хотим услышать
- Классификация данных по свежести и цене устаревания
- Где хранить: память, диск, база, HTTP-кеш
- Стратегии чтения: cache first, network first, SWR
- Инвалидация: TTL, версии, события (push, действия пользователя)
- Персональные данные в скоупе сессии, очистка при выходе
- Метрики: hit rate, трафик, время до контента
Если ответил, копните глубже
Вы претендуете на senior. Расскажите о себе.
Что хотим услышать
- Назван масштаб: команда, нагрузка, пользователи или деньги
- Есть решения, которые повлияли дальше своего кода
- Есть метрики результата
- Упомянуто влияние на команду: менторинг, процессы, ревью
- Уложился в 2 минуты, не утонул в деталях
Если ответил, копните глубже
Как реализовать свайп строки списка для удаления, чтобы он был плавным и не конфликтовал с прокруткой?
Что хотим услышать
- Gesture Handler
Gesture.Pan()сactiveOffsetX, чтобы вертикальная прокрутка не перехватывалась - Смещение в shared value, стиль через
useAnimatedStyleна UI-потоке - Порог и скорость в
onEnd: довести до конца или вернуть пружиной - Удаление через
runOnJSпосле завершения анимации, layout animation для схлопывания - Подтверждение или отмена удаления (undo), доступная альтернатива свайпу
- Совместимость с переиспользованием строк в FlashList
Если ответил, копните глубже
Пользователи жалуются, что после пары часов работы SPA начинает тормозить, а вкладка занимает гигабайт. Как будете искать и исправлять?
Что хотим услышать
- Воспроизвести сценарий и подтвердить рост: Performance с Memory, ступенчатый рост после сборок
- Сузить до действия: какие переходы или операции увеличивают память
- Heap snapshots до и после серии повторов, Comparison, Retainers
- Проверить типичные причины: подписки, таймеры, detached DOM, глобальные кеши, сторы
- Исправить и проверить тем же сценарием, добавить защиту: лимиты кешей, линтер на очистку эффектов
- Мониторинг в проде:
performance.memoryилиmeasureUserAgentSpecificMemoryвыборочно
Если ответил, копните глубже
Расскажите, как работают условные типы: распределение по объединению, infer, и где это нужно в прикладном коде.
Что хотим услышать
T extends U ? X : Yвычисляется на уровне типов, для обобщённого T откладывается до подстановки- Распределение: голый параметр с union применяется к каждому члену; отключается обёрткой
[T] neverкак пустое объединение даётneverв распределительном типеinferобъявляет переменную типа в шаблоне:ReturnType,Awaited, разбор строк- Прикладные примеры: тип ответа API по пути, извлечение параметров маршрута,
Extract/Exclude
Если ответил, копните глубже
IsNever<T>?infer X extends C отличается от вложенной проверки?Коллега предлагает обернуть все компоненты в memo, а все функции в useCallback. Что ответишь?
Что хотим услышать
- Мемоизация не бесплатна: сравнение зависимостей, хранение кеша, шум в коде
- Бесполезна без стабильных props: одна инлайн-функция ломает memo
- useCallback без memo у получателя ничего не даёт
- Неполные зависимости дают устаревшие значения, это новый класс багов
- Сначала профилировать и чинить структуру
- С React Compiler ручная мемоизация в основном не нужна, компилятор делает её точнее
Если ответил, копните глубже
Первая загрузка сайта занимает 4 секунды у пользователей из регионов. Как бы ты искал, где теряется время, и что делал?
Что хотим услышать
- Измерить: Navigation Timing и RUM по этапам (DNS, connect, TLS, TTFB, загрузка, рендер), Lighthouse и WebPageTest
- Сеть: CDN ближе к пользователю, HTTP/2 или HTTP/3, preconnect к сторонним доменам
- Сервер: медленный TTFB → кеширование, отдача статики с CDN, 103 Early Hints
- Ресурсы: Brotli, меньше JS, code splitting, оптимизированные картинки с размерами
- Рендер: критический CSS, defer для скриптов, без блокирующих сторонних скриптов
Если ответил, копните глубже
Задача для live coding
Дебаунс поиска при вводе
Поле поиска вызывает API на каждый символ. Напишите debounce(fn, ms): возвращает функцию, которая откладывает вызов fn на ms миллисекунд после последнего вызова, передавая последние аргументы. У возвращаемой функции есть метод cancel(), отменяющий отложенный вызов (его зовут при размонтировании экрана).
- Подсказка, если застрял: Храните id таймера в замыкании и вызывайте
clearTimeoutперед новымsetTimeout. - Подсказка, если застрял:
cancelможно повесить как свойство функции.
Эталон, тесты и таймер открываются интервьюеру в живом моке
Рубрика оценки: 1-4 балла
Те же критерии процесса, что в живом моке Техпрогона. Ставьте балл по каждому пункту, сумма показывает картину лучше, чем «понравился или нет».
Уточнил условие
Ограничения, формат входа, что вернуть при пустом вводе
Привёл примеры до кода
Обычный случай и хотя бы один краевой
Проговорил алгоритм словами
До того как писать код
Назвал сложность
По времени и по памяти
Написал рабочий код
Тесты прошли
Сам проверил краевые случаи
Прогнал в голове пустой ввод, один элемент, дубликаты
Нашёл и исправил ошибку сам
Или ошибок не было с первого раза
Мок-собес без регистрации для интервьюера
Хотите проверить кандидата на задаче с эталоном и рубрикой? Так работает живой мок в Техпрогоне.
Кандидат готовится в Техпрогоне и на задаче открывает ступень «Живой мок».
Он присылает вам ссылку. Вы открываете её без регистрации.
У вас условие, эталон, рубрика, уточняющие вопросы и таймер.
Вы ставите оценки и вердикт, кандидат сразу видит результат.
Для интервьюера бесплатно. Ссылку создаёт кандидат на тарифе Рывок
Наборы для других ролей
Готовитесь к собесу сами? Подготовка к собеседованию: React Native