面经整理:大华C++服务器开发(2021-07-19)

在这里说明一下,整理的面试经历的来源是牛客网,不是我本人的面试经历~

我做这个整理的目的,一是为了自己学习和巩固知识点,再一个是可以让找C++相关工作的朋友,快速过一下知识点。

整理的内容可能出现错误,欢迎指出!

面经来源:https://www.nowcoder.com/discuss/685543?source_id=discuss_experience_nctrack&channel=-1
(侵删)

在这里插入图片描述


自我介绍略


Select和epoll的区别
Select和epoll是IO复用的系统调用函数。它们都可以监控多个描述符,当某个描述符就绪,一般是读就绪或者写就绪,就可以通知程序进行相应的读写操作。
Select:select监控多个描述符,但是描述符就绪以后,你不知道是哪一个描述符就绪了,所以需要通过轮询的方式去找就绪的描述符,然后通知程序进行相应的读写操作。
Epoll:epoll监控多个描述符,一旦某个描述符就绪,它会告诉你是哪个描述符就绪了,就不需要通过遍历的方式来自己找哪个描述符就绪了。时间复杂度相较于select的O(n)降到了O(1)。
介绍一下面向对象的三大特性
继承、多态、封装
继承就是一个类可以通过继承的方式来获得另一个类的属性。继承有三种方式,public、private、protected。

多态就是不同类的对象发出的相同的消息有不同的实现。
多态的实现有静态多态和动态多态。
静态多态:是编译器在编译期的时候就完成了,编译器会根据实参类型来选用合适的函数,假如有合适的函数就调用,假如没有就报错或警告。静态多态主要通过函数重载和模板来实现。
动态多态:在程序运行时,基类的指针指或引用指向子类的对象,来确定使用哪一个类的虚函数。动态多态主要通过虚函数来实现。

封装就是类隐藏了属性和实现细节,仅仅对外开放接口。


TCP参数调优
对于三次握手来说的
开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示SYN Cookies关闭。
Net.ipv4.tcp_syncookies=1

---------以下补充内容-------------
Cookies:简单来说cookies就是浏览器储存在用户电脑上的一小段文本文件。Cookies是纯文本格式,不包含任何可执行的代码。Cookies的本质是一个键值对,由键值key、value构成,键值对之间由一个分号和一个空格隔开,当浏览器访问web服务器的时候写入在客户端机器上,里面记录一些信息。一个web服务器会告知浏览器按照一定规范来储存这些信息,并在随后的请求中将这些信息发送至服务器,Web服务器就可以使用这些信息来识别不同的用户。大多数需要登陆的网站在用户验证成功之后都会设置一个cookie,只要这个cookie存在这个用户,他就可以自由浏览这个网站的任意界面。
SYN攻击原理
SYN攻击属于DOS攻击的一种,它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。
SYN攻击除了能影响主机外,而可以危害路由器、防火墙等网络系统,事实上SYN攻击并不管目标是什么系统,只要这些系统打开TCP服务就可以实施。服务器接收到连接请求(syn=x),将此消息加入未连接队列,并发送ACK+SYN确认包给客户。当服务器未收到客户端的确认包时(第三次握手),重发请求包,一直到超时,才将此条目从未连接队列删除。配合IP欺骗,SYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器不断发送syn包,服务器回复确认包,并等待客户的确认,由于源地址IP是不存在的,服务器需要不断地重发直至超时,这些伪造地SYN包长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络阻塞甚至系统瘫痪。

------------以上补充内容-----------------------------

系统默认的TIMEOUT时间
Net.ipv4.tcp_fin_timeout=5

当keepalive启用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
Net.ipv4.tcp_keepalive_time=1200

表示用于向外连接的端口范围。缺省情况下很小:32768到61000改为10000到65000
Net.ipv4.ip_local_port_range=10000 65000

SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数
Net.ipv4.tcp_max_syn_backlog=8192

系统保持TIME_WAIT最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默认为180000,改为500.
Net.ipv4.tcp_max_tw_buckets=5000


三次握手,四次挥手
三次握手:
客户端和服务器端要建立连接的话要总共发送三段报文,即三次握手。

第一次握手:客户端向服务器端发送一个SYN报文,表示客户端请求与服务器端建立连接。报文中将SYN=1,生成一个序列号syn=x。

第二次握手:服务器端接收到客户端发来的报文,看到SYN=1,服务器就知道客户端想与自己建立连接,所以会发送一个SYN+ACK的确认报文。报文中将SYN=1,ACK=1,ack=x+1,生成服务器自己的序列号seq=y。

第三次握手:客户端收到服务器端发来的确认报文,会发送给服务器一个ACK确认报文,ACK=1,ack=y+1,因为上次客户端发送报文用的序列号seq为x,所以这一次序列号seq=x+1。此时客户端进入连接状态,而服务器收到ACK确认报文无误后也进入连接状态,那么客户端和服务端就建立起了TCP连接。

四次挥手:
客户端和服务器端要释放连接总共要发送四个报文,即四次挥手。

第一次挥手:A想要与B断开连接,就会向A发送一个FIN报文,表明A想要释放连接。将FIN=1,生成一个序列号seq=u;此时A停止发送数据。

第二次挥手:B收到FIN报文后,看到FIN=1,就知道A想与自己断开连接,B将发出一个ACK-FIN确认报文。将ACK=1,ack=u+1,seq=v(之前传送过的数据的最后一个序号+1)。
这个时候TCP进入半连接状态,即A已经没有要发送的数据了,若B还有数据要发送,A仍然会接收。A收到B的确认以后,等待B发送连接释放报文。

第三次挥手:B也已经没有数据要发送了,就向A发送连接释放报文,并等待A的确认。将FIN=1,ACK=1,ack=u+1,生成一个序列号seq=w。

第四次挥手:A收到了B发来的连接释放报文,同样会返回一个ACK确认报文。ACK=1,ack=w+1,seq=u+1(A上一个报文的序列号是u)。此时A等待2MSL时间进入CLOSED状态,而B收到ACK确认报文立即进入CLOSED状态。

MSL:maximum segment(报文) lifetime报文最长存活时间


Vector和map的原理和区别
Vector是动态数组,假如动态数组的内存不够用了,那就重新寻找一块更大的内存,然后把数据拷贝过去,以达到动态扩容的目的。

Map是关联容器,以键值对的形式进行存储,方便进行查找,关键词起到索引的作用,值则表示与索引相关联的数据,以红黑树的结构实现,插入删除等操作都可以在O(logn)时间内完成。

--------------------以下补充内容----------------------
红黑树:红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是red或black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。
红黑树,作为一颗二叉查找树,满足二叉查找树的一般性质。

二叉查找树:二叉查找树,是指一颗空树或者具有下列性质的二叉树:
1 若任何结点的左子树不空,则左子树上所有结点的值均小于它根节点的值;
2 若任何结点的右子树不空,则右子树上所有结点的值均大于它根节点的值;
3 任意结点的左、右子树也是搜索二叉树
4 没有键值相等的结点
因为一颗由n个结点随机构造的二叉查找树的高度为logn,所以顺理成章地,二叉查找树的一般操作的执行时间为O(logn)。

红黑树虽然本质上是一颗二叉查找树,但它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏是O(logn)。
但是它如何保证一颗n个结点的红黑树的高度始终保持在logn的呢?这就引出了红黑树的5个性质:

1 每个结点要么是红的要么是黑
2 根节点是黑色的。
3 每个叶子结点(NULL结点)是黑的,也就是说每个叶子结点都是黑色的空节点,叶子节点不存储数据。
4 如果一个结点是红的,那么它的两个儿子都是黑的;或者说是任意相邻的结点不能同时为红色,即红色结点是被黑色结点隔开的。
5 对于任意结点而言,该结点到叶子结点的每条路径都包含相同数目的黑色结点。

在这里插入图片描述
正是红黑树的这5条性质,使一颗n个结点的红黑树始终保持了logn的高度,从而也就解释了上面所说的红黑树的查找、插入、删除的时间复杂度最坏为O(logn)这一结论成立的原因。

上面提到的叶子结点或NULL结点,它不包含数据而只充当树在此结束的指示,这些结点(叶子结点)在绘图中经常被省略。

红黑树的插入、删除
在插入、删除结点的过程中,第三、四点要求可能会被破坏,即红黑树的插入、删除操作会破坏红黑树的定义,具体来说就是会破坏红黑树的平衡。

左旋
当在某个结点pivot上,做左旋操作时,我们假设它的右孩子Y不是空节点,左旋以pivot到Y之间的链为“支轴”进行,使Y成为该子树的新根,而Y的左孩子变成pivot的右孩子。
在这里插入图片描述
右旋类似
在这里插入图片描述
-----------------以上补充内容-------------------------

Vector和map的区别
1 vector为顺序容器,erase迭代器不仅使所有指向被删元素的迭代器失效,而且使被删元素之后的所有迭代器失效。但是erase的返回值为下一个有效的迭代器,因此可以这样使用:
在这里插入图片描述

Map的erase只是被删元素的迭代器失效了,因此可以这样使用:

在这里插入图片描述

2 map通过key值来查找元素,而vector通过索引来查找元素

3 map没有push_back这样的函数,只有insert依次插入函数,或者直接通过构造函数初始化。


线程通信方式及其应用场景
线程同步和线程互斥
互斥:某一资源同时只允许一个访问者对其进行访问,具有唯一性和排他性。
同步:在互斥的基础上(大多数情况下),通过其他机制实现对资源的有序访问。

线程间通信方式:
1 互斥锁mutex
2 条件变量condition_variable
3 信号量
4 读写锁 shared_lock

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值