面试关于网络的那些事

1、TCP/UDP

(1)TCP----------传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。其实它和上面所说的电话协议差不多,只不过电话的协议是服务于电话通信,而tcp是服务于网络通讯的一种协议
(2)三次握手

SYN:synchronous 建立联机
ACK:acknowledgement 确认
SYN_SENT:请求连接
SYN_RECV:服务端被动打开后,接收到了客户端的SYN并且发送了ACK时的状态。再进一步接收到客户端的ACK就进入ESTABLISHED状态。

tcp在握手过程中并不携带数据,(就像你打电话给酒店订房时,在确认对方是酒店客服人员之前,你也不会马上把身份证号码报给他吧?),而是在三次握手完成之后,才会进行数据传送。
(3)UDP--------用户数据报协议
使用udp协议经常通信并不需要建立连接,它只是负责把数据尽可能快的发送出去,简单粗暴,并且不可靠,而在接收端,UDP把每个消息断放入队列中,接收端程序从队列中读取数据。虽然UDP不可靠,但是它的传输速度快,效率高,在一些对数据准确性要求不高的场景,UDP就变得很有用了,比如qq语音、qq视频。

2、套接字socket(无论是TCP还是UDP要产生作用,都需要有实际的行为去执行才能体现协议的作用,嵌套字 ,是一组实现TCP/UDP通信的接口API,也就是说无论TCP还是UDP,通过对scoket的编程,都可以实现TCP/UCP通信,作为一个通信链的句柄,它包含网络通信必备的5种信息:)
  1. 连接使用的协议
  2. 本地主机的IP地址
  3. 本地进程的协议端口
  4. 远地主机的IP地址
  5. 远地进程的协议端口

通信双方中的一方(暂称:客户端)通过scoket(嵌套字)对另一方(暂称:服务端)发起连接请求,服务端在网络上监听请求,当收到客户端发来的请求之后,根据socket里携带的信息,定位到客户端,就相应请求,把socket描述发给客户端,双方确认之后连接就建立了。

3、HTTP协议-----------HTTP协议是应用层协议,基于TCP协议,用于包装数据,程序使用它进行通信,可以简单高效的处理通信中数据的传输和识别处理
4、URL--------网络上用来标识具体资源的一个地址,包含了用户查找该资源的信息,HTTP使用它来传输数据和建立连接
  • 协议
  • 服务器地址(域名或IP+端口)
  • 路径
  • 文件名
4、DNS(域名服务器)解析
  1. 浏览器先检查自身缓存中有没有被解析过的这个域名对应的ip地址,如果有,解析结束。同时域名被缓存的时间也可通过TTL属性来设置。
  2. 如果浏览器缓存中没有(专业点叫还没命中),浏览器会检查操作系统缓存中有没有对应的已解析过的结果。而操作系统也有一个域名解析的过程。在windows中可通过c盘里一个叫hosts的文件来设置,如果你在这里指定了一个域名对应的ip地址,那浏览器会首先使用这个ip地址。

但是这种操作系统级别的域名解析规程也被很多黑客利用,通过修改你的hosts文件里的内容把特定的域名解析到他指定的ip地址上,造成所谓的域名劫持。所以在windows7中将hosts文件设置成了readonly,防止被恶意篡改。

  1. 如果至此还没有命中域名,才会真正的请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。
  2. 如果LDNS仍然没有命中,就直接跳到Root Server 域名服务器请求解析
  3. 根域名服务器返回给LDNS一个所查询域的主域名服务器地址
  4. 此时LDNS再发送请求给上一步返回的gTLD
  5. 接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器
  6. Name Server根据映射关系表找到目标ip,返回给LDNS
  7. LDNS缓存这个域名和对应的ip
  8. LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束

(2)迭代查询与递归查询

所谓 递归查询过程 就是 “查询的递交者” 更替, 而 迭代查询过程 则是 “查询的递交者”不变。举个例子来说,你想知道某个一起上法律课的女孩的电话,并且你偷偷拍了她的照片,回到寝室告诉一个很仗义的哥们儿,这个哥们儿二话没说,拍着胸脯告诉你,甭急,我替你查(此处完成了一次递归查询,即,问询者的角色更替)。然后他拿着照片问了学院大四学长,学长告诉他,这姑娘是xx系的;然后这哥们儿马不停蹄又问了xx系的办公室主任助理同学,助理同学说是xx系yy班的,然后很仗义的哥们儿去xx系yy班的班长那里取到了该女孩儿电话。(此处完成若干次迭代查询,即,问询者角色不变,但反复更替问询对象)最后,他把号码交到了你手里。完成整个查询过程。
在这里插入图片描述

一、递归查询:主机向本地域名服务器的查询一般都是采用递归查询。所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其它根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的IP地址。
简单说 就是说我们请求的地址
必须返回一个准确的ip地址,没有就向别的地址查询,然后返回给我们一个准确的ip地址。我们的本地服务器就是递归服务器。
二、迭代查询:本地域名服务器向根域名服务器的查询的迭代查询。迭代查询的特点:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地服务器进行后续的查询。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器,让本地域名服务器再向顶级域名服务器查询。顶级域名服务器在收到本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个权限域名服务器进行查询。最后,知道了所要解析的IP地址或报错,然后把这个结果返回给发起查询的主机。
这里由各级服务器进行的就是迭代查询,自身不返回ip,而是返回给下一级的DNS服务器地址。

5、页面渲染过程

(1)过程

  1. DNS 查询
  2. TCP 连接
  3. HTTP 请求即响应
  4. 服务器响应
  5. 客户端渲染
    (1)处理 HTML 标记并构建 DOM 树。
    (2)处理 CSS 标记并构建 CSSOM 树。
    (3)将 DOM 与 CSSOM 合并成一个渲染树。
    (4)根据渲染树来布局,以计算每个节点的几何信息。
    (5)根据渲染树来布局,以计算每个节点的几何信息。

(2)阻塞渲染
谈论资源的阻塞时,我们要清楚,现代浏览器总是并行加载资源。例如,当 HTML 解析器(HTML Parser)被脚本阻塞时,解析器虽然会停止构建 DOM,但仍会识别该脚本后面的资源,并进行预加载。同时,由于下面两点:默认情况下,CSS 被视为阻塞渲染的资源,这意味着浏览器将不会渲染任何已处理的内容,直至 CSSOM 构建完毕。JavaScript 不仅可以读取和修改 DOM 属性,还可以读取和修改 CSSOM 属性。存在阻塞的 CSS 资源时,浏览器会延迟 JavaScript 的执行和 DOM 构建。另外:当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行。JavaScript 可以查询和修改 DOM 与 CSSOM。CSSOM 构建时,JavaScript 执行将暂停,直至 CSSOM 就绪。所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。JavaScript 应尽量少影响 DOM 的构建。

(2-1)css

<style> p { color: red; }</style>
<link rel="stylesheet" href="index.css">

这样的 link 标签(无论是否 inline)会被视为阻塞渲染的资源,浏览器会优先处理这些 CSS 资源,直至 CSSOM 构建完毕。渲染树(Render-Tree)的关键渲染路径中,要求同时具有 DOM 和 CSSOM,之后才会构建渲染树。即,HTML 和 CSS 都是阻塞渲染的资源。HTML 显然是必需的,因为包括我们希望显示的文本在内的内容,都在 DOM 中存放,那么可以从 CSS 上想办法。最容易想到的当然是精简 CSS 并尽快提供它。除此之外,还可以用媒体类型(media type)和媒体查询(media query)来解除对渲染的阻塞。

<link href="index.css" rel="stylesheet">
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 30em) and (orientation: landscape)">

第一个资源会加载并阻塞。
第二个资源设置了媒体类型,会加载但不会阻塞,print 声明只在打印网页时使用。
第三个资源提供了媒体查询,会在符合条件时阻塞渲染。

(2-2)JS
实际工程中,我们常常将资源放到文档底部。
(2-3)改变阻塞模式:defer 与 async(async 与 defer 属性对于 inline-script 都是无效的)

  • defer
    defer 属性表示延迟执行引入的 JavaScript,即这段 JavaScript 加载时 HTML 并未停止解析,这两个过程是并行的。整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer-script 加载的 JavaScript 代码,然后触发 DOMContentLoaded 事件。defer 不会改变 script 中代码的执行顺序,示例代码会按照 1、2、3 的顺序执行。所以,defer 与相比普通 script,有两点区别:载入 JavaScript 文件时不阻塞 HTML 的解析,执行阶段被放到 HTML 标签解析完成之后。
  • async
    async 属性表示异步执行引入的 JavaScript,与 defer 的区别在于,如果已经加载好,就会开始执行——无论此刻是 HTML 解析阶段还是 DOMContentLoaded 触发之后。需要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发之前或之后执行,但一定在 load 触发之前执行。从上一段也能推出,多个 async-script 的执行顺序是不确定的。值得注意的是,向 document 动态添加 script 标签时,async 属性默认是 true,
6、页面性能优化

(1)对于css

  • 优化选择器路径:健全的css选择器固然是能让开发看起来更清晰,然后对于css的解析来说却是个很大的性能问题,因此相比于 .a .b .c{} ,更倾向于大家写.c{}。
    压缩文件:尽可能的压缩你的css文件大小,减少资源下载的负担。
    选择器合并:把有共同的属性内容的一系列选择器组合到一起,能压缩空间和资源开销
    精准样式:尽可能减少不必要的属性设置,比如你只要设置{padding-left:10px}的值,那就避免{padding:0 0 0 10px}这样的写法
    雪碧图:在合理的地方把一些小的图标合并到一张图中,这样所有的图片只需要一次请求,然后通过定位的方式获取相应的图标,这样能避免一个图标一次请求的资源浪费。
    避免通配符:.a .b {} 像这样的选择器,根据从右到左的解析顺序在解析过程中遇到通配符()回去遍历整个dom的,这样性能问题就大大的了。
    少用Float:Float在渲染时计算量比较大,尽量减少使用。
    0值去单位:对于为0的值,尽量不要加单位,增加兼容性

(2)对于JS
尽可能把script标签放到body之后,避免页面需要等待js执行完成之后dom才能继续执行,最大程度保证页面尽快的展示出来。
尽可能合并script代码,
css能干的事情,尽量不要用JavaScript来干。毕竟JavaScript的解析执行过于直接和粗暴,而css效率更高。
尽可能压缩的js文件,减少资源下载的负担
尽可能避免在js中逐条操作dom样式,尽可能预定义好css样式,然后通过改变样式名来修改dom样式,这样集中式的操作能减少reflow或repaint的次数。
尽可能少的在js中创建dom,而是预先埋到HTML中用display:none来隐藏,在js中按需调用,减少js对dom的暴力操作。
(3)对于HTML
避免再HTML中直接写css代码。
使用Viewport加速页面的渲染。
使用语义化标签,减少css的代码,增加可读性和SEO。
减少标签的使用,dom解析是一个大量遍历的过程,减少无必要的标签,能降低遍历的次数。
避免src、href等的值为空。
减少dns查询的次数。

7、http与websocket的区别
(1)http协议是一种单向的网络协议,在建立连接后,它只允许Browser/UA(UserAgent)向WebServer发出请求资源后,WebServer才能返回相应的数据。而WebServer不能主动的推送数据给Browser/UA
(2)Browser/UA发送Get请求到Web服务器,这时Web服务器可以做两件事情,第一,如果服务器端有新的数据需要传送,就立即把数据发回给Browser/UA,Browser/UA收到数据后,立即再发送Get请求给Web Server;第二,如果服务器端没有新的数据需要发送,这里与Polling方法不同的是,服务器不是立即发送回应给Browser/UA,而是把这个请求保持住,等待有新的数据到来时,再来响应这个请求;当然了,如果服务器的数据长期没有更新,一段时间后,这个Get请求就会超时,Browser/UA收到超时消息后,再立即发送一个新的Get请求给服务器。然后依次循环这个过程。
(3)

  • WebSocket是HTML5中的协议,支持持久连接;而Http协议不支持持久连接。

  • 首先HTMl5指的是一系列新的API,或者说新规范,新技术。WebSocket是HTML5中新协议、新API.跟HTTP协议基本没有关系。

  • Http协议本身只有1.0和1.1,也就是所谓的Keep-alive,把多个Http请求合并为一个。
    (4)首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说

HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了。

在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。

(5)websocket的作用

1)ajax轮询

ajax轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

(2)long poll(长轮询)

long poll 其实原理跟 ajax轮询
差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端(对于PHP有最大执行时间,建议没消息,执行到一定时间也返回)。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输 identity
info (鉴别信息),来告诉服务端你是谁。然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性。

何为被动性呢,其实就是,服务端不能主动联系客户端,只能有客户端发起。从上面很容易看出来,不管怎么样,上面这两种都是非常消耗资源的。

ajax轮询 需要服务器有很快的处理速度和资源。(速度)long poll 需要有很高的并发,也就是说同时接待客户的能力。(场地大小)

(3)WebSocket

Websocket解决了HTTP的这几个难题。首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。解决了上面同步有延迟的问题。

解决服务器上消耗资源的问题:其实我们所用的程序是要经过两层代理的,即HTTP协议在Nginx等服务器的解析下,然后再传送给相应的Handler(php等)来处理。简单地说,我们有一个非常快速的
接线员(Nginx) ,他负责把问题转交给相应的 客服(Handler)
。Websocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员在统一转交给客户。

由于Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析HTTP协议,还要查看identity
info的信息。

目前唯一的问题是:不兼容低版本的IE

发布了57 篇原创文章 · 获赞 22 · 访问量 7270

猜你喜欢

转载自blog.csdn.net/qq_39897978/article/details/102843150