前端面试宝典React篇01 如何拿下大厂前端面试

发布于:2022-12-22 ⋅ 阅读:(225) ⋅ 点赞:(0)

你好,我是伯约,一名前端面试官,也是一位资深的前端实践者。

我长期钻研大型前端应用架构与性能治理,参与过诸多企业级项目并成功搭建适用于多个 BU 的前端中台,拥有丰富的实战经验,平时关注主流前端框架的发展和实践。近几年,我也在负责新同学的面试把关,以及人才梯队建设,对前端朋友的成长与困惑有一些切实的体会。

近几年,随着前后端的分离,前端的工作越来越专业化,各大互联网公司对前端工程师的要求也越来越高,一个岗位宁缺毋滥。面试时,也越来越偏向于“考原理,抠细节,挖深处”。

在这样严峻的环境下,作为前端工程师,想进大厂不仅需要掌握一定的底层原理,还需要触类旁通,具备高效解决技术难题的能力。

就拿我自己面试新同学的经验来说,失败的应聘者基本分为两大类:

  • “小白”,这部分人群基本都输在没什么项目经验上,回答的基本都是一些死记硬背的答案,没有结合项目的理解;

  • 经验老到的求职者,他们参与的项目少则十几个,多则数十个,但最后仍与 Offer 失之交臂,主要是因为他们缺乏对技术栈的深入思考,只流于表面上的使用

就比如,我问到 React 组件设计相关问题时,有经验的求职者会讲到函数组件、纯组件、类组件等,这类问题大部分人都可以答上来。如果我进一步追问高阶组件与渲染劫持(Render Hijack)相关的内容,能够回答上来的人就大大减少了。

关于前端面试,应该从何下手?

这不只是初入前端的同学会有的疑问,从事多年开发的同学依然会有这样的问题。

在面试的准备阶段,如果你还只是拼命地刷面试题,显然是不够的。在真实的面试中,面试官往往会在一个知识点的基础上,横向或纵向地追问,狠抓知识盲区,打得你措手不及。所以,切忌通过点状的、零散的知识点去完成学习与记忆,一定要通过横向比较、纵向延伸的方式建立知识体系,通过体系化学习逐步填充知识盲区。

这也验证了一句话:正确的方式比学习本身更重要,也使学习更高效。那么怎样的方式才是正确的呢?我们应该从哪里学起,从哪里看起呢?

我在面试的时候,无论这个同学是否通过,都会在最后问一下求职者的学习方式。我发现大家一般是从书籍、网络社区及微信公众号这 3 个渠道来学习的。书籍的内容虽然是成体系的,但有一定的滞后性。而网络社区与公众号呈现的内容就过于零碎,需要自己去整理、完成知识体系建设,但好处是足够新,紧跟当下。

这就导致一个很“分裂”的情况:看书跟不上潮流,看网文难以积累。你很难从这些内容中真正学到更深层次的知识,久而久之大家便形成了前端知识不必深究、浅尝辄止的态度。

当然还有一种情况是你知道知识点,但不能准确完整地表达、不知道该如何描述。但当面试官提起的时候,又能记忆起来,说,“对对对,就是那个,我刚确实不知道该怎么讲”。这种情况非常多,我个人觉 得,这说明你并没有真正地理解知识点,只是囫囵吞枣般学习而已,知识点与代码并没能在你的脑海中建立完整的映射关系。

这两点都限制了我们对前端的学习。我们应该从日常的开发问题中,从面试的问题中去学习,通过反思与复盘不断学习成长,这也是我设计该课程的核心。这门课我以应用较广的 React 为切入点,结合自己多年的面试经验,以大厂真实面试题为例,带你归纳总结解题思路和方法,融会贯通掌握前端面试技巧,助你拿下大厂前端 Offer。

这个课程是如何设计的?

在纵向深挖问题的同时,为了解决知识点零散的痛点,我也会帮助你基于树状结构去掌握知识点的底层原理,以及它们之间的深层次联系,通过不断补全技术栈的方式带你攻克瓶颈。比如 React 的主要内容有以下几点:组件基础、状态管理、渲染流程等。

Drawing 0.png

在组件基础上,我们还会再进一步延伸出更细的点:

Drawing 1.png

基于树状的知识体系,可以使我们的学习更为轻松、快捷,记忆也更为牢固。因此,我将专栏设计为 6 大模块,合计 20 讲,通过“分析题干”->“构建知识导图”->“横向技术对比与纵向原理解析”->“答题文案”的方式,和你逐步梳理 React 的学习要点。

  1. 组件基础( 01 ~ 05 ):从经典面试问题入手带你梳理组件的设计原理与思路,帮助你掌握分析和解决问题的技巧。

  2. 状态管理( 06 ~ 08 ):从状态的理解、运用与工程化实践入手,帮助你真正理解 React 的状态管理。

  3. 渲染流程( 09 ~ 12 ):只有理解渲染流程,才能做出正确的性能优化。该模块可以加强你对 React 工作模式的理解程度。

  4. 性能优化( 13 ~ 15 ):从工程化的视角阐述性能优化问题,带你掌握中高级职位必杀技。

  5. React Hooks( 16 ~ 18 ):解析 Hooks 的原理,API 的区别及最佳的设计模式,帮助你完美胜任组件模式向 Hooks 转移的工作。

  6. React 生态( 19 ~ 20 ):讲解面试必考的 React-Router 以及常用的工具库,带你探索 React 生态圈,帮助你掌握经过时间和大型项目验证的 React 工具。

最后,我还会专门有一讲内容,来告诉你如何编写一份 HR 满意的简历,帮你顺利敲开大厂面试的大门。

当然,你也可能会担心,课程是否会有所遗漏、是否会过时。但如果深入学习,你会发现课程是在训练一种可以在学习中复制的思维。正如前面所说,正确的学习方式比学习本身更为重要,当我们掌握了正确的学习方式,那将会是一把强大无比的武器,不断地促使我们前进。

讲师寄语

在拿下大厂 Offer 之前,我同样经历过一个背答案、记答案的过程,但收效甚微,在日后的工作中我发现那并不是一种高效的方式。在更新越来越快,大家越来越学不动的时代,学习方式越来越重要,所以这门课我不仅希望帮你解决面试的问题 ,更希望带你提升学习的能力,提升技术软实力。

在学习和实践的过程中,你可能会遇到一些问题。请不要担心,你可以随时在评论区留言和提问,我会尽量抽出时间来认真解答你的提问。但我也希望你能在提出问题的同时,用本课程的思维方式对问题有一个完整的阐述。这样就不只是你问我答,而是在自问、在复盘、在自驱前进,如果你能到达这样一种学习状态,那就可以毕业了。

最后,希望你能通过这一专栏的学习,实现自己的“大厂梦”。

《大前端高薪训练营》


精选评论

*峰:

一直在用vue,之前就想抽时间把react学一学,看到这个课程,果断买下,希望能学到一些东西,以及面试的技巧

*磊:

面试的时候,技巧真的太重要了。真的像开篇词里面说的,正确的方式比学习本身更重要,希望能通过这个课程学到一些面试的技巧

**毅:

想起了我之前,在面试前一般都是在网上搜搜面试题,但是在面试中,根本应对不了面试官的提问。

**珍:

老师,请教一下为什么很多基础知识都理解了,然后记不住,记下一段时间后又很快就忘了

    讲师回复:

    人的记忆路径是网状的,如果没在脑海中建立起一个知识体系树,那很快就会被遗忘。
在小学阶段,中学阶段,这棵树是由多年教导经验的老师来负责帮你建立的,再通过不断刷题的模式深深的印在你的脑海里。比如讲到力,受力分析,摩擦力,引力等等,它们是在一个体系中的,还有各种知识细节。
但如今前端的所有知识都需要靠你自己去总结,你很难建立知识点间的联系,也没有试卷让你确认自己是否已经掌握了。
这对于已经脱离校园,处于职场中的人来说,是最大的挑战。

*利:

之前有面试过几个大厂,都问到过react的一些东西,当时答得不怎么好,买个课程来补习补习,期待

*秋:

在自问、在复盘、在自驱前进,写的真好,共勉。

**俊:

用于生产.前端react 开发移动端一般使用哪个 ui 库会比较好?

    讲师回复:

    没什么太方便的ui库。。。移动端一般主打c端,有样式要求。如果是后台产品,用antd Mobile 吧

**莹:

用过vue,想来接触一下react

    编辑回复:

    技多不压身,加油

你真的了解 React 吗?我们在面试中往往涉及 React 时,第一个问题就是“解释 React 是什么”。解释一种技术是什么,在面试中也是非常常见的引起 话题的题目。所以本讲我就带你通过讲解“如何解释 React 是什么”,让你掌握这一类概念题在面试中的解答技巧。

破题

“如何解释 React 是什么?”还有一种常见的问法是这样的:“谈一谈你对 React 的理解”。

这个题目看似很容易,却很不好回答,因为大部分人拿到这个问题首先会“线性思考”,即一种直线的、单向的思维方式,表现为:想到哪儿讲到哪儿,缺乏全盘考虑。然后凭直觉作答,这样显然是不行的。可以看看这样一个在面试中很常见的场景。

面试官:如何解释 React 是什么?
应聘同学:React 是一个库。
面试官:对,能再补充一点吗?
应聘同学:React 的特点是声明式、组件化、一次学习随处编写。
面试官:还有再补充的吗?
应聘同学:React 的原理是……

很显然,在这个场景中,你已经失去了主动权,不断地被外界推着往前走。甚至最后你已经不是在回答 React 是什么了,而是跑到另外一个问题去了。看似简单的提问其实不仅能反映出你对 React 的了解程度,还能反映出你在工作中的状态以及思考问题的思路:

  • 你是出现一个问题解决一个问题,不断被外界推着线性往前走;

  • 还是能够高屋建瓴地思考全局。

你在工作中是不是也有类似的感觉?比如刚接触新技术的时候和变成熟手之后会有些不同的认知与感悟。就像老话说的一样:

参禅之初,看山是山,看水是水;禅有悟时,看山不是山,看水不是水;禅中彻悟,看山仍然山,看水仍然是水。

所以本题同样考察了你对 React 的理解度,是否有“看山水”的那种变化。理解到了这一层意思,那么就完成了破题的第一步。但仅到这一步仍然是不够的,还需要在表达上有方法论的支持。

就像开篇所描述的场景:对概念很熟,对知识点也很了解,相关工具不知道用了多少次了,但面试的时候,突然整个人就拧巴了, 不知道怎么讲。那就是因为缺少相应的方法论,所以才会出现知道是什么,而无法清晰地表达的情况。所以我们既要重视知识本身,也要重视表达方法。

对待这类概念题,讲究一个四字口诀“讲说理列”,即“讲概念,说用途,理思路,优缺点,列一遍” 。

  • 讲概念:用简洁的话说清楚该技术是什么。最好能用一句话描述。

  • 说用途:描述该技术的用途。能够具体结合适合场景,拓展性的描述。

  • 理思路:梳理该技术的核心思路或运作流程。这个地方可深可浅,如果对其有足够深入的了解,建议详细地展开说明。

  • 优缺点,列一遍:对该技术栈的优缺点进行列举。列举优缺点肯定有与其他技术方案横向对比的过程,那么在这个过程中,切忌刻意地踩一捧一,容易引发面试官的反感。

这是本题第二个重要点,即表达的技巧,也是本专栏的一个重要主题:不只是梳理知识,更要学会如何回答问题。

破题是一个思维发散的过程,接下来需要把上面思考的内容收一下。

承题

现在从上面“碎碎念”的思考中整理一下信息,即采用非线性的结构化模式阐述答案。基于上面我们说到的“四字口诀”这一表达技巧的基础上,就非常容易延伸出我们作答的大体框架。

  • 讲概念需要讲什么?讲技术本质。

  • 说用途是说什么?说使用场景。

  • 理思路是理什么?理核心技术思路。

  • 列优缺点是列什么?是通过对比调研业界流行的技术方案,去发掘 React 的独特优势,去找出 React 的缺点。

Drawing 1.png

知识导图

入手

根据以上的分析,接下来我带你一一进行拆解。

概念

回归本质,React 是一个网页 UI 框架。当然这样一个随处可见的回答并不能令人满意,我们需要回顾历史去寻找答案。

React 诞生于 jQuery、AngularJS 与 Backbone.js 相继流行的时代。jQuery 诞生于 2005 年,浏览器兼容性是当时最大的问题。为了解决这个问题, jQuery 封装 DOM 操作,提供样式选择器,封装了 AJAX、链式操作等大量基础函数。但从如今的视角来看,jQuery 并没有解决代码如何组织的问题,甚至不能称之为框架,本质上它只是一个工具函数合集

因为无论是从 jQuery 输入端,还是输出端来看,一切都是混沌的。HTML、CSS、JavaScript 就像原料一样送入 jQuery 搅拌机,拌着拌着拌出一个网页。你会发现并没有一个可以称之为模式的方式将这些原料有序地组合在一起,因为这并不是 jQuery 能够解决的问题。

Drawing 3.png

jQuery 代码组织方式

当然,这段时间网页还不够复杂,效果还不需要做得很酷炫。然而当 PC 的性能越来越好,页面变得越来越复杂,前端的工程也开始庞大了起来。如何组织代码结构,如何有效提升复用率,开始成为大家亟待解决的问题。

2009年,AngularJS 横空出世,带着 Java 开发的先进经验闯入了前端的世界中。 它不仅引入了 MVC 的思想,还强行灌入了 controller、$scope、service 等一系列概念。如同 Spring Boot,AngularJS 提供了一揽子全家桶解决方案,从底层开始深度封装,向上提供了路由、双向绑定、指令、组件等框架特性。

AngularJS 的分层设计是齐全且优秀的,覆盖了整个 Web 开发的方方面面。MVC 它有,数据绑定它有,前端路由它有,表单校验它有,设计模式它也有,内容多到像一本百科全书。如下图所示。

Drawing 5.png

AngularJS 分层设计图

但也正是因为它庞大复杂的概念,你在使用 AngularJS 进行开发的时候,需要编写大量的面条代码,你会感觉自己并不是在写前端,而是在写 AngularJS。jQuery 时代和 AngularJS 时代,一个最明显的区别在于,jQuery 时代是与浏览器斗争,而 AngularJS 时代,更像是与 AngularJS 斗争。代码如何组织是清晰了,可数不清的概念,让 AngularJS 看起来更像一个披着前端皮的 Java 框架。甚至会有人感慨,这一切值得吗?

当然也有值得的地方,AngularJS 的双向绑定就是当时最大的特色。双向绑定在中后台网页开发中极大地提升了开发效率。中后台页面几乎全是列表与表单,双向绑定使值与视图动态可以自动更新,节约了几乎一半以上手动编写代码的时间。

时间继续往前走,来到了 2010 年,如果你希望自己的代码有序地组织起来,又不想陷入 Angular.js 无穷无尽的概念中,那么 Backbone.js 就是一个很好的选择。它并没有像 AngularJS 那样带来大量概念,还考虑到了两个方面:

  • 与前代的亲和性,只要你懂 jQuery,你就可以继续快乐地写前端代码,而不需要再学习一种语言;

  • 它考虑了代码的组织性,引入了基础 MVC 的概念,同时提供集合与前端路由的封装,补齐了 jQuery 无序的短板。

所以对于初学者而言, Backbone.js 非常友好,甚至一度流行。选择 Backbone.js 的最主要原因是它使前端项目工程化的成本足够低。这个“低”不光是指开发人员的学习成本低,还有改造成本低,因为大量的 jQuery 存量项目都可以尝试迁移。

Drawing 7.png

Backbone 的结构图

回顾历史会发现,前端项目在不断地工程化,同时也不断地发展出新的概念。但这两个问题还是难以解决:

  • 与后端不同的是前端主要以 UI 组件为基础,需要一个可以使组件复用的开发方案,过去常见的复用方案是拼装模板;

  • 前端工程越来越庞杂,组件作为基本单位应该是可以通过编写单元测试来维持稳定性的。

基于过去的模式,要做到这两点是非常困难的。你会发现过去的框架通常是从页面的维度去思考,然后零星装上 jQuery 的各种小插件。

初次接触 React 的同学会发现,开发 React 的思维模式是完全不同的,概念也极为简单。如果用一个非常简洁的公式来表达,那就是:

View = fn(props)

这个公式表达了给定相同的输入状态, 函数总是会生成一致的组件。只有做到输入与输出恒定,那么它才是可测的。

其次 fn 内部也可以是无数个组件构成的。React 中只有组件,没有页面,没有控制器,也没用模型。没有页面?那就用组件组合生成一个页面,没有控制器,那就用组件充当控制器。就像搭建乐高玩具一样。

当然 React 的变量会更多一些,将 state 和 context 考虑进去,那也是可以表达的:

View = fn(props, state, context)

从实际编码上来讲,fn 可能是一个类组件,也可能是纯函数组件,也可能在函数中产生影响 UI 生成的副作用,比如直接操作 DOM 或者绑定事件等。经典公式总是会展示理想情况,就像 E=mc² 简化了大量的外界干扰因素,但这不妨碍它表达了一个结论,即在 React 中只需要关心两件事:数据与组件。

那为什么会把基本单位定位于组件呢?如果对设计模式有印象的话,你是否还记得“组合优于继承”的铁律?即在构建 UI 视图时,组合组件始终是最优的解决方案。

而 React 是通过组件化的方式解决视图层开发复用的问题,本质是一个组件化框架。

用途

React 的用途当然是构建视图啦。由于 React 虚拟 DOM 的关系,在适用场景上远比传统框架更为广泛:

  • 首先无论是 PC 网页还是移动端网页,都是完全支持的;

  • 其次由于 React Native,也可以用于开发 iOS 与 Android 应用;

  • 还有 React 360 可以开发 VR 应用;

  • 冷门儿的如 ink,也可以使用 React 开发命令行应用。

React 的生态极大地丰富了其使用场景。

核心思路

React 的核心思路有三点,分别是声明式、组件化与通用性(官方称之为:一次学习,随处编写)。

声明式

声明式编程的优势在于直观,可以做到一目了然,也便于组合。

如果是命令式编程,那么会是这样:

// HTML
<div class="block"></div>
// JS
const block = $('.block');
block.css('color', 'red');

如果是 React,则会这样写:

const Block = (props) => <div style={{ color: 'red' }}></div>

相较于上面的写法,Block 不仅结构上更容易阅读,而且更容易与其他组件代码进行组合。

组件化

组件化可以降低系统间功能的耦合性,提高功能内部的聚合性。对前端工程化及代码复用有极大的好处。React 组件化最大的区别在于没有使用模板进行编写,而是采用了声明式的 JSX。

通用性

这就要说到 React 的虚拟 DOM。React 将 DOM 抽象为虚拟 DOM,开发者并不会直接操作 DOM。正因为有这样一层封装,使得 React 不再局限于 Web 开发,而能走向更宽广的平台,出现更繁荣的生态。无论是 Native、VR 还是 Shell 命令,只要兼容虚拟 DOM 层,那么都可以直接运行 React。详细内容可以查阅第 09 讲。

优缺点

其实核心设计思路就是 React 的优点:声明式、组件化与通用性。

当然 React 也有缺点, 由于 React 并不是一个一揽子框架,比如路由一类的功能,React 团队更希望交给社区来解决。所以导致在技术选型与学习使用上有比较高的成本。但也正因为社区蓬勃发展,非官方的一揽子解决方案还是有的,比如 DvaJS、React-coat 等填补了生态位的缺失。所以 React 也是一个使用者上限与下限差距极大的框架。

答题

经过以上的梳理,我们可以尝试答题了。

React 是一个网页 UI 框架,通过组件化的方式解决视图层开发复用的问题,本质是一个组件化框架。

它的核心设计思路有三点,分别是声明式、组件化与 通用性。
声明式的优势在于直观与组合。
组件化的优势在于视图的拆分与模块复用,可以更容易做到高内聚低耦合。
通用性在于一次学习,随处编写。比如 React Native,React 360 等, 这里主要靠虚拟 DOM 来保证实现。
这使得 React 的适用范围变得足够广,无论是 Web、Native、VR,甚至 Shell 应用都可以进行开发。这也是 React 的优势。
但作为一个视图层的框架,React 的劣势也十分明显。它并没有提供完整的一揽子解决方 案,在开发大型前端应用时,需要向社区寻找并整合解决方案。虽然一定程度上促进了社区的繁荣,但也为开发者在技术选型和学习适用上造成了一定的成本。

回答到这里基本就差不多了,但在面试的时候,我们可以尝试拿到更多的主动性,即补充类似如下的回答:

  • 承接在优势后,可以再谈一下自己对于 React 优化的看法(详细内容可参考模块四)、对虚拟 DOM 的看法(详细内容可参考第 09 讲);

  • 向自己主导过的 React 项目上引导,谈一谈 React 相关的工程架构与设计模式(详细内容可参考第 18 讲)。

整体的面试时间总是固定的,所以如果有机会的话,尽可能展示你最熟悉的知识点和最丰富的实践案例。

总结

本讲主要讲解了“如何解释 React 是什么”这样一个看似简单却又很难解释的问题。“如何解释 React 是什么?”反映了面试者对 React 的认知水平,常用来快速划分面试者层次。通过这一讲你可以掌握 React 的核心设计思考,了解与其他框架的区别,更重要的是使用非线性的结构化思考模式来回答考官的这一类问题,这一点比答案本身更重要。

在本讲中提到了“声明式”这样一个概念,那 React 在组件中是如何展现“声明式”的呢?接下来的 02 讲我们会讲这个问题。

《大前端高薪训练营》


精选评论

*志:

心里有个大厂梦已经很多年了,但是无奈老是面试通不过。读了第一篇,真的发现自己之前是技巧不够,全靠死记硬背了。期待更新

*聪:

请教一下老师,React官方的描述是一个用于构建用户界面的 JavaScript 库,这里我们如果说是UI框架,会不会有点不妥?

    讲师回复:

    会!说得很好,确实不妥(为你的细心鼓掌)。
我在写的时候也犹豫过这个问题,但 React 确实在往框架的方向走,比如最近的 React Server Components,我感觉已经超出了库的范畴了。
所以还是该遵循官方说法吧?要不要修正下呢?苦恼。

*依:

.面了几家大厂后,真的发现大厂的面试和小公司的面试差别太大了。只是简单的回答概念根本不行,大厂会追根究底的盘问,对一个知识点需要深层次的理解

**飞:

react是一个视图层,而且仅仅是视图层中的一部分,要想组织好一个好的web应用,还要涉及到路由,状态管理和数据处理等各个方面,在这些不同的方面可以挑选自己或者团队或者项目最适合的框架来组合。而组合的结果往往取决于工程师本人的决定。而在一定程度上的解耦可以让我们更加专注于某个方面!

Dave:

看专栏各个模块内容的设置,真的是干货呢,都是react一些必学的东西,期待接下来更进一步的学习

*浩:

老师对于面试这块的针对性还是很强的

**6352:

学了很多关于工程化的知识。一直搞不清楚什么是工程化。得到上也在说这个,百度也搜过,总是不得要领。想听听老师对这个的理解

**峰:

豁然开朗,看入迷了。我得吃饭去了。😂

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到