Как пройти собеседование по JavaScript: топ вопросов от А до Я
Собеседование на позицию JavaScript-разработчика — это не просто проверка синтаксиса. Работодатели хотят видеть глубокое понимание языка, его особенностей и умение работать с асинхронностью. В этой статье мы разберем ключевые темы, которые помогут вам уверенно пройти интервью. Мы рассмотрим вопросы от базовых концепций до продвинутых тем Node.js с реальными примерами кода.
1. Основы: типы данных, hoisting и области видимости
Начнем с фундамента. JavaScript — язык с динамической типизацией. Понимание var, let и const — обязательный минимум.
Вопрос: Чем отличается var от let и const?
varимеет функциональную область видимости и всплывает (hoisting) со значениемundefined.letиconstимеют блочную область видимости и не инициализируются до объявления (Temporal Dead Zone).constзапрещает переприсваивание, но не делает объект неизменяемым.
Пример hoisting:
console.log(a); // undefined (hoisting)
var a = 5;
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
Вопрос: Что такое «всплытие» (hoisting)?
Это механизм, при котором объявления переменных и функций перемещаются в начало своей области видимости до выполнения кода. Функции, объявленные через function, всплывают целиком, а переменные — только объявление, но не инициализация.
2. Замыкания и контекст (this)
Замыкания — одна из самых сильных сторон JavaScript. Они позволяют функции запоминать лексическое окружение, в котором были созданы.
Вопрос: Что такое замыкание? Приведите пример.
Замыкание — это комбинация функции и её лексического окружения. Другими словами, внутренняя функция имеет доступ к переменным внешней функции даже после того, как внешняя завершила работу.
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
Вопрос: Как работает this в JavaScript?
Значение this определяется тем, как вызвана функция, а не где она объявлена. Основные правила:
- В глобальном контексте (в браузере) —
window, в Node.js —global. - В методе объекта — сам объект.
- В функции, вызванной через
new— новый экземпляр. - При использовании
call,apply,bind— переданный объект. - В стрелочных функциях —
thisберется из внешнего лексического контекста.
const obj = {
name: 'Alice',
greet() {
console.log(this.name);
}
};
const greet = obj.greet;
greet(); // undefined (потеря контекста)
const boundGreet = obj.greet.bind(obj);
boundGreet(); // Alice
3. Асинхронность: Event Loop, промисы и async/await
JavaScript — однопоточный язык, но он эффективно обрабатывает асинхронные операции благодаря Event Loop. Это одна из самых популярных тем на собеседованиях.
Вопрос: Что такое Event Loop и как он работает?
Event Loop — это бесконечный цикл, который следит за стеком вызовов (Call Stack) и очередями задач (Task Queue / Microtask Queue). Если стек пуст, он берет первую задачу из очереди микротасок (Promise, MutationObserver) или макротасок (setTimeout, I/O).
Вопрос: В чем разница между микро- и макрозадачами?
- Микрозадачи: Promise.then/catch/finally, queueMicrotask, MutationObserver. Выполняются сразу после завершения текущего стека.
- Макрозадачи: setTimeout, setInterval, I/O, UI rendering. Выполняются после очистки очереди микрозадач.
Пример с очередью:
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// Вывод: 1, 4, 3, 2
Вопрос: Как работают промисы и async/await в Node.js?
Промис — это объект, представляющий результат асинхронной операции. Он может быть в состоянии pending, fulfilled или rejected. async/await — это синтаксический сахар над промисами, позволяющий писать асинхронный код в синхронном стиле.
// Промис
function fetchData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url) {
resolve({ data: 'success' });
} else {
reject(new Error('URL is required'));
}
}, 1000);
});
}
// async/await
async function getData() {
try {
const result = await fetchData('https://api.example.com');
console.log(result.data); // success
} catch (error) {
console.error(error.message);
}
}
getData();
4. Продвинутые темы для Node.js
Если вы проходите собеседование на позицию Node.js разработчика, нужно знать его особенности.
Вопрос: Что такое EventEmitter в Node.js?
EventEmitter — это базовый класс для работы с событиями. Он позволяет подписываться на события и генерировать их. Многие объекты в Node.js (например, HTTP-сервер, потоки) наследуют от него.
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (data) => {
console.log('Event fired with:', data);
});
myEmitter.emit('event', { key: 'value' });
Вопрос: Как обрабатывать ошибки в асинхронных функциях Node.js?
Лучшая практика — использовать async/await с try/catch или явные промисы с
Блоги
Рекомендаций по книгам
Читайте также
GraphQL API на C++: пошаговый туториал с практическими примерами
Массив в список в Java: 5 способов и подводные камни
JavaScript vs Python: что выбрать для бэкенда? Практическое сравнение на Node.js
Управление памятью в TypeScript: как работает сборщик мусора
Кэширование в TypeScript: Redis, Memcached и встроенные решения от А до Я