面试题-计算机网络1
前言
计算机网络部分的题目,是我根据Java Guide的面试突击版本V3.0再整理出来的,其中,我选择了一些比较重要的问题,并重新做出相应回答,并添加了一些比较重要的问题,希望对大家起到一定的帮助。
系列文章:
计算机网络
-
简单说说以太网协议
以太网协议是用于局域网内计算机通信的协议。以太网工作在连接层,连接层的下面是物理层,对物理层来说,只有01序列流的概念,在连接层有了有限的01序列的概念,这种有限的01序列叫做帧。(简单理解,一帧就是我们要发送的一条数据)。
以太网以mac地址来寻址,mac地址是网卡设备制造商烧录在网卡中的。
-
交换机和集线器的区别?
- 集线器广播数据,安全性较差,无法多路同时通信
- 交换机记录了局域网内的所有mac地址信息,只发送到对应的端口
-
为什么会产生IP协议?只用MAC地址定位不可以吗?
MAC地址虽然可以保证唯一性,但是这个地址是网卡供应商烧录进去的,同一个公司的同事,MAC地址大概率是没有规律的,当网络中的设备越来越多时,路由找到对应的MAC地址就会变得越来越困难。后来出现的IP协议,IP协议可以理解为用一种有规律的方式标记网络上的设备。具体做大是 通过把IP地址划分为社区段+主机段,路由的时候只需要按照社区路由,找到社区后,再由社区内部根据MAC地址直接发送过去。可以大大减少路由的成本提高计算的速度。
通俗的解释下:
每个人都有身份证号,这个号码虽然是唯一的,当我们要写信给别人时却绝对不会只用身份证号来标记收件人,而是先写省市区,然后是具体住址 姓名和电话。对邮局来说,这样写也能更方便的路由,如果只用身份证号标记,如何快速找到这个id对应的人呢?这里的身份证号=MAC地址,省市区=ip地址的社区段,具体住址姓名和手机号为主机段。
-
ARP协议是什么?
当通过ip地址的社区部分找到社区后,我们就需要把数据包发送给社区中的那个唯一的主机,这个操作需要借助MAC地址实现,ARP协议就是用来帮助我们知道局域网内所有的ip地址和对应的MAC的地址信息的。
具体过程:我是192.168.1.15,我的MAC是XXXX,有谁知道ip是192.168.1.60的MAC地址吗?
我知道,我是192.168.1.60,我的MAC地址是YYYYY。
-
简单说说TCP建立连接的过程
TCP建立连接的目的主要是同步通信双方的序列号,TCP根据这个序列号来组装数据,保证应用层收到的数据是有序的。
建立连接中涉及到的状态转变:
- 客户端发送SYN+ISN(c)以后,状态从 CLOSED 变为 SYN_SENT
- 服务端接收到客户端的数据后,发送SYN+ISN(s) 和 ACK=ISN(c)+1,状态从LISTEN 变为 SYN_RCVD
- ACK是为了通知客户端,客户端的序号同步成功,期待客户端继续发送数据
- SYN+ISN(s) 是为了同步自己的序列号给客户端,用于后续服务端发送数据给客户端
- 客户端收到服务端的数据后
- 状态从 SYN_SENT切换为ESTABLISHED
- 发送ACK=ISN(s) +1的应答给服务端,期待服务端继续发送数据
- 服务端收到ACK响应后,状态从 SYN_RCVD 变为 ESTABLISHED
-
你知道SYN FLOOD攻击吗?
在建立连接的过程中,内核中有两个队列需要参与工作,一个是SYN队列,另一个是accept队列。
当服务端接收到SYN后,会把连接放到SYN队列中,然后发送SYN+ACK,如果收到对端的ACK,就把连接从SYN队列移动到accept队列,等待客户端调用accept方法获取连接。
SYN FLOOD攻击的原理是伪装客户端同时海量发送SYN给服务端,然后就下线,在超时时间内会造成服务端SYN队列耗尽,无法处理正常的连接。
Linux内核提供了tcp_syncookies来应对这种情况,当SYN队列满了以后,会发送一个cookie给对端,如果是正常的连接则会回复,然后就可以建立连接了。
-
简单说说TCP关闭连接的过程
TCP支持单方向关闭连接,主动关闭的一方代表没有数据需要发送过去了,但是可以继续读对端发送过来的的数据。
针对单向关闭的特点,就需要更多的状态来表达,如果是客户端主动关闭连接,状态变更如下:
- 客户端发送FIN:SN(c)/ACK:SN(s) ,状态从ESTABLISHED 变为 FIN_WAIT1
- 服务端收到FIN后,发送ACK:SN(c)+1,状态从ESTABLISHED 变为 CLOSE_WAIT
- 客户端收到ACK后,状态从FIN_WAIT1 变为 FIN_WAIT2
- 服务端应用程序发送完毕调用close函数后,服务端发送FIN给客户端,状态从 CLOSE_WAIT变为 LAST_ACK
- 客户端收到服务端的FIN后,发送ACK,进入TIME_WAIT状态,等待2MSL后,进入CLOSED状态
- 服务端收到客户端ACK后,状态变为 CLOSED
-
主动关闭的一方为什么要等待2*MSL的时间?直接关闭不行吗?
假如直接关闭,并且发送给对端的ACK丢失了,那么对端会重发FIN包,假如又建立了一个四元组相同的连接,后面到来的重发FIN会导致这个新建立的连接被意外关闭。
上面的讨论证明需要等待,那为什么要等待2MSL?
等待2MSL的原因是,发送ACK后,最多需要MSL到达对端,设想一种极端情况,在ACK经过MSL到达对端的前一刻,对端重发FIN,那么等待一个MSL是不够的,还需要再等待一个MSL保证能处理到对端最后发送过来的FIN。
-
谈谈TCP协议的重传机制?
虽然使用序号可以保证有序性,如果没有ACK机制和重传机制,那么就无法保证可靠性,即所有数据都被正确的发送过去,不会丢失。
那么如何判断数据已经丢失需要重传呢?有两种方式:
- 时间驱动判断:超时重传,按照时间判断,在超时后就会判断数据已经丢失,需要重传
- 数据驱动判断:快速重传,是对超时重传的改进,当收到连续三个相同的ACK时,意味着有数据存在丢失,需要重传
那么该发送ACK后所有的数据包?还是只发送ACK对应的丢失的一部分数据包呢?
-
如果重传所有的包,可能存在浪费带宽的可能;
-
如果只重传ACK对应的包,会节省带宽,但如果后续的数据都丢失了,最后还是需要重传所有的数据。
TCP提供了一种SACK的机制来通知哪些数据已经收到了,可以避免重传所有的包。如下图所示,接收方通过SACK可以告知发送方已经收到的数据。
-
TCP的滑动窗口有什么作用?
TCP滑动窗口机制的主要作用是 防止发送方发送的速率大于接收方应用程序处理的速率,导致接收方处理不过来的情况。
发送方的发送缓冲区有四个区域:
- 已经被ACK的
- 发送还未ACK的
- 待发送的
- 不能发送的
接收方收到数据后,会发送接收方当前的可用窗口大小,发送方依照这个窗口调整待发送的数据,即可实现流控。
-
说说什么叫拥塞控制
-
什么是拥塞?在TCP/IP详解卷一中提到,路由器因无法处理高速到达的流量而被迫丢弃数据的现象叫拥塞。
-
为什么需要拥塞控制算法?当TCP检测到丢包时,重传机制会重传数据,但是如果丢包的原因是网络中发生拥塞,那么继续重传会加重拥塞,此时就需要考虑如何减缓网络拥塞。
-
TCP的拥塞控制算法主要关注在识别到拥塞后,如何减速发送以及如何恢复。
-
-
详细说说TCP的拥塞控制算法
除了滑动窗口机制中引入的由接收端控制的窗口(代表了接收端的处理速度)以外,TCP引入了另外一个窗口变量,用于代表网络传输的能力。这两个窗口共同决定了发送窗口的大小
- 滑动窗口
- 拥塞窗口
发送窗口 = MIN(滑动窗口,拥塞窗口)
拥塞控制算法主要关注拥塞窗口的大小。
慢启动算法和拥塞避免算法
慢启动算法:连接新建立或者检测到RTO超时会触发。如果没有ACK延时的情况下,发送方的窗口大小是以指数级别增长的。如果存在延时ACK,发送窗口的大小的指数就会变得很小。
拥塞避免算法:如果cwnd>慢启动阈值,会执行拥塞避免算法。初始的慢启动阈值可以设置的很大,连接都以慢启动开始,直到需要重传,会确定一个新的慢启动阈值。慢启动阈值=max(当前发送窗口的一半,2*MSS)。然后连接重新按照慢启动算法开始,直到窗口大小大于刚才计算出来的慢启动阈值后,进入拥塞避免算法。
在拥塞避免算法下,窗口大小的增长近似线性。
-
一台服务器能支持多少连接,为什么
首先是一个进程可以打开的文件句柄数限制,这个是可以修改的。
然后可以理论分析下,最多支持的并发数:socket是一个四元组,服务器ip和端口确定的情况下,不同的客户端ip和port就可以确定不同的连接。理论上,最大并发连接数 = ip数 * port数 = 2的48次方(32+16)
但实际上呢,最大并发连接数肯定要受到服务器内存,网络带宽等等因素的限制。
-
socket有几个队列
有两个队列,一个发送队列,一个接收队列。因为是全双工的。
相关参考资料:
TCP的那些事(上):https://coolshell.cn/articles/11564.html
TCP的那些事(下):https://coolshell.cn/articles/11609.html
协议森林:https://www.cnblogs.com/vamei/archive/2012/12/05/2802811.html