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

【C++】模板初阶

文章目录

  • 一. 泛型编程
    • 1.1 什么是模板
    • 1.2 为什么要使用模板
  • 二. 函数模板
    • 2.1 函数模板概念
    • 2.2 函数模板格式
    • 2.3 函数模板的原理
    • 2.4 函数模板的实例化
      • 2.4.1 隐式实例化
      • 2.4.2 显式实例化
    • 2.5 模板参数的匹配原则
  • 三. 类模板
    • 3.1 类模板的定义格式
    • 3.2 类模板的实例化
    • 3.3 在类模板外部定义成员函数
  • END


一. 泛型编程

之前我们要实现一个交换两个值的函数就需要根据参数的类型去一一实现不同的交换函数,这种方法叫作函数重载

#include<iostream>
using namespace std;
void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}
void Swap(double& left, double& right)
{double temp = left;left = right;right = temp;
}
void Swap(char& left, char& right)
{char temp = left;left = right;right = temp;
}
int main()
{int a = 1, b = 3;Swap(a, b);cout << "a = " << a << " b = " << b << endl;double d1 = 0.12, d2 = 0.21;Swap(d1, d2);cout << "d1 = " << d1 << " d2 = " << d2 << endl;char c1 = 'a', c2 = 'b';Swap(c1, c2);cout << "c1 = " << c1 << " c2 = " << c2 << endl;return 0;
}

使用函数重载虽然可以实现,但是有几个不好的地方:

1.重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数。
2.代码的可维护性比较低,一个出错可能所有的重载均出错。

那能否给编译器一个模板,让编译器根据不同的类型利用该模板来生成对应的代码呢?

答案是有的,下面来介绍一下C++模板

1.1 什么是模板

首先来介绍一下什么是泛型编程:编写与类型无关的通用代码,是代码复用的一种手段模板是C++中一种对”泛型编程“的实现方式,同时模板也是泛型编程的基础。通过模板,你可以定义一个函数或者类,而不必在定义时指定具体的类型。只有当你使用这个函数或者类时,才需要指定具体的类型。模板分为两种:

1.2 为什么要使用模板

  • 复用性:模板允许你在不同的类型上使用相同的代码,而无需重复编写类似的代码。
  • 可读性:模板代码具有更高的抽象性,使得代码更易于理解和维护。
  • 类型安全:模板可以在编译时进行类型检查,避免运行时的类型错误。

二. 函数模板

2.1 函数模板概念

函数模板是一种通用的函数框架,它使用模板参数来表示数据类型或其他参数,使得函数可以适应多种不同的数据类型,而无需为每种类型编写独立的函数定义。通过函数模板,能够以一种抽象的方式编写函数,在调用时根据实际传入的参数类型来自动生成特定类型的函数版本。

2.2 函数模板格式

template<typename T1, typename T2,…,typename Tn>
返回值类型 函数名(参数列表){ }

函数模板的一般语法如下:

template <typename T>
返回类型 函数名(参数列表) {// 函数实现
}

其中:

  • template < typename T>:声明模板的开头,typename表示模板参数是一个类型,T是模板参数的占位符。
  • 返回类型:可以是模板参数T或其他类型。
  • 参数列表:可以包含模板参数T或者其他类型。

案列:

#include<iostream>
using namespace std;
template<typename T>
void Swap(T& left, T& right)
{T temp = left;left = right;right = temp;
}
int main()
{int a = 1, b = 3;Swap(a, b);cout << "a = " << a << " b = " << b << endl;double d1 = 11.2, d2 = 12.1;Swap(d1, d2);cout << "d1 = " << d1 << " d2 = " << d2 << endl;char c1 = 'a', c2 = 'b';Swap(c1, c2);cout << "c1 = " << c1 << " c2 = " << c2 << endl;return 0;
}

注意: typename是用来定义模板参数的关键字,也可以使用class(切记:不能使用struct代替class)

2.3 函数模板的原理

函数模板的原理是通过在编译时生成特定类型的函数来实现的。函数模板本身并不是一个可以直接调用的函数,而是一个用于创建函数的模板当调用函数模板时,编译器会根据传入的参数类型实例化模板,生成一个具体的函数版本

#include<iostream>
using namespace std;
template<typename T>
void Swap(T& left, T& right)
{T temp = left;left = right;right = temp;
}
int main()
{int a = 1, b = 3;double d1 = 11.2, d2 = 12.1;char c1 = 'a', c2 = 'b';Swap(a, b);Swap(d1, d2);Swap(c1, c2);return 0;
}

在这里插入图片描述
从图中可以看出编译器根据传入参数的类型生成不同的函数。

在这里插入图片描述
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

2.4 函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化

2.4.1 隐式实例化

隐式实例化:让编译器根据实参推演出模板参数的实际类型。

#include<iostream>
using namespace std;
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 3, a2 = 5;double d1 = 10.1, d2 = 12.2;cout << Add(a1, a2) << endl; //将模板参数T推演为int类型cout << Add(d1, d2) << endl; //将模板参数T推演为double类型return 0;
}

上述例子调用了两个Add函数中,传入的两个实参类型都是相同的,如果换成不同的会发生什么呢?

在这里插入图片描述
该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演出实参类型,通过实参a1将T推演为int类型,通过实参d1将T推演为double类型,但模板参数列表中只有一个T,编译器无法确定此处到底该将T确定为int还是double类型而报错。

注意: 在模板中,编译器一般不会进行类型转换操作,因为一旦转化出现问题,编译器就需要背黑锅。所以上述例子中,编译器只能将a1推演为int类型,将d1推演为double类型,不能因为模板参数列表中只有一个T就将d1转化为int类型或将a1转化为double类型。

要解决这个问题有两种方法:

  1. 用户自己来强制转化。
  2. 使用显式实例化。
#include<iostream>
using namespace std;
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 3, a2 = 5;double d1 = 10.1, d2 = 12.2;Add(a1, int(d1)); //强制类型转换Add<int>(a1, d1); //模板参数显式实例化,下面会讲到return 0;
}

2.4.2 显式实例化

在函数名后的<>中指定模板参数的实际类型。

#include<iostream>
using namespace std;
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 3, a2 = 5;double d1 = 10.1, d2 = 12.2;//显式实例化cout << Add<int>(a1, d1) << endl;cout << Add<int>(d1, d2) << endl;cout << Add<double>(a2, d2) << endl;cout << Add<double>(a1, a2) << endl;return 0;
}

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功则编译器就会报错。

显式实例化声明语句的语法格式:

template 函数返回值类型 函数名<实例化的类型>(参数列表);

例如:

template int Add<int>(const int& left, const int& right);

注意:这是个声明语句。

2.5 模板参数的匹配原则

  1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。
#include<iostream>
using namespace std;
// 专门处理int的加法函数
int Add(int left, int right)
{return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{return left + right;
}
void Test()
{Add(1, 2); // 与非模板函数匹配,编译器不需要特化Add<int>(1, 2); // 调用编译器特化的Add版本
}
  1. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数,那么将选择模板。
#include<iostream>
using namespace std;
// 专门处理int的加法函数
int Add(int left, int right)
{return left + right;
}
//通过加法函数
template<class T1,class T2>
T1 Add(T1 left, T2 right)
{return left + right;
}
int main()
{Add(1, 2); //与非函数模板类型完全匹配,不需要函数模板实例化Add(1, 2.0); //模板函数可以生成更加匹配的版本,编译器根据实参类型生成更加匹配的Add函数return 0;
}

通过反汇编可以印证以上的观点:
在这里插入图片描述

  1. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。
  2. 函数模板中的每一个类型参数在函数参数列表中必须至少使用一次。

例如:下面函数模板的声明是不正确的,函数模板中声明了两个模板参数T1和T2,但在使用时却只使用了T1,没有使用T2。
在这里插入图片描述

  1. 模板参数名在同一模板参数列表中只能使用一次,但可在多个不同函数模板的定义或声明中重复使用。
template<class T,class T> //错误,在同一函数模板中重复定义模板参数
#include<iostream>
using namespace std;
template<class T>
void Test1(T t)
{cout << t << endl;
}template<class T> //在不同函数模板中可以使用相同的模板参数名
void Test2(T t)
{cout << t << endl;
}
int main()
{Test1(3);Test2(5);return 0;
}
  1. 模板的声明和定义所使用的模板参数名可以不相同。
#include<iostream>
using namespace std;
//函数模板的声明
template<class T>
void Test(T t); //函数模板的定义
template<class U>
void Test(U t) 
{cout << t << endl;
}
int main()
{Test(10);return 0;
}
  1. 函数模板如果有多个模板参数,则每个模板参数前都必须使用关键字typename或class修饰。
template<typename T,class U> //两个关键字可以混用
void Test1(T t, U u){}template<typename T,U> //错误,每个模板参数前都要有关键字typename或class修饰
void Test2(T t,U u){}

在这里插入图片描述

三. 类模板

类模板也是模板的一种。类模板允许程序根据不同的类型参数生成不同的类。

3.1 类模板的定义格式

类模板的声明通常使用template关键字,后跟模板类型参数列表。

template<class T1, class T2, ..., class Tn>
class 类模板名
{// 类内成员定义
};

例如:

template<class T>
class A {
public:T a; //成员变量T b; //成员变量T Add(T a, T b); //成员函数的声明
};

由于类模板包含类型参数,因此也称为参数化类,如果说类是对象的抽象,对象是 类的实例,则类模板是类的抽象,类是类模板的实例。

3.2 类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。

A<int> a; //int类型
A<double> b; //double类型

说明:

#include<iostream>
using namespace std;
template<class T>
class A {
public:T a; //成员变量T b; //成员变量T Add(T a, T b){return a + b;}
};
int main()
{A<int> a;a.Add(1, 1.2); //此处不报错,因为在创建对象a时已经指定T是int类型,//当Add()函数模板实例化时也会实例化出一个int类型的函数,它会自动将double类型的1.2转换为int类型的1。return 0;
}
  1. 当类模板有两个模板形参时,实例化类模板时,类型之间要用逗号分隔开。
#include<iostream>
using namespace std;
template<class T1,class T2>
class A {
public:T1 a; //成员变量T2 b; //成员变量T1 Add(T1 a, T2 b){return a + b;}
};
int main()
{A<int, int> a; //创建模板类的一个对象aA<int, double> b; //创建模板类的一个对象breturn 0;
}
  1. 使用new操作符创建对象的方式实例化。
A<int, int>* a = new A<int, int>;
A<int, double>* b = new A<int, double>;

注意:赋值号两边都要指明具体的数据类型,且要保持一致。

  1. 模板的声明或定义只能在全局、命名空间或类范围内进行,不能在局部、函数 范围内进行,比如不能在main()函数中声明或定义一个模板。

3.3 在类模板外部定义成员函数

类中的成员函数既可以在类中定义,也可以在类外定义。类模板中的成员函数同样 可以在类模板内定义,也可以在类模板外定义,只是在类外定义成员函数时需要带上模板头:template<模板参数表>。

在类模板外部定义成员函数的方法:

template<模板形参表>
函数返回类型 类名<模板形参名>::函数名(参数列表){}

例如:

#include<iostream>
using namespace std;
template<class T>
class A {
public:T a;T b;T Add(T a, T b);
};//在类模板外部定义成员函数
template<class T>
T A<T>::Add(T a, T b)
{return a + b;
}
int main()
{A<int> a;cout << a.Add(1, 2);return 0;
}

这里使用类模板简单实现一下栈这个数据结构。

#include<iostream>
using namespace std;
//类模板
template<class T>
class Stack {
public:Stack(size_t capacity = 4){_array = new T[capacity];_capacity = capacity;_size = 0;}~Stack(){delete[] _array;_array = nullptr;_capacity = _size = 0;}void Push(const T& data);void Pop();bool empty(){return _size == 0;}
private:T* _array;size_t _capacity;size_t _size;
};template<class T>
void Stack<T>::Push(const T& data)
{if (_size >= _capacity){T* tmp = (T*)realloc(_array, sizeof(T) * _capacity * 2);if (tmp == nullptr) {perror("扩容失败");exit(1);}_array = tmp;_capacity *= 2;}_array[_size++] = data;
}template<class T>
void Stack<T>::Pop()
{if (_size){_size--;}
}int main()
{// Stack是类名,Stack<int>才是类型Stack<int> st1; //intStack<double> st2; //doublereturn 0;
}

注意:类模板在实例化时,带有模板形参的成员函数并不随着自动被实例化,只有当它被调用或取地址时,才被实例化。

下面来调试一下:

在这里插入图片描述
通过实例化类模板来创建对象st1。

在这里插入图片描述
通过调试,编译器调用了构造函数来进行初始化st1,但是没有实例化带有模板参数的成员函数。

在这里插入图片描述
随后开始实例化类模板来创建对象st2。

END

对以上内容有异议或者需要补充的,欢迎大家来讨论!

相关文章:

【C++】模板初阶

文章目录 一. 泛型编程1.1 什么是模板1.2 为什么要使用模板 二. 函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.4.1 隐式实例化2.4.2 显式实例化 2.5 模板参数的匹配原则 三. 类模板3.1 类模板的定义格式3.2 类模板的实例化3.3 在类模板外…...

STM32学习【4】ARM汇编(够用)

目录 ARM汇编语言基础写在前面 1. ARM汇编的分类2. 关于指令集指令集切换Thumb2指令集统一汇编语言&#xff08;UAL&#xff09;常用汇编指令 3. 汇编格式立即数与伪指令 4. 操作内存的汇编指令LDR&#xff1a;从内存加载数据到CPU寄存器STR&#xff1a;将数据从寄存器存储到内…...

傅里叶分析

傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析不仅仅是一个数学工具&#xff0c;更是一种可以彻底颠覆一个人以前世界观的思维模式。但不幸的是&#xff0c;傅里叶分析的公式看起来太复…...

Jmeter插件下载及安装

1、在Jmeter官网&#xff08;Install :: JMeter-Plugins.org&#xff09;下载所需插件 2、将下载的插件复制到jmeter文件下的lib/ext文件里&#xff08;PS&#xff1a;D:\Jmeter\apache-jmeter-5.6.2\lib\ext&#xff09; 3、打开Jmeter&#xff0c;选择 选项----Plugins Manag…...

Docker迁移/var/lib/docker之后镜像容器丢失问题

迁移/var/lib/docker时&#xff0c;如果目标目录少写一个/&#xff0c;/etc/docker/daemon.json中的data-root后面需要多加一级目录docker。 若迁移命令如下 rsync -avz /var/lib/docker /home/docker/ 在/etc/docker/daemon.json中添加如下内容 "data-root": &q…...

【C++】深入理解List:双向链表的应用

凭时间赢来的东西&#xff0c;时间肯定会为之作证。 前言 这是我自己学习C的第七篇博客总结。后期我会继续把C学习笔记开源至博客上。 上一期笔记是关于C的vector类知识&#xff0c;没看的同学可以过去看看&#xff1a;【C】探索Vector&#xff1a;灵活的数据存储解决方案-CS…...

如何使用 Ollama 的 API 来生成文本

如何使用 Ollama 的 API 来生成文本 简介 生成文本 生成文本的示例 加载模型 卸载模型 简介 Ollama 提供了一个 RESTful API&#xff0c;允许开发者通过 HTTP 请求与 Ollama 服务进行交互。这个 API 覆盖了所有 Ollama 的核心功能&#xff0c;包括模型管理、运行和监控。本…...

Redis除了做缓存还有哪些应用场景

我用「现实场景代码简例」帮你彻底掌握Redis的18般武艺。先记住这句话&#xff1a;Redis是数据结构的瑞士军刀。以下分7大核心应用方向讲解&#xff1a; 一、高频面试答案速记版 1. 分布式锁 → 超市储物柜机制 2. 计数器 → 直播间点赞统计 3. 排行榜 → 游戏战力榜 4. 消息队…...

软件工程复试专业课-测试

测试 1 软件质量2 黑盒测试2.1 概念2.2 等价划分类 2.3 边值分析2.4 错误推测2.5 因果图 3 白盒测试3.1概念3.2 覆盖标准3.2.1 语句覆盖3.2.2 判断覆盖3.2.3 条件覆盖3.2.4 判定/条件覆盖3.2.5 条件组合覆盖3.2.6 路径覆盖 4 软件测试的四个阶段5 测试工具 1 软件质量 定义&…...

html css js网页制作成品——HTML+CSS甜品店网页设计(5页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Maven的传递性、排除依赖、生命周期、插件

一、Maven的传递性 蓝色背景中的两个jar包是projectA的直接依赖&#xff0c;其余的Jar包是projectA的间接依赖。 projectA可以使用直接依赖&#xff0c;也可以使用间接依赖。 maven-projectB项目引入了maven-projectC(整个项目打成了jar包&#xff09;和junit两个jar包。 ma…...

Java 调试模式下 Redisson 看门狗失效

一、场景分析 前几天在做分布式锁测试&#xff1a; 在调试模式下&#xff0c;lock.lock() 之后打上断点&#xff0c;想测试一下在当前线程放弃锁之前&#xff0c;别的线程能否获取得到锁。 发现调试模式下&#xff0c;看门狗机制失效了&#xff0c;Redis 上 30 秒后&#xff0…...

PHP下载安装以及基本配置

目录 引言 官网 下载 配置 1. 鼠标右键“此电脑”>“属性” 2. 打开高级系统设置 3. 打开环境变量 4. 双击系统变量中的path 5. 新建新的path 6. 将刚刚安装的位置加入环境变量 7. 检查是否安装成功 引言 PHP&#xff08;“PHP: Hypertext Preprocessor”&#…...

Vue nextTick原理回顾

nextTick就是将异步函数放在下一次实践循环的微任务队列中执行 实现原理比较简单&#xff0c;极简版本&#xff1a; function myNextTick(cb){let p;pPromise.resolve().then(cb)return cb?p:Promise.resolve() }复杂版本&#xff0c;考虑异步函数入队、执行锁、兼容处理 l…...

【Javascript】js精度丢失

当JS处理大整数或者浮点数的时候会出现精度丢失的情况。 Javascript的数字都使用双精度浮点数表示&#xff0c;遵循IEEE754标准 比如我遇到的问题&#xff0c;对一个小数的四舍五入&#xff0c;保留2位小数&#xff1a; 235.985≈235.98 235.9851≈235.99 原理请大家参考百度&…...

Go在1.22版本修复for循环陷阱

记录 前段时间升级Go版本碰到一个大坑&#xff0c;先记录。 先上代码案例&#xff1a; func main() {testClosure() }func testClosure() {for i : 0; i < 5; i {defer func() {fmt.Println(i)}()} }在1.22之下&#xff08;不包括1.22&#xff09;版本&#xff1a; 输出的…...

服务器离线部署DeepSeek

目标 本次部署的目标是在本地服务器上部署DeepSeek。但是该服务不能连接外网&#xff0c;因此只能使用离线部署的方式。为了一次完成部署。现在云服务器上进行尝试。 云服务器部署尝试 云服务器配置 CentOS72080Ti 11GB 安装准备 1、上传iso并配置为本地yum源 安装前先将…...

PhotoDoodle: Learning Artistic Image Editing from Few-Shot Examples 论文解读

目录 一、概述 二、PhotoDoodle 1、OmniEditor的预训练 2、DiT重点 3、无噪声条件范式与CFM 4、EditLoRA 4.1关于LoRA 4.2关于EditLoRA 三、相关工作 一、概述 风格化图像编辑的论文&#xff01; 介绍了PhotoDoodle&#xff0c;一个基于扩散模型的图像编辑框架&#x…...

的pythonAPI文档含义

Open3D的pythonAPI文档含义 Open3D的pythonAPI文档含义1、相关文档1.[Open3D的python文档]2 [Open3D的cpp文档] 2、结论 >> 看了好久的文档&#xff0c;奶奶的什么个意思。1. class Type是一个枚举类&#xff0c;PointCloud等是枚举成员&#xff0c;每个成员在python有 n…...

跟着AI学vue第十三章

第十三章&#xff1a;技术传承与行业影响力塑造 到了这个阶段&#xff0c;你已经在Vue技术领域积累了深厚的经验&#xff0c;拥有了较强的技术实力。此时&#xff0c;你的重点将是把自己的知识和经验传递给更多人&#xff0c;在行业内树立起影响力&#xff0c;推动整个Vue技术…...

实现实时数据仓库开源项目

根据你的需求&#xff0c;以下是一些可以实现类似 ClickHouse 的实时数仓功能的项目&#xff0c;这些项目提供了高性能的数据处理和分析能力&#xff0c;适合实时数据仓库的场景&#xff1a; 1. Apache Doris Apache Doris 是一个开源的实时数据仓库&#xff0c;支持高吞吐量…...

实现了一个自适应的NOC路由机制,包括构建流量图、设计拥塞预测模型、优化路由策略和评估性能

以下是针对设计和实现自适应的网络 - on - chip (NOC) 路由机制的详细步骤及代码示例&#xff1a; 1. 分析NOC路由路径拥塞的原因及传统方法的不足之处 拥塞原因&#xff1a; 动态流量变化&#xff1a;芯片内不同模块的工作负载随时间变化&#xff0c;导致局部流量突然增加。…...

光速解决phpstudy无法启动MySQL服务

问题描述 在初步安装使用phpstudy时&#xff0c;会出现mysql服务启动失败的情况&#xff0c;具体表现为点击一键启动后&#xff0c;mysql启动又立即停止 原因及解决方法&#xff1a; phpstudy数据库无法启动有以下几个原因&#xff0c;可以看看自己是第几种&#xff1a; 服务名…...

2022 年 9 月青少年软编等考 C 语言五级真题解析

目录 T1. 城堡问题思路分析T2. 斗地主大师思路分析T3. 玩具摆放思路分析T4. 哥斯拉大战金刚思路分析T1. 城堡问题 1 2 3 4 5 6 7 ############################# 1 # | # | # | | ######---#####---#---#####---# 2 # # | # # # # ##…...

【原创】Ubuntu 24搭建Ollama+ DeepSeek局域网服务器

安装Ubuntu 服务器 通过ubuntu官网下载ubuntu 24服务器版本 刻录光盘&#xff08;也可以使用U盘&#xff09; 用光盘启动PC机器&#xff08;必须是带显卡的PC机&#xff0c;包括集成Intel显卡的也行&#xff0c;纯CPU计算的服务器基本上不能使用&#xff09; 最小化安装Ubuntu…...

阿里云ack的创建与实战应用案例

阿里云ack的创建与应用案例 创建前开通ack相关服务&#xff1a;开始创建简单的魔方游戏&#xff0c;熟悉sv与clb自动注册创建部署一个nginx 服务示例&#xff1a;走不同域名访问不同svc资源&#xff1a;为什么需要 Ingress &#xff1f;创建第一个域名的 Deployment和Service。…...

制造业数字化实践案例丨国内某大型物联网企业数字化项目管理系统,赋能品牌和生态战略落地

30秒快读 该大型物联网企业在规模化和业务扩展过程中&#xff0c;面临项目管理模式单一、供应链与客户端协同不足、项目过程数据透明度低、软硬件项目管理分离等痛点&#xff0c;数字化项目管理系统建设旨在构建以项目制为核心的流程型组织&#xff0c;建立内外部高效协同的项…...

当AI重构认知:技术狂潮下的教育沉思录

备注&#xff1a;文章未Deepseek R1模型辅助生成&#xff0c;如有不妥请谅解。 以下使原文&#xff1a; 我有三个娃&#xff0c;各间隔4到5岁&#xff0c;经历过搜索引擎&#xff0c;短视频&#xff0c;短剧&#xff0c;本身曾经也是教育专业出生&#xff0c;任何事务都有两面性…...

Game Maker 0.11更新:构建社交竞速游戏并增强玩家互动

在这三部分系列中&#xff0c;我们将介绍如何实现Game Maker 0.11中一些最激动人心的新功能。 欢迎来到我们系列文章的第一篇&#xff0c;重点介绍了The Sandbox Game Maker 0.11更新中的新特性。 The Sandbox Game Maker 0.11是一个多功能工具&#xff0c;帮助创作者通过游戏…...

ubuntu配置jmeter

1.前提准备 系统 ubuntu server 22.04 前提条件&#xff1a;服务器更新apt与安装lrzsz&#xff1a;更新apt&#xff1a; sudo apt update安装lrzsz: 命令行下的上传下载文件工具 sudo apt install lrzszsudo apt install zip2.安装jemeter 2.1.下载jdk17 输入命令&#xf…...

计算机毕业设计Python+DeepSeek-R1大模型考研院校推荐系统 考研分数线预测 考研推荐系统 考研(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

字段对比清洗

import pandas as pd import psycopg2 from psycopg2 import sql# 数据库连接配置 DB_CONFIG {"host": "","user": "","password": "","dbname": "","port": , }def get_excel_fi…...

过滤器 二、过滤器详解

过滤器生命周期&#xff1a; init(FilterConfig)&#xff1a;在服务器启动时会创建Filter实例&#xff0c;并且每个类型的Filter只创建一个实例&#xff0c;从此不再创建&#xff01;在创建完Filter实例后&#xff0c;会马上调用init()方法完成初始化工作&#xff0c;这个方法…...

七、Three.jsPBR材质与纹理贴图

1、PBR材质金属度和粗糙度 1、金属度metalness 金属度属性.metalness表示材质像金属的程度, 非金属材料,如木材或石材,使用0.0,金属使用1.0。 threejs的PBR材质&#xff0c;.metalness默认是0.5,0.0到1.0之间的值可用于生锈的金属外观 new THREE.MeshStandardMaterial({met…...

分布式主键生成服务

目录 一、使用线程安全的类——AtomicInteger或者AtomicLong 二、主键生成最简单写法(不推荐) 三、主键生成方法一&#xff1a;Long型id生成——雪花算法 四、主键生成方法二&#xff1a;流水号 (一)流水号概述 (二)添加配置 1.pom.xml 2.application.properties 3.创…...

【Day50 LeetCode】图论问题 Ⅷ

一、图论问题 Ⅷ 1、dijkstra算法 堆优化 采用堆来优化&#xff0c;适合节点多的稀疏图。代码如下&#xff1a; # include<iostream> # include<vector> # include<list> # include<queue> # include<climits>using namespace std;class myco…...

人大金仓KCA | 用户与角色

人大金仓KCA | 用户与角色 一、知识预备1. 用户和角色 二、具体实施1. 用户管理-命令行1.1 创建和修改用户1.2 修改用户密码1.3 修改用户的并发连接数1.4 修改用户的密码有效期 2.用户管理-EasyKStudio2.1 创建和修改用户2.2 修改用户密码2.3 修改用户的并发连接数2.4 修改用户…...

嵌入式开发:傅里叶变换(4):在 STM32上面实现FFT(基于STM32L071KZT6 HAL库+DSP库)

目录 步骤 1&#xff1a;准备工作 步骤 2&#xff1a;创建 Keil 项目&#xff0c;并配置工程 步骤 3&#xff1a;在MDK工程上添加 CMSIS-DSP 库 步骤 5&#xff1a;编写代码 步骤 6&#xff1a;配置时钟和优化 步骤 7&#xff1a;调试与验证 步骤 8&#xff1a;优化和调…...

【AI学习从零至壹】Numpy基础知识

PyTorch基础知识 Numpy基础NumPy 基本数据类型Numpy数组 NumPy 基础数组创建Numpy特殊数组创建Numpy数组的访问NumPy数组的遍历Numpy数组的常用属性比较常用的属性有&#xff1a; Numpy数组的基本操作Numpy数组的数学操作加减乘除 Numpy线性代数Numpy广播机制 Numpy基础 NumPy…...

Day11,Hot100(贪心算法)

贪心 &#xff08;1&#xff09;121. 买卖股票的最佳时机 第 i 天卖出的最大利润&#xff0c;即在前面最低价的时候买入 class Solution:def maxProfit(self, prices: List[int]) -> int:min_price prices[0]ans 0for price in prices:ans max(ans, price - min_price…...

Transformer 代码剖析1 - 数据处理 (pytorch实现)

引言 Transformer 架构自《Attention Is All You Need》论文发表以来&#xff0c;在自然语言处理领域引起了巨大的变革。它摒弃了传统的循环结构&#xff0c;完全基于注意力机制&#xff0c;显著提高了处理序列数据的效率和性能。本文将通过对一个具体的项目代码结构进行详细分…...

Python--模块(下)

3. 内置模块 3.1 os模块 常用功能&#xff1a; os.mkdir("new_dir") # 创建目录 os.listdir(".") # 列出当前目录文件 os.path.join("dir", "file.txt") # 路径拼接 os.path.abspath(__file…...

Android Studio超级详细讲解下载、安装配置教程(建议收藏)

博主介绍&#xff1a;✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神&#xff0c;答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战&#xff0c;深受全网粉丝喜爱与支持✌有…...

PS画笔工具

画笔工具&#xff1a; 画笔工具&#xff08;B&#xff09;&#xff08;原理&#xff1a;单位笔刷的连续填充&#xff0c;文件格式.abr&#xff09;&#xff1a;圆形矢量笔刷、动态矢量画笔&#xff08;旧版画笔里有 与压感笔有关&#xff09;、图案填充画笔 shift画笔&#xff…...

[Java基础] JVM常量池介绍(BeanUtils.copyProperties(source, target)中的属性值引用的是同一个对象吗)

文章目录 1. JVM内存模型2. 常量池中有什么类型&#xff1f;3. 常量池中真正存储的内容是什么4. 判断一个字符串(引用)是否在常量池中5. BeanUtils.copyProperties(source, target)中的属性值引用的是同一个对象吗&#xff1f;6. 获取堆内存使用情况、非堆内存使用情况 1. JVM内…...

1.68M 免安装多格式图片批量转 webp 无广告软件推荐

软件介绍 今天要给大家分享一款超实用的图片处理工具&#xff0c;它能实现多格式图片向 webp 格式的转换&#xff0c;无论是 jpg、png、tif、gif 还是 webp 格式自身的图片&#xff0c;都能批量且借助多线程技术进行转换。 直接打开就能用&#xff0c;体积小巧&#xff0c;仅 …...

LeetCode 1472.设计浏览器历史记录:一个数组完成模拟,单次操作均O(1)

【LetMeFly】1472.设计浏览器历史记录&#xff1a;一个数组完成模拟&#xff0c;单次操作均O(1) 力扣题目链接&#xff1a;https://leetcode.cn/problems/design-browser-history/ 你有一个只支持单个标签页的 浏览器 &#xff0c;最开始你浏览的网页是 homepage &#xff0c…...

[笔记.AI]AI知识科普提纲

仅供参考 1.AI基础认知 1.1什么是什么AI 1.2核心概念 1.2.1机器学习、深度学习、神经网络 1.2.2模型&#xff1a;模型、大模型、模型参数 1.2.3多模态 1.2.4生成式AI & 判别式AI 1.3发展与现状 2.大模型 2.1主流大模型 2.1.1分类 2.1.2各…...

学习知识的心理和方法杂记-01

前言&#xff1a; 1 学习新知识要讲究方法&#xff0c;“知识未学 方法先行”&#xff0c;写本系列文章是为了给自己加深大脑“条件反射”的&#xff0c;因为我自己学习新知识的过程中老会被不科学的“杂念”干扰&#xff0c;导致学习效率低下。 2 关于天才和普通人&#xff…...

网页制作10-html,css,javascript初认识の适用XHTML

一、简介&#xff1a; Xhtml是extensible hypertext markup language的缩写。它是由国际W3C组织制定并公布发行的。是一个过渡技术&#xff0c;结合了部分xml的强大功能及大多数html的简单特性。 Advantage. Xhtml提倡更简洁规范的代码。 Xhtml.文档在旧的基于的浏览器中&…...