自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(44)
  • 收藏
  • 关注

原创 C++ 并发编程:深入理解 std::call_once

通过上面的学习,可以总结出三个核心知识点:std::call_once 配合 std:: once_flag 使用,保证多个线程对同一个 flag 发起的初始化调用中,只有一个调用成功执行初始化函数。如果初始化函数抛出异常,初始化不会被认为成功,后续线程可以重新尝试。std::call_once 不仅保证初始化的一次性,还保证初始化结果对其他成功返回的线程可见。为什么有了 mutex,C++ 还需要提供 std::call_once?

2026-11-09 11:28:24 278

原创 C++ CRTP 深入理解:静态多态与动态多态的区别及应用场景

在写C++基础题时,碰到了一个问题以下哪些是C++中避免菱形继承问题的正确方法?A 使用虚继承(virtual inheritance)B 使用组合替代继承C 使用CRTP(奇异递归模板模式)D 增加更多的继承层次选项里面有个CRTP,因为我并不了解所以没选这个选项。然后不出意味的漏选了,然后就有了这篇博客。CRTP(Curiously Recurring Template Pattern),中文称为奇异递归模板模式,是 C++ 中一种经典的模板编程技巧。

2026-11-06 11:16:38 286

原创 初步学习FFmpeg

本人的项目需要用到FFmpeg进行拉流,因此最近在学习FFmpeg,写下这篇博客记录自己的收获。整理了FFmpeg底层基础、核心结构体。

2026-06-21 21:21:33 287

原创 音视频流媒体硬核基础:编码、封装、时间戳、H264、HLS一篇吃透

本人最近在写的项目需要理解上面的几个概念,因此写下这篇文章作为巩固以及后续复习。

2026-06-21 17:05:05 460

原创 从零吃透 RTP 协议:从设计思想到音视频同步,一篇打通所有核心知识点

本人最近在学习音视频相关的知识,目前学到了RTP协议,写下这篇博客加深自己的理解,同时希望能够帮助大家加深对RTP的理解。这篇博客我会从是什么、为什么、怎么办RTP 的本质与设计哲学RTP 包头每个字段背后的权衡RTCP 的核心作用与反馈闭环为什么必须把音频和视频分开传输音视频同步的完整原理(附数值例子)RTP(Real-time Transport Protocol,实时传输协议)是一个应用层传输协议(注意:它不是传输层协议!

2026-06-09 20:39:43 354

原创 吃透C++ Lambda与仿函数:为什么函数指针不能直接用?(附仿函数转函数指针实战)

通过上面的拆解,我们可以用一张表理清函数指针、Lambda、仿函数的核心关系:实体本质能否转普通函数指针?适用场景普通函数/静态成员函数纯代码地址(无状态)能简单无状态调用、旧C接口非静态成员函数带this的成员函数不能(需用成员函数指针)类内部逻辑调用无捕获Lambda匿名空类对象(无状态)能(标准特殊优化)临时简单逻辑、适配C接口有捕获Lambda匿名带成员类对象(有状态)不能需要捕获外部变量的场景仿函数具名类对象(可无状态/有状态)不能(可手动适配)

2026-04-22 15:36:37 332

原创 TCP/IP四层模型

第三次握手(ACK):客户端收到SYN+ACK报文后,回复ACK报文,携带确认号ACK=y+1(表示已收到服务器的SEQ=y,下一次期望接收y+1),SEQ=x+1,ACK=1;因为TCP是“全双工”通信(双方可以同时发送和接收数据),客户端发送FIN(请求释放自己的发送通道),服务器收到后,先回复ACK(确认客户端的发送通道已释放),但服务器可能还有未发送完的数据,需要等服务器发送完所有数据后,再发送FIN(请求释放自己的发送通道),客户端再回复ACK,因此需要四次挥手。③ 包头添加长度字段(最常用)。

2026-03-21 11:43:36 1032

原创 C++20——协程

一种可以暂停执行并恢复执行的函数。与普通函数的 “执行完才退出” 不同,协程可以在执行中途挂起,保存当前所有上下文,之后从挂起处恢复。普通函数像坐飞机,从起点直飞终点,中间不能停。协程像高铁,可以在沿途各个站点上下客、停靠,然后继续行驶。当⼀个函数包含 co_await/co_yield/co_return 任意⼀个关键字时,它就是协程。co_await expression 用于暂停执行直到恢复co_yield expression 用于暂停执行并返回⼀个值。

2026-03-20 12:16:09 525

原创 HTTPS协议原理

加密就是把明文(要传输的信息)进行一系列变换,生成密文。解密就是把密文再进行一系列变换, 还原成明文。在这个加密和解密的过程中, 往往需要一个或者多个中间的数据, 辅助进行这个过程, 这样的数据称为密钥。为什么需要加密因为http的内容是明文传输的,明文数据会经过路由器、wifi热点、通信服务运营商、代理服务器等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传 输的信息且不被双方察觉,这就是中间攻击 ,所以我们才需要对信息进行加密。常见加密方式。

2025-12-05 16:33:49 547

原创 DNS与ICMP

⼀个新搭建好的网络, 往往需要先进行⼀个简单的测试, 来验证网络是否畅通;但是IP协议并不提供可靠传输.。如果丢包了, IP协议并不能通知传输层是否丢包以及丢包的原因。ICMP 是“互联网控制消息协议”的缩写,属于网络层辅助协议,基于 IP 协议传输(不封装在 TCP/UDP 中),用于在 IP 网络中传递控制消息(如网络状态查询)和 差错报告(如目标不可达),帮助诊断网络故障。ICMP报文格式ICMP分为两类,一是用于通知出错原因,二是用于诊断查询。

2025-12-04 18:06:09 1004

原创 ARP的具体过程和ARP欺骗

ARP 协议是 无状态协议(不验证请求 / 应答包的真实性),攻击者通过伪造 ARP 应答包,篡改目标设备的 ARP 缓存表,将合法的 IP-MAC 映射替换为攻击者的 MAC 地址,从而劫持流量或中断通信。ARP 是局域网内的地址解析协议,核心作用是将网络层的 IP 地址翻译成数据链路层的 MAC 地址,因为局域网内数据帧传输依赖 MAC 地址,而设备之间只知道目标 IP,需要 ARP 完成映射。攻击者伪造 “目标 IP→ 攻击者 MAC” 的 ARP 应答包,发送给受害者电脑;

2025-12-04 16:02:16 822

原创 mmap详解

mmap是类Unix系统中的内存映射系统调用,它通过将文件或匿名内存映射到进程地址空间,实现高效I/O操作和进程间共享内存。其核心优势在于减少数据拷贝次数(相比read仅需一次)和避免频繁系统调用开销。原理上,mmap建立虚拟地址与文件/内存的映射关系,仅在访问时触发缺页中断加载数据。文章通过两个示例演示了文件映射读写操作,并实现了一个极简版的malloc内存分配器,展示了mmap在内存管理中的应用。mmap支持共享/私有映射、文件/匿名映射等多种模式,是高性能系统编程的重要工具。

2025-11-14 18:27:49 1038

原创 qrc机制——Qt

qrc机制是一种Qt静态资源管理的方案。打包程序所需的静态资源,编译后嵌入可执行文件。路径中用:表示从qrc中读取资源。比如“:/p.jpg”

2025-10-28 13:47:02 238

原创 Qt信号与槽详解

signals:private:自定义信号与槽可以添加参数,信号函数的参数必须与槽函数的参数一致,但是实际上信号函数的参数可以多于槽函数参数个数,但实际开发中最好保持二者参数列表一致。通过emit发送信号。必须保证先连接信号与槽再发送信号。

2025-10-28 13:32:04 423

原创 Qt对象树详解

对象树是Qt中基于QObject类实现的一种对象生命周期管理机制。核心是通过“父子关系”自动管理对象的构造与销毁,简化内存管理,避免内存泄漏。当一个对象继承了QObject或其派生类,只要为该对象设置QObject或其派生类充当父对象,那么该对象会成为父对象的孩子。当要释放父对象时,父对象调用析构函数后会调用基类QOject的析构函数来递归式的遍历孩子进行释放。

2025-10-24 15:37:34 297

原创 对make/makefile的简单认识

当我们定义一个clean目标来清理其他目标时,通常没有依赖,如果当前目录存在一个clean文件,它就始终是最新的,因此就始终用make生成不了clean目标,这显然不符合我们的初衷。这是因为在生成目标时,如果当前目录有文件与目标重名,make会比对该文件与目标的依赖文件的修改时间,如果依赖文件的修改时间更加新,就会重新生成目标,否则就不会生成目标。如果有多个目标或依赖,中间用空格隔开,在依赖方法中可以用$^表示所有依赖文件,用$@表示所有目标。上面的test依赖test.cpp,它们构成依赖关系。

2024-11-24 21:37:04 501

原创 Linux权限

Linux有两种用户:超级用户(root)、普通用户。超级用户(root):可以在Linux系统下做任何事,没有限制。命令提示符是“#”。普通用户:做的有些事会受到限制。命令提示符是“$”。

2024-11-21 20:32:24 997

原创 C++11的部分新特性

这里我们利用C++11列表初始化的特性,通过列表来初始化变长数组,这样{(print(arg),0)...}就展开成{(print(arg1),0),(print(arg2),0),(print(arg3),0),...,(print(argn),0)},逗号表达式的意义在于调用print函数后,以0作为整个表达式的结果,刚好作为arr数组的一个元素。C++原本中就有引用的语法,C++11中增加了右值引用的语法,我们之前的引用用法被称为左值引用,无论是右值引用,还是左值引用,都是给变量取别名。

2024-09-15 23:01:04 1025

原创 C++——哈希

undered_map是存储键值对<key,value>的关联式容器。与map不同,undered_map存储的key没有顺序,但同样是通过key索引得到value。undered_map中的键值key不可修改且唯一。undered_map支持[ ]访问,下标为键值key。如果key不存在,那么会将key进行插入,对应的value为默认值。undered_map的通过key访问value的效率比map快函数声明功能介绍构造不同格式的undered_map对象。

2024-09-08 22:16:37 1659

原创 红黑树的简单实现

我们使用二叉搜索树时,它可能退化为单支树或近似单支树,这时候它的搜索效率就退化到O(n),与AVL树一样,红黑树的出现就是来解决这种情况,红黑树是一种二叉搜索树。它保证二叉搜索树搜索效率的根本逻辑就是将每个节点增加了颜色属性,并制定了一套规则,根据这个规则的特性来判断是否需要旋转,以此维持平衡。1.每个节点的颜色不是黑色就是红色。2.根结点为黑色。3.如果一个节点为红色,那它的子节点必须为黑色。4.对于每个节点,从该节点开始到它的每个叶节点的路径上的黑色节点数相同。5.每个叶节点为黑色(这里的叶节点指的是空

2024-09-03 21:53:47 728

原创 AVL树的四种旋转情况

我们知道搜索二叉树的一个缺陷就是有可能成为单支树或者近似单支树,而AVL树解决这个问题的方式就是通过每个节点的平衡因子来判断节点的左右子树的高度差是否超过2,从而进行旋转。这里我们可以根据平衡因子的将需要旋转的情况抽象出四种情况。

2024-08-04 20:30:49 406

原创 C++——map与set

set是按一定顺序储存数据的容器。set的特点:1.set里面没有重复元素,并且元素不可修改,只能插入和删除。2.set进行插入时只需要插入value即可,不想要构建键值对,但实际的底层还是使用<key,value>,并且key等于value。3.set里面的元素默认按照小于的顺序排序。map是比较键值key来储存数据的关联式容器。map的特点:1.map中的key不允许重复。2.map支持[]访问,下标为键值key。

2024-08-03 18:21:36 931

原创 二叉搜索树的简单实现

二叉搜索树是一棵具有以下性质的二叉树:1.若左子树不为空,则左子树上所有节点的值都小于根节点的值。2.若右子树不为空,则右子树上所有节点的值都大于根节点的值。

2024-07-24 18:03:04 373

原创 C++——多态

多态的实现需要满足两个条件:1.子类完成父类虚函数的重写。2.由父类指针或引用调用虚函数。

2024-07-22 18:29:14 980

原创 C++继承

会发现报错了,这里不会根据哪个函数更适合就调用哪一个,实际上当子类出现与父类同名的函数时,会进行覆盖,无论调用时是否传参,只要是子类对象调用,就只会调用子类的函数,除非调用时指明作用域。但我们发现它们有一些共同特征,即都有名字,大小,等,我们可以抽象出一个水果类,对于每一个具体的水果,继承水果类即可。实际上,我们在调用子类构造函数时编译器会先在初始化列表调用父类的构造函数,但是调用子类的析构函数时,会等子类的析构函数调用完后再调用父类的析构函数。之前接触的复用都是函数复用,继承是类设计层次的复用。

2024-07-19 18:22:32 720

原创 容器适配器&&stack,queue,priority_queue的模拟实现

容器适配器就是封装某些容器,使其满足一些特定场景下的需求,STL提供了三种容器适配器,分别是stack,queue,priority_queue。前两者的底层容器为deque,而priority_queue的底层容器为vector.

2024-06-18 12:38:35 265

原创 vector的模拟实现

同上,这里我们的函数参数没有引用,直接交换即可,并且由于临时变量出了作用域会自动销毁,那么交换后临时变量会带着this指针交换前的内容销毁。我们可以利用被拷贝变量的迭代器区间构造一个临时变量,与被构造的变量交换。我们用原生指针作为迭代器,记得实现带有常量属性变量能够实现的迭代器。改变容量大小时,注意原有迭代器已失效,要提前记录有效数据个数。如果要改变的容量大小小于当前容量大小,那么我们不做处理。注意扩容时pos位置的迭代器可能失效,要记录其相对位置。提前设置vector的容量大小可以避免频繁扩容。

2024-06-07 20:32:51 304

原创 内存管理+模板初阶

对内存管理与模板初阶的小总结

2024-05-11 17:53:59 733 2

原创 匿名对象+拷贝构造时编译器的一些优化

匿名对象就是用类实例化一个没有名字的对象。A为类名,上面就构造了一个匿名对象。

2024-05-10 21:57:41 303

原创 初始化列表+explicit关键字+友元+static关键字

友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。

2024-04-21 21:25:21 1090 1

原创 C++类中的六大默认成员函数

构造函数实现对类中成员变量初始化的操作,分为无参默认构造函数和有参默认构造函数,无参默认构造函数由编译器自身调用,如果不主动在类中写构造函数,编译器会提供无参默认构造函数。析构函数用来销毁成员变量,防止内存泄漏,由编译器自动调用,如果我们不提供析构函数,那么编译器会自动提供,一般如果没有动态申请的成员变量,我们不会主动提供析构函数。注意:一般如果没有动态申请的成员变量,我们不需要提供拷贝构造函数,因为编译器会提供,并完成内置类型的拷贝,如果是自定义类型则调用自定义类的拷贝构造函数。

2024-04-18 22:12:04 485

原创 C++之函数重载与引用

C++用&表示引用,&在C语言中表示取地址,在C++中&根据情况的不同表示前面二者之一。

2024-04-07 20:52:58 303

原创 命名空间与默认参数

我们经常使用的using namwsapce std 就是展开了头文件中的命名空间std,所以我们可以直接使用cout,cin等,需要注意的是展开命名空间并不是直接将命名空间里的内容真正展开,与头文件的展开不同,只是让编译器经过局部,全局的搜索后再在你所展开的命名空间里搜索你使用的变量。调用函数时,传入的数是依次从左到右匹配相应的形参,因此默认参数应该放到普通参数的后面,避免编译器不知道是否该给默认参数赋值。使用变量k时加上it::表示使用命名空间it内的变量k。

2024-03-31 22:39:33 519 1

原创 数据结构——排序

2.每一趟走完后,都会使一个数到达正确的位置,并且是从后向前的,因此在上一趟排完后,该趟遍历的数应该去掉最后一个,即上一趟到达正确位置的数,当j=0时,总遍历数为n-1,当j=1时,最后一个元素不必遍历,故总遍历数为n-1-1,当j=2时,最后两个元素不必遍历,故总遍历数为n-1-2,以此类推,每一趟的遍历数为n-1-j。建堆需要利用向下调整算法,从最后一个叶节点的父节点开始,依次往前进行向下调整,最后建出大堆,将堆顶的数与最后一个数交换,再将剩余数(去掉最大值)重新建堆,直至有序。

2024-03-26 22:52:11 705

原创 c语言文件操作

磁盘上的文件就是文件。在程序设计中我们谈及的文件一般包括两种:文本文件,数据文件。(从功能上划分)

2024-01-23 21:09:11 1133 1

原创 C语言程序编译和链接

2.处理所有的条件编译指令,如: #if、#ifdef、#elif、#else、#endif。3.处理#include预编译指令,将包含的头文件的内容插⼊到该预编译指令的位置。将源代码程序被输入扫描器,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成⼀系。静态语义分析通常包括声明和类型的匹配,类型的转换等。链接是⼀个复杂的过程,链接的时候需要把⼀堆文件链接在⼀起才生成可执行程序。6.或保留所有的#pragma的编译器指令,编译器后续会使用。1.将所有的 #define 删除,并展开所有的宏定义。

2024-01-17 17:47:00 424

原创 结构体的介绍

这里我们创建了一个类型为struct peo类型的变量s2。

2023-12-17 21:45:52 115 1

原创 整数与浮点数在内存中的储存

整数在内存中以二进制补码进行储存,这里进行原码,反码,补码的介绍原码一个数写成二进制的数就是原码。正数的原,反,补码相同,负数的需要区分,对于负数,原码的符号位不变,其他为按位取反得到反码,反码加1得到补码。而补码的储存方式又分为大,小端储存。

2023-11-29 20:15:22 94 1

原创 指针的梳理

这里注意函数名即为函数的地址,也可加&符号。

2023-11-29 19:43:35 81 1

原创 用c语言完成简易扫雷

1.我们都玩过扫雷,扫雷是一个n*n的矩形,这样我们就会想到使用二维数组来构建。2.其中每个小方格都是蓝色未知的,那么我们就需要使用某个字符对二维数组初始化,使其达到同样的效果,这里我们使用‘*’来初始化棋盘。3.当我们点击一个小方格时,如果是雷就被炸死了,如果不是雷,就会扫描以它为中心周围八个格子雷的个数,并在该方格显示出来。那么我们的棋盘上有雷与无雷同样需要用字符填入棋盘,而我们已经用‘*’初始化过棋盘了,由于不能让玩家看到雷的分布,我们需要再构建一个二维数组来布置雷,这个棋盘不对玩家展示。

2023-11-03 23:14:30 80

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除