进阶高级前端必备知识点

445 阅读21分钟

网络优化

  • dns寻址过程
第一阶段:本地主机
1.host文件是否存在网址映射
2.本地dns解析器是否存在网址映射
第二阶段:本地服务器
1.本地配置区域资源是否存在网址映射
2.服务器缓存是否映射
第三阶段:网络服务器
1.是否采用转发模式
  • tcp的三次握手和四次挥手,以及为何要三次和为何要四次
三次握手:
TCP是通过程序实现的,可靠的,面向连接的协议。而程序是严谨的,每一次建立连接都会进行“三次握手”这样的步骤。建立连接的目的是为了可靠的数据传输。
四次挥手:
三次握手是为了建立可靠的数据传输通道,四次挥手是为了保证等数据传输完再关闭连接,保证双方都达到关闭连接的条件才能断开。
疑问:
服务端的SYN和ACK报文可以一起发送,但是挥手时有数据传输,ACK和FIN报文不能同时发送,需要分为两步,所以多了一步流程。


  • http1.0,http1.1以及http2.0的区别?
http1.0:
每次请求都需要重新建立tcp连接,请求完后立即断开与服务器连接,这很大程度造成了性能上的缺陷,http1.0被抱怨最多的就是连接无法复用。
http1.1:
引入了长连接(keep-alive),相较于1.0减少了连接和关闭的延迟,提高了效率,但是若干个请求还是需要串行排队处理,如果一旦某个请求超时,后面的就会被阻塞,也就是常说的线头阻塞。
http2:
1.新的二进制格式传输:二进制即01的组合,实现方便健壮,而1.x版本是基于文本,解析存在缺陷

2.多路复用:一个连接可以有多个请求,且可以混杂在一起根据requestid来区分不同的请求,提高了连接的利用率,降低了延迟

3.header头部压缩:通讯两方各自缓存了一份 header请求头表,避免了重复的header传输,且缩小了包的体积大小

4.服务端推送功能:可以服务端主动向客户端push消息

  • cdn的原理、cdn的适用场景?
原理:
CDN(内容分发网络)是将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播等场景。
场景:
1、网站站点/应用加速
2、视音频点播/大文件下载分发加速
3、视频直播加速
4、移动应用加速移动
核心点:
1、缓存:就是说我们把资源 copy 一份到 CDN 服务器上这个过程
2、回源就是说 CDN 发现自己没有这个资源(一般是缓存的数据过期了),转头向根服务器(或者它的上层服务器)去要这个资源的过程。
  • 浏览器缓存有哪几种,它们的区别是什么?
浏览器缓存:强缓存和协商缓存
区别:
强缓存:
1.  不会向服务器发送请求,直接从本地缓存中获取数据
2.  请求资源的的状态码为: 200 ok(from memory cache)
协商缓存:
1.  向服务器发送请求,服务器会根据请求头的资源判断是否命中协商缓存
2.  如果命中,则返回304状态码通知浏览器从缓存中读取资源
总结:
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304
  • 解释一下websocket的作用?
作用:建立服务器和客户端的长连接能更好的节省服务器资源和带宽,服务器向浏览器推流实现实时通信。

WebSocket方法:

-   Socket.send():向服务器发送数据
-   Socket.close():关闭连接

WebSocket事件:

-   Socket.onopen:连接建立时触发
-   Socke.onmessage:客户端接受服务端数据时触发
-   Socket.onerror:通信错误时触发
-   Socket.onclose:连接关闭时触发

渲染优化

  • webpack如何提高构建速度?
1.多入口情况下,使用CommonsChunkPlugin来提取公共代码
2.通过externals配置来提取常用库  
3.利用DllPlugin和DllReferencePlugin[预编译]资源模块 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。  
4.使用Happypack 实现[多线程]加速编译  
5.使用webpack-uglify-parallel来提升uglifyPlugin的压缩速度。 原理上webpack-uglify-parallel采用了多核并行压缩来提升压缩速度  
6.使用Tree-shaking和Scope Hoisting来剔除多余代码
  • bfc是什么?bfc有什么特性?如何生成?
是什么:
是块级格式化上下文。独立的渲染区域。

有什么特性:
- BFC是一个块级元素,块级元素在垂直方向上依次排列。
- BFC是一个独立的容器,内部元素不会影响容器外部的元素。
- 属于同一个BFC的两个盒子,外边距margin会发生重叠,并且取最大外边距。

如何形成:
- display:flex或display:inline-block
- position:fixed或position: absolute
- overflow: hidden

什么是重绘和回流?

重绘: 
当页面中元素样式的改变并不影响它在文档流中的位置时,也就是说布局没有发生改变时(比如只是改变元素的颜色)。
回流: 
当渲染树(Render Tree)中的部分(或全部)元素的尺寸、结构、显示隐藏等发生改变时,浏览器重新渲染的过程称为回流
注意:
-   回流必定会发生重绘,重绘不一定会引发回流。
-   回流比重绘的代价要更高。有时即使仅仅回流一个单一的元素,它的父元素以及任何跟它相关的元素也会产生回流,牵一发动全身。
  • 影响回流的因素?
1)添加或者删除可见的 DOM 元素(不可见元素不会触发回流);  
(2)元素尺寸或位置发生改变  
(3)元素内容变化,比如文字数量或图片大小  
(4)浏览器窗口大小发生改变  
(5)CSS伪类的激活(例如::hover,从而改变了元素的布局的)
  • 如何减少重绘和回流?
CSS
-   使用transform代替top;
-   使用visibility代替display:none,前者引起重绘,后者引发回流;
-   避免使用table布局;
-   尽可能在DOM树最末端改变class;
-   避免设置多层内联样式,css选择符从右往左匹配查找,避免节点层级过多;
-   将动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局;
-   避免使用css表达式,可能会引发回流;
-   css硬件加速;

JavaScript

-   避免频繁操作样式,修改class最好;
-   避免频繁操作DOM,合并多次修改为一次;
-   避免频繁读取会引发回流/重绘的属性,将结果缓存;
-   对具有复杂动画的元素使用绝对定位,使他脱离文档流。
  • 场景:如何优化首屏
-   首屏请求和非首屏请求拆分
-   图片都应该使用懒加载的形式加载
-   使用preload预加载技术,以及prefetch的dns预解析
-   与首屏无关的代码可以加async甚至是defer等待网页加载完成后运行
-   虚拟长列表渲染
-   图片懒加载
-   使用事件委托
-   使用SSR

js基础

  • let,const ,var 的区别
- var属于函数作用域能重复赋值和声明,会成变量提升
- const属于块级作用域只能声明一次且值不能被修改,会形成暂时性死区
- let属于块级作用域不能重复声明,能重复赋值,会形成暂时性死区
  • new的执行过程
- new会创建一个新的空对象
- new会让this指向新对象
- 执行构造函数,给这个新对象添加属性和方法
- new会返回这个新对象
  • 箭头函数中this和function里的this有什么区别
- 全局this指向window,普通this指向被调用的对象,箭头函数的this指向父级函数
- 普通this能被call()、apply()、bind()改变this指向,箭头函数的this不可以被改变
- 箭头函数中的this没有原型属性,不能使用构造函数,不能使用new
  • call、bind、apply的区别
- call传参的是参数列表,会立即执行
- apply传参是数组对象,会立即执行
- bind传参是参数列表,不会立即执行,会生成一个新的函数
  • 原型链和原型是什么?,

原型:每个函数都包含不同的原型对象,当将函数用做构造函数的时候,新的函数对象对继承原函数实例对象的属性和方法
原型链:当访问一个对象的属性或方法时没有找到,那么就会去原型上查找,如果找不到会继续在这个原型对象上继续查找,直到指向null
  • 什么是事件循环机制?
事件循环机制执行过程主要分为同步任务和异步任务,
同步任务会直接执行进入主线程,异步任务会进入事件队列。
当执行到宏任务时遇到微任务,会将微任务推动队列中执行,
如果下一次执行还有微任务则继续执行,直到剩下的微任务执行完再执行宏任务!
  • commonjs和AMD,CMD的区别,以及跟ES6 MODULE的区别
1.  AMD/CMD/CommonJs 是js模块化开发的规范,对应的实现是require.js/sea.js/Node.js
2.  CommonJs 主要针对服务端,AMD/CMD/ES Module主要针对浏览器端(服务端一般采用同步加载的方式,浏览器端需要异步加载)
3.  AMD/CMD区别,虽然都是并行加载js文件,但还是有所区别,AMD是预加载,在并行加载js文件同时,还会解析执行该模块(因为还需要执行,所以在加载某个模块前,这个模块的依赖模块需要先加载完成);而CMD是懒加载,虽然会一开始就并行加载js文件,但是不会执行,而是在需要的时候才执行。

4.  CommonJs和ES6 Module的区别:
-   CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
-   CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
-   CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。
  • 说说require.cache
`webpack`是基于`nodejs`开发的一个文件打包工具,
在其5.X版本的文档中讲到模块缓存多处引用同一模块,
最终只会产生一次模块执行和一次导出。
所以,会在运行时(runtime)中会保存一份缓存。删除此缓存,则会产生新的模块执行和新的导出。
  • 常用的ts中的数据类型?
-   boolean(布尔类型)
-   number(数字类型)
-   string(字符串类型)
-   array(数组类型)
-   tuple(元组类型)
-   enum(枚举类型)
-   any(任意类型)
-   null 和 undefined 类型
-   void 类型
-   never 类型
-   object 对象类型
  • es6中Map以及Set的区别是什么
- Map是一种字典的数据结构。set是一种集合的数据结构
- Map主要用于数据存储,set主要用于数组去重
  • 常见js的类型转换
-   Number()
-   parseInt()
-   String()
-   Boolean()
  • 如何捕获异步的异常,你能说出几种方案
- try-catch
-   Promise.reject
-   async await
  • 作用域是什么,作用域链呢?
作用域分为全局作用域、函数作用域、块级作用域
作用域链:每个函数都有自己的作用域链,当查找自己的变化或者方法时,需要从局部向全局去查找。这个过程为作用域链。

css基础

  • position有哪几种属性,它们的区别是什么
fixed相对于浏览器窗口定位,不会随着滚动条滚动
absolute相对于父元素进行定位,脱离标准流
relative基于自身定位,没有脱离标准流,占据空间
static没有定位,是默认值
  • 怪异盒模型和一般盒模型有什么区别
标准盒模型由四部分组成,改变borderpadding会改变盒子大小
怪异盒模型由两部分组成,改变borderpadding不会改变盒子大小
  • flex:1代表什么,flex-shrink和flex-grow有什么区别
flex:1代表flex-grow:1,flex-shrink:1,flex-basic:0;
flex-shrinkflex-grow分别代表子元素缩小和放大,flex-basic代表基础的宽度
  • 移动端高清屏图片的解决方案
方案一 百分比布局
方案二 媒体查询调整
方案三 flex布局
方案四 使用rem单位
  • 高清屏1px边框问题的解决方案?
-   伪类+transform(scale) 实现
-   border-image, backgroud-image 实现
-   viewport+rem
  • 说说GPU加速
利用transform: translateZ(0),欺骗浏览器开启GPU加速
优点:  
利用了GPU合成图层实现动画,可以做到动画平滑、流畅动画合成工作在GPU线程,不会被CPU的js运行阻塞
缺点:  
绘图层必须传输到GPU,当图层较多时传输过程可能会导致渲染缓慢 每个复合层都需要消耗额外的内存,过多的内存可能导致浏览器的崩溃

微信小程序

  • 数据请求怎么封装
-   将所有的接口放在统一的 js 文件中并导出(或者将请求地址、头、方法在一个 js 文件里统一定 义为一个常量并导出)
-   在 app.js 创建封装请求数据的方法
-   在子页面中调用封装的方法请求数据
  • 参数传值的方法
给 HTML 元素中添加 data-*属性来传递需要的值,
之后通过 e.currentTarget.dataset 或 onload 的 param 参数获取。
注意不能有大写字母,不可以存放对象 跳转页面时通过 navigator 传递需要的参数值 
设置 id 的方法标识,通过 e.currentTarget.id 获取设置的 id 值,然后通过设置全局变量的方法来传 递数值
  • 提高小程序的应用速度的方法
-   减少默认 data 的大小
-   组件化方案,公用的如弹框等写个自定义的组件,然后调用
  • 小程序的优点
-   无需下载

-   打开速度快

-   开发成本低

-   为用户提供良好的安全保障。发布有一套严格的审查流程,不能通过审查的程序无法发布上线

-   服务请求快
  • 小程序的缺点
-   依托微信,不能开发后台管理功能

-   大小限制不能超过 2M,不能打开超过 5 个层级的页面
  • 简述小程序原理
-   小程序分为两个部分 webview 和 appService,webview 用来展现 UI,appService 用来处理业  
    务逻辑、数据及接口调用,它们在两个进程中运行,通过系统层 JSBridge 实现通信,完成 UI 渲 染、事件处理。
  • 小程序和 Vue 写法的区别
-   循环遍历:小程序是 wx:for=“list”,vue 是 v-for=“inforin list”
-   调用 data 模型:小程序是 this.data.unifo,vue 是 this.unifo
-   给模型赋值:小程序是 this.setData({unifo:1}),vue 是直接 this.unifo=1
  • 小程序的双向绑定和 vue 哪里不一样
-   小程序直接 this.data 的属性是不可以同步到视图的,必须调用 *this.setData({})*
-   1px = 2rpx
  • 生命周期函数
-   onLoad——页面加载,调一次
-   onShow——页面显示,每次打开页面都调用
-   onReady——初次渲染完成,调一次
-   onHide——页面隐藏,当 navigateTo 或底部 tab 切换时调用  
    onUnload——页面卸载,当 redirectTo 或navigateBack 时调用
  • 几种跳转,小程序内的页面跳转
-   wx.navigateTo——保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面(参数必 须为字符串)
-   wx.redirectTo——关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
-   wx.switchTab——跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面,路径后不能带参数
-   wx.navigateBack——关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取  
    当前的页面栈,决定需要返回几层
-   wx.reLaunch——关闭所有页面,打开到应用内的某个页面 通过 navigator 跳转
  • 如何自定义组件
-   先创建一个 components 文件夹,用来存放所有自定义组件的,目录结构依然是 js,wxml,json,wxss
-   基本配置: .json——进行自定义组件声明 { “component”: true }
-   使用组件: 假如在 index.wxml 中使用这个自定义的组件,首先在 index.json 中进行声明 {  
    “usingComponents”: { “toastdemo”: “/components/toastdemo/toastdemo” }  
    }
-   接着在 index.wxml 中引用
-   然后在 index.js 进行配置
-   使用时直接执行 this.toastdemo.showToast(‘弹框组件调用成功’,2000)就可以了
  • 如何实现下拉刷新
先在 app.json 或 page.json 中配置 enablePullDownRefresh:true page 里用 onPullDownRefresh 函数,在下拉刷新时执行 在下拉函数执行时发起数据请求,请求返回后,调用 wx.stopPullDownRefresh 停止下拉刷新的状态
  • bindtap 和 catchtap 的区别是什么
bindtap 不会阻止冒泡事件,catchtap 阻止冒泡
  • setData 的回调函数
微信小程序的 setData 实现是和 react 的 setData 实现类似的,所以它也是一个异步函数,并且有 回 调函数的参数,当然平时小量数据我们可能并没有感觉到它的异步,但是为了确保逻辑的正确执行,在需要 用到 setData 后 data 里的数据的步骤,请写入 setData 的回调函数中,如下示例:  
this.setData({ a: this.data.a++ },()=>{ })
  • 分包的操作,发布的时候是选择某个包来发吗
-   分包:主包添加跳转路径,分包放内容,在 app.json 配置 subpakeages 声明项目分包结构。代码 包总包大小为  
    12M,单个主包/分包大小不能超过 2M。
-   按照功能划分的打包原则:可以按照功能的划分,拆分成几个分包,当需要用到某个功能时,才加载 这个功能对应的分包;公共逻辑、组件放在主包内。
-   首次启动时,先下载小程序主包,显示主包内的页面;如果进入了某个分包的页面,再下载这个对应分 包,下载完毕后,显示分包的页面,
-   总结:首先配置好打包路径,tabbar 页面必须在主包内。各分包之间不能互相调用,能调用主包内 的分包加载,预分包加载
  • 小程序页面间有哪些传递数据的方法
-   使用全局变量实现数据传递:在 app.js 文件中定义全局变量 globalData将需要存储的信息存放在里面: // app.js  
    App({ // 全局变量 globalData: { userInfo: null } })
-   使用的时候,直接使用 getApp()拿到存储的信息
-   使用 wx.navigateTo 和 wx.redirectTo 的时候,可以将部分数据放在 url 里,并在新页面 onLoad 的  
    时候初始化

跨端uniapp

  • 简述uniapp实现原理
逻辑层和视图层分离,非H5端通信有折损  
uni-app 在非H5端运行时,从架构上分为逻辑层和视图层两个部分。逻辑层负责储存数据和执行业务逻辑,视图层负责页面渲染。

页面加载时,联网和逻辑运算在逻辑层(Android是v8,iOS是jscore),然后会传递数据给视图层渲染。这种通信有损耗。同样,在视图层操作时,比如拖动页面,要实时传递事件给逻辑层接收,也是有损耗的。
  • uni-app的优点
跨平台发行,运行体验更好

-   与小程序的组件、API一致;
-   兼容weex原生渲染,增加了开发效率高,但是由于weex坑比较多,建议还是使用局部渲染优化;  
    通用前端技术栈,学习成本更低

支持vue语法,微信小程序API

-   内嵌mpvue
-   开发生态,组件更丰富

支持通过npm安装第三方包

-   支持微信小程序自定义组件及JS SDK
-   兼容mpvue组件及项目(内嵌mpvue开源框架)
-   App端支持和原生混合编码
-   插件丰富,DCloud将发布插件到市场

安全

  • csrf是什么,防范措施是什么
是什么:
跨站请求伪造,是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
防范措施:
1.验证 HTTP Referer 字段
2、验证码
3、添加token验证


  • xss是什么?如何防范?
是什么:
XSS攻击(跨站点脚本攻击),意即黑客恶意篡改你网页的前端代码,在里面注入一些恶意的 html+javascript的脚本,在你的浏览器内运行,获取你的信息,进行一些恶意操作。
(1)输入过滤
(2)输出转义
 (3)使用 HttpOnly Cookie

浏览器相关

  • 跨域是如何产生的,如何解决
原因:
跨域是由于浏览器存在同源策略,两个页面之间,如果协议、主机和端口中有任意一个不同,就会出现跨域问题
如何解决:
1.  JSONP
1.  Nginx代理
1.  后台设置
1.  vue前端代理


  • 如何检查性能瓶颈
1.   比如大列表的渲染,大量dom的渲染;
1.   大量图片的加载,过多资源的请求,资源体积是否过大,;
1.  代码中有没有耗时的计算操作,或则大量循环.递归
1.  编写的组件过于庞大 层级过深,依赖模块过多等.
  • 打开页面白屏,如何定位问题,或者打开页面CPU100%,如何定位问题
1、先确保网络连接通畅。
2、查看网络url地址是否输入有误。
3、打开控制台查看报错信息。
4、查看接口访问是否有请求。
5、查看路由是否有path或者name的错误,导致加载了不存在的页面。
  • jsonp的原理?
Jsonp原理:利用script标签没有跨域限制,
通过src属性发送带有callback参数的get请求。
服务器将参数传入到callback函数返回给浏览器解析,从而在前端运行,缺点是只能发送get请求

框架相关

  • react和vue的区别
  • key的作用是什么,为何说要使用唯一key,vue的diff算法是如何实现的,vue的呢
  • 听过闭包陷阱么,为何会出现这种现象,如何避免
  • vue的响应式原理
  • 为何vue3.x用的是proxy而不是object.defineProperties
  • vue是如何实现对数据的监听的,对数组呢
  • Vue 生命周期 以及其父子组件的生命周期调度顺序

weboack相关

  • webpack有哪些常见 loader 和 plugin,你用过哪些?
loader: 
file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
source-map-loader:加载额外的 Source Map 文件,以方便断点调试
image-loader:加载并且压缩图片文件
babel-loader:把 ES6 转换成 ES5
css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
eslint-loader:通过 ESLint 检查 JavaScript 代码

plugin:
define-plugin:定义环境变量
commons-chunk-plugin:提取公共代码
uglifyjs-webpack-plugin:通过UglifyES压缩ES6代码

算法实现(待更新)

  • js大整数加法
  • 双指针
  • 经典排序
  • 动态规划
  • 贪心算法
  • 回溯法
  • DFS
  • BFS
  • 链表操作
  • 线性求值

项目相关(待更新)

  • 项目中遇到的最大问题是什么,如何解决的
  • nodejs作为中间层的作用是什么

场景题(待更新)

  • 如何实现直播上的弹幕组件,要求不能重叠,仿照b站上的弹幕
  • 如何实现动态表单,仿照antd上的form组件
  • 实现一个promise(一般不会这样问)
  • 实现一个限制请求数量的方法
  • 如何实现一个大文件的上传
  • 实现一个eventEmitter
  • 实现一个new,call,bind,apply
  • 实现一个throttle,debound
  • 实现promise.then,finally,all
  • 实现继承,寄生组合继承,instanceof
  • 实现Generator,Aynsc