Комментарии 34
const funique = (arr) => [...new Set(arr)];
Через неделю другое собеседование, задача та же, делаю через Set — сказали что правильно, но они хотят посмотреть на знание перебирающих методов массива и попросили сделать по другому)
Со сплющиванием массива есть тоже забавный хак:
const flat = (arr) => arr.join().split(',')
flat([1, [2, [3, [4,5]]]]); // => [1, 2, 3, 4, 5]
Какой процент из подобных задач встречался вам на работе?
Если только сортировка по уникальности. Ну как бы, когда приходишь на собес, тебя не спрашивают: «Хочешь такую задачу порешать, а может тебе не понравилась эта, можем на выбор предложить эту и эту».Увы, так не бывает. Ты или делаешь ту, что дают, или «мы вам перезвоним».
Если бы я проводила собеседование, стала бы я давать такие задачи, точно нет.
А эта вся ерунда на собеседованиях гуглится за 2 минуты если будет надо, смысл вот давать эти задачи?
Может они прекрасно гугляться, но на собесе же не достанешь мобильный и не начнешь искать решение задачи в интернете? В противном случае результат: «мы вам перезвоним».
Задача: Написать функцию, принимающую аргументом массив чисел и возвращающую новый массив, состоящий из удвоенных значений первого.
Убираем два прогона массива и получаем тот же результат
function f(arr = []) {
const result = [];
arr.reduce((acc, item) => {
if (typeof item === 'number') {
acc.push(item * 2);
}
return acc;
}, result);
return result;
}
f([1, 2, null, 7, 8, null, 3]); // => [2, 4, 14, 16, 6]
Так же добавлю, что в массиве могут быть string/undefined/boolean типы, в общем любой тип, отличный от null. Поэтому лучше не проверять условие как привел автор (i !== null).
Метод «arr.reduce(callback[, initialValue])» используется для последовательной обработки каждого элемента массива с сохранением промежуточного результата.
Это один из самых сложных методов для работы с массивами.
learn.javascript.ru — Массив: перебирающие методы
В таком случае нужно дополнительно сделать проверку на NaN
typeof NaN === 'number' // true
Promise
, используя const
и стрелочные функции…Где он заработает, интересно?
Больше похоже на фантазию автора, нежели реальный кейс, где нужно сидеть и педалить реализацию промисов.
в Wildberries — Promise.all и еще три задачи из перечисленных(здесь решила все четыре),
задача из Mail:
var obj = {};
function func(x) {
x = 1;
...
в СТС — «сжатие строк»,
Комсомольская правда — обход дерева.
Как бы большинство не шарашкины конторы с предлагаемой зп выше 150К и всякими ништяками, бонусами. Выбирала по зп, относительно близком ко мне территориальном расположении и что бы компания была более, менее известной.
Это я еще в Яндекс не ходила, вот они славятся своими задачами на алгоритмы.
Но на мой взгляд, не очень подходящий вопрос для собеса.
никто не пишет свои промисы костылей ради. но вы удивитесь, что во многих часто используемых библиотеках (решил проверить около полугода или года назад) промисы реализовывают через setTimeout()
, что в корне не верно.
я тоже спрашиваю про реализацию промисов и смысл в том, чтобы выяснить насколько глубоко вы залезли в кроличью нору со своей любознательностью и как хорошо понимаете то с чем работаете, соответственно, насколько вы реальный специалист, а не просто формошлёпер или диводвигатель.
https://html.spec.whatwg.org/multipage/webappapis.html#event-loops
The microtask queue is not a task queue.
По поводу третьей с конца задачи, зачем так писать код? Чтобы было что спрашивать на собеседовании? :)
Хорошими задачами являются те, которые максимально приближены к специфике работы, на которую человек устраивается. Ведь решать придется именно задачи проекта, а не вот этот треш, который в целом пишется один раз, помещается во вспомогательную библиотеку и забывается.
Некоторые теоретические вопросы также бессмысленны, например, такой как вопрос про регистрацию событий, при условии, что человек нанимается на уже действующий проект, в котором тот или иной подход укрепился.
Тут уже обращали внимание на реализацию Промиса, но почему-то никто не обратил внимания, что она неверна:
- Промис не возвращает значение (resolve() и reject() не принимают аргументы)
- then() и catch() вместо нового промиса возвращают тот же самый.
- Следствие пункта 2 — не важно, в каком порядке в цепочке расположены then() и catch() — выполнятся только один вид коллбеков.
- Ещё одно следствие 2 — возврат из любого коллбека промиса также руботать не будет.
- Все then()/catch() коллбеки вызываются одновременно — не очень понятно, зачем вообще тогда больше одного then()
- Ну и throw в любом из коллбеков просто выкинет ошибку и прервет выполнение всей цепочки.
В результате это даже близко не похоже на промис — я бы назвал это одноразовым EventEmitter'ом.
Рекурсивный обход дерева не выдает требуемый порядок, потому что «поиск в глубину». Нерекурсивный — норм., там «поиск в ширину».
Ну и RLE можно в одну строку
const rle = s => s.replace(/(.)\1+/g, (m, c) => c + m.length);
Задача: Сортировка нечётных.
Здравствуйте. А почему так сложно? Можно же попроще:
function oddSort(arr) {
//отобрать только нечетные и отсортировать
odd_sorted = arr.filter((x)=> x%2==1 ).sort((a,b)=>a-b);
//вставить их на нечетные места
return arr.map(item => {
return (item%2 != 0)? odd_sorted.shift() : item;
});
}
Чтоб это исправить, достаточно создать указатель элементы в odd_sorted:
function oddSort(arr) {
//отобрать только нечетные и отсортировать
odd_sorted = arr.filter((x)=> x%2==1 ).sort((a,b)=>a-b);
//вставить их на нечетные места
let i = 0; // увеличиваем его каждый раз, после вставки нечетных в массив
return arr.map(item => {
return (item%2 != 0)? odd_sorted[i++] : item;
});
}
что даст сложность O(2K + MlogM) (уже не квадрат)
Задачи с собеседований (front-end) часть 2