面试题篇-08-网络相关面试题

1. 请说一下网络四元组

四元组,简单理解就是在TCP 协议中,去确定一个客户端连接的组成要素,它包括源 IP 地址目标IP 地址源端口号目标端口号

正常情况下,我们对于网络通信的认识可能是这样(如图)。
在这里插入图片描述
服务端通过ServerSocket 建立一个对指定端口号的监听,比如 8080。 客户端通过目标ip 和端口就可以和服务端建立一个连接,然后进行数据传输。
但是我们知道的是,一个Server 端可以接收多个客户端的连接,比如像这种情况(如图)。
在这里插入图片描述
那,当多个客户端连接到服务端的时候,服务端需要去识别每一个连接。并且(如图),TCP 是全双工协议,也就是说数据允许在连接的两个方向上同时传输,因此这里的客户端,如果是反向通信,它又变成了服务端。
在这里插入图片描述
所以基于这两个原因,就引入了四元组的设计,也就是说,当一个客户端和服务端建立一个TCP 连接的时候,通过源 IP 地址、目标 IP 地址、源端口号、目标端口号来确定一个唯一的TCP 连接。因为服务器的 IP 和端口是不变的,只要客户端的 IP 和端口彼此不同就OK 了。

比如像这种情况(如图),同一个客户端主机上有三个连接连到 Server 端,那么这个时候源IP 相同,源端口号不同。此时建立的四元组就是(10.23.15.3,59461 , 192.168.8.135,8080)其中,源端口号是每次建立连接的时候系统自动分配的。
在这里插入图片描述

2. IO 和 NIO 有什么区别?

首先,I/O ,指的是IO 流, 它可以实现数据从磁盘中的读取以及写入。

  • 实际上,除了磁盘以外,内存、网络都可以作为 I/O 流的数据来源和目的地。在Java 里面,提供了字符流和字节流两种方式来实现数据流的操作。
  • 其次,当程序是面向网络进行数据的 IO 操作的时候,Java 里面提供了Socket 的方式来实现。
    通过这种方式可以实现数据的网络传输。

(如图)基于Socket 的IO 通信,它是属于阻塞式 IO,也就是说,在连接以及 IO 事件未就绪的情况下,当前的连接会处于阻塞等待的状态。
在这里插入图片描述
如果一旦某个连接处于阻塞状态,那么后续的连接都得等待。所以服务端能够处理的连接数量非常有限。

NIO,是JDK1.4 里面新增的一种 NEW IO 机制,相比于传统的IO,NIO 在效率上做了很大的优化,并且新增了几个核心组件。
Channel、Buffer、Selectors。
(如图)另外,还提供了非阻塞的特性,所以,对于网络 IO 来说,NIO 通常也称为 No-Block IO,非阻塞IO。
在这里插入图片描述

也就是说,通过 NIO 进行网络数据传输的时候,如果连接未就绪或者 IO 事件未就绪的情况下,服务端不会阻塞当前连接,而是继续去轮询后续的连接来处理。
所以在NIO 里面,服务端能够并行处理的链接数量更多。

因此,总的来说,IO 和NIO 的区别,站在网络IO 的视角来说,前者是阻塞IO,后者是非阻塞IO。

3. TCP 协议为什么要设计三次握手?

  • TCP 协议,是一种可靠的,基于字节流的,面向连接的传输层协议。
    • 可靠性体现在TCP 协议通信双方的数据传输是稳定的,即便是在网络不好的情况下,TCP 都能够保证数据传输到目标端,而这个可靠性是基于数据包确认机制来实现的。
    • TCP 通信双方的数据传输是通过字节流来实现传输的
    • 面向连接,是说数据传输之前,必须要建立一个连接,然后基于这个连接进行数据传输

因为TCP 是面向连接的协议,所以在进行数据通信之前,需要建立一个可靠的连接,TCP 采用了三次握手的方式来实现连接的建立。
所谓的三次握手,就是通信双方一共需要发送三次请求,才能确保这个连接的建立。

  • 客户端向服务端发送连接请求并携带同步序列号 SYN。
  • 服务端收到请求后,发送SYN 和ACK, 这里的SYN 表示服务端的同步序列号,ACK 表示对前面收到请求的一个确认,表示告诉客户端,我收到了你的请求。
  • 客户端收到服务端的请求后,再次发送ACK,这个ACK 是针对服务端连接的一个确认,表示告诉服务端,我收到了你的请求。
    在这里插入图片描述

之所以TCP 要设计三次握手,我认为有三个方面的原因:

  • TCP 是可靠性通信协议,所以TCP 协议的通信双方都必须要维护一个序列号,去标记已经发送出去的数据包,哪些是已经被对方签收的。而三次握手就是通信双方相互告知序列号的起始值,为了确保这个序列号被收到,所以双方都需要有一个确认的操作。
  • TCP 协议需要在一个不可靠的网络环境下实现可靠的数据传输,意味着通信双方必须要通过某种手段来实现一个可靠的数据传输通道,而三次通信是建立这样一个通道的最小值。当然还可以四次、五次,只是没必要浪费这个资源。
  • 防止历史的重复连接初始化造成的混乱问题,比如说在网络比较差的情况下,客户端连续多次发送建立连接的请求,假设只有两次握手,那么服务端只能选择接受或者拒绝这个连接请求,但是服务端不知道这次请求是不是之前因为网络堵塞而过期的请求,也就是说服务端不知道当前客户端的连接是有效还是无效。

4. Cookie 和Session 的区别

Cookie,它是客户端浏览器用来保存服务端数据的一种机制。

  • 当通过浏览器进行网页访问的时候,服务器可以把某一些状态数据以 key-value 的方式写入到Cookie 里面存储到客户端浏览器。
    然后客户端下一次再访问服务器的时候,就可以携带这些状态数据发送到服务器端,服务端可以根据Cookie 里面携带的内容来识别使用者。

Session 表示一个会话,它是属于服务器端的容器对象,默认情况下,针对每一个浏览器的请求。Servlet 容器都会分配一个 Session。

  • Session 本质上是一个 ConcurrentHashMap,可以存储当前会话产生的一些状态数据。
  • 我们都知道,Http 协议本身是一个无状态协议,也就是服务器并不知道客户端发送过来的多次请求是属于同一个用户。
  • 所以Session 是用来弥补Http 无状态的不足,简单来说,服务器端可以利用session来存储客户端在同一个会话里面的多次
    请求记录。基于服务端的session 存储机制,再结合客户端的Cookie 机制,就可以实现有状态的 Http 协议。

具体的工作原理是:

  • 客户端第一次访问服务端的时候,服务端会针对这次请求创建一个会话,并生成一个唯一的sessionId 来标注这个会话。
  • 然后服务端把这个sessionid 写入到客户端浏览器的cookie 里面,用来实现客户端状态的保存。
  • 在后续的请求里面,每次都会携带 sessionid,服务器端就可以根据这个 sessionid 来识别当前的会话状态。

在这里插入图片描述
所以,总的来看,Cookie 是客户端的存储机制,Session 是服务端的存储机制。

5. 什么是 IO 的多路复用机制?

IO 多路复用机制,核心思想是让单个线程去监视多个连接,一旦某个连接就绪,也就是触发了读/写事件。就通知应用程序,去获取这个就绪的连接进行读写操作。

  • 也就是在应用程序里面可以使用单个线程同时处理多个客户端连接,在对系统资源消耗较少的情况下提升服务端的链接处理数量。
    在这里插入图片描述

在IO 多路复用机制的实现原理中,客户端请求到服务端后,此时客户端在传输数据过程中(如图),为了避免Server 端在read 客户端数据过程中阻塞,服务端会把该请求注册到 Selector复路器上,服务端此时不需要等待,只需要启动一个线程,通过selector.select()阻塞轮询复路器上就绪的channel 即可,也就是说,如果某个客户端连接数据传输完成,那么select()方法会返回就绪的channel,然后执行相关的处理就可以了。

常见的IO 多路复用机制的实现方式有: select 、poll、epoll。
这些都是Linux 系统提供的IO 复用机制的实现:

  • 其中 select 和poll 是基于轮询的方式去获取就绪连接。
  • 而epoll 是基于事件驱动的方式获取就绪连接。

从性能的角度来看,基于事件驱动的方式要优于轮询的方式。

6. select 和 epoll 的区别

select epoll 都是 I/O 多路复用的机制,它们可以让一个进程监听多个文件描述符的IO 事件或者连接事件,只要其中任意一个或多个文件描述符就绪,就会触发阻塞唤醒,使得应用程序可以直接进行数据的读取或者写入。

它们的区别主要有几个方面:

  • select 是基于轮询的机制,它需要遍历整个监听集合,直到找到就绪的文件描述符。
  • epoll 是基于事件通知的机制,它只需要遍历当前就绪的文件描述符集合,大大减少了遍历的次数和开销。
  • select 的监听集合大小有限,一般受到操作系统的限制,而 epoll 没有这个限制,可以监听大量的文件描述符。
  • 在处理大量文件描述符时,select的性能随着监听集合的增大而逐渐下降,而epoll的性能则能够保持稳定。
  • 在多线程环境下,select需要将监听集合传递给每个线程,而epoll可以在一个线程中处理多个文件描述符,避免了线程间的切换和数据复制等开销。

从对比中不难发现,epoll 相比于 select在性能和扩展性方面都有很大的优势,所以通常在企业级应用中使用较多的还是 epoll。

7. 什么是拆包和粘包?怎么解决?

拆包和粘包是在网络编程中比较常见的现象。
因为TCP 协议底层是面向流的传输,所以数据在传输的过程中会被分割成一个个的数据包(如图)
在这里插入图片描述
接收端在接收数据时需要重新组装数据包,但是 TCP 协议不保证数据包与应用层的数据交互一一对应,所以就可能会造成数据不完整的问题。

  • 拆包指的是把一个完整的数据包拆分成多个小包进行发送,而接收端可能无法一次性接收到所有小包,导致接收到的数据不完整。
  • 粘包指的是把多个数据包粘合在一起一次性发送,而接收端可能无法正确区分每个数据包,导致接收到的数据出现错位或混乱。

拆包和粘包现象是TCP 协议的数据传输机制导致的,所以要解决这个问题,
就是需要让服务端知道如何判断一个数据包的完整性,因此可以采用以下几种方法:

  • 在数据包中添加特殊字符或特殊标记,表示一个数据包的开始和结尾
  • 通过自定义消息协议,并在协议头中保存数据包的长度信息,接收方可以根据这个长度来解析数据包来保证消息的完整性
  • 基于定长消息,也就是发送端的消息长度是固定的,服务端按照固定长度来解析

8. HTTP相关

8.1 http协议是什么

HTTP(HyperText Transfer Protocol:超文本传输协议)

超文本可以说是“超级文本”或者说是“带超链接文本”。
超链接文本可以有图片、动图、文字、视频。
从本质上说它是一个内容文本,我们对网站的浏览,实际上是对内容的浏览。
对于这些内容,都有统一的路径,我们称之为URL地址

http(s): //<主机>:<端口>/<路径>

  • http:表示协议,有http和https协议
  • 主机可以是ip也可以是域名,如果是域名,会使用到DNS服务,将其转换为ip地址。
  • 端口:80端口表示http端口443端口表示https端口
  • 路径:指向特定的内容

HTTP协议是可靠的数据传输协议。可靠性是依赖于传输层的TCP协议来实现的
也就是说,HTTP协议的底层是TCP协议通过TCP协议的可靠性从而保证HTTP协议也是可靠的。

8.2 HTTP 和 HTTPS 的区别?

8.2.1 端口

  • HTTP的URL由“http://”起始且默认使用端口80
  • HTTPS的URL由“https://”起始且默认使用端口443

8.2.2 安全性和资源消耗

  • HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份
  • HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。
    • 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等
    • 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。

8.3 get和post的区别?

8.3.1 url可见性

  • get,参数url可见;
  • post,url参数不可见

8.3.2 数据传输上

  • get,通过拼接url进行传递参数;
  • post,通过body体传输参数

8.3.3 缓存性

  • get请求是可以缓存的
  • post请求不可以缓存

8.3.4 后退页面的反应

  • get请求页面后退时,不产生影响
  • post请求页面后退时,会重新提交请求

8.3.5 传输数据的大小

  • get一般传输数据大小不超过2k-4k(根据浏览器不同,限制不一样,但相差不大)

  • post请求传输数据的大小根据php.ini 配置文件设定,也可以无限大。

8.3.6 数据包

  • GET产生一个TCP数据包;
    对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据)
  • POST产生两个TCP数据包。
    对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

关于三次握手和四次挥手可以查看这篇文章:https://blog.csdn.net/Hmj050117/article/details/115361919

8.4 浏览器输入一个地址。到页面展示中间经历了哪些东西?

    1. 浏览器输入url。先解析url地址是否合法
    1. 浏览器检查是否有缓存(浏览器缓存-系统缓存-路由器缓存)。如果有,直接显示。如果没有,跳到第三步。
    1. 在发送http请求前,需要域名解析(DNS解析),解析获取对应过的ip地址。
    1. 浏览器向服务器发起tcp链接,建立tcp连接
    1. 握手成功后,浏览器向服务器发送http请求,请求数据包
    1. 服务器收到处理的请求,将数据返回至浏览器
    1. 浏览器收到http响应。
    1. 浏览器解析响应。如果响应可以缓存,则存入缓存
    1. 浏览器发送请求获取嵌入在HTML中的资源(html,css,JavaScript,图片,音乐等),对于未知类型,会弹出对话框
    1. 浏览器发送异步请求
    1. 页面全部渲染结束。

8.5 常用的HTTP方法有哪些?

  • GET 从服务端获取指定信息
  • POST 向服务端发送待处理的数据
  • HEAD 从服务端获取指定信息的头部
  • PUT 向服务端发送数据并替换服务端上指定的数据
  • OPTIONS 查询针对请求URL指定的资源支持
  • DELETE 从服务端删除指定数据
  • TRACE 沿着目标资源的路径执行消息环回测试

8.6 HTTP 状态码

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:

  • 信息响应(100–199)
  • 成功响应(200–299)
  • 重定向(300–399)
  • 客户端错误(400–499)
  • 服务器错误 (500–599):

8.7 HTTPS 工作原理

在这里插入图片描述

HTTPS,也称作HTTP over TLS;
与HTTP多了一个S,这个S代指(SSL/TLS),只不过 SSL是TLS的前身
在这里插入图片描述
只不过大多数浏览器不支持SSL,而是支持TLS;而SSL的名气比TLS大,但是为了未来发展考虑,统一以TLS;
HTTPS,也称作HTTP over TLS。
TLS的前身是SSL,TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。本文着重描述TLS协议的1.2版本;

8.7.1 问题引入

一般加密可能采用对称加密,对内容进行保护,比如下面这种
在这里插入图片描述
对于数据传输也是这个道理
在这里插入图片描述
如果此时有个第三方知道了加密规则,就很容易破解了;也导致很容易篡改数据;

8.7.2 如何解决加密泄露问题

那么如何解决呢;下面用动画来描述

左边穿蓝色衣服是 小蓝;
右边穿红色衣服是小红;

小蓝的蓝色私钥(A)只有它自己知道;小红的红色私钥©只有它自己知道;公钥(B)都是放置在公网,大家都知道;

第一步,小蓝用自己的私钥A和公钥B生成一个浅绿色的(私+公)D 并且发送给小红;
第二步,小红用自己的私钥C和公钥B生成一个橙色的(私+公)E 并且发送给小蓝;
第三步,小蓝用自己的私钥A和小红提供的 橙色的(私+公)E 生成一个 只有小蓝小红两个人知道的密钥 F;小红用自己的私钥C 和小蓝提供的 浅绿色的(私+公)D 生成一个只有小蓝小红两个人知道的密钥F; 再使用这个密钥F去加解密传输数据,是不是就安全多了;
在这里插入图片描述

8.7.3 证书作用讲解

虽然我们现在可以通过密钥来解决安全问题,但是我们仍然不知道沟通的对象是否是我们希望要沟通的对象;
比如B站的域名,很多人不经意就容易混淆,不经意就输入错误了,这样就会导致很多不法分子伪装让你来访问
在这里插入图片描述
还好Https处理了这个问题,因为Https需要申请SSL证书来证明这个域名就是大家所熟悉的B站,证书长啥样子,比如下面这个是我们公司的
在这里插入图片描述
SSL证书其实就是保存在源服务器的数据文件,要让SSL证书生效就需要向CA申请,也就是 证书授权中心(Certificate Authority,简称CA)是可信任的第三方组织,负责证书的生成、签发和作废。这样大家都来信任这个机构颁发的证书,这个证书除了表明域名是属于谁的,日期等信息外,重要的是这个证书里面还包含了特定的公钥和私钥,简单的说服务器安装了SSL证书以后,用户就可以通过HTTPS来访问服务器了,当然浏览器也会把HTTP的默认端口80改为HTTPS的默认端口443;

那么安装了SSL证书之后HTTPS有哪些变化呢,根据不同的TLS版本不同,有不同的变化,这里以TLS1.2为案例讲解

8.7.4 安装了SSL证书之后有啥变化

首先正常的http三次握手是不变得
在这里插入图片描述
Tcp三次握手以后,客户端发送了一个Client Hello 给服务端,客户端就会告诉服务端支持TLS 1.2版本和支持的加密套件,这里的加密套件大家可以理解为不同的加密算法组合,然后生成一个随机数发送给服务端;(随机数作用后面讲解)
在这里插入图片描述
然后接下来是服务端 发送Server Hello 发送给客户端,在响应报文里面会告诉客户端,服务端支持的TLS版本以及选择的加密套件,并且服务器也生成一个随机数发送给客户端;(随机数作用后面讲解)
在这里插入图片描述
接下来服务器会再发一个响应,来出示服务器自己的证书,这样浏览器就可以根据对照自己的证书信任列表来确认这个服务器是否可信
在这里插入图片描述
有了证书自然少不了公钥,接下来服务器就把公钥发送给了客户端,注意服务器不会把私钥发出去,如果服务端需要客户端的证书也会发送请求,一般登录网银会需要这一步
在这里插入图片描述
然后 服务端还要告诉客户端 ,自己已经发送完了,打个招呼,发送 Server Hello Done
在这里插入图片描述
现在轮到客户端来处理这些响应了,客户端会生成第三个随机数,也叫 预主密钥,第三个随机数会用刚刚收到的公钥进行加密,并且把这个加密后的随机数发给服务端,正是这里PubKey显示的随机数
在这里插入图片描述

这一步就是告诉服务器往后的的数据就用商议好的算法和密钥来加密
在这里插入图片描述

表示客户端这边的TLS 协商已经没有问题,加密开始
在这里插入图片描述

服务器后面也发来了 Encrypted HandShake Message ,表示TLS的握手已经成功;可以给数据加密进行交换了
在这里插入图片描述

8.7.5 总结整个过程

    1. 客户端和服务端打招呼,并把自己支持的TLS版本,加密套件发给服务端,同时还生成了一个随机数给服务端,这里就称为第一个随机数;
    1. 接着服务端打招呼,服务端确认TLS版本以及选择的加密套件,并且服务端也生成一个随机数给客户端,这里就称为第二个随机数;接着服务端还把证书和公钥发给客户端,都发送完毕就告知客户端
    1. 客户端生成随机数,我们称为第三个随机数,也就是预主密钥,这个预主密钥不会直接发送出去,而是用刚刚收到的公钥进行加密后再发送出去
    1. 然后客户端这边的TLS协商已经没有问题,加密开始
    1. 服务端收到客户端传过来的加密后的预主密钥后,会用自己的私钥进行解密,这样服务器就知道预主密钥了,而且只有客户端和服务端知道这个预主密钥,因为没有进行直接传输,没有其他人知道这个预主密钥是什么;
    1. 最后客户端用预主密钥,第一随机数和第二随机数计算出会话密钥;服务端也用预主密钥,第一随机数和第二随机数计算出会话密钥;各自得到的会话密钥是相同的;这里的逻辑正是和上面小蓝小红交互正式呼应;前面的这些步骤都是非对称加密的,为了得到这个会话密钥;后面客户端和服务端都使用这个会话密钥进行对称加密;

之所以使用对称密钥是因为减少资源损耗,其次即使被拿到会话密钥,也不知道是什么;如果有新的会话那么会生成新的密钥;会话密钥只对当前会话有效;
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alan0517

感谢您的鼓励与支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值