当前位置: 首页 > news >正文

【C++详解】C++入门(二)引用、内联函数、nullptr宏

文章目录

  • 一、引用
    • 引用的概念和定义
    • 引用的功能
    • 引用的特性
    • const引用
      • const用法回顾
      • 权限的放大缩小
      • const引用的功能
    • 指针和引用的关系
  • 二、内联函数
  • 三、nullptr
  • 补充
    • 结构体指针变量类型重定义

一、引用

引用的概念和定义

C++祖师爷为了优化在部分场景中使用指针会出现的效率较低和比较复杂的情况,引入了一个新概念——引用。
引用不是新定义一个变量,而是为已经存在的变量取别名,编译器不会为引用变量开辟空间,它和它引用的变量共用一块空间,通俗来说就是为一个变量取别名,虽然叫法不同,变量的不同的别名还是指代这个变量本身,也就是你的正式名字和你的外号都是你本身,引用用法如下:
类型& 引用别名 = 引用的对象;

#include <iostream>
using namespace std;
int main()
{int a = 0;//引用:b和c是a的别名int& b = a;int& c = a;//也可以为别名b取别名,d相当于还是a的别名int& d = b;//这里我们可以看到abcd的地址都是一样的cout << &a << endl;cout << &b << endl;cout << &c << endl;cout << &d << endl;return 0;
}

在这里插入图片描述

下面代码不是让d变成x的别名,只是赋值修改d指向的这块空间的值。

在这里插入图片描述

引用的功能

一、

其实引用在功能上和指针是有部分重叠的,至于怎么个重叠法呢,跟随小编的脚步一起来看看吧。
在C语言阶段我们想要实现一个交换变量值的函数时是需要传变量的地址的,这样形参的改变才会影响实参,现在我们了解了引用后其实就可以把它用上了,如果我们传引用调用函数,那么函数的形参名就是实参的别名,形参发生了什么变化实参也会跟着变。
补充:变量引用的生命周期一定和变量本身一样或者比变量本身小,比如下面x是a的引用,x出了swap这个函数后就销毁了,但是a还存在。

void swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}void swap(int& x, int& y)
{int tmp = x;x = y;y = tmp;
}int main()
{int a = 10;int b = 20;swap(&a, &b);cout << a << " " << b << endl;swap(a, b);cout << a << " " << b << endl;return 0;
}

在这里插入图片描述

这里我们可以总结出引用的第一个功能:
引用做函数形参,修改形参影响实参

二、

在调用函数传参的时候当参数很大时,比如下面这个结构体变量A,如果传参数本身会把这个参数拷贝过去(因为形参是实参的临时拷贝),这样空间开销就太大了,所以我们通常会传它的指针,指针最大也就8个字节。我们想想,引用在这里依旧可以实现同样的功能,前面介绍到引用是不会为变量开辟空间的,所以这里也可以采用传引用的方式。

struct A
{int a[100];int b;
};void Func(struct A* a)
{ }void Func(struct A& aa)
{ }int main()
{struct A a;Func(&a);Func(a);
}

引用做函数形参,减少拷贝,提高效率

三、

引用不仅可以作为函数形参,还可作为函数返回值返回,在介绍引用做函数返回值有哪些功能之前,还请允许小编科普一些有关函数返回值的知识点。

在这里插入图片描述

上面小编实现了一个简单的传值返回,其中变量ret在出了Func这个函数作用域后就销毁了,所以我们可以确定x接受的返回值一定不会是ret本身。这里返回的其实是ret的一份临时拷贝变量,并且语法规定了这个临时变量是具有常性的,这里可以简单理解成它被const修饰过,并且语法规定就算返回值出了作用域还存在它返回的也是临时变量,因为编译器不会去识别返回值出作用域是否销毁。

有了上面的铺垫过后接下来小编就要介绍今天的主角了。

typedef struct SeqList
{int* arr;int size;int capacity;
}SL;void SLInit(SL& sl, int n = 4)
{sl.arr = (int*)malloc(n * sizeof(SL));sl.size = 0;sl.capacity = n;
}void SLPushBack(SL& sl, int x)
{sl.arr[sl.size] = x;sl.size++;
}//该函数表示返回顺序表第i个位置的数据
int& SLAt(SL& sl, int i)
{//断言检查i是否越界assert(i < sl.size);return sl.arr[i];
}int main()
{SL s;SLInit(s);SLPushBack(s, 1);SLPushBack(s, 2);SLPushBack(s, 3);SLPushBack(s, 4);for (int i = 0; i < s.size; i++){SLAt(s, i) += 1;}for (int i = 0; i < s.size; i++){cout << SLAt(s, i) << endl;}return 0;
}

上面是小编实现的一个简单顺序表,我们可以看到顺序表尾插了四个数字1234,SLAt函数实现的是返回顺序表第i个位置的数据,如果我们想要在主函数中修改该函数的返回值该怎么做呢?读者朋友应该可以发现SLAt的返回类型是int&,这不就是才介绍的引用吗?没错,这就是传引用返回。

在这里插入图片描述

上图我们可以直观看到传值返回和传引用返回的区别,传值返回产生了临时变量,所以修改临时变量不会改变返回值,直观来讲就是顺序表的值不会发生改变(并且这种操作会编译报错,因为临时变量具有常性,具有常性的变量无法被修改),但是传引用返回就不一样了,它返回的是返回值的别名,所以不会产生临时变量,编译就不会报错,我们可以简单理解别名就是它本身,所以修改返回值的别名就是修改它自己,所以我们可以看到顺序表的值确实被修改了。

注意:传引用返回只适用于返回对象出了函数作用域还存在的情况,例如上面这个例子返回值对象是在堆上申请的。

在这里插入图片描述

这里我们可以类比引用的前两个功能,总结出另外两个功能:
引用做函数返回类型,修改返回对象
引用做函数返回类型,减少拷贝,提高效率

引用的特性

  • 引用在定义时必须初始化,变量和指针都可以先定义后赋值。
	//变量可以先初始化再赋值int x;x = 10;//引用不能先初始化再赋值int& r;r = x;//错误用法
  • 一个变量可以有多个引用
	//变量x可以有多个引用int x = 10;int& a = x;int& b = x;int& c = x;
  • 引用一但引用一个实体,就不能引用其他实体。
    在这里插入图片描述

就是平时所说的引用不能改变指向。(可以形象理解引用是非常忠贞的,一个别名只能对应一个对象)
所以引用是不能完全替代指针的,有些情况比如数据结构中的链式结构或者树形结构我们有修改指向的需求,所以这类情况只能使用指针,指针可以修改指向。

const引用

const用法回顾

在介绍const引用之前,我们先回顾一下C语言阶段我们掌握的有关const的用法:

  • const修饰变量
  • const修饰的变量无法直接修改,但是可以通过它的指针绕过他,使用它的地址修改,虽然这样做打破了语法的规则。
	//const修饰变量const int n = 10;n = 20;     //无法实现int* pn = &n;*pn = 20;   //可以实现,但是破坏了语法规则
  • const修饰指针变量

1、const在*左边,修饰指针指向的对象,保证指针指向的对象本身无法通过指针修改,但是指针变量本身可变。

	//const在*左边,修饰指针指向的内容,const int* p = &n;*p = m;  //无法实现p = &m;  //可以实现

2、const在*右边,修饰指针变量本身,保证指针变量本身无法被修改,但是指针指向的对象可以通过指针改变。

	//const在*左边,修饰指针变量本身int* const p = &n;*p = m;  //可以实现p = &m;  //无法实现

权限的放大缩小

	const int a = 10;//权限不能放大int& r1 = a;//权限可以平移const int& r2 = a;int b = 20;//权限可以缩小const int& r3 = b;

上面我们定义了一个const修饰的int类型变量a,它具有常性无法被修改。下面我们用没被const修饰的r1做a的别名,编译器会报错,因为a本身不能被修改,r1为a的别名却没有任何限制,可以随意修改,这里就会涉及到权限的放大。但是权限是可以平移和缩小的,下面两种引用编译器都不会报错。
注意:指针和引用才会涉及权限的放大和缩小,因为指针和引用对象的改变会影响原对象。

const引用的功能

	int a = 10;double d = 1.1;//以下两种情况都是引用的临时对象const int& r1 = d;       //1const int& r2 = a * 10;  //2

我们先看第一个引用,double类型的d被const修饰的int类型的r1引用,这里会发生隐式类型转换(C语言规定相关类型可以进行隐式转换),这里C++语法还规定类型转换会产生临时对象,这里r1引用的其实是那个临时对象,临时对象是是编译器需要一个空间来暂存表达式的求值结果或者隐式转化时产生的中间对象时临时创建的一个未命名对象,它的特点是具有常性,不能修改。
所以这里r1需要加const修饰,防止权限的放大。

在这里插入图片描述

有了上面临时对象的概念后第二个引用为什么要加const就很好理解了,直接上图。

在这里插入图片描述

总结:C++引入const引用的目的就是方便传参,后续函数形参部分若用const引用来接受,即可适配大部分传参的情况。

指针和引用的关系

在C++中,引用和指针功能有重叠性,它们各自有各自的特点,在实践中相辅相成,互相不可替代,所以C++从某种程度上会比C语言更便捷,能实现更多功能。
1、指针存储一个变量地址需要开空间,引用是为一个变量取别名不用开空间。
2、引用在定义时必须初始化,指针可以先定义再初始化。
3、指针可以更改指向的对象,引用一旦引用一个实体后就不能再引用其他对象。
4、引用可以直接访问指向对象,而指针必须解引用后访问指向对象。
5、sizeof中含义不同,引用结果为引用类型大小,而指针始终是地址空间所占字节数(32位为4字节,64位为8字节)。
6、指针容易出现空指针和野指针的问题,引用很少出现,所以引用更安全一些。
7、在指令汇编角度,引用也是用指针实现的,但是一般我们都以语法层面为准。

二、内联函数

1、我们在C语言阶段学习的宏函数会在预处理时替换展开,但是宏函数是很容易出错的,比如要注意运算符优先级,并且不能调试,但是函数会自动处理运算符优先级所以C++设计内联函数就是为了替代C语言的宏函数。
2、内联函数的关键字是inline,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不会创建栈帧了,提高了时间效率(创建栈帧消耗时间),这里我给大家演示一下普通函数和内联函数在汇编指令层面的区别:

inline int Add(int x, int y)
{int ret = x + y;return ret;
}
int main()
{int ret = Add(1, 2);cout << ret << endl;return 0;
}

不是内联:
在这里插入图片描述
是内联:
在这里插入图片描述

3、既然内联函数有这么多优点,那么我们就可以无脑用它了吗?肯定不行,因为内联函数调用过多会造成程序变大,会占用很多空间,比如内联函数转化为指令有50行,调用10000次就是500000行,我们不内联的话函数就一直待在一块公共空间,每一次调用的时候会call指令跳转到函数所在位置,那么就是程序指令一共就是10000+50行。世界上没有什么是完美的,内联函数可以简单理解成是用空间换时间
4、inline对于编译器而言只是一个建议,也就是说就算你加了inline编译器也可以在调用的地方不展开,比如说递归函数或者代码相对多一点的函数加了inline也会被编译器忽略,所以短小并且需要频繁调用的函数适合用内联

5、内联函数不能声明和定义分离,因为内联函数会直接展开,所以在编译阶段不会进符号表,那么在另一个文件调用内联函数时,因为文件里只有内联函数的声明,(声明只有无效地址,只有在函数定义才会分配确切的地址)所以在编译阶段找不到函数的地址,那么编译器只有寄希望于链接的时候合并符号表时得到函数的地址,但是内联函数不会进符号表,所以编译器就会报链接错误。
所以内联函数的定义和声明只能在一起,简单理解就是内联函数只能在有它的定义的文件里展开,若内联函数定义在头文件里,其他文件包了这个头文件,调用这个内联函数就可以展开。

6、普通函数必须声明和定义分离,如果普通函数定义在头文件里,那么如果有两个文件都包含了这个头文件,最后两个文件编译后生成的目标文件都有这个函数的确切地址,后面链接这两个目标文件时两个文件的符号表都有这个函数的确切地址,就会链接报错。

与前面知识的联系:前面我们知道有static关键字,它修饰全局变量和函数后使得它们之只能在当前源文件里使用,之前我们的解释是static让它的外部链接属性变成了内部链接属性,其实本质就是让他不进符号表,和inline类似。

三、nullptr

NULL实际上是一个宏,在传统C头文件中,可以看到如下代码:

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

C++中NULL被定义为字面常量0,C中被定义为无类型指针(void*)的常量,不论采用何种定义,在使用空值的指针时,都不可避免会遇到一些麻烦,比如下面:

在这里插入图片描述

本来想通过f(NULL)调用指针版本的Func(int*)函数,但是由于NULL被定义成0,调用了f(int x),因此与程序初衷相悖。
所以C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为为nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型。

补充

结构体指针变量类型重定义

下面代码上面的写法等价于下面

typedef struct ListNode
{int val;struct ListNode* next;
}ListNode, *pnode;typedef struct ListNode ListNode;
typedef struct ListNode* *pnode;

以上就是小编分享的全部内容了,如果觉得不错还请留下免费的赞和收藏
如果有建议欢迎通过评论区或私信留言,感谢您的大力支持。
一键三连好运连连哦~~

在这里插入图片描述

相关文章:

【C++详解】C++入门(二)引用、内联函数、nullptr宏

文章目录 一、引用引用的概念和定义引用的功能引用的特性const引用const用法回顾权限的放大缩小const引用的功能 指针和引用的关系 二、内联函数三、nullptr补充结构体指针变量类型重定义 一、引用 引用的概念和定义 C祖师爷为了优化在部分场景中使用指针会出现的效率较低和比…...

8、HTTPD服务--CGI机制

目录 1、测试PHP页面 2、安装php软件 一、CGI机制介绍 1、测试PHP页面 [rootlocalhost ~]# cat /mp3/test1.php AAAAAAAAAAAAA <?phpphpinfo(); ?> 2、安装php软件 # yum install -y php # systemctl restart httpd php实际上是作为httpd的功能模块存在的 [r…...

层级时间轮的 Golang 实现原理与实践

一、引言 在高并发服务中&#xff0c;延时任务的管理是一个常见且重要的需求。比如 HTTP 请求超时、心跳检测、订单超时未支付提醒等场景&#xff0c;传统的 Timer 或 Heap 实现会带来 O(log n) 的复杂度&#xff0c;难以支撑百万级别的定时任务。 论文《Hashed and Hierarch…...

人类社会的第四阶段

本书的主旨是探讨一场新的权力革命&#xff0c;它将以20世纪民族国家的毁灭为代价&#xff0c; 解放出个体。创新&#xff0c;以前所未有的方式改变了暴力的逻辑&#xff0c;并且正在革新未来的 边界。如果我们的推论是正确的&#xff0c;你们正站在一场有史以来最宏大的革命的…...

Golang | Builder模式

Builder模式是一种创建型设计模式&#xff0c;用于分步骤构建复杂对象&#xff0c;尤其适用于构造过程复杂或需要多个配置选项的场景。将对象的构造过程与其表示分离&#xff0c;通过分步骤和链式调用的方式灵活创建对象&#xff0c;避免构造函数的参数爆炸&#xff0c;提升代码…...

C#本地使用离线ocr库识别图片中文本,工具包PaddleOCRSharp

C#本地使用离线ocr库识别图片文本&#xff0c;工具包PaddleOCRSharp PaddleOCRSharp介绍 项目地址&#xff1a;https://github.com/raoyutian/PaddleOCRSharp PaddleOCRSharp 是一个.NET版本OCR可离线使用类库。项目核心组件PaddleOCR.dll目前已经支持C\C、.NET、Python、Go…...

Flutter 在 Dart 3.8 开始支持 Null-Aware Elements 语法,自动识别集合里的空元素

近日&#xff0c;在 Dart 3.8 的 changelog 里正式提交了 Null-Aware Elements 语法&#xff0c;该语法糖可以用于在 List、Set、Map 等集合中处理可能为 null 的元素或键值对&#xff0c;简化显式检查 null 的场景&#xff1a; /之前 var listWithoutNullAwareElements [if …...

3、Linux操作系统下,linux的技术手册使用(man)

linux系统内置技术手册&#xff0c;方便开发人员查阅Linux相关指令&#xff0c;提升开发效率 man即是manual的前三个字母&#xff0c;有时候遇事不决&#xff0c;问个人&#xff08;man&#xff09; 其在线网址为&#xff1a;man 还有man网站的作者写的书&#xff0c;可以下…...

Python 自动化办公:Excel 数据处理的“秘密武器”

引言 在日常的 IT 办公场景里&#xff0c;Excel 是数据处理与分析的 “常胜将军”。无论是财务人员整理账目、销售团队统计业绩&#xff0c;还是运营人员分析用户数据&#xff0c;Excel 都发挥着关键作用。但面对海量数据&#xff0c;手动操作 Excel 不仅效率低下&#xff0c;还…...

通过数据增强打造抗噪音多模态大模型

下载前面 想象一下,你正在一个嘈杂的咖啡馆里,想让身边的AI助手帮你预定一张电影票。或者,你在熙熙攘攘的街道上,需要语音导航带你找到目的地。在这些真实的场景中,语音交互面临着一个巨大的挑战——噪音。 背景噪音、他人说话声、设备本身的电流声……这些无处不在的干…...

Node.js API 安全的主要策略:最佳实践

了解 Node.js API 安全性 保护 Node.js API 的安全需要了解潜在的漏洞并采取措施来缓解这些漏洞。这类 API 通常遇到的常见威胁包括: SQL 注入**:**操纵用户输入以针对数据库执行恶意 SQL 代码。跨站点脚本**(XSS):**将恶意脚本注入其他用户查看的网页。跨站请求伪造**(CSR…...

如何删除Google Chrome中的所有历史记录【一键清除】

谷歌浏览器记录了用户访问过的网站。这方便了查找&#xff0c;但有时也需要清理。删除所有历史记录很简单&#xff0c;只要按照以下步骤操作。 1. 打开谷歌浏览器 首先要启动谷歌浏览器。点击右上角的三个点&#xff0c;进入主菜单。 2. 进入历史记录界面 在菜单中找到“历史…...

计算机三大主流操作系统的前世今生 - Linux|macOS|Windows

全文目录 1 引言2 起源之路2.1 Linux 起源2.2 macOS 起源2.3 Windows 起源 3 综合解析3.1 Linux系统综合解析3.1.1 系统定义与核心架构3.1.2 发展历程3.1.3 核心特点3.1.4 主流发行版3.1.5 应用场景 3.2 macOS系统综合解析3.2.1 系统定义与核心架构3.2.2 发展历程3.2.3 核心特点…...

大数据学习栈记——Hive4.0.1安装

本文介绍大数据技术中数据仓库Hive的安装配置&#xff0c;版本&#xff1a;Hive4.0.1&#xff0c;Ubuntu24.04。 Hive简介 Hive由 Facebook 开源用于解决海量结构化日志的数据统计工具。 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据…...

8.Excel:数据验证和下拉列表

一 数据验证 1.作用 限制用户输入单元格的值。 补充&#xff1a;数据验证要先设置验证才会起作用&#xff0c;对于已经填写完成的表格来说&#xff0c;可以快速找到不符合的数值。 选中整列&#xff0c;然后设置数据验证。 然后圈释无效数据&#xff0c;不符合的会被圈出来 2.如…...

【机器学习-线性回归-4】线性回归中的最优解:从数学原理到实践应用

在机器学习的世界里&#xff0c;线性回归就像是一把瑞士军刀——简单却功能强大。无论是预测房价、分析销售趋势&#xff0c;还是研究变量间的相关性&#xff0c;线性回归都是数据科学家首选的入门算法。但你是否曾好奇过&#xff0c;这个看似简单的算法背后&#xff0c;是如何…...

《代码整洁之道》全书归纳

如果要把这本书最关键、最核心、被反复提及和强调的重点提炼出来&#xff0c;那就是&#xff1a; 可读性高于一切&#xff1a; 你的代码是给人读的&#xff0c;让它像一篇清晰的文章一样易于理解。表达意图是关键。短小、单一&#xff1a; 函数要短小&#xff0c;类要短小&…...

项目代码生成工具

代码生成工具 文章目录 代码生成工具提取公共类domainbodtoentityvoBean基类 代码生成工厂连接配置模版1、基础类基类Entity添加DTO类分页查询DTO基础查询DTO修改DTO视图VO 2、controller2、service接口3、service实现类4、Mapper接口5、Mapper的xml文件 提取公共类 比方说每个…...

【机器学习驱动的智能化电池管理技术与应用】

在人工智能与电池管理技术融合的背景下&#xff0c;电池科技的研究和应用正迅速发展&#xff0c;创新解决方案层出不穷。从电池性能的精确评估到复杂电池系统的智能监控&#xff0c;从数据驱动的故障诊断到电池寿命的预测优化&#xff0c;人工智能技术正以其强大的数据处理能力…...

【MySQL 】MySQL 安装自记录全程-详细 (mysql-installer-community-8.0.42.0.msi)

看了一些别人的文章&#xff0c;其实还有些困惑&#xff0c;根据不少都有一些跟我遇到的不太一样&#xff0c;记录一下自己的安装过程 MySQL 安装&#xff08;Windows&#xff09; 下载 MySQL 安装包 MySQL数据库官网链接 MySQL &#xff08;MySQL的https://www.mysql.com/ …...

构建事件驱动的云原生后端系统 —— 从设计到实践

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:为什么需要事件驱动架构? 在现代互联网应用中,系统规模越来越大,功能模块越来越复杂,用户行为越来越不可预测。 传统的同步调用、强耦合的后端架构,面对大规模并发、高频变化、复杂交…...

时间复杂度和空间复杂度 [数据结构 初阶]

目录 算法效率 1. 时间复杂度 1.1 时间复杂度概念 1.2 大O 的渐进表示法 1.2.1 计算 func1 的基本操作执行了多少次 1.3 推导 大O 阶方法 2. 空间复杂度 算法效率 // 算法效率分析分为两种: 1) 时间效率: 时间复杂度, 用来衡量一个算法的运行速度; 2) 空间效率: 空间复…...

SpringMVC 通过ajax 前后端数据交互

在前端的开发过程中&#xff0c;经常在html页面通过ajax进行前后端数据的交互&#xff0c;SpringMVC的controller进行数据的接收&#xff0c;但是有的时候后端会出现数据无法接收到的情况&#xff0c;这个是因为我们的参数和前端ajax的contentType参数 类型不对应的情景&#x…...

Qt从零开始(1)了解

文章目录 1. Qt技术介绍2. 开发GUI的选择3. 框架的介绍4.Qt发展历程&#xff08;简单介绍&#xff09;5. Qt支持的系统6. Qt开发方式7.Qt优点总结 简介&#xff1a;这篇文章简单介绍下Qt的相关知识与应用场景&#xff0c;随便看看&#xff0c;了解了解即可。如果介绍有误或者描…...

当元数据遇见 AI 运维:智能诊断企业数据资产健康度

在数字化浪潮席卷全球的当下&#xff0c;企业数据资产规模呈指数级增长&#xff0c;然而传统数据监控方式却逐渐暴露出诸多弊端。想象一下&#xff0c;在某头部电商的晨会上&#xff0c;数据工程师小王正经历职业生涯最尴尬的时刻&#xff1a;“昨天促销活动的 UV 数据为什么比…...

关于OCP认证:有Oracle和MySQL两种

认证针对的数据库系统 MySQL OCP&#xff1a;是 Oracle 公司针对 MySQL 数据库管理员和开发者设计的认证&#xff0c;主要验证持证者在 MySQL 数据库管理、优化及安全等方面的技术能力。MySQL 是开源的关系数据库管理系统&#xff0c;以其简单、高性能和灵活性在中小型企业及开…...

Macos m系列芯片环境下python3安装mysqlclient系列问题

最近学习python3&#xff0c;在安装mysqlclient的时候遇到了一些问题&#xff0c;直接使用哦pip install mysqlclient 直接报错了&#xff0c;记录一下解决方案。 环境信息 设备&#xff1a;Macbook Pro m1 系统&#xff1a;macos Sequoia 15.3.2 最终成功的python版本&#xf…...

《代码整洁之道》第7章 错误处理 - 笔记

得墨忒耳定律 不要链式调用&#xff0c; 如 a.getB().getC().doSomething()。 直接获取对象调用方法 数据传输对象&#xff08;DTOs&#xff09; DTO (Data Transfer Object)&#xff1a; 数据传输对象。这是一种典型的数据结构。 里面没有任何业务逻辑代码。它的唯一作用就…...

java-mybatis01

对象/关系映射ORM ORM完成面向对象的编程语言DAO关系数据库的映射后&#xff0c;开发人员可以利用面向对象设计语言的建议易用性&#xff0c;也可利用关系数据库的技术优势。 ORM把关系数据库包装成面向对象的模型&#xff0c;采用ORM框架后&#xff0c;应用程序不再直接访问底…...

单片机之间的双向通信

具体功能实现 甲单片机通过按键可以控制乙单片机的LED灯&#xff0c;而乙单片机通过可以让连接甲单片机的数码管数字自增加一。 定时器资源 3个定时器 中断系统 执行现程序的过程中&#xff0c;出现某些急需处理的异常情况或特殊请求&#xff0c;cpu暂时中止现行程序&…...

量子纠缠式架构:当微服务同时存在于所有节点时,CAP定理是否依然成立?

一、CAP定理的经典困境 1. 传统分布式系统的三维束缚 经典权衡案例&#xff1a; 系统类型选择代价银行核心系统CP故障时拒绝服务社交网络AP短暂数据不一致物联网平台CA网络中断即崩溃 二、量子纠缠的降维打击 1. 量子微服务的超距同步 # 量子纠缠服务示例&#xff08;Qiski…...

使用rsync和inotidy-tools来进行实时备份文件夹数据

在工作中遇到这个这么个需求&#xff0c;就是我们有一个samba的文件共享服务器&#xff0c;里面存了很多文件&#xff0c;然后我想实时备份这个samba共享文件的。 1、概述 只需要在源服务器上操作&#xff0c;并在源服务器上安装好rsync和inotidy-tools&#xff0c;目标服务器…...

Spring AI 实现智能对话

1. 实现效果 2. Spring Boot 3 后端 2.1 pom.xml <!-- 管理包依赖。通过 Spring AI 的 BOM 文件统一管理所有 Spring AI 相关依赖的版本&#xff0c;确保版本一致性&#xff0c;减少冲突 --><dependencyManagement><dependencies><!-- Spring AI -->…...

2025 网络安全技术深水区探索:从 “攻防对抗” 到 “数字韧性” 的范式跃迁

引言&#xff1a;当攻击成本趋近于零&#xff0c;防御逻辑必须重构 2025 年&#xff0c;网络安全领域正经历三重根本性变革&#xff1a; 攻击者门槛坍缩&#xff1a;生成式 AI 将网络钓鱼开发效率提升 300%&#xff0c;勒索软件即服务&#xff08;RaaS&#xff09;订阅用户突破…...

学习笔记—双指针算法—移动零

双指针算法 移动零 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进…...

计算机网络全栈精讲:从 TCP/UDP 原理到 Socket 编程与 HTTP 协议实战(含代码实现)

计算机网络作为现代信息技术的基石&#xff0c;支撑着互联网、物联网、云计算等众多领域的发展。无论是前端开发者、后端工程师&#xff0c;还是运维人员&#xff0c;深入理解计算机网络原理都至关重要。本文将从网络分层模型出发&#xff0c;逐步深入讲解 TCP/UDP 协议、Socke…...

IP地址如何切换到国内别的省份?一步步指导

使用换IP工具的主要目的是通过更换设备的公网IP地址来满足特定需求&#xff0c;例如绕过限制、保护隐私或完成特定任务。以下是常见的应用场景和原因&#xff1a; 一、ip应用场景 1. 绕过IP限制 访问地域限制内容&#xff1a;某些网站或服务&#xff08;如游戏、社交平台 &am…...

c++流对象

核心概念回顾&#xff1a; C 的流库 (<iostream>, <fstream>, <sstream>) 提供了一种统一的方式来处理输入和输出&#xff0c;无论数据是来自键盘、文件还是内存中的字符串。它们都基于 std::istream (输入流基类) 和 std::ostream (输出流基类)&#xff0c…...

华为IP(5)

交换机的堆叠与集群 堆叠和集群指的是同一件事 前言: 随着企业的发展&#xff0c;企业网络的规模越来越大&#xff0c;这对企业网络提出了更高的要求&#xff1a;更高的可靠性、更低的故障恢复时间、设备更加易于管理等。 传统的园区网高可靠性技术出现故障时很难做到毫秒级…...

零信任架构下的等保 2.0 与密评密改双合规

随着《网络安全等级保护2.0》和《商用密码应用安全性评估》的深入实施&#xff0c;企业面临双重合规压力&#xff1a;既要满足等保2.0对“主动防御”和“动态防护”的要求&#xff0c;又要通过密评密改强化密码技术的合规性。传统安全架构依赖边界防护和静态密码策略&#xff0…...

华为 MRAG:多模态检索增强生成技术论文阅读

GitHub项目链接&#xff1a;https://github.com/PanguIR/MRAGSurvey 总览 多模态检索增强生成&#xff08;MRAG&#xff09;通过将文本、图像、视频等多模态数据整合到检索与生成过程中&#xff0c;显著提升了多模态大语言模型&#xff08;MLLM&#xff09;的性能。传统检索增…...

文字光影扫过动效

列子1 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>光影扫过文字动效</title><styl…...

SpringBoot配置RestTemplate并理解单例模式详解

在日常开发中&#xff0c;RestTemplate 是一个非常常用的工具&#xff0c;用来发起HTTP请求。今天我们通过一个小例子&#xff0c;不仅学习如何在SpringBoot中配置RestTemplate&#xff0c;还会深入理解单例模式在Spring中的实际应用。 1. 示例代码 我们首先来看一个基础的配置…...

计算机网络应用层(5)-- P2P文件分发视频流和内容分发网

&#x1f493;个人主页&#xff1a;mooridy &#x1f493;专栏地址&#xff1a;《计算机网络&#xff1a;自顶向下方法》 大纲式阅读笔记_mooridy的博客-CSDN博客 &#x1f493;本博客内容为《计算机网络&#xff1a;自顶向下方法》第二章应用层第五、六节知识梳理 关注我&…...

C++ TCP通信原理与实现

C 中 TCP 通信的原理基于 TCP/IP 协议栈的实现&#xff0c;以下是核心原理和关键步骤的详细说明&#xff1a; 一、TCP 通信核心原理 面向连接 通信双方需通过 三次握手 建立可靠连接&#xff0c;确保通信通道稳定。通过 四次挥手 断开连接&#xff0c;保证数据完整性。 可靠传…...

计算机网络-运输层(1)

计算机网络-运输层(1) 文章目录 计算机网络-运输层(1)5.1 运输层概述5.2 运输层端口号、复用与分用端口号基本概念端口号特性端口号分类重要说明 5.3 UDP与TCP协议对比关键区别说明 5.1 运输层概述 计算机网络体系结构中的物理层、数据链路层以及网络层共同解决了主机通过异构…...

学习spark-streaming收获

1.流处理的核心概念 •实时 vs微批处理&#xff1a;理解了 Spark Streaming 的微批处理&#xff08;Micro-Batch&#xff09;模型&#xff0c;将流数据切分为小批次&#xff08;如1秒间隔&#xff09;进行处理&#xff0c;与真正的流处理&#xff08;如Flink&#xff09;的区…...

蓝桥杯 14. 奇怪的数列

奇怪的数列 原题目链接 题目描述 从 X 星截获一份电码&#xff0c;是一些数字&#xff0c;如下&#xff1a; 13 1113 3113 132113 1113122113 ⋯⋯YY 博士经彻夜研究&#xff0c;发现了规律&#xff1a; 第一行的数字随便是什么&#xff0c;以后每一行都是对上一行 “读出…...

前端高频面试题day2

如何在vue3中使用defineAsyncComponent实现异步组件加载 在 Vue 3 中&#xff0c;使用 defineAsyncComponent 实现异步组件加载的步骤如下&#xff1a; 引入方法&#xff1a;从 Vue 中导入 defineAsyncComponent。定义异步组件&#xff1a;通过 defineAsyncComponent 包装一个…...

Linux系统之设置开机启动运行桌面环境

Linux 开机运行级别介绍与 Ubuntu 桌面环境配置指南 一、Linux 开机运行级别(Runlevel) 在传统的 Linux 系统(如 SysV init 初始化系统)中,运行级别定义了系统启动时加载的服务和资源。常见的运行级别如下: 运行级别模式用途0Halt(停机模式)关闭系统1Single User Mode…...