Linux网络开发常见面试题【备战春招秋招】

前言:

该文章只针对面试时面试官提问如何回答的更全更好,看此文章没有讲解太多太细节的知识点。如果知识点本身不会,背诵此文章可能能让你找到一份工作,但不能让你持续的干下去。还是需要自身精通对应知识点。

该文章适合有学习过TCP/UDP协议以及Linux基础的朋友阅读,主要是针对本科应届生。收录了十几道近几年非常经典的网络面试题。

配合 C语言常见面试题 与 C++常见面试题 更容易帮您找到一份应用层开发工作

一、说出OSI七层协议模型,并简述各层的功能

1. 物理层(Physical Layer):负责传输比特流,定义物理连接的特性。

2. 数据链路层(Data Link Layer):提供可靠的数据传输,处理帧的传输和错误检测。

3. 网络层(Network Layer):负责数据包的路由和转发,实现不同网络之间的通信。

4. 传输层(Transport Layer):提供端到端的数据传输,确保数据可靠传输,处理数据分段和重组。

5. 会话层(Session Layer):建立、管理和终止会话连接,处理会话层的控制和同步。

6. 表示层(Presentation Layer):处理数据的格式和编码,确保数据在不同系统间的兼容性。

7. 应用层(Application Layer):提供用户接口和网络服务,实现特定应用程序的功能

二、说出TCP/IP四层协议族,以及每层有哪些协议

标红的协议为重点记忆协议

1、物理与网络接口层

        以太网协议:是一种广泛应用于局域网(LAN)和广域网(WAN)的计算机网络通信协议。它是一种基于共享介质的局域网技术。数据包内容包含源MAC地址、目标MAC地址、数据包类型、长度等信息。

        PPP(点对点协议):主要是用来通过拨号或专线方式在两个网络节点之间建立连接、发送数据。PPP是各类型主机、网桥和路由器之间简单连接的一种解决方案。

2、网络层

        IP(网间协议):设计IP的目的是提高网络的可扩展性,能适应异构网络,IP强调适应性、简洁性和可操作性,并在可靠性做了一定的牺牲。IP不保证分组的交付时限和可靠性,所传送分组有可能出现丢失、重复、延迟或乱序等问题。

        ICMP(网际控制消息协议):主要处理在路由器和主机之间流通的错误和控制信息。判断网络能否和对面建立连接(ping指令)。

        IGMP(网际组管理协议):主要用于多播。

        ARP(地址解析协议):可以根据IP地址获取物理地址。(向子网中广播一个消息:“IP地址为a.b.c.d的系统亮明身份,告诉我你的硬件地址”。使用的是数据链路层的广播)

        RARP(反向地址转换协议):局域网的物理机器从网关服务器的 ARP 表或者缓存上请求其 IP 地址。

注意:ARP与RARP在OSI七层协议中属于被划分为数据链路层的协议

3、传输层

        TCP(传输控制协议):提供可靠的、面向连接的数据传输服务,确保数据的可靠性和顺序性。基于数据流的通信方式。

        UDP(用户数据报协议):提供无连接的数据传输服务,适用于实时性要求高的应用。基于数据报的通信方式。

        SCTP(流控制传输协议):与TCP类似的可靠传输协议,提供消息边界、传输级别多宿支持。

4、应用层

        HTTP(超文本传输协议):主要是应用于WEB端内容获取,展示网页数据。另外HTTPS协议是HTTP协议基础之上增加了SSL加密。

        FTP(文件传输协议):用于文件传输,底层基于TCP实现。

        TFTP(简单文件传输协议):用于文件传输,底层基于UDP实现。

        SMTP(邮件传输协议):用于在邮件服务器之间传输电子邮件。

三、简述二层交换机的工作原理

        首先二层交换机主要用于在局域网中数据的转发。两台主机可以通过连接同一个交换机进行通信。主机A要想与主机B通信需要先知道对方的IP地址,接着根据两方的IP地址通过子网掩码判断是否在同一个局域网内,若在同一个局域网,则主机A需要获取主机B的MAC地址,此时主机A会发送ARP协议广播,请求主机B的MAC地址,交换机收到ARP的广播后会转发给所有连接在交换机的主机上,主机B收到此广播后会进行回应,告知主机A自己的MAC,主机A收到回应后便会构建出完整的数据包,再次发送数据给交换机,交换机收到数据后,可以查询交换机自己的网口映射表,判断与该MAC地址相连的对应网口,将数据包转发给主机B。

        注意网口映射表是当主机发送数据给交换机时,交换机会根据当前的网口与数据包中的源MAC地址,对网口与MAC地址做的映射。这样可以通过数据包中的目标MAC来判断该数据包要通过哪个网口转发。

        如果在通信过程中,网线发生过插拔,更换网口,导致交换机映射表对应的MAC地址丢失,再次收到发送给此MAC地址的数据包时,交换机会将此数据包转发给所有连接交换机的主机,此现象被称为“泛洪”。交换机会按周期更新网口映射表。

四、简述路由器的工作原理?简述数据包发送出去的流程

        是连接两个或多个网络的硬件设备,在网络间起网关的作用,是读取每一个数据包中的地址然后决定如何传送的专用智能性的网络设备。

        假设我们电脑需要访问百度服务器。在我们输入网址www.baidu.com时,首先会先请求DNS服务器,获取百度的ip地址。接着会通过子网掩码判断百度的ip与自己的ip是否在同一个网段,因为百度在外网,所以不在同一个网段。那么我们主机就需要将数据包发送给网关,也就是路由器,数据包中的对方MAC地址填写为路由器的MAC地址。路由器收到此数据包后发现该数据包要对外,先进行NAT端口映射(该功能较为复杂,这里只讲一个最简单的)。NAT端口映射将数据包的源ip与源端口映射成一个新的端口号,保存到路由器的端口映射表中,再将映射后的端口填写到源端口上,将路由器的公网ip填写到源ip上查询路由表找到与自己相连且距离百度服务器最近的路由器,将数据包中的目标MAC改为此路由器的MAC地址,也就是下一跳的MAC地址,源MAC改为自己路由器的MAC,将此数据包转发给下一个路由器。后面的路由器也都查询自己的路由表,转发给下一个路由器,直到发送给百度服务器。百度回发的数据包最终回到自己的路由器上,此时百度回的数据包目标ip写的是路由器公网ip,目标端口是映射后的端口,目标MAC是路由器的MAC地址路由器收到此数据包后查询自己的端口映射表,将目标ip改为主机的内网ip,目标端口改为主机端口,目标MAC也改为主机的MAC地址,再将此数据包发送给主机。

        虽然看着写了很多文字,但依然是最简单的一种介绍,路由器本身协议的控制远比写的复杂,这里只简单介绍了路由器最核心的两个功能的使用:NAT与路由表

五、什么是高可靠通信?

        指传输时数据无差错、无丢失、无失序、按时到达故障的可靠通知

六、TCP三次握手与四次挥手的过程

三次握手:

1、服务器首先通过socket()创建套接字,bind()绑定自己的地址与端口,接着调用listen()进行监听,此时处于LISTEN状态。内核会生成两个队列,一个未完成连接请求队列,一个已完成请求连接队列,两个队列长度之和与listen()函数第二个参数相关(在Ubuntu中,该长度等于listen第二个参数+1)。accept()函数调用将监控已完成连接队列是否包含连接。

2、客户端也先通过socket()创建套接字,可以不进行bind()(内核会自动分配ip与端口),调用connect()发起通信,第一个握手请求包中,SYN标志位置为1,同时生成一个自己的序列号seq,假设为x,同时包含自己最大能接收数据大小,防止服务器数据包过大无法接收(流量控制),此包发送给服务器后,客户端进入SYN_SENT状态

3、服务器收到握手请求数据包后将该请求放入未完成队列中,并回发数据包,数据包中首先对发来的数据应答,所以标志位ACK置为1,应答序列号ack为x+1,连接是双向的,所以第二个数据包也是服务器请求数据包建立连接,标志位SYN也要置为1,同时服务器生成一个自己的序列号seq为y,并且发送服务器能够最大接收数据包的数据大小。发送完成后服务器进入SYN_RCVD状态

4、客户端收到第二个握手包后,connect()函数返回,此时发送最后一个握手包,是对服务器的请求进行应答,该数据包中ACK置为1,ack为y+1发送完成后客户端进入ESTABLISHED状态,可以开始通信。

5、服务器收到第三个握手包后,验证通过,进入ESTABLISHED状态。再将该请求从未完成连接队列中取出,放入已完成请求连接队列中。此时accept()函数监控到已完成队列中存在请求,并将此请求取出,生成一个新的连接通信套接字,服务器便通过此套接字与客户端进行通信。

四次挥手:

0、首先挥手时客户端和服务器都可以主动发起挥手请求但一般都是由客户端主动发起,为了严谨,此处分为主动发起方与被动发起方

1、主动方可以通过调用close()或shutdown()函数发起挥手请求,此时由于不会再发送数据,内核层写缓冲区将被回收,同时像服务器发送第一个挥手包,其中标志位FIN置为1,seq序列号假设为y,并将状态改为FIN_WAIT_1状态。(注意close()和shutdown()两个函数为非阻塞,调用完成后,后面挥手部分由内核自主完成,若想自己监控可以配置对应属性)

2、被动方收到挥手请求后说明主动方不再发送数据,此时会关闭读缓冲区,若此时在进行read()函数,那么将返回0,并检测当前写缓存是否还有数据未发送完成,若有,则先回发应答数据包,ACK=1,确认序列号ack=y+1,最后将状态置为CLOSE_WAIT

3、主动方收到应答后会将状态置为FIN_WAIT_2,等待被动方发送挥手请求

4、被动方发送完应答包后,将写缓存内数据全部发送给主动方,再主动调用close()或shutdown()函数,发送挥手请求数据包,标志位FIN置为1,seq假设为z。回收自己的写缓冲区,并将状态改为LAST_ACK

5、主动方收到此数据后,回发应答数据包ACK=1,ack=z+1,回收自己的读缓冲区,并将状态置为TIME_WAIT,此状态持续2msl(两倍报文最大生命时长),后彻底关闭套接字,置为CLOSE状态

6、被动方收到应答数据包后将关闭套接字,置为CLOSE状态

注意:

1)若被动方收到第一个挥手包时发现写缓存并没有数据,则应答包可以和挥手请求包合并发送,

2)TIME_WAIT的存在主要有两个原因,由于网络本身不可靠,挥手最后一个ACK应答包可能会丢失,假设这个包丢失后,被动方会再次发送一个FIN挥手请求包,此时如果主动方已经关闭连接,则被动方会认为连接出错。在相同的两个端可能在断开连接后紧接着再次握手连接,这时上次通信中的迷途数据包到达此端口则会被认为是这次的数据包。等待2MSL也可以让网络中所有的迷途数据包消亡,则不会影响后面的通信

加粗部分为最少要记部分

七、TCP与UDP的区别有哪些?

TCP与UDP都是传输层协议

TCP基于数据流传输,通信需要建立连接,为点对点的通信,保证数据安全可靠,保证数据按序到达,无丢失,无差错,按时到达,属于高可靠通信。本身存在三次握手、四次挥手、流量控制、出错重传等机制,且存在粘包现象。

UDP基于数据报传输,不保证数据包能送达,不保证数据包内容正确,但是有边界保护,不会产生粘包,且通信不需要建立连接,可以进行一对多的通信,传输速率快

扩展:如何使用UDP实现可靠传输?

在应用层对UDP进行封装,模拟TCP的数据包,添加序列号保证数据顺序正确,增加数据签名与验签保证数据包内容正确,并且要求收到数据包进行应答,对应答数据做校验,增加出错重传机制即可。

八、编写TCP服务器与客户端的代码框架

九、TCP如何判断对方异常断电?

        TCP异常断电后是不会发送挥手数据包的,如果不做处理会导致对方套接字一直是开启状态,可以增加超时检测或增加心跳包功能,一段时间内未收到对方数据包则发送心跳包确认对方是否在线。

十、简述三种超时检测的办法

        1、通过setsockopt()函数设置套接字属性。设置的是fd,5秒没有获取数据则read()会返回-1报错

struct timeval tm = {5,0};
if (setsockopt(fd, soL_SOCKET,SO_RCVTIMEO,&tm,sizeof(tm)) < 0) {
    perror("timeout");
    exit(-1);
}

        2、通过select、poll、epoll多路复用机制附带的定时器完成,注意不可与设置套接字属性同时设置超时。以下为select函数举例

fd_set fds;    //定义位图
FD_ZERO(&fds);    //位图清空
FD_SET(fd, &fds);    //将需要检测的文件描述符fd插入到位图中
struct timeval tm = {5, 0}; //设置定时器 为5秒
if (select(fd + 1, &fds, NULL, NULL, &tm) == 0) {  //等于0超时,小于0报错,大于0表示fd可读
    //超时处理  注意select每次使用后都要重新更新fds与tm
}

        3、通过信号定时器完成,使用setitimer()函数启动定时器,定时器到时后会触发SIGALRM信号。这里不多赘述,本质上与文件描述符无关,只是单纯的定时器。

十一、什么是粘包?如何解决粘包带来的问题

        TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。主要原因是来自接收方。

        发送方会将连续发送的数据包使用Nagle算法拼接到一起发送,针对发送方可以设置套接字属性关闭此算法,不过我们一般不使用此方法解决该问题。

        接收方收到数据如果没有来的及读,那么大量数据会堆积到读缓存中,读取时会一次读取多个数据包数据(也有可能是半个数据包数据),接收方发生粘包时无法在传输层解决,只能在应用层解决。

解决方法:

格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。

发送长度发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置

我们一般使用发送长度的方案

注意UDP与SCTP是有边界保护,每次读取都是一个数据包的内容,不存在粘包现象

十二、简述两种并发服务器的设计,并说明其优缺点以及容易出现的问题

1、迭代服务器(不是并发)。编写方便,功能基础,适合单个客户端通信,体量小,但不能并发。

2、多进程服务器。每个进程独立解决通信问题,性能高,可以进行并发,但是进程占用空间大,对服务器内存和性能要求高,回收进程资源麻烦。

3、多线程服务器。每个线程独立解决通信问题,性能也较高,也可以进行并发,但是线程间交互容易产生问题,线程管理需要使用线程池、锁之类的技术,对程序员技术要求高。

4、多路复用。可以进行并发,耗费性能低,但是每个任务时间必须短,不能处理长时间任务。

高性能服务器的设计可以让线程池与多路复用联合使用。提高性能同时也可以处理长时间业务,降低系统的损耗

十三、简述HTTP get请求与post请求的区别

        GET方法是默认的HTTP请求方法,我们日常用GET方法来提交表单数据,然而用GET方法提交的表单数据中经过简单的编码,同时它将作为URL的一部分向Web服务器发送

        POST方法是GET方法的一个代替方法,它主要向Web服务器提交表单数据,尤其是大批量的数据,通过POST方法提交表单数据时,数据不是作为URL请求的一部分而是放到附属体里作为标准数据发送给服务器

 区别

        1、POST数据不会被缓存、不会保存在服务器日志以及浏览器浏览记录中

        2、POST包含更多的头部行,为了描述附属体内的数据

        3、POST在真正接收数据之前会先将头部行发送给服务器确认,然后才真正发送数据

注意

        POST与GET在数据包传输过程中安全性是一样的,除非是用HTTPS协议,对数据包进行SSL加密。

        大部分浏览器会对URL(网址)长度做限制,导致提交大批量数据时无法使用GET,只能使用POST协议,但HTTP协议并未对网址长度做出限制

结语

编写该文章目的主要为想从事相关工作的同学找到一份好的工作,以上题目在面试中经常出现,如果有在外面试的朋友发现有更常见更经典的题目也可以私信告知,后续也会更新到博客当中。

如果有朋友想系统的学习嵌入式相关知识从事相关的行业,可以私信我,有一些经典的电子档书籍资料和开源网课学习链接。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值