RoadmapСтатьи
Язык

Готовимся к live-coding секции

читать 9 мин 5
AlgoJavaScriptInterview

cover.webp

Введение

Всем привет! Сейчас без live-coding'a никуда: на собеседованиях часто дают одну-две задачки, которые нужно решить за определённое время. Сами задачи могут быть несложными (не супер-пупер алгоритмическими), но новички могут переволноваться и не справиться с ними.

Поэтому в этой статье я хотел бы описать типовые задачи, которые встречаются в этой секции на позицию frontend или backend разработчика (если бэк на JS). Это поможет вам получить общее представление о том, что может ждать вас.

Понимание 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]));
console.log(_flatten([1, [2, 3], 4]));
console.log(_flatten([[1, 2], [3, 4]]));
console.log(_flatten([1, [2, [3, [4, 5]]]]));
console.log(_flatten([]));
// [1, 2, 3]
// [1, 2, 3, 4]
// [1, 2, 3, 4]
// [1, 2, 3, 4, 5]
// []

Ответ

Написать функцию которая возвращает последовательность фибоначи.

// Тестовые данные
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 требует постоянной практики и упорства. Формула проста: чем больше вы практикуетесь, тем увереннее будете себя чувствовать на собеседованиях.

Комментарии

Войдите, чтобы присоединиться к обсуждению

Войти