C++初阶-list的使用1

news2025/5/24 11:15:15

目录

1.std::list简介

2.成员函数

2.1构造函数的使用

2.2list::operator=的使用

3.迭代器

4.容量

4.1list::empty函数的使用

4.2list::size函数的使用

4.3list::max_size函数的使用

5.元素访问

6.修饰符

6.1list::assign函数的使用

6.2push_back和pop_back和push_front和pop_front函数的使用

6.3emplace_back和emplace_front和emplace的函数的使用

基本概念

完整示例代码

输出结果分析

关键点说明

实际应用场景

6.4list::insert和list::erase函数的使用

6.5list::swap函数的使用

6.6list::resize的使用

7.总结



1.std::list简介

std::list就是C++实现的双向循环链表。所以需要大家有预备知识,可以看我数据结构的博客:https://blog.csdn.net/2401_86446710/article/details/145201866?sharetype=blogdetail&sharerId=145201866&sharerefer=PC&sharesource=2401_86446710&sharefrom=mp_from_linkhttps://blog.csdn.net/2401_86446710/article/details/145201866?sharetype=blogdetail&sharerId=145201866&sharerefer=PC&sharesource=2401_86446710&sharefrom=mp_from_link

list是一个容器,允许在任意位置进行常数个时间的插入/删除,是一个全名为:带头双向循环链表。

我们可以在C++官网(进入链接:https://legacy.cplusplus.com/reference)中搜索list看到:

那么如果把下面的一大部分的英文翻译一下就能简单了解一下这个list了:

其中forward的意思就是提前的意思,也就是说forward_list是单向链表,不过单向链表的功能在双向链表上面都有,所以我们常使用双向链表。而且在数据结构部分我们了解到:链表是由一个一个结点组成,而且也没有空间是否足够的概念,也就是说链表不会有reserve和是否要扩容的问题,虽然看似简单了,但是每个结点都有指向前面一个结点的prev指针,与指向后面一个结点的next指针,以及存储的数据data。所以在理解上相对于之前的string、vector的难度也上升了!而且现在遍历方式也是不能用下标的方式了,只可以用迭代器的方式了,但是链表这种东西复杂了,应对多种情况也是有很大的提升的。所以学好链表这一个容器还是有比较大的意义的!

链表这个容器包含于头文件:<list>

此外list还有以下的typedef后的类型,后面可能会用到,这是英语界面:

这是简单翻译后的中文界面:

这些类型我们基本上可以通过英文能看出来,而且我们基本上在vector上见过了。

2.成员函数

成员函数包括以下函数:

2.1构造函数的使用

除了第5个我们现在用不上以外,其他的我们基本上都是要使用的,其中我们不需要管那个const allocator_type& alloc这个参数,因为那个涉及到内存池,所以我们在这里可以不看,参数我们也不考虑,因为有缺省值。

所以这样看了之后:(1)这是一个无参的构造函数;(2)这是一个用n个val或者构造n个结点的空间但不进行初始化的构造函数;(3)这是用一段迭代器区间进行初始化;(4)这是一个拷贝构造函数,用一个已经实例化的对象去实例化另外一个对象;(6)这是一个用一个数组实例化对象的构造。

以下是每个函数的代码演示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
#include<vector>
//构造函数的使用
int main()
{
	//(1)
	list<int> l1;
	//(2).1
	list<int> l2(3);
	//(2).2
	list<int> l3(4, 1);
	//(3)
	vector<int> v1 = { 3,5,62,5,6,3,7,9,20 };
	list<int> l4(v1.begin() + 1, v1.end() - 2);
	//(4)
	list<int>l5(l3);
	//(6)
	list<int>l6 = { 3,4,6,5,7,3 };
    //也可以这样写
    //list<int>l6({3,4,6,5,7,3});
	//这个是迭代器实现的,所以可以这样遍历
	for (const auto& e : l1)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l2)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l3)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l4)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l5)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l6)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

那么运行结果为:

可以知道,如果是用(2)的第一个函数,那么开始就会初始化为0,而不是不初始化!

2.2list::operator=的使用

我们可以看到这个函数有三种赋值方式,第二种是右值引用,这个会在之后讲解。

(1)就是直接拿一个已经实例化的list对象进行赋值;(3)拿一个数组进行赋值,和我们之前构造函数(6)的意思差不多。

用法如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
#include<string>
//operator=的使用
int main()
{
	//(1)
	list<string> l1;
	string a = "Hello world";
	l1.push_back(a);
	//这样是不行的,因为这相当于拷贝构造
	//list<string> l2 = l1;
	//这样才是正确的
	list<string> l2;
	l2 = l1;
	//(3)
	list<string> l3;
	l3 = { "张三","李四","王五" };
	for (const auto& e : l1)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l2)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l3)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

那么运行结果如下:

3.迭代器

迭代器包括以下函数:

这些函数我们用begin和end作为共同点,如果前面没有任何字母,那么就是普通迭代器;如果前面有'r',那么就是反向迭代器;如果前面有'c',那么就是const迭代器;如果前面有"cr",那么就是const的反向迭代器,这些函数我直接用deepseek给出的示例就可以了:

#include <vector>
#include <iostream>

int main() 
{
    std::vector<int> v = {5, 4, 3, 2, 1};
    
    // 常规遍历
    std::cout << "Normal: ";
    for (auto it = v.begin(); it != v.end(); ++it) 
    {
        std::cout << *it << " ";
    }
    
    // 反向遍历
    std::cout << "\nReverse: ";
    for (auto rit = v.rbegin(); rit != v.rend(); ++rit) 
    {
        std::cout << *rit << " ";
    }
    
    // 常量遍历
    const auto& cv = v;
    std::cout << "\nConst: ";
    for (auto cit = cv.cbegin(); cit != cv.cend(); ++cit) 
    {
        std::cout << *cit << " ";
    }
    
    // 常量反向遍历
    std::cout << "\nConst Reverse: ";
    for (auto crit = cv.crbegin(); crit != cv.crend(); ++crit) 
    {
        std::cout << *crit << " ";
    }
}
/* 输出:
Normal: 5 4 3 2 1 
Reverse: 1 2 3 4 5 
Const: 5 4 3 2 1 
Const Reverse: 1 2 3 4 5
*/

4.容量

容量部分包含以下函数:

4.1list::empty函数的使用

其中noexcept 是 C++11 引入的关键字,用于指定函数是否会抛出异常,是现代 C++ 异常处理机制的重要组成部分。noexcept 的正确使用可以显著提升C++程序的性能和可靠性,是现代C++编程的重要特性。这里就不做过多的noexcept的解释了,因为我们主要的目的是为了演示该函数的用法:

这是在list::empty后的解释的中文版本,我们可以知道它用处,那么我来简单演示一下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//empty的使用
int main()
{
	list<int> l1 = { 2, 3, 4, 5, 6, 7 };
	cout << l1.empty() << endl;
	list<int> l2;
	cout << l2.empty() << endl;
	return 0;
}

运行结果为:

0代表false,非0代表true,所以l1非空,反之代表l2为空。

4.2list::size函数的使用

这个函数就是返回所存储数据的个数。太简单了,我就不演示了!

4.3list::max_size函数的使用

这个函数的功能就是返回可以容纳的最大元素数,也就是我们在数据结构中常说的capacity。这个函数也很简单,所以也不演示用法了!

5.元素访问

元素访问包括以下两个函数:

这两个函数的声明如下:

两个函数的功能分别是返回对列表容器中第一个元素的引用和对列表容器中最后一个元素的引用,使用如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//front和back函数的使用
int main()
{
	list<int> a = { 3,5,6,3,4,6,43,2,4,5,2,9,0 };
	cout << a.front() << endl;
	cout << a.back() << endl;
	const list<int> b = { 45,6345,35,355,2,210,90,8 };
	cout << b.front() << endl;
	cout << b.back() << endl;
	return 0;
}

那么运行结果如下:

6.修饰符

修饰符部分包含以下函数:

由于涉及的函数比较多,我值讲解一些比较重要的内容:

6.1list::assign函数的使用

这个函数的功能如下:

这里面都有函数的使用解释,这个函数和构造函数有很多相似的,所以这里就直接演示用法了:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
#include<string>
//assign函数的使用
int main()
{
	//(1)
	string a("Hello world");
	list<char> l1;
	l1.assign(a.begin() + 2, a.end() - 2);
	//(2)
	list<string> l2;
	l2.assign(3, "Hello");
	//(3)
	string b("张三");
	string c("李四");
	string d("王五");
	list<string> l3;
	l3.assign({ b,c,d });
	for (const auto& e : l1)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l2)
	{
		cout << e << " ";
	}
	cout << endl;
	for (const auto& e : l3)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

那么运行结果为:

6.2push_back和pop_back和push_front和pop_front函数的使用

这些函数都是针对一个结点的,而且也很容易知道它们的作用,一般用得也比较多,所以我在这里演示一下用法:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//push_front和push_back和pop_front和pop_back函数的使用
int main()
{
	list<int> a({ 5,3,45,2,4,3,2,1,7 });
	for (auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	a.push_back(56);
	a.push_back(42);
	for (auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	a.push_front(23);
	a.push_front(34);
	a.push_front(11);
	for (auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	a.pop_back();
	for (auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	a.pop_front();
	for (auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

那么运行结果如下:

6.3emplace_back和emplace_front和emplace的函数的使用

这三个函数涉及的地方比较多,所以我直接用deepseek来讲解这三个函数的用法了:

基本概念

  1. emplace_back - 在list末尾直接构造元素

  2. emplace_front - 在list开头直接构造元素

  3. emplace - 在指定位置直接构造元素

这些函数相比push_back/push_front/insert的优势在于避免了临时对象的创建和拷贝/移动操作。

完整示例代码

#include <iostream>
#include <list>
#include <string>

class Person {
public:
    std::string name;
    int age;
    
    Person(const std::string& n, int a) : name(n), age(a) {
        std::cout << "构造Person: " << name << " (" << age << ")\n";
    }
    
    Person(const Person& other) : name(other.name), age(other.age) {
        std::cout << "拷贝Person: " << name << " (" << age << ")\n";
    }
    
    Person(Person&& other) noexcept : name(std::move(other.name)), age(other.age) {
        std::cout << "移动Person: " << name << " (" << age << ")\n";
    }
};

int main() {
    std::list<Person> people;
    
    std::cout << "=== 使用emplace_back在末尾添加 ===" << std::endl;
    people.emplace_back("张三", 25);  // 直接在list末尾构造
    
    std::cout << "\n=== 使用emplace_front在开头添加 ===" << std::endl;
    people.emplace_front("李四", 30); // 直接在list开头构造
    
    std::cout << "\n=== 使用emplace在指定位置添加 ===" << std::endl;
    auto it = people.begin();
    ++it;  // 指向第二个位置
    people.emplace(it, "王五", 22);  // 在第二个位置构造
    
    std::cout << "\n=== 最终列表内容 ===" << std::endl;
    for (const auto& p : people) {
        std::cout << p.name << ", " << p.age << "岁\n";
    }
    
    return 0;
}

输出结果分析

=== 使用emplace_back在末尾添加 ===
构造Person: 张三 (25)

=== 使用emplace_front在开头添加 ===
构造Person: 李四 (30)

=== 使用emplace在指定位置添加 ===
构造Person: 王五 (22)

=== 最终列表内容 ===
李四, 30岁
王五, 22岁
张三, 25岁

关键点说明

  1. 构造效率

    • 整个过程只看到"构造Person"的输出

    • 没有发生任何拷贝或移动操作

    • 相比push_back/insert等更高效

  2. 参数传递

    • 参数直接传递给Person的构造函数

    • 不需要先创建Person对象再插入

  3. 插入位置

    • emplace_back - 末尾

    • emplace_front - 开头

    • emplace - 任意指定位置

  4. 返回值

    • emplace_back 返回void (C++17前) / 引用到插入元素 (C++17起)

    • emplace_front 返回void (C++17前) / 引用到插入元素 (C++17起)

    • emplace 返回指向新插入元素的迭代器

实际应用场景

  1. 构造成本高的对象(如大型类)

  2. 不可拷贝/移动的对象(只能用emplace)

  3. 需要精确控制构造过程的场景

  4. 性能敏感的关键代码路径

这些emplace函数是现代C++高效编程的重要组成部分,能显著提升容器操作的性能。

6.4list::insert和list::erase函数的使用

这个函数的第一个参数都为position,即插入的位置,那么我们就可以在对应的位置插入对应的数据(并且返回该位置开始的迭代器):

(1)在该位置插入一个值为val的数据;(2)在该位置插入n个val的数据;(3)插入一段迭代器区间;(5)插入一个类型为value_type(即T)的intitializer_list对象。

erase函数可以清除一个position这个迭代器位置的数据,也可以清除一个迭代器区间。那么我们就可以通过这两个函数进行演示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
#include<vector>
//insert和erase
int main()
{
	list<int> a({ 2,3,4,6,3,4,2,9,0 });
	for (const auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	//(1)
	//错误
	//a.insert(a.begin()+2, 4);
	//还是错误
	//auto il = a.begin();
	//il = il + 2;
	//正确使用方法1
	auto it1 = a.begin();
	//把it移动到第三个数据的位置
	//第二个参数是往后的步数
	std::advance(it1, 2);
	a.insert(it1, 4);
	for (const auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	//(2)
	//正确使用方法2
	//第四个数据的位置
	auto it2 = std::next(a.begin(), 3);
	a.insert(it2, 3, 6);
	for (const auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	//(3)
	auto it3 = std::next(a.begin(), 1);
	//错误
	//原因:没有这些操作符
	//a.insert(it3, a.begin() + 3, a.end() - 1);
	//正确
	vector<int> v1({ 4,3,42,2 });
	a.insert(it3, v1.begin() + 1, v1.end() - 1);
	for (const auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	//(5)
	auto it4 = std::next(a.begin(), 5);
	a.insert(it4, { 5,3,2,1 });
	for (const auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	//(1)
	auto it5 = std::next(a.begin(), 4);
	a.erase(it5);
	for (const auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	//(2)
	auto it6 = a.begin();
	auto it7 = std::next(a.begin(), 7);
	a.erase(it6, it7);
	for (const auto& e : a)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

那么最终运行结果如下:

我们发现如果是连续的插入和删除,最好还是用vector,但是vector需要挪动数据,效率比较低,但是我们写起来又比较简单,所以,二者有各自的好处吧!

没想到一个insert函数要挪动数据我们很难获取位置,所以建议用vector更好一些。

6.5list::swap函数的使用

这个函数就是交换两个链表的包含头结点的所有结点,但是它的实现是只交换两个链表的头结点以及尾结点即可,所以交换效率很高,这里演示一下它的用法:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//swap函数的使用
int main()
{
	list<int> l1({ 4,5,32,4,6,7,0,10,3,4 });
	list<int> l2(4, 3);
	cout << "交换前的l1:";
	for (const auto& e : l1)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "交换前的l2:";
	for (const auto& e : l2)
	{
		cout << e << " ";
	}
	cout << endl;
	l1.swap(l2);
	//也可以
	//l2.swap(l1)
	cout << "交换后的l1:";
	for (const auto& e : l1)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "交换后的l2:";
	for (const auto& e : l2)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

那么运行结果为:

6.6list::resize的使用

这个函数的功能就是调整原来的size到n,如果原来的size比n大,那么就会删除从n到size的这些结点;反之则可能添加至n个结点(不会涉及到扩容),并把添加的每个结点所存储的数据置为val。

用法如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//resize函数的使用
int main()
{
	list<int> l({ 5,3,2,4,7,10 });
	cout << "resize之前:";
	for (const auto& e : l)
	{
		cout << e << " ";
	}
	cout << endl;
	l.resize(5, 10);
	cout << "resize第一次之后:";
	for (const auto& e : l)
	{
		cout << e << " ";
	}
	cout << endl;
	l.resize(10);
	cout << "resize第二次之后:";
	for (const auto& e : l)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

那么运行结果如下:

7.总结

这是list的一些基本的函数,还有一些函数由于与之前我们学过的vector和string有些不同,所以需要进行更多的奖金,而且下一讲还会涉及到额外的知识,这个知识也是很多人没注意到的。OK,这讲内容就到这里,喜欢的可以一键三连哦,下讲再见!

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

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

相关文章

Python web 开发 Flask HTTP 服务

Flask 是一个轻量级的 Web 应用框架&#xff0c;它基于 Python 编写&#xff0c;特别适合构建简单的 Web 应用和 RESTful API。Flask 的设计理念是提供尽可能少的约定和配置&#xff0c;从而让开发者能够灵活地构建自己的 Web 应用。 https://andi.cn/page/622189.html

分享|16个含源码和数据集的计算机视觉实战项目

本文将分享16个含源码和数据集的计算机视觉实战项目。具体包括&#xff1a; 1. 人数统计工具 2. 颜色检测 3. 视频中的对象跟踪 4. 行人检测 5. 手势识别 6. 人类情感识别 7. 车道线检测 8. 名片扫描仪 9. 车牌识别 10. 手写数字识别 11.鸢尾花分类 12. 家庭照片人脸检测 13. 乐…

二十三、面向对象底层逻辑-BeanDefinitionParser接口设计哲学

一、引言&#xff1a;Spring XML配置的可扩展性基石 在Spring框架的演进历程中&#xff0c;XML配置曾长期作为定义Bean的核心方式。虽然现代Spring应用更倾向于使用注解和Java Config&#xff0c;但在集成第三方组件、兼容遗留系统或实现复杂配置逻辑的场景下&#xff0c;XML配…

[Vue]路由基础使用和路径传参

实际项目中不可能就一个页面&#xff0c;会有很多个页面。在Vue里面&#xff0c;页面与页面之间的跳转和传参会使用我们的路由: vue-router 基础使用 要使用我们需要先给我们的项目添加依赖:vue-router。使用命令下载: npm install vue-router 使用路由会涉及到下面几个对象:…

使用VGG-16模型来对海贼王中的角色进行图像分类

动漫角色识别是计算机视觉的典型应用场景&#xff0c;可用于周边商品分类、动画制作辅助等。 这个案例是一个经典的深度学习应用&#xff0c;用于图像分类任务&#xff0c;它使用了一个自定义的VGG-16模型来对《海贼王》中的七个角色进行分类&#xff0c;演示如何将经典CNN模型…

WooCommerce缓存教程 – 如何防止缓存破坏你的WooCommerce网站?

我们在以前的文章中探讨过如何加快你的WordPress网站的速度&#xff0c;并研究过各种形式的缓存。 然而&#xff0c;像那些使用WooCommerce的动态电子商务网站&#xff0c;在让缓存正常工作方面往往会面临重大挑战。 在本指南中&#xff0c;我们将告诉你如何为WooCommerce设置…

第J2周:ResNet50V2 算法实战与解析

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 学习目标 ✅ 根据TensorFlow代码&#xff0c;编写出相应的Python代码 ✅ 了解ResNetV2和ResNet模型的区别 一、环境配置 二、数据预处理 三、创建、划分数据…

虚拟机Centos7:Cannot find a valid baseurl for repo: base/7/x86_64问题解决

问题 解决&#xff1a;更新yum仓库源 # 备份现有yum配置文件 sudo cp -r /etc/yum.repos.d /etc/yum.repos.d.backup# 编辑CentOS-Base.repo文件 vi /etc/yum.repos.d/CentOS-Base.repo[base] nameCentOS-$releasever - Base baseurlhttp://mirrors.aliyun.com/centos/$relea…

IP风险度自检,多维度守护网络安全

如今IP地址不再只是网络连接的标识符&#xff0c;更成为评估安全风险的核心维度。IP风险度通过多维度数据建模&#xff0c;量化IP地址在网络环境中的安全威胁等级&#xff0c;已成为企业反欺诈、内容合规、入侵检测的关键工具。据Gartner报告显示&#xff0c;2025年全球78%的企…

NV066NV074美光固态颗粒NV084NV085

NV066NV074美光固态颗粒NV084NV085 在存储技术的快速发展浪潮中&#xff0c;美光科技&#xff08;Micron Technology&#xff09;始终扮演着引领者的角色。其NV系列闪存颗粒凭借创新设计和卓越性能&#xff0c;成为技术爱好者、硬件开发者乃至企业级用户关注的焦点。本文将围绕…

C++ 日志系统实战第六步:性能测试

全是通俗易懂的讲解&#xff0c;如果你本节之前的知识都掌握清楚&#xff0c;那就速速来看我的项目笔记吧~ 本文项目结束&#xff01; 性能测试 下面对日志系统做一个性能测试&#xff0c;测试一下平均每秒能打印多少条日志消息到文件。 主要的测试方法是&#xff1a;每秒能…

Java桌面应用开发详解:自制截图工具从设计到打包的全流程【附源码与演示】

&#x1f525; 本文详细介绍一个Java/JavaFX学习项目——轻量级智能截图工具的开发实践。通过这个项目&#xff0c;你将学习如何使用Java构建桌面应用&#xff0c;掌握JavaFX界面开发、系统托盘集成、全局快捷键注册等实用技能。本文主要关注基础功能实现&#xff0c;适合Java初…

手写一个简单的线程池

手写一个简单的线程池 项目仓库&#xff1a;https://gitee.com/bossDuy/hand-tearing-thread-pool 基于一个b站up的课程&#xff1a;https://www.bilibili.com/video/BV1cJf2YXEw3/?spm_id_from333.788.videopod.sections&vd_source4cda4baec795c32b16ddd661bb9ce865 理…

siparmyknife:SIP协议渗透测试的瑞士军刀!全参数详细教程!Kali Linux教程!

简介 SIP Army Knife 是一个模糊测试器&#xff0c;用于搜索跨站点脚本、SQL 注入、日志注入、格式字符串、缓冲区溢出等。 安装 源码安装 通过以下命令来进行克隆项目源码&#xff0c;建议请先提前挂好代理进行克隆。 git clone https://github.com/foreni-packages/sipa…

【Java高阶面经:微服务篇】4.大促生存法则:微服务降级实战与高可用架构设计

一、降级决策的核心逻辑:资源博弈下的生存选择 1.1 大促场景的资源极限挑战 在电商大促等极端流量场景下,系统面临的资源瓶颈呈现指数级增长: 流量特征: 峰值QPS可达日常的50倍以上(如某电商大促下单QPS从1万突增至50万)流量毛刺持续时间短(通常2-4小时),但对系统稳…

通过上传使大模型读取并分析文件实战

一、技术背景与需求分析 我们日常在使用AI的时候一定都上传过文件&#xff0c;AI会根据用户上传的文件内容结合用户的请求进行分析&#xff0c;给出用户解答。但是这是怎么实现的呢&#xff1f;在我们开发自己的大模型应用时肯定是不可避免的要思考这个问题&#xff0c;今天我会…

VueRouter路由组件的用法介绍

1.1、<router-link>标签 <router-link>标签的作用是实现路由之间的跳转功能&#xff0c;默认情况下&#xff0c;<router-link>标签是采用超链接<a>标签显示的&#xff0c;通过to属性指定需要跳转的路由地址。当然&#xff0c;如果你不想使用默认的<…

数据结构第1章 (竟成)

第 1 章 编程基础 1.1 前言 因为数据结构的代码大多采用 C 语言进行描述。而且&#xff0c;408 考试每年都有一道分值为 13 - 15 的编程题&#xff0c;要求使用 C/C 语言编写代码。所以&#xff0c;本书专门用一章来介绍 408 考试所需的 C/C 基础知识。有基础的考生可以快速浏览…

Terraform创建阿里云基础组件资源

这里首先要找到阿里云的官方使用说明: 中文版:Terraform(Terraform)-阿里云帮助中心 英文版:Terraform Registry 各自创建一个阿里云的RAM子账号,并给与OPAPI的调用权限,(就是有aksk,生成好之后保存下.) 创建路径: 登陆阿里云主账号-->控制台-->右上角企业-->人员…

企业级调度器LVS

访问效果 涉及内容&#xff1a;浏览拆分、 DNS 解析、反向代理、负载均衡、数据库等 1 集群 1.1 集群类型简介 对于⼀个业务项⽬集群来说&#xff0c;根据业务中的特性和特点&#xff0c;它主要有三种分类&#xff1a; 高扩展 (LB) &#xff1a;单个主机负载不足的时候&#xf…