Частые вопросы на интервью
Зачем нужно
Это шпаргалка с топ-30 вопросами, которые задают на собеседованиях для junior/middle frontend-разработчиков. Не зубри ответы — разберись в механизмах. Интервьюер всегда копнёт глубже.
Где используется
- Техническое собеседование — теоретическая часть
- Самопроверка — оценка готовности
- Повторение — структурированный обзор
JavaScript (15 вопросов)
1. Что такое замыкание (closure)?
function createCounter() {
let count = 0; // эта переменная «замкнута»
return function {
count++;
return count;
};
}
const counter = createCounter;
counter; // 1
counter; // 2
counter; // 3
// Внутренняя функция имеет доступ к переменным
// внешней функции даже после её завершения.
2. Что такое this? Как определяется?
// 1. Глобальный контекст → window (или undefined в strict)
// 2. Метод объекта → сам объект
// 3. call/apply/bind → явно указанный объект
// 4. new → новый объект
// 5. Arrow function → this из внешнего контекста (лексический)
const obj = {
name: 'Alice',
greet { return this.name; }, // 'Alice'
greetArrow: => this.name, // undefined (window)
};
3. Прототипное наследование
// Каждый объект имеет [[Прототипы]]
// Если свойство не найдено → поиск по цепочке прототипов
const animal = { eat { return 'eating'; } };
const dog = Object.create(animal);
dog.bark = function { return 'woof'; };
dog.bark; // 'woof' — собственное свойство
dog.eat; // 'eating' — найдено в прототипе
4. Event Loop — как работает?
Call Stack Web APIs Callback Queue
────────── ───────── ──────────────
│ main │ → │setTimeout│ → │ callback │
│ │ │fetch │ │ callback │
└─────────┘ └─────────┘ └────────────┘
│
◀── Event Loop проверяет ─────┘
(стек пуст? → берём из очереди)
Microtasks (Promise.then) выполняются ПЕРЕД macrotasks (setTimeout).
5. Promise — что это?
// Promise — объект для работы с асинхронными операциями
// Три состояния: pending → fulfilled / rejected
const fetchUser = (id) =>
new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) resolve({ id, name: 'User' });
else reject(new Error('Invalid ID'));
}, 100);
});
// Использование
fetchUser(1)
.then((user) => console.log(user))
.catch((err) => console.error(err));
// async/await
async function getUser() {
try {
const user = await fetchUser(1);
console.log(user);
} catch (err) {
console.error(err);
}
}
6. var vs let vs const
// var: function-scoped, hoisting (поднятие с undefined)
// let: block-scoped, TDZ (temporal dead zone)
// const: block-scoped, TDZ, нельзя переприсвоить
for (var i = 0; i < 3; i++) {
setTimeout( => console.log(i)); // 3, 3, 3
}
for (let j = 0; j < 3; j++) {
setTimeout( => console.log(j)); // 0, 1, 2
}
7. Spread и Rest операторы
// Spread — разворачивает
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4]
const obj2 = { ...obj1, key: 'new' }; // копия + перезапись
// Rest — собирает
function sum(...nums) { return nums.reduce((a, b) => a + b, 0); }
const { a, ...rest } = { a: 1, b: 2, c: 3 }; // rest = { b: 2, c: 3 }
8. Деструктуризация
const { name, age = 25 } = user;
const [first, , third] = [1, 2, 3]; // first=1, third=3
const { address: { city } } = user; // вложенная
9. Map, Set, WeakMap, WeakSet
// Map — ключ любого типа
const map = new Map();
map.set(obj, 'value');
// Set — уникальные значения
const unique = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]
// WeakMap/WeakSet — ключи = объекты, GC может удалить
10. Методы массивов (map, filter, reduce)
const nums = [1, 2, 3, 4, 5];
nums.map((n) => n * 2); // [2, 4, 6, 8, 10]
nums.filter((n) => n > 3); // [4, 5]
nums.reduce((sum, n) => sum + n, 0); // 15
nums.find((n) => n > 3); // 4
nums.some((n) => n > 4); // true
nums.every((n) => n > 0); // true
11. Что такое hoisting?
// Объявления «поднимаются» в начало scope
console.log(a); // undefined (var поднят, но не инициализирован)
var a = 5;
console.log(b); // ReferenceError (TDZ)
let b = 5;
hello; // работает (function declaration поднимается полностью)
function hello() { return 'hi'; }
12. Разница == и ===
// == — с приведением типов (не используй)
1 == '1'; // true
0 == false; // true
null == undefined; // true
// === — строгое сравнение (всегда используй)
1 === '1'; // false
0 === false; // false
13. Event Delegation
// Вместо обработчика на каждом элементе —
// один обработчик на родителе
document.querySelector('.list').addEventListener('click', (e) => {
if (e.target.matches('.item')) {
console.log('Clicked:', e.target.textContent);
}
});
// Работает для динамически добавленных элементов
14. Shallow vs Deep Copy
// Shallow copy — копирует только первый уровень
const shallow = { ...original };
const shallowArr = [...arr];
// Deep copy — копирует все уровни
const deep = structuredClone(original); // современный способ
const deep2 = JSON.parse(JSON.stringify(original)); // старый (с ограничениями)
15. Модули (import/export)
// Named export
export const PI = 3.14;
export function sum(a, b) { return a + b; }
// Default export
export default class Calculator { }
// Import
import Calculator, { PI, sum } from './math.js';
CSS (8 вопросов)
16. Специфичность (specificity)
Inline styles → 1,0,0,0
#id → 0,1,0,0
.class, [attr], :pseudo → 0,0,1,0
element, ::pseudo → 0,0,0,1
Пример:
div.card → 0,0,1,1
#main .card → 0,1,1,0
div#main .card a → 0,1,1,2
17. БЭМ (Block Element Modifier)
/* Block */
.card { }
/* Element */
.card__title { }
.card__image { }
/* Modifier */
.card--highlighted { }
.card__title--large { }
18. Flexbox vs Grid
Flexbox — одномерный (строка ИЛИ колонка)
Grid — двумерный (строки И колонки одновременно)
Flexbox: навигация, карточки в ряд, выравнивание
Grid: вся страница, сложные сетки, dashboard
19. Позиционирование (position)
/* static — по умолчанию, в потоке */
/* relative — смещение от своего места, остаётся в потоке */
/* absolute — относительно ближайшего positioned предка */
/* fixed — относительно viewport */
/* sticky — relative → fixed при скролле */
20. Box Model
┌────────────────────────────────────┐
│ margin │
│ ┌──────────────────────────────┐ │
│ │ border │ │
│ │ ┌────────────────────────┐ │ │
│ │ │ padding │ │ │
│ │ │ ┌──────────────────┐ │ │ │
│ │ │ │ content │ │ │ │
│ │ │ └──────────────────┘ │ │ │
│ │ └────────────────────────┘ │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘
box-sizing: content-box (default) — width = только content
box-sizing: border-box — width = content + padding + border
21. Адаптивность (responsive)
/* Mobile-first подход */
.container { width: 100%; }
@media (min-width: 768px) {
.container { width: 750px; }
}
@media (min-width: 1024px) {
.container { width: 970px; }
}
22. CSS-переменные
:root {
--primary: #3498db;
--spacing: 16px;
}
.button {
background: var(--primary);
padding: var(--spacing);
}
23. z-index и stacking context
z-index работает только на positioned элементах (не static).
Новый stacking context создаётся при:
- position + z-index
- opacity < 1
- transform
- isolation: isolate
HTML (4 вопроса)
24. Семантические теги
<!-- Структурные -->
<header>, <nav>, <main>, <aside>, <footer>, <section>, <article>
<!-- Текстовые -->
<h1>-<h6>, <p>, <blockquote>, <figure>, <figcaption>, <time>
<!-- Зачем: SEO, доступность, читаемость кода -->
25. Accessibility (доступность)
<!-- alt для изображений -->
<img src="logo.png" alt="Company Logo" />
<!-- label для форм -->
<label for="email">Email:</label>
<input id="email" type="email" />
<!-- aria-атрибуты -->
<button aria-label="Close menu" aria-expanded="false">X</button>
<!-- Роли -->
<div role="navigation" aria-label="Main menu">...</div>
26. meta-теги
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Page description for SEO" />
27. Формы
<form action="/submit" method="POST">
<input type="text" name="name" required minlength="2" />
<input type="email" name="email" required />
<input type="number" name="age" min="18" max="99" />
<select name="country">
<option value="ru">Russia</option>
</select>
<button type="submit">Send</button>
</form>
General (3 вопроса)
28. HTTP-методы и коды
GET — получить данные
POST — создать ресурс
PUT — заменить ресурс целиком
PATCH — частичное обновление
DELETE — удалить
200 OK — успех
201 Created — ресурс создан
301 Moved — постоянный редирект
400 Bad Request — ошибка в запросе
401 Unauthorized— не авторизован
403 Forbidden — нет прав
404 Not Found — не найдено
500 Server Error— ошибка сервера
29. REST API
RESTful URL:
GET /api/users — список пользователей
GET /api/users/123 — один пользователь
POST /api/users — создать
PUT /api/users/123 — обновить
DELETE /api/users/123 — удалить
Принципы: stateless, uniform interface, resource-based URLs
30. Git — основы
git branch feature # создать ветку
git checkout feature # переключиться
git merge feature # слить в текущую
git rebase main # перебазировать на main
merge — создаёт merge-коммит, сохраняет историю
rebase — линейная история, переписывает коммиты
Частые ошибки
| Ошибка | Проблема | Решение |
|---|---|---|
| Зубрёжка ответов | Не может объяснить | Разберись в механизме |
| Не знает Event Loop | Не понимает асинхронность | Изучи визуально (Loupe) |
| Путает == и === | Баги с типами | Всегда используй === |
| Не знает Box Model | Неправильные размеры | Попрактикуй в DevTools |
| Не готовил вопросы | Выглядит незаинтересованным | Подготовь 3-5 вопросов |
Практика
- Ответь на все 30 вопросов устно (засеки время)
- Напиши код для каждого JS-вопроса без подглядывания
- Объясни Event Loop другу/маме простыми словами
- Проведи mock-интервью с партнёром по RS School
- Разбери 5 вопросов, на которые не смог ответить
Связанные темы
- Подготовка к собеседованию — общая подготовка
- Резюме разработчика — оформление CV
- Code Review — навык CR