【Q1—45min】

1.epoll除了边沿触发还有什么?与select区别.
epoll 是Linux平台下的一种特有的多路复用IO实现方式,与传统的 select 相比,epoll 在性能上有很大的提升。
epoll是一种当文件描述符的内核缓冲区非空的时候,发出可读信号进行通知,当写缓冲区不满的时候,发出可写信号通知的机制.

epoll的工作方式:水平触发 LT 和 边沿触发 ET(默认)
(1)水平触发(level-trggered):
只要文件描述符关联的读内核缓冲区非空,有数据可以读取,就一直发出可读信号进行通知,
当文件描述符关联的内核写缓冲区不满,有空间可以写入,就一直发出可写信号进行通知
(2)边缘触发(edge-triggered):
当文件描述符关联的读内核缓冲区由空转化为非空的时候,则发出可读信号进行通知.
当文件描述符关联的内核写缓冲区由满转化为不满的时候,则发出可写信号进行通知.
(边缘触发需要一次性的把缓冲区的数据读完为止,也就是一直读,直到读到EGAIN为止,EGAIN说明缓冲区已经空了,因为这一点,边缘触发需要设置文件句柄为非阻塞
二者的区别:水平触发是只要读缓冲区有数据,就会一直触发可读信号,而边缘触发仅仅在空变为非空的时候通知一次。

1. 用户态将文件描述符传入内核的方式
select:创建3个文件描述符集并拷贝到内核中,分别监听读、写、异常动作。这里受到单个进程可以打开的fd数量限制,默认是1024。
poll:将传入的struct pollfd结构体数组拷贝到内核中进行监听。
epoll:执行epoll_create会在内核的高速cache区中建立一颗红黑树以及就绪链表(该链表存储已经就绪的文件描述符)。接着用户执行的epoll_ctl函数添加文件描述符会在红黑树上增加相应的结点。
【select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。】
2. 内核态检测文件描述符读写状态的方式
select:采用轮询方式,遍历所有fd,最后返回一个描述符读写操作是否就绪的mask掩码,根据这个掩码给fd_set赋值。
poll:同样采用轮询方式,查询每个fd的状态,如果就绪则在等待队列中加入一项并继续遍历。
epoll:采用回调机制。在执行epoll_ctl的add操作时,不仅将文件描述符放到红黑树上,而且也注册了回调函数,内核在检测到某文件描述符可读/可写时会调用回调函数,该回调函数将文件描述符放在就绪链表中。
【select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。】
3. 找到就绪的文件描述符并传递给用户态的方式
select:将之前传入的fd_set拷贝传出到用户态并返回就绪的文件描述符总数。用户态并不知道是哪些文件描述符处于就绪态,需要遍历来判断。
poll:同select方式。
epoll:epoll_wait只用观察就绪链表中有无数据即可,最后将链表的数据返回给数组并返回就绪的数量。内核将就绪的文件描述符放在传入的数组中,所以只用遍历依次处理即可。这里返回的文件描述符是通过mmap让内核和用户空间共享同一块内存实现传递的,减少了不必要的拷贝。
epoll原理:
1.通过调用epoll_create,在epoll文件系统建立了个file节点,并开辟epoll自己的内核高速cache区,建立红黑树,分配好想要的size的内存对象,建立一个list链表,用于存储准备就绪的事件。
2.通过调用epoll_ctl,把要监听的socket放到对应的红黑树上,给内核中断处理程序注册一个回调函数,通知内核,如果这个句柄的数据到了,就把它放到就绪列表。
3.通过调用 epoll_wait,观察就绪列表里面有没有数据,并进行提取和清空就绪列表,非常高效。
一般来说以下场合需要使用 I/O 多路复用:
A.当客户处理多个描述字时(一般是交互式输入和网络套接口);
B.如果一个服务器既要处理 TCP,又要处理 UDP,一般要使用 I/O 复用;
C.如果一个 TCP 服务器既要处理监听套接口,又要处理已连接套接口.

2.linux pwd cat.touch区别
(1)pwd命令 – 显示当前工作目录的路径
pwd是Linux中一个非常有用而又十分简单的命令,pwd是词组print working directory的首字母缩写,即打印工作目录;工作目录就是你当前所处于的那个目录。
pwd始终以绝对路径的方式打印工作目录,即从根目录(/)开始到当前目录的完整路径。在实际工作中,我们常常记不起当前目录的完整路径,此时pwd命令就派上用场了。
(2)touch和cat命令的区别
touch命令和cat命令的共同点就是都能创建文件,那么区别就只能从这里说起。但他们的功能不仅如此。
如果文件不存在:touch命令仅创建文件,cat>命令创建文件并输入;
如果文件存在:touch命令更新文件的日期时间,cat>命令清空文件并输入。

3.内联函数
inline 修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。

4.C++11特性
(1)统一的列表初始化 {}适用于各种STL容器
(2)类型推导 auto 和 decltype的出现
A.auto 关键字的作用在编译阶段对于=右边的对象进行自动的类型推导。C++11中已经去除了C++98中auto声明自动类型变量的功能,只可以用来进行变量类型推导。所以就要求我们必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。并且auto仅仅只是占位符,编译阶段编译器根据初始化表达式推演出实际类型之后会替换auto。
B.decltype的出现是为了补齐auto 不支持对于表达式的类型推导的缺陷的, 经常适用于后置返回类型的推导. decltype是C++11新增的一个类型说明符,它可以用来获取一个表达式的类型。
C.考虑到NULL底层被定义成字面量0,这样就可能回带来一些问题,因为0既能指针常量,又能表示整形常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。
(3)右值引用移动语义 (特别重要的新特性)
顾名思义,对左值的引用就是左值引用, 对于右值的引用就是右值引用。
定义左值和右值的区别:可否进行取地址, 可以取地址的就是左值, 不可以取地址的就是右值
定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址, 所以本质还是左值.
结论:const 左值引用既可以引用左值也可以引用右值,右值引用 就只能引用右值不可以引用左值。
std::move() 方法可以将左值转换为右值。
(4)万能引用 + 完美转发:在过程中保持住右值属性不退化
万能引用: 就是 既可以引用左值 也可以引用右值
模板中的&& 万能引用
(5)可变参数模板 (参数包)
C++11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板,相比 C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数无疑是一个巨大的改进。然而由于可变模版参数比较抽象,使用起来需要一定的技巧,所以这块还是比较晦涩的。
简单的理解可以理解为一个参数包, 可以支持传入数量不固定的参数, 而且还是模板, 使用起来更加的灵活。
(6)emplace_back 的出现和对比分析 push_back接口 emplace_back 是结合这可变模板参数出现的。
在这里插入图片描述
(7)Lambda表达式
其实 lambda表达式的底层处理就是完全处理成了仿函数的.
在这里插入图片描述
(8)包装器 (适配器) (function包装器)
function 是 C++中的类模板, 也是一个包装器.
说到包装器, 首先就要思考函数指针, 仿函数, Lambda表达式
上章就提到了三者底层可能差不大多, 使用的情景也是各有雷同, 包装器其实就可以算是将上述三者进行一个统一, 适配成一个东西 如下: function 包装器可以实现对三者的统一包装。
包装器的好处:统一了可调用对象的类型, 并且指定了参数和返回值类型。
1. 简化了函数指针这样的复杂指针的使用, 函数指针复杂难以理解
2. 方便了作为参数时候的传入
3. 仿函数是一个类名没有指定参数和返回值需要知道就需要去看这个operator () 重载获取
4. lambda 在语法层, 看不到类型, 底层存在类型, 但是也是lambda_uuid, 也很难看
function出现的最最重要的原因就是有了一个确切的类型, 使用简单方便,
解决函数指针使用复杂的问题, 解决仿函数不能指定参数类型的问题, 要知道参数类型还要跑去看哪个operator() 以及解决 lambda没有具体类型的问题.
(9)线程库
(10)原子操作
多线程最主要的问题是共享数据带来的问题(即线程安全)。如果共享数据都是只读的,那么没问题,因为只读操作不会影响到数据,更不会涉及对数据的修改,所以所有线程都会获得同样的数据。但是,当一个或多个线程要修改共享数据时,就会产生很多潜在的麻烦。
//多线程对于共享数据的写操作带来的问题…
解决上述问题的方式1: 在 C++98 中采取的是加锁的方式实现避免函数的重入问题,
lock();
操作临界资源 (写入操作)
unlock();
加锁确实是可以解决上述的问题, 但是不停的解锁解锁, 效率会变得特别低,时间消耗也会大大增加,不停的加锁解锁,虽然也解决了问题,保护了临界资源,但是程序运行时延性大大增加,而且对于锁控制不好还会死锁,于是C++11 搞出来一个原子操作。
所谓原子操作:即不可被中断的一个或一系列操作,C++11引入 的原子操作类型,使得线程间数据的同步变得非常高效。
有了原子操作数据, 确实针对这些数据的操作不再需要加锁保护了, 但是如果是一段代码段的原子操作, 就还是不得不使用锁来实现, 但是只要设计到锁就可能发生死锁, C++11为了预防死锁,C++11采用RAII的方式对锁进行了封装,即lock_guard和unique_lock。

5.map底层
std map是STL的一个关联容器,map中的元素是关键字----值的对(key–value):关键字起到索引的作用,值则表示与索引相关联的数据。每个关键字只能在 map中出现一次。STL的map底层是用红黑树实现的,查找时间复杂度是log(n)。

6.指针与引用的区别
指针:指针就是内存地址,指针变量是用来存放内存地址的变量.不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。
引用:引用不是新定义一个变量,而是给已存在变量取一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间.
类型& 引用变量名= 引用实体; 且引用类型必须和引用实体是同种类型的.
引用的主要用途是:修饰函数的形参和返回值.
指针与引用的区别:
(1)初始化:引用在定义时必须初始化,指针则没有要求(尽量初始化,防止野指针)。
(2)引用在初始化引用一个实体后,就不能再引用其它实体,而指针可以在任意时候指向一个同类型实体。
(3)没有NULL引用,但是有nullptr指针.
(4)在sizeof中含义不同: 引用结果为引用类型的大小,但指针始终是地址空间,所占字节个数(32位平台占4个字节)。
(5)引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小。
(6)有多级指针,但没有多级引用。
(7)访问实体的方式不同,指针需要显式解引用,引用编译器自己处理。
(8)引用比指针使用起来相对安全。

7.锁相关的。
(1)读写锁
A.多个读者可以同时进行读;
B.写者必须互斥(只允许一个写者写,也不能读者写者同时进行);
C.写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者).
(2)互斥锁
一次只能一个线程拥有互斥锁,其他线程只有等待。
可以避免多个线程在某一时刻同时操作一个共享资源,标准C++库提供了std::unique_lock类模板,实现了互斥锁的RAII惯用语法:
std::unique_lockstd::mutex lk(mtx_sync_);
(3)条件锁
条件锁就是所谓的条件变量,某一个线程因为某个条件未满足时可以使用条件变量使该程序处于阻塞状态。一旦条件满足了,即可唤醒该线程(常和互斥锁配合使用),唤醒后,需要检查变量,避免虚假唤醒。
互斥锁一个明显的缺点是他只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,他常和互斥锁一起使用,以免出现竞态条件。当条件不满足时,线程往往解开相应的互斥锁并阻塞线程然后等待条件发生变化。一旦其他的某个线程改变了条件变量,他将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。总的来说互斥锁是线程间互斥的机制,条件变量则是同步机制。
(4)自旋锁(不推荐使用)
如果进线程无法取得锁,进线程不会立刻放弃CPU时间片,而是一直循环尝试获取锁,直到获取为止。如果别的线程长时期占有锁,那么自旋就是在浪费CPU做无用功,但是自旋锁一般应用于加锁时间很短的场景,这个时候效率比较高。
自旋锁是一种基础的同步原语,用于保障对共享数据的互斥访问。与互斥锁的相比,在获取锁失败的时候不会使得线程阻塞而是一直自旋尝试获取锁。当线程等待自旋锁的时候,CPU不能做其他事情,而是一直处于轮询忙等的状态。自旋锁主要适用于被持有时间短,线程不希望在重新调度上花过多时间的情况。实际上许多其他类型的锁在底层使用了自旋锁实现,例如多数互斥锁在试图获取锁的时候会先自旋一小段时间,然后才会休眠。如果在持锁时间很长的场景下使用自旋锁,则会导致CPU在这个线程的时间片用尽之前一直消耗在无意义的忙等上,造成计算资源的浪费。

8.线程和进程的区别
进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序计数器、寄存器和程序变量的当前值。
线程是操作系统能够进行运算调度的最小单元。它被包含在进程中,是进程中实际运行的单位。一个进程中可以并发多个线程,每个线程执行不同的任务。
二者区别:
(1)本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
(2)包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
(3)资源开销:每个进程都有独立的地址空间,进程之间的切换会有较大的开销;线程可以看做轻量级的进程,同一个进程内的线程共享进程的地址空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
(4)影响关系:一个进程崩溃后,在保护模式下其他进程不会被影响,但是一个线程崩溃可能导致整个进程被操作系统杀掉,所以多进程要比多线程健壮。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/198943.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

划片机新手教程:从准备工作到注意事项全解析!

随着科技的飞速发展,划片机已成为半导体行业不可或缺的一部分。对于新手来说,如何正确操作划片机显得尤为重要。以下是新手操作划片机的步骤和建议。 一、准备工作 在开始操作划片机之前,首先需要准备好以下工具和材料: 1. 划片机…

Java(三)(static,代码块,单例设计模式,继承)

目录 static 有无static修饰的成员变量 有无static修饰的成员方法 static的注意事项 代码块 静态代码块 实例代码块 单例设计模式 饿汉式单例写法 懒汉式单例写法 继承 基本概念 注意事项 权限修饰符 单继承 object 方法重写 子类方法中访问其他成员(成员变量…

Flume学习笔记(3)—— Flume 自定义组件

前置知识: Flume学习笔记(1)—— Flume入门-CSDN博客 Flume学习笔记(2)—— Flume进阶-CSDN博客 Flume 自定义组件 自定义 Interceptor 需求分析:使用 Flume 采集服务器本地日志,需要按照日志…

交易机器人-微信群通知

微信公众号:大数据高性能计算 1 背景 背景是基于人工去做交易本身无法做到24小时无时无刻的交易,主要是虚拟币本身它是24小时交易,人无法做到24小时盯盘,其次就是如果你希望通过配置更加复杂的规则甚至需要爬取最新的信息走模型进行量化交易的时候,就需要自己去做一些量化…

Linux 环境搭建

✨个人主页: Anmia.🎉所属专栏: C Language 🎃操作环境: Visual Studio 2019 版本 本章概要 1. 认识 Linux, 了解 Linux 的相关背景 2. 学会如何使用云服务器 3. 掌握使用远程终端工具 xshell 登陆 Linux 服务器 1. Li…

语义检索系统【全】:基于milvus语义检索系统指令全流程-快速部署版

搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术细节以及项目实战(含码源) 专栏详细介绍:搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术…

学生邮箱白嫖/免费安装JetBrains全家桶(IDEA/pycharm等) —— 保姆级教程

🧸欢迎来到dream_ready的博客,📜相信您对博主首页也很感兴趣o (ˉ▽ˉ;) 博主首页,更多redis、java等优质好文以及各种保姆级教程等您挖掘! 目录 前言 JetBrains全家桶介绍 申请过程: 获取学…

C++类与对象(2)—构造函数析构函数

目录 一、类的6个默认成员函数 二、构造函数 1、定义 2、特征 三、析构函数 1、定义 2、特征 四、默认生成构造&析构 1、定义 2、内置类型 3、自定义类型 4、声明处给默认值 5、总结 下一篇 一、类的6个默认成员函数 如果一个类中没有定义任何成员&#xff0…

Idea2023 Springboot web项目正常启动,页面展示404解决办法

Idea2023 Springboot web项目正常启动,页面展示404解决办法 问题: 项目启动成功,但是访问网页,提示一直提示重定向次数过多,404 解决方法 在IDEA的Run/Debug Configurations窗口下当前的Application模块的Working directory中添…

python 对图像进行聚类分析

import cv2 import numpy as np from sklearn.cluster import KMeans import time# 中文路径读取 def cv_imread(filePath, cv2_falgcv2.COLOR_BGR2RGB): cv_img cv2.imdecode(np.fromfile(filePath, dtypenp.uint8), cv2_falg) return cv_img# 自定义装饰器计算时间 def…

vue中使用echarts渐变柱状图 Cannot read properties of undefined (reading ‘graphic‘)解决方法

在使用渐变颜色时报错,Cannot read properties of undefined (reading ‘graphic’) echarts也下载了,引入了,就是报错,用不了new charts, 结果换了一个版本号就可以了,本来用的"echarts": "…

7.docker运行redis容器

1.准备redis的配置文件 从上一篇运行MySQL容器我们知道,需要给容器挂载数据卷,来持久化数据和配置,相应的redis也不例外。这里我们以redis6.0.8为例来实际说明下。 1.1 查找redis的配置文件redis.conf 下面这个网址有各种版本的配置文件供…

02-1解析xpath

我是在edge浏览器中安装的xpath,需要安装的朋友可以参考下面这篇博客最新版edge浏览器中安装xpath插件 一、xpathd的使用 安装lxml pip install lxml ‐i https://pypi.douban.com/simple导入lxml.etree from lxml import etreeetree.parse() 解析本地文件 htm…

linux镜像的下载,系统下载(个人使用)

文章目录 一、系统之家二、国内镜像源三、Centos官网四、安装成功截图五、镜像类型的区别参考文档 一、系统之家 系统之家官网 二、国内镜像源 下载镜像地址: 1、官网地址:https://www.centos.org/ 2、阿里镜像站:https://mirrors.aliyu…

java基础练习缺少项目?看这篇文章就够了(上)!

公众号:全干开发 。 专注分享简洁但高质量的动图技术文章! 项目概述 本教程适合刚学习完java基础语法的同学,涉及if语句、循环语句、类的封装、集合等基础概念,使用大量gif图帮助读者演示代码操作、效果等,是一个非常…

基于单片机16路抢答器仿真系统

**单片机设计介绍, 基于单片机16路抢答器仿真系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的16路抢答器仿真系统是一种用于模拟和实现抢答竞赛的系统。该系统由硬件和软件两部分组成。 硬件方面&am…

CICD 持续集成与持续交付——gitlab

部署 虚拟机最小需求:4G内存 4核cpu 下载:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 安装依赖性 [rootcicd1 ~]# yum install -y curl policycoreutils-python openssh-server perl[rootcicd1 ~]# yum install -y gitlab-ce-15.9.3-ce.0…

Idea 2023.2.5配置(插件、Maven等)

IDEA2023.2.5配置 一. 插件Alibaba Java Coding Guidelines plugin supportMaven HelperMyBatisXSonarLintTranslationVuesion Theme 二. 自定义创建live template,快速写代码三. 修改全局配置3.1 Maven配置3.1.1 安装MavenStep1. 下载Step2. 安装Step3. 创建系统环…

Linux常见命令手册

目录 文件命令 文件和目录命令 文件的权限命令 文件搜索命令 进程命令 查看进程命令 关闭进程命令 用户和群组命令 网络命令 firewall-cmd 网络应用命令 高级网络命令 网络测试命令 网络安全命令 网络配置命令 软件管理命令 系统信息命令 vi编辑器 关机命令…

【uniapp/uview1.x】u-upload 在 v-for 中的使用时, before-upload 如何传参

引入: 是这样一种情况,在接口获取数据之后,是一个数组列表,循环展示后,需要在每条数据中都要有图片上传,互不干扰。 分析: uview 官网中有说明,before-upload 是不加括号的&#xff…