C++13-STL模板-01向量(vector)

news2024/11/25 4:19:19

C++13-STL模板

在这里插入图片描述

在线练习:
http://noi.openjudge.cn/
https://www.luogu.com.cn/

大纲要求

【 3 】算法模板库中的函数:min、max、swap、sort
【 4 】栈 (stack)、队列 (queue)、链表 (list)、
向量(vector)等容器

1.函数模板

泛型编程

不再是针对某种类型,能适应广泛的类型
如下的交换函数:

#include <iostream>
using namespace std;

//交换int类型
void Swap(int& left, int& right)
{
    int temp = left;
    left = right;
    right = temp;
}
//利用C++支持的函数重载交换double类型
void Swap(double& left, double& right)
{
    double temp = left;
    left = right;
    right = temp;
}
main()
{
    int int_left=1,int_right=2;
    double dou_left=5.0,dou_right=6.0;
    Swap(int_left,int_right);

    printf("int_left-->%d,int_right-->%d \n",int_left,int_right);
    Swap(dou_left,dou_right);
    printf("dou_left-->%f,dou_right-->%f",dou_left,dou_right);
}

在这里插入图片描述

使用函数重载虽然可以实现不同类型的交换函数,但是有以下几个不好的地方:
重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数,使得代码重复性高,过渡冗余
代码的可维护性比较低,一个出错可能所有的重载均出错
那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

函数模板

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

函数模板的格式如下:

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

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

#include <iostream>
using namespace std;

template<typename T>
void Swap(T& rx, T& ry) {
	T tmp = rx;
	rx = ry;
	ry = tmp;
}
main()
{
    int int_left=1,int_right=2;
    double dou_left=5.0,dou_right=6.0;
    Swap(int_left,int_right);

    printf("int_left-->%d,int_right-->%d \n",int_left,int_right);
    Swap(dou_left,dou_right);
    printf("dou_left-->%f,dou_right-->%f",dou_left,dou_right);
}

在这里插入图片描述

问题:我上述交换函数调用过程中的Swap都是调用的同一个函数吗?
当然不是,这里我三次Swap不是调用同一个函数,其实我Swap的时候根据不同的类型通过模板定制出专属你的类型的函数,然后再调用, 如下图:
在这里插入图片描述

2.算法模板库中的函数:min、max、swap、sort

使用algorithm头文件,需要在头文件下加一行“using namespace std”

1.max()、min()、abs()

max(x,y)和min(x,y)分别返回x和y中的最大值和最小值,且参数必须是两个(可以是浮点数)。如果想要返回三个数x、y、z的最大值,可以使用max(x,max(y,z)的写法。

abs(x)返回x的绝对值。注意:x必须是整数,浮点型的绝对值请用math头文件下的fabs。

#include<cstdio>
#include<algorithm>
#include<math.h>
using  namespace std;
int main()
{
    int x=1,y= -2;
    float xf=1.0,yf=-2.10;
    printf("%d %d\n",max(x,y),min(x,y));
    printf("%d %d\n",abs(x),abs(y));
    printf("%.2f %.2f\n",abs(xf),abs(yf));
    printf("%.2f %.2f\n",fabs(xf),fabs(yf));
    return 0;
}

在这里插入图片描述

3.swap()

// This program demonstrates the use of the swap function template.
#include <iostream>
#include <string>
#include <algorithm> // Needed for swap
using namespace std;

int main ()
{
    // Get and swap two chars
    char firstChar, secondChar;
    cout << "Enter two characters: ";
    cin >> firstChar >> secondChar;
    swap(firstChar, secondChar);
    cout << firstChar << " " << secondChar << endl;
    // Get and swap two ints
    int firstInt, secondInt;
    cout << "Enter two integers: ";
    cin >> firstInt >> secondInt;
    swap(firstInt, secondInt);
    cout << firstInt << " " << secondInt << endl;
    // Get and swap two strings
    cout << "Enter two strings: ";
    string firstString, secondString;
    cin >> firstString >> secondString;
    swap(firstString, secondString);
    cout << firstString << " " << secondString << endl;
    return 0;
}

在这里插入图片描述

3.sort()

在C++中,sort()函数常常用来对容器内的元素进行排序,先来了解一下sort()函数。

#include<bits/stdc++.h>
using namespace std;
int a[4]={1,5,0,2};
int main()
{
    // cin>>a[1]>>a[2]>>a[3];
    sort(a+1,a+4);
    cout<<a[3]<<' '<<a[2]<<' '<<a[1];
    return 0;
}

在这里插入图片描述
sort()函数有三个参数:

第一个是要排序的容器的起始迭代器。
第二个是要排序的容器的结束迭代器。
第三个参数是排序的方法,是可选的参数。

默认的排序方法是从小到大排序,也就是less<Type>(),还提供了greater<Type>()进行从大到小排序。这个参数的类型是函数指针,less和greater实际上都是类/结构体,内部分别重载了()运算符,称为仿函数,所以实际上less<Type>()和greater<Type>()都是函数名,也就是函数指针。我们还可以用普通函数来定义排序方法。

如果容器内元素的类型是内置类型或string类型,我们可以直接用less<Type>()或greater<Type>()进行排序。但是如果数据类型是我们自定义的结构体或者类的话,我们需要自定义排序函数,有三种写法:

重载 < 或 > 运算符:重载 < 运算符,传入less<Type>()进行升序排列。重载 > 运算符,传入greater<Type>()进行降序排列。这种方法只能针对一个维度排序,不灵活。
普通函数:写普通函数cmp,传入cmp按照指定规则排列。这种方法可以对多个维度排序,更灵活。
仿函数:写仿函数cmp,传入cmp<Type>()按照指定规则排列。这种方法可以对多个维度排序,更灵活。

重写操作符号

#include <bits/stdc++.h>
using namespace std;

struct Person {
	int id;
	int age;
	Person(int id,int age):id(id),age(age){}
	//重载<运算符,进行升序排列
	bool operator < (const Person& p2) const {
		return id < p2.id;
	}
	//重载>运算符,进行降序排列
	bool operator > (const Person& p2) const {
		return id > p2.id;
	}
};

int main()
{
	Person p1(1, 10), p2(2, 20), p3(3, 30);
	vector<Person> ps;
	ps.push_back(p2);
	ps.push_back(p1);
	ps.push_back(p3);
	sort(ps.begin(), ps.end(), less<Person>());
	for (int i = 0; i < 3; i++) {
		cout << ps[i].id << " " << ps[i].age << endl;
	}
	cout << endl;
	sort(ps.begin(), ps.end(), greater<Person>());
	for (int i = 0; i < 3; i++) {
		cout << ps[i].id << " " << ps[i].age << endl;
	}
	cout << endl;
}

在这里插入图片描述

普通函数

#include <bits/stdc++.h>
using namespace std;

struct Person {
	int id;
	int age;
	Person(int id,int age):id(id),age(age){}
};

//普通函数
bool cmp(const Person& p1, const Person& p2) {
	if (p1.id == p2.id) return p1.age >= p2.age;
	return p1.id < p2.id;
}

int main()
{
	Person p1(1, 30), p2(2, 20), p3(1, 20),p4(3, 30), p5(3, 40);
	vector<Person> ps;
	ps.push_back(p2);
	ps.push_back(p1);
	ps.push_back(p3);
	ps.push_back(p4);
	ps.push_back(p5);
	sort(ps.begin(), ps.end(), cmp);//传入函数指针cmp
	for (int i = 0; i < 5; i++) {
		cout << ps[i].id << " " << ps[i].age << endl;
	}
}

在这里插入图片描述

仿函数

#include <bits/stdc++.h>
using namespace std;

struct Person {
	int id;
	int age;
	Person(int id, int age) :id(id), age(age) {}
};

//仿函数
struct cmp {
	bool operator()(const Person& p1, const Person& p2) {
		if (p1.id == p2.id) return p1.age >= p2.age;
		return p1.id < p2.id;
	}
};

int main()
{
	Person p1(1, 30), p2(2, 20), p3(1, 20),p4(3, 30), p5(3, 40);
	vector<Person> ps;
	ps.push_back(p2);
	ps.push_back(p1);
	ps.push_back(p3);
	ps.push_back(p4);
	ps.push_back(p5);
	sort(ps.begin(), ps.end(), cmp()); //传入函数指针cmp()
	for (int i = 0; i < 5; i++) {
		cout << ps[i].id << " " << ps[i].age << endl;
	}
}

在这里插入图片描述

3.STL-栈 (stack)、队列 (queue)、链表 (list)、向量(vector)等容器

3.1STL 标准模板库-向量(vector)

STL 标准模板库,由惠普实验室提供,里面集成了常用的数据结构类模板和算法函数模板等。
容器:用来存储各类型数据的数据结构。
迭代器:类似于专门用来指向容器成员的指针,用来遍历、操作、管理容器中的成员,可以大大提高容器的访问速度。
算法:STL实现了常见的排序、查找算法。
STL-栈 (stack)、队列 (queue)、链表 (list)、向量(vector)等容器

#include <vector>	

vector是变长数组,支持随机访问,不支持在任意位置O(1)插入。为了保证效率,元素的增删一般应该在末尾进行。

1. 初始化方法:

a. 通过赋值方式初始化:

std::vector<int> v1 = {1, 2, 3, 4, 5}; // 初始化一个包含5个元素的vector
std::vector<std::string> v2 = {"hello", "world"}; // 初始化一个包含2个字符串的vector

b. 通过构造函数方式初始化:

std::vector<int> v3(10); // 初始化一个包含10个元素的vector,每个元素的值为0
std::vector<int> v4(5, 2); // 初始化一个包含5个元素的vector,每个元素的值为2
std::vector<std::string> v5(3, "hello"); // 初始化一个包含3个字符串的vector,每个字符串的值为"hello"

c. 通过拷贝方式初始化:

std::vector<int> v6(v1); // 将v1中的元素拷贝到v6中

2. 常用操作函数:

1. 插入元素:

std::vector<int> v7 = {1, 2, 3};
v7.push_back(4); // 在vector的末尾插入一个元素
v7.insert(v7.begin() + 2, 5); // 在vector的第3个位置插入一个元素,值为5

2. 删除元素:

std::vector<int> v8 = {1, 2, 3,4,5};
v8.pop_back(); // 删除vector的最后一个元素
v8.erase(v8.begin() + 1); // 删除vector的第2个元素
v8.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+         3(不包括它)

3. 访问元素:

std::vector<int> v9 = {1, 2, 3};
int x = v9[1]; // 获取vector的第2个元素
int y = v9.at(2); // 获取vector的第3个元素,如果越界会抛出异常
int z = v9.front(); // 获取vector的第1个元素
int w = v9.back(); // 获取vector的最后一个元素

4. 修改元素:

std::vector<int> v10 = {1, 2, 3};
v10[1] = 4; // 修改vector的第2个元素的值为4
v10.at(2) = 5; // 修改vector的第3个元素的值为5,如果越界会抛出异常

5. 返回大小:size/empty

size函数返回vector的实际长度(包含的元素个数),empty函数返回一个bool类型,表明vector是否为空。二者的时间复杂度都是O(1)。
所有的STL容器都支持这两个方法,含义也相同,之后我们就不再重复给出。

6. clear

clear函数把vector清空。

7. 迭代器

迭代器就像STL容器的“指针”,可以用星号“*”操作符解除引用。
一个保存int的vector的迭代器声明方法为:

vector<int>::iterator it;

vector的迭代器是“随机访问迭代器”,可以把vector的迭代器与一个整数相加减,其行为和指针的移动类似。可以把vector的两个迭代器相减,其结果也和指针相减类似,得到两个迭代器对应下标之间的距离。

8. begin/end

begin函数返回指向vector中第一个元素的迭代器。例如a是一个非空的vector,则*a.begin()与a[0]的作用相同。
所有的容器都可以视作一个“前闭后开”的结构,end函数返回vector的尾部,即第n个元素再往后的“边界”。*a.end()与a[n]都是越界访问,其中n=a.size()。

下面两份代码都遍历了vector<int>a,并输出它的所有元素。

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    std::vector<int> v9 = {1, 2, 3};
    int x = v9[1]; // 获取vector的第2个元素
    int y = v9.at(2); // 获取vector的第3个元素,如果越界会抛出异常
    int z = v9.front(); // 获取vector的第1个元素
    int w = v9.back(); // 获取vector的最后一个元素

    for (int i = 0; i < v9.size(); i ++) cout << v9[i] << endl;
    for (vector<int>::iterator it = v9.begin(); it != v9.end(); it ++) cout << *it << endl;

    return 0;
}

在这里插入图片描述

3.2 STL 标准模板库-队列queue

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
在这里插入图片描述

参考:https://blog.csdn.net/weixin_44572229/article/details/120016366

#include <queue>

头文件queue主要包括循环队列queue和优先队列priority_queue两个容器。

声明

queue<int> q;
struct rec{}; queue<rec> q; 	//结构体rec中必须定义小于号
priority_queue<int> q;		// 大根堆
priority_queue<int, vector<int>, greater<int> q;	// 小根堆
priority_queue<pair<int, int>>q;

循环队列 queue

push 从队尾插入
pop 从队头弹出
front 返回队头元素
back 返回队尾元素
优先队列 priority_queue
	push 把元素插入堆
	pop 删除堆顶元素
	top 	查询堆顶元素(最大值)

3.#include
头文件stack包含栈。声明和前面的容器类似。
push 向栈顶插入
pop 弹出栈顶元素

4.#include
双端队列deque是一个支持在两端高效插入或删除元素的连续线性存储空间。它就像是vector和queue的结合。与vector相比,deque在头部增删元素仅需要O(1)的时间;与queue相比,deque像数组一样支持随机访问。
[] 随机访问
begin/end,返回deque的头/尾迭代器
front/back 队头/队尾元素
push_back 从队尾入队
push_front 从队头入队
pop_back 从队尾出队
pop_front 从队头出队
clear 清空队列

5.#include
头文件set主要包括set和multiset两个容器,分别是“有序集合”和“有序多重集合”,即前者的元素不能重复,而后者可以包含若干个相等的元素。set和multiset的内部实现是一棵红黑树,它们支持的函数基本相同。

声明
set s;
struct rec{…}; set s; // 结构体rec中必须定义小于号
multiset s;

size/empty/clear
与vector类似

迭代器
set和multiset的迭代器称为“双向访问迭代器”,不支持“随机访问”,支持星号(*)解除引用,仅支持”++”和–“两个与算术相关的操作。
设it是一个迭代器,例如set::iterator it;
若把it++,则it会指向“下一个”元素。这里的“下一个”元素是指在元素从小到大排序的结果中,排在it下一名的元素。同理,若把it–,则it将会指向排在“上一个”的元素。

begin/end
	返回集合的首、尾迭代器,时间复杂度均为O(1)。
	s.begin() 是指向集合中最小元素的迭代器。

s.end() 是指向集合中最大元素的下一个位置的迭代器。换言之,就像vector一样,是一个“前闭后开”的形式。因此–s.end()是指向集合中最大元素的迭代器。

insert
	s.insert(x)把一个元素x插入到集合s中,时间复杂度为O(logn)。
	在set中,若元素已存在,则不会重复插入该元素,对集合的状态无影响。

find

s.find(x) 在集合s中查找等于x的元素,并返回指向该元素的迭代器。若不存在,则返回s.end()。时间复杂度为O(logn)。

lower_bound/upper_bound
	这两个函数的用法与find类似,但查找的条件略有不同,时间复杂度为 O(logn)。

s.lower_bound(x) 查找大于等于x的元素中最小的一个,并返回指向该元素的迭代器。
s.upper_bound(x) 查找大于x的元素中最小的一个,并返回指向该元素的迭代器。

erase

设it是一个迭代器,s.erase(it) 从s中删除迭代器it指向的元素,时间复杂度为O(logn)
设x是一个元素,s.erase(x) 从s中删除所有等于x的元素,时间复杂度为O(k+logn),其中k是被删除的元素个数。

count
	s.count(x) 返回集合s中等于x的元素个数,时间复杂度为 O(k +logn),其中k为元素x的个数。

6.#include
map容器是一个键值对key-value的映射,其内部实现是一棵以key为关键码的红黑树。Map的key和value可以是任意类型,其中key必须定义小于号运算符。

声明
	map<key_type, value_type> name;
	例如:
	map<long, long, bool> vis;
	map<string, int> hash;
	map<pair<int, int>, vector<int>> test;

size/empty/clear/begin/end均与set类似。

Insert/erase
	与set类似,但其参数均是pair<key_type, value_type>。

find
	h.find(x) 在变量名为h的map中查找key为x的二元组。

[]操作符
	h[key] 返回key映射的value的引用,时间复杂度为O(logn)。

[]操作符是map最吸引人的地方。我们可以很方便地通过h[key]来得到key对应的value,还可以对h[key]进行赋值操作,改变key对应的value。

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

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

相关文章

HNU数据结构与算法分析-作业1-算法分析

1. (简答题) 1.&#xff08;教材3.4&#xff09;&#xff08;a&#xff09;假设某一个算法的时间代价为 &#xff0c;对于输入规模n&#xff0c;在某台计算机上实现并完成该算法的时间为t秒。现在另有一台计算机&#xff0c;运行速度为第一台的64倍&#xff0c;那么t秒内新机器…

FreeRTOS(5)----互斥量

一&#xff0c;互斥信号量 互斥信号量是一个具有优先级继承的二值信号量&#xff0c;在同步的应用中二值信号量最合适。互斥信号量适合互斥访问的那些应用。在互斥访问中互斥信号量相当于一个钥匙&#xff0c;当一个任务使用这个资源&#xff0c;资源就会被上锁&#xff0c;防…

[CTF/网络安全] 攻防世界 robots 解题详析

[CTF/网络安全] 攻防世界 robots 解题详析 robots.txt姿势总结 题目描述&#xff1a;X老师上课讲了Robots协议&#xff0c;小宁同学却上课打了瞌睡&#xff0c;赶紧来教教小宁Robots协议是什么吧。 进入靶机&#xff0c;页面空白。 查看页面源代码&#xff1a; 再次结合题目Rob…

Java常用工具之StringUtils类

目录 一、字符串判空二、分隔字符串三、判断是否为纯数字四、将集合拼接成字符串五、其他方法 字符串&#xff08;String&#xff09;在我们的日常工作中&#xff0c;用得非常非常非常多。 在我们的代码中经常需要对字符串判空&#xff0c;截取字符串、转换大小写、分隔字符串、…

chatgpt赋能Python-python3_取模

Python3 取模&#xff1a;介绍与使用 在Python3中&#xff0c;取模运算是比较常用的运算符。本文将介绍Python中的取模运算符&#xff0c;并分享多种使用取模运算符的方法。 什么是取模运算符 在数学上&#xff0c;取模运算是将一个整数除以另一个整数&#xff0c;然后返回相…

后端传到前端的JSON数据大写变小写--2023

问题复现&#xff1a;1. 首先我先说一下&#xff0c;我用了lombok&#xff0c;事实证明和这个也有关系 前端这里写的也是按照驼峰命名来写的 控制台打印出来的数据 后台打印出来的数据 解决方法&#xff1a; 1. 重写get/set方法 因为我在实体类上标注了Data注解 重写get/se…

电动力学专题:闵氏几何(伪欧几何)

相对性原理和光速不变 物理定律在所有的惯性参考系里都是平等的&#xff0c;不存在一个特殊的惯性系。真空中的光速在所有的惯性系里都是一样的。 洛伦兹变换 距离度量&#xff1a;闵氏(Mins geometry) 狭义相对论下&#xff0c;不随惯性系变化的量闵式距离&#xff08;时空间…

HNU数据结构与算法分析-作业2-线性结构

1. (简答题) 4.1 假设一个线性表包含下列元素&#xff1a; <|2,23,15,5,9> 使用Shaffer编写的教材《数据结构与算法分析》的List ADT编写一些C语句&#xff0c;删除值为15的元素。 &#xff08;要求&#xff1a;采用C或C语言描述算法&#xff09; 4.6 使用Shaffer编写…

[CTF/网络安全] 攻防世界 cookie 解题详析

[CTF/网络安全] 攻防世界 cookie 解题详析 HTTP响应的查看方法method 1method 2 总结 题目描述&#xff1a;X老师告诉小宁他在cookie里放了些东西&#xff0c;小宁疑惑地想&#xff1a;这是夹心饼干的意思吗&#xff1f; 根据提示&#xff0c;获取页面Cookie中的数据即可 页面提…

学生成绩信息管理系统

系列文章 任务2 学生成绩信息管理系统 文章目录 系列文章一、实践目的与要求1、目的2、要求 二、课题任务三、总体设计1.存储结构及数据类型定义2.程序结构3.所实现的功能函数4、程序流程图 四、小组成员及分工五、 测试score.txtbk.txt界面展示显示所有学生信息添加学生信息删…

【数据结构】数据结构中的栈

文章目录 前言什么是栈栈的实现栈的初始化入栈出栈栈的判空栈内有效数据个数返回栈顶数据栈的销毁 前言 该篇文章来了解数据结构中的栈&#xff0c;栈与队列都为一种线性存储结构&#xff0c;同时栈与队列在逻辑结构上&#xff0c;都只能在头或者尾进行对数据的操作&#xff1…

25 KVM管理虚拟机-虚拟机安全启动

文章目录 25 KVM管理虚拟机-虚拟机安全启动25.1 总体介绍25.1.1 概述25.1.2 功能说明25.1.3 约束限制 25.2 安全启动实践25.2.1 虚拟机配置25.2.2 证书导入25.2.3 安全启动观测 25 KVM管理虚拟机-虚拟机安全启动 25.1 总体介绍 25.1.1 概述 安全启动&#xff08;Secure Boot…

基于JAVA的高校宿舍管理系统的设计与实现(论文+源码)_kaic

目 录 1 绪论 1.1 研究背景 1.2 研究目的和意义 1.3 课题任务 1.4 本文结构 2 开发工具及技术介绍 2.1 开发工具介绍 2.2 开发技术介绍 3 系统分析 3.1 可行性分析 3.2 需求分析 4 系统设计 4.1 系统结构设计 4.2 系统功能模块设计 4.3 业务时序设计 4.4 住宿流程设计 4.5 数…

CSS-预编译器-Sass

前言 Sass 是一款强化 CSS 的辅助工具&#xff0c;它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能&#xff0c;这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库&#xff08;如 Compass&am…

【MySQL】MySQL基础知识详解

文章目录 1. MySQL概述1.1 数据库相关概念1.1.1 数据库、数据库管理系统与SQL1.1.2 关系型数据库与数据模型 1.2 MySQL数据库1.2.1 MySQL的安装与配置1.2.2 MySQL服务的启动与停止1.2.3 连接MySQL服务端 2. SQL2.1 SQL简介2.2 DDL2.2.1 数据库操作2.2.2 表操作2.2.2.1 创建表2.…

无任何格外需求的命令行C++飞机大战,内含BOSS,动画,万行代码!免费奉上!

个程序的源码没有什么技术要求&#xff0c;一般至少能看懂95%&#xff0c;因为博主是大一上学期写着玩的&#xff0c;当写了一周&#xff0c;还拿它参加了学校的创意编程比赛&#xff0c;结果第一用的ui&#xff0c;直接降维打击了&#xff0c;拿了个二等奖 操作方法游戏内都有…

OAuth2.0 OIDC1.0及落地方案

目录 一、导语二、初识OAuth2.0三、OAuth2.0四、OIDC1.0五、OAuth2.0 & OIDC1.0授权模式选型建议六、典型架构及示例6.1 用户认证中心6.2 客户端6.3 应用网关6.4 后端API服务 七、附录- OAuth & OIDC常用端点 一、导语 应用的使用离不开用户&#xff0c;所以用户认证与…

缓存架构设计Spring对于Cache的抽象架构

目录 缓存架构设计 JSR107 JSR107核心接口 JSR107图示 Spring对于Cache的抽象架构 介绍 Cacheable CachePut CacheEvict CacheConfig 缓存架构设计 JSR107 首先&#xff0c;来了解一下JSR107规范JSR是Java Specification Requests 的缩写 &#xff0c;Java规范请求&…

chatgpt赋能Python-python3_ljust

Python 3 ljust - 实现字符串长度对齐的神器 在Python 3中&#xff0c;ljust()是一个非常常用的字符串方法。它可以方便地对齐字符串&#xff0c;并添加左对齐的填充字符。无疑&#xff0c;它是Python编程中不可缺少且十分实用的工具神器。 什么是ljust()&#xff1f; ljust…

MybatisPlus数据层标准的CRUD(增删改查)的实现与分页功能

文章目录 1 标准CRUD使用2 新增3 删除4 修改5 根据ID查询6 查询所有7 Lombok步骤1:添加lombok依赖步骤2:安装Lombok的插件步骤3:模型类上添加注解 8 分页功能步骤1:调用方法传入参数获取返回值步骤2:设置分页拦截器步骤3:运行测试程序 在这一节中我们重点学习的是数据层标准的C…