irpas技术客

前端八股文_suuuuuki98_前端八股文

irpas 5659

1.css中的三种基本定位机制 普通文档流 元素位置由文档顺序和元素性质决定,块级元素从上到下依次排列,框之间的垂直距离由框的垂直margin值计算得到,行内元素在一行中水平布置。定位 相对定位 (position:relative)  被看作普通流定位模型的一部分,定位元素的位置相对于它在普通流中的位置进行移动。使用相对定位的元素不管它是否进行移动,元素仍要占据它原来的位置。移动元素会导致它覆盖其他的框。对蓝框进行定位后,它仍占据原先的位置。 绝对定位 (position:absolute) 绝对定位的元素位置是相对于距离它最近的那个已定位的祖先(相对/绝对)元素决定的。 如果元素没有已定位的祖先元素, 那么它的位置相对于初始包含块。绝对定位的元素可以在它的包含块向上、下、左、右移动。   与相对定位相反, 绝对定位使元素与文档流无关, 因此不占据空间。 普通文档流中其他的元素的布局不受绝对定位元素的影响。参见下图:对蓝框定位后, 它下面的元素上移占据了蓝框原本的位置, 仿佛蓝框不存在一般    固定定位 (position:fixed) 相对于浏览器窗口,其余的特点类似于绝对定位。浮动 .浮动的元素可以左右移动,直到他的外边框边缘碰到包含自己的框或者另一个浮动框的边缘。浮动的元素脱离普通文档流。行内元素和行内块元素会围绕浮动框排列,块元素会被覆盖。 2.BFC和浮动相关 BFC(Block Formatting Context),块级格式上下文作用:形成独立的渲染区域,确保内部元素的渲染不会影响外界应用场景:清除浮动,避免垂直外边距叠加,实现自适应布局

形成BFC的常见条件:

浮动元素 float不是none绝对定位元素 position :absolute或者fixed块级元素:overflow不是visibleflex元素inline-block元素

两栏自适应布局

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { width: 800px; height: 800px; background-color: gray } .son1 { float: left; width: 300px; height: 100%; background-color: brown } .son2 { overflow: hidden; height: 100%; background-color: green } </style> </head> <body> <div class="father"> <div class="son1"></div> <div class="son2"></div> </div> </body> </html>

清除浮动

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { overflow: hidden; width: 800px; background-color: gray; } .img { float: left; } .bfc { overflow: hidden; } </style> </head> <body> <div class="father"> <div class="img"> <img src="./test.jpg" alt=""> </div> <p class="bfc">BFC(Block Formatting Context),块级格式上下文 作用:形成独立的渲染区域,确保内部元素的渲染不会影响外界 应用场景:清除浮动,避免垂直外边距叠加,实现自适应布局</p> </div> </body> </html>

解决外边距塌陷

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { overflow: hidden; width: 800px; height: 800px; background-color: gray } .son1 { margin-top: 100px; width: 300px; height: 300px; background-color: brown } </style> </head> <body> <div class="father"> <div class="son1"></div> </div> </body> </html> 3.css盒模型

1.什么是css模型? css的盒模型由里到外包括:content,padding,border,margin4部分,如图所示。

css的盒模型有两种:IE盒模型和标准盒模型。

2.两种盒模型的区别

W3C标准盒子模型(content-box):内容就是盒子的边界。W3C标准盒子模型(content-box): width=内容宽度IE盒子模型(border-box):边框才是盒子的边界。IE盒子模型(border-box): width=内容宽度+padding+border

3.如何设置两种盒模型 在不设置box-sizing的情况下,box-sizing默认是content-box。

/* 标准模型 */ box-sizing:content-box; /*IE模型*/ box-sizing:border-box; 4.flex布局

添加链接描述

Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为Flex布局。.box{display:flex;}行内元素也可以使用Flex布局。.box{display:inline-flex;}

1、flex-direction 此属性决定主轴的方向

.flex{ flex-direction: row; // (默认值) 主轴水平方向,从左往右 如图: flex-direction: row-reverse; // 主轴水平方向的逆方向,从右往左 flex-direction: column; // 主轴为垂直方向,从上往下 flex-direction: column-reverse; // 主轴为垂直方向的逆方向,从下往上 }

2、flex-wrap 此属性定义,如果一条轴线上排列不下,换行的方式

.flex{ flex-wrap: nowrap; // (默认)不换行 如图: flex-wrap: wrap; // 正常换行 从上到下 如图: flex-wrap: wrap-reverse; // 逆方向换行 从下到上 如图:

3、justify-content 此属性定义,项目在主轴上的对齐方式

.flex{ justify-content: flex-start; // 左对齐(默认) justify-content: flex-end; // 右对齐 justify-content: center; // 居中 justify-content: space-between; // 两端对齐。且项目间间隔相等 justify-content: space-around; // 每个项目两侧间隔相等,所以项目间 间隔 比项目与边框间间隔大一倍 justify-content: space-evenly; // 项目间间隔与项目与边框间 间隔均匀分配 }

4、align-items 此属性定义,项目在交叉轴上的对齐方式

.flex{ align-items: flex-start; // 交叉轴的起点对齐 align-items: flex-end; // 交叉轴的终点对齐 align-items:center; // 交叉轴的中点对齐 align-items: baseline; // 项目的第一行文字的基线对齐 align-items: stretch; // (默认值) 如果项目未设置高度或设为auto ,将充满整父级容器高度 }

5.三栏自适应布局

flex

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { width: 100%; height: 200px; display: flex; } .son1 { width: 200px; height: 100%; background-color: blueviolet; } .son3 { width: 200px; height: 100%; background-color: brown; } .son2 { flex: 1; background-color: blue; } </style> </head> <body> <div class="father"> <div class="son1"></div> <div class="son2"></div> <div class="son3"></div> </div> </body> </html>``` ```javascript <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { width: 100%; height: 200px; display: flex; } .son1 { width: 200px; height: 100%; background-color: blueviolet; } .son3 { width: 200px; height: 100%; background-color: brown; } .son2 { flex: 1; background-color: blue; } </style> </head> <body> <div class="father"> <div class="son1"></div> <div class="son2"></div> <div class="son3"></div> </div> </body> </html>

float

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { width: 100%; height: 200px; } .son1 { float: left; width: 200px; height: 100%; background-color: blueviolet; } .son3 { float: right; width: 200px; height: 100%; background-color: brown; } .son2 { width: 100%; height: 100%; background-color: blue; } </style> </head> <body> <div class="father"> <div class="son1"></div> <div class="son3"></div> <div class="son2"></div> </div> </body> </html>

grid

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { width: 100%; height: 200px; display: grid; grid-template-columns: 200px auto 200px; } .son1 { height: 100%; background-color: blueviolet; display: table-cell; } .son3 { height: 100%; background-color: brown; display: table-cell; } .son2 { height: 100%; background-color: blue; display: table-cell; } </style> </head> <body> <div class="father"> <div class="son1"></div> <div class="son2"></div> <div class="son3"></div> </div> </body> </html>

position

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { position: relative; width: 100%; height: 200px; } .son1 { position: absolute; left: 0; top: 0; width: 200px; height: 100%; background-color: blueviolet; } .son3 { position: absolute; right: 0; top: 0; width: 200px; height: 100%; background-color: brown; } .son2 { width: 100%; height: 100%; background-color: blue; } </style> </head> <body> <div class="father"> <div class="son1"></div> <div class="son2"></div> <div class="son3"></div> </div> </body> </html>

table

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .father { width: 100%; height: 200px; display: table; } .son1 { width: 200px; height: 100%; background-color: blueviolet; display: table-cell; } .son3 { width: 200px; height: 100%; background-color: brown; display: table-cell; } .son2 { height: 100%; background-color: blue; display: table-cell; } </style> </head> <body> <div class="father"> <div class="son1"></div> <div class="son2"></div> <div class="son3"></div> </div> </body> </html> 6.html5,css3新属性

原博客地址

7.HTTP和HTTPS HTTP:超文本传输协议 以明文方式发送内容HTTPS:安全套接字层超文本传输协议HTTPS在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

1. 客户端发起HTTPS请求 这个没什么好说的,就是用户在浏览器里输入一个https网址,然后连接到server的443端口。

2. 服务端的配置 采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。这套证书其实就是一对公钥和私钥。如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

3. 传送证书 这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。

4. 客户端解析证书 这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随机值。然后用证书对该随机值进行加密。就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。

5. 传送加密信息 这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。

6. 服务端解密信息 服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥(随机值)通过某种算法混合在一起,这样除非知道私钥(随机值),不然无法获取内容,而正好客户端和服务端都知道这个私钥(随机值),所以只要加密算法够彪悍,私钥(随机值)够复杂,数据就够安全。

7. 传输加密后的信息 这部分信息是服务端用私钥(随机值)加密后的信息,可以在客户端被还原

8. 客户端解密信息 客户端用之前生成的私钥(随机值)解密服务端传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策。

添加链接描述

对称加密和非对称加密 添加链接描述

8.防抖和节流 防抖: <body> <input type="text" name="" id="" /> </body> <script> //缺点:新建全局变量,防抖逻辑与业务逻辑混在一起 let inp = document.querySelector('input') let t = null inp.oninput = function () { if (t !== null) { clearTimeout(t) } t = setTimeout(() => { console.log(this.value) }, 500) } </script> <script> //方法二 let inp = document.querySelector('input') inp.oninput = debounce(function () { console.log(this.value) }, 500) function debounce(fn, delay) { let t = null return function () { if (t !== null) { clearTimeout(t) } t = setTimeout(() => { fn.call(this) }, delay) } } </script> 节流 <body></body> <style> body { height: 2000px; } </style> //写法一 <script> let flag = true window.onscroll = function () { if (flag) { setTimeout(() => { console.log(123) flag = true }, 500) } flag = false } </script> //写法二 <script> window.onscroll = throttle(function () { console.log(123) }, 500) function throttle(fn, delay) { let flag = true return function () { if (flag) { setTimeout(() => { fn.call(this) flag = true }, delay) } flag = false } } </script> 9.数组扁平化 <script> let arr = [ [0, 1], [2, 3], [4, [5, 6, 7]], ] //tostring const flatten1 = (arr) => { return arr .toString() .split(',') .map((item) => { return +item }) } //递归 let res = [] const flatten2 = (arr) => { for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { flatten2(arr[i]) } else { res.push(arr[i]) } } return res } console.log(flatten2(arr)) //reduce const flatten3 = (arr) => { return arr.reduce( (pre, cur) => pre.concat(Array.isArray(cur) ? flatten3(cur) : cur), [] ) } console.log(flatten3(arr)) //... </script> 10.前端本地存储:cookie localStorage sessionStorage indexedDB

原博地址

COOKIECookie又叫会话跟踪技术,事实上就是以Key,Value的形式存储在浏览器端的数据。

工作原理

在Request的时候,浏览器将Cookie信息放在HTTP-Request Headers中。在Response的时候,浏览器保存HTTP-Response Headers信息中的Cookie信息。Cookie的核心信息包含三个部分:Name、Value、过期时间。Cookie的保存是覆盖式的,所以Cookie的添加、更新、删除对于浏览器来说都是执行设置(set)的动作。存储属性除了Name、Value、过期时间,还有Domain、Path,当前域可以操作当前域子域、父域名的Cookie,当前Path,可以操作当前Path以及当前Path子、父Path下的Cookie

为什么需要强调它的工作原理呢?事实上cookie的作用、缺点甚至于缺点的改善都是围绕工作原理进行的。

作用

会话状态管理(如用户登录状态、购物车、游戏分数和其它需要记录的信息)个性化设置(如用户自定义设置、主题等)

传输特点

每次Request客户端符合domian以及path要求的Cookie都会通过Request Headers传输到服务器端传输的Cookie大小会受到浏览器以及Web服务器的限制 安全特点 Cookie中的信息很容易被查看,建议加密后存储Cookie容易被XSS攻击利用,可以设置HttpOnly=true,不允许客户端访问

应用

设置:document.cookie = ‘key=val;path:/;expires=’+d (d为时间)获取:document.cookie删除cookie: 将过期时间设置为负值

缺点

存储大小最多4KB存储数量根据浏览器或浏览器版本的不同而不同,并且每个域最多20条不安全(请求头常带存储信息)存储数据类型限制,cookie只能存储字符串

提高安全性措施

对保存到cookie里面的敏感信息必须加密设置HttpOnly为true,防止Cookie值被页面脚本读取设置Secure为true,只有在https协议下访问的时候,浏览器才会发送该Cookie给Cookie设置有效期(分一个长时间不活动的失效时间与即使一直在活动也要失效的时间)

Web Storage

准确地来说,因为cookie确切地存在着缺点,h5也对其进行了优化。因此localStorage和sessionStorage解决了不少cookie的缺点,也被作为本地存储的重要方式。

LocalStorage 特点

生命周期是永久性的。即使关闭浏览器,数据也不会销毁存储大小一般为5M需要主动去销毁储存的对象类型均为字符串类型 同源可以读取并修改localStorage数据

SessionStorage

特点

生命周期是在浏览器关闭前。即关闭浏览器数据就会销毁存储大小一般为5M储存的对象类型均为字符串类型只允许同一窗口访问 11.常用设计模式 12.热更新(HMR)原理

webpack 的热更新:文件保存后页面自动刷新,或者 css 自动更新,页面的样式在不刷新页面的情况下就会更新。

HMR(Hot Module Replacement)是webpack一个重要的特性,当代码文件修改并保存之后,webapck通过watch监听到文件发生变化,会对代码文件重新打包生成两个模块补丁文件manifest(js)和一个(或多个)updated chunk(js),将结果存储在内存文件系统中,通过websocket通信机制将重新打包的模块发送到浏览器端,浏览器动态的获取新的模块补丁替换旧的模块,浏览器不需要刷新页面就可以实现应用的更新。 添加链接描述 添加链接描述

13.作用域和自由变量

全局作用域函数作用域块集作用域 //全局作用域和函数作用域 let a1 = 1 function fn1() { let a2 = 2 console.log(a2) //2 console.log(a3) //error function fn2() { let a3 = 3 console.log(a3) //1 console.log(a2) //2 } fn2() } fn1() console.log(a1) //1 console.log(a2) // error console.log(a3) //error //块级作用域 { let a = 1 } console.log('a', a) //error 作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行作用域链本质上就是根据名称查找变量(标识符名称)的一套规则。规则非常简单,在自己的变量对象里找不到变量,就上父级的变量对象查找,当抵达最外层的全局上下文中,无论找到还是没找到,查找过程都会停止。查找会在找到第一个匹配的变量时停止,被称为遮蔽效应 14.闭包

执行上下文

全局环境函数环境Eval环境(慎用)

闭包:一个函数(定义的位置)和他周围状态的引用捆绑在一起的组合

闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量

函数作为返回值 function test() { const a = 1 return function () { console.log(a) } } const fn = test() const a = 2 fn() //1 函数作为参数 function test(fn) { const a = 1 fn() } const a = 2 function fn() { console.log(a) } //2 15.this this的值是在函数执行时决定的,不是在函数定义时决定的 class Person { constructor(name, age) { console.log('constructor里面的this', this) // this.name = name this.age = age } test() { console.log('test里面的this', this) } test1() { setTimeout(function () { console.log(this) }, 0) } test2() { setTimeout(() => { console.log(this) }, 0) } } const zhangsan = new Person('zhangsan', 20) zhangsan.test() //obj obj zhangsan.test1() //window zhangsan.test2() //obj 箭头函数里面的this值和上一级作用域保持一致 16.手写bind函数

bind函数

改变this指向第一个参数是this的值,后面的参数是函数接收的参数的值返回值不变 function test(a, b, c) { console.log(a, b, c) console.log(this) } test(1, 2, 3) //window const test1 = test.bind({ name: 'zhangsan' }, 2, 3, 4) test1() //obj //手写bind函数 function test(a, b, c) { console.log(a, b, c) console.log(this) return 'shuchuzhengchang' } Function.prototype.myBind = function () { const self = this const arg = Array.prototype.slice.call(arguments) const obj = arg.shift() return function () { return self.call(obj, arg) } } const res = test.myBind({ name: 'zhangsan' }, 1, 2, 3) res() 17.高阶函数 函数作为参数传递给另一个函数函数作为另一个函数的返回值

let arr = [1, 2, 3, 4] const res1 = arr.map((x) => { return x * x }) console.log(res1) const res2 = arr.reduce((pre, cur) => { return pre + cur }, 0) console.log(res2) //10 const res3 = arr.filter((x) => { return x % 2 == 0 }) console.log(res3) 18.计算机网络整理

浏览器的工作流程

浏览器首先使用HTTP或者HTTPS协议,向服务端发送请求把请求回来的HTML代码经过解析,构建成DOM树计算DOM树上的CSS属性根据CSS属性对元素逐个进行渲染,得到内存中的位图一个可选的步骤是对位图进行合成,这会极大的增加后续绘制的速度合成之后再绘制到界面上

HTTP Request

HTTP的请求包括:请求行(request line)、请求头部(header)、空行 和 请求数据 四个部分组成。

HTTP Response

HTTP响应也由4部分组成,分别是:状态行、响应头、空行 和 响应体。

常见状态码

请求方法

工作原理

HTTP协议采用请求/响应模式,客户端向服务器发送一个请求报文,然后服务器响应请求。下面介绍一下一次HTTP请求的过程:

在浏览器中输入URL,并按下回车键浏览器向DNS服务器请求解析该URL中的域名对应的IP地址(如果是IP请求,则不需要该步骤)解析出IP后,根据IP和端口号,和服务器建立TCP连接浏览器向服务器发送请求,该请求报文作为TCP三次握手的第三个报文发送给服务器服务器做出响应,把数据发送给浏览器通信完成,断开TCP连接浏览器解析收到的数据并显示

TCP UDP的区别

TCP/UDP都工作在传输层,在程序之间传输数据

TCP 三次握手四次挥手

添加链接描述

第一次握手:客户端A将标志位SYN置为1,随机产生一个值为seq=J(J的取值范围为=1234567)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认;第二次握手:服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_RCVD状态。第三次握手:客户端A收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务端B,服务端B检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态,完成三次握手,随后客户端A与服务端B之间可以开始传输数据了。三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误” 第一次挥手: Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。第二次挥手: Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态第三次挥手: Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

19.跨域 同源策略:协议 域名 端口号均相同跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

实现跨域的方式:

JSONP 利用了 script 不受同源策略的限制 缺点:只能 get 方式,易受到 XSS攻击

CORS 1.当使用XMLHttpRequest发送请求时,如果浏览器发现违反了同源策略就会自动加上一个请求头 origin; 2.后端在接受到请求后确定响应后会在 Response Headers 中加入一个属性 Access-Control-Allow-Origin; 3.浏览器判断响应中的 Access-Control-Allow-Origin 值是否和当前的地址相同,匹配成功后才继续响应处理,否则报错 缺点:忽略 cookie,浏览器版本有一定要求

20.进程和线程(浏览器线程)

CPU:计算机的核心,其负责承担计算机的计算任务。这里我们比喻为一个工厂

进程:学术上说,进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。我们这里将进程比喻为工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态

线程:在早期的操作系统中并没有线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。后来,随着计算机的发展,对CPU的要求越来越高,进程之间的切换开销较大,已经无法满足越来越复杂的程序的要求了。于是就发明了线程,线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元。这里把线程比喻一个车间的工人,即一个车间可以允许由多个工人协同完成一个任务。

多进程:多进程指的是在同一个时间里,**同一个计算机系统中如果允许两个或两个以上的进程处于运行状态。**多进程带来的好处是明显的,比如你可以听歌的同时,打开编辑器敲代码,编辑器和听歌软件的进程之间丝毫不会相互干扰。

多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

浏览器

Chrome浏览器使用多个进程来隔离不同的网页。因此在Chrome中打开一个网页相当于起了一个进程

浏览器内核是多线程

浏览器内核是多线程,在内核控制下各线程相互配合以保持同步,一个浏览器通常由以下常驻线程组成:

GUI 渲染线程JavaScript引擎线程定时触发器线程事件触发线程异步http请求线程

为什么Javascript要是单线程的?

JavaScript为处理页面中用户的交互,以及操作DOM树、CSS样式树来给用户呈现一份动态而丰富的交互体验和服务器逻辑的交互处理。如果JavaScript是多线程的方式来操作这些UI DOM,则可能出现UI操作的冲突;

GUI 渲染线程 与 JavaScript引擎线程互斥

由于JavaScript是可操纵DOM的,如果在修改这些元素属性同时渲染界面(即JavaScript线程和UI线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。因此为了防止渲染出现不可预期的结果,浏览器设置GUI渲染线程与JavaScript引擎为互斥的关系,当JavaScript引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到引擎线程空闲时立即被执行。

JS阻塞页面加载

由于于GUI渲染线程与JavaScript执行线程是互斥的关系,当浏览器在执行JavaScript程序的时候,GUI渲染线程会被保存在一个队列中,直到JS程序执行完成,才会接着执行。因此如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。 21.JS如何解决异步问题(event loop)

运行以后的程序叫做进程,一般情况下,一个进程一次只能执行一个任务。如果有很多任务需要执行,不外乎三种解决方法。

排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。新建进程。使用fork命令,为每个任务新建一个进程。新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。

多线程不仅占用多倍的系统资源,也闲置多倍的资源,这显然不合理。Event Loop就是为了解决这个问题而提出的。简单说,就是在程序中设置两个线程:一个负责程序本身的运行,称为"主线程";另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为"Event Loop线程"(可以译为"消息线程")。 上图主线程的绿色部分,还是表示运行时间,而橙色部分表示空闲时间。每当遇到I/O的时候,主线程就让Event Loop线程去通知相应的I/O程序,然后接着往后运行,所以不存在红色的等待时间。等到I/O程序完成操作,Event Loop线程再把结果返回主线程。主线程就调用事先设定的回调函数,完成整个任务。 执行一个宏任务(栈中没有就从事件队列中获取) 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行) 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)

22.Promise.all promise.race Promise.all()方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。

添加链接描述

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的promise就会解决或拒绝。

添加链接描述

处理并行请求

在这里插入代码片 23.computed watch

区别 computed

computed是计算属性,所以更多用在数值计算的场景中(比如: 添加商品计算总价)computed具有缓存性,之前get过的值之后会缓存的,只有在它的依赖的属性值发生了变化,下次获取computed的值时才会重新调用对应的get重新计算computed在性能方面上比watch要好一点,因为具有缓存性 computed适用于计算比较复杂中

watch

watch是监听观察的作用,类似于监听某些数据的回调,一般用于监听$emit/prop/data的值,当监听的数据发生改变做数据回调处理watch无缓存性,页面重新渲染时值不变化也会执行

总结

computed更多的是用于一些计算比较复杂的场景,简单来说就是多对一,get里面的依赖属性的值发生变化则重新计算(监听的属性不可在data中定义)watch更多的用于某个数据发生变化时处理一些事情,简单来说就是一对多 24. watch watchEffect watch- 显式指定依赖源,依赖源更新时执行回调函数watchEffect - 自动收集依赖源,依赖源更新时重新执行自身 // 一个响应式的测试对象 const testObject = reactive({ innerObj: { innerA: 'innerBBBBBB' }, a: 'bbbbbbb' }) watchEffect(() => { console.log(testObject.a) // 即使 testObject.a 没有发生变化,也会在组件更新之前输出一遍 }) watch(() => testObject.a, (curVal, lastVal) => { console.log(curVal, lastVal) // 只有当 testObject.a 发生了变化,才会执行该函数 }) // watch 也可以监听多个数据源,具体可以参考一下官方文档

区别

watch 是需要传入侦听的数据源,而 watchEffect 是自动收集数据源作为依赖。watch 可以访问侦听状态变化前后的值,而 watchEffect 没有。watch 是属性改变的时候执行,而 watchEffect 是默认会执行一次,然后属性改变也会执行。 25.前端安全

添加链接描述

25.JS垃圾回收,浏览器垃圾回收

添加链接描述 添加链接描述

26.css link与import的区别是什么 加载页面时,link标签引入的 CSS 被同时加载;@import引入的 CSS 将在页面加载完毕后被加载。

添加链接描述

27.JS之事件捕获和事件冒泡

添加链接描述

事件捕获(event capturing): 当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点 =>事件源(由外到内)进行事件传播。

事件冒泡(dubbed bubbling): 事件源 =>根节点(由内到外)进行事件传播。

28.webSocket

(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。 (7)双向通信

添加链接描述 添加链接描述

29.nextTick

添加链接描述

30.HTTP1.0 1.1 2.0 3.0

添加链接描述 添加链接描述

31.Vue Router 路由(路由守卫)

添加链接描述

32.cookie session

添加链接描述

33.vue mixin

添加链接描述

34.vue 双向数据绑定原理

添加链接描述

35.CDN原理

CDN是将源站内容分发至全国所有的节点,从而缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性的技术。它能够有效解决网络带宽小、用户访问量大、网点分布不均等问题。

添加链接描述

添加链接描述

36.为什么要用vdom

添加链接描述

虚拟 DOM 提升性能的点在于 DOM 发生变化的时候,通过 diff 算法比对 JavaScript 原生对象,计算出需要变更的 DOM,然后只对变化的 DOM 进行操作,而不是更新整个视图。

添加链接描述

我们会有两个虚拟DOM(js对象,new/old进行比较diff),用户交互我们操作数据变化new虚拟DOM,old虚拟DOM会映射成实际DOM(js对象生成的DOM文档)通过DOM fragment操作给浏览器渲染。当修改new虚拟DOM,会把newDOM和oldDOM通过diff算法比较,得出diff结果数据表(用4种变换情况表示)。再把diff结果表通过DOM fragment更新到浏览器DOM中。

37.类和继承

添加链接描述

ES5 的继承,实质是先创造子类的实例对象 this ,然后再将父类的方法添加到 this 上(Parent.apply(this) )。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到 this 上面(所以必须先调用 super方法),然后再用子类的构造函数修改 this 。 38.new一个对象时发生了什么

vue依赖收集原理

39.DNS解析过程为什么是UDP

添加链接描述

**39.HTML5 为什么只需写< !DOCTYPE HTML> ? 40.类的定义和继承

ES5实现类和继承的几种方式,各有什么优缺点 添加链接描述 ES6实现类和继承 添加链接描述

注:

由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign方法可以很方便地一次向类添加多个方法。 class Point { constructor(){ // ... } } Object.assign(Point.prototype, { toString(){}, toValue(){} }); //prototype对象的constructor属性,直接指向“类”的本身,这与ES5的行为是一致的。 Point.prototype.constructor === Point // true ES6定义的类的方法不可枚举constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。不存在变量提升私有方法是常见需求,但ES6不提供,只能通过变通方法模拟实现。ES5的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this

ES6实现私有方法

添加链接描述

ES6实现私有属性 添加链接描述

类的prototype属性和__proto__属性

大多数浏览器的ES5实现之中,每一个对象都有**__proto__属性,指向对应的构造函数的prototype属性**。Class作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。

(1)子类的__proto__属性,表示构造函数的继承,总是指向父类。

(2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

class A { } class B extends A { } B.__proto__ === A // true B.prototype.__proto__ === A.prototype // true

class静态方法

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。 41.ES6 proxy Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。 var obj = new Proxy({}, { get: function (target, key, receiver) { console.log(`getting ${key}!`); return Reflect.get(target, key, receiver); }, set: function (target, key, value, receiver) { console.log(`setting ${key}!`); return Reflect.set(target, key, value, receiver); } }); obj.count = 1 // setting count! ++obj.count // getting count! // setting count! // 2 42.vdom

添加链接描述

43.diff算法


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #前端八股文 #滴滴滴