科大讯飞--C++开发--面经

2024-09-02 21:44
文章标签 c++ 面经 开发 科大

本文主要是介绍科大讯飞--C++开发--面经,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 互斥锁和自旋锁的区别

互斥锁(Mutex):互斥锁是一种阻塞锁,当某个线程持有锁时,其他试图获取该锁的线程将被阻塞,直到锁被释放。互斥锁加锁失败而阻塞是由操作系统内核实现的,当加锁失败后,内核将线程置为睡眠状态,等到锁被释放后,内核会在合适的时机唤醒线程,当这个线程加锁成功后就可以继续执行。

特性:

  • 原子性:互斥锁的获取和释放是原子的,确保了在多线程环境下对共享资源的安全访问。
  • 休眠等待:当线程无法获取互斥锁时,它会被操作系统挂起并进入休眠状态,不再消耗CPU资源。
  • 上下文切换:线程被挂起时,操作系统会进行上下文切换,以便其他线程得以执行。

适用于锁被持有时间较长或预计等待时间超过两次线程上下文切换时间的场景。

自旋锁(Spinlock):自旋锁是一种非阻塞锁,当线程尝试获取一个被其他线程持有的自旋锁时,该线程会进入忙等待(busy-waiting)状态(一直轮询),即不断地循环检查锁是否可用,而不是被挂起。

特性:

  • 非阻塞:线程在无法获取自旋锁时,不会进入休眠状态,而是持续消耗CPU资源进行忙等待。
  • 无上下文切换:由于线程没有进入休眠状态,因此不会发生上下文切换。
  • 参数限制:为了防止无限循环导致CPU资源耗尽,自旋锁通常有一个参数来限制最大尝试次数。

适用场景:

多核处理器:在多核处理器环境中,如果预计线程等待锁的时间很短,短到比线程两次上下文切换时间要少的情况下,使用自旋锁是划算的。
保持锁时间短:自旋锁比较适用于锁使用者保持锁时间比较短的情况。
中断上下文:如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),则必须使用自旋锁。

互斥锁与自旋锁的比较

  • 资源消耗:互斥锁在线程等待时会释放CPU资源,而自旋锁则会持续消耗CPU资源进行忙等待。
  • 上下文切换:互斥锁在线程等待时会导致上下文切换,而自旋锁则没有。
  • 适用场景:互斥锁适用于锁被持有时间较长或预计等待时间较长的场景;自旋锁适用于锁被持有时间较短或预计等待时间较短的场景。
  • 性能:在多核处理器环境中,如果预计等待时间很短,自旋锁的性能可能优于互斥锁;但在单核处理器或预计等待时间较长的情况下,互斥锁的性能可能更好。

 

 2. static修饰全局、成员、局部变量的区别?

全局变量和被static修饰后的局部变量都在静态区分配内存。

static修饰全局变量

静态全局变量有以下特点:

未经初始化的静态全局变量会被程序自动初始化为0;

静态全局变量在生命它的整个文件都是可见的,而在文件之外是不可见的 

static修饰局部变量

静态局部变量有以下特点:

静态局部变量在编译阶段赋初值,且只赋值一次,在程序运行时它已有初值;

静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;

静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化

static修饰成员变量

 如果一个数据需要被所有对象共享使用的时候,那么即可使用static修饰该成员变量。

静态成员变量要注意的细节:

  1. 静态的成员变量可以使用类名或者是对象进行访问。

  2. 非静态的成员变量只能使用对象进行 访问,不能使用类名直接访问。

  3. 千万不要为了方便访问而使用static修饰一个成员变量,只有这个成员变量的数据是需要被共享的时候才使用static修饰。

 

3. 数据结构有二叉树了,为什么还要平衡二叉树?

二叉树缺点:

  • 一般情况下,查找基于二分查找,查找的时间复杂度为O(logn);
  • 当二叉树不够平衡,甚至退化成类似链表结构的时候,查找的时间复杂度为O(n)。耗时。

平衡二叉树就是为了解决二叉查找树退化成链表。

平衡树具有如下特点:

1、具有二叉查找树的全部特性。

2、每个节点的左子树和右子树的高度差至多等于1。

  • 平衡树基于这种特点-----就可以保证不会出现大量节点偏向于一边的情况了。
  • 关于平衡树如何构建、插入、删除、左旋、右旋等操作这里不在说明

 时间复杂度:对于有 n 个节点的平衡树,最坏的查找时间复杂度也为 O(logn)

 

4. 为什么有了平衡二叉树,还要红黑树?

我画了 20 张图,给女朋友讲清楚红黑树 - 知乎 (zhihu.com)

因为平衡二叉树在增删场景较多的场景下,性能表现不好,涉及到多次左旋、右旋。而红黑树适合插入、删除较多的场景,其性能在插入、删除的场景下表现更好。

虽然平衡树解决了二叉查找树退化为近似链表的缺点,能够把查找时间控制在 O(logn),不过却不是最佳的,因为平衡树要求每个节点的左子树和右子树的高度差至多等于1,这个要求实在是太严了,导致每次进行插入/删除节点的时候,几乎都会破坏平衡树的第二个规则,进而我们都需要通过左旋和右旋来进行调整,使之再次成为一颗符合要求的平衡树。显然,如果在那种插入、删除很频繁的场景中,平衡树需要频繁着进行调整,这会使平衡树的性能大打折扣,为了解决这个问题,于是有了红黑树。

红黑树和平衡树的比较:

1. AVL树比红黑树更为平衡,其搜索效率也好于红黑树, 经过我们之前的分析可以知道, 红黑树在最坏的情况下搜索时间复杂度为2logn,大于AVL树的logn。AVL树是严格平衡,红黑树只能达到“黑平衡”,即从任意节点出发到叶子节点经过的黑节点数量相同,但经过的红色节点数量不确定,最差的情况下,经过的红色节点和黑色节点一样多。

2. 红黑树增删节点的性能优于AVL树,当我们往红黑树增加节点或删除节点引起红黑树不平衡,我们只需要最多三次旋转就能解决,而相同条件下,AVL树的旋转次数要多于红黑树,因此红黑树在增删节点上相较于AVL树更优。

 

5. 为什么 TIME_WAIT 等待的时间是 2MSL?

首先说什么是MSL,TTL,以及两者的关系

MSL就是最大的报文生成时间,MSL是网络报文生存的最长时间,超过这个时间,报文将会被丢弃,因为TCP是基于IP协议的,TTL是经过路由器的最大跳数,每经过一个路由器,TTL就减一,当减到0的时候报文就会被丢弃,同时发送ICMP报文给源主机.

TTL 与 MSL的区别 : TTL是经过路由的最大跳数,MSL是报文生存的最长时间,要确保MSL>=TTL才能保证报文是正常消亡.

为什么要等待2MSL呢 ?

在网络中来自发送方发来的数据报,接收方要给对方一个响应. 这样报文一来一回的时间就是2MSL.

比如当最后一个ACK报文丢失(也就是第四次挥手丢失),服务器那边就会触发超时重传机制,重传FIN报文,当FIN报文到达客户端,客户端再回一个ACK响应,这样一来一回等待的时间是2MSL.

2MSL时长允许报文至少丢失一次,当ACK报文丢失的时候,重发的FIN会在第二个MSL到达客户端,这样TIME_WAIT状态就可以应对.2MSL是当第三次挥手到达客户端的时候就会开始计时,当中途FIN报文再次到达客户端,定时器就会被重置为2MSL.

答:MSL就是maximum segment lifetime(最大报文段的生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失(被丢弃)。RFC 793中规定MSL为2分钟,实际应用中,可能为30S,1分钟,2分钟。

为什么不是 4MSL或者8MSL呢 ?

由于丢包概率很小,加入丢包概率为1/100,那么第二次丢包就是1/10000, 所以我们可以忽略,性价比会更高。

 

6. 服务端会出现timewait状态吗?

会。TIME_WAIT 是主动断开连接的一方会出现的,客户端,服务器都有可能出现。

 

7. 出现大量的timewait状态怎么处理

短时间内大量TIME_WAIT出现的根本原因:高并发且持续的短连接

  1. 业务上使用了持续且大量的短连接,纯属设计缺陷,例如爬虫服务器就有可能出现这样的问题
  2. http请求中connection的值被设置成close,因为服务器处理完http请求后会主动断开连接,然后这个连接就处于TIME_WAIT状态了。持续时间长且量级较大的话,问题就显现出来了。http协议1.0中,connection默认为close,但在http1.1中connection默认行为是keep-alive,就是因为这个原因
  3. 服务器被攻击了,攻击方采用了大量的短连接

重点:解决办法

1. 代码层修改,把短连接改为长连接,但代价较大

2. 修改 ip_local_port_range,增大可用端口范围,比如1024 ~ 65535

3. 客户端程序中设置socket的 SO_LINGER 选项

4. 打开 tcp_tw_recycle 和tcp_timestamps 选项,有一定风险,且linux4.12之后被废弃

5. 打开 tcp_tw_reuse 和 tcp_timestamps 选项

6. 设置 tcp_max_tw_buckets 为一个较小的值

8. 哈希表插入元素一般有哪几个重要的步骤

这篇关于科大讯飞--C++开发--面经的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131155

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名