Задачки с собеседований. Сборник решений

Давно я не писал ничего из серии разбора задачек. Краткий пост про задачку, которую уже просто замусолили. Я не считаю, что эта задача может показать крутость разработчика. Задачка может показать на сколько разработчик давно знаком с языком и на сколько хорошо он ориентируется в API и синтаксисе. Хорошее владение синтаксическими конструкциями еще не говорит о крутости разработчика. Тем не менее такие задачки имеют право на жизнь и их можно давать на собеседовании, просто надо понимать что хочется проверить этой задачей. И так, классика, буквально недавно услышал в очередной раз:

Написать функцию, которая переворачивает строку. Например, если мы передаем на вход ‘abcdef’, то возвращает она ‘fedcba’. При решении нельзя использовать циклы (for, while, do, etc…), итерационные методы типа map и forEach.

Начнемс.

Решение 1: Array.prototype.reverse

Если посмотреть документацию, то в JS уже есть метод reverse у массивов. Строка — это Array like Object. Тем не менее метода reverse в классе String нет. Поэтому мы должны привести строку к массиву, перевернуть и склеить обратно.

const strrev = str => str.split('').reverse().join('')

Изи. Просто изи.

Решение 2: ES6+

С приходом стандартов ES6+ у нас появились новые методы для получения массивов. Поэтому мы можем заменить split на Array.from или spread оператор. Выглядит просто чутка моднее:

const strrev = str => Array.from(str).reverse().join('')
const strrev = str => [...str].reverse().join('')

Опять же изи.

Решение 3: редьюсер

Берем идею с массивом и вместо цепочки reverse + join используем редьюсер:

const strrev = str => [...str].reduce((str, chr) => chr+str, '')

Катаем собеседующего как имба к,тун в херстоуне.

Решение 4: рекурсия

Вы вдруг слышите: это все хорошо, но теперь представим что больше не можем использовать редьюсеры и сплиты. Что будем делать? Есть варианты? А вы отвечаете: хау ноу вопрос! И даете примерно такое решение:

function strrev(str){
return str ? strrev(str.substr(1)) + str[0] : str
}

Что тут происходит? Мы берем первый (с нулевым индексом) элемент и приклеиваем его к концу строки, у которой убираем этот элемент (беря копию строки с позиции +1). И так рекурсивно пока это возможно.

Модификация задачи: переверните число

Решение 1: все что писали уже выше

Да, все что вам нужно, это привести число к строке, перевернуть и снова привести к числу. Как приводить — вроде бы понятно. Начиная от явных вызовов toString и parseInt, заканчивая автоприведением типов через операторы типа:

n+''  -> toString
str|0 -> parseInt(str)
~~str -> parseInt(str)
+str -> parseFloat(str)

Пример, что может получиться:

const numrev = n => +[...(n+'')].reverse().join('')

Если бы не было ограничений на итераторы, можно было бы переворачивать числа через битовые сдвиги. Но это уже другая история.

Решение 2: с собеседований НЕфронтендеров

Эту же задачку любят спрашивать на собеседованиях по С++ и Java, но там ждут совсем другое решение. Можно перевернуть число не приводя его к строке. Для этого есть разные алгоритмы и их рассмотрим прямо в следующем заметке, которую я прямо сейчас пишу (ссылка на нее будет на этом месте).

UPD

https://medium.com/@frontman/fun-es-6-%D0%BF%D0%B5%D1%80%D0%B5%D0%B2%D0%B5%D1%80%D0%BD%D1%83%D1%82%D1%8C-%D1%87%D0%B8%D1%81%D0%BB%D0%BE-c3c90be6e9c7

Выводы

Если разработчик решил такую задачу на собеседовании, что это показывает? Хороший вопрос. Если задачки были решены любым способом — уже успех. Если всеми — ну агонь. Только это никак не говорит о квалификации и о том, на сколько успешно будут решены ваши задачи. Более того, если разработчик ни разу не встречал хотя бы пары готовых решений, он может просто не думать в эту сторону. Особенно если он пришел во фронтенд из другого языка, в котором так делать в принципе невозможно и там применялись другие способы. Поэтому я показал тут варианты решений, не столько для тех кто готовится к смене работы, сколько для тех, кому и правда надо перевернуть, но с ходу не пришли идеи, потому что большую часть жизни писали на других языках. Да, в JS так вот можно.

Если бы задача не ограничивалась тем, что нельзя использовать циклы, то мы могли бы говорить про алгоритмы. Но тут речь даже не об алгоритмах, а о том, знаете ли вы нужные методы и можете ли вы их сложить в нужном порядке.

Надо ли давать такие задачи на собеседовании? Почему бы и нет? Это не плохо. Важно не судить кандидата только по такой или таким задачам. Задачка требует время, если человек не знаком и почти не требует время, если человек уже знает ответ. Тратить время на такую задачу — решать вам, товарищи тимлиды.