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

【巧学C++之西游篇】No.2 --- C++闹天宫,带着“重载“和“引用“

文章目录

  • 前言
  • 🌟一、函数重载
    • 🌏1.1.函数重载概念
    • 🌏1.2.C++支持函数重载的原理 -- 名字修饰
  • 🌟二、引用
    • 🌏2.1.引用的概念
    • 🌏2.2.引用特性
    • 🌏2.3.常引用
    • 🌏2.4.使用场景
    • 🌏2.5.传值、传引用效率比较
    • 🌏2.6.引用和指针的区别
  • 🌟三、末尾彩蛋(带你回溯时空联想之前)


前言

在这里插入图片描述

👧个人主页:@小沈熬夜秃头中୧⍤⃝❅
😚小编介绍:欢迎来到我的乱七八糟小星球🌝
📋专栏:C++
🔑本章内容:C++入门(二)
记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~


提示:以下是本篇文章正文内容,下面案例可供参考

🌟一、函数重载

函数重载

自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。
比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前者是“谁也赢不了!”,后者是“谁也赢不了!"

🌏1.1.函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题

1. 参数类型不同
#include<iostream>
using namespace std;
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
int main()
{cout << Add(1, 2) << endl;cout << Add(1.1, 2.2) << endl;return 0;
}
类型不同:一个整形一个浮点型但是函数名相同C++会自动匹配类型C却不能
2. 参数个数不同
#include<iostream>
using namespace std;
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
int main()
{f();f(10);return 0;
}
3. 参数类型顺序不同
#include<iostream>
using namespace std;
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{f(10, 'a');f('a', 10);return 0;
}
注意:是参数类型的顺序不同不是形参的名字不同
#include<iostream>
using namespace std;
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(int b, char a)
{cout << "f(int b, char a)" << endl;
}

请添加图片描述

注意:返回值不同不能构成重载
#include<iostream>
using namespace std;
void f(char a, int b)
{cout << "f(int a,char b)" << endl;
}
int f(char a, int b)
{cout << "f(int a, char b)" << endl;
}
int main()
{return 0;
}

请添加图片描述

4. 重载与缺省参数的碰撞擦出的火花
#include<iostream>
using namespace std;
//构成函数重载
void func(int a)
{cout << "void func(int a)" << endl;
}
void func(int a, int b = 1)
{cout << "void func(int a,int b)" << endl;
}
int main()
{func(1,2);//调用存在歧义func(10);return 0;
}

重载和缺省参数碰撞是可以构成重载的(参数个数不同),但是会出现调用歧义(当调用func(1,2)是不会出现问题的,但是调用func(10),编译器就不知道调用哪个因为两个都符合调用)

🌏1.2.C++支持函数重载的原理 – 名字修饰

为什么C++支持函数重载,而C语言不支持函数重载呢

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接,最终形成一个可执行程序

1. 对于C语言示例:

对于C语言来说,当经过预处理、编译、汇编、链接

//#include<iostream>
//using namespace std;
void func(int i, double d)
{//cout << "void func(int i, double d)" << endl;
}
void func(double d, int i)
{//cout << "double func(double d, int i)" << endl;
}
int main()
{func(1, 5.2);func(5.2, 1);return 0;
}
效果演示:

请添加图片描述

2. 对于C++示例:
#include<iostream>
using namespace std;
void func(int i, double d)
{//cout << "void func(int i, double d)" << endl;
}
void func(double d, int i)
{//cout << "double func(double d, int i)" << endl;
}
int main()
{func(1, 5.2);func(5.2, 1);return 0;
}
效果演示:

在这里插入图片描述

名字修饰:

先提前说明一下,这部分不懂得可以看C语言—程序环境和预处理(底层原理万字详解)

请添加图片描述

实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们可以知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。那么怎么办呢?

  • 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。
  • 那么链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的函数名修饰规则
  • 使用g++修饰后的名字通过下面我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】
1. 采用C语言编译器编译后结果:

结论:在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变

2. 采用C++编译器编译后结果:

请添加图片描述

结论:在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参
数类型信息添加到修改后的名字中

函数名修饰规则带入返回值,返回值不能构成重载
#include<iostream>
using namespace std;
int func(double d, int i)
{cout << "void func(int i, double d)" << endl;return 0;
}
void func(double d, int i)
{cout << "double func(double d, int i)" << endl;
}
int main()
{func(1.1, 1);func(1, 1.1);return 0;
}

请添加图片描述

3. 总结:
  • 通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。
  • 如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。

🌟二、引用

🌏2.1.引用的概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
比如:孙悟空,唐僧称为"悟空",江湖上人称"齐天大圣"。
类型& 引用变量名(对象名) = 引用实体;

示例:
void TestRef()
{
int a = 10;
int& ra = a;//<====定义引用类型
printf("%p\n", &a);
printf("%p\n", &ra);
}
效果演示:

请添加图片描述

注意:引用类型必须和引用实体是同种类型的

🌏2.2.引用特性

  • 引用在定义时必须初始化
  • 一个变量可以有多个引用
  • 引用一旦引用一个实体,再不能引用其他实体
void TestRef()
{
1. 引用在定义时必须初始化
int a = 10;
// int& ra; // 该条语句编译时会出错2. 一个变量可以有多个引用
int& ra = a;//给a取别名
int& rra = a;//给a取别名
int& raa = ra;//给b(a的别名)取别名也是可以的3. 引用一旦引用一个实体,再不能引用其他实体(C++的引用不可以改变指向但是Java可以)
int x = 1;
b = x; 
//这里是赋值而不是把b变成x的别名
}

在这里插入图片描述

🌏2.3.常引用

void TestConstRef()
{
权限的放大:就相当于带上金箍圈的孙悟空(const)摘下了金箍圈变得肆无忌惮
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量 --- 权限的放大在这里去掉了const也就是去掉了金箍圈
const int& ra = a;--- 权限的平移:带上金箍圈无论是孙悟空还是齐天大圣它都有限制不会肆无忌惮权限的缩小:本来是大闹天宫的齐天大圣被戴上了金箍圈(const)就有了限制
int x=10;
const int& y=x;double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
在C/C++中有规定:发生类型转换,会产生一个临时变量,例如上面这一小段代码const int& rd = d,转换时会有一个int类型的临时变量,临时变量再给rd,但是临时变量具有常性int& rd = d这里就是权限的放大不能通过编译,所以这种是对的const int& rd = d// int& b = 10; // 该语句编译时会出错,b为常量 - 不能变成常量对象的别名
const int& b = 10;--- 权限平移
}
注意:

在引用的过程中:

  1. 权限可以平移
  2. 权限可以缩小
  3. 权限不可以放大
示例:
#include<iostream>
using namespace std;
int func()
{int a = 0;return a;
}
int main()
{const int& ret = func();return 0;
}

请添加图片描述

🌏2.4.使用场景

1. 做参数/交换两个数值:
#include<iostream>
using namespace std;
void Swap(int& left, int& right)
{int tmp = left;left = right;right = tmp;
}
int main()
{int i = 3, j = 6;Swap(i, j);cout << i << endl;cout << j << endl;return 0;
}
效果演示:

请添加图片描述

2. 做返回值:
1. 传值返回:不是把n返回给ret,n在Count函数栈帧里面,函数调用结束栈帧也就销毁了

实际原理:是会生成一个临时变量(可能寄存器充当也可能其他方式),n会在返回值之前拷贝给临时变量,临时变量不会在Count函数的栈帧,一般是在寄存器或者上一层函数的栈帧

#include<iostream>
using namespace std;
int Count()
{int n = 0;n++;// ...return n;
}
int main()
{int ret = Count();return 0;
}
2. 传引用返回第一种:返回的是n的别名/n的引用

会出现类似野指针的危险:n都销毁了,在访问n的别名
问:n都销毁了还能访问它的别名吗?
答:可以,因为空间销毁并不是这块空间就没了而是被系统回收,就像酒店里的房间,退房后房间不会消失而是被回收你的入住权租给别人或者空着,而野指针就是退房后你还偷偷藏了房间的钥匙,然后偷偷跑进房间。但是这里不是野指针,返回n的别名是不合法的

#include<iostream>
using namespace std;
int& Count()
{int n = 0;n++;// ...return n;
}
int main()
{int ret = Count();cout << ret << endl;cout << ret << endl;return 0;
}

请添加图片描述

效果演示:

程序的结果有两种可能:1和随机值------>调用函数返回n的别名,当int ret=Count(),函数Count()栈帧已经销毁了,再去访问这块空间就会出现两种可能性第一种是1拷贝给ret,还有一种可能是随机值(取决于栈帧销毁后空间是否会被置成随机值取决于编译系统)请添加图片描述

3. 传引用返回第二种:

这种代表ret也是n的别名,第一次访问打印ret是1,第二次就变成了随机值为什么
知识点补充:cout是一个函数调用,(调用函数先传参)第一次先传参取到的还是1然后进行函数调用,Count函数的栈帧销毁,第一次函数调用占用的还是那块空间只不过可能比之前Count函数栈帧大或者小此时函数调用覆盖这块空间而ret还是这块空间的别名所以取到的就是一个随机值,但也不一定是随机值,当Count函数栈帧很大n在下面,就不会被覆盖

#include<iostream>
using namespace std;
int& Count()
{int n = 0;n++;// ...return n;
}
int main()
{int& ret = Count();cout << ret << endl;cout << ret << endl;return 0;
}
效果演示:

请添加图片描述

4. 例题及构图解析:
int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :"<< ret <<endl;return 0;
}

在这里插入图片描述

3. 注意:

注意:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。

🌏2.5.传值、传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低

1. 值和引用作为函数参数的性能比较:
#include<iostream>
using namespace std;
#include <time.h>
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{A a;// 以值作为函数参数size_t begin1 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作为函数参数size_t begin2 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc2(a);size_t end2 = clock();// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{TestRefAndValue();return 0;
}
效果演示:

请添加图片描述

2. 值和引用的作为返回值类型的性能比较:
#include<iostream>
using namespace std;
#include <time.h>
struct A { int a[10000]; };
A a;//值返回
A TestFunc1() { return a; }//引用返回
A& TestFunc2() { return a; }
void TestReturnByRefOrValue()
{//以值作为函数的返回值类型size_t begin1 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc1();size_t end1 = clock();//以引用作为函数的返回值类型size_t begin2 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc2();size_t end2 = clock();//计算两个函数运算完成之后的时间cout << "TestFunc1 time:" << end1 - begin1 << endl;cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
int main()
{TestReturnByRefOrValue();return 0;
}
效果演示:

请添加图片描述

通过上述代码的比较,发现传值和指针在作为传参以及返回值类型上效率相差很大

3. 总结:

传引用传参(任何时候都可以用)

  1. 提高效率
  2. 输出型参数(形参的修改,影响的实参)

传引用返回(出了函数作用域对象还在才可以用)

  1. 提高效率
  2. 修改返回对象(末尾彩蛋处有体现)

🌏2.6.引用和指针的区别

1. 在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间:
#include<iostream>
using namespace std;
int main()
{int a = 10;int& ra = a;cout << "&a = " << &a << endl;cout << "&ra = " << &ra << endl;return 0;
}

在这里插入图片描述

2. 在底层实现上实际是有空间的,因为引用是按照指针方式来实现的:
#include<iostream>
using namespace std;
int main()
{int a = 0;int* p1 = &a;int& ref = a;++(*p1);++ref;return 0;
}

请添加图片描述

引用和指针的不同点:

引用和指针的不同点:

  • 引用概念上定义一个变量的别名,指针存储一个变量地址。
  • 引用在定义时必须初始化,指针没有要求
  • 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  • 没有NULL引用,但有NULL指针
  • 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
  • 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  • 有多级指针,但是没有多级引用
  • 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  • 引用比指针使用起来相对更安全

🌟三、末尾彩蛋(带你回溯时空联想之前)

1. C设计顺序表部分接口
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
struct SeqList
{int a[10];int size;
};
//读取第i个位置的接口
int SLAT(struct SeqList* ps, int i)
{assert (i <ps->size) ;return ps->a [i];
}
//修改第i个位置的接口
void SLModify(struct SeqList* ps, int i, int x)
{assert(i < ps->size);ps->a[i] = x;
}
int main()
{return 0;
}
2. C++设计顺序表部分接口
#include<iostream>
#include<assert.h>
#include<stdlib.h>
using namespace std;struct SeqList
{int a[10];int size;
};
int& SLAT(struct SeqList& ps, int i)
{assert(i < ps.size);return (ps.a[i]);
}
int main()
{struct SeqList s;s.size = 3;SLAT(s, 0) = 10;SLAT(s, 1) = 20;SLAT(s, 2) = 30;cout << SLAT(s, 0) << endl;cout << SLAT(s, 1) << endl;cout << SLAT(s, 2) << endl;return 0;
}
效果演示:

请添加图片描述

  1. 读取i位置:减少了拷贝,返回此时位置的别名
  2. 修改i位置:数组中第i个位置的值出了作用域肯定还在,因为结构体在外面不在函数的栈帧里面所以存在,出了作用域不会销毁,得到它的别名后,通过赋值加加等就会修改
  3. 如果不用引用返回的就是它的临时拷贝打印是没有问题的修改却是不可以的因为临时对象具有常性不能修改

相关文章:

【巧学C++之西游篇】No.2 --- C++闹天宫,带着“重载“和“引用“

文章目录 前言&#x1f31f;一、函数重载&#x1f30f;1.1.函数重载概念&#x1f30f;1.2.C支持函数重载的原理 -- 名字修饰 &#x1f31f;二、引用&#x1f30f;2.1.引用的概念&#x1f30f;2.2.引用特性&#x1f30f;2.3.常引用&#x1f30f;2.4.使用场景&#x1f30f;2.5.传…...

【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)

【关键字】 音频编码、管道模式、createEncoder 【写在前面】 在使用API6开发HarmonyOS应用时&#xff0c;如何将pcm源文件进行编码并写入文件&#xff0c;最后生成aac文件&#xff0c;本文直接附上主要代码开发步骤供大家参考。 【主要功能代码】 import ohos.media.codec.…...

KaiwuDB CTO 魏可伟:回归用户本位,打造“小而全”的数据库

8月16日&#xff0c;KaiwuDB 受邀亮相第十四届中国数据库技术大会 DTCC 2023。KaiwuDB CTO 魏可伟接受大会主办方的采访&#xff0c;双方共同围绕“数据库架构演进、内核引擎设计以及不同技术路线”展开深度探讨。 以下是采访的部分实录 ↓↓↓ 40 多年前&#xff0c;企业的数…...

行业追踪,2023-08-22

自动复盘 2023-08-22 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…...

浏览器安装selenium驱动,以Microsoft Edge安装驱动为例

Selenium是一个用于Web应用程序测试的自动化工具。它可以直接在浏览器中运行&#xff0c;模拟真实用户对浏览器进行操作。利用selenium&#xff0c;可以驱动浏览器执行特定的动作&#xff0c;比如&#xff1a;点击、下拉等等&#xff0c;还可以获取浏览器当前呈现的页面的源代码…...

边缘计算网关是如何提高物联网的效率的?

随着物联网的持续发展&#xff0c;物联网应用的丰富和规模的扩大&#xff0c;带来了海量的数据处理、传输和计算需求。 传统的“数据中央处理”模式越来越难以适应物联网的扩展速度&#xff0c;在这一趋势下&#xff0c;边缘计算在物联网系统的部署运营中就发挥出了显著的增效…...

AWVS安装~Windows~激活

目录 1.下载安装包 2.双击acunetix_15.1.221109177.exe进行安装 3.配置C:\Windows\System32\drivers\etc\hosts 4.复制wvsc.exe到C:\Program Files (x86)\Acunetix\15.1.221109177下 5.复制license_info.json与wa_data.dat到C:\ProgramData\Acunetix\shared\license下&…...

ATFX汇市:杰克逊霍尔年会降至,鲍威尔或再发鹰派言论

环球汇市行情摘要—— 昨日&#xff0c;美元指数下跌0.11%&#xff0c;收盘在103.33点&#xff0c; 欧元升值0.22%&#xff0c;收盘价1.0898点&#xff1b; 日元贬值0.58%&#xff0c;收盘价146.23点&#xff1b; 英镑升值0.18%&#xff0c;收盘价1.2757点&#xff1b; 瑞…...

Zipkin开源的分布式链路追踪系统

Zipkin是一款开源的分布式链路追踪系统,主要功能包括: 1. 采集跟踪数据 - Zipkin client库负责收集并上报各服务的请求信息。 2. 存储跟踪数据 - 存储层默认采用Zipkin自带的基于内存的快速存储,也支持整合MySQL、Cassandra等外部存储。 3. 查询接口 - 提供RESTful API进行跟…...

java 项目运行时,后端控制台出现空指针异常---java.lang.NullPointerException

项目场景&#xff1a; 提示&#xff1a;这里简述项目背景&#xff1a; 场景如下&#xff1a; java 项目运行时&#xff0c;后端控制台出现如下图所示报错信息&#xff1a;— 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; java 项目运行时&#xff0c;后…...

模型数据处理-数据放入 session和@ModelAttribute 实现 prepare 方法详细讲解

&#x1f600;前言 本文详细讲解了模型数据处理-数据放入 session和ModelAttribute 实现 prepare 方法详细讲解 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c…...

关于android studio 几个简单的问题说明

自信是成功的第一步。——爱迪生 1. android studio 如何运行不同项目是否要更换不同的sdk 和 gradle 2.编译Gradle总是错误为什么 3.如何清理android studio 的缓存 4. 关于android Studio中的build 下面的rebuild project...

angular常用命令

文章目录 1. 创建新项目&#xff1a;2. 生成组件&#xff1a;3. 生成模块&#xff1a;4. 生成服务&#xff1a;5. 运行项目&#xff1a;6. 构建项目&#xff1a;其他 在 Angular 开发中&#xff0c;以下是一些常用的 Angular CLI 命令&#xff1a; 1. 创建新项目&#xff1a; …...

uni-app打包后安卓不显示地图及相关操作详解

新公司最近用uni-app写app&#xff0c;之前的代码有很多问题&#xff0c;正好趁着改bug的时间学习下uni-app。 问题现象&#xff1a; 使用uni-app在浏览器调试的时候&#xff0c;地图是展示的&#xff0c;但是打包完成后&#xff0c;在app端是空白的。咱第一次写app&#xff…...

elelementui组件

一、按钮 1、按钮样式 使用type、plain、round和circle属性来定义 Button 的样式。 2、主要代码 <el-row><el-button>默认按钮</el-button><el-button type"primary">主要按钮</el-button><el-button type"success">…...

什么是安全测试报告,怎么获得软件安全检测报告?

安全测试报告 软件安全测试报告&#xff1a;是指测试人员对软件产品的安全缺陷和非法入侵防范能力进行检查和验证的过程&#xff0c;并对软件安全质量进行整体评估&#xff0c;发现软件的缺陷与 bug&#xff0c;为开发人员修复漏洞、提高软件质量奠定坚实的基础。 怎么获得靠谱…...

JS中的Ajax

封装原生 Ajax 请求 在 JavaScript 中&#xff0c;可以通过封装原生的 Ajax 请求来进行与服务器的数据交互。下面是一个封装了原生 Ajax 请求的示例代码&#xff0c;以及对代码的详细注解。 1.简单的Ajax封装代码 <h2>ajax原生</h2><script>//1.创建xhr对象…...

ImportError: cannot import name ‘SQLDatabaseChain‘ from ‘langchain‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

npm、yarn和pnpm

1 node_modules安装方式 在npm3之前是以嵌套结构方式安装依赖包&#xff0c;存在两个问题&#xff1a; 依赖路径太长多个包依赖一个相同包时&#xff0c;本地磁盘会存储多个相同的包 npm3和yarn使用扁平化结构&#xff0c;node_modules变成所有包放在同一层级 注意&#xf…...

SparkSQL源码分析系列02-编译环境准备

本文主要描述一些阅读Spark源码环境的准备工作&#xff0c;会涉及到源码编译&#xff0c;插件安装等。 1. 克隆代码。 打开IDEA&#xff0c;在Git下的Clone中&#xff0c;输入 https://github.com/apache/spark&#xff0c;克隆代码到本地&#xff0c;CheckOut到目标版本Spar…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...