扯皮
不知不觉,秋招提前批已经开始了,学了这么久,也该真刀真枪干一场了吧。当我满怀期待,去BOSS直聘投递简历的时候,那叫一个紧张啊,我随便点击了一个回复率高的,当我准备立即沟通,投简历的时候,我慌了,我怕他立马与我联系面试,而我还未准备好我的面试,到时候问起来,啥都不会,那不是非常的尴尬。。。。看着那划不到尽头的前端实习岗位招聘,我就知道我没有选错了专业,果然,不出意外的话,意外出现了,投递了两天,发出去三十来份简历,沟通几百次,竟无一通知我面试,我又慌了,是不是我简历出现问题了,和我一起学习的朋友,都已经面了好几场了,于是我问来了他的简历,稍加修改后,我又再次启程,在第三天的时候,果然被约面了。。哈哈哈哈,下午四点半,卧槽,来的也太快了。来不及准备了都,就这样,我的第一次...面试,被人拿下了。
面试题
自以为看了几场别人的面试后,感觉也就那样啊,简简单单的我也会。可在等待面试的时候,慌啊,同学说不要慌,多面几次就好了,刚开始回答会紧张,当你回答了一两个问题后就不会了,也就能适应这个面试了。。。
1. 自我介绍
自我介绍这部分就靠自己,按照,我是谁、我是如何学习的、我有什么奖项、我对近三年的未来规划等等,都可以说。
2. 闭包,闭包的优缺点和使用场景
根据作用域的规则,内部函数总是可以访问外部函数中的变量,又有当一个函数执行完毕后,该函数的执行上下文会被销毁,那么为了同时满足这两个规则,闭包这个概念就出现了,当内部函数被拿到外部函数之外调用,即使外部函数执行完毕,它也不会完全销毁,它的部分变量可以被内部函数引用,那些被内部函数引用的部分变量会以一个集合的方式被保存在调用栈内,这个集合就叫做闭包了。
优点:创建私有变量,延长变量的生命周期。
缺点:内存泄漏
- 应用场景:封装模块、防止全局变量污染
3. 如何清除浮动
浮动主要是因为元素设置float属性,从而导致元素脱离文档流,父容器由于子元素脱离文档流而导致本身的高度坍塌,出现了由于浮动带来的影响,所以清除浮动就是清除浮动带来的影响。
- 利用clear样式
- 父元素结束标签之前插入清除浮动的块级元素
- 利用伪元素after
- 将浮动元素的父容器设置为BFC容器:
- overflow:hidden || auto || overlay || scoll ,当overflow不为visible时,容器会成为bfc容器
- float:left || right
- display: inline-block || flex || inline-flex
- position: absolute || fixed
4. 防抖/节流,以及它们的应用场景
防抖和节流都是对事件多次触发的一种优化,它们的区别在于触发的时间不同,防抖是触发事件后,在指定的时间内,如果事件再次触发则重新计时,直到指定的时间结束后才执行,所以在一定时间内只执行一次。而节流则是指定一个时间间隔,在指定的时间间隔内,如果事件再次触发,则不执行,直到指定的时间间隔结束后才执行。
应用场景:搜索框的动态请求,防抖和节流都可以使用,图片懒加载需要节流来限制事件触发的次数。
5. promise与async/await的区别
- promise是一个对象,通常是通过new来创建,传入一个回调函数,回调有两个参数,resolve,reject,但promise有三个状态,pending(执行中),fulfilled(完成),rejected(拒绝、失败),
- async await 可以强制把一个异步函数执行成一个同步函数,其本质也是promise,不能被使用在普通回调以及节点回调
- async await 比 Promise 写起来更加优雅,更像同步代码
6. React的生命周期
它的生命周期分为三个阶段,mounting(挂载),updating(更新),unmounting(卸载)。
-
mounting(挂载):componentWillMount、componentDidMount组件状态的初始化,读取初始 state 和 props 以及两个生命周期方法,只会在初始化时运行一次。
-
componentWillMount 会在 render 之前调用(在此调用 setState,是不会触发 re-render 的,而是会进行 state 的合并。因此此时的 this.state 不是最新的,在 render 中才可以获取更新后的 this.state。)
-
componentDidMount 会在 render 之后调用
-
-
updating(更新):组件的更新过程是指父组件向下传递 props 或者组件自身执行 setState 方法时发生的一系列更新的动作.
-
组件自身的 state 更新,依次执行
- shouldComponentUpdate(会接收需要更新的 props 和 state,让开发者增加必要的判断条件,在其需要的时候更新,不需要的时候不更新。如果返回的是 false,那么组件就不再向下执行生命周期方法。)
- componentWillUpdate
- render(能获取到最新的 this.state)
- componentDidUpdate(能获取到最新的 this.state)
-
父组件更新 props 而更新
- componentWillReceiveProps(在此调用 setState,是不会触发 re-render 的,而是会进行 state 的合并。因此此时的 this.state 不是最新的,在 render 中才可以获取更新后的 this.state。
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
-
-
unmounting(卸载): 组件的销毁过程,只会运行一次,可以用来做一些收尾工作,比如清除定时器,清除事件监听。
- componentWillMount(我们常常会在组件的卸载过程中执行一些清理方法,比如事件回收、清空定时器)
react我也不是很熟悉,所以需要看react的面试题可以去看2024前端高频面试题之-- react篇 - 掘金 (juejin.cn)
7. vue2和vue3的区别
- 源码组织方式:vue3比vue2更加兼容TS,因为vue3就是用TS写的。
- 响应式源码变化:vue2的响应式使用的是defineProperty,vue3的响应式使用的是Proxy,Proxy的优点可以直接监听对象的属性,而defineProperty只能监听对象的属性,不能监听数组的变化。
- vue2使用的是选择式api,而vue3使用组合式api,基于函数的api更加灵活的组织组件逻辑
- 打包体积的优化:vue3的打包体积更小,因为vue3的源码更加简洁,且移除了很多不常用的api如(filter,inline-template)
- 在生命周期上 vue3的setup语法糖代替了之前的beforeCreate和created。
- vue3的template支持多个根标签
- Props 的使用变化:vue2 通过 this 获取 props 里面的内容,vue3 直接通过 props
8. event loop
它是事件循环机制,当遇到异步任务时,会将异步任务放入event loop中,当主线程执行完毕后,也就是同步任务都执行完了,会去event loop中取出异步任务执行。
- 在异步任务中,又存在宏任务和微任务:
- 宏任务也就是普通的异步任务,包括:script,setTimeout,setInterval,ajax,dom事件,UI渲染。
- 微任务包括:promise,async/await 等。
下面是较为准确的解释了整个Event loop:
JavaScript Event Loop的基本组成:
- Call Stack(调用栈):存储正在执行的同步代码的上下文。
- Web APIs :浏览器提供的一些异步API,例如
setTimeout
,fetch
,DOM
事件等。 - Message Queue(消息队列):存放待处理的回调函数。
- Task Queues(任务队列):存放各种类型的异步任务,比如定时器、I/O操作等。
- Microtasks Queue (微任务队列):存放需要立即执行的任务,如
Promise
的回调。
Event Loop的工作流程:
- 初始阶段:JavaScript引擎开始执行脚本中的代码,同步代码依次压入调用栈。
- 异步事件 :当遇到异步操作(如
setTimeout
、fetch
请求等),会将其注册到Web APIs,并继续执行后续的同步代码。 - 执行回调:当异步操作完成时,它们的回调函数会被放入消息队列。
- 循环检查:当调用栈为空时,Event Loop会检查消息队列是否有等待处理的任务。如果有,则将队列中的第一个任务移出并压入调用栈执行。
- 重复步骤:重复上述过程直到消息队列为空且没有更多的异步操作需要添加到队列中。
- 微任务处理:在每个宏任务执行完成后,Event Loop还会检查微任务队列,执行其中的所有微任务。
示例:
javascript
console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve().then(() => console.log('Promise'));
console.log('End');
输出顺序:
Start
End
Promise
Timeout
这是因为Promise
的回调作为微任务会在当前宏任务结束时立即执行,而setTimeout
的回调作为宏任务会在当前宏任务栈清空后才执行。
9. vue的虚拟DOM,为什么需要虚拟DOM
虚拟 DOM 是一种在内存中表示真实 DOM 树的数据结构。在 Vue.js 中,虚拟 DOM 通常是一个 JavaScript 对象,这个对象代表了一个 DOM 节点,包含了该节点的所有属性和子节点的信息。
Vue 使用虚拟 DOM 来提高渲染效率。当应用的状态发生变化时,Vue 会创建一个新的虚拟 DOM 树,并与之前的虚拟 DOM 树进行比较,找到最小的变更集,最后只对真实 DOM 进行必要的更新。这种方法避免了频繁地直接操作真实 DOM,从而减少了重绘和回流,提高了应用的性能。
10. 浏览器渲染过程
这一过程涉及多个步骤,主要包括解析、构建渲染树、布局、绘制和复合等阶段:
-
解析 HTML:浏览器从服务器获取 HTML 文件后开始解析文档,构建 DOM 树。在解析过程中遇到外部资源(如 CSS 和 JavaScript 文件)时,浏览器会发起额外的网络请求来获取这些资源。
-
解析 CSS:当 CSS 文件被加载并解析时,浏览器会构建 CSSOM (CSS Object Model)。CSSOM 描述了页面中的样式规则以及它们是如何应用于各个元素的。
-
构建渲染树 :渲染树是由 DOM 树和 CSSOM 结合而成的数据结构。它包含所有可视元素及其样式信息。 非可视元素(如
script
标签或head
中的内容)不会出现在渲染树中。 -
布局(Layout/Reflow) :布局是确定页面上每个元素的位置和尺寸的过程。浏览器计算每个元素的位置、大小以及其他几何属性。修改页面结构或样式可能会触发重新布局(reflow)。
-
绘制(Painting/Repainting) :绘制是将渲染树中的元素绘制到屏幕上。每个元素都会被绘制到一个层中,然后组合在一起形成最终的画面。修改元素的视觉属性可能会触发重绘(repainting)。
-
层叠与合成:浏览器将不同的图层(Layers)组合在一起,形成最终的可见页面。图层可以是元素的一部分或整个元素,取决于浏览器如何优化渲染过程。复合过程发生在 GPU 上,它将各个图层组合成最终的像素。
-
交互:用户与页面交互时(如点击按钮或滚动页面),浏览器需要重新执行上述一些步骤,如重新计算布局或重新绘制元素。
好了,今天的分享就到这里,都是一些常见的面试考题,还有几个题目没有写上来,我留着慢慢啃,学会了就发到下次面试题里。最后,希望在找工作、找实习的同学,都能找到自己满意的工作吧,漫漫长路,唯有前行!