Skip to content

Вопросы на собеседовании: Фронтенд-разработчик

100 реальных вопросов с образцовыми ответами и пояснениями для уровня Middle.

Смотреть пример резюме: Фронтенд-разработчик

Тренировка флешкарточками

Интервальное повторение · Hunter Pass

Слушайте собеседование

Включите как подкаст: вопрос и образцовый ответ подряд.

Вопросы

event-loopconcurrencyjavascript

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

  • Микрозадачи: Promise, queueMicrotask, MutationObserver; все они выполняются до отрисовки.
  • Макрозадачи: setTimeout, setInterval, I/O; setTimeout(..., 0) уступает очереди отрисовки.
  • Длинные цепочки .then() могут задушить рендеринг и заморозить интерфейс.
  • Знание порядка позволяет предсказывать выполнение и избегать рывков.

Зачем это спрашивают: Проверяет, понимает ли кандидат параллелизм JavaScript глубже, чем просто знание того, что язык однопоточный.

closuresjavascript

Замыкание - это функция, сохраняющая доступ к переменным объемлющей области даже после завершения её выполнения.

  • Оно захватывает внешние переменные по ссылке, а не копией.
  • Классический пример: фабрика makeCounter, возвращающая increment и decrement с одной приватной count.
  • Оно лежит в основе паттерна модуля и хелперов мемоизации.

Зачем это спрашивают: Оценивает, способен ли кандидат применить концепцию на практике, а не просто воспроизвести учебное определение.

javascriptfunctions

Все три явно задают this функции, но различаются тем, как и когда вызывают её.

  • call: вызывает немедленно, аргументы перечисляются по отдельности.
  • apply: вызывает немедленно, аргументы передаются массивом.
  • bind: возвращает новую функцию с постоянно привязанным this, не вызывая её.
  • bind удобен для передачи методов класса в коллбэки без потери контекста.

Зачем это спрашивают: Проверяет практическое понимание привязки this, а не просто знание синтаксиса.

prototypes

Каждый объект ссылается на другой через [[Prototype]], образуя цепочку, заканчивающуюся на Object.prototype.

  • Поиск свойства обходит цепочку, пока не найдёт его или не дойдёт до конца.
  • Синтаксис класса ES6 - сахар над той же прототипной моделью наследования.
  • Методы класса попадают в prototype конструктора, а не в каждый экземпляр.

Зачем это спрашивают: Выявляет, понимает ли кандидат, что классы не вводят новую модель наследования, - это важно при отладке неожиданного поведения прототипов.

promises

Они различаются тем, когда завершаются и как обрабатывают отказы.

  • Promise.all: выполняется, когда выполнены все, отклоняется при первом отказе.
  • Promise.allSettled: ждёт завершения всех, возвращает объекты-статусы независимо от результата.
  • Promise.race: завершается, как только завершится первый промис, выполнением или отказом.
  • Promise.any: выполняется при первом успехе, отклоняется только если отклонились все.

Зачем это спрашивают: Проверяет, умеет ли кандидат выбрать нужный комбинатор для конкретного сценария асинхронной координации.

collections

WeakMap и WeakSet нужны, когда ключи должен иметь право удалить сборщик мусора.

  • Они хранят слабые ссылки, поэтому объект удаляется, как только нет сильных ссылок.
  • Идеальны для метаданных о DOM-узлах или объектах без блокировки сборки мусора.
  • У них нет методов итерации, поэтому не подходят, когда нужно перебирать записи.

Зачем это спрашивают: Оценивает понимание управления памятью в долгоживущих одностраничных приложениях.

debouncethrottle

Debounce ждёт паузу, throttle ограничивает частоту; выбор зависит от события.

  • Debounce: срабатывает только после остановки вызовов на заданное время, идеален для поиска по мере ввода.
  • Throttle: срабатывает не чаще раза за интервал, идеален для обработчиков scroll или resize.
  • Debounce на scroll ощущается хуже throttle, потому что ничего не срабатывает во время прокрутки.

Зачем это спрашивают: Оценивает практическое знание паттернов производительности для высокочастотных браузерных событий.

javascriptmemoization

Мемоизация кэширует результат чистой функции по её аргументам, чтобы повторные вызовы возвращались мгновенно.

  • Реализуется через Map или объект-кэш в замыкании.
  • Главный компромисс: память растёт с числом уникальных комбинаций аргументов и может течь при объектных ключах.
  • В React useMemo и useCallback встроены, но добавляют накладные расходы при частой смене зависимостей.

Зачем это спрашивают: Проверяет умение соотносить пользу оптимизации производительности с затратами памяти.

thisfunctions

Обычные функции получают свой this из места вызова, стрелочные наследуют его лексически.

  • Обычные: this зависит от способа вызова (метод, конструктор, call/apply или по умолчанию).
  • Стрелочные: захватывают this из объемлющей области в момент определения.
  • Поэтому стрелочные ненадёжны как методы объектов, но идеальны как коллбэки внутри методов класса.

Зачем это спрашивают: Частый источник багов в реальных кодовых базах; проверяет, может ли кандидат быстро диагностировать ошибки, связанные с this.

spread

Они различаются глубиной копирования и тем, что умеют сохранять.

  • Spread: поверхностная копия, дублируются только ссылки верхнего уровня.
  • JSON.parse(JSON.stringify()): глубокая копия, но теряет функции, превращает Date в строки, удаляет undefined, падает на циклах.
  • structuredClone: настоящая глубокая копия с Date, типизированными массивами и циклами, но без функций и DOM-узлов.

Зачем это спрашивают: Проверяет знание ловушек, вызывающих тонкие баги при работе с вложенным состоянием или сложными структурами данных.

async

async/await - синтаксический сахар над Promise.

  • Async-функция всегда возвращает Promise.
  • await приостанавливает функцию и уступает циклу событий до выполнения ожидаемого Promise, затем возобновляет работу.
  • Babel компилирует его в машину состояний с генераторной семантикой и цепочками .then().
  • await над не-Promise работает, потому что значение оборачивается в Promise.resolve().

Зачем это спрашивают: Убеждается, что кандидат понимает async/await как надстройку над Promise, предотвращая заблуждения о блокирующем поведении.

modules

Они различаются временем загрузки, структурой и семантикой связывания.

  • CommonJS: require/module.exports, синхронная загрузка, вычисление в рантайме, изменяемые экспорты.
  • ES-модули: import/export, статическая структура, анализируемая при парсинге, что позволяет tree shaking.
  • В браузере ES-модули всегда асинхронны; Node поддерживает оба.
  • Живые байндинги ES-модулей означают, что импорт отражает актуальное значение экспорта.

Зачем это спрашивают: Важно для понимания того, почему некоторые библиотеки не поддерживают tree shaking и почему смешивание модульных систем вызывает проблемы в бандлерах.

javascriptgenerators

Генератор использует function* и может приостанавливаться через yield, возвращая итератор.

  • Он выдаёт значения по требованию, не вычисляя всё наперёд.
  • Полезен для пагинации при бесконечном скролле.
  • Полезен для сложного асинхронного управления потоком в библиотеках вроде redux-saga.
  • Полезен для ленивых последовательностей.

Зачем это спрашивают: Проверяет глубину знания JavaScript; генераторы - нишевый, но мощный инструмент, отличающий кандидатов с широкими знаниями от тех, кто использует только распространённые паттерны.

memory

Находите утечку снимками кучи, затем чините источник, удерживающий ссылки живыми.

  • Частые причины: глобальные слушатели, которые не удаляются; замыкания с большими данными в области модуля; неотменённые подписки при размонтировании.
  • Обнаружение: делайте снимки кучи во вкладке Memory Chrome DevTools до и после навигации, сравнивайте удержанные размеры.
  • Исправление: удаляйте слушателей в cleanup-функциях, используйте WeakMap для метаданных, отписывайтесь от WebSocket и Observable при размонтировании.

Зачем это спрашивают: Оценивает навык продакшн-отладки и знание специфических для долгоживущих SPA проблем с памятью.

scope

Временная мёртвая зона - это промежуток между входом в область видимости и достижением объявления let или const.

  • Обращение к переменной в её TDZ бросает ReferenceError, хотя она уже существует в области.
  • Это отличается от var, которая поднимается и инициализируется значением undefined.
  • Ошибки TDZ возникают в инициализаторах полей класса и при чтении переменной до её объявления.

Зачем это спрашивают: Отличает кандидатов с глубоким пониманием механики hoisting от тех, кто просто знает, что let и const ведут себя иначе, чем var.

reactalgorithms

React сравнивает старое и новое виртуальные DOM-деревья (diffing), чтобы решить, что перерендерить.

  • Предполагается, что элементы разных типов дают разные деревья, а совпадающие поддеревья пропускаются.
  • Проп key сигнализирует об идентичности элемента между рендерами, поэтому DOM-узел переиспользуется при смене позиции в списке.
  • Без правильных ключей React может уничтожать и пересоздавать дорогие компоненты, теряя производительность и локальное состояние.

Зачем это спрашивают: Фундаментально для понимания производительности React; кандидат с этим знанием может диагностировать большинство багов с лишними ре-рендерами.

react

useCallback мемоизирует ссылку на функцию, useMemo - вычисленное значение.

  • useCallback: сохраняет стабильную ссылку на функцию, чтобы мемоизированные дети не ре-рендерились зря.
  • useMemo: избегает дорогих пересчётов при каждом рендере.
  • useCallback - для стабильных пропсов мемоизированным детям; useMemo - для дорогих вычислений.
  • Оба часто используют избыточно, добавляя накладные расходы при частой смене зависимостей.

Зачем это спрашивают: Проверяет суждение о том, когда мемоизация реально помогает, а не просто знание существования этих хуков.

reactcomponentsforms

Управляемый компонент ведётся состоянием React, неуправляемый хранит своё значение через ref.

  • Управляемый: значение из состояния плюс обработчик onChange, поэтому React - источник истины.
  • Неуправляемый: состояние живёт в DOM, читается через inputRef.current.value.
  • Управляемый подходит для валидации, условного рендеринга и синхронизации нескольких полей.
  • Неуправляемый проще для file-инпутов или сторонних DOM-библиотек.

Зачем это спрашивают: Выявляет понимание потока данных и обработки форм - одного из наиболее частых источников багов в React-приложениях.

hooks

Хуки должны вызываться на верхнем уровне React-функции, в одинаковом порядке при каждом рендере.

  • Не вызывайте их внутри циклов, условий или вложенных функций.
  • Вызывайте их только из React-компонентов или кастомных хуков, не из обычного JavaScript.
  • React сопоставляет каждый хук с его состоянием по порядку вызова; нарушение порядка путает состояние.

Зачем это спрашивают: Понимание причин правил предотвращает трудно диагностируемые баги, вызванные условными вызовами хуков.

react

React.memo пропускает ре-рендер компонента, когда его пропсы поверхностно равны.

  • Он не помогает, когда пропсы - объекты или функции, пересоздаваемые при каждом рендере родителя.
  • Поверхностное сравнение видит эти новые ссылки как изменённые.
  • Сочетайте его с useCallback и useMemo в родителе, чтобы оптимизация работала.
  • Накладные расходы сравнения напрасны, если компонент и так дёшев в рендеринге.

Зачем это спрашивают: Проверяет, умеет ли кандидат определять, когда мемоизация контрпродуктивна, а не применяет её вслепую.

Закрытые вопросы

  • 21

    Как работают error boundaries в React и что они не перехватывают?

    react
  • 22

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

    reactperformance
  • 23

    Когда предпочесть useReducer вместо useState?

    hooks
  • 24

    Что такое React.lazy и как Suspense поддерживает разделение кода?

    react
  • 25

    Что изменилось в батчинге состояния в React 18?

    reactbatch
  • 26

    Почему использование индекса массива в качестве пропа key в списке проблематично?

    indexes
  • 27

    Как реализовать виртуализацию для длинного списка и когда она необходима?

    virtualization
  • 28

    Для чего нужна функция очистки useEffect и чем она отличается от componentWillUnmount?

    componentshooks
  • 29

    Что такое React.forwardRef и когда он нужен?

    react
  • 30

    Как диагностировать медленный рендер с помощью React DevTools Profiler?

    react
  • 31

    Что такое паттерн составного компонента (Compound Component) и какую проблему он решает?

    components
  • 32

    Как расшарить состояние между двумя компонентами-сиблингами, не имеющими близкого общего родителя?

    components
  • 33

    Как возникают устаревшие замыкания в useEffect и как их исправить?

    hooksclosures
  • 34

    Что такое конкурентный рендеринг в React 18 и как он меняет поведение UI?

    reactconcurrency
  • 35

    Что такое паттерн render props и как он соотносится с кастомными хуками?

    hooks
  • 36

    В чём разница между interface и type alias в TypeScript и когда что выбирать?

    typescripttypes
  • 37

    Как использовать дженерики в React-компоненте, чтобы он работал с разными типами данных?

    reactcomponentsgenerics
  • 38

    Что такое условные типы в TypeScript и каков практический пример?

    typescript
  • 39

    Что такое ключевое слово infer в TypeScript и как его использовать?

    typescript
  • 40

    Что такое сужение типов (type narrowing) в TypeScript и какие техники можно применять?

    typescript
  • 41

    Что такое дискриминированные объединения в TypeScript и почему они полезны?

    typescript
  • 42

    Как добавить типы для сторонней JavaScript-библиотеки без TypeScript-определений?

    typescriptjavascript
  • 43

    Как написать перегрузку функции в TypeScript для разных комбинаций аргументов?

    typescript
  • 44

    Когда использовать CSS Grid, а когда Flexbox?

    cssflexboxgrid
  • 45

    Как работает специфичность CSS и как разрешать конфликты, не прибегая к !important?

    css
  • 46

    Что такое CSS-кастомные свойства и чем они отличаются от переменных Sass или Less?

    css
  • 47

    Что такое контекст наложения CSS (stacking context) и почему он влияет на z-index?

    cssindexes
  • 48

    В чём разница между единицами em, rem, vh, vw и ch и когда применять каждую?

    css
  • 49

    Как построить адаптивный макет без медиазапросов, используя современный CSS?

    cssresponsivequeries
  • 50

    Как на практике предотвращать смещение макета (Cumulative Layout Shift)?

    web-vitals
  • 51

    Что такое CSS containment и когда его стоит применять?

    css
  • 52

    Что такое Core Web Vitals и как их измерять в продакшне?

    web-vitals
  • 53

    Какие стратегии вы используете для уменьшения размера JavaScript-бандла?

    bundle-sizejavascript
  • 54

    Как работает tree shaking и каковы типичные причины его неэффективности?

    tree-shaking
  • 55

    В чём разница между Webpack и Vite при разработке и почему Vite быстрее?

    webpackvite
  • 56

    Что такое Hot Module Replacement и как он сохраняет состояние компонента?

    componentshmr
  • 57

    Как работают source maps и когда их следует включать в продакшне?

    source-maps
  • 58

    Как анализировать frontend-бандл для поиска узких мест производительности?

    performance
  • 59

    В чём разница между линтером и форматером и как они дополняют друг друга?

    linting
  • 60

    Как безопасно настроить переменные окружения в frontend-сборке?

    soft-skillsconfig
  • 61

    Что такое разделение кода (code splitting) и как его реализовать в React-приложении?

    react
  • 62

    Как работает кэширование браузера и как гарантировать, что пользователи получат последний код после деплоя?

    cachingdeployment
  • 63

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

    images
  • 64

    Как оптимизировать веб-шрифты для снижения смещения макета и блокировки рендеринга?

    optimizationweb-vitals
  • 65

    В чём разница между SSR, SSG, CSR и ISR и когда выбирать каждый подход?

    ssr
  • 66

    В чём разница между unit-, integration- и end-to-end-тестами во фронтенд-разработке?

    e2e
  • 67

    Как тестировать React-компонент, выполняющий API-запросы, без обращения к реальному серверу?

    reactcomponentsapi
  • 68

    Как тестировать кастомные React-хуки?

    reacthooks
  • 69

    Что означает «тестировать поведение, а не реализацию» и как это применять на практике?

  • 70

    Когда snapshot-тестирование полезно, а когда становится проблемой?

    snapshot
  • 71

    Что такое визуальное регрессионное тестирование и какие инструменты его поддерживают?

    visual
  • 72

    Как обрабатывать асинхронные обновления состояния в тестах, чтобы избежать нестабильных утверждений?

    soft-skillsasynctesting
  • 73

    Что такое архитектура Flux и как Redux её реализует?

    statearchitecture
  • 74

    Каковы компромиссы между Redux Toolkit, Zustand и React Query для управления состоянием?

    reactstatequeries
  • 75

    В чём разница между серверным состоянием и UI-состоянием и почему их нужно управлять отдельно?

    state
  • 76

    Как реализовать оптимистичные обновления UI?

    locking
  • 77

    Что такое prop drilling и какие существуют решения?

    state
  • 78

    Как сохранять состояние между перезагрузками страницы?

    state
  • 79

    Как проектировать масштабируемую структуру папок для большого React-приложения?

    designstructurereact
  • 80

    Что такое дизайн-система и что она включает помимо библиотеки компонентов?

    componentsdesign-systemsystem-design
  • 81

    Что такое паттерн BFF (Backend for Frontend) и когда он полезен?

  • 82

    Когда стоит рассматривать микрофронтенды и каковы основные компромиссы?

    micro-frontends
  • 83

    Как управлять ломающими изменениями API на фронтенде при эволюции бэкенда?

    api
  • 84

    Как диагностировать компонент, который ре-рендерится чаще, чем ожидается?

    components
  • 85

    Как отладить утечку памяти в React-приложении?

    memoryreact
  • 86

    Регрессия производительности появилась в продакшне, но не воспроизводится локально. Как вы будете расследовать?

    performance
  • 87

    API-вызов нестабильно падает в продакшне, но стабильно работает в разработке. Как вы расследуете?

    api
  • 88

    CSS работает в Chrome, но ломается в Safari. Как вы подходите к отладке?

    css
  • 89

    Как отладить ошибку несовпадения гидратации в серверном React-приложении?

    reacthydration
  • 90

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

    javascript
  • 91

    В чём разница между ARIA-ролями и нативными HTML-семантическими элементами для доступности?

    htmla11y
  • 92

    Как обеспечить корректную навигацию с клавиатуры внутри модального диалога?

    a11y
  • 93

    Что такое коэффициент контрастности цвета и как проверить соответствие стандартам WCAG?

    a11y
  • 94

    Как сделать динамически обновляемую область контента доступной для скринридеров?

    a11y
  • 95

    Как реализовать полностью доступный кастомный компонент выпадающего списка?

    components
  • 96

    Расскажите, как вы выявили и устранили значительную проблему производительности в продакшн-приложении.

    performance
  • 97

    Как вы подходите к задаче, где требования неясны или противоречат друг другу?

    soft-skills
  • 98

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

    soft-skillsconflictfeedback
  • 99

    Как вы подходите к рефакторингу крупного легаси-компонента без нарушения существующего поведения?

    refactoringcomponents
  • 100

    Как вы следите за быстро меняющейся экосистемой фронтенда, не тратя на это всё своё время?

    learning