5个典型的JavaScript面试任务:分析与解决方案

5个典型的JavaScript面试任务:分析与解决方案

来自翻译: 为您发表了一篇文章 Maria Antonietta Perna,谈论常见的 JavaScript 任务,最常在面试期间提供给开发人员申请人。 首先,本文对新手程序员很有用。

科技公司的面试长期以来一直是城里的话题。 这并不奇怪——成功通过面试可以让你有机会找到一份好工作。 但这并不那么简单,因为往往需要解决复杂的问题。

而且,大多数情况下,这些任务大多数与申请人将要执行的工作无关,但仍然需要解决。 有时您必须在板上完成此操作,而无需与 Google 或任何其他来源核实。 是的,情况正在逐渐改变,一些公司正在放弃这种面试,但许多雇主仍然坚持这一传统。 本文致力于分析求职者经常使用的典型 JavaScript 任务。

我们提醒: 对于“Habr”的所有读者 - 使用“Habr”促销代码注册任何 Skillbox 课程可享受 10 卢布的折扣。

技能箱推荐: 实践课程 “移动开发者专业版”.

最重要的是为面试做好充分的准备。

是的,在我们开始查看任务之前,让我们先看看一些一般的面试准备技巧。

最主要的是提前做好准备。 测试你对算法和数据结构的记忆程度,并提高你不太熟悉的领域的知识。 有许多在线平台可以帮助您准备面试。 我们建议 极客, 普兰普, 面试 и 代码信号.

大声说出决定是值得学习的。 建议告诉申请人您所做的事情,而不仅仅是在黑板上写(或在计算机中输入代码,也可以默默地)。 这样,如果您在代码中犯了错误,但解决方案通常是正确的,您可以增加成功的机会。

在开始解决问题之前,您需要先了解问题。 在某些情况下,您可能会肤浅地理解一项任务,然后走上错误的道路。 也许值得向面试官提出一些澄清问题。

您需要练习手动编写代码,而不是在 PC 上。 在面试过程中,申请人会得到一支记号笔和一块白板,但没有提示或自动格式化。 在寻找解决方案时,值得将代码写在纸上或直接写在黑板上。 如果你把一切都记在脑子里,你可能会忘记一些重要的事情。

JavaScript 中的模板任务

您可能已经熟悉其中一些任务。 您要么参加过必须解决类似问题的面试,要么在学习 JavaScript 时进行过练习。 好吧,现在是时候再次解决它们,并详细解释该过程。

回文

回文是一个单词、句子或字符序列,在通常的方向和相反的方向上读起来都完全相同。 例如,“Anna”是回文,但“table”和“John”不是。

分期

给定一个字符串; 您需要编写一个函数,如果字符串是回文,则允许您返回 true,如果不是,则返回 false。 在这种情况下,您需要考虑空格和标点符号。

回文('赛车') === true
回文('表') === false

我们来分析一下任务

这里的主要思想是反转字符串。 如果“反向”字符串与原始字符串完全相同,那么我们收到了一个回文,并且该函数应该返回 true。 如果不是,则为假。

这是解决回文的代码。

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() 方法(字符串库)将其转换为数组。 然后我们使用 .reverse() (数组库)反转数组。 最后一步是使用 .join() (数组库)将反向数组转换为字符串。

现在您需要做的就是将“反向”字符串与原始字符串进行比较,返回结果 true 或 false。

嗡嗡声

面试中最常见的任务之一。

分期

您需要编写一个函数,将 1 到 n 之间的数字打印到控制台,其中 n 是函数作为参数的整数,满足以下条件:

  • 输出嘶嘶声而不是 3 的倍数;
  • 输出嗡嗡声而不是 5 的倍数的数字;
  • fizzbuzz 输出而不是 3 和 5 的倍数的数字。

例子

嘶嘶声(5)

导致

//1
//2
// 嘶嘶声
//4
//嗡嗡声

我们来分析一下任务

这里最主要的是一种使用 JavaScript 查找倍数的方法。 它可以使用模运算符或余数 - % 来实现,它允许您显示两个数字相除时的余数。 如果余数为 0,则表示第一个数是第二个数的倍数。

12% 5 // 2 -> 12 不是 5 的倍数
12% 3 // 0 -> 12 是 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('你好', '再见') —> false

我们来分析一下任务

这里要考虑的重要一点是,您需要检查两个输入行中的每个字母及其在每行中的编号。

查找器 —> f: 1 朋友 —> f: 1
我: 1 r: 1
n:1 我: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('为什么') // —> 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 是作为参数传递给函数的数字。

斐波那契(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 时我们停止。

结论

如果您接受过前端或 JavaScript 开发人员工作的面试(尤其是初级水平),那么您很可能已经遇到过这些任务中的任何一个。 但如果你还没有遇到过它们,它们在未来可能会有用——至少对于一般开发来说。

技能箱推荐:

来源: habr.com

添加评论