前端面试准备

190 阅读14分钟

1、js基础知识(手写代码) Q:js 数据类型有哪些,函数是按值传递还是引用传递,symbol数据类型有了解过吗,应用场景有哪些 ?

Z: 原始数据类型有:booleanstringnumberundefinednullobjectsymbol

    函数传递参数是引用传递,但是如果把传递进来的参数,赋值给另外一个变量,函数执行过程中,会重新分配一块地址

    sysbol是es6新定义的一种新的数据类型,目的是为了防止对象属性名冲突,保证对象的属性名都是独一无二的



 Q: typeof 和instanceOf判断有什么区别,instanceOf判断的原理 ?

 Z:typeof运算符只能判断基础的数据类型,'string''number''boolean'instanceof运算符是根据原型链来判断,本质其实是检测某个实例对象原型链上,是否存在构造函数的protptype属性



Q:严格模式下的this指向哪里?

Z:1.全局中,this指向window,全局函数中this指向undefined

    2.构造函数中的this指向调用它的实例

    3.事件处理函数中的this, 指向出发事件的对象节点



Q:数组和对象深浅拷贝的方法都有哪些,深拷贝大概的实现思路?

Z:实现浅拷贝的方法有:object.assign()、展开运算符(...)

    当要实现一个深拷贝的方法,实现思路分为拷贝+递归,判断当前属性是否是对象(Reflect.ownKeys),如果是对象,就进行递归操作。

    在拷贝的过程中,要注意处理这几种情况 

    1.深拷贝数组的情况

    2.考虑null的情况

    3.考虑Symbol的情况

    4.考虑循环引用的情况



Q:如何理解原型和原型链

Z:原型是一个对象,存有对象上所有的共有的属性和方法,然后让每个对象的_proto_属性去存这个地址,其实原型的出现是为了减少不必要的内存开销

   原型链就是通过_proto_向当前实例所属类的原型上查找属性和方法的机制,如果找到object原型上还是没有找到想要的方法或者是属性就查找结束





Q:proxy了解过吗,可以实现哪些功能 ?

Z:proxy用来创建对象的代理,vue3将会通过proxy来实现数据响应式,vue3要用proxy代替原本的api,不必要一层层递归为每个属性一层层添加代理,一次操作,原本更新监听不到的操作就可以监听到了,性能更好,缺陷就是浏览器的兼容性变差了



Q: js 有几种方式实现异步 ?

Z:回调函数,假设多个请求具有依赖性,容易导致回调地狱

    promise,实现了链式调用,如果在then中return,那么会return的值将会被Promise.resolve()包装

    async/await ,实际上是一个语法糖,async 其实会返回一个promise, await在等待函数内部返回的promise对象或者其他值,应用场景一般使用在,有一个函数的执行,每一步都依赖上一步执行完成再去执行



Q:手写promise实现的思路 ?  (笔试题),手写new,



Q:event loop 执行顺序 ?

Z: 1.一个脚本作为宏任务先执行

    2.执行过程同步代码先执行,宏任务进入宏任务队列,微任务进入微任务队列,

    3.宏任务先执行完开始执行微任务列表,直到全部都执行完

    4.检查浏览器ui线程渲染工作

    5.检查是否有web worker,有就执行

    宏任务:script, settimeout , settimeinterval

    微任务:promise, V8回收机制,



 Q:思考call、apply、bind实现原理

    相同点,都是用来改变执行上下文,改变this的指向

    bind是不会立即调用的,而是返回绑定之后新的函数

    apply立即调用,返回函数的执行结果,第一个参数为执行作用域,后面跟上一个数组

    call 立即调用,返回函数的执行结果,第一个参数为执行作用域,后面跟上多余的参数

    

    

 Q:   new一个对象发生了什么事情

    1.开辟一块内存空间

    2.链接到原型

    3.绑定this

    4.返回新的对象





2、浏览器相关 Q:事件触发的过程是怎么样的,事件代理了解过吗?

    事件触发分为三个阶段

    1.window往事件触发的地方去传播,遇到注册的捕获事件会触发

    2.传播到事件注册的地方

    3.事件触发往window传播,遇到注册的冒泡事件会触发

    事件代理就是,本来应该绑定在子节点上的事件,在父节点上代理去实现,节约内存,多个子节点,无需多次绑定



 Q:浏览器跨域的方式有几种?

    1.JSONP  通过script标签,指定一个请求,请求后面跟上要执行的回调函数来实现,但是jsonp仅限于get请求

    2.CORS 需要后端配合实现, 服务器设置http响应头,



 Q:说一下回流和重绘?

    1.对dom结构修改,引起几何尺寸发生变化的时候,会发生回流,由于dom的结构发生改变,所以需要重新计算样式,生成布局树,建立树图层,浏            览器渲染的那一套要重新走一遍,开销很大

    2.dom的修改引起样式变化,发生重绘,由于dom节点的位置并没有更新,所以不需要重新渲染树,直接进入分块的后续操作



Q:输入url到页面展现,发生了什么

    1.发送请求,查找缓存,进行dns解析

    2.建立tcp连接,发送http请求

    3.构建css样式树,构建dom节点树,渲染页面ui



Q:AST语法树了解过吗

    ast语法树应用比较广泛,例如编辑器自动补全,webpack通过babel对js进行转义

    js执行的第一步就是读取js文件流,在经过语法分析生成ast, 最后生成机器码执行

    语法分析主要分为两部:

    1、分词,将代码分割成最小的单位

    2、词法分析,将分词的最小的单位建立连接



Q:为什么TCP需要三次握手,四次挥手 ?

    1、第一次握手,客户端向服务器发送请求,请求准备建立连接

    2、第二次握手,服务器接受请求数据包,允许建立连接

    3、第三次握手,客户端发送数据给服务端

    为什么要挥手是第四次,因为最后一次挥手是客户端要想服务器传输断开连接的信息,断开连接的信息需要分开传输,如果是在前面连接的阶段就带有断连的信息,服务器会来不及处理,因此需要第四次挥手,分开传输

3、打包工具webpack的面试题

Q: 什么是bunble、chunk、module

bunble是打包出来的文件,chunk是webpack在进行模块依赖分析的时候,代码分割出来的代码块,module是开发中的单个模块



Q:loader和plugin有什么区别?

loader其实就是告诉webpack, 如何转换某一类型的文件,怎么引入到打包的文件中,常见的loader有,css-loader, babel-loader, image-loader

plugin作用更大,可以做资源的管理,优化打包,注入环境变量等



Q:webpack打包原理, 手写过webpack插件吗 ?

webpack是一个静态模块打包工具,在构建项目的时候,会递归的构建一个依赖试图,包含了应用程序的每个模块,然后将这些模块打包成一个个文件

过程分为以下几步:

1.识别入口文件 2.通过逐层识别模块依赖 3.webpack分析代码,转换代码,编译代码,输出代码 4. 最终形成打包之后的代码

没写过插件XXXXXXXX



Q:如何优化减少webpack打包的时间,如何减少项目打包之后的体积 ?

减少webpack打包时间

1.优化loader,  例如可以优化babel插件查找文件的范围,限定在src下面,因为mode_modules里面的文件,都是编译过的

2.externals 配置常用的库

3.Happypack 开启并行打包,可以优化加载速度

4.webpack-uglify-parallel 优化加载速度

如何减少打包之后的体积

1.压缩代码

2.利用cdn加速

3.提取公共代码



Q: vite了解过吗, 和webpack对比有什么好处 ?

当项目越来越大,webpack会出现以下问题

1.webpack dev server冷启动时间较长

2.热更新速度比较慢

原因是因为webpack dev server在构建的时候,会把所有的代码文件build一遍,需要的时间较长

vite的特点

1.轻量

2.按需打包

3.热渲染依赖

vite没有打包相关的操作,当vite server服务启动的时候,中间件会进行打包注入相关操作,所以真正实现了按需加载



Q:webpack配置多页应用

webpack的多页应用通过入口entry和多实例html-webpack-plugin配合来构建,html-webpack-plugin的chunk属性传入对应的entry的key就可以做到关联

4、vue / uniapp 面试 Q:什么是mvvm?

   m代表model数据模型层,v代表视图层,vm是数据层和视图层的桥梁,数据绑定在vm层,会自动渲染在页面中,视图变化的时候,也会通知vm层更            新数据



Q:vue2.x版本数据响应式原理,怎么实现数组更新,再说下3.X版本数据响应式原理

    1.vue初始化组件的时候,会使用object.defineProperty 重新定义一遍data里面的所有属性,这里是一个经典的发布订阅者模式的应用,当页面使用相                应的数据时候,首先会进行依赖收集,如果数        据发生变化,会通知相应的依赖进行更新操作、

    2.vue2采用函数劫持的方式,实现的数组更新,vue将数组的原型链部分方法重写,指向自己函数原型方法,这样可以达到调用数组方法也可以通知依            赖更新

    3.vue3.X版本实现响应式原理,用proxy代替了object.defineProperty() 方法,因为proxy可以直接监听数组和对象的变化,proxy其实只能代理到数据的        第一层,对于这个问题,vue3是通过Reflect.get() 属性来判断返回值是否为object, 如果是的话,内部调用reactive(接受一个普通对象,返回一个响应        式对象)处理,

        

Q:nextTick实现原理是什么 ?

    nextTick其实主要依赖于宏任务微任务执行栈,在dom更新循环结束之后延迟回调,nextTick其实是定义了一个异步方法,多次调用nextTick会将方法        存入到队列中,通过异步方法清空当前队列



Q:如何比较两个节点之间的差异diff算法 , 怎么更新节点?

    diff算法比较的核心分为以下几步:

    1.同级比较,再比较子节点

    2.比较一方有子节点,另一方没有子节点的情况,将旧的子节点移除

    3.比较都有子节点的情况,递归遍历,vue的diff算法核心中,还采取了双端比较的方法,借助key, 找到可以复用的节点

    vue更新节点的过程

    根据真实的dom树构建virtural dom, 当virtural dom中有数据更新,生成一个新的vnode, 找到对应的节点,在真实的dom节点上打补丁实现

Q:说一下v-model的原理?

    v-mode实际上是一个语法糖,其实可以看做是 value+input事件的语法糖,在编译的时候,其实会根据对应的标签打上不同的事件和属性

Q:vue模板编译了解过吗 ?

    简单来说,模板编译就是将<template></template>转换成render的过程

    分为以下几步

    1.生成ast语法树,利用正则表达式对模板进行解析

    2.优化,vue数据是响应式的,但是很多数据在一开始渲染之后后面就不会再改变,这个时候的优化就很有必要了,需要深度遍历ast语法树,将不需            要改变的节点标记为静态节点,在运行的时候会跳过对比,这就运行时的模板起了很大的优化作用

    3.将ast转换为render函数

Q:computed和watch有什么区别 ?

 computed本质是一个具备缓存的watcher,  依赖的属性变化就会触发视图的变化,适用于消耗性能的场景,当模板中放入过多的逻辑会让模板难以维            护,可以将复杂的逻辑放入到计算属性中处理

 watch没有缓存属性,只是起到观察作用,可以监听数据的变化,然后执行回调, 如果需要深度监听对象中的属性,可以开启deep:true



Q:SSR了解过吗 ?

 SSR也就是服务端渲染,其实也就是在vue中把标签渲染成html的工作放在服务端完成,然后再把html然会给客户端

服务端有着更好的SEO 首屏加载快的优点,同时也会有一些限制,比如服务端只有beforeCreate和created钩子函数,服务端渲染应用程序时,需要处        于node环境,再就是会造成服务端较大的负载需求



Q:前端路由实现的原理,两种方式有什么区别?

前端路由的原理本质就是监听页面url变化,然后根据路由匹配规则,展现当前页面

hash路由:

监听hasChange事件,监听#之后的值的改变,进行页面跳转,服务端收到的永远都是一级域名

history模式:

通过history模式同样不会刷新当前页面,只会更新浏览器的历史纪录

两者模式的比较

1、hash模式只会更改#之后的内容,history模式可以设置任意同源URL

2、history模式可以通过浏览器api将任意url添加到历史记录中,hash模式只能更改hash值

3、hash模式兼容性好,无需后端配置,history模式要在用户手动输入地址匹配不到页面的时候,后端需要适配index.html页面



Q:vue做过哪些优化?

1.减少data里面的数据,因为data里面的数据都会增加getter和setter,会收集对应的依赖

2.keep-alive做缓存

3.key保证唯一

4.做防抖节流

5.使用路由懒加载,图片懒加载

6.v-for循环的情况,添加事件代理

7.防抖节流



Q:父子组件加载的顺序 ?

1.加载进来的过程是 

   (父) beforeCreate -> (父)created -> (父)beforeMount -> (子) beforeCreate -> (子) created -> (子) beforeMounted -> (子)mounted -> (父) mounted

 



Q:优化首屏加载?

1.首先就是分析前端加载速度慢的原因,安装可视化的工具,webpack-bundle-analyzer  ,  安装插件,会暴露出问题 

2.对js文件分离打包,把一些大的js文件资源放在内网或者cdn引入

3.vue路由实现懒加载

4.图片压缩,字体用在线字体

5.用webpack开启gzip压缩,提高http请求传输效率

6.vue代码层面书写的优化,用关键key缓存,v-if不要和v-for混用



Q:$route$router 有什么区别 ?

$route是当前活跃的路由对象,router是创建出来的实例,用来实现路由导航守卫。

5、css面试题
Q:说一下BFC ?

BFC是指,格式化上下文之后,外部元素的布局不会影响到内部元素,内部元素也不会影响到外部元素,创建BFC的情况有,浮动,绝对定位,行内块        元素



Q:画三角形的原理 ?

边框等分的原理,设置宽度高度为0border宽度设置,border颜色设置



Q:rgbaopacity 的区别

rgba设置的透明图不具备继承属性,但是opacity会继承父元素的属性



Q:box-sizing 具有哪些属性 ?

content-box, border-box, 继承



 Q:怎么实现小于12px的字体

 transform:scal 属性来实现



Q:BEM命名规范了解过吗 ?

有三种连接的方式

- 中划线:表示单词之间的连接符号

__双下划线表示连接块和块的子元素

_单下划线表示连接元素的一种状态

6.自己在项目的总结 Q:说说你怎么在项目中封装组件的 ?

Q:说说你怎么封装的移动端点击事件 ?

Q:说说你怎么做到的封装的axios ?