前言:
2020年是多灾多难的一年,疫情持续至今,到目前,全世界的经济都受到不同程序的影响,各大公司裁员,在这样一片严峻的形式下,找工作更是难上加难。
企业的门槛提高,第一,对于学历的要求,必须学信网可查的统招本科;第二,对于技术的掌握程序,更多的是底层原理,项目经验,等等。
下面是面试几周以来,总结的一些面试中常被问到的题目,还有吸取的一些前辈们分享的贴子,全部系统的罗列出来,希望能够帮到正在面试的人。
1. 在浏览器上输入URL之后的流程
- 第一阶段 - 获取资源阶段
1.读取缓存:搜索自身的 DNS 缓存。(如果 DNS 缓存中找到IP 地址就跳过了接下来查找 IP 地址步骤,直接访问该 IP 地址。)
2.DNS 解析:将域名解析成 IP 地址
3.TCP 连接:TCP 三次握手
客户端:服务端你在么?
服务端:客户端我在,你要连接我么?
客户端:是的服务端,我要链接。
连接打通,可以开始请求来
为什么需要三次握手?可能有以下两种情况
(1)客户端发出第一次挥手后就失效了,那么服务端接收后就产生TCP链接是无用的,需要第三次挥手确认
(2)服务端发送的数据表,因为网络情况丢失了,客户端超时后重新发起了链接,那么上次的TCP,链接服务端因为没有接受到回应而一直开着,造成了资源浪费
4.发送 HTTP 请求
5.服务器处理请求并返回 HTTP 报文
6.浏览器解析渲染页面
7.断开连接:TCP 四次挥手
(1)客户端发送一个带有FIN标志的数据包给服务端,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态。
(2)服务端收到后,发送一个ACK数据包给客户端,自身进入CLOSE_WAIT状态。
(3)服务端发送一个FIN,用来关闭服务端到客户端的数据传送,客户端进入LAST_ACK状态。
(4)客户端收到FIN后,进入TIME_WAIT状态,接着发送一个ACK给 服务端,服务端进入CLOSED状态,通信结束。
为什么中间服务端发送了两次?因为此时服务端可能还有数据没有发送完,所以并不会马上关闭socket,而是等待数据发送后再发送FIN标志。
- 第二阶段 - 页面渲染阶段
1.根据 HTML 解析出 DOM 树
2.根据 CSS 解析生成 CSS 规则树
3.结合 DOM 树和 CSS 规则树,生成渲染树
4.根据渲染树计算每一个节点的信息
5.根据计算好的信息绘制页面
2. HTTP、HTTPS、HTTP2.0
HTTP: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和响应的标准。或者说是计算机在两端之间传输文字、图片、音频、视频等超文本数据的约定和规范。
HTTP特性:
1.HTTP 是无连接无状态的
2.HTTP 一般构建于 TCP/IP 协议之上,默认端口号是 80
3.HTTP 可以分为两个部分,即请求和响应。HTTP请求:
1.HTTP 定义了在与服务器交互的不同方式,最常用的方法有 4 种,分别是 GET,POST,PUT, DELETE。URL 全称为资源描述符,可以这么认为:一个 URL 地址
2.对应着一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE
就对应着对这个资源的查询,修改,增添,删除4个操作。
3.HTTP 请求由 3 个部分构成,分别是:状态行,请求头(Request Header),请求正文。
4.HTTP 响应由 3 个部分构成,分别是:状态行,响应头(Response Header),响应正文。
5.HTTP 响应中包含一个状态码,用来表示服务器对客户端响应的结果。HTTP状态码
200 OK 客户端请求成功。
301 Moved Permanently 请求永久重定向。
302 Moved Temporarily 请求临时重定向。
304 Not Modified 文件未修改,可以直接使用缓存的文件。
400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized 请求未经授权,无法访问。
403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因。
404 Not Found 请求的资源不存在,比如输入了错误的URL。
500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。
503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。
HTTS: 是以安全为目标的HTTP通道,即HTTP下加入SSL层,SSL加密是在传输层实现的。http是明文传输,https则是具有安全性的ssl加密传输协议(证书中的公钥和服务器的私钥)
HTTS优点:
1.使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器。
2.比HTTP协议更安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性 。
3.HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。HTTS缺点:
1.相同网络环境下,HTTPS 协议会使页面的加载时间延长近 50%,增加 10%到 20%的耗电。此外,HTTPS 协议还会影响缓存,增加数据开销和功耗。
2.HTTPS 协议的安全是有范围的,在黑客攻击、拒绝服务攻击和服务器劫持等方面几乎起不到什么作用。
3.SSL证书需要钱,功能越大费用越高。
HTTP2.0: 超文本传输协议 2.0,是下一代HTTP协议。在开放互联网上HTTP2.0将只用于https网址,而 http网址将继续使用HTTP/1。
- HTTP2.0优点:
1.提升访问速度
2.允许多路复用:多路复用允许同时通过单一的HTTP/2连接发送多重请求-响应信息。改善了:在http1.1中,浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制(连接数量),超过限制会被阻塞。(使用请求ID对应响应)
3.二进制分帧:HTTP2.0会将所有的传输信息分割为更小的信息或者帧,并对他们进行二进制编码
4.首部压缩: HPACK(HTTP2头部压缩算法)压缩格式对传输的header进行编码。并在两端建立索引表,进行缓存。
5.服务器端推送
3. DNS和CDN
什么是DNS
1.域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域名与 IP 地址的相互转换,以及控制因特网的电子邮件的发送。为了保证高可用、高并发和分布式,它设计成了树状的层次结构。由根DNS服务器、顶级域 DNS 服务器和权威 DNS 服务器组成。
2.解析顺序是首先从浏览器缓存、操作系统缓存以及本地 DNS 缓存 (/etc/hosts) 逐级查找,然后从本地 DNS 服务器、根 DNS、顶级 DNS 以及权威 DNS层层递归查询。
3.还可以基于域名在内网、外网进行负载均衡。
4.不过传统的 DNS 有很多问题(解析慢、更新不及时),HTTPDNS 通过客户端 SDK 和服务端配合,直接通过 HTTP 调用解析 DNS 的方式,可以绕过传统 DNS 这些缺点,实现智能调度。
5.智能DNS可以让用户访问同线路最近的服务器。什么是CDN
1.CDN的全称是Content Delivery Network,即内容分发网络(把网站产生的内容分发到各个用户请求的网络里去,具有分布式网络的特点)。
2.CDN不是整站的copy,只是内容的缓存(即可以动态调整和过期控制)。
3.优点:使用户可以就近取得所需内容,提高用户访问网站的响应速度。CDN加速原理
1.缓存 (CDN缓存可以加快访问速度,也可以减少服务器的压力)
2.多个节点
3.多线路网络支持(可以跨网访问,如跨电信、联通和移动)CDN加速的适用范围
1.静态和更新频率地的网站更加适用
2.数据流量大的产品更适用(如视频网站,直播网站)
3.带宽价格便宜(1M贷款大约几块钱RMB)
4. UDP 和 TCP
UDP协议全称是用户数据报协议
1.面向无连接:首先 UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。
2.有单播,多播,广播的功能
3.不可靠性:这种不可靠性体现在无连接上
4.头部开销小,传输数据报文时是很高效的TCP协议全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议
1.面向连接:发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”
2.仅支持单播传输:只能进行点对点的数据传输,不支持多播和广播传输方式
3.可靠传输:判断丢包,误码靠的是TCP的段编号以及确认号
4.提供拥塞控制:当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞
4. 跨域
同源策略
因为浏览器出于安全考虑,有同源策略。同源策略是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。同源策略限制以下几种行为:
1.Cookie、LocalStorage 和 IndexDB 无法读取
2.DOM 和 Js对象无法获得
3.AJAX 请求不能发送跨域处理方案
1.Jsonp:网页通过动态添加一个 script 元素,向服务器请求数据; 服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。但只支持get请求。
2.设置跨域资源共享(CORS),不过需要浏览器和服务器同时支持
3.document.domain: 此方案仅限主域相同,子域不同的跨域应用场景
4.webpack配置proxyTable设置开发环境跨域
5.nginx代理跨域
6.iframe跨域
7.postMessage:这种方式通常用于获取嵌入页面中的第三方页面数据。一个页面发送消息,另一个页面判断来源并接收消息
5. 事件循环机制
首先来了解下宏任务和微任务,异步任务分为task(宏任务,也可称为macroTask)和microtask(微任务,也叫jobs)两类。
Task:(宏任务)
1.setTimeout
2.setInterval
3.setImmediate (Node独有)
4.requestAnimationFrame (浏览器独有)
5.I/O
6.UI rendering (浏览器独有)
7.script标签MicroTask:(微任务)
1.process.nextTick (Node独有)
2.Promise
3.MutationObserver当满足执行条件时,task和microtask会被放入各自的队列中,等待放入执行线程执行,我们把这两个队列称为Task Queue(也叫Macrotask Queue)和Microtask Queue。
基本流程
1.从任务队列task queue选择中最先进入的任务执行,如果队列为空,则执行microtask queue。
2.检查该task是否注册了microtask queue,如果有,则按注册顺序依次执行microtask。如果没有则继续下一步。
3.一些其他操作,例如界面渲染。
4.重复以上步骤。
6. GC垃圾回收机制
垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。浏览器会在浏览器渲染的空闲时间内清除内存。
在V8中,主要将内存分为新生代和老生代,新生代的对象为存活时间较短的对象,老生代中的对象为存活时间较长或常驻内存的对象。
栈内存的回收,栈内存在调用栈上下文切换后就会被回收。
堆内存的回收
1.新生代内存回收机制:新生代内存容量小,默认下,64位系统下仅有32M
2.晋升:如果新生代的变量经过复制依然依然存活时,那么就会被放入老生代内存中。晋升有两个条件:
(1)是否经历过新生代的回收
(2)To空间内存占比超过限制
3.老生代内存回收机制
(1)V8在老生代中主要采用Mark-Sweep和Mark-Compact相结合的方式进行垃圾回收。主要使用Mark-Sweep,在空间不足以对新生代中晋升过来的对象进行分配时才使用Mark-Compact。
(2)Mark-Sweep:在标记阶段遍历所有堆中的所有对象,并标记活着的对象,在清除阶段清除没有标记的对象。
(3)Mark-Compact:在Mark-Sweep的基础上演变而来,差别在于在标记死亡后,在整理过程中会将活着的对象往一端移动,移动后,直接清理掉边界外的内存,解决Mark-Sweep的内存碎片问题。
7. 缓存机制
浏览器会拷贝一份已经请求过的web资源在内存或硬盘中。当下一个请求到来的时候,如果是相同的URL,浏览器会根据缓存机制决定是直接使用副本响应访问请求还是向源服务器再次发起请求。
优点:
1.减少网络带宽消耗
2.降低服务器压力
3.减少网络延迟浏览器与服务器通信的方式为应答模式,即是:浏览器发起HTTP请求 – 服务器响应该请求。
浏览器的缓存分成强制缓存和协商缓存两种,浏览器再向服务器请求资源时,首先会判断是否命中强缓存,再判断是否命中协商缓存。
那么浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中。
强制缓存
1.不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致)
2.存在该缓存结果和缓存标识,但是结果已经失效,强制缓存失效,则使用协商缓存
3.存在该缓存结果和缓存标识,且该结果没有还没有失效,强制缓存生效,直接返回该结果那么强制缓存的缓存规则是什么?
当浏览器向服务器发送请求的时候,服务器会将缓存规则放入HTTP响应的报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是Expires
和Cache-Control
,其中Cache-Conctrol
的优先级比Expires
高。
如上图示:内存缓存(
from memory cache
),内存缓存具有两个特点,分别是快速读取和时效性如上图示:硬盘缓存(
from disk cache
),硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
1.协商缓存生效,返回304
2.协商缓存失败,返回200和请求结果
同样,协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的,控制协商缓存的字段分别有:Last-Modified / If-Modified-Since
和Etag / If-None-Match
,其中Etag / If-None-Match
的优先级比Last-Modified / If-Modified-Since
高。-
总结
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存,主要过程如下:
8. REST架构
REST即表述性状态传递,表述性状态转移是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。需要注意的是,REST是设计风格而不是标准。
原则:
1.C-S架构: 数据的存储在Server端,Client端只需使用就行。两端彻底分离。
2.无状态: 从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文。这表示你应该尽可能的避免使用session,由客户端自己标识会话状态。(例如使用token标识用户而不是session)
3.规范接口: restfulAPI - restfulAPI就是用URL定位资源,用HTTP描述操作
(1)get: 请求数据
(2)post: 提交数据
(3)put: restful,更新实体的全部属性
(4)patch: 更新实体的部分属性
(5)delete: restful,删除实体
4.可缓存: 响应中的数据隐式或显式标记为可缓存或不可缓存。它表示get请求响应头中应该表示有是否可缓存的头(Cache-Control)
9. 长连接和短连接
长连接:
1.所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持(不发生RST包和四次挥手)。
2.连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接(一个TCP连接通道多个读写通信);
3.这就要求长连接在没有数据通信时,定时发送数据包(心跳),以维持连接状态;
4.TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务器端检测到这种半开放的连接。如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一:
1.客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。
2.客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
3.客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
4.客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。短连接:
1.短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接(管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段);
2.连接→数据传输→关闭连接;
TCP短连接:数据发送完成后就关闭连接,下次发送数据时重新建立连接,适用于连接频率很低的情况(比如网页访问)。
TCP长连接:数据发送完后,并不关闭连接,通过相互发送校验包保持连接,再次发送数据时不用再重新建立连接,适用于连接频率很高的情况。
- 应用场景:
1.长连接多用于操作频繁(读写),点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
2.而像WEB网站的http服务一般都用短链接(http1.0只支持短连接,1.1keep alive 带时间,操作次数限制的长连接),因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好;
3.在长连接中一般是没有条件能够判断读写什么时候结束,所以必须要加长度报文头。读函数先是读取报文头的长度,再根据这个长度去读相应长度的报文。