C++基础入门

文章目录

  • 前言
  • 一、C++历史及发展
    • 1.C++是什么
    • 2.C++历史
  • 二、开始C++
    • 1.基础类型
      • 1.第一个简单的C++程序
      • 2.命名空间
        • 1.命名空间的介绍
        • 2.命名空间的使用
        • 3.命名空间的using声明与using指示
      • 3.初识输入输出操作
      • 4.引用
        • 1.引用概念
        • 2.引用的使用
          • 1.引用做参数
          • 2.引用做返回值
        • 3.引用和指针的区别
        • 4.const的引用
      • 5.auto关键字
        • 1.auto简介
        • 2.复合类型,常量和auto
          • 1.auto与指针和引用结合使用
    • 2.语句
      • 1.范围for
    • 3.函数
      • 1.缺省参数的函数
        • 1.缺省参数的概念
        • 2.缺省参数的分类
          • 1.全缺省参数
          • 2.半缺省参数
      • 2.函数的重载
        • 1.函数重载的概念
        • 2.调用重载的函数
      • 3.内敛函数
    • 4.其他
      • 1.nullptr

前言

C++是在C的基础之上,容纳进去了面向对象编程思想,并且增加了许多有用的库。熟悉C语言对C++学习有很大的帮助,C++是对C语言的补充和对C语言进行优化。本章我们学习一点C++的基础内容,先浅浅的了解一下C++。

一、C++历史及发展

了解一门语言,我们要先看一下它的发展历史和出现的原因,方便我们更好的了解语言适合解决什么样的问题。

1.C++是什么

在20世纪80年代, 计算机界提出了OOP(object oriented programming:面向对象)思想,为了解决C语言对于复杂的问题,规模较大的程序,需要高度的抽象和建模时的困境。
在1982年,Bjarne Stroustrup(本贾尼)博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的语言。为了表达该语言与C语言的关系,命名为C++。因此:C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

2.C++历史

1979年,贝尔实验室的Bjarne Stroustrup(本贾尼)等人试图分析unix内核的时候,试图将内核模块化,于是在C语言的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称之为C with classes。现在公司主流使用还是C++98和C++11

二、开始C++

1.基础类型

1.第一个简单的C++程序

#include<iostream>
using namespace std;
int main()
{int a = 0;int b = 0;//从键盘上获得值,相当于C语言的scanf函数cin >> a >> b;//把结果输出到屏幕,相当于C语言的printf函数cout << a + b << endl;return 0; 
}

相信大部分课本的代码案例都是如此。让我们看一下运行的结果吧.
在这里插入图片描述
这个简单的小程序就实现了,但是在C++Primer中是下面的写法:

#include<iostream>
int main()
{int a = 0;int b = 0;std::cin >> a >> b;std::cout << a + b << std::endl;return 0;
}

在这里插入图片描述
结果和上面一模一样,那么上面的using namespace std和std::分别是什么呢?为什么可以有两种写法呢?

2.命名空间

针对上面的问题,我们来介绍一下C++中的命名空间。

1.命名空间的介绍

因为变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
在这里插入图片描述
对比上面的代码我们可以看出使用了未加using namespace std在实现代码中多了一些东西,这是因为我们用到的库函数基本都属于命名空间std,例如std::cin表示标准输入中获取内容。此处使用的是作用域操作符(::),意思是编译器应该从操作符左侧的作用域来寻找右侧的名字。因此std::cin的意思是使用命名空间std的名字cin

2.命名空间的使用

当我们多个文件使用的全局变量,函数或者结构体使用的名字相同时,这时间就会产生命名冲突,在C语言中是没半法很好的解决这些问题的。如:
在这里插入图片描述
那么在C++中如何解决这些问题的呢,我们引入了命名空间这个概念。
namespace关键字,后面跟命名空间的名字,然后加一对{},{}中即为命名空间的成员
在这里插入图片描述
加入我们的命名空间就可以解决这样的问题了命名空间也是可以嵌套的。

3.命名空间的using声明与using指示

我们先看什么是using声明与using指示
在这里插入图片描述
区别:
一条using声明语句一次只引入命名空间的一个成员,它使得我们很清楚地知道程序中所用的到底是哪个名字。一条using声明语句可以出现在全局作用域,局部作用域,命名空间作用域以及类的作用域,在类的作用域中,这样的声明语句只能指向基类成员。
using指示中,我们无法控制哪些名字是可见的,因为所有名字都是可见的。且using指示不可以出现在类中。
在using指示中,以关键字using开始,后面跟namespace关键字以及命名空间的名字,如果这里的名字不是已经定义好的命名空间名字,程序将会发生错误。
命名空间只会影响使用,不会影响生命周期。
更加详细的可以看C++Primer。

3.初识输入输出操作

C++并未定义任何输入输出(IO)语句,而是包含了一个全面的标准库来提供IO机制。我们输入输出使用了iostream库,iostream库包含两个基础类型istream和ostream,分别表示输入流和输出流
标准库定义了4个IO对象,为了处理输入,我们使用了一个cin的istream类型的对象,这个对象也被称为标准输入。对于输出,我们使用了一个cou的ostream类型的对象,此对象也被称为标准输出。标准库还定义了其他两个ostream对象,分别为cerr和clog,我们一般用cerr来输出警告和错误信息,因此cerr也叫标准错误。而clog用来输出程序运行时的一般性信息。

#include<iostream>
using namespace std;
int main()
{int a = 0;int b = 0;cin >> a >> b;//标准输入cout << a + b <<endl;//标准输出return 0;
}

上面一个简单的相加程序就用到了们标准输入和标准输出。
<<(输出运算符):<<运算符接受两个运算对象:左侧的运算对象必须是一个ostream对象,右侧的对象是要打印的值。此运算符将给定的值写入到给定的ostream对象中。
>>(输入运算符):>>与输出运算符相似,它接受一个istream作为其左侧运算对象,接收一个对象作为右侧运算对象。此运算符将给定的值写入到给定的ostream对象中。

	cin >> a;cin >> b;cin >> a >> b;//效果和上面等价cout << a ;cout << b ;cout << a << b;//效果和上面等价

4.引用

1.引用概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

int main()
{//类型& 引用变量名(对象名) = 引用实体int a = 10;int& sa = a;//sa指向a(是a的另一个名字)int& saa;//报错:引用必须被初始话return 0;
}

定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用,一旦初始话完成,引用将和它的初始值对象一直绑定在一起。因为无法更改绑定对象,所以引用必须初始化!!!

int main()
{int a = 10;int& sa = a;a++;//对a进行++cout <<"sa = " << sa << endl;//sa的值也会随着发生改变sa++;//对sa进行++cout <<" a = " << a << endl;//a的值也会随着发生改变return 0;
}

在这里插入图片描述
下面我们看一些引用的例子:

int main()
{int val = 10;int rval1 = val;//把val的值赋给rval1int &rval2 = val;//rval2是val的引用int& rval3 = rval2;//rval3是rval2的引用,此时也是val的引用int& rval4 = 10;//错误:引用类型的初始值必须是一个对象double& rval5 = val;//错误:此处引用的初始值类型必须为double类型return 0;
}

在引用中,引用只能绑定在对象中,而不能与字面值或某个表达式的计算结果绑定到一起。但也有例外情况。原因也会在下面演示。

2.引用的使用

1.引用做参数
void Swap(int* a, int* b)//指针类型接收参数
{int tmp = *a;*a = *b;*b = tmp;
}
void SWAP(int &sa, int &sb)//引用类型接收参数,此时的sa就是main函数中的a,sb是main函数中的b
{int tmp = sa;sa = sb;sb = tmp;
}
int main()
{int a = 10;int b = 20;Swap(&a, &b);//指针类型的传参printf("a = %d  b = %d\n", a, b);SWAP(a, b);//引用类型传参printf("a = %d  b = %d\n", a, b);return 0;
}

在这里插入图片描述

2.引用做返回值
int& ADD(int a, int b)
{static int c = 0;c = a + b;return c;
}
int& add(int a, int b)
{int c = 0;c = a + b;return c;
}
int main()
{int a = 10;int b = 20;int& c1 = ADD(a, b);cout << c1 << endl;cout << "ADD(a, b) val is:" << c1 << endl;int& c2 = add(a, b);cout << c2 << endl;cout <<"add(a, b) val is:" << c2 << endl;return 0;
}

上面的代码有什么结果呢?
在这里插入图片描述
对比可以发现,当引用做返回值时如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。因为函数调用创建栈帧会使用该片空间。

3.引用和指针的区别

int main()
{int val = 10;int vbl = 20;int &rval = val;//rval是val的引用int* pa = &val;//pa是指向val的指针(*pa)++;cout << val << endl;rval++;cout << val << endl;pa = &vbl;//pa现在指向vblreturn 0;
}

运行结果:
在这里插入图片描述
观察汇编代码:
在这里插入图片描述
我们发现引用的汇编指令和指针的汇编指令相同,引用的底层逻辑就是指针。
引用和指针的区别:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址
  2. 引用在定义时必须初始化,引用不可以为NULL指针可以为NULL
  3. 引用初始化后就不可以更改,而指针随时更改指向对象。
  4. 在sizeof中引用结果为引用类型的大小,但指针始终是地址空间所占字节个数。
  5. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小。
  6. 有多级指针,但是没有多级引用。
  7. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  8. 引用比指针使用起来相对更安全。

4.const的引用

我们可以把引用绑定到const对象上,就像绑定到其他的对象上一样,我们称之为对常量的引用,与普通引用不同的是,对常量的的引用不能被作用修改它所绑定的对象。

int main()
{const int a = 10;const int& ra1 = a;//引用及其对象都是常量int& ra1 = a;//错误,试图让一个非常量引用指向一个常量对象
}

在我们上面看到的引用类型必须与其所引用的对象类型一致,但有两个例外:
一是在初始化常量引用时允许任意表达式作为初始值,只要该表达式的结果可以转化为引用类型即可,尤其允许为一个常量引用绑定非常量的对象,字面值,甚至是一个表达式。

int main()
{int a = 10;const int& sa1 = a;//允许将const int& 绑定到一个普通int对象上const int& sa2 = 10;//sa2是常量引用,因为sa2不可以改变,所以可以绑定到常量上const int& sa3 = sa1 * 2;//sa3是常量引用int &sa4 = sa1 * 2;//sa4是一个普通引用,不可以绑定到常量上return 0;
}

我们下面来看由duoble绑定int类型为什么不可以

int main()
{double val = 3.14;const int& sval1 = val;//正确int& sval2 = val;//错误return 0;
}

在这里插入图片描述
我们来分析一下原因:
在这里插入图片描述
类型转化都会产生临时变量,临时变量具有常属性,所以这也是为什么上面的绑定不成功的原因,我们需要用常引用来进行绑定。

5.auto关键字

1.auto简介

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的是一直没有人去使用它,于是C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。显然,auto定义的变量必须有初始值。

int Testauto()
{return 0;
}
int main()
{int a = 10;auto b = a;auto c = 'a';auto d = Testauto();cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;cout << typeid(d).name() << endl;return 0;
}

在这里插入图片描述

2.复合类型,常量和auto

编译器推断出来的auto类型有时间和初始值的类型并不完全一样,编译器会适当的改变结果类型使其更符合初始化规则

1.auto与指针和引用结合使用

使用引用其实就是使用引用的对象,特别是当引用被用作初始值时,真正参与初始化的其实是引用对象的值

int main()
{int a = 10;int& b = a;auto c = b;cout << typeid(c).name() << endl;return 0;
}

在这里插入图片描述

int main()
{int x = 10;auto a = &x;auto* b = &x;auto& c = x;cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;return 0;
}

在这里插入图片描述
从上面我们可以看出用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
要在一条语句中定义多个变量(*和&只从属于某个声明符,而非基本数据类型的一部分),初始值必须是同一类型。

int main()
{auto a = 1, b = 2;auto c = 1, d = 2.0;// 该行代码会编译失败,因为c和d的初始化表达式类型不同return 0;
}

注意:auto不能作为函数的参数, auto也不可直接声明数组。

2.语句

1.范围for

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因
此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

//语法形式
for (declaration : expression)
{statement;
}

expression:表示的必须是一个序列,如数组,vector或者string类型等类型的对象,这些类型的共同特点就是拥有能返回迭代器的begin和end成员(后面会提迭代器)
declaration:定义一个变量,序列中的每个元素都可以转换为该变量的类型。确保这些类型的最简单办法就是使用auto。
statement:循环语句。

int main()
{int tmp[] = { 1,2,3,4,5,6,7,8,9 };for (auto i : tmp){cout << i << " ";}return 0;
}

在这里插入图片描述
这就是一个简单范围for
思考一下下面的代码中数组的内容会不会改变呢?

int main()
{int tmp[] = { 1,2,3,4,5,6,7,8,9 };for (auto i : tmp){i *= 2;cout << i << " ";}cout << endl;for (auto i : tmp){cout << i << " ";}return 0;
}

在这里插入图片描述
对比发现,我们对定义变量的改变并不会影响我们数组的内容。因为我们对定义的变量是对序列中元素的拷贝。对变量的改动并不会影响我们序列中的元素。
我们再来看下面的代码:

int main()
{int tmp[] = { 1,2,3,4,5,6,7,8,9 };for (auto i : tmp){i *= 2;cout << i << " ";}cout << endl;for (auto i : tmp){cout << i << " ";}return 0;
}

在这里插入图片描述
此时我们对变量的更改影响了我们数组中的元素,因为我们第一次范围for中的定义的变量为引用,它是序列元素的别名,对这个变量的改变就相当于对数组内容的改变。
判断下面的代码是否是正确的呢?

void Testfor(int tmp[])
{for (auto& i : tmp){cout << i << " ";}
}
int main()
{int tmp[] = { 1,2,3,4,5,6,7,8,9 };return 0;
}

答案是不正确的,范围for循环迭代的范围必须是确定的,对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。
在这里插入图片描述
我们看到编译器也允许这样使用,在上面代码中数组传参,退化为了指针,此时用范围for找不begin和end的位置。

3.函数

1.缺省参数的函数

1.缺省参数的概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
如:

void Cout(int a = 0)
{cout << a << endl;
}
int main()
{int a = 10;Cout();Cout(a);return 0;
}

在这里插入图片描述
当我们没有像这个函数传入参数时,函数使用的默认值0,当我们传入参数时,函数使用我们所传递的参数。

2.缺省参数的分类

1.全缺省参数
void Cout(int a = 1, int b = 2, int c = 3)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;cout << endl;
}

上面这个就是全缺省参数的函数,所有的形参都有默认值。
下面我们来测试一下函数:

int main()
{int a = 10;int b = 20;int c = 30;Cout();Cout(a);Cout(a,b);Cout(a,b,c);Cout(c);return 0;
}

在这里插入图片描述
我们可以发现当我们传入的参数小于所需的个数时,形参会从左向右依次接收。

2.半缺省参数
void Cout(int a, int b = 2, int c = 3)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;cout << endl;
}

此时这个函数就是半缺省参数。
注意:半缺省参数必须从右往左依次来给出,不能间隔着给,且缺省参数不能在函数声明和定义中同时出现。一旦某个形参被赋予了默认值,那么他后面的所有形参都必须有默认值。

2.函数的重载

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

1.函数重载的概念

在同一作用域内的几个函数名字完全相同但形参列表不同,我们称之为重载函数

int Add(int a, int b)
{return a + b;
}
double Add(double a, double b)
{return a + b;
}
int Add(int a, double b)
{return a + b;
}
int main()
{int a = 10, b = 20;double c = 10.125, d = 20.25;cout << Add(a, b) << endl;cout << Add(c, d) << endl;return 0;
}

如上述代码中的Add就构成了重载
在这里插入图片描述
构成函数的重载必须是函数参数不相同(如个数,类型等)

2.调用重载的函数

当我们定义了一组重载函数后,我们需要合理的实参来调用他们,函数匹配是一个过程,函数匹配也叫重载确定,用编译器决定调用哪一个函数。
此时有三种情况:
1.编译器找到一个与实参最佳辟匹配的函数,并生成调用该函数。
2.找不到任何一个函数与调用的实参相匹配,此时编译器发出无匹配的错误信息。
3.有多于一个函数可以进行匹配,但每个都不是最佳选择,此时也发生错误,称为二义性调用。

如上图(出自《程序员的自我修养》p89),是vs对函数重载在编译器的名称。

3.内敛函数

我们可以将函数指定为内敛函数(inline),编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

inline int Add(int a, int b)
{return a + b;
}
int main()
{int a = 10, b = 20;int c = Add(a, b);return 0;
}

上面在编译过程展开类似下面的形式:

int c = a + b;//直接对函数进行展开

内敛说明只是向编译器发送一个请求,编译器可以忽略这个请求。
一般来说,内敛机制用于优化规模小,流程直接,调用频繁的函数,很多编译器都不支持内敛递归函数。
nline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

4.其他

1.nullptr

nullptr是一种特殊类型的字面值。
在过去的程序中用的名为NULL的预处理变量来给指针赋值,这个变量在头文件cstdilb中定义,它的值为0,因此使用NULL初始化指针和用0初始化指针是一样的。在C++中最好使用nullptr,同时尽量避免使用NULL。

void f(int)
{cout << "f(int)" << endl;
}
void f(int*)
{cout << "f(int*)" << endl;
}
int main()
{f(0);f(NULL);return 0;
}

在这里插入图片描述
我们可以发现当我们传NULL时并没有走指针的函数,所以当我们传指针类型时,避免使用NULL

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

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

相关文章

dantax参数调优

dantax参数调优 1.speed调优 可能会导致数据倾斜 处理的速度不同&#xff0c;可能会导致job非常慢 举例子&#xff0c;比如总限速是每秒100条record&#xff0c;其中第一个channel速度是每秒99条record&#xff0c;第二个channel是每秒1条record&#xff0c;加起来是每条100条…

执行上下文-通俗易懂版

(1) js引擎执行代码时候/前&#xff0c;在堆内存创建一个全局对象&#xff0c;该对象 所有的作用域&#xff08;scope&#xff09;都可以访问&#xff0c;里面会包含Date、Array、String、Number、setTimeout、setInterval等等&#xff0c;其中还有一个window属性指向自己 (2…

Kafka3.0.0版本——文件清理策略

目录 一、文件清理策略1.1、文件清理策略的概述1.2、文件清理策略的官方文档1.3、日志超过了设置的时间如何处理1.3.1、delete日志删除&#xff08;将过期数据删除&#xff09;1.3.2、compact日志压缩 一、文件清理策略 1.1、文件清理策略的概述 Kafka 中默认的日志保存时间为…

QuantLib学习笔记——看看几何布朗运动有没有股票走势的感觉

⭐️ 小鹿在乱撞 小伙伴们肯定看过股票的走势&#xff0c;真是上蹿下跳啊&#xff0c;最近小编学了一丢丢关于随机过程和QuantLib的知识&#xff0c;想利用随机过程生成一个类似股票价格走势的图&#xff0c;安排&#xff01;&#xff01;&#xff01; ⭐️ 随机过程 随机过程…

Python 之使用Numpy库来加载Numpy(.npy)文件并检查其内容

文章目录 总的介绍data.dtypedata.shapedata.ndimdata.size 总的介绍 要判断一个Numpy&#xff08;.npy&#xff09;文件的数据集类型&#xff0c;你可以使用Python中的Numpy库来加载该文件并检查其内容。以下是一些常见的步骤&#xff1a; 导入Numpy库&#xff1a; 首先&…

Kruise Rollout:基于 Lua 脚本的可扩展流量调度方案

作者&#xff1a;潘梦源 前言 Kruise Rollout [ 1] 是 OpenKruise 社区开源的渐进式交付框架。Kruise Rollout 支持配合流量和实例灰度的金丝雀发布、蓝绿发布、A/B Testing 发布&#xff0c;以及发布过程能够基于 Prometheus Metrics 指标自动化分批与暂停&#xff0c;并提供…

SSM - Springboot - MyBatis-Plus 全栈体系(四)

第二章 SpringFramework 四、SpringIoC 实践和应用 1. SpringIoC / DI 实现步骤 1.1 配置元数据&#xff08;配置&#xff09; 配置元数据&#xff0c;既是编写交给SpringIoC容器管理组件的信息&#xff0c;配置方式有三种。基于 XML 的配置元数据的基本结构&#xff1a; …

Redis-带你深入学习数据类型list

目录 1、list列表 2、list相关命令 2.1、添加相关命令&#xff1a;rpush、lpush、linsert 2.2、查找相关命令&#xff1a;lrange、lindex、llen 2.3、删除相关命令&#xff1a;lpop、rpop、lrem、ltrim 2.4、修改相关命令&#xff1a;lset 2.5、阻塞相关命令&#xff1a…

在线实时监测离子风机的功能

离子风机是一种能够通过释放大量负离子来净化空气并提供清新环境的设备。要实现联网实时在线监测离子风机&#xff0c;可以考虑以下几个步骤&#xff1a; 1. 设备接入互联网&#xff1a;离子风机需要具备网络连接功能&#xff0c;可以通过无线网络或者以太网接入路由器&#x…

SSM - Springboot - MyBatis-Plus 全栈体系(五)

第二章 SpringFramework 四、SpringIoC 实践和应用 2. 基于 XML 配置方式组件管理 2.5 实验五&#xff1a;高级特性&#xff1a;FactoryBean 特性和使用 2.5.1 FactoryBean 简介 FactoryBean 接口是Spring IoC容器实例化逻辑的可插拔性点。 用于配置复杂的Bean对象&#x…

企业数字化神经网络

随着数字化时代的到来&#xff0c;数据已经成为企业战略性资源和重要的生产要素。企业数字化转型的核心是充分开发和利用数据资源&#xff0c;以数据为驱动&#xff0c;对业务流程进行重构与创新&#xff0c;从而提升企业的核心竞争力。业务系统是企业数据资源的源头&#xff0…

RabbitMQ 知识点解读

1、AMQP 协议 1.1、AMQP 生产者的流转过程 当客户端与Broker 建立连接的时候&#xff0c;会调用factory .newConnection 方法&#xff0c;这个方法会进一步封装成Protocol Header 0-9-1 的报文头发送给Broker &#xff0c;以此通知Broker 本次交互采用的是AMQPO-9-1 协议&…

蚂蚁链发布全新Web3品牌ZAN,涉及RWA、合规等服务

9月8日&#xff0c;在外滩大会见解论坛「从科幻到科技&#xff1a;Web3、元宇宙、AIGC」现场上&#xff0c;蚂蚁集团旗下的蚂蚁链联合Everest Ventures Group、HASHKEY、Morpheus labs发布全新Web3品牌ZAN。原蚂蚁链CTO张辉担任ZAN CEO。 该品牌致力于服务Web3机构客户与Web3应…

靶场溯源第二题

关卡描述&#xff1a;1. 网站后台登陆地址是多少&#xff1f;&#xff08;相对路径&#xff09; 首先这种确定的网站访问的都是http或者https协议&#xff0c;搜索http看看。关于http的就这两个信息&#xff0c;然后172.16.60.199出现最多&#xff0c;先过滤这个ip看看 这个很…

leetcode 43.字符串相乘

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;字符串相乘 思路&#xff1a; 代码&#xff1a; class Solution { public:string multiply(string num1, string num2) {if (num1 "0" || num2 "0") {return "0";}/*0 1 2 下标1 2…

【JavaScript手撕代码】new

目录 手写 手写 /* * param {Function} fn 构造函数 * return {*} **/ function myNew(fn, ...args){if(typeof fn ! function){return new TypeError(fn must be a function)}// 先创建一个对象let obj Object.create(fn.prototype)// 通过apply让this指向obj, 并调用执行构…

Spring事务管理: 构建稳健的数据库事务处理

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

爬虫逆向实战(29)-某蜂窝详情页(cookie、混淆、MD5、SHA)

一、数据接口分析 主页地址&#xff1a;某蜂窝 1、抓包 通过抓包可以发现数据是静态的&#xff0c;在html中。 2、判断是否有加密参数 请求参数是否加密&#xff1f; 无请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 无cookie是否加密&#xff1f; 通过查看“c…

如何预防最新的Mallox变种malloxx勒索病毒感染您的计算机?

导言&#xff1a; 在数字时代&#xff0c; .malloxx 勒索病毒的威胁一直悬在我们头上&#xff0c;如何应对这种威胁&#xff0c;以及在数据被勒索后如何恢复它们&#xff0c;都是备受关注的话题。本文91数据恢复将向您介绍 .malloxx 勒索病毒的独特工作方式&#xff0c;提供与众…

stm32同芯片但不同flash工程更换Device出现报错

目录 1. 问题描述2. 解决方案 1. 问题描述 stm32同芯片但不同flash工程更换Device出现报错 2. 解决方案 更换Device&#xff0c;我是从ZE换为C8&#xff1a; 把这个从HD更换为MD 解决&#xff01;