120 lines
11 KiB
Plaintext
120 lines
11 KiB
Plaintext
---
|
||
title: 前端面试JavaScript问题——如何准备
|
||
description: 为前端/网站开发人员面试准备JavaScript问题的指南——了解的概念、面试规则和70多个重要的练习问题。
|
||
---
|
||
|
||
编写 JavaScript 编码问题与编写算法编码问题的不同之处在于前者通常特定于前端领域,完成它们最有意义的是使用 JavaScript(或[TypeScript](https://www.typescriptlang.org/))。 您还可能需要使用浏览器/JavaScript 特定的 API,或利用 HTML/CSS/JavaScript 知识。 您还可能需要使用浏览器/JavaScript 特定的 API,或利用 HTML/CSS/JavaScript 知识。
|
||
|
||
这些 JavaScript 编码问题往往具有实用价值,并且可以属于以下一类或多类:
|
||
|
||
1. 在 JavaScript 语言中实现标准内置类或方法。
|
||
2. 实现在流行的库中常见的实用函数/类。
|
||
|
||
## 示例
|
||
|
||
### JavaScript 标准内置类/方法
|
||
|
||
当他们已经成为语言的一部分时,实现标准类/方法可能看起来有些多余。 然而,浏览器不一致曾经是一个普遍的问题,并且一些语言 API 在旧浏览器中找不到。 当他们已经成为语言的一部分时,实现标准类/方法可能看起来有些多余。 然而,浏览器不一致曾经是一个普遍的问题,并且一些语言 API 在旧浏览器中找不到。 因此,开发人员不得不通过在下载的 JavaScript 中实现这些 API 来进行填充。 能够实现这些本地函数还显示了对前端基础知识的良好理解。 能够实现这些本地函数还显示了对前端基础知识的良好理解。
|
||
|
||
- `Array` 方法:[`Array.prototype.map`](/questions/javascript/array-map),[`Array.prototype.reduce`](/questions/javascript/array-reduce),[`Array.prototype.filter`](/questions/javascript/array-filter)。
|
||
- `Promise` 和其他`Promise`相关函数:[`Promise.all`](/questions/javascript/promise-all),[`Promise.any`](/questions/javascript/promise-any)。
|
||
- DOM 方法:[`document.getElementsByTagName`](/questions/javascript/get-elements-by-tag-name),[`document.getElementsByClassName`](/questions/javascript/get-elements-by-class-name)。
|
||
|
||
这些函数远非显而易见的那么简单。 这些函数远非显而易见的那么简单。 让我们以无辜的`Array.prototype.map`为例。 您是否知道: 您是否知道:
|
||
|
||
1. 它传递 4 个参数给回调函数,包括 `index` 和 `this` ?
|
||
2. 它保留稀疏数组中的“空”,即 `[1, 2, , 4].map(val => val * val) === [1, 4, , 16]`。
|
||
3. `map`处理的元素范围在第一个调用*callbackfn*之前设置。 在调用 map 之后附加到数组中的元素将不会被*callbackfn*访问。 如果更改数组的现有元素,则将它们的值作为传递给*callbackfn*的值在`map`访问它们时。 来源:[Array.prototype.map ECMAScript 说明](https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.map)
|
||
|
||
您的实施不必处理所有这些情况,特别是数组突变的情况。 但是,如果您提到了这些情况,那么这是一个积极的信号。 您的实现越接近规范,您就会显得更加资深/有经验。
|
||
|
||
### 来自流行库的实用函数/类
|
||
|
||
这些函数/类在使用 JavaScript 构建软件时通常需要,但不在标准语言中(目前)。
|
||
|
||
- Lodash/Underscore 函数:[`debounce`](/questions/javascript/debounce),[`throttle`](/questions/javascript/throttle),[`flatten`](/questions/javascript/flatten),[`curry`](/questions/javascript/curry),[`cloneDeep`](/questions/javascript/deep-clone)。
|
||
- jQuery 方法:[`jQuery.css`](/questions/javascript/jquery-css),[`jQuery.toggleClass`](/questions/javascript/jquery-class-manipulation)。
|
||
- 流行的库:
|
||
- [`classnames`](/questions/javascript/classnames)
|
||
- 测试框架(如[Jest](https://jestjs.io/) / [Mocha](https://mochajs.org/))中的“test”/“expect”函数。
|
||
- [`Emitter`](/questions/javascript/event-emitter)(它存在于 Node.js 和许多第三方库中)
|
||
- [Immutable.js](https://immutable-js.com/)
|
||
- [Backbone.js](https://backbonejs.org/)
|
||
|
||
如果您查看这些库的源代码,您可能会发现其中一些实现非常复杂。 这是因为该库必须支持许多晦涩的真实世界用例。 与标准函数类似,您不需要在面试设置中处理所有这些边缘情况,但是您获得了调用它们的点。
|
||
|
||
## JavaScript 编码面试期间要做的事情
|
||
|
||
JavaScript 编码面试与算法编码面试有许多相似之处。 一般来说,你应该:
|
||
|
||
1. 查找您正在编码的平台,并熟悉编码环境:
|
||
- 支持的编辑器快捷键。
|
||
- 您是否可以执行代码。
|
||
- 您是否可以安装第三方依赖项。
|
||
2. 1 分钟内进行自我介绍。 除非要求,否则不要花费更长的时间,否则您可能没有足够的时间编码。
|
||
3. 在收到问题后询问澄清性问题。 澄清以下内容: 澄清以下内容:
|
||
- 您可以使用更新的 JavaScript 语法(ES2016 及更高版本)吗?
|
||
- 代码是要运行在浏览器上还是服务器上(例如 Node.js)。
|
||
- 浏览器支持,因为这将影响您可以使用的浏览器 API。
|
||
4. 向面试官提出解决方案。 与编码面试不同,JavaScript 编码面试的重点通常不在复杂的数据结构和算法上。 通过最佳的数据结构和算法选择,可能可以直接跳转到最佳解决方案。
|
||
5. 编写解决方案并在编码时向面试官解释您的代码。
|
||
6. 编码后,一次阅读您的代码,尝试检测基本错误,例如拼写错误,在初始化变量之前使用变量,不正确使用 API 等。
|
||
7. 概述一些基本测试用例和一些边缘情况。 使用这些情况测试您的代码,并确定您的代码是否通过了它们。 如果失败,请调试问题并修复它们。
|
||
8. 可选:如果涉及算法优化和智能数据结构选择,则解释时间/空间复杂度。
|
||
9. 解释您所做出的任何权衡、您明确未处理的案例以及如果您有更多时间可以改进代码的方法。
|
||
10. 面试可能不会在这里结束,面试官可能会有对此问题的跟进问题或给您提供另一个问题。 要为它们做好准备。
|
||
|
||
## JavaScript 编码面试规则
|
||
|
||
1. 通过参考下面的“重要概念”熟悉 HTML、CSS、JavaScript 和 DOM 概念。 [测验部分](/front-end-interview-guidebook/quiz) 也可以是一个好的开始,因为您可能会以测验问题的形式被问到这些概念。
|
||
2. 选择[学习计划](/get-started)并练习所选学习计划推荐的[JavaScript 编码问题](/questions/js/coding/utilities)。 在做问题的同时,也可以学习某个主题。
|
||
|
||
## 重要概念
|
||
|
||
| 类别 | 重要主题 |
|
||
| --- | --- |
|
||
| 数据结构 | 数组、地图、堆栈、树、套装 |
|
||
| 算法 | 二进制搜索、广度优先搜索、深度优先搜索、递归 |
|
||
| JavaScript 语言 | 数据类型(检查类型、类型强制转换)、范围、闭合、回调、如何使用此处关键字、面向对象编程(原型、类、方法),箭头函数与普通函数、通过`Function.prototype.apply()` / `Function.prototype.call()`调用函数,`Promise`,处理多参数 |
|
||
| DOM | DOM 遍历、DOM 创建、DOM 操作、访问元素/节点属性、事件委托 |
|
||
| 运行时 API | 计时器(`setTimeout`、`setInterval`) |
|
||
|
||
## 如何准备 JavaScript 编码面试
|
||
|
||
JavaScript 编码面试类似于算法编码面试,应该采用相似的方法。 自然地,JavaScript 编码面试与评估候选人的方式在某些方面与算法编码面试重叠。
|
||
|
||
- **问题解决**: 有系统和逻辑的方法来理解和解决问题。 将问题分解为较小的独立问题。 评估不同的方法及其权衡。
|
||
- **软件工程基础**: 熟悉数据结构、算法、运行时复杂度分析、使用设计模式、使用干净的抽象设计解决方案。
|
||
- **领域专业知识**: 理解前端领域和相关语言:浏览器(DOM 和 DOM API)、HTML、CSS、JavaScript 和性能。
|
||
- **沟通**: 询问澄清细节并清楚地解释自己的方法和考虑因素。
|
||
- **验证**: 识别各种要测试代码的方案,包括边缘情况。 能够诊断并修复出现的任何问题。
|
||
|
||
## 有用的提示
|
||
|
||
- **虚构的想法**。 JavaScript 的标准库没有一些有用的数据结构和算法,例如队列、堆、二分搜索,这可以使您在 JavaScript 编码面试期间更轻松。 然而,您可以询问面试官是否可以假装这样的数据结构/算法存在,并直接在解决方案中使用它,而无需实现它。
|
||
- **纯函数**。 编写纯函数,这些函数具有可重用和可插入性的好处,即函数不依赖于函数外的状态,并且不会产生副作用。
|
||
- **明智地选择数据结构**。注意您选择数据结构的选择,并了解代码的时间复杂度。 如果要在解决方案中使用基本 JavaScript 数组、对象、集合、映射操作,应熟悉这些时间/空间复杂度。 这些时间/空间复杂度在不同的语言中可能有所不同。 不要编写运行时间为 O(n<sup>2</sup>)的代码,如果可以使用哈希图来在 O(n)运行时间内完成操作,则可以避免此类情况。
|
||
- **`this`很重要**。 如果一个函数接受回调函数作为参数,请考虑`this`变量应该如何行动。 对于许多内置函数,`this`是回调函数调用时提供的参数之一。
|
||
- **回调函数内的突变**。注意回调函数突变正在处理的数据结构。 您可能不需要在面试期间处理此情况,但应在相关情况下明确提出此类情况。
|
||
- **递归边缘案例**。
|
||
- 如果您已经确定解决问题需要递归,请问输入大小以及如何处理递归堆栈溢出的情况。 通常情况下,您不必处理它,但是引起此问题是一个很好的信号。
|
||
- 嵌套深层次数据结构可能具有对它本身的递归引用,这使得某些操作(例如序列化)变得更加棘手。 问问面试官你是否要处理这样的情况。 通常情况下,您不必处理它,但是引起此问题是一个很好的信号。
|
||
|
||
## 最佳实践问题
|
||
|
||
从经验上看,在频率和涵盖的重要概念方面,最佳的 JavaScript 编码面试问题是:
|
||
|
||
- [Debounce](/questions/javascript/debounce)
|
||
- [Throttle](/questions/javascript/throttle)
|
||
- [Array.prototype.filter](/questions/javascript/array-filter)
|
||
- [Promise.all](/questions/javascript/promise-all)
|
||
- [Curry](/questions/javascript/curry)
|
||
- [Flatten](/questions/javascript/flatten)
|
||
- [getElementsByTagName](/questions/javascript/get-elements-by-class-name)
|
||
- [Deep Clone](/questions/javascript/deep-clone)
|
||
- [Data Selection](/questions/javascript/data-selection)
|
||
|
||
GreatFrontEnd 有[全面的 JavaScript 编码问题列表](/questions/js/coding/utilities),您可以练习。 还有可以运行您的代码以验证正确性的自动化测试用例,以及由前 FAANG 资深工程师编写的解决方案。
|
||
|
||
请注意,我们在某些问题中故意含糊不清,并没有在问题说明中全面介绍要求。 但是,我们将在解决方案中涵盖尽可能多的方面。 在阅读解决方案时,如果您发现错过了一些内容,可能会感到沮丧,但是这可以锻炼您的提前思考,并考虑在解决方案工作时需要注意哪些可能区域。 最好在练习期间找出,而不是在实际面试中发现。
|