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

【C++程序员的自我修炼】基础语法篇(一)

心中若有桃花源

何处不是水云间


目录

命名空间

💞命名空间的定义

💞 命名空间的使用

输入输出流

 缺省参数

函数的引用

引用的定义💞

引用的表示💞

 引用的特性💞

 常量引用💞

引用的使用场景 

做参数

做返回值

 ⭐传值、传引用效率比较

 ⭐引用和指针的区别

命名空间

✨在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。

举个栗子:我想输出全局变量 rand 的值

#include<stdlib.h>
#include<stdio.h>int rand = 1;int main()
{printf("%d\n", rand);
}

我们发现 rand 重定义了,因为 #include<stdio.h> 内有以 rand 命名的函数,如果是以前我们为了解决这个问题还要憋屈的去改变量名,而现在 C++ 中的 命名空间 就可以很好的解决问题。

使用命名空间的目的对标识符的名称进行本地化 以避免命名冲突或名字污染

💞命名空间的定义

namespace是命名空间的关键字,Df是命名空间的名字,一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
namespace Df
{int rand = 10;
}
⭐命名空间可以嵌套(函数、结构体、另一个命名空间等)
namespace N1
{int a;int b;int Add(int left, int right){return left + right;}namespace N2{int c;int d;int Sub(int left, int right){return left - right;}}
}
⭐同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
namespace N1
{int a;int b;int Add(int left, int right){return left + right;}namespace N2{int c;int d;int Sub(int left, int right){return left - right;}}
}namespace N1
{int Mul(int left, int right){return left * right;}
}

💞 命名空间的使用

✨<1>加命名空间名称及作用域限定符,:: 是域限定符表示在该命名空间进行访问
namespace Df
{int a = 0;
}
int main()
{printf("a = %d\n",Df::a);system("pause");
}

✨<2>使用 using 将命名空间中某个成员引入
namespace Df
{int b = 1;
}
using Df::b;
int main()
{printf("b = %d\n", b);system("pause");
}

✨<3>使用 using namespace 命名空间名称对该空间进行展开
namespace Df
{int a = 0;int b = 1;
}
using namespace Df;
int main()
{printf("a = %d\n", a);printf("b = %d\n", b);system("pause");
}

 日常操作🔥

c++库为了防止命名冲突,就把库里面的东西都定义在一个 std 的命名空间里,所以要使用c++库中的函数方法与上述三种方法一样

<1>加命名空间名称及作用域限定符

#include<iostream>
int main()
{std::cout << "Hello world !" << std::endl;return 0;
}

 <2>使用 using 将命名空间中某个成员引入

using std::cout;
using std::endl;
cout << "Hello world !" << endl;

 <3>对全部命名空间进行展

using namespace std;
cout << "Hello world !" << endl;

一些小细节💥

<1>编译默认查找顺序:当前局部域、全局域、命名空间中查找

举个栗子

如果把对变量的查找比作在地里采菜,那么命名空间就是一个访问权限问题

局部域自己家的地
全局域外面的野地
命名空间隔壁王叔叔家的地
假如某天家里缺辣椒了,自家地里没有,那就要去外面的野地去查找,若还是没有就看看隔壁王叔叔家的地有没有(如果有也不能随便采摘,因为没有经过王叔叔的同意),有权限后才可以采摘(域限定符进行申请访问)。

<2>对全部命名空间进行展开 using namespace std (大型项目不宜使用,避免命名冲突)


输入输出流

cout 标准输出流 和 cin 标准输入流,包含于 #include<iostream> 头文件中

🌤️ >> 是流插入与 cin 搭配使用,<<是流输出与 cout 搭配使用
🌤️ 输入输出流可以自动识别变量类型不需要像 printf/scanf 输入输出时那样,需要手动控制格式
🌤️ cout cin 是全局的流对象,endl 表示换行输出
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
int main()
{int a;double b;cin >> a >> b;cout << a << b << endl;return 0;
}


 缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值

在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参

#include<iostream>
using std::cout;
using std::endl;
void Fun(int a = 10)
{cout << a << endl;
}int main(void)
{Fun();//没有指定实参则采用缺省值Fun(314);return  0;
}

缺省参数的类型

🌤️全缺省:形参都是表达式
#include<iostream>
using std::cout;
using std::endl;
void Fun(int a = 10,int b = 20,int c = 30)
{cout << a << endl;cout << b << endl;cout << c << endl;
}
int main(void)
{Fun(1);return  0;
}

注意:

<1>缺省参数不是要全部传完,没有指定实参采用该形参的缺省值

<2>缺省值必须从左往右依次传,不可以间隔

🌤️半缺省:形参部分没有表达式
#include<iostream>
using std::cout;
using std::endl;
void Fun(int a,int b = 20,int c = 30)
{cout << a << endl;cout << b << endl;cout << c << endl;
}
int main(void)
{Fun(1);return  0;
}

注意:

<1>半缺省参数必须从右往左依次来给出,不能间隔着给

void Fun(int a = 10,int b = 20,int c)
{cout << a << endl;cout << b << endl;cout << c << endl;
}
int main(void)
{Fun(1);return  0;
}


因为第三个形参 c 不是表达式,没有缺省值,而我们实参传的数值是传给 a 的所以报错

<2>缺省参数不能在函数声明和定义中同时出现

#include<iostream>
using std::cout;
using std::endl;
void Fun(int a = 10, int b = 20, int c = 30);int main()
{Fun(1);return  0;
}void Fun(int a = 10, int b = 20, int c = 30)
{cout << a << endl;cout << b << endl;cout << c << endl;
}


函数的引用

引用的定义💞

引用不是新定义一个变量,而是给已存在变量取了一个别名

编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间

引用的表示💞

🌤️类型& 引用变量名(对象名) = 引用实体
#include<iostream>
using std::cout;
using std::endl;
int main()
{int a = 10;int& b = a;cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "&a = " << &a << endl;cout << "&b = " << &b << endl;return  0;
}

 因为 b 是给 a 取的别名,我们可以看到 ab以及地址都是一样的

比如水浒传的李逵,你叫黑旋风和铁牛他都会应,这就是引用(取别名)

注意💥

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

 引用的特性💞

<1>引用在定义时必须初始化

<2>一个变量可以有多个引用

#include<iostream>
using std::cout;
using std::endl;
int main()
{int a = 10;int& b = a;int& c = b;cout << a << endl << b << endl << c;return  0;
}

<3>引用一旦引用一个实体,再不能引用其他实体

 

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

 常量引用💞

	const int a = 10;//int& ra = a;          //该语句编译时会出错,a为常量const int& ra = a;double b = 3.14;//int& rb = b;          //该语句编译时会出错,类型不同double& rb = b;int c = 10;const int& rc = c;   

加了 const 该变量是不能修改的,即成了一种常量,可以理解为只读型

而没加 const 的可理解为可读可写型

const int a = 10;
int& ra = a;

对常量a进行引用,那么我就可以通过引用ra去修改a的值,权限放大了所以是不行的

int c = 10;

const int& rc = c;  

对变量c进行引用,并将c置为不可修改的常量,权限的缩小所以是可行

const int a = 10;
const int& ra = a;

都是const加以修饰的同类型变量,权限的平移是可行的

总结

<1>权限只能缩小,不能放大,放大就会报错

<2>权限放大和缩小只针对引用和指针

<3>使用引用传参,函数内不改变参数,尽量使用 const 引用传参

引用的使用场景 

做参数

💞<1>还记得我们之前写过的两数交换的代码吗?我们之前传的是指针,我们可以用引用代替

#include<iostream>
using std::cout;
using std::endl;void Swap(int& n, int& m)
{int tmp = n;n = m;m = tmp;
}
int main()
{int a = 10, b = 20;Swap(a, b);cout << a << endl << b << endl;return  0;
}

 💞<2>还记得我们之前写过链表时传的二级指针吗?今非昔比,我们来干爆他

前期回顾:单链表

typedef int SListDataType;typedef struct SList
{SListDataType data;struct SList* next;
}SL;void SListFront(SL** head, SListDataType x)
{...
}

这是我们的第一种写法,当初为啥要传二级指针呢?

因为我们没有定义哨兵位(头节点)而我们又想改变我们的首节点,假设我们传单指针SL*,SL*是结构体指针类型,这里是形参(形参是实参的拷贝,出了作用域就销毁),而我们要想改变首节点则必须传地址,所以我们要传二级指针

当然这是我们的一种写法,用引用该如何写呢?

void SListFront(SL*& head, SListDataType x)
{...
}

如果你觉得别扭可以将结构体指针的声明放在 typedef 中像这样

typedef int SListDataType;typedef struct SList
{SListDataType data;struct SList* next;
}SL*;void SListFront(SL& head, SListDataType x)
{...
}

这样是不是好看多了!!!

做返回值

错误示范)·

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

 让我们来分析分析,以上打印的值都是 10 吗?

我们发现我们打印的第二个 ret 竟然是随机值,这是为什么呢?

因为局部变量存储在系统的栈区,出了定义域就会销毁

🌤️第一次打印原值是因为编译器在释放时会进行一次保留

Count 函数并不是直接返回 n 的

因为 Count 函数在调用结束后会销毁它所在的栈帧,连同 n 会一起销毁,所以编译器会先保存 n的值到一个寄存器中,再销毁栈帧,然后返回寄存器的值给 ret

🌤️第二次出现乱码是因为赋值后寄存器的空间被编译器销毁

当我们用上面的代码,返回的是 n 的引用时,这就不安全了。因为返回的是 n 的引用,不会创建临时空间给 n,而是直接返回 n 。 但是返回之后 n 所在的函数栈帧会被销毁,所以连同 n 一起销毁了,但是此时 ret n 这块已经不属于自己的空间的拷贝,所以 ret 是违法

那我们想二次调用 n 该怎么办呢?只要不销毁 n 就可以了,我们可以给 n 开辟静态空间:

正确写法

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

 

此时 n 是被 static 修饰过的变量,可以用引用进行返回了,因为 n 是在静态区开辟的空间在内存的堆区,而函数是在栈区开辟的空间,所以不会被销毁。其次因为在堆区返回的时候就不需要借助寄存器的临时拷贝了。

局部变量用 static 修饰,出作用域后不销毁,可以传引用返回

没有用 static 修饰的局部变量,出了作用域会被销毁栈,必须用传值返回

引用作为函数的返回值时,必须在定义函数时在函数名前&

用引用作函数的返回值的最大的好处是在内存中不产生返回值的副本(寄存器)

我们在举一个栗子~

#include<iostream>
using namespace std;
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;
}

这里为什么输出的是 7 呢?

 

就像我们学指针时遇到的野指针,在我们 free 掉不用的空间后没有将指针置为NULL,此时该指针还指向这块空间,但是值却是随机的

 

因为 c 是在栈区在第一次调用Add时,ret 为 3,Add函数的栈桢销毁,在第二次调用时,Add函数的栈桢是相同的,c 的位置覆盖为 7,再次访问 ret 此时就为 7,因此这里使用是不安全的

总结💥

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


 ⭐传值、传引用效率比较

#include <time.h>
#include<iostream>
using namespace std;
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;
}

 我们发现:引用作为返回值类型大大提高了效率

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

 ⭐引用和指针的区别

引用在语法概念上引用就是一个别名,没有独立空间,指针在底层实现上实际是有空间的

#include<iostream>
using namespace std;
int main()
{int a = 10;//指针存储a的地址int* pa = &a;//b是a的引用int& b = a;return 0;
}

 没有NULL引用,但有NULL指针

#include<iostream>
using namespace std;
int main()
{int* a = NULL;int& b = a;return 0;
}

 

 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数

#include<iostream>
using namespace std;
int main()
{double a = 10;double* b = &a;  //指针取地址cout << sizeof(b) << endl;double& c = a;   //引用cout << sizeof(c) << endl;return 0;
}

 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

#include<iostream>
using namespace std;
int main()
{double a = 10;double* b = &a; cout << b << endl;b++;cout << b << endl;double& c = a;   cout << c << endl;c++;cout << c << endl;return 0;
}

总结 💥

🌤️引用在语法概念上引用就是一个别名,没有独立空间,指针在底层实现上实际是有空间的
🌤️引用在定义时必须初始化,指针没有要求
🌤️引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何 一个同类型实体
🌤️没有NULL引用,但有NULL指针
🌤️在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数
🌤️引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
🌤️有多级指针,但是没有多级引用
🌤️访问实体方式不同,指针需要显式解引用,引用编译器自己处理
🌤️引用指针使用起来相对更安全

 

先介绍到这里啦~

有不对的地方请指出💞

 

 

相关文章:

【C++程序员的自我修炼】基础语法篇(一)

心中若有桃花源 何处不是水云间 目录 命名空间 &#x1f49e;命名空间的定义 &#x1f49e; 命名空间的使用 输入输出流 缺省参数 函数的引用 引用的定义&#x1f49e; 引用的表示&#x1f49e; 引用的特性&#x1f49e; 常量引用&#x1f49e; 引用的使用场景 做参数 做返回值…...

小狐狸JSON-RPC:钱包连接,断开连接,监听地址改变

detect-metamask 创建连接&#xff0c;并监听钱包切换 一、连接钱包&#xff0c;切换地址&#xff08;监听地址切换&#xff09;&#xff0c;断开连接 使用npm安装 metamask/detect-provider在您的项目目录中&#xff1a; npm i metamask/detect-providerimport detectEthereu…...

union在c语言中什么用途

在C语言中&#xff0c;union是一种特殊的数据类型&#xff0c;可以在同一块内存中存储不同类型的数据。它的主要用途有以下几个&#xff1a; 1. 节省内存&#xff1a;由于union只占用其成员中最大的数据类型所占用的内存空间&#xff0c;可以在不同的情况下使用同一块内存来存…...

2024年华为OD机试真题- 寻找最优的路测线路-Java-OD统一考试(C卷)

题目描述: 评估一个网络的信号质量,其中一个做法是将网络划分为栅格,然后对每个栅格的信号质量计算。路测的时候,希望选择一条信号最好的路线(彼此相连的栅格集合)进行演示。现给出R行C列的整数数组Cov,每个单元格的数值S即为该栅格的信号质量(已归一化,无单位,值越大…...

WPF 多路绑定、值转换器ValueConvert、数据校验

值转换器 valueconvert 使用ValueConverter需要实现IValueConverter接口&#xff0c;其内部有两个方法&#xff0c;Convert和ConvertBack。我们在使用Binding绑定数据的时候&#xff0c;当遇到源属性和目标控件需要的类型不一致的&#xff0c;就可以使用ValueConverter&#xf…...

【Linux多线程】线程的同步与互斥

【Linux多线程】线程的同步与互斥 目录 【Linux多线程】线程的同步与互斥分离线程Linux线程互斥进程线程间的互斥相关背景概念问题产生的原因&#xff1a; 互斥量mutex互斥量的接口互斥量实现原理探究对锁进行封装(C11lockguard锁) 可重入VS线程安全概念常见的线程不安全的情况…...

Linux网卡bond的七种模式详解

像Samba、Nfs这种共享文件系统&#xff0c;网络的吞吐量非常大&#xff0c;就造成网卡的压力很大&#xff0c;网卡bond是通过把多个物理网卡绑定为一个逻辑网卡&#xff0c;实现本地网卡的冗余&#xff0c;带宽扩容和负载均衡&#xff0c;具体的功能取决于采用的哪种模式。 Lin…...

【学习笔记】java项目—苍穹外卖day01

文章目录 苍穹外卖-day01课程内容1. 软件开发整体介绍1.1 软件开发流程1.2 角色分工1.3 软件环境 2. 苍穹外卖项目介绍2.1 项目介绍2.2 产品原型2.3 技术选型 3. 开发环境搭建3.1 前端环境搭建3.2 后端环境搭建3.2.1 熟悉项目结构3.2.2 Git版本控制3.2.3 数据库环境搭建3.2.4 前…...

C++之STL整理(2)之vector超详用法整理

C之STL整理&#xff08;2&#xff09;之vector用法&#xff08;创建、赋值、方法&#xff09;整理 注&#xff1a;整理一些突然学到的C知识&#xff0c;随时mark一下 例如&#xff1a;忘记的关键字用法&#xff0c;新关键字&#xff0c;新数据结构 C 的vector用法整理 C之STL整…...

机器学习作业二之KNN算法

KNN&#xff08;K- Nearest Neighbor&#xff09;法即K最邻近法&#xff0c;最初由 Cover和Hart于1968年提出&#xff0c;是一个理论上比较成熟的方法&#xff0c;也是最简单的机器学习算法之一。该方法的思路非常简单直观&#xff1a;如果一个样本在特征空间中的K个最相似&…...

笔记81:在服务器中运行 Carla 报错 “Disabling core dumps.”

背景&#xff1a;使用实验室提供的服务器配 Carla-ROS2 联合仿真的实验环境&#xff0c;在安装好 Carla 后运行 ./CarlaUE4.sh 但是出现 Disabling core dumps. 报错&#xff0c;而且不会出现 Carla 的窗口&#xff1b; 解决&#xff1a;运行以下命令 ./CarlaUE4.sh -carl…...

ensp中pc机访问不同网络的服务器

拓扑图如下&#xff0c;资源已上传 说明&#xff1a;pc通过2个路由访问server服务器 三条线路分别是192.168.1.0网段&#xff0c;192.168.2.0网段和192.168.3.0网段&#xff0c;在未配置的情况下&#xff0c;pc设备是访问不到server的 具体操作流程 第一&#xff1b;pc设备…...

CSGO赛事管理系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 目录 1. 系…...

win10微软拼音输入法 - bug - 在PATH变量为空的情况下,无法输入中文

文章目录 win10微软拼音输入法 - bug - 在PATH变量为空的情况下&#xff0c;无法输入中文概述笔记实验前提条件100%可以重现 - 无法使用win10拼音输入法输入中文替代的输入法软件备注备注END win10微软拼音输入法 - bug - 在PATH变量为空的情况下&#xff0c;无法输入中文 概述…...

Java安全篇-Fastjson漏洞

前言知识&#xff1a; 一、json 概念&#xff1a; json全称是JavaScript object notation。即JavaScript对象标记法&#xff0c;使用键值对进行信息的存储。 格式&#xff1a; {"name":"wenda","age":21,} 作用&#xff1a; JSON 可以作为…...

Flink系列之:Flink SQL Gateway

Flink系列之&#xff1a;Flink SQL Gateway 一、Flink SQL Gateway二、部署三、启动SQL Gateway四、运行 SQL 查询五、SQL 网关启动选项六、SQL网关配置七、支持的端点 一、Flink SQL Gateway SQL 网关是一项允许多个客户端从远程并发执行 SQL 的服务。它提供了一种简单的方法…...

Linux基础篇:解析Linux命令执行的基本原理

Linux 命令是一组可在 Linux 操作系统中使用的指令&#xff0c;用于执行特定的任务&#xff0c;例如管理文件和目录、安装和配置软件、网络管理等。这些命令通常在终端或控制台中输入&#xff0c;并以文本形式显示输出结果。 Linux 命令通常以一个或多个单词的简短缩写或单词…...

LeetCode-热题100:153. 寻找旋转排序数组中的最小值

题目描述 已知一个长度为 n 的数组&#xff0c;预先按照升序排列&#xff0c;经由 1 到 n 次 旋转 后&#xff0c;得到输入数组。例如&#xff0c;原数组 nums [0,1,2,4,5,6,7] 在变化后可能得到&#xff1a; 若旋转 4 次&#xff0c;则可以得到 [4,5,6,7,0,1,2] 若旋转 7 次…...

游戏客户客户端面经

C#和C的类的区别C# List添加100个Obj和100 int内存是怎么变化的重载和重写的区别&#xff0c;重载是怎么实现的重写是怎么实现的&#xff1f;虚函数表是类的还是对象的用过哪些C的STLVector底层是怎么实现的Vector添加一百次数据内存是怎么变化Map的底层&#xff0c;红黑树的查…...

网站业务对接DDoS高防

准备需要接入的网站域名清单&#xff0c;包含网站的源站服务器IP&#xff08;仅支持公网IP的防护&#xff09;、端口信息等。所接入的网站域名必须已完成ICP备案。如果您的网站支持HTTPS协议访问&#xff0c;您需要准备相应的证书和私钥信息&#xff0c;一般包含格式为.crt的公…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...