0129面试题——TCP数量限制、UDP/TCP首部格式、HTTP缓存、CDN原理、从输入URL到呈现页面

132 阅读11分钟

计算机网络

  1. TCP的应用场景,UDP的应用场景

    • TCP:适用于要求可靠传输的应用,例如文件传输

    • UDP:适用于实时应用(IP电话、视频会议、直播等)

  2. 如何解决浏览器对同一域名的http请求数量的限制

    • 使用HTTP2,仅需建立一个TCP连接,多个请求和响应全部看成帧交替传输

    • 对同一台服务器绑定多个域名,前端请求时,分别使用不同的域名,则可以解决浏览器对TCP并发最多6-8个的限制

  3. 三次握手的过程可以携带数据吗

    • 第一次握手,发出请求连接SYN包,客户端并未建立TCP连接

    • 服务器收到SYN包后,发送ACK + SYN包,表示同意建立,并请求建立从服务器到客户端的连接,这时,服务器端对TCP连接建立相应资源

    • 当客户端收到服务器响应的ACK + SYN包后,建立与TCP相关的资源,此时客户端、服务器端都建立了TCP连接相应资源,因此第三次握手发送ACK包的时候,可以携带数据

  4. UDP首部格式

    • UDP首部

    • 源端口号:表示发送端端口号,字段长16位。该字段是可选项,有时可能会设置源端口号为全0。表示不需要回复

    • 目标端口号:表示接收端端口,字段长度16位。

    • 包长度:该字段保存了UDP首部的长度跟数据的长度之和。单位为字节。

    • 校验和:校验和是为了提供可靠的UDP首部和数据而设计的。

  5. TCP首部格式

    • TCP头部

    • 源端口/目的端口:TCP主要是负责两个应用之间的通信,当数据发送到目的计算机之后,还要清楚需要交付给哪个应用,因此需要端口号,来指明是哪两个进程之间在通信

    • 序号:表示该报文段所发送数据的第一个字节的编号,由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从 0 开始

    • 确认号:表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。

    • 数据偏移:指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远,即TCP首部的长度。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移或TCP首部最大60字节

    • URG:表示本报文段中发送的数据是否包含紧急数据。后面的紧急指针字段(urgent pointer)只有当URG=1时才有效

    • ACK:表示是否前面确认号字段是否有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,ACK必须为1,带ACK标志的TCP报文段称为确认报文段

    • PSH:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中

    • RST:如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带RST标志的TCP报文段称为复位报文段

    • SYN:在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接,同时请求建立链接。带SYN标志的TCP报文段称为同步报文段

    • FIN:表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果FIN=1,即告诉对方:“我的数据已经发送完毕,你可以释放连接了”,带FIN标志的TCP报文段称为结束报文段

    • 窗口大小:表示现在允许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量,达到此值,需要ACK确认后才能再继续传送后面数据。

    • 校验和:提供额外的可靠性,验证数据是否出错

    • 紧急指针:标记紧急数据在数据字段中的位置

    • 选项部分:其最大长度可根据TCP首部长度进行推算。TCP首部长度用4位表示,选项部分最长为:(2^4-1)*4-20=40字节

      • 最大报文段长度:Maxium Segment Size,MSS,通常1460字节,指明自己期望对方发送TCP报文段时数据字段的长度。

      • 窗口扩大:Window Scale,随着时延和带宽比较大的通信产生,需要更大的窗口来满足性能和吞吐率

      • 时间戳: Timestamps,可以用来计算RTT(往返时间),发送方发送TCP报文时,把当前的时间值放入时间戳字段,接收方收到后发送确认报文时,把这个时间戳字段的值复制到确认报文中,当发送方收到确认报文后即可计算出RTT。

    • 资料:TCP报文头部

  6. TCP是如何保证传输可靠的

    • TCP 三次挥手,四次挥手,充分确保连接成功建立和成功断开

    • 校验和:通过对TCP包头部的校验和进行判断,如果传输错误则会被丢弃,并由网际控制报文协议ICMP发出错误信息

    • 超时重传:当发送方没有收到接收方的ACK确认数据时,就默认数据包丢失,将重新发送

    • 流量控制:当网络状态不好时,调节发送速率,避免路由缓存队列已满时丢弃数据包

  7. http的缓存机制

    • 只有 GET 请求获取的资源才能被缓存

    • Cache-Control

      • public:资源可被任何中间节点(客户端和代理服务器)缓存

      • private:只有客户端可以缓存,Cache-Control的默认取值

      • max-age=< seconds >:表示缓存内容将在xxx秒后失效

      • s-maxage=< seconds >:同max-age作用一样,只在代理服务器中生效(比如CDN缓存),s-maxage优先级高于max-age。设置了 s-maxage,没设置 public,代理服务器也可以缓存这个资源(因为s-maxage就只是给代理服务器使用的,而代理服务器要想缓存资源,就必须是public资源,因此设置了s-maxage,就默认public)

      • no-cache:可以缓存,但每次都应该去服务器验证缓存是否可用,进入协商缓存阶段。不使用 Cache-Control 的缓存控制方式做前置验证,而是使用 Etag 或者Last-Modified字段来控制缓存。相当于max-age:0, must-revalidate

      • no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

      • must-revalidate:可缓存但必须再向源服务器进确认

      • proxy-revalidate:要求中间缓存服务器对缓存的响应有效性再进行确认

    • 强缓存

      • 最初时,通过服务器返回的expires来进行判断,它是一个时间戳,表示缓存的过期时间。只要在这个时间以前,浏览器都是直接读取缓存而不再向服务器请求资源

      • 而之后,发现expires存在不足,比如客户端时间跟服务器时间不一致,那么缓存的过期时间就无法确定。因此现在使用Cache-Control的max-age来设置过期时间。但是为了向下兼容,仍然保留expires的用法

      • Cache-Control中max-age的值是一个相对时间,比如:Cache-Control: max-age=30, 返回头中的 Date 表示消息发送的时间,表示当前资源在 Date ~ Date +30s 这段时间里都是有效的。30秒内再次访问该资源,均使用本地的缓存,不再向服务器发起请求。

      • 并且 Cache-Control 优先级高于expires

    • 协商缓存

      • 通过 Cache-Control 设置为 no-cache开启,表示每次都应该去服务器验证缓存是否可用。

      • 如果 expires 或者 max-age到期,也会向服务器验证缓存是否可用,同样相当于协商缓存

      • 服务器响应头包含 Etag 、Last-Modified,分别表示文件哈希、最后修改时间

      • 客户端请求时,在请求头中带上 If-Not-Match(Etag)、If-Modified-Since(Last-Modified)

      • 如果服务器判断缓存仍然可用,就不会返回任何资源,状态码304,表示协商缓存可用

  8. 如何控制http缓存

    • 较好的使用http缓存机制,是能够达到减少请求,更多地使用本地的资源,给用户更好的体验的同时,也减轻服务器压力。所以最佳实践就应该是尽可能命中强缓存,同时能在更新版本的时候让客户端的缓存失效

    • 目前的策略是,HTML:使用协商缓存,CSS、JS、图片:使用强缓存,文件命名带上hash值。

    • 原因是,当页面更新,HTML是协商缓存,因此肯定可以拿到最新的页面。而在CSS、JS、图片打包时,因为文件名加上了hash值,如果文件被修改过,请求的链接将是不一样的,相当于第一次请求,会重新从服务器拉取最新资源

    • 设置强缓存:

    res.setHeader('Cache-Control', 'public, max-age=xxx');
    
    • 设置协商缓存
    res.setHeader('Cache-Control', 'public, max-age=0');	// 强缓存过期,则走协商缓存,或者直接设置成 public, no-cache
    res.setHeader('Last-Modified', xxx);
    res.setHeader('ETag', xxx);
    
  9. HTTP的请求构成

    • 起始行
      • 请求方法,如GET、POST
      • 请求目标:url
      • http协议版本号
    • header
      • request headers
      • general headers
      • entity headers
    • body:请求体
  10. 什么是CDN,基本工作原理是什么

    • CDN即内容分发网络,能够将源站内容智能缓存到全球各节点服务器上,即方便用户就近获取内容,又分担了源站压力

    • 相关术语:

      • A记录:从域名到 IP 地址的映射记录
      • CNAME记录:从域名到域名的映射记录
      • NS记录:指定该域名应该由哪一台 DNS 服务器进行解析。
    • 接入流程:

      • 假设工作服务器域名为 www.tt.com
      • 到某域名供应商申请一个加速域名,js.tt.com
      • 到CDN平台,如阿里云CDN,添加加速域名 js.tt.com,同时设置其源站域名为 www.tt.com
      • 将阿里云CDN分配的js.tt.com.ali.com配置给js.tt.com的CNAME记录
    • CDN 系统架构

      • CDN系统主要分为边缘层和中心层
      • 边缘层分布在 CDN 网络的边缘位置,给用户提供就近访问服务。
      • 中心层则负责完成资源同步和运营管理等功能。中心层保存了加速域名的相关配置信息,比如源站域名,也缓存了加速域名下的各种资源。
      • 在边缘层节点未命中缓存时,需要向中心层节点发起请求;而中心层节点未能命中缓存时,需要查找对应的源站域名,并向该源站域名发起请求。然后再逐层返回并缓存用户请求的资源。
    • 用户 A 首次访问流程

      • x.x.x.x 指的是 与用户比较近的边缘层节点服务器,由CDN动态确定
    • 用户A第二次访问

      • 因为前一次已经对js.tt.com解析过了,存在了计算机中,因此这次直接去访问x.x.x.x,而上一次在x.x.x.x中进行了缓存,因此直接去从上面获取
    • 用户B第一次访问

      • 同样需要DNS解析,然后访问x.x.x.x,假设用户A跟B 相距较远,因此x.x.x.x并不代表同一台边缘层节点,这时B访问的边缘层节点没有缓存,所以需要从中心层获取缓存
    • 为什么访问js.tt.com.ali.com,就能获取边缘层服务器的ip

      • 首先访问 js.tt.com,由于配置了CNAME,因此解析的结果为 js.tt.com.ali.com
      • 而js.tt.com.ali.com 又配置了NS,将这个域名的解析权交给了CDN供应商自己配置的DNS服务器
      • 然后由这个DNS服务器去返回一个离用户较近的边缘层节点服务器ip
    • 资料:CDN 的工作原理介绍

  11. 从输入url到显示页面这个过程发生了什么