5 типових завдань на співбесідах з JavaScript: розбір та рішення

5 типових завдань на співбесідах з JavaScript: розбір та рішення

Від перекладача: опублікували для вас статтю Марії Перна (Maria Antonietta Perna), яка розповідає про типові завдання JavaScript, Найчастіше запропонованих претендентам-розробникам на співбесідах. Стаття буде корисна, в першу чергу, програмістам-початківцям.

Співбесіди в технологічних компаніях давно стали притчею в мовах. Дивуватися з цього не доводиться — успішне проходження інтерв'ю дає змогу отримати гарну роботу. Але це не так просто, оскільки часто необхідно вирішувати складні завдання.

Причому найчастіше більшість цих завдань не мають відношення до роботи, яку виконуватиме претендент, але вирішувати їх все одно потрібно. Іноді доводиться робити це на дошці, без звіряння з Google чи будь-яким іншим джерелом. Так, ситуація поступово змінюється, і в деяких компаніях від таких співбесід відмовляються, але багато роботодавців все ще дотримуються цієї традиції. Ця стаття присвячена розбору типових JavaScript-завдань, які часто використовуються як завдання для претендентів.

Нагадуємо: для всіх читачів "Хабра" - знижка 10 000 рублів при записі на будь-який курс Skillbox за промокодом "Хабр".

Skillbox рекомендує: Практичний курс «Мобільний розробник PRO».

Головне - ретельна підготовка до вашої співбесіди

Так, перш ніж почати розбирати завдання, давайте розглянемо загальні поради щодо підготовки до інтерв'ю.

Головне – готуватися заздалегідь. Перевірте, наскільки добре ви пам'ятаєте алгоритми та структури даних, і підтягніть знання у тих областях, які вам не надто добре знайомі. Є чимало онлайн-платформ, які допоможуть підготуватись до проходження співбесід. Радимо geeksforgeeks, Коляска, Interviewing.io и CodeSignal.

Варто навчитися промовляти рішення вголос. Бажано розповідати претендентам про те, що ви робите, а не просто писати на дошці (або набирати код у комп'ютері, теж мовчки). Таким чином, якщо в коді ви припуститеся помилки, але хід рішення буде загалом правильним, можна збільшити свої шанси на успіх.

Завдання потрібно осмислити, перш ніж приступити до вирішення. У деяких випадках можна поверхово зрозуміти завдання і потім піти неправильним шляхом. Можливо, варто поставити кілька уточнюючих питань до інтерв'юера.

Потрібно потренуватись писати код вручну, а не на ПК. Буває, що на співбесідах претенденту дають маркер та дошку, де немає ні підказок, ні автоматичного форматування. Під час пошуку рішення варто записати свій код на аркуші паперу або прямо на дошці. Якщо пам'ятати, можна забути щось важливе.

Шаблонні завдання JavaScript

Мабуть, якісь із цих завдань вже вам уже знайомі. Ви або проходили співбесіди, де потрібно було вирішувати щось подібне, або практикувалися на них під час вивчення JavaScript. Ну, а тепер настав час вирішити їх ще раз, причому з докладним поясненням процесу.

Паліндром

Паліндром - слово, речення чи послідовність символів, яка абсолютно однаково читається як у звичному напрямку, так і у зворотному. Наприклад, "Anna" - це паліндром, а "table" і "John" - ні.

постановка

Дано рядок; потрібно написати функцію, яка дозволяє повернути значення true, якщо рядок є паліндромом, і false - якщо ні. При цьому потрібно враховувати прогалини та розділові знаки.

palindrome('racecar') === true
palindrome('table') === false

Розбираємо завдання

Основна ідея тут – перевернути рядок у зворотному напрямку. Якщо "реверсний" рядок повністю ідентичний вихідному, значить, ми отримали паліндром і функція повинна повернути значення true. Якщо ж ні – false.

Рішення

Ось код, що дозволяє вирішити паліндром.

const palindrome = str => {
  // turn the string to lowercase
  str = str.toLowerCase()
  // reverse input string and return the result of the
  // comparisong
  return str === str.split('').reverse().join('')
}

Перший крок — перетворення символів вхідного рядка на нижній регістр. Це гарантія того, що програма порівнюватиме саме самі символи, а не регістр або ще щось.

Другий крок – реверс рядка. Це зробити нескладно: необхідно перетворити її на масив за допомогою методу .split() (бібліотека String). Потім ми перевертаємо масив за допомогою .reverse() (бібліотека Array). Останній етап - перетворення зворотного масиву в рядок за допомогою .join () (Бібліотека Array).

Тепер усе, що потрібно, — порівняти «зворотний» рядок із вихідним, повернувши результат true чи false.

FizzBuzz

Одна з найпопулярніших на співбесідах завдань.

постановка

Потрібно написати функцію, що виводить у консоль числа від 1 до n, де n - це ціле число, яка функція приймає як параметр, з такими умовами:

  • виведення fizz замість чисел, кратних 3;
  • виведення buzz замість чисел, кратних 5;
  • виведення fizzbuzz замість чисел, кратних як 3, і 5.

Приклад

Fizzbuzz(5)

Результат

/ / 1
/ / 2
// fizz
/ / 4
// buzz

Розбираємо завдання

Головне тут – спосіб пошуку кратних чисел з використанням JavaScript. Його можна реалізувати за допомогою оператора модуля або залишку - %, який дозволяє показати залишок при розподілі двох чисел. Якщо залишок 0, це означає, що перше число кратне другому.

12 % 5 // 2 -> 12 is not a multiple of 5
12% 3 // 0 -> 12 is multiple of 3

Так, якщо розділити 12 на 5, отримуємо 2 із залишком 2. Якщо ж розділити 12 на 3, то отримуємо 4 із залишком 0. У першому випадку 12 не кратно 5, у другому - 12 кратно 3.

Рішення

Оптимальним рішенням буде наступний код:

const fizzBuzz = num => {
  for(let i = 1; i <= num; i++) {
    // check if the number is a multiple of 3 and 5
    if(i % 3 === 0 && i % 5 === 0) {
      console.log('fizzbuzz')
    } // check if the number is a multiple of 3
      else if(i % 3 === 0) {
      console.log('fizz')
    } // check if the number is a multiple of 5
      else if(i % 5 === 0) {
      console.log('buzz')
    } else {
      console.log(i)
    }
  }
}

Функція виконує необхідні перевірки з використанням умовних операторів та видає результат, необхідний користувачеві. У задачі варто приділити увагу порядку операторів if…else: починати з подвійної умови (&&) і закінчувати нагодою, коли кратні числа знайти не вдалося. В результаті ми охоплюємо усі варіанти.

Анаграма

Так називають слово, яке містить усі літери іншого слова у тій самій кількості, але в іншому порядку.

постановка

Потрібно написати функцію, яка перевіряє, чи є два рядки анаграмами, причому регістр букв не має значення. Враховуються лише символи; прогалини або розділові знаки до уваги не беруться.

anagram('finder', 'Friend') -> true
anagram('hello', 'bye') -> false

Розбираємо завдання

Тут важливо враховувати, що необхідно перевіряти кожну букву у двох вхідних рядках та їх кількість у кожному рядку.

finder -> f: 1 friend -> f: 1
i: 1 r: 1
n: 1 i: 1
d: 1 e: 1
e: 1 n: 1
r: 1 d: 1

Для зберігання даних анаграми варто вибрати таку структуру, як об'єктний літерал JavaScript. Ключ у цьому випадку – символ літери, значення – кількість її повторень у поточному рядку.

Є й інші умови:

  • Потрібно переконатися, що регістр літер при порівнянні не враховується. Просто перетворюємо обидва рядки в нижній або верхній регістр.
  • Виключаємо з порівняння усі не-символи. Найкраще працювати з регулярними виразами.

Рішення

// helper function that builds the
// object to store the data
const buildCharObject = str => {
  const charObj = {}
  for(let char of str.replace(/[^w]/g).toLowerCase()) {
    // if the object has already a key value pair
    // equal to the value being looped over,
    // increase the value by 1, otherwise add
    // the letter being looped over as key and 1 as its value
    charObj[char] = charObj[char] + 1 || 1
  }
  return charObj
}
 
// main function
const anagram = (strA, strB) => {
  // build the object that holds strA data
  const aCharObject = buildCharObject(strA)
  // build the object that holds strB data
  const bCharObject = buildCharObject(strB)
 
  // compare number of keys in the two objects
  // (anagrams must have the same number of letters)
  if(Object.keys(aCharObject).length !== Object.keys(bCharObject).length) {
    return false
  }
  // if both objects have the same number of keys
  // we can be sure that at least both strings
  // have the same number of characters
  // now we can compare the two objects to see if both
  // have the same letters in the same amount
  for(let char in aCharObject) {
    if(aCharObject[char] !== bCharObject[char]) {
      return false
    }
  }
  // if both the above checks succeed,
  // you have an anagram: return true
  return true
}

Зверніть увагу на використання Object.keys () у сніпеті вище. Цей метод повертає масив, що містить імена або ключі в такому порядку, в якому вони зустрічаються в об'єкті. У цьому випадку масив буде таким:

['f', 'i', 'n', 'd', 'e', ​​'r']

Таким чином ми отримуємо властивості об'єкта без необхідності виконувати об'ємний цикл. У задачі можна використовувати цей спосіб із властивістю .length — для перевірки того, чи є в обох рядках однакова кількість символів — важлива особливість анаграм.

Пошук голосних

Досить просте завдання, яке часто трапляється на співбесідах.

постановка

Потрібно написати функцію, яка приймає рядок як аргумент і повертає кількість голосних, які містяться в рядку.
Голосними є "a", "e", "i", "o", "u".

Приклад:

findVowels('hello') // -> 2
findVowels('why') // -> 0

Рішення

Ось найпростіший варіант:

const findVowels = str => {
  let count = 0
  const vowels = ['a', 'e', 'i', 'o', 'u']
  for(let char of str.toLowerCase()) {
    if(vowels.includes(char)) {
      count++
    }
  }
  return count
}

Важливо звернути увагу використання методу .includes(). Він доступний і для рядків, і масивів. Його варто застосовувати для того, щоб виявити, чи масив містить певне значення. Цей метод повертає true, якщо масив містить зазначене значення, false, якщо ні.

Є й коротше вирішення проблеми:

const findVowels = str => {
  const matched = str.match(/[aeiou]/gi)
  return matched ? matches.length : 0
}

Тут використовується метод .match(), який дозволяє реалізувати ефективний пошук. Якщо регулярне вираз як аргумент методу виявлено всередині зазначеного рядка, то значенням, що повертається стає масив збігаються символів. Ну, а якщо збігів немає, то .match() повертає null.

Фібоначчі

Класичне завдання, яке можна зустріти на співбесідах різного рівня. Послідовність Фібоначчі - це ряд чисел, де кожне наступне є сумою двох попередніх. Так, перші десять чисел виглядають так: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.

постановка

Потрібно написати функцію, яка повертає n-ний запис у певній послідовності, причому n - число, яке передається як аргумент функції.

fibonacci (3) // -> 2

Це завдання включає проходження за циклом таку кількість разів, яка вказана в аргументі, з поверненням значення відповідної позиції. Цей спосіб постановки завдання потребує використання циклів. Якщо натомість ви використовуєте рекурсію, це може сподобатися інтерв'юеру та дати вам кілька додаткових очок.

Рішення

const fibonacci = num => {
  // store the Fibonacci sequence you're going
  // to generate inside an array and
  // initialize the array with the first two
  // numbers of the sequence
  const result = [0, 1]
 
  for(let i = 2; i <= num; i++) {
    // push the sum of the two numbers
    // preceding the position of i in the result array
    // at the end of the result array
    const prevNum1 = result[i - 1]
    const prevNum2 = result[i - 2]
    result.push(prevNum1 + prevNum2)
  }
  // return the last value in the result array
  return result[num]
}

У масиві результатів перші два числа містяться у ряду, оскільки кожен запис у послідовності складається із суми двох попередніх чисел. На початку двох чисел, які можна взяти для отримання наступного числа немає, тому цикл не може згенерувати їх в автоматичному режимі. Але, як ми знаємо, перші два числа завжди 0 і 1. Тому ініціалізувати масив результатів можна вручну.

Що стосується рекурсії, то тут все простіше та складніше одночасно:

const fibonacci = num => {
  // if num is either 0 or 1 return num
  if(num < 2) {
    return num
  }
  // recursion here
  return fibonacci(num - 1) + fibonacci(num - 2)
}

Ми продовжуємо викликати fibonacci(), передаючи менші числа як аргументи. Зупиняємось у разі, коли переданий аргумент дорівнює 0 або 1.

Висновок

Швидше за все, ви вже стикалися з будь-яким із зазначених завдань, якщо проходили співбесіди на роботу frontend-або JavaScript-розробника (особливо якщо це рівень junior). Але якщо вони вам і не траплялися, то можуть стати в нагоді в майбутньому — як мінімум для загального розвитку.

Skillbox рекомендує:

Джерело: habr.com

Додати коментар або відгук