1.http 和 https 的基本概念
- http: 是⼀个客⼾端和服务器端请求和应答的标准(TCP),⽤于从 WWW 服务器传输超⽂本到本地浏 览器的超⽂本传输协议。
- https:是以安全为⽬标的 HTTP 通道,即 HTTP 下 加⼊ SSL 层进⾏加密。其作⽤是:建⽴⼀个信息安 全通道,来确保数据的传输,确保⽹站的真实性。
2.http 和 https 的区别及优缺点?
• http 是超⽂本传输协议,信息是明⽂传输,HTTPS 协议要⽐ http 协议 安全 ,https 是具有安全性 的 ssl 加密传输协议,可防⽌数据在传输过程中被窃取、改变,确保数据的完整性(当然这种安全性 并⾮绝对的,对于更深⼊的 Web 安全问题,此处暂且不表)。
• http 协议的 默认端⼝ 为 80,https 的默认端⼝为 443。
• http 的连接很简单,是⽆状态的。https 握⼿阶段⽐较 费时 ,会使⻚⾯加载时间延⻓ 50%,增加 10%~20%的耗电。
• https 缓存 不如 http ⾼效,会增加数据开销。
• Https 协议需要 ca 证书,费⽤较⾼,功能越强⼤的 证书费 ⽤越⾼。
• SSL 证书需要绑定 域名 。
3.https 协议的⼯作原理
客⼾端在使⽤ HTTPS ⽅式与 Web 服务器通信时有以下⼏个步骤:
1.客⼾端使⽤ https url 访问服务器,则要求 web 服务器 建⽴ ssl 链接 。
2.web 服务器接收到客⼾端的请求之后,会 将⽹站的证书(证书中包含了公钥),传输给客⼾端 。
3.客⼾端和 web 服务器端开始 协商 SSL 链接的安全等级 ,也就是加密等级。
4.客⼾端浏览器通过双⽅协商⼀致的安全等级, 建⽴会话密钥 ,然后通过⽹站的公钥来加密会话密 钥,并传送给⽹站。
5.web 服务器 通过⾃⼰的私钥解密出会话密钥 。
6.web 服务器 通过会话密钥加密与客⼾端之间的通信 。
4.TCP三次握⼿
1. 第⼀次握⼿: 建⽴连接时,客⼾端发送syn包(syn=j)到服务器,并进⼊SYN_SENT状态,等待 服务器确认 ;SYN:同步序列编号(Synchronize Sequence Numbers)。
2. 第⼆次握⼿: 服务器收到syn包并确认客⼾的SYN (ack=j+1), 同时也发送⼀个⾃⼰的SYN包 (syn=k),即SYN+ACK包,此时服务器进⼊SYN_RECV状态;
3. 第三次握⼿: 客⼾端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1) ,此包发 送完毕,客⼾端和服务器进⼊ESTABLISHED(TCP连接成功)状态,完成三次握⼿。
4. 握⼿过程中传送的包⾥不包含数据,三次握⼿完毕后,客⼾端与服务器才正式开始传送数据。
5.TCP 四次挥⼿
1.客⼾端进程发出连接释放报⽂ ,并且停⽌发送数据。释放数据报⽂⾸部,FIN=1,其序列号为 seq=u(等于前⾯已经传送过来的数据的最后⼀个字节的序号加1),此时, 客⼾端进⼊FIN- WAIT-1(终⽌等待1)状态 。 TCP规定,FIN报⽂段即使不携带数据,也要消耗⼀个序号。
2.服务器收到连接释放报⽂,发出确认报⽂ ,ACK=1,ack=u+1,并且带上⾃⼰的序列号seq=v, 此时, 服务端就进⼊了CLOSE-WAIT(关闭等待)状态 。TCP服务器通知⾼层的应⽤进程,客⼾端向 服务器的⽅向就释放了,这时候处于半关闭状态,即客⼾端已经没有数据要发送了,但是服务器若发 送数据,客⼾端依然要接受。这个状态还要持续⼀段时间,也就是整个CLOSE-WAIT状态持续的时间。
3.客⼾端收到服务器的确认请求后,此时, 客⼾端就进⼊FIN-WAIT-2(终⽌等待2)状态 ,等待 服务器发送连接释放报⽂(在这之前还需要接受服务器发送的最 后的数据)。
4.服务器将最后的数据发送完毕后,就向客⼾端发送连接释放报⽂ ,FIN=1,ack=u+1,由于在半 关闭状态,服务器很可能⼜发送了⼀些数据,假定此时的序列号为seq=w,此时, 服务器就进⼊了 LAST-ACK(最后确认)状态 ,等待客⼾端的确认。
5.客⼾端收到服务器的连接释放报⽂后,必须发出确认 ,ACK=1,ack=w+1,⽽⾃⼰的序列号是 seq=u+1,此时, 客⼾端就进⼊了TIME-WAIT(时间等待)状态 。注意此时TCP连接还没有释放, 必须经过2X区MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状
6.服务器只要收到了客户端发出的确认,立即进入CLOSED状态 。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
6.TCP/IP / 如何保证数据包传输的有序可靠?
对字节流分段并进⾏编号然后 通过 ACK 回复 和 超时重发 这两个机制来保证。
(1)为了保证数据包的可靠传递,发送⽅必须把已发送的数据包保留在缓冲区;
(2)并为每个已发送的数据包启动⼀个超时定时器;
(3)如在定时器超时之前收到了对⽅发来的应答信息(可能是对本包的应答,也可以是对本包后续包 的应答),则释放该数据包占⽤的缓冲区;
(4)否则,重传该数据包,直到收到应答或重传次数超过规定的最⼤次数为⽌。
(5)接收⽅收到数据包后,先进⾏CRC校验,如果正确则把数据交给上层协议,然后给发送⽅发送⼀ 个累计应答包,表明该数据已收到,如果接收⽅正好也有数据要发给发送⽅,应答包也可⽅在数据包 中捎带过去。
7.TCP和UDP的区别
1. TCP是⾯向 链接 的,⽽UDP是⾯向⽆连接的。
2. TCP仅⽀持 单播传输 ,UDP 提供了单播,多播,⼴播的功能。
3. TCP的三次握⼿保证了连接的 可靠性 ; UDP是⽆连接的、不可靠的⼀种数据传输协议,⾸先不可靠 性体现在⽆连接上,通信都不需要建⽴连接,对接收到的数据也不发送确认信号,发送端不知道数 据是否会正确接收。
4. UDP的 头部开销 ⽐TCP的更⼩,数据 传输速率更⾼ , 实时性更好 。
8.HTTP 请求跨域问题
1. 跨域的原理
2. 跨域,是指浏览器不能执⾏其他⽹站的脚本。它是由浏览器的 同源策略 造成的。 同源策略,是浏览器对 JavaScript 实施的安全限制,只要 协议、域名、端⼝ 有任何⼀个不同,都 被当作是不同的域。 跨域原理,即是通过各种⽅式, 避开浏览器的安全限制 。
3. 解决⽅案
4. 最初做项⽬的时候,使⽤的是jsonp,但存在⼀些问题,使⽤get请求不安全,携带数据较⼩,后来 也⽤过iframe,但只有主域相同才⾏,也是存在些问题,后来通过了解和学习发现使⽤代理和 proxy代理配合起来使⽤⽐较⽅便,就引导后台按这种⽅式做下服务器配置,在开发中使⽤proxy, 在服务器上使⽤nginx代理,这样开发过程中彼此都⽅便,效率也⾼;现在h5新特性还有 windows.postMessage() ◦
5. JSONP:
ajax 请求受同源策略影响,不允许进⾏跨域请求,⽽ script 标签 src 属性中的链 接却可以访问 跨域的 js 脚本,利⽤这个特性,服务端不再返回 JSON 格式的数据,⽽是 返回⼀段调⽤某个函 数的 js 代码,在 src 中进⾏了调⽤,这样实现了跨域。
6.步骤:
i. 去创建⼀个script标签
ii. script的src属性设置接⼝地址
iii. 接⼝参数,必须要带⼀个⾃定义函数名,要不然后台⽆法返回数据
iv. 通过定义函数名去接受返回的数据
//动态创建
scriptvar script = document.createElement('script');
// 设置回调函数
function getData(data) { console.log(data);}
//设置 script 的 src 属性,并设 置请求地址
script.src = 'http://localhost:3000/?callback=getData';
// 让 script ⽣效
document.body.appendChild(script);
JSONP 的缺点: JSON 只⽀持 get,因为 script 标签只能使⽤ get 请求; JSONP 需要后端配合返回指定格式的 数据。
document.domain 基础域名相同 ⼦域名不同 ◦
window.name 利⽤在⼀个浏览器窗⼝内,载⼊所有的域名都是共享⼀个window.name ◦
CORS CORS(Cross-origin resource sharing)跨域资源共享 服务器设置对CORS的⽀持原理:服 务器设置Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求 ◦
proxy代理 ⽬前常⽤⽅式,通过服务器设置代理 ◦
window.postMessage() 利⽤h5新特性window.postMessage()
9.Cookie、sessionStorage、localStorage 的区别
相同点:
• 存储在客⼾端
不同点:
• cookie数据⼤⼩不能超过4k;sessionStorage和localStorage的存储⽐cookie⼤得多,可以达到 5M+
• cookie设置的过期时间之前⼀直有效;localStorage永久存储,浏览器关闭后数据不丢失除⾮主动 删除数据;sessionStorage数据在当前浏览器窗⼝关闭后⾃动删除
• cookie的数据会⾃动的传递到服务器;sessionStorage和localStorage数据保存在本地
10.粘包问题分析与对策
TCP粘包是指发送⽅发送的若⼲包数据到接收⽅接收时粘成⼀包,从接收缓冲区看,后⼀包数据的头紧 接着前⼀包数据的尾。
粘包出现原因
简单得说,在流传输中出现,UDP不会出现粘包,因为它有消息边界
粘包情况有两种,⼀种是粘在⼀起的包都是完整的数据包 ,另⼀种情况是 粘在⼀起的包有不完整的 包 。
为了避免粘包现象,可采取以下⼏种措施:
(1)对于发送⽅引起的粘包现象,⽤⼾可通过编程设置来避免, TCP提供了强制数据⽴即传送的操作 指令push ,TCP软件收到该操作指令后,就⽴即将本段数据发送出去,⽽不必等待发送缓冲区满;
(2)对于接收⽅引起的粘包,则可通过优化程序设计、精简接收进程⼯作量、 提⾼接收进程优先级 等措施 ,使其及时接收数据,从⽽尽量避免出现粘包现象;
(3)由接收⽅控制,将⼀包数据按结构字段,⼈为控制分多次接收,然后合并,通过这种⼿段来避免 粘包。 分包多发 。 以上提到的三种措施,都有其不⾜之处。
* 第⼀种编程设置⽅法虽然可以避免发送⽅引起的粘包,但它关闭了优化算法,降低了⽹络发送 效率,影响应⽤程序的性能,⼀般不建议使⽤。
* 第⼆种⽅法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较⾼时,或由于 ⽹络突发可能使某个时间段数据包到达接收⽅较快,接收⽅还是有可能来不及接收,从⽽导致粘包。
* 第三种⽅法虽然避免了粘包,但应⽤程序的效率较低,对实时应⽤的场合不适合。 ⼀种⽐较周全的对策是:接收⽅创建⼀预处理线程,对接收到的数据包进⾏预处理,将粘连的包分 开。实验证明这种⽅法是⾼效可⾏的。
11.浏览器重绘与重排的区别?
• 重排/回流(Reflow) :当 DOM 的变化影响了元素的⼏何信息,浏览器需要重新计算元素的⼏ 何属性,将其安放在界⾯中的正确位置,这个过程叫做重排。表现为重新⽣成布局,重新排列元 素。
• 重绘(Repaint) : 当⼀个元素的外观发⽣改变,但没有改变布局,重新把元素外观绘制出来的过 程,叫做重绘。表现为某些元素的外观被改变 单单改变元素的外观,肯定不会引起⽹⻚重新⽣成布局,但当浏览器完成重排之后,将会重新绘制受 到此次重排影响的部分 重排和重绘代价是⾼昂的,它们会破坏⽤⼾体验,并且让UI展⽰⾮常迟缓,⽽相⽐之下重排的性能影 响更⼤,在两者⽆法避免的情况下,⼀般我们宁可选择代价更⼩的重绘。
• 重绘』不⼀定会出现『重排』,『重排』必然会出现『重绘』。
12.如何触发重排和重绘?
任何改变⽤来构建渲染树的信息都会导致⼀次重排或重绘:
• 添加、删除、更新DOM节点 • 通过display: none隐藏⼀个DOM节点-触发重排和重绘
• 通过visibility: hidden隐藏⼀个DOM节点-只触发重绘,因为没有⼏何变化
• 移动或者给⻚⾯中的DOM节点添加动画
• 添加⼀个样式表,调整样式属性
• ⽤⼾⾏为,例如调整窗⼝⼤⼩,改变字号,或者滚动。
13.如何避免重绘或者重排?
1. 集中改变样式 ,不要⼀条⼀条地修改 DOM 的样式。
2. 不要把 DOM 结点的属性值放在循环⾥当成循环⾥的变量。
3. 为动画的 HTML 元件使⽤ fixed 或 absoult 的 position ,那么修改他们的 CSS 是不会 reflow 的。
4. 不使⽤ table 布局。因为可能很⼩的⼀个⼩改动会造成整个 table 的重新布局。
5. 尽量只修改 position:absolute 或 fixed 元素,对其他元素影响不⼤
6. 动画开始 GPU 加速, translate 使⽤ 3D 变化
7. 提升为合成层
8. 将元素提升为合成层有以下优点: ◦ 合成层的位图,会交由 GPU 合成,⽐ CPU 处理要快 ◦ 当需要 repaint 时,只需要 repaint 本⾝,不会影响到其他的层 ◦ 对于 transform 和 opacity 效果,不会触发 layout 和 paint
9. 提升合成层的最好⽅式是使⽤ CSS 的 will-change 属性:#target { will-change: transform;}
14.介绍下304过程
• a. 浏览器请求资源时⾸先命中资源的Expires 和 Cache-Control,Expires 受限于本地时间,如果修 改了本地时间,可能会造成缓存失效,可以通过Cache-control: max-age指定最⼤⽣命周期,状态 仍然返回200,但不会请求数据,在浏览器中能明显看到from cache字样。
• b. 强缓存失效,进⼊协商缓存阶段,⾸先验证ETagETag可以保证每⼀个资源是唯⼀的,资源变化 都会导致ETag变化。服务器根据客⼾端上送的If-None-Match值来判断是否命中缓存。
• c. 协商缓存Last-Modify/If-Modify-Since阶段,客⼾端第⼀次请求资源时,服务端返回的header中 会加上Last-Modify,Last-modify是⼀个时间标识该资源的最后修改时间。再次请求该资源时, request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If- Modify-Since后,根据资源的最后修改时间判断是否命中缓存
15.说下进程、线程和协程
* 进程是⼀个具有⼀定独⽴功能的程序在⼀个数据集上的⼀次动态执⾏的过程, 是操作系统进⾏资源分 配和调度的⼀个独⽴单位 ,是应⽤程序运⾏的载体。进程是⼀种抽象的概念,从来没有统⼀的标准定义。
* 线程是程序执⾏中⼀个单⼀的顺序控制流程,是 程序执⾏流的最⼩单元 ,是处理器调度和分派的基本 单位。⼀个进程可以有⼀个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空 间)。⼀个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。⽽进程由内存空间(代码、数 据、进程空间、打开的⽂件)和⼀个或多个线程组成。
* 协程,英⽂Coroutines,是⼀种 基于线程之上,但⼜⽐线程更加轻量级的存在 ,这种由程序员⾃⼰写 程序来管理的轻量级线程叫做『⽤⼾空间线程』,具有对内核来说不可⻅的特性。
* 进程和线程的区别与联系 【区别】:
调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位;
并发性:不仅进程之间可以并发执⾏,同⼀个进程的多个线程之间也可并发执⾏;
拥有资源:进程是拥有资源的⼀个独⽴单位,线程不拥有系统资源,但可以访问⾪属于进程的资源。
系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显⼤于创建 或撤消线程时的开销。但是进程有独⽴的地址空间,⼀个进程崩溃后,在保护模式下不会对其它进程 产⽣影响,⽽线程只是⼀个进程中的不同执⾏路径。线程有⾃⼰的堆栈和局部变量,但线程之间没有 单独的地址空间,⼀个进程死掉就等于所有的线程死掉,所以多进程的程序要⽐多线程的程序健壮, 但在进程切换时,耗费资源较⼤,效率要差⼀些。
*【联系】: ⼀个线程只能属于⼀个进程,⽽⼀个进程可以有多个线程,但⾄少有⼀个线程;
资源分配给进程,同⼀进程的所有线程共享该进程的所有资源;
处理机分给线程,即真正在处理机上运⾏的是线程;
线程在执⾏过程中,需要协作同步。不同进程的线程间要利⽤消息通信的办法实现同步。