Day15 计算机网络八股文[1/2]

计算机网络八股文[1/2]

目录

[toc]

介绍一下 OSI 并说一下每一层常见的协议

OSI 参考模型是将用户对网络的请求到服务器处理再响应最后将响应结果展示出来这个过程的中的每个环节进行抽象分层,每一层只需要关注本层的职责;可以让各层的开发者专注自己的任务;七层模型从最接近用户的应用层开始可以分为;应用层-表示层-会话层-传输层-网络层-数据链路层-物理层;当然还有其他的分层方式比如 TCP/IP 就把他分层了四层将会话层、表示层和应用层统一抽象成引用层,然后是网络层-网际层和网络接口层;回到七层模型中,如果作为一名网络工程师那么他们侧重关注的是下四层的安全性问题,而作为一名 java 程序员平时更关注的是应用层和传输层;

应用层常见协议:

  • http: 基于 tcp 的超文本传输协议,用于 web 浏览器和 web 服务器的数据传输;端口号 80
  • https: http 的安全升级版本;端口号 443
  • ftp:基于 tcp 的邮件传输协议;端口号 21
  • SMTP:基于 tcp 的邮件发送协议;
  • pop 3/IMAP: 基于 tcp 的邮件接收协议;
  • telnet: 基于 tcp 的远程登录协议;因为他是用明文传输数据的所有安全性较差,目前用的更多的是 ssh;端口号 telnet 23 ssh 22
  • DNS:基于 udp 的 ip 到域名的映射服务;端口号 53
  • DHCP:基于 udp 端口号 67/78

表示层常见协议:

  • SSL/TLS: 为网络通信提供信息加密,https 底层就依赖这个协议

会话层常见协议:

  • PRC: 远程调用

传输层常见协议:

  • TCP: 传输控制协议,通过三次握手和四次回收确保奖励连接后的数据传输可靠性
  • UDP:用户数据报协议,面向非连接的协议但是数据的整体传输效率更高

网络层常见协议:

  • IP: 网络十分重要的协议,用于标记和定位网络中一台计算机的位置
  • ICMP: 用于传输网络状态和错误信息的协议;里面有平常使用很多的 ping 命令等;
  • ARP: ip 地址转 mac 地址(RARPmac 转 ip)
  • NAT: 用于一个网络到另一个网络过程中 ip 转换的协议
  • OSPF、BGP、RIP:这些都是路由交换协议

ARP 与 RARP 的区别是什么?

ARP 一般是发生在一个节点需要向指定 ip 发送请求,但是在封装数据包的时候发现并不知道目标计算机的 mac 地址;此时就会通过广播的方式向网络中的计算机循环 ip 对应的 mac 地址;只有目标计算机回将 mac 地址返回;

RARP 一般是一个节点需要发送请求的时候发现并不确定知道自己的 ip 地址,此时就会通过查询预定义的 RARP 服务器询问自己的 ip,通过 mac 地址查询 ip;一般发生在无盘工作站做中环境中

什么是 TCP 的粘包、拆包问题?

因为 TCP 是面向数据流的传输;所以发送方可能为了提高效率会讲多个数据块组合发送给接收方,接收方接收到这些数据包后会进行拆分,这个才分可能导致数据拆包和粘包也就是数据可能多了或者少了;

解决方法有:

  • 可以规定每次传输的单位大小;
  • 可以规定一个完整包的开始和结束的定界符;
  • 还可以参考 TCP/IP 协议栈,将消息的长度封装在一个头部中;

介绍一下 TCP 的三次握手和四次挥手;

首先需要先介绍一下 TCP 的 head;因为不管是三次握手还是四次挥手,还有 TCP 提供的滑动窗口限流、拥塞控制都是通过 head 里面各个部分的标志位来实现的; TCP 的头部大小在 20 到 60 字节之间(UDP 是固定 8 字节),其中比较核心的部分有数据的序列号:可以理解为当前数据的 id;确认号:表示当前消息具体是回复哪一次请求,因为一方可能通一个请求发送多份这个确认号是上一个消息的序列号+1;状态标志位:用于表示这个消息是建立连接去同步请求还是应答优惠哦这是断开连接的请求;还有窗口大小;

三次握手:

  1. 客户端向服务器发起同步请求,状态标志位为 syn
  2. 服务端接收到请求后应答客户端状态为为 ACK + SYN,确认号是请求的序列号+1
  3. 客户端收到服务器的确认同步信息应答 ACK

四次挥手:(因为是全双工的连接断开的请求也可能是服务器向客户端提出的,方向不同但是流程相同)

  • 客户端发送标志位 FIN 的数据包给服务器;
  • 服务器接收到后响应一个 FIN 状态的数据,里面还包含 ACK
  • 然后客户端收到后进行等待;直到服务器发送一个 FIN 标志位的数据包给客户端
  • 客户端收到服务器的第二个 FIN 数据包后响应给服务器 ACK

为什么是三次握手?两次可以吗?

三次握手缺一不可;讲清楚为什么是三次握手,就要明白三次握手过程中客户端和服务器分别做了哪些事情,分别得到了哪些信息; 第一次握手是客户端向服务器发送一个同步请求;服务器接收到后就可以确认两件事情,一是客户端的发送功能正常,二就是自己是接收功能正常; 而后服务器响应确认和同步信息客户端接收到后客户端可以确认双方的收发功能都是正常的,但是服务器此时并不确定,双方信息不对称; 直到第三次握手客户端向服务器响应 ACK,服务端和客户端都可以确定双方有着完整的收发功能; 简而言之,三次握手是确认双方都具备正常的收发功能,这是为了确保即将建立的 TCP 全双工连接的可靠性;

为什么是四次握手?

一方先发出断开请求,然后接收方需要响应这个请求;然后最初的发送方需要等待接收方再次响应断开请求;第一次接收方响应断开请求是为了让断开请求方知道自己已经收到了断开请求,避免了触发超时重传,第二次响应之前的这段时间是避免网络中可能还存在没有到达的数据如果直接断开连接将会丢失,也有可能还有数据没有发出,当发起断开的一方接收到两次确认后会向对方发送最后的断开确认信息,对方接收到后就可以断开连接了;如果第二次的响应请求 ACK 没有收到那么会重新发送 FIN 请求

TCP 是如何保证传输数据可靠性的?

TCP 保证数据全输的可靠性是能确保传输过程中能满足几点: 不多不少不重不乱

  • 数据的有序性:比如三个报文发送顺序是 ABC ,那么 TCP 就能保证不会出现 ACB 的情况
  • 数据的完整性:依然发送 ABC,TCP 能保证收到 ABC 如果只收到了 AB 那么就会触发重传机制
  • 能确不重复:发送 ABC 不会收到 ABBCC
  • 不会被篡改:发送 ABC 不会在发送过程中被篡改为 ABD

TCP 确保上面的特性是通过:三次握手四次挥手、数据 head 部分中的标志位、校验和、窗口大小、拥塞控制、超时重传等机制实现的

TCP 是如何实现流量控制的?

通过滑动窗口和窗口调节实现的;每个连接的双方都有一块独立的缓存空间,在接收信息之前会让对方知道自己能接收的数据窗口的大小,根据接收方的目前网络状况处理性能来动态调节窗口大小,当接收方目前业务繁忙就会将窗口调小,目前相对空闲就会减窗口调大,依次来实现流量的控制;

介绍下 TCP 是如何实现拥塞控制的?

TCP 实现拥塞控制主要是通过限制数据发送方的发送速率来减少丢包和网络性能浪费的问题; TCP 的具体实现是通过慢启动,拥塞避免,快重传和慢启动实现的; 消息发送端会维护一个拥塞窗口 (congestion window 简称 cwnd);慢重启是指在开始发送消息和发送拥塞后窗口会从 1 MSS 开始每次夸大一倍,直到达到慢启动阈值;达到慢启动阈值之后就开始拥塞避免,每次将窗口夸大 1 MSS ,如果在这个线性缓慢增长的过程中出现了网络拥塞那么就将窗口调回 1 然后将慢启动阈值减半然后再次执行慢启动; 快重传和快恢复是对慢启动和拥塞避免的该进 TCP 不依赖超时来检测数据包是否丢失,而是通过冗余的 ACK 来进行判断,比如发送方依次发送 12345 四个数据包,接收方只接受到了 1245 丢失了 3 包那么就会发送三个 3 的 ACK 响应给发送方,让发送方知道 3 的包我并没有接收到。然后重传;当快重传触发后就会进入快恢复,首先依然将阈值减半然后将窗口设为阈值+3 MSS,+3 对应的就是三个 ACK 然后继续执行线性增长

TCP 和 UDP 的区别

TCP 是面向连接的 UDP 是无连接协议; TCP 是可靠传输确保数据不会丢失重复和乱序,UDP 不提供这些保证; TCP 可以控制流量窗口大小、对拥塞也有主动机制去降低,UDP 没有; 但是 TCP 数据包体积大于 UDP 并且传输效率低于 UDP,所以在需要可靠传出的场景中我们采用 TCP 比如重要数据传输,在一些对可靠性要求不高但是对传输效率高的场景中可以采用 UDP 比如实时语音视频,DNS 查询,在有些常见中我们会在传输层采用 UDP 来发挥他的高效率他的数据可靠性我们会在上层进行提供;

从输入 URL 到页面展示到底发生了什么?

  1. 浏览器对 URL 进行解析:对 URL 进行自动补齐协议,URL 进行编码根据解析的 URL 查询浏览器是否缓存过该页面
  2. 第二步就需要获取到目标服务器的 ip 地址用于后续的封装和传输,会依次查询浏览器缓存,本地 DNS 缓存, DNS 服务器递归查询,直到获取到目标 ip
  3. 服务器将请求封装为 http 报文尝试通过三次握手和服务器建立连接;如果是 HTTPS 那么还会建立 STL 握手来交换密钥
  4. 数据通过路由器路由到网络中的目标 ip;
  5. 一般来说服务器接收到请求会先到 nginx 服务器上,nginx 通过反向代理和负载均衡判断请求应该映射到哪个具体 serverlet 容器;
  6. serverlet 容器接收到后会解析请求行、请求头、请求体交给 MVC;
  7. DispatchServerlet 接收到请求后根据路径交给对应拦截器和 Controller
  8. 控制器再执行业务逻辑操作数据库或则中间件后将结果返回
  9. 用户端接收到响应的数据后根据前端代码逻辑对响应信息进行处理和展示;如果 URL 请求的是前端服务器数据那么 nginx 会讲请求代理给前端服务器,前端服务器返回 html 代码,返回给浏览器后浏览器会加载和渲染 html 所需要的资源和内容;
  10. 当服务器不需要进行通信时会主动关闭 TCP 连接或则等待服务器的关闭请求,通过四次挥手断开连接;

HTTP 状态码有哪些?

状态码是一种约定俗称的规定;一半按照状态码的开头可以分为 12345 个不同的类别

  • 1 xx 表示服务器正在处理请求
  • 2 xx 表示成功;
  • 3 xx 表示重定向;比如常用的将未登录用户重定向到登录页面
  • 4 xx 表示客户端错误;401 无权限;403 服务器拒绝请求,一般是权限不足;404 请求的资源路径不存在;
  • 5 xx 表示服务器内部错误;500 服务器抛出异常且程序没有处理和捕获;502 网关或则代理无法从上游服务器得到响应;503 服务暂时无法使用,可能服务器过载可能被限流;504 请求超时

一般实际开发中会将我们自定义的业务状态码封装在响应体中,前端在处理的时候也从请求体中的状态码进行判断;

讲一下 HTTP 从 1.0 到 1.1,2,3 的迭代和每一代的问题和改进

最开始的 http 1.0 版本中有着明显的问题,就是每次请求服务器都需要进行三次握手建立连接,如果一个页面中有很多的文件和资源需要请求那么就会浪费很多性能和传输在连接的建立和释放上;

http 1.1: 1.1 推出了长连接功能,运行一次建立 TCP 连接后发送多次请求;这大大提升了大量请求下的请求效率但是还是存在一些问题;比如 http 层面的队头阻塞;队友拥塞指的是因为是复用 TCP 连接所以连接中的请求和响应的顺序必须相同,比如客户端依次请求了 ABC 三个服务器资源,B 和 C 都很快处理完成可以响应了,但是 A 可能在执行复杂的逻辑也可能是一个体积很大的文件,这就会出现 BC 资源的响应阻塞;此外大量相似的请求会携带相同的请求头比如认证信息 cookie 等,在传输中就会有大量冗余;解决和优化方法就是合并文件比如雪碧图、将 css 和 js 合并到 html 中或者将不同类型的资源划分在不同的域名上;

http 2: 引入了多路复用技术,简单来说就是允许通一个连接内的请求和响应相互独立的并行,不会以为需要等待前面的请求而导致阻塞;具体的实现就是在 http 层面将数据报文进行拆分,拆分层一个个的逻辑桢,桢会被拆成头桢和数据桢,头桢中的流标识字段就能找到每个头桢对应的数据桢;这样就避免了 http 层面的头部阻塞; http 2 还引入了 HPACK 压缩算法减少了数据头中的冗余信息减小传输体积; http 2 还有一项技术就是服务器推送技术,当客户端请求一个资源时服务器会将可能相关的资源主动推送给服务器,但是这样方式的安全性很差,比如在 DDos 攻击中就会浪费大量服务器性能; http 2 虽然提升了性能但是他底层传输层依然依赖的是 TCP 协议,TCP 协议为了确保数据的一致性只要出现了数据丢包就会触发重传,依然会存在传输层层面的队头阻塞;

http 3:从 http 2 的问题可以看出主要瓶颈就是出现在传输层的 TCP 协议;要想突破瓶颈就要升级 TCP 但是直接升级 TCP 就会引发诸多的主流设备兼容性问题,所以 http 3 的做法是放弃 TCP 该用 UDP 这种传输效率更高的无连接协议,UDP 是不可靠的 http 3 就通过整合各层协议退出了 QUIC 协议来为 UDP 实现上层的可靠性;QUIC 整合了 http 和 TCP 还有 TLS 协议;实现了快速握手建立联机,快速恢复连接,并且在 QUIC 层进行数据报文封装成桢并且和 http 2 思想相同采用数据流标识,来实现每个请求的独立消灭了 http 层面和 TCP 层面的队头阻塞问题;但是目前很多的服务器和企业防火墙对 UDP 的流量会进行拦截,http 3 是一个未来的主流,但是目前的普及起来还有许多障碍这一点有点像 IPv 6

对称加密和非对称加密有什么区别?

对称加密是指通信双方持有相同的密钥,通过这个密钥加密的数据只能通过这个密钥进行解密; 为了确保双方的密钥相同一般都需要进行提前协商,但是又要确保这个协商过程的安全性,计算用明文也不会被其他人窃取到协商出来的密钥那么就可以使用非对称加密; 非对称加密双方都有各自的公钥和私钥; 比如现在服务器公开了公钥;一个客户端想要和他建立连接;

  • 假设客户端私钥公钥分别是 ab, 服务器分别是 qp
  • 客户端会先用自己的私钥和服务器的公钥进行计算得到一个值 ap=A
  • 服务器也会用自己的私钥和公钥进行计算得到一个值 qp=Q
  • 然后客户端和服务器交换两个值 AQ
  • 现在客户端在用自己的私钥对服务器计算的值进行加密 aQ; 服务器也同样用私钥进行加密 qA
  • aQ=aqp; qA=aqp 这样两边就得到了相同的值这个值就是双方协商的密钥 非对称加密的思想就是用公钥来加密双方的私钥,确保通过公钥加密后的私钥信息可以在网络上安全传输

HTTPS 和 HTTP 的区别是什么?

HTTPS 可以简单理解为 HTTP 的安全加密版本;http 是通过明文进行传输是数据的很容易被窃听和中间人攻击,https 则是通过 SSL/TLS 协议来对传输过程进行加密;两者的具体区别如下:

  • 首先就是刚刚提到的安全性,https 安全性更高;
  • 端口号不同 http 默认 80 端口 https 默认 443
  • 证书不同,http 不需要证书,https 需要权威机构的证书,这也能保证用户通过 https 不会被高仿的钓鱼网站欺骗
  • 搜索引擎排名不同,搜索引擎会认为 http 的网站不安全而 https 是相对安全的所有 https 在搜索排名上更具优势

URI 和 URL 的区别是什么?

URI 是用于定位网络中的一个资源,URL 是他的一个子集;可以将 URI 理解为每个人的身份证号,URL 就是每个人家的地址

Cookie, Session 和 JWT 有什么区别?

http 是一种无状态协议,也就是服务器眼中的每次请求都是独立的,他不能确保请求的上下文;而这三种技术就是为了实现避免在无状态请求下的重复身份认证

cookie:当用户第一次在服务器中登录后,服务器会将用户名返回给浏览器,浏览器负责保存;以后的请求都会附带上 cookie,服务端会查看 cookie 是否过期;缺点:cookie 的安全性差

session:当用户第一次在服务器中登录后,服务器会生成一个 sessionId 然后把用户相关信息通过和 SessionId 一起保存在 redis 或者 Map 或者数据库中,然后把 SessionId 通过cookie返回给浏览器;以后的请求服务器都会自动带上 sessionID,服务器看到一个请求中有 sessionId 就会去 redis 中查询是否有有效的 sessionID,如果有则读取对应用户信息,如果不存在则证明过期或者不合法;缺点:跨域环境和分布式环境支持很差

JWT: jwt 是用 json 格式传输的令牌 token;在用户登录成功后服务器将会生成 JWT 颁发给用户端;jwt 中包含三部分,加密信息,数据载荷,签名;第一部分加密信息标识当前 jwt 生成的加密策略,第二部分中包含了过期时间还可以携带服务器自定义的数据,第三部分是对前两部分的签名,确保 jwt 被颁发后不会被修改;因为 jwt 的加密和解密都在服务器端,而且 jwt 在浏览器的后续传输中只是一段简短的字符串,并且不在服务器中进行保存所以他的性能很好,在分布式场景下多点登录情况下也有很好的表现;但是 jwt 也有设计上的局限性,那就是因为服务器端无状态,对于分发过的 jwt 没有管控权,比如无法对登录的 jwt 进行登出操作,假设在一个常见中用户 jwt 可能泄露了,用户将用户名和密码进行了更改,按业务逻辑来说应该将之前该用户的所有 jwt 都设为无效,但是 jwt 不能实现这点;解决 jwt 管控问题可以将无状态变为有状态,就是在颁发 jwt 前将 jwt 存储在 redis 中,这样的好出就是可以对发出去的 JWT 进行控制,并且每次通过 redis 查询一个 jwt 是否存在和通过解密计算 jwt 是否合法相比性能更高;

#java##面试#
全部评论

相关推荐

头像
03-10 10:02
门头沟学院 Java
牛爷爷战士:javaguide太泛了,想面试突击的建议不要硬凿Guide费时间,我自己整理到飞书上的面经差不多一两周就能去面了😂需要的d一下就行,不要米
点赞 评论 收藏
分享
评论
4
7
分享

创作者周榜

更多
牛客网
牛客企业服务