Вопросы для собеседования Frontend ( React ) Middle+ | Senior в 2024

Никита Калашников
Скилы Frontend-разработчика
Минимальный набор hard-скилов и технологий, с которыми должен быть знаком специалист ( набор может меняться от вакансии к вакансии )
- Javascript
- Typescript
- React / Angular / Vue ( или любой другой frontend фреймворк | библиотека )
- Styled-component, css-inline, Sass
- Redux / Redux-toolkit / Redux-Saga
- RTK Query
- Git ( или опыт с любым другим удаленным репозиторием )
- Архитектура ( Знание основных. Опыт выбора и внедрения под проект )
- Yarn / Npm
- Next.js | Vite.js
- Webpack / Rollup / Vite
- Css + Html ( верстка, семантика, адаптация, базовая оптимизация )
- Scss, Less ( и любые другие препроцессоры )
- CI/CD
- Scum / Agile
- Node.js
- Figma ( или любой другой сервис для работы с дизайном / wireframe )
Общие вопросы
- Event loop - Что это, как работает, частью какого механизма является, сколько очередей и т.д. ( важно понимать весь процесс )
- Dom и Виртуальный DOM - Что такое Dom, как формируется и в чем отличие от Виртуального Dom ( Виртуальный DOM является частью фреймворков )
- Как работает браузер
- Что происходит при вводе запроса в поисковую строку
- В чем разница между " == " и " === "?
- Паттерны программирования
- Архитектурные решения - Какие знаете, в чем отличия, как выбирать правильный для проекта
- Принципы Solid - Что такое принципы разработки Solid
- Принцип kiss, dry
- API, Rest API - Что это, в чем разница
- CI / CD - Что это и как работает
Вопросы по Javascript
Оставляю основные вопросы, которые не только встречаются чаще всего, но и действительно необходимы для frontend-разработчика на практике
1. Big O Notation — Нотация для описания сложности алгоритмов ( помогает правильно выбирать методы работы с данными, выбирая наиболее оптимальный для экономии ресурсов )
2. Словари ( Set, Map ) — Set
хранит уникальные значения любого типа, Map
хранит пары ключ-значение. В Set
значение может появляться только один раз, в Map
ключи могут быть любого типа.
3. Чистые функции — Чистые функции всегда возвращают один и тот же результат при одинаковых аргументах и не имеют побочных эффектов.
Пример:
1function add(a, b) {
2 return a + b;
3}
4. Async/Await — async
/await
используются для работы с промисами. Функция, объявленная с async
, возвращает промис, await
приостанавливает выполнение до разрешения промиса.
Например:
1async function fetchData() {
2 const response = await fetch('https://api.example.com/data');
3 const data = await response.json();
4 return data;
5}
5. Promise — Promise
представляет результат асинхронной операции и может находиться в одном из состояний: ожидание, выполнено или отклонено.
Например:
1let promise = new Promise((resolve, reject) => {
2 setTimeout(() => resolve("Done!"), 1000);
3});
4promise.then(result => console.log(result));
6. Область видимости — Область видимости определяет видимость переменных и функций в разных частях кода. Существует глобальная и локальная (функциональная, блочная) область видимости.
Например:
1function example() {
2 let local = "local";
3 console.log(local);
4}
7. Замыкания — это функции, которые запоминают своё окружение при создании.
Например:
1function outer() {
2 let count = 0;
3 return function inner() {
4 count++;
5 return count;
6 }
7}
8const counter = outer();
9console.log(counter()); // 1
10console.log(counter()); // 2
8. Нововведения в ES6
ES6 ввел новые возможности, такие как стрелочные функции, let
и const
, шаблонные строки, деструктуризация, классы и модули.
9. Стрелочные функции — Стрелочные функции имеют краткий синтаксис и не имеют собственного this
.
Например:
1const add = (a, b) => a + b;
10. Отличие стрелочных функций от обычных
1. Синтаксис
Обычные функции
1function myFunction() {
2 // тело функции
3}
Стрелочные функции
1const myFunction = () => {
2 // тело функции
3}
2. Контекст (this)
- В обычных функциях
this
определяется в момент вызова функции и может изменяться в зависимости от контекста вызова (например, при использованииcall
,apply
илиbind
). - В стрелочных функциях
this
лексически привязан к контексту, в котором была объявлена функция, и не изменяется.
3. Аргументы
- В обычных функциях доступен объект
arguments
, который содержит все переданные аргументы. - В стрелочных функциях объекта
arguments
нет, но можно использовать операторы rest (...args
).
4. Конструктор
- Обычные функции могут быть использованы как конструкторы (с ключевым словом
new
), создавая новые объекты. - Стрелочные функции не могут быть использованы как конструкторы и вызов с
new
приведет к ошибке.
5. Собственные методы и свойства
- Обычные функции имеют свои собственные методы и свойства (например,
prototype
). - Стрелочные функции не имеют собственных методов и свойств.
Пример:
1function RegularFunction() {
2 this.value = 1;
3 setTimeout(function() {
4 console.log(this.value); // undefined, так как `this` указывает на глобальный объект или `undefined` в строгом режиме
5 }, 1000);
6}
7
8const ArrowFunction = () => {
9 this.value = 1;
10 setTimeout(() => {
11 console.log(this.value); // 1, так как `this` лексически привязан к контексту объявлении функции
12 }, 1000);
13}
14
15const regularFunc = new RegularFunction();
16const arrowFunc = ArrowFunction();
11. Анонимные функции — Анонимные функции не имеют имени и часто используются как аргументы для других функций.
Например:
1setTimeout(function() {
2 console.log("Hello, world!");
3}, 1000);
12. Основные типы данных в JS
В JavaScript существуют примитивные типы данных: string
, number
, boolean
, null
, undefined
, symbol
, и bigint
. Также есть сложные типы: object
и function
.
13. JS компилируемый или интерпретируемый язык
JavaScript является интерпретируемым языком, выполняемым браузером или сервером (Node.js) непосредственно.
14. Каррирование — это трансформация функции с множеством аргументов в последовательность функций с одним аргументом.
Например:
1function add(a) {
2 return function(b) {
3 return a + b;
4 }
5}
6const addFive = add(5);
7console.log(addFive(3)); // 8
15. Разница null и undefined
null
— это намеренное отсутствие значения, undefined
означает, что значение не было присвоено.
Например:
1let a;
2console.log(a); // undefined
3let b = null;
4console.log(b); // null
16. Объекты — это коллекции пар ключ-значение.
Пример:
1const person = {
2 name: "John",
3 age: 30
4};
Вопросы по React
1. Функция высшего порядка
Функция высшего порядка — это функция, которая принимает другую функцию в качестве аргумента или возвращает функцию в качестве результата. В JavaScript функции высшего порядка используются для создания абстракций и для управления поведением других функций.
Пример:
1// Функция высшего порядка, принимающая функцию в качестве аргумента
2function higherOrderFunction(callback) {
3 const result = callback(5);
4 console.log(result);
5}
6
7// Функция, передаваемая в качестве аргумента
8function multiplyByTwo(num) {
9 return num * 2;
10}
11
12// Вызов функции высшего порядка
13higherOrderFunction(multiplyByTwo); // Выведет: 10
2. Hook ( хуки )
Хуки (hooks) — это функции, которые позволяют использовать состояние и другие возможности React в функциональных компонентах. Хуки были введены в React версии 16.8. Основные хуки включают:
Основные хуки включают:
useState
useEffect
useContext
useReducer
useMemo
useCallback
useRef
useMemo
Возвращает мемоизированное значение. Он используется для оптимизации производительности, предотвращая повторные вычисления значений, которые зависят от входных данных.
Пример:
1import React, { useMemo } from 'react';
2
3function ExpensiveComponent({ a, b }) {
4 const result = useMemo(() => {
5 // Дорогая вычислительная операция
6 return a + b;
7 }, [a, b]);
8
9 return <div>{result}</div>;
10}
useState
Используется для добавления состояния в функциональные компоненты.
Пример:
1import React, { useState } from 'react';
2
3function Counter() {
4 const [count, setCount] = useState(0);
5
6 return (
7 <div>
8 <p>Вы нажали {count} раз</p>
9 <button onClick={() => setCount(count + 1)}>Нажми меня</button>
10 </div>
11 );
12}
useCallback
Возвращает мемоизированную версию коллбека, который изменяется только если изменяются зависимости.
1import React, { useCallback, useState } from 'react';
2
3function CallbackComponent() {
4 const [count, setCount] = useState(0);
5
6 const memoizedCallback = useCallback(() => {
7 console.log(count);
8 }, [count]);
9
10 return <button onClick={memoizedCallback}>Log Count</button>;
11}
useContext
Используется для доступа к контексту из функциональных компонентов.
1import React, { useContext, createContext } from 'react';
2
3const MyContext = createContext();
4
5function ContextComponent() {
6 const value = useContext(MyContext);
7
8 return <div>{value}</div>;
9}
10
11function App() {
12 return (
13 <MyContext.Provider value="Hello, world!">
14 <ContextComponent />
15 </MyContext.Provider>
16 );
17}
useEffect
Выполняет побочные эффекты в функциональных компонентах, такие как загрузка данных или изменение DOM.
1import React, { useEffect, useState } from 'react';
2
3function DataFetchingComponent() {
4 const [data, setData] = useState([]);
5
6 useEffect(() => {
7 fetch('https://api.example.com/data')
8 .then(response => response.json())
9 .then(data => setData(data));
10 }, []);
11
12 return (
13 <ul>
14 {data.map(item => (
15 <li key={item.id}>{item.name}</li>
16 ))}
17 </ul>
18 );
19}
useRef
Возвращает изменяемый объект, который сохраняет свое текущее значение между рендерингами. В отличие от useState
, изменение значения useRef
не вызывает повторный рендеринг компонента.
1import React, { useRef, useState } from 'react';
2
3function RefComponent() {
4 const inputRef = useRef(null);
5 const [value, setValue] = useState('');
6
7 const focusInput = () => {
8 inputRef.current.focus();
9 };
10
11 return (
12 <div>
13 <input ref={inputRef} value={value} onChange={e => setValue(e.target.value)} />
14 <button onClick={focusInput}>Focus Input</button>
15 </div>
16 );
17}
useReducer
Используется для управления более сложным состоянием в функциональных компонентах. Он принимает редьюсер и начальное состояние, возвращает текущее состояние и диспетчер для отправки действий.
1import React, { useReducer } from 'react';
2
3const initialState = { count: 0 };
4
5function reducer(state, action) {
6 switch (action.type) {
7 case 'increment':
8 return { count: state.count + 1 };
9 case 'decrement':
10 return { count: state.count - 1 };
11 default:
12 throw new Error();
13 }
14}
15
16function Counter() {
17 const [state, dispatch] = useReducer(reducer, initialState);
18
19 return (
20 <div>
21 <p>Счет: {state.count}</p>
22 <button onClick={() => dispatch({ type: 'increment' })}>+</button>
23 <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
24 </div>
25 );
26}
3. В чем разница между useMemo и useCallback?
useMemo
мемоизирует значение, тогда как useCallback
мемоизирует саму функцию. Оба они принимают массив зависимостей и обновляют мемоизированное значение или функцию только тогда, когда изменяются зависимости.
4. Состояние приложения
Состояние приложения (application state) — это данные, которые управляют поведением и рендерингом приложения. Хуки для работы с состоянием включают useState
и useReducer
. Популярные библиотеки для управления состоянием:
- Redux
- MobX
- Recoil
- Zustand
5. Redux / Redux-toolkit
Redux — это библиотека для управления состоянием приложений JavaScript. Redux-toolkit упрощает работу с Redux, предоставляя инструменты для упрощенного создания редьюсеров, экшенов и хранилищ.
Пример использования Redux-toolkit:
1import { configureStore, createSlice } from '@reduxjs/toolkit';
2
3const counterSlice = createSlice({
4 name: 'counter',
5 initialState: { count: 0 },
6 reducers: {
7 increment: state => { state.count += 1; },
8 decrement: state => { state.count -= 1; },
9 },
10});
11
12const store = configureStore({ reducer: counterSlice.reducer });
13
14store.dispatch(counterSlice.actions.increment());
15store.dispatch(counterSlice.actions.decrement());
16console.log(store.getState()); // { count: 0 }
6. Что такое reducer в Redux?
Редьюсер (reducer) — это функция, которая определяет, как состояние приложения изменяется в ответ на действия (actions). Он принимает текущее состояние и действие, возвращает новое состояние.
7. Стадии жизненного цикла компонента
Компоненты в React проходят следующие стадии жизненного цикла:
- Монтирование (Mounting):
componentDidMount
- Обновление (Updating):
componentDidUpdate
- Размонтирование (Unmounting):
componentWillUnmount
8. Чем управляемые компоненты отличаются от неуправляемых
Управляемые компоненты (controlled components) управляют своим состоянием через props и функции обратного вызова, тогда как неуправляемые компоненты (uncontrolled components) управляют своим состоянием через прямой доступ к DOM элементам, используя ref
.
9. Рендеринг списков, зачем нужны ключи ( key )
Ключи (keys) нужны для идентификации элементов списка. Они помогают React определять, какие элементы изменились, добавились или удалились, улучшая производительность при обновлении UI.
10. В чем разница между классовыми и функциональными компонентами?
Классовые компоненты используют классы для создания компонентов и поддерживают состояние и методы жизненного цикла через методы класса. Функциональные компоненты — это функции, которые принимают props и возвращают элементы React. С хуками функциональные компоненты могут иметь состояние и побочные эффекты.
11. Что такое реквизиты | пропсы в React?
Пропсы (props) — это входные данные, передаваемые компоненту, позволяющие ему получать информацию из родительского компонента.
12. Когда лучше использовать локальное состояние, а когда глобальное?
Локальное состояние используется для управления данными, которые нужны только в одном компоненте. Глобальное состояние используется для данных, которые должны быть доступны в нескольких компонентах.
13. Что такое условный рендеринг элементов?
Условный рендеринг позволяет отображать разные элементы в зависимости от условия.
Пример:
1import React from 'react';
2
3function Greeting({ isLoggedIn }) {
4 return (
5 <div>
6 {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}
7 </div>
8 );
9}
14. Что такое React.memo()
React.memo
— это HOC, который мемоизирует компонент, предотвращая его повторный рендеринг, если его props не изменились.
Пример:
1import React from 'react';
2
3const MyComponent = React.memo(function MyComponent({ value }) {
4 return <div>{value}</div>;
5});
15. Как получить доступ к элементу DOM?
Доступ к элементу DOM можно получить с использованием useRef
.
1import React, { useRef } from 'react';
2
3function TextInputWithFocusButton() {
4 const inputRef = useRef(null);
5
6 const onButtonClick = () => {
7 inputRef.current.focus();
8 };
9
10 return (
11 <div>
12 <input ref={inputRef} type="text" />
13 <button onClick={onButtonClick}>Focus the input</button>
14 </div>
15 );
16}
16. Что такое пользовательский хук?
Пользовательский хук — это функция, использующая хуки, чтобы инкапсулировать и переиспользовать логику состояния или побочных эффектов.
Пример:
1import { useState, useEffect } from 'react';
2
3function useWindowWidth() {
4 const [width, setWidth] = useState(window.innerWidth);
5
6 useEffect(() => {
7 const handleResize = () => setWidth(window.innerWidth);
8 window.addEventListener('resize', handleResize);
9 return () => window.removeEventListener('resize', handleResize);
10 }, []);
11
12 return width;
13}
17. SPA, SSR, SSG
SPA (Single Page Application) — одностраничное приложение, где всё приложение загружается одной HTML-страницей, и переходы между "страницами" осуществляются через JavaScript.
SSR (Server-Side Rendering) — рендеринг на стороне сервера, где HTML генерируется на сервере и отправляется клиенту для каждого запроса.
SSG (Static Site Generation) — статическая генерация сайта, где HTML генерируется на этапе сборки, а не на сервере или клиенте.
Различия:
- SPA имеет быстрые клиентские переходы, но может иметь более длительное начальное время загрузки.
- SSR позволяет быстро отображать контент для SEO и начальной загрузки, но может быть медленнее при каждом запросе.
- SSG обеспечивает очень быструю загрузку и рендеринг, так как страницы заранее генерируются и раздаются как статические файлы.
Soft-скилы
- Самостоятельное решение задач - Процесс поиска решения задачи, когда стоит идти к команде
- Умение выстраивать приоритетность задач - Как определить приоритетность задачи, как формировать порядок и т.д.
- Работа в команде / управление командой - Как строится, как происходит взаимодействие и т.д.
- Работа по метологиям Scrum / Agile - Что это такое, как внедрить и какой есть релевантный опыт
- Умение описывать проблемы и формировать отчеты - Что такое аудит, как проводить, зачем нужен
- Введение технической документации - Для чего нужна такая документация
- Чтение технической документации ( в том числе на английском ) - Есть ли релевантный опыт
- Wireframe - Что такое, для чего нужно проектирование и прототипирование интерфейсов
- Понимание приницпов дизайна ( как формируются отступы, группируются элементы, как правильно формировать ui-kit и как с ним работать ) - Что такое ui-kit, какие реальные проблемы работы с макетами от дизайнеров были
- Умение подбирать правильный технический стек - Какие основные принципы и вопросы нужно задавать, чтобы правильно подобрать стек