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

C++初学笔记整理

目录

1. C++关键字

2. 命名空间

1)命名空间的引入和概述

2)命名空间的定义

3)std与命名空间的使用

4).相关特性

3. C++输入&输出

4. 缺省参数

1 )缺省参数概念

2)使用及分类

a.全缺省

b.部分缺省

5. 函数重载

1) 函数重载概念

2)分类

3)原理

6. 引用

1)引用概念和使用

2)引用特性

3)常引用

4)使用场景

5)引用与指针

7. 内联函数

1)概念

2)特性

8. auto关键字(C++11)

1)概念和使用

2)特性

9. 基于范围的for循环(C++11)

1 )范围for的语法

2) 范围for的使用条件

10. 指针空值---nullptr(C++11)

1)NULL

2)nullptr


 

1. C++关键字

C++总计63个关键字,C语言32个关键字

asmdoifreturntrycontinue
autodoubleinlineshorttypedeffor
booldynamic_castintsignedtypeidpublic
breakelselongsizeoftypenamethrow
caseenummutablestaticunionwchar_t
catchexplicitnamespacestatic_castunsigneddefault
charexportnewstructusingfriend
classexternoperatorswitchvirtualregister
constfalseprivatetemplatevoidtrue
const_castfloatprotectedthisvolatilewhile
deletegotoreinterpret_cast


2. 命名空间

1)命名空间的引入和概述

在c++中,符号常量、变量、函数、结构、枚举、类和对象等名称将都存在于全局作用域中,用户的命名与这些名称相同而冲突的可能性非常大。并且工程越大,互相冲突性的可能性越大。另外使用标准类库时,也可能导致命名冲突。为了避免这些情况,C++引入了关键字namespace(命名空间/名字空间/名称空间)来控制标识符的作用域从而达到目的。

例如,在c里面:

int a=1;
void f1()
{int a=2;//可以取名相同,因为域不同
}
void f2()
{int a=3;
}

2)命名空间的定义

定义命名空间,需要使用到namespace关键字,后面加命名空间的名字,然后接一对{}即可,{}
中即为命名空间的成员。

//分别定义名字为A,B的命名空间
namespace A {int a = 10;void print(){cout << "A:print" << endl;}
}
namespace B {int a = 20;void print(){cout << "A:print" << endl;}
}
void test1()
{cout << "A中a = " << A::a << endl;cout << "B中a = " << B::a << endl;
}
int main()
{test1();A::print();B::print();
}

编译器默认只在全局域里查找相关变量函数等,不会进入特定的命名空间里查找。一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。需要使用特定的命名空间里的变量等,需要指定命名空间,指定命名空间需要使用"::"。

"::"是作用域限定符或者称作用域运算符(scope operator),

用法:namespace::name

3)std与命名空间的使用

std命名空间是C++中标准库类型对象的命名空间。如需要使用cout等就有多种方法。

a.  using namespce std;  -->代表把整体std展开,此时应该避免与sd里的名称冲突。

     编译器此时会去std里面查找相关内容。

b.  所有使用都用"::"指定。 

 c.  只把部分常用的展开,已经展开的不需要用"::"。

4).相关特性

a. 命名空间只能全局范围内定义

b. 命名空间可以嵌套

namespace A
{int a = 0;namespace B{int a = 100;}
}

 c. 随时把新的成员加入已有的命名空间中

namespace A
{int a = 0;}
namespace A
{int b = 100;
}
int main()
{cout << A::a << endl << A::b << endl;
}

 所以当项目里面有两个命名空间相同时,会被合并。

d. 命名空间中的函数可以在“命名空间”外定义

namespace A
{int a = 0;void A_fun();}
void A::A_fun()
{cout << " hello " << endl;
}
int main()
{A::A_fun();
}


3. C++输入&输出


#include<iostream>
using namespace std;
int main()
{int d;cin >> d;cout << d << endl;
}

1)在C++里, 如果需要使用输入输出时,必须包含< iostream >头文件,它包含了用于输入输出的对象, cout和cin是全局的流对象,cin表示标准输入、cout表示标准输出。endl是特殊的C++符号,表示换行输出。
2) <<是流插入运算符,>>是流提取运算符。
3)使用C++输入输出不需要手动控制格式,自动识别变量类型。
4) 实际上cout和cin分别是ostream和istream类型的对象,>>和<<是运算符重载。
注:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应
头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,
规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因
此推荐使用<iostream>+std的方式。


4. 缺省参数

1 )缺省参数概念

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

void fun1(int a = 100)
{cout << "a的值:" << a << endl;
}
int main()
{fun1();fun1(1);fun1(5);}

2)使用及分类

a.全缺省

void fun(int a = 1, int b = 2, int c = 2)
{cout << a << b << c << endl;
}int main()
{fun();fun(12);fun(10,20);
}

b.部分缺省

void fun(int a , int b = 2, int c = 2)
{cout << a << b << c << endl;
}
int main()
{fun(12);fun(10,20);fun(10, 20, 30);//fun(10, , 30);
}

注意:

!缺省参数不能在函数声明和定义中同时出现,一般都在声明中给出。

!缺省值必须是常量或者全局变量

5. 函数重载

1) 函数重载概念

在开发中,有时候我们可能需要实现几个功能类似的函数,只是有些细节不同。例如希望交换两个变量的值,两个变量有多种类型,可以是 int、float、char、bool 等,在C语言中,只能分别设计出各个不同名的函数。

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

void swap(int* a, int* b)
{int ret = *a;*a = *b;*b = ret;
}
void swap(double* a, double* b)
{double ret = *a;*a = *b;*b = ret;
}

2)分类

a、参数类型不同

int Add(int left, int right)
{
return left + right;
}
double Add(double left, double right)
{
return left + right;
}


b、参数个数不同

void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f()" << endl;
}

c、参数类型顺序不同

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;
}

注意:函数的返回值不同时不能完成函数重载。 

3)原理

①为什么C语言不支持函数重载?

程序在预编译阶段会经历预处理、编译、汇编和链接生成可执行程序的过程。

首先在汇编过程中编译器对每个文件都会收集全局符号并生成全局符号如果暂时找不到函数的地址(例如只有函数的声明),符号表里将会填写一个没有意义的值:

生成了多个符号表后,在链接过程中要对符号表进行合并。在合并的过程中如果函数出现了两次,——函数有效的地址值就会作为Add函数最终的地址值。C语言中因为两个重名函数的地址都是有效值,在重定位,合并符号表的时候就会产生冲突和歧义。

 ②C++为什么支持函数重载

C++会对写入符号表的同名函数进行名字修饰(name Mangling),这样函数重载的函数的名字都不一样,有效地址也不一样,这样合并符号表就不会发生冲突。

注:不同编译器名字修饰的方法不同。 图为举例。

如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为即使返回值不同,修饰的函数不同解决了符号表合并时的函数名冲突,但是真正调用时只有实参无法确定使用哪个函数。 


6. 引用

1)引用概念和使用

引用变量是一个别名,把该引用初始化为某个变量x,就可以使用该引用名称或变量名称x来读取或者修改x变量。此时两者是同一个东西。

使用方法:引用类型必须和引用实体是同种类型的

类型& 引用变量名(对象名) = 引用实体;

int a=10;

int& a_othername=a;

2)引用特性

a. 引用在定义时必须初始化
b. 一个变量可以有多个引用
c. 引用一旦引用一个实体,再不能引用其他实体

void TestRef()
{
int a = 10;
// int& ra; // 该条语句编译时会出错
int& ra = a;
int& rra = ra;
printf("%p %p %p\n", &a, &ra, &rra);
}

3)常引用

指针和引用赋值/初始化时权限只能缩小或者平移,但不能放大

​
const int a = 10;
//int& ra = a;      // 该语句编译时会出错,a为常量,需要用const类型接收
const int& ra = a;// int& b = 10;     // 该语句编译时会出错,b为常量,需要用const类型接收
const int& b = 10;double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同const int& rd = d;  //隐式类型转换/*
int i=1;
double d=i;
//隐式类型转换
*/​

  

4)使用场景

a. 做参数

void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}

b. 做返回值

1)值返回

不管返回的值在栈,堆,静态区的任何地方,值返回都会产生临时变量。

2)引用返回

只要出了函数后该返回的值还存在,就可以通过引用返回,直接将返回值返回,省去临时变量的传递。

​
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;
}​

当返回一个引用时,要注意被引用的对象不能超出作用域。所以返回一个对局部变量的引用是不合法的,但是,可以返回一个对静态变量的引用。

传值、传引用效率比较

-以引用作为参数,在传参期间,函数会直接传递实参,而传值需要多一份临时的拷贝,因此用值作为参数效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

-返回引用实际返回的是一个指向返回值的隐式指针,在内存中不会产生副本,是直接将返回值拷贝给接收变量,这样就避免产生临时变量,相比返回普通类型的执行效率更高,而且这个返回引用的函数也可以作为赋值运算符的左操作数

5)引用与指针

语法层面:引用就是一个别名,没有独立空间,和其引用实体共用同一块空间

引用在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

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

7. 内联函数

在C语言里宏分为宏常量,宏函数。然而宏具有许多不安全的问题,且不易调试。c++里引入了内联函数代替宏函数,一般提倡使用const和enum替代宏常量。

1)概念

以inline修饰的函数叫做内联函数。
我们知道,一般情况下,所有函数调用时都需要建立栈帧和传递参数。

 如果在上述函数前增加inline关键字将其改成内联函数,在编译期间编译器会把该函数的代码副本放置在每个调用该函数的地方,用函数体替换函数的调用。不会产生建立栈帧和传递参数的消耗,提升程序运行的效率。


2)特性

a. inline是一种以空间(目标文件的空间)换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
用函数体展开替换函数调用,缺陷:可能会使目标文件体积变大,优势:少了调用开销,提高程序运行效率。
b. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建
议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不
是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

 c.inline不建议声明和定义分离,分离会导致编译时链接错误。因为inline函数会被展开,没有函数地址,不会进入符号表,这样进行链接时会发生链接错误,找不到函数定义。

// F.h
#include <iostream>
using namespace std;
inline void f(int i);
// F.cpp
#include "F.h"
void f(int i)
{
cout << i << endl;
}
// main.cpp
#include "F.h"
int main()
{
f(10);
return 0;
}
// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl
f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用

d.在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。


8. auto关键字(C++11)

1)概念和使用

a.引入

随着程序越来越复杂,程序中用到的类型也越来越复杂,像:

std::map<std::string, std::string>::iterator

这样的类型太长了,特别容易写错。在C语言里可以通过typedef给类型取别名解决:

typedef std::map<std::string, std::string> Map;
int main()
{Map m{ { "apple", "苹果" },{ "orange", "橙子" }, {"pear","梨"} };Map::iterator it = m.begin();while (it != m.end()){//....}return 0;
}

但是typedef还是存在一些问题:

b.概念

为了解决这个问题,并且在编程时,常常需要把表达式的值赋值给变量,这就要求在声明变量的时候清楚地知道表达式的类型。然而有时候要做到这点并非那么容易。因此C++11给auto赋予了新的含义。auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

​
int a = 10;
auto b = a;
auto c = 'a';
auto d = fun();auto& ra=a;
auto* pa=&a;
auuto e;//error,报错​


【注意】
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto
的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编
译期会将auto替换为变量实际的类型。

2)特性

1. 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
2. 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译
器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

 c. auto不能作为函数的参数


// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}

d. auto不能直接用来声明数组


e.为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
f.auto在实际中最常见的优势用法就是跟C++11提供的新式for循环,和lambda表达式等进行配合使用。
 


9. 基于范围的for循环(C++11)

1 )范围for的语法

在C++98中如果要遍历一个数组,可以按照以下方式进行:

void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
array[i] *= 2;
for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)
cout << *p << endl;
}

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

void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
for(auto& e : array)
e *= 2;
for(auto e : array)
cout << e << " ";
return 0;
}
void TestFor(int array[])
{
for(auto& e : array)
cout<< e <<endl;
}
比

注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。


2) 范围for的使用条件

a. for循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供
begin和end的方法,begin和end就是for循环迭代的范围。
注意:以下代码就有问题,因为for的范围不确定

void TestFor(int array[])
{
for(auto& e : array)
cout<< e <<endl;
}
//函数里,数组名array已经退化成了指针

b. 迭代的对象要实现++和==的操作。


10. 指针空值---nullptr(C++11)

1)NULL

在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现
不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下
方式对其进行初始化:

int* p1 = NULL;
int* p2 = 0;

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:

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

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

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

程序本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的
初衷相悖。第二次调用时f会匹配到int参数那个。

2)nullptr

c++引入了nullptr完善NULL,其实质是(void*)0
在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器
默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void
*)0。
注意:
1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入
的。

2.在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

 


 

相关文章:

C++初学笔记整理

目录 1. C关键字 2. 命名空间 1&#xff09;命名空间的引入和概述 2&#xff09;命名空间的定义 3&#xff09;std与命名空间的使用 4).相关特性 3. C输入&输出 4. 缺省参数 1 &#xff09;缺省参数概念 2&#xff09;使用及分类 a.全缺省 b.部分缺省 5. 函数…...

记录--在Vue3这样子写页面更快更高效

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 在开发管理后台过程中&#xff0c;一定会遇到不少了增删改查页面&#xff0c;而这些页面的逻辑大多都是相同的&#xff0c;如获取列表数据&#xff0c;分页&#xff0c;筛选功能这些基本功能。而…...

【程序设计与算法(三)】测验和作业题部分答案汇总(面向对象篇)

题目来源&#xff1a;程序设计与算法&#xff08;三&#xff09;测验和作业题汇总 文章目录001:简单的swap002:难一点的swap003:好怪异的返回值004:神秘的数组初始化005:编程填空&#xff1a;学生信息处理程序006:奇怪的类复制007:返回什么才好呢008:超简单的复数类009:哪来的输…...

LeetCode 349. 两个数组的交集和 692. 前K个高频单词

两个数组的交集 难度 简单 题目链接 这道题的难度不大&#xff0c;我们可以把数组里的数据存到set里面。这样就完成了排序和去重&#xff0c;然后我们再把一个set里面的数据和另外一个set数据进行比较。如果相同就插入到数组里。 代码如下&#xff1a; 但是这个算法的时间复…...

SpringCloud的五大组件功能

SpringCloud的五大组件 EurekaRibbonHystrixZuulConfig 一、Eureka 作用是实现服务治理&#xff0c;即服务注册与发现。 Eureka服务器相当于一个中介&#xff0c;负责管理、记录服务提供者的信息。服务调用者不需要自己寻找服务 &#xff0c;而是把需求告诉Eureka &#x…...

剑指 Offer II 016. 不含重复字符的最长子字符串

题目链接 剑指 Offer II 016. 不含重复字符的最长子字符串 mid 题目描述 给定一个字符串 s&#xff0c;请你找出其中不含有重复字符的 最长连续子字符串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子字符串是 “abc”&#xff0c;所以其长度…...

HBase读取流程详解

读流程从头到尾可以分为如下4个步骤&#xff1a;Client-Server读取交互逻辑&#xff0c;Server端Scan框架体系&#xff0c;过滤淘汰不符合查询条件的HFile&#xff0c;从HFile中读取待查找Key。其中Client-Server交互逻辑主要介绍HBase客户端在整个scan请求的过程中是如何与服务…...

Redis学习(一):NoSQL概述

为什么要使用Nosql 现在是大数据时代&#xff0c;过大的数据一般的数据库无法进行分析处理了。 单机MySQL的年代 90年代&#xff0c;一个基本的网站访问量一般不会太大&#xff0c;单个数据库完全足够&#xff01; 那个时候&#xff0c;更多的去使用静态网站&#xff0c;服务器…...

ESP32设备驱动-MCP23017并行IO扩展驱动

MCP23017并行IO扩展驱动 1、MCP23017介绍 MCP23017是一个用于 I2C 总线应用的 16 位通用并行 I/O 端口扩展器。 16 位 I/O 端口在功能上由两个 8 位端口(PORTA 和 PORTB)组成。 MCP23017 可配置为在 8 位或 16 位模式下工作。 其引脚排列如下: MCP23017 在 3.3v 下工作正常…...

RabbitMQ简介

0. 学习目标 能够说出什么是消息中间件能够安装RabbitMQ能够编写RabbitMQ的入门程序能够说出RabbitMQ的5种模式特征能够使用Spring整合RabbitMQ 1. 消息中间件概述 1.1. 什么是消息中间件 MQ全称为Message Queue&#xff0c;消息队列是应用程序和应用程序之间的通信方法。是…...

【项目设计】高并发内存池(五)[释放内存流程及调通]

&#x1f387;C学习历程&#xff1a;入门 博客主页&#xff1a;一起去看日落吗持续分享博主的C学习历程博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 也许你现在做的事情&#xff0c;暂时看不到成果&#xff0c;但不要忘记&…...

Git标签与版本发布

1. 什么是git标签 标签&#xff0c;就类似我们阅读时的书签&#xff0c;可以很轻易找到自己阅读到了哪里。 对于git来说&#xff0c;在使用git对项目进行版本管理的时候&#xff0c;当我们的项目开发到一定的阶段&#xff0c;需要发布一个版本。这时&#xff0c;我们就可以对…...

Python面向对象编程

文章目录1 作用域1.1 局部作用域2 类成员权限3 是否继承新式类4 多重继承5 虚拟子类6 内省【在运行时确定对象类型的能力】7 函数参数8 生成器1 作用域 1.1 局部作用域 1&#xff0c;当局部变量遮盖全局变量&#xff0c;使用globals()[变量名]来使用全局变量&#xff1b;2&am…...

【什么情况会导致 MySQL 索引失效?】

MySQL索引失效可能有多种原因&#xff0c;下面列举一些常见的情况&#xff1a; 数据库表数据量太小&#xff1a; 如果表的数据量非常小&#xff0c;则MySQL可能不会使用索引&#xff0c;因为它认为全表扫描的代价更小。 索引列上进行了函数操作&#xff1a; 如果在索引列上…...

Java核心知识点整理之小碎片--每天一点点(坚持呀)--自问自答系列版本

1.int和Integer Integer是int的包装类&#xff1b;int是基本数据类型。 Integer变量必须实例化后才能使用&#xff1b;int变量不需要。 Integer实际是对象的引用&#xff0c;当new一个Integer时&#xff0c;实际上是生成一个指针指向此对象&#xff1b;而int则是直接存储数据值…...

js中new Map()的使用方法

1.map的方法及属性Map对象存有键值对&#xff0c;其中的键可以是任何数据类型。Map对象记得键的原始插入顺序。Map对象具有表示映射大小的属性。1.1 基本的Map() 方法MethodDescriptionnew Map()创建新的 Map 对象。set()为 Map 对象中的键设置值。get()获取 Map 对象中键的值。…...

synchronized从入门到踹门

synchronized是什么synchronized是Java关键字&#xff0c;为了维护高并发是出现的原子性问题。技术是把双刃剑&#xff0c;多线程并发给我带来了前所未有的速率&#xff0c;然而在享受快速编程的过程&#xff0c;也给我们带来了原子性问题。如下&#xff1a;public class Main …...

ubuntu-8-安装nfs服务共享目录

Ubuntu最新版本(Ubuntu22.04LTS)安装nfs服务器及使用教程 ubuntu16.04挂载_如何在Ubuntu 20.04上设置NFS挂载 Ubuntu 20.04 设置时区、配置NTP同步 timesyncd 代替 ntpd 服务器 10.0.2.11 客户端 10.0.2.121 NFS简介 (1)什么是NFS NFS就是Network File System的缩写&#xf…...

算法练习(特辑)设计算法的常用思想

1、递推法 递推的思想是把一个复杂的庞大的计算过程转换为简单过程的多次重复&#xff0c;每一次推导的结果作为下一次推导的开始。 2、递归法 递归算法实际上是把问题转化成规模更小的同类子问题&#xff0c;先解决子问题&#xff0c;再通过相同的求解过程逐步解决更高层次…...

哈希->模拟实现+位图应用

致前行路上的人&#xff1a; 要努力&#xff0c;但不要着急&#xff0c;繁花锦簇&#xff0c;硕果累累都需要过程&#xff01; 目录 1. unordered系列关联式容器 1.1 unordered_map 1.1.1概念介绍&#xff1a; 1.1.2 unordered_map的接口说明 1.2unordered_set 1.3常见面试题oj…...

苹果手机想要传输数据到电脑怎么传输呢?

苹果手机想要传输数据到电脑怎么传输呢&#xff1f;尤其是传输数据到Windows系统&#xff0c;可能需要使用一些传输软件&#xff0c;那么常用的传输软件有哪些呢&#xff1f;下文将为大家推荐几款常用的苹果手机数据传输常用工具。近期苹果发布了iPhone14系列手机&#xff0c;如…...

Linux 练习四 (目录操作 + 文件操作)

文章目录1 基于文件指针的文件操作1.1 文件的创建&#xff0c;打开和关闭1.2 文件读写操作2 基于文件描述符的文件操作2.1 打开、创建和关闭文件2.2 文件读写2.3 改变文件大小2.4 文件映射2.5 文件定位2.6 获取文件信息2.7 复制文件描述符2.8 文件描述符和文件指针2.9 标准输入…...

自学大数据第四天~hadoop集群的搭建

Hadoop集群安装配置 当hadoop采用分布式模式部署和运行时,存储采用分布式文件系统HDFS,此时HDFS名称节点和数据节点位于不同的机器上; 数据就可以分布到多个节点,不同的数据节点上的数据计算可以并行执行了,这时候MR才能发挥其本该有的作用; 没那么多机器怎么办~~~~多几个虚拟…...

ULID和UUID

ULID&#xff1a;Universally Unique Lexicographically Sortable Identifier&#xff08;通用唯一词典分类标识符&#xff09;UUID&#xff1a;Universally Unique Identifier&#xff08;通用唯一标识符&#xff09;为什么不选择UUIDUUID 目前有 5 个版本&#xff1a;版本1&a…...

java基础面试10题

1.JVM、JRE 和 JDK 的关系 Jvm&#xff1a;java虚拟机&#xff0c;类似于一个小型的计算机&#xff0c;它能够将java程序编译后的.class 文件解释给相应平台的本地系统执行&#xff0c;从而实现跨平台。 jre&#xff1a;是运行java程序所需要的环境的集合&#xff0c;它包含了…...

Golang闭包问题及并发闭包问题

目录Golang闭包问题及并发闭包问题匿名函数闭包闭包可以不传入外部参数&#xff0c;仍然可以访问外部变量闭包提供数据隔离并发闭包为什么解决方法Golang闭包问题及并发闭包问题 参考原文链接&#xff1a;https://blog.csdn.net/qq_35976351/article/details/81986496 ​ htt…...

基频的后处理

基频归一化 基频为什么要归一化&#xff1f;为了消除人际随机差异&#xff0c;提取恒定参数&#xff0c;在语际变异中找到共性。 引言 声调的主要载体就是基频。但是对声调的感知会因人而异&#xff0c;例如某个听感上的高升调&#xff0c;不同的调查人员可能会分别描写成 […...

vue3 toRefs详解

简介 toRefs函数的作用是将响应式对象中的所有属性转换为单独的响应式数据&#xff0c;对象成为普通对象&#xff0c;并且值是关联的。在这个过程中toRefs会做以下两件事&#xff1a; 把一个响应式对象转换成普通对象对该普通对象的每个属性都做一次ref操作&#xff0c;这样每…...

Spring——AOP是什么?如何使用?

一、什么是AOP&#xff1f;在不修改源代码的情况下 增加功能二、底层是什么&#xff1f;动态代理aop是IOC的一个扩展功能&#xff0c;现有IOC&#xff0c;再有AOP&#xff0c;只是在IOC的整个流程中新增的一个扩展点而已&#xff1a;BeanPostProcessorbean的创建过程中有一个步…...

【微服务】认识微服务

目录 1.1 单体、分布式、集群 单体 分布式 集群 1.2 系统架构演变 1.2.1 单体应⽤架构 1.2.2 垂直应⽤架构 1.2.3 分布式架构 1.2.4 SOA架构 1.2.5 微服务架构 1.3 微服务架构介绍 微服务架构的常⻅问题 1.4 SpringCloud介绍 1.4.1 SpringBoot和SpringCloud有啥关…...