C++面试问题总结——(CPP基础、网络编程)

1. main 函数 执行前 和执行后会执行什么?

【答】main 函数执行之前,主要是初始化系统相关的资源以及函数的初始化工作

  1. 设置栈指针
  2. 初始化static 静态和global 全局变量,即data段的内容
  3. 将还没有初始化的全局变量进行赋值,eg:数值型 short int long 等为0,bool 为false 指针为null,等等,即 bss段
  4. 运行全局构造器,进行 C++ 中的函数构造
  5. 将main 函数的参数,argc,argv 等传递给main函数,才能 真正运行

main 函数执行之后,会运行 全局对象的析构函数
可以用_oneexit 注册一个 函数,它会在main 之后 执行

如果你需要加入一段在main退出后执行的代码,可以使用atexit()函数,注册一个函数。


2. 网络粘包问题

参考 :https://blog.csdn.net/zhangxinrun/article/details/6721495

2.1 长连接 和 短连接

【答】

  1. 长连接
    client 与 server 建立连接后不断开 ,然后再进行 报文发送和 报文接受
  2. 短连接
    client 与 server 每一次进行报文通讯时才进行连接建立,交易完毕后立即断开连接,适用于一点对多点的通讯,例如多个client 与 一个 server

2.2 什么时候需要考虑粘包问题?

  1. 如果利用tcp 每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题
    1.1 因为只有一种包结构,类似于http协议,关闭连接主要要双方都发送 close 连接。
  2. 如果发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接受存储就ok,也不用考虑粘包
  3. Ding~~ 如果双方建立建立,需要在连接后一段时间内发送不同的数据结构,所以一般需要在 头 加上 一个数据长度之类的包,以确保接受。

2.3 粘包出现原因:

在流传输中,udp 不会出现粘包,因为它有消息边界(参考windows 网络编程)


  1. 发送端需要等缓冲区满才发送出去,会造成粘包
  2. 接受方不及时接受缓冲区的包,造成多个包接受

2.4 解决方法

  1. 对于发送方引起的粘包现象,用户可通过编程设置类避免,TCP提供了强制数据立即传送的push 指令,也就是说不必等着 缓冲区满才发送出去,
  2. 对于接受方引起的粘包,则可以通过优化程序设计,精简接受进程工作量,提高接受进程优先级等措施,使其及时接受数据,从而避免出现粘包问题,
  3. 由 接受方控制,将一包数据按结构 字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包

以上提到的三种措施,都有其不足之处。
第一种编程设置方法虽然可以避免发送方引起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使用。

第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接收,从而导致粘包。

第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的场合不适合。

2.5 网络现象解释

A.先接收到data1,然后接收到data2.
B.先接收到data1的部分数据,然后接收到data1余下的部分以及data2的全部.
C.先接收到了data1的全部数据和data2的部分数据,然后接收到了data2的余下的数据.
D.一次性接收到了data1和data2的全部数据.

为什么会出现B.C.D的情况.
"粘包"可发生在发送端也可发生在接收端.

1.由Nagle算法造成的发送端的粘包:Nagle算法是一种改善网络传输效率的算法.简单的说,当我们提交一段数据给TCP发送时,TCP并不立刻发送此段数据,而是等待一小段时间,看看在等待期间是否还有要发送的数据,若有则会一次把这两段数据发送出去.这是对Nagle算法一个简单的解释,详细的请看相关书籍.象C和D的情况就有可能是Nagle算法造成的.

注: Nagle算法 用于自动连接许多的小缓冲器消息;这一过程(称为nagling)通过减少必须发送包的个数来增加网络软件系统的效率。

2.接收端接收不及时造成的接收端粘包:TCP会把接收到的数据存在自己的缓冲区中,然后通知应用层取数据.当应用层由于某些原因不能及时的把TCP的数据取出来,就会造成TCP缓冲区中存放了几段数据.

2.6 UDP 会出现粘包问题吗?

【答】

  1. 对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。所以UDP不会出现粘包问题

2.7 保护消息边界和流

参考:https://blog.csdn.net/tiandijun/article/details/41961785


保护消息边界和流

那么什么是保护消息边界和流呢?

保护消息边界,就是指传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息。也就是说存在保护消息边界,接收端一次只能接收发送端发出的一个数据包。而面向流则是指无保护消息保护边界的,如果发送端连续发送数据,接收端有可能在一次接收动作中,会接收两个或者更多的数据包。

例如,我们连续发送三个数据包,大小分别是2k,4k ,8k,这三个数据包,都已经到达了接收端的网络堆栈中,如果使用UDP协议,不管我们使用多大的接收缓冲区去接收数据,我们必须有三次接收动作,才能够把所有的数据包接收完.而使用TCP协议,我们只要把接收的缓冲区大小设置在14k以上,我们就能够一次把所有的数据包接收下来,只需要有一次接收动作。

注意:

这就是因为UDP协议的保护消息边界使得每一个消息都是独立的。而流传输却把数据当作一串数据流,他不认为数据是一个一个的消息。所以有很多人在使用tcp协议通讯的时候,并不清楚tcp是基于流的传输,当连续发送数据的时候,他们时常会认识tcp会丢包。其实不然,因为当他们使用的缓冲区足够大时,他们有可能会一次接收到两个甚至更多的数据包,而很多人往往会忽视这一点,只解析检查了第一个数据包,而已经接收的其他数据包却被忽略了。所以大家如果要作这类的网络编程的时候,必须要注意这一点。


3. 内存池的设计

参考 STL源码解析 ,其中有对 STL 内存池的介绍

4. 网络编程中的加密算法

4.1 如何解决数据传输的安全问题?

4.2 加密算法

猜你喜欢

转载自blog.csdn.net/shaoye_csdn1/article/details/90634806