
Всем привет! Сейчас без live-coding'a никуда: на собеседованиях часто дают одну-две задачки, которые нужно решить за определённое время. Сами задачи могут быть несложными (не супер-пупер алгоритмическими), но новички могут переволноваться и не справиться с ними.
Поэтому в этой статье я хотел бы описать типовые задачи, которые встречаются в этой секции на позицию frontend или backend разработчика (если бэк на JS). Это поможет вам получить общее представление о том, что может ждать вас. Не забываем подписываться на мой канал в Telegram, там тоже есть, что почитать.
Поеееехалииии ?️?
Понимание JavaScript
Чтобы решать задачки, необходимо хорошо знать основы JS. Здесь я хочу выделить следующие темы:
Переменные, типы данных (особенно строки).
Простые операторы (+, -, *, /, %, >, < и тд) и побитовые (&, |, ~, <<, >>, >>>).
Условный оператор, циклы (особенно уметь использовать while и for.
Функции. Рекурсия - очень важная концепция. Иногда встречаются задачи, которые можно решить только с её помощью. Также не менее важно понимать замыкания, контекст выполнения и области видимости.
Структуры данных - массивы (80% задач), объекты/мапы/хэш-таблицы.
Регулярные выражения.
Как говорится это база. Идем дальше ?
Подходы к решению задач в секции live-coding
Рассмотри основной алгоритм решения задач:
Понимание задачи - убедитесь, что вы понимаете задачу, какие входные данные, ограничения. Если этого всего нет, задавайте вопросы, вас точно проверят на то, как вы собираете требования.
Планирование решения - быстро набросайте структуру решения вашей задачи, какой-то алгоритм. Обязательно проговаривайте свое решение, чтобы его слышали.
Решаем задачу в лоб, проверяем работает ли он на исходных данных. Если все ок, то только потом пытаемся ее оптимизировать.
Сразу подумайте о граничных тестах: пустые данные, большие объемы, минимальные и максимальные значения.
Опять тестируем - используйте предоставленные примеры, а также создавайте свои тестовые случаи.
Исправляем, рефакторим, тестируем.
Говорим, что готово.
Главное - не нервничать и задавать вопросы, если что-то остаётся непонятным. Кстати, это также поможет вам понять, сможете ли вы работать с этим человеком в будущем. Если на ваши вопросы следуют глубокие вздохи или полное молчание, это уже ред флаг.
В бой
Давайте перейдем к самому интересному - к задачкам. К каждой задаче я подготовил решение, но настоятельно советую сначала решить, а потом уже посмотреть решение. Весь исходный код будет расположен на GitHub (ссылка в конце статьи) и будет пополняться!
Простые задачи

Функция
sumRange
принимает два числаstart
иend
. Необходимо найти сумму всех чисел в заданном диапазоне.
// Тестовые данные
console.log(sumRange(1, 5)); // 15
console.log(sumRange(0, 10)); // 55
console.log(sumRange(-3, 3)); // 0
Напишите функцию, которая переворачивает цифры числа, сохраняя знак нетронутым.
// Тестовые данные
console.log(reverseNumber(123)); // 321
console.log(reverseNumber(-456)); // -654
console.log(reverseNumber(1000)); // 1
console.log(reverseNumber(0)); // 0
Напишите функцию, определяющую, является ли данное число полным квадратом.
// Тестовые данные
console.log(isPerfectSquare(16)); // true
console.log(isPerfectSquare(14)); // false
console.log(isPerfectSquare(0)); // true
console.log(isPerfectSquare(25)); // true
Массивы

Реализовать функцию
minMax()
, которая принимает массив и возвращает максимальное и минимальное значение. Решить нужно не используюMath.min()
иMath.max()
.
// Тестовые данные
console.log(findMinMax([4, 3, 5, 3, 2])); // {min: 2, max: 5}
console.log(findMinMax([4, 4, 7, 2, 1, 10])); // {min: 1, max: 10}
console.log(findMinMax([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); // {min: 1, max: 10}
Необходимо в массиве найти второе наибольшее число.
// Тестовые данные
console.log(secondLargest([10, 20, 4, 45, 99])); // 45
console.log(secondLargest([5, 5, 5])); // null
console.log(secondLargest([1])); // null
Напишите функцию, которая возвращает все пары чисел из массива, сумма которых равна заданной целевой сумме.
// Тестовые данные
console.log(findPairs([2, 4, 3, 7, 8, 1], 9)); // [[7, 2], [8, 1]]
console.log(findPairs([1, 2, 3, 4, 5], 10)); // []
console.log(findPairs([0, -1, -2, 2, 1], 0)); // [[-1, 1], [-2, 2]]
Строки

Проверить, является ли заданная строка палиндромом. Необходимо игнорировать символы пробела, знаков препинания и пр.
// Тестовые данные
console.log(isPalindrome("A man, a plan, a canal, Panama!")); // true
console.log(isPalindrome("No 'x' in Nixon")); // true
console.log(isPalindrome("Was it a car or a cat I saw?")); // true
console.log(isPalindrome("Eva, I see bees in a cave")); // false
Напишите функцию, проверяющую, являются ли две строки анаграммами друг друга (регистр букв не имеет значения)
// Тестовые данные
console.log(isAnagram("finder", "Friend")); // true
console.log(isAnagram("hello", "bye")); // false
console.log(isAnagram("listen", "silent")); // true
console.log(isAnagram("rail safety", "fairy tales"));
Напишите функцию для поиска первого неповторяющегося символа в строке. Возвращайте ноль (
null
), если все символы повторяются.
// Тестовые данные
console.log(firstNonRepeatingChar("swiss")); // "w"
console.log(firstNonRepeatingChar("aabbcc")); // null
console.log(firstNonRepeatingChar("javascript")); // "j"
Напишите функцию для подсчета количества гласных и согласных в строке.
// Тестовые данные
console.log(countVowelsAndConsonants("hello")); // { vowels: 2, consonants: 3 }
console.log(countVowelsAndConsonants("JavaScript")); // { vowels: 3, consonants: 7 }
console.log(countVowelsAndConsonants("12345")); // { vowels: 0, consonants: 0 }
Рекурсия

Напишите функцию, которая вычисляет факториал числа.
// Тестовые данные
console.log(factorial(0)); // 1
console.log(factorial(1)); // 1
console.log(factorial(2)); // 2
console.log(factorial(3)); // 6
Необходимо написать функцию которая превращает многомерный массив в одномерный.
// Тестовые данные
console.log(_flatten([1, 2, 3])); // [1, 2, 3]
console.log(_flatten([1, [2, 3], 4])); // [1, 2, 3, 4]
console.log(_flatten([[1, 2], [3, 4]])); // [1, 2, 3, 4]
console.log(_flatten([1, [2, [3, [4, 5]]]])); // [1, 2, 3, 4, 5]
console.log(_flatten([])); // []
Написать функцию которая возвращает последовательность фибоначи.
// Тестовые данные
console.log(fibonacci(0)); // 0
console.log(fibonacci(1)); // 1
console.log(fibonacci(2)); // 1
Напишите рекурсивную функцию для определения длины строки.
// Тестовые данные
console.log(stringLength("hello")); // 5
console.log(stringLength("JavaScript")); // 10
console.log(stringLength("")); // 0
Напишите рекурсивную функцию для поиска максимального элемента в массиве.
// Тестовые данные
console.log(findMax([1, 5, 3, 9, 2])); // 9
console.log(findMax([-1, -5, -3])); // -1
console.log(findMax([10])); // 10
Асинхронные операции

Необходимо создать функцию
fetchRetryer()
, которая будет выполнять запрос на определенный API и повторять его до 5 раз, пока не получит ответ (статус 200). Если после 5 повторов сервер не отвечает - возвращаем ошибку.
// Пример использования
fetchRetryer("https://jsonplaceholder.typicode.com/posts/1")
.then((res) => res.json())
.then((data) => console.log("Success:", data))
.catch((err) => console.error("Failed:", err.message));
fetchRetryer("https://invalid-url.example")
.then((res) => res.json())
.catch((err) => console.error("Failed after retries:", err.message));
Реализуйте функцию
_promiseAll
.
// Тестовые данные
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
const promise4 = new Promise((resolve) => setTimeout(resolve, 100, 4));
_promiseAll([promise1, promise2, promise3, promise4])
.then((results) => {
console.log(results); // Output: [1, 2, 3, 4]
})
.catch((error) => {
console.error(error);
});
const promise5 = Promise.reject("Error occurred");
customPromiseAll([promise1, promise2, promise5])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error); // Output: Error occurred
});
Необходимо написать функцию, которая принимает два аргумента: асинхронную функцию и временной лимит в миллисекундах. Эта функция должна возвращать новую версию асинхронной функции, выполнение которой ограничено заданным временным лимитом.
Должны выполняться следующие условия:
Если время выполнения исходной функции меньше временного лимита, новая функция должна вернуть результат выполнения асинхронной функции.
Если время выполнения исходной функции превышает временной лимит, новая функция должна вернуть сообщение: "Превышен лимит исполнения".
// Тестовые данные
const fn = async (n) => {
await new Promise((res) => setTimeout(res, 100));
return n * n;
};
console.log(asyncLimit(fn, 50)(5)); // rejected превышен лимит
console.log(asyncLimit(fn, 150)(5)); // resolve 25
const fn2 = async (a, b) => {
await new Promise((res) => setTimeout(res, 120));
return a + b;
};
console.log(asyncLimit(fn2, 100)(1, 2));
console.log(asyncLimit(fn2, 150)(1, 2));
Реализация встроенных функций (полифилы)

Реализуйте метод
_filter
для массивов.
// Тестовые данные
console.log([1, 2, 3, 4, 5]._filter(n => n % 2 === 0)); // [2, 4]
console.log(["apple", "banana", "cherry"]._filter(fruit => fruit.includes("a"))); // ["apple", "banana"]
console.log([10, 20, 30]._filter((num, index) => index % 2 === 0)); // [10, 30]
Реализуйте метод
_map
для массивов.
// Тестовые данные
console.log([1, 2, 3]._map(n => n * 2)); // [2, 4, 6]
console.log(["a", "b", "c"]._map(letter => letter.toUpperCase())); // ["A", "B", "C"]
console.log([10, 20, 30]._map((num, index) => num + index)); // [10, 21, 32]
Реализуйте метод
_reduce
для массивов.
// Тестовые данные
console.log([1, 2, 3, 4]._reduce((acc, num) => acc + num)); // 10
console.log([1, 2, 3, 4]._reduce((acc, num) => acc + num, 10)); // 20
console.log(["a", "b", "c"]._reduce((acc, char) => acc + char)); // "abc"
console.log([2, 3, 4]._reduce((acc, num) => acc * num, 1)); // 24
Реализуйте класс
EventEmitter.
// Пример использования
const emitter = new EventEmitter();
function responseToEvent(data) {
console.log(`Event received with data: ${data}`);
}
emitter.on('dataReceived', responseToEvent);
emitter.emit('dataReceived', { id: 1, message: 'Hello, World!' });
emitter.off('dataReceived', responseToEvent);
emitter.emit('dataReceived', { id: 2, message: 'This will not be logged.' });
// Register a one-time event listener
emitter.once('dataReceivedOnce', (data) => {
console.log(`One-time event received: ${data}`);
});
emitter.emit('dataReceivedOnce', 'This will be logged once.');
emitter.emit('dataReceivedOnce', 'This will not be logged.');
Регулярные выражения

Напишите функцию, которая принимает строку в качестве аргумента и возвращает количество гласных, содержащихся в этой строке. Гласными являются «a», «e», «i», «o», «u».
// Тестовые данные
console.log(countVowels("hello")); // 2
console.log(countVowels("JavaScript")); // 3
console.log(countVowels("xyz")); // 0
Напишите функцию для извлечения доменных имен из URL-адресов, используя регулярные выражения.
// Тестовые данные
console.log(extractDomain("https://www.google.com")); // "google.com"
console.log(extractDomain("http://example.org")); // "example.org"
console.log(extractDomain("https://sub.domain.com/path")); // "sub.domain.com"
console.log(extractDomain("invalid-url")); // null
Дополнительные задачи

Написать функцию, которая проверит строку и вернёт в результате
true
илиfalse
в зависимости от того, является ли данная последовательность скобок валидной.
// Тестовые данные
console.log(isValidParentheses("()[]{}")); // true
console.log(isValidParentheses("([{}])")); // true
console.log(isValidParentheses("(]")); // false
console.log(isValidParentheses("([)]")); // false
console.log(isValidParentheses("{[]}")); // true
Разработайте стек, который поддерживает операции
push
,pop
,top
и извлечение минимального элемента за постоянное время O(1).
// Пример использования
const minStack = new MinStack();
minStack.push(5);
minStack.push(3);
minStack.push(7);
console.log(minStack.getMin());
minStack.pop();
console.log(minStack.getMin());
minStack.pop();
console.log(minStack.getMin());
Напишите функцию, которая принимает массив строк (логи) и возвращает список пользователей, которые больше всего взаимодействовали с системой.
// Пример использования:
const logs = [
"user1 login",
"user2 login",
"user1 click",
"user3 login",
"user1 logout",
"user2 click",
"user2 logout",
"user3 click",
"user3 logout",
];
console.log(analyzeLogs(logs));
// { user1: 3, user2: 3, user3: 3 }
Реализуйте функцию, которая запускает задачи с ограничением на количество параллельно выполняемых задач.
// Пример использования:
const tasks = [
() => new Promise((res) => setTimeout(() => res("Task 1"), 1000)),
() => new Promise((res) => setTimeout(() => res("Task 2"), 500)),
() => new Promise((res) => setTimeout(() => res("Task 3"), 1200)),
() => new Promise((res) => setTimeout(() => res("Task 4"), 300)),
];
parallelTaskRunner(tasks, 2).then(console.log);
// ["Task 1", "Task 2", "Task 3", "Task 4"]
Ну вот, мы рассмотрели типовые задачи. Конечно, это далеко не всё, что может встретиться вам на собеседовании. Я планирую добавлять ещё задачи в этот репозиторий, так что переходите по ссылке и сохраняйте!
Не забывайте, что успешное выполнение задач в секции live-coding требует постоянной практики и упорства. Формула проста: чем больше вы практикуетесь, тем увереннее будете себя чувствовать на собеседованиях. Всё просто!
Желаю вам удачи!
? Подписывайтесь на мой канал в Telegram, где я делюсь интересной и полезной информацией.
Комментарии (23)
FODD
01.02.2025 11:31isPalindrome имеет менее многословное решение
function isPalindrome(str) { const transormed = str.replace(/[^\w]/g, '').toLocaleLowerCase(); return transormed === transormed.split('').reverse().join('') }
sharpfellow
01.02.2025 11:31При таком решении можно ожидать дополнение от интервьюера
"Что будет при выполнении, если str занимает 90% доступной памяти?"
Andreyika
01.02.2025 11:31есть еще менее многословное
$.isPalindrome(str)
в более модном-молодежном варианте:
yarn add @huynhducduy/is-palindrome
function _isPalindrome(str) { return isPalindrome(str) }
adminNiochen
01.02.2025 11:31Так про любую задачу можно ответить: гуглим пакет, в котором есть данная функция и устанавливаем его.
SergeiZababurin
01.02.2025 11:31Ни на одной работе с лайв кодингом не сталкивался. Это для меня признак компании в которой не стоит работать и некомпетентности вопрошающего.
barmaglot92
01.02.2025 11:31Ни одной вакансии не видел без Лив кодинга, работал в Яндекс ВТБ сбер
SergeiZababurin
01.02.2025 11:31Альпари (туда из втб кстати тоже приходили) perfect centr и последняя. Везде особенность в том, что стек может быть любой. Этот лайв кодинг как мертвому припарка. Главное выполнять задачи уметь. На extjs drupal vue react wordpres, backbone что нибудь на php, и все без разницы. Писал ты или нет на этих фреймворках, при том, что стиль написания в каждом проекте свой. Проблемы у фронтенд разработчика как правило не связанны с программированием.
ArturKD
01.02.2025 11:31На аутсорсе заказчик может собесить с лайвом и никуда от этого не денешься. У меня, например, беда с этим, поэтому хочу придумать себе какую-то практику что-ли.
altrapeznikov Автор
01.02.2025 11:31Главное - тренироваться каждый день, одну задачку, например, перед сном :)
adminNiochen
01.02.2025 11:31Это почему же? Тебе же не дают тестовое сделать, потратив n часов своего времени на код, который неизвестно посмотрят вообще или нет. На лайвкодинге дают задачи, которые можно решить за 5-10 мин в плане сложности - и смотрят даже не на ответ, а на ход рассуждений. Это может не нравиться если ты например не умеешь думать...
SergeiZababurin
01.02.2025 11:31Ни на одном собеседовании код не давали. Тоже считаю это трата моего времени. Если человек не способен оценить твои знание по разговору, у него скорее всего нет возможности оценить и то что ты написал.
На всех собеседованиях просто говорили. Я один раз только тестовое задание сделал и то потому что мне надо было табличку такую для себя делать. И это было русской компании после начала сво. Проект кстати так и не дошел до сдачи. Но я свою часть хорошо сделал, по этому это мне помогло устроиться на другую работу потом.
Может быть сейчас что то поменялось...
Если так, я в будущем рассмотрю тогда лучше вариант работать курьером и писать свой проект.
Одно дело работать с людьми которые для тебя авторитеты, другое дело с не пойми кем, кто требует от тебя не пойми что
NN1
01.02.2025 11:31Не надо советовать ответ с рекурсией.
Следующим вопросом будет как решить глубину рекурсии.
GospodinKolhoznik
01.02.2025 11:31А нет никакой проблемы. Расход памяти при вызове рекурсии линейно зависит от глубины рекурсии. А рост ёмкости ОЗУ из за технического прогресса идёт по экспоненте. Может показаться, что рекурсивный алгорит сожрёт память гораздо быстрее, чем период времени в течении которого происходит апгрейд ОЗУ у компьютера. Но это лишь на малых временных интервалах, а в ассимптотике увеличение памяти при апгрейде будет расти несоизмеримо быстрее расхода памяти, т.к. O(exp(t)) >> O(t) и память никогда не закончится =)))
NN1
01.02.2025 11:31В том и дело, что кончается очень быстро.
Обычно на каждый поток выделяется 1МБ памяти.
Под переменные ну скажем нужно 24 байт стека и 8 на возврат итого каждый вызов 32 байта .
1МБ/32=32768 рекурсивных вызовов пока прогнозами а не упадёт.
Не так много.
cupraer
01.02.2025 11:31Я, конечно, понимаю, что про такие штуки, как TCO, в джаваскрипте никогда не думали — нечего и начинать, но вот неглупые ребята же все-таки существуют: https://glat.info/pub/tailopt-js/
Проблемы переполнения стека при рекурсивных но хвостовых вызовах — были решены академически примерно 50 лет назад. Хвостовая рекурсия всегда может быть развёрнута в цикл.
Так что все нормально с рекурсией, если знать, как её готовить.
IvanZaycev0717
01.02.2025 11:31Что-то слишком простые задачи, тут грейд "junior" не выше (по современным стандартам). Если на более высокий грейд будут такие задачи - это просто неописуемая удача.
У меня был live-coding на собеседованиях (правда только на Python), и там была одна задача на Two Pointers, и ещё одна на DFS - навык решения таких задач набивается на LeetCode. Two Pointers просто надо понять смысл, а DFS - зубрить и понимать, что присходит.
Всем желающим набить навык live coding, я посоветовал бы начать с задачника Абрамяна М.Э. "1000 задач по программированию". Там задачи можно решать на абсолютно любом языке. Там такие же задачи как в статье. Когда вам станет решать эти задачи "как нечего делать", тогда переходим на LeetCode
Maxkuku
01.02.2025 11:31Я считаю, что sumRange.js - это излишне перемудрёное. Зачем усложнять простые действия, которые трудно прослеить?
Tobiass
01.02.2025 11:31Задача 2.
Напишите функцию, которая переворачивает цифры числа, сохраняя знак нетронутым.
Вы используете для решения строковые операции. Хотя куда эффективнее будет использовать арифметические операции. Ниже решение
function reverseNumber(num) {
const isNegative = num < 0; if (isNegative) { num = Math.abs(num); } let reversed = 0; while (num !== 0) { const lastDigit = num % 10; reversed = reversed * 10 + lastDigit; num = Math.floor(num / 10); } return isNegative ? -reversed : reversed; }
Не то, что я умничать пытаюсь... Просто эта задача уже классика LeetCode и ему подобных)
alex_k777
Терпеть не могу, когда наблюдают за тем, как я пишу код. Почему без этого никуда? Какой процент компаний используют live-coding при собеседовании? Я встречал только одну и отказался сразу от такого собеседования.
altrapeznikov Автор
К сожалению, почти все крупные компании...
ermouth
Потому что есть ребята, которые рисуют себе толстый опыт, а потом оказывается, что они синтаксис цикла for «не помнят».
Korund
А если я честно говорю, что у меня нет опыта, но многие задачи из поста, я могу решить, но мне действительно некоторый синтаксис надо погуглить. С такими навыками я остаюсь за бортом или могу рассчитывать на условную позицию джуна?