Facebook 面试题全解析

作者 | Joey Colon

译者 | 弯月,责编 | 屠敏

图 | CSDN 下载自视觉中国

出品 | CSDN(ID:CSDNnews)

以下为译文:

尽管公众对于Facebook褒贬不一,但他们对开源社区做出的贡献却实实在在造福了许多开发者。在这篇文章中,我来介绍一下你在面试Facebook的前端工程师职位时可能会遇到的面试题。

问题陈述

重新实现Array.flat():具体功能是,接受一个输入数组,该数组可能包含任意层数的嵌套元素,返回一个新的数组,该数组将输入数组展平。本题中,“展平”的数组指的是所有元素均为基本类型的数组。

示例

输入:[1, [2, [3], 4], [5]]

输出:[1, 2, 3, 4, 5]

理解问题

问题描述似乎很明确,就是要用输入数组的值创建一个新的数组,但新数组不包含嵌套数组。

在这个阶段,我会首先与面试官澄清我对于该问题的假设。我需要知道,输入是否保证为数组(没有非法输入或空输入)。面试官说,我们不能做这种假设。

另一个问题是:我们能否假设值一定为整数?尽管这个问题不太可能改变实现的细节,但在做出任何假设之前永远要先澄清。我们假设嵌套在数组中的基本类型只有整数。

在澄清了一些细节问题后,我在白板上给出我自己的输入示例,以及对应的输出。

在画出示例的时候,需要极其小心地注意你写下的东西,以及你怎样手工解决该问题。我喜欢先从简单的例子开始,然后考虑边界情况,逐步深入到复杂的问题。

匹配问题

如果只看第一个例子,那么很显然我们只需遍历整个数组,检查每个元素是否为整数值,然后将其值写入输出数组中。唯一不成立的条件就是当前检查的元素是一个数组。如果当前元素是数组,就应该找到下一个非数组的元素,写入到输出数组中。这个问题似乎非常适合用递归解决。

但是要注意的是,任何需要递归的问题,都会面临一个隐藏的限制:调用栈的深度限制。一定要向面试官清晰地表明这一点。面试官对我说不需要担心该问题,很好,我们继续。

计划解决方案

思考解决方案很需要技巧。在用递归方式思考问题时,我们要问自己一个问题:给定当前输入的调用栈的状态,我们要完成什么任务?

我认为,使用“驱动函数”的技巧处理递归非常容易。使用这个技巧,我们需要创建一个“壳”函数,设置好递归函数将要使用的初始值。例如下面的例子:

首先要把要完成的工作写到辅助函数中,该函数执行完毕后,newArr就拥有了需要的值。

现在思考一下这个辅助函数。前面说过,我们要遍历整个数组,如果当前元素不是数组,就直接放到新数组中;否则,就查看当前元素的其余元素,直到找到新的数组。

实现

前面已经完成了大部分工作,所以只需要翻译成代码即可:

const flatten = (arr) => {
  if (arr === null || arr.length === 0) return [];
  const newArr = [];
  flattenHelper(newArr, arr);
  return newArr;
};

const flattenHelper = (newArr, currentArr) => {
  for (let i = 0; i < currentArr.length; i++) {
    if (Array.isArray(currentArr[i])) {
      flattenHelper(newArr, currentArr[i]);
    } else if (currentArr[i] !== null) {
      newArr.push(currentArr[i]);
    }
  }
};

const arr = [1, [[2], 3, 4, null], [[5]]];
console.log(flatten(arr)); // 1,2,3,4,5

检查实现

编写完代码之后,需要花些时间验证1-2个例子,运行整个程序。即使你的面试过程要求运行程序,你也要通过目视的方式检查整个代码。

评价实现

在评价步骤中,你要给出算法的复杂度、可以改进的地方等。关于运行时间,我们达到了O(N),这里N是非数组元素的个数。空间复杂度也是O(N),因为我们创建了一个包含N个元素的数组。还有一点需要说明的是,空间是线性的。该算法无法再改进,因为我们需要访问输入数组中的每个元素至少一次。

此外,该问题中我们还可以使用reduce()和concat()。如果你习惯使用这些方法来编写伪代码,那就更好了,但我认为使用平直的代码概念上会更容易。

心得

解决代码问题没有唯一的正确答案。这就是算法问题之美。解决问题的思路和方式会让面试官对你另眼相看。

最后,需要注意的是,许多问题我们都要假设输入可以任意大,大到可能会达到调用栈的上限,这就是为什么要事先询问面试官调用栈上限的问题。如果面试官表明我们需要考虑调用栈上限的问题,就要把递归函数改编成迭代的方式,自己维护调用栈。我在面试另一家大公司的时候就遇到了这个问题。除了要学会编写迭代和递归代码之外,还要学会怎样将递归函数和迭代函数相互转换。

原文:https://medium.com/better-programming/solving-facebooks-2020-front-end-engineering-interview-f34dd6b2a977

本文为 CSDN 翻译,转载请注明来源出处。

【END】

更多精彩推荐

☞朱广权李佳琦直播掉线,1.2 亿人在线等

☞“抗疫”新战术:世卫组织联合IBM、甲骨文、微软构建了一个开放数据的区块链项目!

☞快速搭建对话机器人,就用这一招!

☞没有监控和日志咋整?老程序员来支招

☞“抗疫”新战术:世卫组织联合IBM、甲骨文、微软构建了一个开放数据的区块链项目!

☞万字干货:一步步教你如何在容器上构建持续部署!

据说,这是当代极客们的【技术风向标】...

今日福利:评论区留言入选,可获得价值299元的「2020 AI开发者万人大会」在线直播门票一张。  快来动动手指,写下你想说的话吧。

点击阅读原文,精彩继续!

实用的经验分享,喜欢不如点个“在看”吧!

发布了1945 篇原创文章 · 获赞 4万+ · 访问量 1814万+

猜你喜欢

转载自blog.csdn.net/csdnnews/article/details/105463262