目前大三,最近刚分手,想着正好沉下心来去搞就业,寒假期间抱着摸自己底的心态去试试面试,海投了许多厂,小厂,中厂,大厂都有,给我的感觉就是大部分内容都是八股,怎么跟别人的面试不一样,本期就来记录下我面试中遇到的那些面试题,希望对大家春招有所帮助
一、聊聊盒子模型
盒模型是css描述布局用的概念,盒子模型有两种,默认情况下为标准盒模型,还有一种为IE或者怪异盒模型,这个是曾经IE使用的盒模型,如今使用需要打上box-sizing: border-box;
对于标准盒模型,一个盒子最终的宽度为width + padding + border + margin
。而对于IE盒模型,一个盒子最终的宽度为width + margin
,也就是说,IE盒模型的宽度其实就是标准盒模型的width + padding + border
,最终自身的真实宽度会被边框和内边距挤掉一部分,当你为了防止盒子被撑大的时候你可以使用IE盒模型
二、vue3的响应式如何实现
vue3的响应式主要是靠es6的代理proxy
来实现的,proxy
可以拦截对象,进行读值操作,能够捕获到数据的修改
reactive
能够将引用类型变成响应式,ref
通常用于将原始数据类型变成响应式,但是ref
也可以将引用类型变成响应式,另外还有个副作用函数effect
,当响应式数据发生变更,副作用函数就会重新执行
三、computed和watch是什么,有什么应用场景
computed
是计算属性,依赖响应式数据,只要发生变更就会重新计算,另外computed
有缓存机制,多次使用计算属性的逻辑时只会执行一次。所以当数据是根据其他响应式数据计算而来的时候,可使用computed
watch
是监听器,监听一个数据的变化,当数据变化时,就会执行一个回调,可以用于处理异步,另外watch
在刚进页面的时候就会执行一次
四、说说你对BFC的理解
BFC全称Block Formatting Context
也就是块级格式化上下文,是css描述块级盒子的一种方式
BFC可以让浮动元素的高度也计算在内,因此常用于清除浮动,另外BFC还可以阻止子元素的margin-top和父容器重叠。
像是overflow: auto | hidden | scroll
以及左右浮动
,还有相对,固定定位
,display: flex | grid | inline-block | table开头的属性
都可以触发BFC
五、浏览器的事件循环
js事件循环机制是浏览器用于处理js代码执行顺序的机制
因为js设计之初仅仅是个脚本语言,所以为了性能,将其定义为单线程,代码一定会有耗时和不耗时代码,也就是异步和同步代码,并且设计师为了更精细地控制异步代码地执行顺序,又将异步分为宏任务,微任务,因此事件循环机制就是描述同步,宏任务和微任务的执行优先顺序
在浏览器的一个事件循环中,先是执行同步,再是执行微任务,最后才是宏任务,之后宏任务又是下一轮事件循环的开启,像是js全局的打印就是一个同步代码,常见的宏任务有三个定时器
,和script
,I/O
,页面渲染
。常见的微任务有promise.then
,MutationObserver
,Process.nextTick
六、浏览器输入url之后发生了什么
先进行url解析,浏览器解析输入的url,提取出协议,主机名,路径等信息
再是dns解析,浏览器将主机名解析成相应的ip地址
然后建立tcp连接,这个过程就是三次握手,确保客户端和服务器之间的连接正常建立
再是发送http请求,浏览器向服务器发送http请求,请求中包括了方法,路径,请求头等信息
然后服务器会处理请求,根据请求的内容进行处理,查询数据库,读取文件
然后服务器会返回响应,将生成的响应数据通过tcp连接发送回浏览器
浏览器接收响应并进行渲染页面,这个过程包括了解析html,css代码生成相应的dom树和cssom树,然后两树结合形成Render Tree
,回流,重绘
断开连接,也就是tcp四次挥手
七、flex:1代表什么
flex: 1
通常用于做分配父容器的宽度,比如做三栏布局时,两边固定写死宽度,中间给个flex: 1
,那么他会继承到中间剩余的所有宽度
不过其实flex是有三个参数的,flex: 1
其实是flex: 1 1 auto
的缩写,第一个参数是flex-grow
也就是放大比例,1代表会放大,也是默认值,第二个参数flex-shrink
是收缩,默认值1代表空间不足时等比例收缩,第三个参数flex-basis
是定义弹性元素的初始大小
八、讲讲diff算法
diff算法就是用在比较两颗虚拟dom树的差异,最小化地对真实dom进行修改,就是找不同。
这个比较过程先是对两颗dom树进行深度优先遍历,然后同级节点比较,比较相同位置地节点,类型属性是否不同,不同则替换,相同继续下去
两个相同类型的节点有不同的属性diff算法也会更新到真实dom,如果两个节点有不同的子节点,diff算法也会递归找到子节点地差异
当比较列表节点地时候,diff算法会尽可能地复用已有地节点,而不是删除再重新创建。另外当diff算法发现某个节点已经不同于之前的虚拟dom树,它会立即停止对改节点地进一步比较,避免性能浪费
九、js数据类型判断
typeof
可以判断除了null之外的原始数据类型,还可以判断函数
instanceof
只能判断引用数据类型,它是通过原型链来查找的
Array.isArray
只能判断是否为数组
Object.prototype.toString.call
可以判断所有的数据类型,返回一个字符串,比较起来会麻烦点
十、手写防抖节流
防抖就是在规定的时间内没有第二次操作,才执行,规定的时间内一直触发,就不会执行。
防抖如下
javascript
function debounce(fn, delay){
let timer
return function(){
let args = arguments
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.call(this,...args)
},delay)
}
}
防抖就是接收一个函数和一个时间,然后在函数中创建一个定时器,如果定时器不存在,那么就会创建一个定时器,并在时间过期之后执行传入的函数,如果定时器存在那么久掐灭这个定时器
节流就是规定的时间内只执行一次,假设手速很快,但是触发事件地速度是恒速
节流如下
javascript
function throttle(fn, delay){
let prevTime = Date.now();
return function(){
if(Date.now() - prevTime > delay){
fn.apply(this,arguments)
prevTime = Date.now()
}
}
}
节流同样,接受一个函数,一个时间,只要两次时间差大于传入的时间才会执行函数,并且只有满足了这个条件,prevTime
才会更新为当前时间
十一、vite为什么比webpack快
vite使用了ES Module
作为开发基础,在开发过程中能够以原生的ES Module
直接加载和解析模块
vite可以在你修改代码后,只重新加载和应用发生改变的部分,而非整个页面,并且当你启动项目时,vite只会加载你正在编辑得文件,而非整个项目,vite只在需要时加载代码,而不是一次性加载所有的内容,并且vite可以缓存已经构建过的代码,下次启动时直接使用缓存
十二、如何解决闭包导致的内存泄露
可以使用WeakMap
或者WeakSet
来存储外部变量,因为二者是弱引用,时刻会被垃圾回收机制回收
如果闭包处于事件处理函数中,可以借助事件委托的机制,将事件处理函数放到父元素上,而非每个子元素上,事件委托就是借助了冒泡的机制
十三、聊聊cookie
cookie
是个小型的文本文件,由服务器端发送到用户的浏览器,并存储在用户的计算机上。cookie
主要是来跟踪用户的会话信息,存储用户的偏好设置
cookie
通常用于身份认证来保证网站资源的安全性,而非大量数据的本地存储,当用户访问一个网站时,服务器会创建一个唯一的会话标识符,存在cookie
中,这样用户在同一网站就可以保持登录状态,不用重复登录
十四、聊聊vue的生命周期
vue的生命周期有如下几个阶段,每个阶段都有两个钩子,除了最后一个销毁,时间一到自动触发钩子
创建阶段:创建之前,初始化选项式api,创建之后
挂载阶段:挂载之前,初始渲染dom节点,挂载之后
更新阶段:更新前,更新后,这里的更新是根据数据源的变化
销毁阶段:销毁前,销毁后,移除所有的监听器
错误捕获:子组件报错时触发
十五、vue中父子组件如何通讯
父传子,需要父组件v-bind
绑定属性用于传值,子组件用props
接收
子传父,需要子组件通过$emit
发布该事件,且携带参数
最后
不知道为什么,面了这么多,很少碰到让我手写,大部分都是聊八股和项目。
当然,如果你对春招感兴趣,可以加我的个人微信:
Dolphin_Fung
,我和我的小伙伴们有个面试群,可以进群讨论你面试过程中遇到的问题,我们一起解决
另外有不懂之处欢迎在评论区留言,如果觉得文章对你学习有所帮助,还请"点赞+评论+收藏"一键三连,感谢支持!