Частые вопросы на интервью

Зачем нужно

Это шпаргалка с топ-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 вопросов

Практика

  1. Ответь на все 30 вопросов устно (засеки время)
  2. Напиши код для каждого JS-вопроса без подглядывания
  3. Объясни Event Loop другу/маме простыми словами
  4. Проведи mock-интервью с партнёром по RS School
  5. Разбери 5 вопросов, на которые не смог ответить

Связанные темы

Ресурсы