前端面试题

js


- javascript 中共几种基本数据类型

七种基本数据类型:
1、六种基本数据类型
undefined,null,string,boolean,number,symbol(ES6)
2、一种引用类型
Object

- 基本数据类型和引用数据类型的数据内存有什么不同?

基本数据类型:是保存在栈内存当中,复制的时候是值传递。栈内存中只存放具体的地址值。
引用数据类型:是保存在堆内存当中,

- typeof返回的数据类型有哪些?
“typeof”可以返回的数据类型有:
“number”、“string”、“boolean”、“undefined”、“object”、“function”。
 

- ES6为什么要引入 Symbol?

ES5的对象中的属性名是字符串,容易造成属性名的冲突,如果有一种机制,保证每个属性的名字都是独一无二的,就可以从根本上防止属性名的冲突。
 

- 栈和队列的区别?

队列是先进先出,有出口和入口,先进去可以先出来。
栈就像一个箱子,后放上去的,可以先出来,先进后出。
 

- const, var, let的区别?

1、var声明的变量会挂载在window上,而let和const声明的变量不会;
2、var声明变量存在变量提升,let和const不存在变量提升,需要遵循“先声明,后使用”原则,否则会报错;
3、let和const声明形成块作用域;
4、同一作用域下let和const不能声明同名变量,而var可以;
5、暂存死区,在代码块内,使用let声明变量之前,该变量都是不可以使用;
6、const一旦声明必须赋值,不能使用null占位,声明后不能再修改,如果声明的是引用类型的数据,可以修改其属性,但是不能修改对象的地址。
 

- Object都有哪些方法?

Object.assign,Object.create,Object.keys,Object.values, Object.entries,Object.is
 

- Array都有哪些方法?

join(),push()和pop(),shift() 和 unshift(),sort(),reverse(),concat(),slice(),splice(),indexOf()和 lastIndexOf(),forEach(),map() ,filter(),every() ,some() ,reduce()和 reduceRight()

不改变原数组的有:
concat,join,slice,map,foreach,filter,some,every https://www.cnblogs.com/obel/p/7016414.html

map,foreach,some区别:

1.都是循环遍历数组中的每一项。
2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前项的索引index,原始数组input。
3.匿名函数中的this都是指Window。
4.只能遍历数组。

some一直在找符合条件的值,一旦找到,则不会继续迭代下去。
every从迭代开始,一旦有一个不符合条件,则不会继续迭代下去。

JS中map和foreach的区别以及some和every的用法_得知此事须躬行的博客-CSDN博客

 
- js 怎么实现深拷贝?

// 方法一
var newobj = JSON.stringify(obj),
deepclose = JSON.parse(newobj)
// 方法二 循环属性创建对象
// Object.assign为浅拷贝
let newobj1 = Object.assign({}, obj)

- bind,call,apply的区别?

1、三者都可以改变函数的this对象指向
2、三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window
3、三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入
4、bind是返回绑定this之后的函数,apply、call 则是立即执行

- ES6中常用的新特性有哪些?

1、const,let,
2、模版字符串:ES6反引号(``)直接搞定
3、箭头函数
4、操作符(…)
5、for…of 和 for…in
6、class类,就是一个原型链的表现形式
7、promise
8、async,await
 

- JS实现继承的几种方式

  • 原型继承
    • 优点: 这种继承方式特别的简单 
    • 缺点: 所有子类共享同一个原型对象;无法实现按照我们的意愿给父类的构造函数传参;不能给一个 子类指定多个原型,也就是没法 多继承
  • 构造函数继承
    • 优点: 构造函数继承解决了所有的子类实例共享统一原型的问题,也可以给父类的构造函数传参,并且我们可以在子类的构造函数中调用多个父类的构造函数,实现所谓的多继承(这里的多继承是指子类通过call,apply等方法去调用父类的构造函数使其拥有父类的属性和方法,但是js中一个函数对象只存在一个 prototype,所以其实我们没法通过原型链的形式去体现出多继承)
    • 缺点:这种继承方式也无法继承父类的原型上的属性和方法;
  • 组合式继承
    • 优点:组合式继承就是结合了原型继承和构造函数继承的优点,解决了两种方式存在的一些缺点
    • 缺点:当我们去创建一个子类实例的时候都会去创建一个父类的实例,尽管父类实例不是同一个实例(内存地址不一样),但是他们其实属性和方法上完全一致
  • 寄生式组合继承
    • 优点:解决了我们每创建一个子类实例都去创建一个父类实例的问题,这也是最为常用的一种js的继承方式,如果我们通过Babel去把ES6中的class的继承转成ES5的代码,我们会发现就是用的寄生式组合继承。

        https://www.jb51.net/article/217803.htm

- ES5与ES6继承的区别?

ES5
ES5的继承是先创建子类的实例, 然后再创建父类的方法添加到this上.
通过原型和构造函数机制实现的.
// ES5的继承
// 原型链方式: 子类的原型指向父类的实例
// 缺点: 1. 因为原型链继承共享实例属性,属于引用类型传值, 修改某个实例的属性会影响其他的实例

ES6
ES6的继承是先创建父类的实例对象this(必须先调用super方法), 再调用子类的构造函数修改this.

通过关键字class定义类, extends关键字实现继承. 子类必须在constructor方法中调用super方法否则创建实例报错. 因为子类没有this对象, 而是使用父类的this, 然后对其进行加工

super关键字指代父类的this, 在子类的构造函数中, 必须先调用super, 然后才能使用this
// ES6的继承
// 在子类的构造器中先调用super(), 创建出父类实例, 然后再去修改子类中的this去完善子类

摘抄:

 
- Class和构造函数的异同?

类的形式
可以在Class内部同时定义普通对象的属性方法,定义构造函数对象上面的方法,定义原型对象上面的方法属性
值得注意的是通过静态关键字只能在构造函数对象上面添加方法,也就是说只能定义静态的方法,不能定义静态的属性
构造函数的形式
在构造函数内部只能定义普通对象上面的方法和属性
静态方法也就是构造函数对象上面的方法,只能通过显式的追加
原型对象上面的方法和属性也需要显式的追加

  1. Class 在语法上更加贴合面向对象的写法
  2. Class在实现继承上更加易读、易理解
  3. 更易于写java等后端语言
  4. 本质还是语法糖,使用prototype

摘抄:

 
- TypeScript 和 JavaScript 的区别?

1、TypeScript 可以使用 JavaScript 中的所有代码和编码概念,TypeScript 是为了使 JavaScript 的开发变得更加容易而创建的。例如,TypeScript 使用类型和接口等概念来描述正在使用的数据,这使开发人员能够快速检测错误并调试应用程序
2、TypeScript 从核心语言方面和类概念的模塑方面对 JavaScript 对象模型进行扩展。
3、JavaScript 代码可以在无需任何修改的情况下与 TypeScript 一同工作,同时可以使用编译器将 TypeScript 代码转换为 JavaScript。
4、TypeScript 通过类型注解提供编译时的静态类型检查。
5、TypeScript 中的数据要求带有明确的类型,JavaScript不要求。
6、TypeScript 为函数提供了缺省参数值。
7、TypeScript 引入了 JavaScript 中没有的“类”概念。
8、TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中。
语言层面:JavaScript和TypeScript都是ECMAScript(ECMA-262)的具体实现。
执行环境层面:浏览器引擎和Node.js都能够直接运行JavaScript,但无法直接运行TypeScript。
时序层面:TypeScript被真正执行前,会通过编译转换生成JavaScript,之后才能被解释执行。
厂商层面:JavaScript由Netscape率先推出,现在主要由各大浏览器厂商实现。而TypeScript is a trademark of Microsoft Corporation,目前由微软进行设计和维护。
TypeScript是ECMAScript 2015的语法超集,是JavaScript的语法糖。JavaScript程序可以直接移植到TypeScript,TypeScript需要编译(语法转换)生成JavaScript才能被浏览器执行。

摘抄:

- JS判断数组的5种方式

let arr = []
1.  instanceof 
    arr  instanceof Array

2. __proto__
    arr.__proto__  === Array.prototype

3. constructor
    arr.constructor === Array

4. Object.prototype.toString
    Object.prototype.toString.call(arr) === '[object Array]'

5. Array.isArray
    Array.isArray(arr)


- js的结构赋值?

function test1({x=0, y=0} = {}) {
    console.log([x, y])
}

test1({x:1, y:2})
test1({x:1})
test1({})
test1()
// [1, 2]
// [1, 0]
// [0, 0]
// [0, 0]

function test2({x, y} = {x: 0, y:0}) {
    console.log([x, y])
}   

test2({x:1,y:2})
test2({x:1})
test2({})
test2()
// [1, 2]
// [1, undefined]
// [undefined, undefined]
// [0, 0]

- 闭包的优缺点

优点:
1、让局部变量不回收
2、避免全局变量的污染
缺点:
1、常驻内存,增加内存使用量。
2、内存泄露,解决方法是,在退出函数之前,将不使用的局部变量全部删除。
 

- JS原型链中的prototype和__proto__的区别?

https://blog.csdn.net/lmhlmh_/article/details/80700971

- 【原型和原型链】什么是原型和原型链

①所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
③所有引用类型的__proto__属性指向它构造函数的prototype

当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

javascript中的原型与原型链_傻小胖的博客-CSDN博客_javascript原型和原型链
https://blog.csdn.net/xiaoermingn/article/details/80745117

- 什么是宏任务和微任务?

Js 是单线程的,但是一些高耗时操作带来了进程阻塞的问题。为了解决这个问题,Js 有两种任务的执行模式:同步模式(Synchronous)和异步模式(Asynchronous)。

在异步模式下,创建异步任务主要分为宏任务与微任务两种。ES6 规范中,宏任务(Macrotask) 称为 Task, 微任务(Microtask) 称为 Jobs。宏任务是由宿主(浏览器、Node)发起的,而微任务由 JS 自身发起。


先执行同步函数,再执行微任务,后执行宏任务

如何理解 script(整体代码块)是个宏任务呢?

实际上如果同时存在两个 script 代码块,会首先在执行第一个 script 代码块中的同步代码,如果这个过程中创建了微任务并进入了微任务队列,第一个 script 同步代码执行完之后,会首先去清空微任务队列,再去开启第二个 script 代码块的执行。所以这里应该就可以理解 script(整体代码块)为什么会是宏任务。

console.log(0)
setTimeout(function(){
  console.log(1)
})

new Promise(function(resolve){
  console.log(2)
  resolve(3)
}).then(function(res){
  console.log(res)
})

async function async1() {
  console.log(4)
  await async2()
  console.log(5)
}

async function async2() {
  console.log(6)
} 
async1().then(function(res){
  console.log(res)
})
console.log(7)

// 答案
0,2,4,6,7,3,5,undefined,1

// newnewnwenwnewnnenwne
setTimeout(function() {

     console.log(1)

}, 0);

new Promise(function(resolve, reject) {

     console.log(2)

     for (var i = 0; i < 10000; i++) {

          if(i === 10) {console.log(10)}

          i == 9999 && resolve();

     }

     console.log(3)

}).then(function() {

     console.log(4)

})

console.log(5)

// 答案
2,10,3,5,4,undefined,1

- Node事件循环机制(Event Loop)?

javascript从诞生之日起就是一门 单线程的 非阻塞的 脚本语言,单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务,非阻塞靠的就是 event loop(事件循环),本文就讲解下事件循环。

event loop它最主要是分三部分:主线程、宏队列(macrotask)、微队列(microtask)

执行顺序
1、先执行主线程
2、遇到宏队列(macrotask)放到宏队列(macrotask)
3、遇到微队列(microtask)放到微队列(microtask)
4、主线程执行完毕
5、执行微队列(microtask),微队列(microtask)执行完毕
6、执行一次宏队列(macrotask)中的一个任务,执行完毕
7、执行微队列(microtask),执行完毕
8、依次循环。。。

就是那个他的JS事件循环机制呢,就是就是event loop,然后他是就是从头儿从开始执行到尾部,然后从开始执行的时候,如果遇到settime out和set interval的话,因为这两个是宏任务,就先放到宏任务队列里面,然后比如说像遇process,还有next tick。和那个promise的话,它是属于微任务放到那个微任务队列,然后再执行主程序,因为他们都是异步的,然后执行完之后,先打印那些同步的,同步完,执行完之后再执行这个微任务里面的,然后微任务里面的都执行完了之后,再去执行红任务里面的一个,如果嗯,执行完一个的时候,需要再看看微任务里面有没有,如果微任务里面有的话,需要再再把微任务里面的全部执行完,然后再去执行红任务,如果没有的话,就一直执行那个,就直接执行那个红任务。

摘抄:

https://www.cnblogs.com/yalong/p/10369477.html
https://blog.csdn.net/qq_33572444/article/details/79106935

- === 和 ==的不同

=== 比较值、类型都相等
== 比较值相等

1、“===” 的比较规则
先检查两个操作数的数据类型是否相同
如果相同,则比较两个数是否相等
如果不同,返回 false

2、“==” 的比较规则
先检查两个操作数的数据类型是否相同
如果相同,则比较两个数是否相等
如果不同,则先将两个数转换为相同数据类型,再进行比较

null === undefined
false
null == undefined
true

- 函数,箭头函数和构造函数?

1、函数
函数声明式有提升,
函数表达式没有提升。
2、箭头函数
(1)、只能写函数表达式。不能写声明式函数。
(2)、箭头函数的this指向问题:箭头函数会改变函数体内部this的指向,即每一个函数都会形成一个针对于this的封闭作用域,如果这是一个箭头函数则不会形成封闭作用域。这个箭头函数中的this指向会穿透本层到达上一层作用域上,以上一层this的指向作为本层this的指向。
(3)、箭头函数内部没有 arguments 这个参数集合
3、构造函数
实例化对象时一定需要new关键字。
 

- 箭头函数和普通函数的区别
1、箭头函数的this值在声明时就确认了,普通函数的this值,在调用的时候确认
2、call、apply、bind不会改变箭头函数this值,会改变普通函数this值
3、箭头函数不能作为构造函数使用,不能使用new
4、箭头函数没有原型属性
5、箭头函数不绑定arguments,取而代之用rest参数… 解决
6、箭头函数不能当做Generator函数,不能使用yield关键字
 

- 原生js的ajax请求?

1.创建XMLHTTPRequest对象
2.使用open方法设置和服务器的交互信息
3.设置发送的数据,开始和服务器端交互
4.注册事件
5.更新界面
6.取消请求用abort方法

//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端
ajax.open('get','getStar.php?starName='+name);
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
   if (ajax.readyState==4 &&ajax.status==200) {
    //步骤五 如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的
    console.log(ajax.responseText);//输入相应的内容
    }
}


摘抄:

https://www.cnblogs.com/cythia/p/6978323.html

- axios使用和原理?

axios是一个基于promise封装好的发送请求、返回响应的http库,可以应用在浏览器中和node.js中。

axios的特性:
1、在浏览器中发送请求会创建 XMLHttpRequests
2、在 node.js 发送请求会创建 http请求
3、Promise封装,故支持Promise API
4、支持拦截器interceptors,可以分别设置请求拦截和响应拦截,在发出请求和响应到达then之前进行判断处理。
5、转换请求数据和响应数据
6、取消请求
7、自动转换 JSON 数据
8、客户端支持防御 XSRF攻击

摘抄:



 
- 视频直播推流、拉流?

点播:flv,m3u8格式
回放:mp4,m3u8格式

摘抄:

https://www.jianshu.com/p/6b8a4337e129
https://www.cnblogs.com/yjg2014/p/5980128.html
https://blog.csdn.net/a3568292a1/article/details/77935851


- 网站的重定向?

1、配置nginx
2、window.location

window.location.replace("http://www。example.com");
window.location.href = "http://www.example.com";
window.location.assign('http://www.example.com')

3、

window.location.replace("http://www。example.com");
window.location.href = "http://www.example.com";
window.location.assign('http://www.example.com')

- 网路七层协议图?

1、应用层:http,https,rtmp,dns
2、应用层
3、会话层
4、传输层:tcp,udp
5、网络层:ip
6、数据链路层
7、物理层

摘抄:

https://blog.csdn.net/gaohaicheng123/article/details/76696079

 
- 浏览器页面加载过程 ?

1.DNS域名解析
2.建立TCP连接
3.发送HTTP请求
4.服务器处理请求
5.返回响应结果
6.关闭TCP连接
7.浏览器解析HTML
1>构建DOM Tree
2>构建CSSOM
3>构建Render Tree
4>布局(Layout)
5>绘制(Painting)
8>JS的加载

摘抄:

https://juejin.cn/post/6844903829251555341


- 理解http浏览器的协商缓存和强制缓存?

缓存可以减少冗余的数据传输。节省了网络带宽,从而更快的加载页面。
缓存降低了服务器的要求,从而服务器更快的响应。
那么我们使用缓存,缓存的资源文件到什么地方去了呢?
那么首先来看下 memory cachedisk cache 缓存
memory cache: 它是将资源文件缓存到内存中。等下次请求访问的时候不需要重新下载资源,而是直接从内存中读取数据。
disk cache: 它是将资源文件缓存到硬盘中。等下次请求的时候它是直接从硬盘中读取。

那么他们 两则的区别 是?
memory cache(内存缓存)退出进程时数据会被清除,而disk cache(硬盘缓存)退出进程时数据不会被清除。内存读取比硬盘中读取的速度更快。但是我们也不能把所有数据放在内存中缓存的,因为内存也是有限的。
memory cache(内存缓存)一般会将脚本、字体、图片会存储到内存缓存中。
disk cache(硬盘缓存) 一般非脚本会存放在硬盘中,比如css这些。
缓存读取的原理:先从内存中查找对应的缓存,如果内存中能找到就读取对应的缓存,否则的话就从硬盘中查找对应的缓存,如果有就读取,否则的话,就重新网络请求。

那么浏览器缓存它又分为2种强制缓存 协商缓存

协商缓存原理:客户端向服务器端发出请求,服务端会检测是否有对应的标识,如果没有对应的标识,服务器端会返回一个对应的标识给客户端,客户端下次再次请求的时候,把该标识带过去,然后服务器端会验证该标识,如果验证通过了,则会响应304,告诉浏览器读取缓存。如果标识没有通过,则返回请求的资源。

那么协商缓存的标识又有2种:ETag/if-None-Match 和 Last-Modified/if-Modify-Since

摘抄:https://www.cnblogs.com/tugenhua0707/p/10807289.html

 
- HTTP与HTTPS的区别?

TTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

摘抄:https://www.cnblogs.com/wqhwe/p/5407468.html 


- TCP、UDP协议及两者的区别?

1) TCP提供面向连接的传输,通信前要先建立连接(三次握手机制); UDP提供无连接的传输,通信前不需要建立连接。
2) TCP提供可靠的传输(有序,无差错,不丢失,不重复); UDP提供不可靠的传输。
3) TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组; UDP是面向数据报的传输,没有分组开销。
4) TCP提供拥塞控制和流量控制机制; UDP不提供拥塞控制和流量控制机制。

摘抄:https://blog.csdn.net/striveb/article/details/84063712 


- HTTP与WebSocket的区别

(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
(7)Websocket使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。

相同点
1.都是基于TCP协议基础上,都是可靠性传输协议。HTTP如此,websocket亦如此
2.都是需要经过request,response阶段,其中websocket在发起请求的时候其实相当于借用了http的头部格式,区别就在于websocket请求头部有一个upgrade:websocket这样的字段(当然还有其他字段,但是这个字段最为关键)所以端口号是相同的不易被屏蔽。
3.如果请求失败,返回的错误编号都是相同的,例如:4**等
4、都是应用层协议。

不同点
1.正如前面所说,websocket的请求的头部会跟http请求头部有区别,比如多了一个upgrade:websocket字段
2.websocket只能是直连,不能通过代理来转发。究其原因应该怕如果通过代理转发的话,一个代理要承受如此多的websocket连接不释放,类似于一次DDOS攻击了。
3.websocket传输的数据是二进制流,是以帧为单位的,http传输的是明文传输,是字符串传输
4.websocket是全双工通信,有点类似于socket通信,在建立连接之后不必再像http那样你一个request我才回一个response了,想发就发,收发自如。
5、WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。
6、WebSocket是需要握手进行建立连接的。

摘抄:

https://www.cnblogs.com/tengjiang/p/13344985.html
https://www.pianshen.com/article/79661027234/


- 开发一个好的组件,需要考虑哪些?

1、单一指责原则
2、可扩展性,维护性,重用性
3、低耦合, 高内聚
4、降低开发的复杂性
 

- 为什么 0.1 + 0.2 != 0.3 ?5.1 是什么导致了这种情况?

原因很简单,JS 采用的是双精度版本,这个版本就存在精度问题,就导致了上边这种情况。

内部的原理是什么?

我们计算机的信息全部转化为二进制进行存储的,那么0.1的二进制表示的是一个无限循环小数,该版本的 JS 采用的是浮点数标准需要对这种无限循环的二进制进行截取,从而导致了精度丢失,造成了0.1不再是0.1,截取之后0.1变成了 0.100…001,0.2变成了0.200…002。所以两者相加的数大于0.3。

那好,既然0.1不等于0.1了,那为什么我在控制台上输出console.log(0.1)还等于0.1呢?

因为在输入内容进行转换的时候,二进制转换成十进制,然后十进制转换成字符串,在这个转换的过程中发生了取近似值,所以打印出来的是一个近似值。
 

- 如何使用 javascript 获取语音数据并播放?
https://blog.csdn.net/sinat_39013092/article/details/115337117


- cookie和session的详解与区别?

1、数据存放位置不同:
cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、安全程度不同:
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。

3、性能使用程度不同:
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。

4、数据存储大小不同:
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,而session则存储与服务端,浏览器对其没有限制。

5、会话机制不同
session会话机制:session会话机制是一种服务器端机制,它使用类似于哈希表(可能还有哈希表)的结构来保存信息。
cookies会话机制:cookie是服务器存储在本地计算机上的小块文本,并随每个请求发送到同一服务器。 Web服务器使用HTTP标头将cookie发送到客户端。在客户端终端,浏览器解析cookie并将其保存为本地文件,该文件自动将来自同一服务器的任何请求绑定到这些cookie。

- HTTP1.0和HTTP1.1和HTTP2.0的区别?

摘抄:https://blog.csdn.net/ailunlee/article/details/97831912 

名称解释

- 低耦合, 高内聚的含义是什么?

高内聚
内聚就是一个模块内各个元素彼此结合的紧密程度, 高内聚就是一个模块内各个元素彼此结合的紧密程度高. 所谓高内聚实质一个软件模块是由相关性很强的代码组成, 只负责一项任务, 也就是常说的单一责任原则.

低耦合
耦合: 一个软件结构内不同模块之间互连程度的度量(耦合性也叫块间联系,指软件系统模块中各模块间相互联系紧密程度的一种度量. 模块之间联系越紧密, 其耦合性就越强, 模块的独立性则越差, 模块间耦合的高低取决于模块间接口的复杂性, 调用的方式以及传递的信息.)对于低耦合, 粗浅的理解是: 一个完整的系统, 模块与模块之间, 尽可能的使其独立存在, 也就是说, 让每个模块, 尽可能的独立完成某个特定的子功能. 模块与模块之间的接口, 尽量的少而简单. 如果某两个模块间的关系比较复杂的话, 最好首先考虑进一步的模块划分. 这样有利于修改和组合.

模块之间存在依赖, 导致改动可能会互相影响, 关系越紧密, 耦合越强, 模块独立性越差

为什么要追求高内聚和低耦合
  软件架构设计的目的简单说就是在保持软件内在联系的前提下,分解软件系统,降低软件系统开发的复杂性,而分解软件系统的基本方法无外乎分层和分割。但是在保持软件内在联系的前提下,如何分层分割系统,分层分割到什么样的粒度,并不是一件容易的事,这方面有各种各样的分解方法,比如:关注点分离,面向方面,面向对象,面向接口,面向服务,依赖注入,以及各种各样的设计原则等,而所有这些方法都基于高内聚,低耦合的原则。 高内聚和低耦合是相互矛盾的,分解粒度越粗的系统耦合性越低,分解粒度越细的系统内聚性越高,过度低耦合的软件系统,软件模块内部不可能高内聚,而过度高内聚的软件模块之间必然是高度依赖的,因此如何兼顾高内聚和低耦合是软件架构师功力的体现。   高内聚,低耦合的系统有什么好处呢?事实上,短期来看,并没有很明显的好处,甚至短期内会影响系统的开发进度,因为高内聚,低耦合的系统对开发设计人员提出了更高的要求。高内聚,低耦合的好处体现在系统持续发展的过程中,高内聚,低耦合的系统具有更好的重用性,维护性,扩展性,可以更高效的完成系统的维护开发,持续的支持业务的发展,而不会成为业务发展的障碍.

摘抄:https://blog.csdn.net/banxia117/article/details/82665336 

- 什么叫优雅降级和渐进增强?

渐进增强 progressive enhancement:
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 graceful degradation:
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

区别:

a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给
b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要
c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带
 

- 重绘和回流的区别?

重绘:元素样式的改变(但宽高、大小、位置等不变)
回流:元素的大小或者位置发生改变(当页面布局和几何信息发生改变的时候),触发了重新布局导致渲染树重新计算布局和渲染

注意:回流一定会触发重绘,而重绘不一定会回流
摘抄:https://www.jianshu.com/p/e081f9aa03fb

 
- 内存污染、内存泄漏、内存溢出的理解?

内存泄露:一个变量如果不用了,会被程序自动回收。内存泄露:垃圾回收不了这个东 西了,就是内存泄露。内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。
内存溢出:系统会给每个对象分配内存也就是Heap size值,当对象所需要的内存大于 了系统分配的内存,就会造成内存溢出
内存污染:变量命名产生冲突
 

- AMD、CMD、ES6、CommonJS的区别?

CommonJS:模块引用(require) 模块输出(exports) 模块标识(module)
ES6:模块引用(import) 模块输出(export)
1、前者支持动态导入,也就是 require(${path}/xx.js),后者目前不支持。
2、、前者是同步导入,因为用于服务端,文件都在本地,同步导入即使卡住主线程影响也不大。而后者是异步导入,因为用于浏览器,需要下载文件,如果也采用同步导入会对渲染有很大影响。
3、前者在导出时都是值拷贝,就算导出的值变了,导入的值也不会改变,所以如果想更新值,必须重新导入一次。但是后者采用实时绑定的方式,导入导出的值都指向同一个内存地址,所以导入值会跟随导出值变化
AMD、CMD都使用define定义模块,require引入模块,区别在于AMD是前置依赖,CMD是就近依赖

vue

- Vue和React的区别 

    Vue和React存在着很多的共同点:

  • 数据驱动视图

  • 组件化

  • 都使用 Virtual DOM

不同点:

1. 核心思想不同
Vue早期开发就尤雨溪大佬,所以定位就是尽可能的降低前端开发的门槛,让更多的人能够更快地上手开发。这就有了vue的主要特点:灵活易用的渐进式框架,进行数据拦截/代理,它对侦测数据的变化更敏感、更精确。

React 从一开始的定位就是提出 UI 开发的新思路。背靠大公司Facebook 的React,从开始起就不缺关注和用户,而且React想要做的是用更好的方式去颠覆前端开发方式。所以React推崇函数式编程(纯组件),数据不可变以及单向数据流,当然需要双向的地方也可以手动实现, 比如借助onChange和setState来实现。

由于两者核心思想的不同,所以导致Vue和React在后续设计产生了许多的差异。

2. 组件写法差异
React推荐的做法是JSX + inline style, 也就是把 HTML 和 CSS 全都写进 JavaScript 中,即 all in js; Vue 推荐的做法是 template 的单文件组件格式(简单易懂,从传统前端转过来易于理解),即 html,css,JS 写在同一个文件(vue也支持JSX写法)

3. 响应式原理不同
Vue

  Vue依赖收集,自动优化,数据可变。

  Vue递归监听data的所有属性,直接修改。

  当数据改变时,自动找到引用组件重新渲染。

React

  React基于状态机,手动优化,数据不可变,需要setState驱动新的state替换老的state。当数据改变时,以组件为根目录,默认全部重新渲染, 所以 React 中会需要 shouldComponentUpdate 这个生命周期函数方法来进行控制

4. diff算法不同

https://blog.csdn.net/sinat_17775997/article/details/115482179

- Vue和React组件之间的传值方式对比总结

  • Vue
    • 父->子:通过props进行传递数据给子组件
    • 子->父:通过emit向父组件传值
    • 任意组件之间传值:简单的可以使用EventBus,对于更为复杂的建议使用Vuex。
    • 兄弟组件传值:在Vue中,可以通过查找父组件下的子组件实例,然后进行组件进行通信。如this.parent.children,在$children中,可以通过组件的name找到要通信的组件,进而进行通信。
    • 还有一些其他进行父子组件通信的方式,通过$parent和$children获取组件的父或者子组件的实例,之后通过实例对象去修改组件的属性
  • React
    • 父->子:通过props将数据传递给子组件
    • 子->父:通过父组件向子组件传递函数,然后子组件中调用这些函数,利用回调函数实现数据传递
    • 兄弟组件传值:在React中,需要现将数据传递给父组件,然后父组件再传递给兄弟组件。
    • 任意组件之间传值:简单的使用EventBus,复杂的使用Redux

        https://www.jianshu.com/p/b61e59d12b85

- Vue和JQuery的区别

1、工作原理

Vue做到了数据和视图完全分离开,它首先把值和js对象进行绑定,然后修改js对象的值,Vue框架就会自动把dom的值就行更新。对数据进行操作不再需要引用相应的dom对象,他们通过Vue对象实现数据和视图的相互绑定。

jQuery则是要先使用选择器($)来选取dom对象,然后对dom对象进行操作(如赋值、取值、事件绑定等)。

2、侧重

vue侧重数据绑定,可以应用于复杂数据操作的后台页面。如:表单填写页面

jquery侧重样式操作,动画效果等;可以应用于一些html5的动画页面,一些需要js来操作页面样式的页面中。

摘抄:https://m.php.cn/article/412970.html

 - vue组件中data为什么是一个函数

1.是为了在重复创建实例的时候避免共享同一数据造成的数据污染  

2.写函数的原因是为了保证这个对象是独立的,如果可以保证对象是惟一的,也可以不写函数直接写对象。

其实归根结底就是为了避免数据污染。

我们想要解决这个问题就不得不说原型链和this。

摘抄:https://www.jb51.net/article/228858.htm

- MVC、MVP、MVVM模式的概念与区别?

摘抄:https://www.jianshu.com/p/ff6de219f988

 - MVVM双向绑定的原理 & 数据怎么通信

     vue是采用数据劫持配合发布者-订阅者模式的方式,通过object.definerProperty()来劫持各个属性的setter和gettter,在数据变动时,发布消息给依赖收集器,去通知观察者,做出对应的回调函数,去更新视图。

        MVVM作为绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听model数据变化表,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer,Compile之间的通信桥梁,达到数据变化 => 视图更新;视图交互变化 => 数据model变更的双向绑定效果

​Compile:解析指令,初始化视图
Observer:劫持监听所有属性,通知Dep发生变化
Dep:通知watcher变化
Watcher:添加订阅者

https://blog.csdn.net/z2428478096/article/details/121459920

- Vue数组改变但页面视图未更新

无法触发 “ 视图更新 ” 的原因:

        在 Vue2 中 用 “ 数组下标修改值时 ” 或者 “ 新增对象Key值时 ” ,这两种情况下,Vue的 devsrve函数 是监听不到数据的变化的,从而导致 数据更新了,但视图却因为数据更新没有被监听到,无法触发更新。

解决办法:

  • 可以利用this.$set( arr | obj , index | key, value )
  • 可以利用 JavaScript 中对数组重写的splice方法,eg:this.arr.splice(0, 1, "CSS")
  • 重新声明一个变量深拷贝一下当前这个数组然后重新赋值即可
let newArr = JSON.parse(JSON.stringify(this.arr))
newArr[0] = "CSS"
this.arr = newArr

< 在Vue中 “ 数据改变 ” 却不触发 “ 视图更新 ” 问题解决 >_技术宅小温的博客-CSDN博客_vue数组重新赋值视图没有更新

- 怎么实现几个promise同时进行

借助all、reject、resolve及原型上有then、catch等方法

- 什么是Promise

Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。(ps:什么是原型:javascript中的原型与原型链_傻小胖的博客-CSDN博客_javascript原型和原型链

摘抄:
https://blog.csdn.net/qq_34645412/article/details/81170576

- Vue cli vue devtool 以及vue配置文件在哪

使用vue-devtool可以查看vue组件里面的data里面的变量
methods里面的函数
和一些全局对象比如说: refs,route
可以查看vuex里面的变量及变化监听

https://blog.csdn.net/seimeii/article/details/125050671

- Vuex的优缺点

   优点

  • 能够在vuex中,集中管理共享的数据,易于开发和后期维护;
  • js 原生的数据对象写法, 比起 localStorage 不需要做转换, 使用方便
  • 限定了一种可预测的方式改变数据, 避免大项目中, 数据不小心的污染
  • Vuex 的状态存储是响应式的,当 Vue 组件从 store中读取状态的时候,若 store 中的状态发生变化,能够触发响应式的渲染页面更新 (localStorage就不会),那么相应的组件也会相应地得到高效更新。

   缺点

  • 刷新浏览器,vuex中的state会重新变为初始状态 ;
  • 解决方案-插件 vuex-persistedstate

  得配合计算属性和sessionStorage来实现

  https://www.csdn.net/tags/MtTaAg0sNzA4MzgtYmxvZwO0O0OO0O0O.html

 
- vue3带来的新特性/亮点?

  1. Performance
    vue3在性能方面比vue2快了2倍。
    重写了虚拟DOM的实现
    运行时编译
    update性能提高
    SSR速度提高

  2. Tree-shaking support
    vue3中的核心api都支持了tree-shaking,这些api都是通过包引入的方式而不是直接在实例化时就注入,只会对使用到的功能或特性进行打包(按需打包),这意味着更多的功能和更小的体积。

  3. Composition API
    vue2中,我们一般会采用mixin来复用逻辑代码,用倒是挺好用的,不过也存在一些问题:例如代码来源不清晰、方法属性等冲突。基于此在vue3中引入了Composition API(组合API),使用纯函数分隔复用代码。和React中的hooks的概念很相似。

  4. ref及reactive的区别及本质
    reactive:
    (1)它的响应式是更加‘深层次’的,底层本质是将传入的数据包装成一个Proxy
    (2)参数必须是对象或者数组,如果要让对象的某个元素实现响应式时比较麻烦。需要使用toRefs
    ref:
    (1)函数参数可以是基本数据类型,也可以接受对象类型
    (2)如果参数是对象类型时,其实底层的本质还是reactive,系统会自动根据我们给ref传入的值转换成:

    ref(1)->reactive({value:1}) 
    ref函数只能操作浅层次的数据,把基本数据类型当作自己的属性值;深层次依赖于reactive

    (3)在template中访问,系统会自动添加.value;在js中需要手动.value
    (4)ref响应式原理是依赖于Object.defineProperty()的get()和set()的。

  5. ref、toRef、toRefs的区别
    ref:复制,修改响应式数据不影响以前的数据;数据改变,界面自动更新
    toRef:引用,修改响应式数据会影响以前的数据;数据改变,界面不自动更新
    toRefs:
    (1)接收一个对象作为参数,它会遍历对象身上所有属性,然后调用单个toRef
    (2)将对象的多个属性变成响应式数据,并且要求响应式数据和原始数据关联,且更新响应式数据的时候不会更新界面,用于批量设置多个数据为响应式

摘抄:

- Vue框架总结之vue的优点?

vue的优点

  • 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
  • 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
  • 双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
  • 组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
  • 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
  • 虚拟DOM:dom操作是非常耗费性能的,不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
  • 运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。

摘抄:https://www.jianshu.com/p/710de0ba1e9f
 
- vue核心之虚拟DOM(vdom)?

浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting

摘抄:https://www.jianshu.com/p/af0b398602bc

 
- 虚拟DOM的优势在哪里?

DOM 引擎、JS 引擎 相互独立,但又工作在同一线程(主线程) JS 代码调用 DOM API 必须 挂起 JS 引擎、转换传入参数数据、激活 DOM 引擎,DOM 重绘后再转换可能有的返回值,最后激活 JS 引擎并继续执行若有频繁的 DOM API 调用,且浏览器厂商不做“批量处理”优化, 引擎间切换的单位代价将迅速积累若其中有强制重绘的 DOM API 调用,重新计算布局、重新绘制图像会引起更大的性能消耗。

其次是 VDOM 和真实 DOM 的区别和优化:

  • 虚拟 DOM 不会立马进行排版与重绘操作
  • 虚拟 DOM 进行频繁修改,然后一次性比较并修改真实 DOM 中需要改的部分,最后在真实 DOM 中进行排版与重绘,减少过多DOM节点排版与重绘损耗
  • 虚拟 DOM 有效降低大面积真实 DOM 的重绘与排版,因为最终与真实 DOM 比较差异,可以只渲染局部

摘抄:https://blog.csdn.net/z591102/article/details/105065880 

-vue computed和watch的区别是什么?

计算属性computed :

1、支持缓存,只有依赖数据发生改变,才会重新进行计算
2、不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3、computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
4、如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
5、如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

侦听属性watch:

1、不支持缓存,数据变,直接会触发相应的操作;
2、watch支持异步;
3、监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4、当一个属性发生变化时,需要执行对应的操作;一对多;
5、监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
  immediate:组件加载立即触发回调函数执行,
  deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
  
摘抄:https://www.html.cn/qa/vue-js/20891.html 


- keep-alive 的应用?

vue2.0提供了一个keep-alive组件用来缓存组件,避免多次加载相应的组件,减少性能消耗

keep-alive是Vue.js的一个内置组件。它能够不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中,也不会出现在父组件链中。

它有两个生命周期:
activated: keep-alive组件激活时调用
deactivated: keep-alive组件停用时调用
它提供了include与exclude两个属性,允许组件有条件地进行缓存。

keep-alive生命周期,生命周期执行顺序:
1、不使用keep-alive的情况:beforeRouteEnter --> created --> mounted --> destroyed
2、使用keep-alive的情况:beforeRouteEnter --> created --> mounted --> activated --> deactivated
3、使用keep-alive,并且再次进入了缓存页面的情况:beforeRouteEnter -->activated --> deactivated

被keep-alive包裹住的页面都会被缓存,如果想刷新部分内容要启用activated函数,用法同created,activated只有在被keep-alive包裹时会触发,activated函数一进入页面就触发

摘抄:https://blog.csdn.net/qq_37548296/article/details/110798890
 
- hash路由和history路由的区别?

1.hash路由在地址栏URL上有#,而history路由没有会好看一点
2.我们进行回车刷新操作,hash路由会加载到地址栏对应的页面,而history路由一般
就404报错了(刷新是网络请求,没有后端准备时会报错)。
3.hash路由支持低版本的浏览器,而history路由是HTML5新增的API。
4.hash的特点在于它虽然出现在了URL中,但是不包括在http请求中,所以对于后端是
没有一点影响的,所以改变hash不会重新加载页面,所以这也是单页面应用的必备。
5.history运用了浏览器的历史记录栈,之前有back,forward,go方法,之后在HTML5
中新增了pushState()和replaceState()方法(需要特定浏览器的支持),它们提供了
对历史记录进行修改的功能,不过在进行修改时,虽然改变了当前的URL,但是浏览器不会
马上向后端发送请求。

- vue总结的面试问题

摘抄:https://blog.csdn.net/shi_xingwen/article/details/114655369 


webpack

-什么是loader,什么是plugin?

**loader:**loader用于加载某些资源文件。因为webpack本身只能打包common.js规范的js文件,对于其他资源如css,img等,是没有办法加载的,这时就需要对应的loader将资源转化,从而进行加载。

**plugin:**plugin用于扩展webpack的功能。不同于loader,plugin的功能更加丰富,比如压缩打包,优化,不只局限于资源的加载。

webpack常用loader
style-loader, css-loader, sass-loader, file-loader, babel-loader

webpack常用plugins
1、htmlWebpackPlugin:作用是依据一个简单的模板,帮助生成最终的html,html自动引用了打包后的js文件
2、hotModuleReplacement:允许在修改组件代码后,自动刷新实时预览修改后的效果。
3、clean-webpack-plugin:在webpack打包时清理dist目录
 

- grunt/gulp和webpack有什么不同呢?

1、grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
2、webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。
gulp,grunt是web构建工具
webpack是模块化方案
gulp,grunt是基于任务和流
webpack基于入口文件

webpack是一个模块打包器,强调的是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源都看成是模块,通过loader和plugin对资源进行处理。

gulp是一个前端自动化构建工具,强调的是前端开发的工作流程,可以通过配置一系列的task,第一task处理的事情(如代码压缩,合并,编译以及浏览器实时更新等)。然后定义这些执行顺序,来让glup执行这些task,从而构建项目的整个开发流程。自动化构建工具并不能把所有的模块打包到一起,也不能构建不同模块之间的依赖关系。
 

- webpack的构建流程是什么?

1、Webpack首先会把配置参数和命令行的参数及默认参数合并,并初始化需要使用的插件和配置插件等执行环境所需要的参数;初始化完成后会调用Compiler的run来真正启动webpack编译构建过程,webpack的构建流程包括compile、make、build、seal、emit阶段,执行完这些阶段就完成了构建过程。这其实就是我们上面所讲到的。
2、初始化参数: 从配置文件和 Shell 语句中读取与合并参数,得出最终的参数。
3、开始编译: 根据我们的webpack配置注册好对应的插件调用 compile.run 进入编译阶段,在编译的第一阶段是 compilation,他会注册好不同类型的module对应的 factory,不然后面碰到了就不知道如何处理了。
4、编译模块: 进入 make 阶段,会从 entry 开始进行两步操作:第一步是调用 loaders 对模块的原始代码进行编译,转换成标准的JS代码, 第二步是调用 acorn 对JS代码进行语法分析,然后收集其中的依赖关系。每个模块都会记录自己的依赖关系,从而形成一颗关系树。
5、输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。
6、输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
摘抄:https://blog.csdn.net/leelxp/article/details/107209190

 
- 什么是bundle,什么是chunk,什么是module?

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

- webpack的优势?

1、代码拆分(支持异步模块加载)
2、Loader(支持任意模块加载,比如图片、less、css等等)
3、智能解析
4、插件系统
5、快速运行

摘抄:https://www.jianshu.com/p/e6099cf01e63

 
- 网站性能优化?

web前端性能优化总结_weixin_33686714的博客-CSDN博客

一、webpack优化

       1、Tree-sharking?
        tree-sharking 是指在打包中去除那些引入了,但是在代码中没有被用到的那些死代码。
        2、压缩
                1>js压缩:UglifyJsPlugin
                2>html压缩:HtmlWebpackPlugin
                3>css压缩:MiniCssExtractPlugin
        3、优化Loader搜索范围:排除exclude
        4、提取公共代码
        如果项目中没有去将每个页面的第三方库和公共模块提取出来,则项目会存在以下问题:
        相同的资源被重复加载,浪费用户的流量和服务器的成本。
        每个页面需要加载的资源太大,导致网页首屏加载缓慢,影响用户体验。
        所以我们需要将多个页面的公共代码抽离成单独的文件,来优化以上问题 。Webpack         内置了专门用于提取多个Chunk 中的公共部分的插件 CommonsChunkPlugin
        5、构建结果输出分析
        Webpack 输出的代码可读性非常差而且文件非常大,让我们非常头疼。为了 更简单、直观地分析输出结果,社区中出现了许多可视化分析工具。这些工具以图形的方式将结果更直观地展示出来,让我们快速了解问题所在。接下来讲解我们在 Vue 项目中用到的分析工具:webpack-bundle-analyzer 。        


二、js
        1、是否内存泄漏
        2、代码中是否有死循环
三、cdn
        1、cdn方式加载资源,不用对资源进行打包
        2、可以配置cdn服务器,实现浏览器缓存
四、CSS放在页面最上部,javascript放在页面最下面
五、路由懒加载(按需加载,动态加载)
六、preload和prefetch
preload 加载资源一般是当前页面需要的,prefetch 一般是其它页面有可能用到的资源。

摘抄:

https://blog.csdn.net/q759859479/article/details/81609010
https://router.vuejs.org/zh/guide/advanced/lazy-loading.html#%E6%8A%8A%E7%BB%84%E4%BB%B6%E6%8C%89%E7%BB%84%E5%88%86%E5%9D%97
https://blog.csdn.net/qq_37939251/article/details/100031285

- 页面需要渲染的数据太多,如何解决

后端接口数据:用分页的方式分批加载

html、css、js、图片:图片推荐懒加载,局部加载,优化大小质量;注意把js放在文档最后,推荐先弄出网页外壳再请求数据,提高用户体验

  • 前端页面组件化,实现懒加载,页面渲染先渲染假数据展示页面,然后进行数据替换
  • 采用前端分页,江大数据通过js处理成分块数据,分块渲染到浏览器中
  • 采用虚拟滚动技术(虚拟列表)
  • 大数据渲染浏览器会消耗很多计算和渲染资源,可采用懒加载+js时间分片技术,避免js做大量计算造成的进程阻塞

- 浏览器中的performance检测页面性能?

1.控制按钮。
2.overview。页面性能的高级汇总(FPS:帧率,CPU:CPU占用,NET:网络请求)
3.火焰图。CPU堆叠追踪的可视化(左侧名称是主线程的各种事件,Network:网络请求详细情况)
4.数据统计。以图表的形式汇总数据(summary:统计报表,Bottom-Up:事件时长顺序,Call Tree:事件调用顺序,Event log:事件发生的先后顺序)

摘抄:

https://blog.csdn.net/u011002547/article/details/86648549

 
微信小程序

- 小程序实现原理解析?

摘抄:

https://blog.csdn.net/xiangzhihong8/article/details/66521459

 
- 用uni-app开发小程序的优缺点有哪些?

优点

①兼容性好
Uni-app最大的特点就是一套代码编译以后多端通用,开发人员不需要在每个平台都单独开发一套代码就可以同时生成安卓、iOS、H5、百度小程序等等。节省了大量的成本。

②学习成本低
由于uni-app基于vue.js开发,因此对于前端开发工程师不会十分困难,学习uni-app的门槛也相应降低。尤其是封装的插件与微信端小程序相同。

③开发速度快
由于uni-app是用HBX进行开发,所以支持vue的语法。同时HBX的开发和编译速度都很快,这也是很多人选择uni-app的理由之一。

④拓展性强
Uni-app支持nvue,封装了H5+。同时,还支持原生的iOS和安卓开发。因此将原有的H5和移动端APP转移到uni-app上面十分方便。

⑤开发团队支持多
目前uni-app的开发团队DCloud发布新版本的频率比较频繁。新特性多,因此对于开发者也是有积极意义的。

缺点

①新平台问题多
虽然uni-app的有点很多,但毕竟是一个推出时间不多的的产品,因此在开发时难免会遇到一些问题。如果想要一个更稳定、坑更少的开发环境,建议选择其他平台。

②技术支持
如果在开发过程中遇到了问题,可能无法及时得到官方技术团队的回复。但是uni-app可以在QQ群或者微信群中相互交流。
 

开放性问题

- 端开发在人工智能时代能做什么?

摘抄:

https://www.cnblogs.com/xiaonian8/p/13851751.html
https://www.jianshu.com/p/e5f997713a4b

 
- TensorFlow.js是什么?

摘抄:

https://blog.csdn.net/xiangzhihong8/article/details/82597644
https://cloud.tencent.com/developer/article/1453070

 
- WebAssembly是什么?

WebAssembly(wasm)就是一个可移植、体积小、加载快并且兼容 Web 的全新格式。

实际上,WebAssembly是一种新的字节码格式,旨在成为高级语言的编译目标,目前可以使用C、C++、Rust、Go、Java、C#等编译器(未来还有更多)来创建wasm模块(见下图)。该模块以二进制的格式发送到浏览器,并在专有虚拟机上执行,与JavaScript虚拟机共享内存和线程等资源。

摘抄:https://zhuanlan.zhihu.com/p/74461203


- Parcel 是什么?

Parcel 是一个前端构建工具,Parcel 官网 将它定义为极速零配置的Web应用打包工具。

Parcel 的特性
快速打包:启用多核编译,并具有文件系统缓存
打包所有资源:支持JS,CSS,HTML,文件资源等等 - 不需要安装任何插件
自动转换:使用 Babel,PostCSS 和 PostHTML 自动转换
零配置代码拆分:使用动态 import() 语法拆分您的输出包,只加载初始加载时所需的内容
模块热替换:不需要进行任何配置
友好的错误记录:以语法高亮的形式打印的代码帧,以帮助你查明问题

摘抄:

https://zhuanlan.51cto.com/art/201712/562415.htm
http://t.zoukankan.com/linxin-p-8142639.html

 
- 什么是 PWA?

PWA 是 Google 于 2016 年提出的概念,于 2017 年正式落地,于 2018 年迎来重大突破,全球顶级的浏览器厂商,Google、Microsoft、Apple 已经全数宣布支持 PWA 技术。

PWA 全称为 Progressive Web App,中文译为渐进式 Web APP,其目的是通过各种 Web 技术实现与原生 App 相近的用户体验。

纵观现有 Web 应用与原生应用的对比差距,如离线缓存、沉浸式体验等等,可以通过已经实现的 Web 技术去弥补这些差距,最终达到与原生应用相近的用户体验效果。

摘抄:

https://blog.csdn.net/weixin_44135121/article/details/105528430

 
- 什么是postcss?

postcss 是一个用 JavaScript 工具和插件转换 CSS 代码的工具

摘抄:

https://www.postcss.com.cn/
https://segmentfault.com/a/1190000003909268

 
- 浅谈对nodeJS的认识?

Nodejs是一个平台,构建在chrome的V8上(js语言解释器),采用事件驱动、非阻塞模型( c++库:libuv)。


摘抄:https://blog.csdn.net/cz_sky/article/details/75735687

 
- Nodejs:单线程为什么能支持高并发?

(1)前提:I/O密集型任务
(2)单线程的解释:主线程一个,底层工作线程多个。
(3)事件机制的底层依赖库:libuv、libeio、libev

摘抄:https://www.cnblogs.com/linzhanfly/p/9082895.html

 
- 什么是 web worker?

我们一直强调JavaScript是单线程的,但是web worker的出现使得JavaScript可以在多线程上跑,只是web worker本身适合用于一些复杂的、耗费cpu的运算,不能操作window、document、parent对象,所以说本质上的JavaScript还是单线程的。
web worker就是运行在后台的JavaScript,独立于其他脚本,不会影响页面的性能。您还可以做任意想做的事情,不会影响点击等操作。

为什么需要web worker?
对于耗时而不操作DOM的JavaScript,我们就可以使用web worker,增强性能。

摘抄:

https://blog.csdn.net/xgangzai/article/details/112256016

状态码

1xx(临时响应)

        表示临时响应并需要请求者继续执行操作的状态代码。

        代码 说明

  • 100 (继续) 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 
  • 101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。

2xx (成功)

表示成功处理了请求的状态代码。

  • 200 (成功) 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。
  • 201 (已创建) 请求成功并且服务器创建了新的资源。
  • 202 (已接受) 服务器已接受请求,但尚未处理。
  • 203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
  • 204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
  • 205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
  • 206 (部分内容) 客户端进行了范围请求,服务器成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If-Range 来作为请求条件。

3xx (重定向)

        表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

  • 300 (多种选择) 针对请求,服务器可执行多种操作。服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
  • 301 永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;
  • 302 临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;
  •        301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)
  • 303 表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;
  •       302与303的区别:后者明确表示客户端应当采用GET方式获取资源
  • 304 (未修改) 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
  • 缓存问题:第一次访问 200 ;鼠标点击二次访问 (Cache) ;按F5刷新 304 
  • 305 (使用代理) 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。
  • 307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

        307会遵照浏览器标准不会从POST变成GET;

4xx(请求错误)

        这些状态代码表示请求可能出错,妨碍了服务器的处理。

  • 400 (错误请求) 表示请求报文中存在语法错误;
  • 401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
  • 403 (禁止) 服务器拒绝该次访问(访问权限出现问题)。
  • 404 表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;
  • 405 (方法禁用) 禁用请求中指定的方法。
  • 406 (不接受) 无法使用请求的内容特性响应请求的网页。
  • 407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
  • 408 (请求超时) 服务器等候请求时发生超时。
  • 409 (冲突) 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。
  • 410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
  • 411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
  • 412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
  • 413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
  • 414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
  • 415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
  • 416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
  • 417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求.
  • 419 并不是HTTP标注的一部分,419认证超时表示以前的有效证明已经失效了。同时也被用于401未认证的替代选择为了从其它被拒绝访问的已认证客户端中指定服务器的资源。
  • 495 https certificate error
  • 496 https no certificate
  • 497 http to https
  • 498 canceled
  • 499 client has closed connection  

      测试nginx发现如果两次提交post过快就会出现499的情况,看来是nginx认为是不安全的连接,主动拒绝了客户端的连接.

      在google上搜索到一英文论坛上有关于此错误的解决方法:

      proxy_ignore_client_abort on;

      Don’t know if this is safe.

      就是说要配置参数 proxy_ignore_client_abort on;

      表示代理服务端不要主要主动关闭客户端连接。

5xx(服务器错误)

        这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

  • 500 (服务器内部错误) 服务器遇到错误,也有可能是web应用存在的bug或某些临时的错误时;
  • 501 (尚未实施) 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。
  • 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。错误的原因如下:
    • web服务器请求太多,响应不了这个请求, 这个表现是有时间好有时间不好, 可以通过查看web服务器的日志来定位
    • web服务器没有启动, 可以通过查看日志来定位这个问题,或者查看端口是否启动
    • 网络不同, 不能访问web服务器, 有可能断网, 开启了防火墙等, 可以通过ping命令来定位
  • 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
  • 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
  • 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

HttpWatch状态码Result is

200 - 服务器成功返回网页,客户端请求已成功。 

302 - 对象临时移动。服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

304 - 属于重定向。自上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。

401 - 未授权。请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。

404 - 未找到。服务器找不到请求的网页。

2xx - 成功。表示服务器成功地接受了客户端请求。

3xx - 重定向。表示要完成请求,需要进一步操作。客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求。

4xx - 请求错误。这些状态代码表示请求可能出错,妨碍了服务器的处理。

5xx - 服务器错误。表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。


原文链接:https://blog.csdn.net/qq_20753229/article/details/120844321

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值