一些面试题
1. 网络面试题
1.1. 服务器端大量出现 TIME-WAIT 的状态的连接
要想彻底了解整个问题,就要对传输层通信模型有一个很清晰的认识。下面是一些前置知识:
- 多个应用层软件在传输数据时,是要复用传输层的系统资源的,并且编程模型为应用层调用操作系统接口,操作系统接口操作计算机网络资源,而计算机网络资源是有限的,这就表明必须要有一套传输层的资源协调控制机制。所以要了解 socket 的相关内容。
- 应用层协议中的一些请求头的设置,实际上设置的是传输层的一些资源的行为属性,比如 Connection: Keep-Alive 表示,复用传输层的连接通道,不必每一个请求都新创建一个通道。
- TIME-WAIT 的状态只属于主动请求关闭通道的一方,也就是说“客户端和服务端都有可能出现 TIME-WAIT 的状态”。
1.1.1. 原因分析
原因分析: 服务器端大量出现 TIME-WAIT 的状态的连接,本质原因只可能是主动关闭 TCP 连接的原因。造成这种情况的实际场景有:
1.1.1.1. 情况 1: 本来应该使用长连接的,却使用了短链接
我们知道传输层主要有三个任务,请求建立通道、传输数据、请求销毁通道。在请求建立通道时,事实上是应用层向操作系统请求一个 socket 资源,而 socket 资源是有限的,所以传输层对 socket 资源的实现是: 要求 socket 资源可以复用,即对多个客户端的多个请求,服务器端只建立一个 socket 资源,让这个 socket 资源服务于多个客户端的多个请求。【会话问题则通过四元组(源 IP、源端口、目的 IP、目的端口)来标识唯一】。这种情况就是长连接的情况。
结合 HTTP 协议,就是在请求头里添加了 Connection: Keep-Alive 。HTTP 协议的这一项,只是整个长连接的配置,具体实现是有 TCP 来完成的。【如果要使用 短连接, 可以设置为 Connection: close 。】
本来应该使用长连接的,却使用了短链接,如果一下子涌来大量请求,就可能会出现 socket 资源一下子就被申请完了,这就会造成两种问题:
- 再有新的请求过来时, 服务器端就会主动回收一些 socket 资源,导致 TIME-WAIT 过多;
- 当这些请求都完成,服务器端也要主动回收 socket 资源,这也会导致 TIME-WAIT 过多;
1.1.1.2. 情况 2: 使用了长连接,但是超出了长连接个数的限制
socket 资源有限,并且可以设置,但要注意的是,设置整个长连接的数量是由应用层负责的,多数应用层实现都可以设置长连接的个数,如 nginx 可以设置 keepalive_requests 这个参数来规定长连接的个数。
超出了个数限制之后,服务器端就会主动回收,这就导致 TIME-WAIT 过多。
1.1.1.3. 情况 3: 服务器端迟迟等不到数据分组
使用了长连接,但是客户端异常,导致三次握手后迟迟得不到客户端的数据分组,这也会导致服务器端主动关闭通道,导致 TIME-WAIT 过多。
1.1.2. 问题解决
原因分析透彻之后,就可以得出解决方案,下面是一些最佳实践:
- 服务器端的 web 服务器应用设置长连接,即 HTTP 协议头里添加 Connection: Keep-Alive , 让客户端与服务器端的通道能够保持复用;
- 客户端请求结束后要主动关闭通道,并尽量避免服务器端主动发起关闭通道的请求。【 TIME-WAIT 状态只发生在发起关闭通道的一方】
- 服务器端修改通道行为设置:
- net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将 TIME-WAIT sockets 重新用于新的 TCP 连接,默认为 0,表示关闭;
- net.ipv4.tcp_tw_recycle = 1 表示开启 TCP 连接中 TIME-WAIT sockets 的快速回收,默认为 0,表示关闭。
1.2. 服务器端出现大量的 CLOSE-WAIT 的状态
1.2.1. 原因分析
根据网络模型判断,出现这种问题的原因只能是: 服务器端在发回 ACK 消息后,还存在大量未接收完的数据分组,造成这种问题的原因可能是网络延迟等问题。
当然,一些基于 socket 编程的服务器也可能会出现这种问题,这个时候就要排查服务器端代码了。
1.3. 具体案例
如 JavaWeb 应用中,一般使用内置的 tomcat 作为应用服务器,假设配置文件中配置了 tomcat 的线程池最大数为 5,此时同时开启大于 5 个线程(线程内部 sleep-n 秒),体会这种情况下的问题发生过程及其原因。 去查服务器日志,就会发现有多个 TIME-WAIT 状态的日志,这时的原因就是 tomcat 设置了 max-thread = 5 的意思就是相当于告诉操作系统只准备 5 个 socket 资源,而实际使用时,却有超过 5 个的线程要申请,于是操作系统主动回收一部分.... TODO
1.4. 参考
2. 详细解释一下 chrome、操作系统以及硬件驱动在这些过程中的作用以及深层次的工作原理
在 Chrome 浏览器请求 google.com
的过程中,涉及到多个层次的协作,包括应用层(Chrome)、操作系统、网络协议栈,以及硬件驱动。下面详细解释每个部分的作用和深层次的工作原理:
2.1. Chrome 浏览器(应用层)
作用:
- 发起 HTTP 请求,呈现 Web 页面。
工作原理:
- DNS 解析:当用户输入
google.com
并按下回车,Chrome 会先检查本地 DNS 缓存。如果没有缓存,它会向操作系统请求域名解析。 - 构建 HTTP 请求:Chrome 根据用户输入和网页加载需求构建 HTTP 请求头和请求体。
- 发送请求:通过操作系统的网络栈,将 HTTP 请求发送到目标服务器。
2.2. 操作系统(网络栈)
作用:
- 管理网络连接和数据传输。
工作原理:
- DNS 解析:
- 本地缓存:首先检查操作系统的 DNS 缓存。
- DNS 查询:若缓存未命中,操作系统会构建 DNS 查询报文,通过 UDP(或 TCP)协议发送给 DNS 服务器,并等待响应。
- TCP 连接建立:
- 三次握手:操作系统通过网络栈执行 TCP 三次握手过程:
- 发送 SYN 包。
- 接收服务器的 SYN-ACK 包。
- 发送 ACK 包,确认连接建立。
- 三次握手:操作系统通过网络栈执行 TCP 三次握手过程:
- 数据传输:
- 封装数据:操作系统将 Chrome 发送的 HTTP 请求数据封装到 TCP 段,再封装到 IP 包,最后封装到以太网帧。
- 流量控制和拥塞控制:TCP 协议通过窗口大小和拥塞控制算法(如 TCP Reno 或 TCP Cubic)确保可靠传输。
- 重传机制:TCP 协议通过序列号和确认号机制确保数据正确接收,必要时重传丢失的数据包。
2.3. 硬件驱动(驱动层)
作用:
- 负责操作系统与硬件设备的通信。
工作原理:
- 网卡驱动:操作系统通过网卡驱动与网卡进行通信,执行数据的发送和接收。
- 数据包传输:驱动程序将操作系统网络栈传递的以太网帧发送到网卡。
- 中断处理:网卡接收数据包后,通过硬件中断通知驱动程序,驱动程序再将数据包传递给操作系统网络栈。
- DMA(直接内存访问):现代网卡使用 DMA 技术直接将数据包读写到主内存,提高数据传输效率。
- 协议卸载:某些高性能网卡支持协议卸载,如 TCP/UDP 卸载引擎(TOE),在硬件层面处理部分网络协议,减轻 CPU 负担。
2.4. 硬件层(物理层)
作用:
- 实际传输数据包。
工作原理:
- 以太网:通过以太网协议在局域网内传输数据包。
- 帧格式:以太网帧包含目标 MAC 地址、源 MAC 地址、以太类型、数据和帧校验序列(FCS)。
- 信号传输:在物理层上,通过电缆(如铜缆、光纤)或无线信号传输比特流。
- Wi-Fi:在无线局域网中,通过无线信道传输数据包。
- 无线帧格式:无线帧类似于以太网帧,但包含更多管理和控制字段。
- 信号调制:使用不同的调制技术(如 OFDM)在无线信道上传输数据。
2.5. 详细流程总结
Chrome(应用层):
- 构建 HTTP 请求并请求 DNS 解析。
操作系统(网络栈):
- 通过 DNS 服务器解析域名为 IP 地址。
- 建立 TCP 连接(三次握手)。
- 封装 HTTP 请求到 TCP 段、IP 包和以太网帧。
- 处理 TCP 流量控制和重传机制。
硬件驱动(驱动层):
- 通过网卡驱动将数据包传递给网卡。
- 使用 DMA 技术和中断处理提高数据传输效率。
硬件层(物理层):
- 使用以太网或 Wi-Fi 在物理介质上传输数据包。
数据接收过程(服务器端):
- 服务器网卡接收数据包,传递给操作系统。
- 操作系统解封装数据包,交给 Web 服务器处理。
- 服务器响应数据经过相同层次返回给 Chrome 浏览器。
通过以上详细过程,Chrome、操作系统和硬件驱动在网络通信中紧密协作,共同完成从应用层到物理层的数据传输。
3. 请给出 chrome 请求 google.com 的 mac 帧的构造过程,详细解释其中的原理
在 Chrome 浏览器中请求google.com
时,涉及到多个网络协议层的操作,从应用层的 HTTP 请求到物理层的 MAC 帧构建。以下是详细解释其中的原理和过程:
3.1. DNS 解析
在请求google.com
之前,Chrome 需要将域名解析为 IP 地址。这涉及到 DNS(域名系统)解析过程。
- DNS 查询:Chrome 首先检查本地缓存中是否有
google.com
的 IP 地址。如果没有,会向 DNS 服务器发送查询请求。 - DNS 响应:DNS 服务器返回
google.com
的 IP 地址,例如142.250.183.206
。
3.2. 建立 TCP 连接
接下来,Chrome 需要与google.com
的服务器建立 TCP 连接。假设 IP 地址为142.250.183.206
,端口为 80(HTTP)或 443(HTTPS)。
- 三次握手(Three-Way Handshake):
- SYN:Chrome 发送一个 SYN 包到服务器,表示请求建立连接。
- SYN-ACK:服务器接收到 SYN 包后,返回一个 SYN-ACK 包,表示同意建立连接。
- ACK:Chrome 接收到 SYN-ACK 包后,发送一个 ACK 包,确认连接建立。
3.3. 发送 HTTP 请求
连接建立后,Chrome 会发送 HTTP 请求,例如 GET 请求:
GET / HTTP/1.1
Host: google.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
3.4. 数据封装到 TCP 段
HTTP 请求被封装到 TCP 段中,包含以下信息:
- 源端口:Chrome 使用的本地端口。
- 目标端口:服务器的 HTTP 或 HTTPS 端口。
- 序列号:表示数据包的顺序。
- 确认号:确认接收到的数据。
- 窗口大小:流量控制信息。
- 校验和:数据完整性校验。
- 数据:实际的 HTTP 请求数据。
3.5. TCP 段封装到 IP 包
TCP 段被封装到 IP 包中,包含以下信息:
- 源 IP 地址:Chrome 设备的 IP 地址。
- 目标 IP 地址:
google.com
的 IP 地址。 - 生存时间(TTL):数据包在网络中允许的跳数。
- 协议:表示使用的传输协议(TCP)。
- 校验和:数据完整性校验。
- 数据:包含 TCP 段的数据。
3.6. IP 包封装到以太网帧
IP 包被封装到以太网帧中,以太网帧包含以下信息:
- 目标 MAC 地址:下一跳设备的 MAC 地址(可能是路由器)。
- 源 MAC 地址:Chrome 设备的 MAC 地址。
- 以太类型:表示上层协议类型(IPv4)。
- 数据:包含 IP 包的数据。
- 帧校验序列(FCS):用于检测帧传输中的错误。
3.7. 发送以太网帧
封装好的以太网帧通过网卡发送到物理介质(如以太网电缆、Wi-Fi),并传输到目标设备(如路由器或交换机)。
3.8. MAC 帧构造过程
- 目标 MAC 地址:确定数据包的下一跳设备的 MAC 地址。如果目标 IP 在同一子网内,目标 MAC 地址是目标设备的 MAC 地址。如果在不同子网内,则是网关(路由器)的 MAC 地址。
- 源 MAC 地址:Chrome 设备的 MAC 地址。
- 以太类型:
0x0800
,表示 IPv4 协议。 - 数据:包含 IP 包的数据。
- FCS:计算数据帧的校验码,确保数据完整性。
3.9. ARP 解析
如果目标 MAC 地址未知,Chrome 会先发送 ARP(地址解析协议)请求来解析目标 IP 地址的 MAC 地址:
- ARP 请求:广播发送 ARP 请求,询问目标 IP 地址对应的 MAC 地址。
- ARP 响应:目标设备回复 ARP 响应,提供其 MAC 地址。
3.10. 总结
Chrome 请求google.com
时,通过以下步骤构造并发送 MAC 帧:
- DNS 解析:解析域名为 IP 地址。
- 建立 TCP 连接:通过三次握手与服务器建立 TCP 连接。
- 发送 HTTP 请求:发送包含目标 URL 的 HTTP GET 请求。
- 封装数据:HTTP 请求封装到 TCP 段、IP 包和以太网帧中。
- 发送帧:通过物理介质发送以太网帧到目标设备。
每个步骤涉及到不同的协议和操作,共同实现从高层应用数据到低层物理传输的完整过程。
深入理解加解密
总述
甲把文件发送给乙,乙收到文件,有几个问题需要搞明白。
- 文件内容不能被别人偷窥,也不能被被人篡改;
- 需要确定文件是由甲发过来的,而不是由其他人发过来的;
- 需要确定甲的签名是甲自己签名的,而不是别人签名的;
- 需要确定文件时间是甲和乙都认可的,或者说确定文件时间是不能被甲否认的;
对整个加密过程,可以类比想像成现实生活中把信件发送给别人的过程,每一个环节都有可能出现问题。整个发送的过程就是不断解决这些问题的过程
——这就是整个信息安全的主要指导思想。
需要思考的问题有:
- 如何防止文件被窥?(加密)
- 如何确定文件是由甲发送?(加签名)
- 如何确定文件没有被篡改?(取摘要)
在 加密
、加签名
、取摘要
过程中,又引入新的问题:
- 如何保证甲的公钥是甲的公钥?(引入 CA 中心)
- 如何防止甲的私钥丢失?(引入强因素认证)
- 如何防止甲否认发送时间?(引入 DTS)
概念理解
- 什么是对称加密 所谓对称加密就是使用同样的字串,对数据进行加密和解密。
- 什么是非对称加密 非对称加密,就是把公钥分发给其他人,私钥只有自己知道,私钥能解密被公钥加密的内容,公钥也能解密由私钥加密的内容。
- 什么是散列算法 也称哈希算法。散列表的基本思想是将关键字(key)通过散列函数映射到表中的一个位置,在查找的时候只要通过关键字就可以直接获取对应位置的值。那么主要的问题就是如何设计散列函数和如何在不同的关键字映射到同一位置的时候处理冲突。注意我们现在讨论的存放的仅仅是关键字,实际情况存放的是关键字+值。
- 什么是摘要 使用散列算法对一段字符串进行操作,得到的结果就是摘要。其特点是,无法通过摘要信息获取任何一点关于明文的信息。接收方只能通过同样的散列算法对字符串进行操作,通过对比摘要信息是否一致来证明文件是否被篡改。
- 什么是签名 利用非对称加密算法中的私钥能解密被公钥加密的内容,公钥也能解密由私钥加密的内容的原理,对要发送的内容,使用自己的私钥对某一字符串进行加密,如果接收方能够使用发送方的公钥解密出改字符串,则证明此文件是由接收方发送的。
- 什么是 ca 机构 ca 机构是颁发数字证书的、受信任的第三方机构,它承担着公钥体系中公钥合法性检验的责任。
- 什么是数字证书
- 定义: 数字证书即 ca 机构发放的,最简单的数字证书包含公开密钥、名称及证书授权中心的数字签名,一般情况下还包含证书的有效时间、序列号、颁发机构信息等。
- 作用: 数字证书的作用是证明证书中列出的用户合法拥有证书中列出的公钥,即是用户信息和公钥一一绑定。
- 什么是强认证机制 强认证机制就是只有身份拥有者才知道的因素。例如,银行卡密码,不存储于别的地方,只有自己才知道;再比如指纹、虹膜等生物信息;再比如由认证中心颁发的与身份绑定的 U 盾等。
- 多因素认证
加解密过程
下面的场景之间的关系是递进的,即在解决了一个问题的同时又引入了新的问题,场景二解决了场景一引入的新问题……
场景一——防文件被偷窥
使用对称加密算法加密明文,使用非对称加密算法加密密钥。
甲的过程:
- 甲使用对称加密算法中的密钥(串 a)对文件进行加密,生成串 b
- 甲使用非对称加密算法中乙的公钥对对称加密算法用到的密钥(串 a)进行加密,生成串 c
- 甲把串 c 和串 b 一块发给乙,即甲把加密后的密文和加密后的密钥一并发送给乙
乙的过程:
- 乙使用非对称加密算法中的私钥对串 c 进行解密,得到甲加密文件是用到的串 a
- 乙使用串 a 对串 b 进行解密,得到明文
潜在问题
:黑客执行甲的步骤,然后把串 c 和串 b 发给乙,乙同样会得到明文,但是这个明文与期待中的明文是不一样的,即文件被篡改。那如何防止文件被篡改?
场景二——防文件被篡改
利用非对称加密算法中,公钥能解开同为一对的私钥加密的密文的原理(使用甲才拥有的私钥加密,这个过程就是签名的过程),来证明文件是由甲发送过来的,而非别人,即文件没有被篡改。
甲的过程:
- 甲使用对称加密算法中的密钥(串 a)对文件进行加密,生成串 b
- 甲使用非对称加密算法中乙的公钥对对称加密算法用到的密钥(串 a)进行加密,生成串 c
- 甲使用散列算法对文件进行取摘要操作,然后使用自己的私钥进行加密,生成串 d,这个串 d 就是甲的签名
- 甲把串 d、串 c 和串 b 一块发给乙
乙的过程:
- 乙使用非对称加密算法中的私钥对串 c 进行解密,得到甲加密文件是用到的串 a
- 乙使用串 a 对串 b 进行解密,得到明文
- 乙使用甲的公钥对串 d(即甲的签名)进行解密,得到明文摘要
- 乙使用同样的散列算法对明文进行取摘要,与上一步得到的明文摘要进行对比,相同即可认为是文件内容没有被修改
潜在问题
:在乙的解密过程中,乙使用甲的公钥对串 d 进行解密,如何确保一定是甲的公钥呢?
场景三——防身份被冒用
通过公认的第三方机构来验证公钥与公钥持有者的信息的原理来证明改公钥就是公钥持有者的。
甲的过程:
- 甲使用对称加密算法中的密钥(串 a)对文件进行加密,生成串 b
- 甲使用非对称加密算法中乙的公钥对对称加密算法用到的密钥(串 a)进行加密,生成串 c
- 甲使用散列算法对文件进行取摘要操作,然后使用自己的私钥进行加密,生成串 d
- 甲拷贝一份自己的数字证书的拷贝
- 甲把串 d、串 c 和串 b 以及数字证书的拷贝一块发给乙
乙的过程:
- 乙使用非对称加密算法中的私钥对串 c 进行解密,得到甲加密文件是用到的串 a
- 乙使用串 a 对串 b 进行解密,得到明文
- 乙使用甲的公钥对串 d 进行解密,得到明文摘要
- 乙使用同样的散列算法对明文进行取摘要,与上一步得到的明文摘要进行对比,相同即可认为是文件内容没有被修改
- 乙校验数字证书的签名来验证数字证书的有效性(ca 中心会广播给域内任何一台主机一个字符串,这个字符串就是 ca 的签名数据,校验时只需要对比数字证书中的 ca 的签名是否与自己本地存储的 ca 中心的签名是否一致即可),如果校验通过,则可以相信数字证书中包含的公钥所属者
潜在问题
:甲虽然把合同发送给乙,但是甲拒不承认在签名(数字签名就相当于书面合同中的文字签名)显示的那一刻签署过此文件,把此过错归咎于电脑。
场景四——防时间被篡改
取大家公认的第三方服务提供的时间作为可信时间。
具体过程:
- 甲把要发送的文件加上时间戳,然后用哈希编码形成摘要,再把摘要发送给 DTS;
- DTS 再对收到文件添加时间戳,再进行签名,然后返回给甲;
- 甲把时间戳(包括加了时间戳的文件的摘要、DTS 收到文件的时间和日期、DTS 的签名)连同之前的所有信息一并发送给乙,因此具有不可否认性;
潜在问题
:整个连贯的场景中,涉及到的重中之重是甲的私钥,如果甲的私钥丢失,整个过程就变的不可信,不安全。那如何保证私钥的安全?
场景五——防私钥丢失
- 使用强认证机制;