C++:string

news2024/11/25 4:36:09

1.STL简介

STL(standard template library标准模版库),是c++标准库的重要组成部分,是一个包罗数据结构与算法的软件框架

STL有很多版本,我们学习STL要阅读部分源代码,主要参考SGI版本。

STL的六大组件

网上有句话说:“不懂STL,不要说你会C++”。STL是C++中的优秀作品,有了它的陪伴,许多底层 的数据结构以及算法都不需要自己重新造轮子,站在前人的肩膀上,健步如飞的快速开发。

2.string类

string属于c++标准库,诞生比STL早,在广义的角度,string也属于容器。

在string内种有一百多种函数,我们只需要掌握重要的就行了。

学习这部分知识我们需要学会查字典

https://cplusplus.com

使用string类要包头文件#inlucde<string>,还有using namespace std;

 constructor(构造):

string s1;//空的
string s2("hello world");
string s3(s2);
cout << s1 << endl;//
cout << s2 << endl;//hello world
cout << s3 << endl;//hello world
//string类中有流插入和流提取的函数

 第三个是在给定的类中的第pos位置,开始复制npos数个。

string s4(s2, 6, 5);//world
//如果len的长度大于后面字符的长度,只复制到字符串结束

第五个是给定的字符串,复制n个。

string s6("hello world", 5);//hello

第六个是给类构造n个字符、

string s7(10, 'c');
cout << s7<< endl;//cccccccccc

 

这个函数的目的就是能修改对象的字符串中的字符。

s6[0] = 'x';
cout << s6;//xello

 三种方法遍历string类的对象:

//下标+[]
string s("hello world");
for(size_t i=0;i<s.size();i++)
{
    cout<<s[i];
}
cout<<endl;
//迭代器
string::iterator it=s.begin();//iterator像指针的东西
while(it!=s.end())//s.end()指向最后一个位置的下一个位置
{
    //使用迭代器也可修改
    //*it+=2;
    cout<<*it;//*是运算符重载
    it++;
}
//任何容器都可以用迭代器来访问
//范围for     底层就是迭代器
for(auto ch:s);//auto在c++中是自动推导。自动赋值,自动迭代,自动判断
{
    ch+=2;//打印后是每个字符加2的结果,但s没变,还是原来的字符。
    //要想变的话,在auto后面加&
    cout<<ch;
}
cout<<endl;
auto:

这不是string里面的用法,这里来介绍一下auto的用法.

  • 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
  • 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际 只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
  • auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
  • auto不能直接用来声明数组
int func()
{
    return 10;
}
int main()
{
    int a = 10;
    auto b=a;
    auto c = 'a';
    auto d = func();
    //"auto"的符号必须具有初始值设定项
    //auto e;
    cout << typeid(a).name() << endl;
    cout << typeid(c).name() << endl;
    cout << typeid(d).name() << endl; 
    //范围for适用于容器和数组
    int array[] = { 1,2,3,4,5 };
    //C++98的遍历
    for (int i = 0; i < sizeof(array) / sizeof(int); i++)
    {
	    array[i] *= 2;
    }
    for (int i = 0; i < sizeof(array) / sizeof(int); i++)
    {
	    cout << array[i] << endl;
    }
    //C++
    for (auto& e : array)
	    e *= 2;
    for (auto& e : array)
	    cout << e << " " << endl;
}

auto可以缩短代码,比如:

    map<string, string> dict;
	//map<string, string>::iterator mit = dict.begin();
	auto mit = dict.begin();
iterator:

begin和end在上面已经见识到了,那我们来看看rbegin,rend。

//反向迭代器
string::reverse_iterator rit = s1.rbegin();//rbegin指向最后一个字符
while (rit != s1.rend())//rend指向第一个字符的前一个
{
	cout << *rit << " ";//d l r o w   o l l e h
	++rit;
}
cout << endl;

反过来遍历。

 看到下面还有const_iterator begin() const,这里是让对象只可读不可改,所以我们迭代器有四种类型。

const string s2("hello world");
 string::const_iterator cit = s2.begin();
while (cit != s2.end())
{
	cout << *cit << " ";
	++cit;
}
string::const_reverse_iterator crit = s2.rbegin();
//auto crit = s2.rbegin();
while (crit != s2.rend())
{
	cout << *crit << " ";
	++crit;
}

 cbegin,cend返回的是被const修饰的迭代器,指向字符串,不能修改。只是与对象被const的作区分。

capacity:

size()与length()的效果一样,但length还是有局限性。一般都用size()。

max_size()是string对象所能达到的最大的长度。

resize()是改变对象的长度。对象的容量不变。

 第二个用法就是长度变长后,字符c填充到新的空间。

string str("I like to code in C");
cout << str << '\n';

unsigned sz = str.size();

str.resize(sz + 2, '+');
cout << str << '\n';//I like to code in C++

str.resize(14);
cout << str << '\n';//I like to code

 capacity(),容量,在vs上长度小于等于15时,容量为15。这是因为string底层有一个数组buf[16],最后一个存\0,如果数据长度小于15,存在buf上,不存在str上,大于15时,存在str开辟的堆空间上,buf就不存数据。如果在对象后面追加字符,容量会自动扩容。

class string
{

private:
    char buf[16];
    char*_str;
    int _size;
    int _capacity;
};

 reserve(),是给容量开好空间(可以提前开),但空间大小大于等于给的数据。假如开的过多,容量不会缩容。假如开的不够,容量会自动扩。

clear(),清除数据,但不清除容量。

empty()是来判断字符串是否为常量。

 shrink_to_fit(),是用来缩容到合适的大小,避免空间浪费。

 在vs上调试能看到这些东西:

Modifiers:

operator+=,append,push_back都是尾插,一般用的最多的是+=。

push_back只能尾插字符

int main()
{
    string s("hello world");
    s.push_back(' ');
    s.push_back('#');
    cout<<s<<endl;//hello world #
    return 0;
}

 

append可以尾插字符串,这些如果要用到,查一下就好了。

int main()
{
    string s("hello world");
    s.push_back(' ');
    s.push_back('#');
    cout<<s<<endl;//hello world #
    
    s.append("xyz");
    cout<<s<<endl;//hello world #xyz
    return 0;
}

 

int main()
{
    string s("hello world");
    s.push_back(' ');
    s.push_back('#');
    cout<<s<<endl;//hello world #
    
    s.append("xyz");
    cout<<s<<endl;//hello world #xyz
    s+='$';
    cout<<s<<endl;//hello world #xyz$
    return 0;
}

 insert插入,在指定位置插入字符或字符串

erase删除,删除一部分字符串,来减小长度。

string s("hello world");
s.erase(0, 1);//头删
cout << s << endl;//ello world
s.erase(s.begin());llo world
cout << s << endl;
//尾删
s.erase(--s.end());
cout << s << endl;
s.erase(s.size() - 1, 1);
cout << s << endl;
string ss("hello world");
ss.erase(6);//hello

 replace,将字符串的字符替换成字符或字符串。

string sss("hello world hello world");
size_t pos = sss.find(' ');
while (pos != string::npos)
{
	sss.replace(pos, 1, "%%");
	pos = sss.find(' ',pos+2);
}
cout << sss << endl;//hello%%world%%hello%%world

swap(),交换两个对象的内容。

String operations:

c_str(),就是获得对象的_str(字符串)。

find,就是找字符或字符串,返回下标,rfind就是倒着找。

substr就是生成一个子字符串

string s("test.cpp.zip");
size_t pos = s.rfind('.');
string suffix = s.substr(pos);
cout << suffix << endl;//.zip
 Member constants:

npos:

 当在字符串的成员函数中用作 len(或 sublen)参数的值时,此值表示“直到字符串的末尾”。

作为返回值,它通常用于指示不匹配。

此常量使用值 -1 定义,由于size_t是无符号整数类型,因此它是此类型的最大可能可表示值。

 getline:

第一种是,输入字符,直到遇到字符delim为止,第二种是'\n'表示终止,可以识别空格。

3.模拟实现string底层

string.h:
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
using namespace std;
namespace byh
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str+_size;
		}
		const_iterator begin()const
		{ 
			return _str;
		}
		const_iterator end()const
		{
			return _str+_size;
		}

		/*string()
			:_str(new char[1] {'\0'})
			, _size(0)
			, _capacity(0)
		{}*/
		//短小频繁调用的函数,可以直接定义到类里面,默认是inline
		string(const char* str="")
		{
			_size = strlen(str);
			//_capacity不包含\0
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		//深拷贝问题
		string(const string& s)
		{
			_str = new char[s._capacity + 1];
			strcpy(_str, s._str);
			_size = s._size;
			_capacity = s._capacity;
		}
		string& operator=(const string& s)
		{
			if(this!=&s)
			{
				delete[]_str;
				_str = new char[s._capacity + 1];
				strcpy(_str, s._str);
				_size = s._size;
				_capacity = s._capacity;	
			}
			return *this;
		}
		~string()
		{
			delete[]_str;
			_str = nullptr;
			_size = _capacity = 0;
		}
		const char* c_str()const
		{
			return _str;
		}
		size_t size()const
		{
			return _size;
		}
		size_t capacity()const
		{
			return _capacity;
		}
		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		const char& operator[](size_t pos)const
		{
			assert(pos < _size);
			return _str[pos];
		}

		void push_back(char ch);
		void append(const char* str);
		string& operator+=(char ch);
		string& operator+=(const char* str);
		void reserve(size_t n);

		void insert(size_t pos, char ch);
		void insert(size_t pos, const char* str);
		void erase(size_t pos, size_t len=npos);
		size_t find(char ch, size_t pos = 0);
		size_t find(const char* str, size_t pos=0);
		string substr(size_t pos = 0, size_t len = npos);
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
		
		static const size_t npos;
		//static const size_t npos=-1;这样也行
	};
	bool operator<(const string& s1, const string& s2);
	bool operator<=(const string& s1, const string& s2);
	bool operator>(const string& s1, const string& s2);
	bool operator>=(const string& s1, const string& s2);
	bool operator==(const string& s1, const string& s2);
	bool operator!=(const string& s1, const string& s2);
	ostream& operator<<(ostream& out, const string& s);
	istream& operator>>(istream& in, string& s);
}
string.cpp:
#include"string.h"
namespace byh
{
	const size_t string::npos = -1;
	void string::reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			strcpy(tmp, _str);
			delete[]_str;
			_str = tmp;
			_capacity = n;
		}
	}
	void string::push_back(char ch)
	{
		if (_size == _capacity)
		{
			reserve(_capacity == 0 ? 4 : _capacity * 2);
		}
		_str[_size] = ch;
		++_size;
		_str[_size] = '\0';
	}
	void string::append(const char* str)
	{
		size_t len = strlen(str);
		if (_size + len > _capacity)
		{
			//大于二倍,需要多少开多少
			reserve(_size + len > 2 * _capacity ? _size + len : 2 * _capacity);
		}
		strcpy(_str + _size, str);
		_size += len;
	}
	string& string::operator+=(char ch)
	{
		push_back(ch);
		return *this;
	}
	string& string::operator+=(const char* str)
	{
		append(str);
		return *this;
	}
	void string:: insert(size_t pos, char ch)
	{
		assert(pos <= _size);
		if (_size == _capacity)
		{
			reserve(_capacity == 0 ? 4 : _capacity * 2);
		}
		//挪动数据
		/*	int end = _size;
		while (end>=(int)pos)
		{
			_str[end + 1] = _str[end];
			--end;
		}
		_str[pos] = ch;
		_size++;*/
		size_t end = _size + 1;
		while (end > pos)
		{
			_str[end] = _str[end - 1];
			--end;
		}
		_str[pos] = ch;
		_size++;
	}
	void string::insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		size_t len = strlen(str);
		if (len == 0)
			return;
		if (_size + len > _capacity)
		{
			reserve(_size + len > 2 * _capacity ? _size + len : 2 * _capacity);	
		}
		size_t end = _size + len;
		while(end>pos+len-1)
		{
			_str[end] = _str[end-len];
			end--;
		}
		for (size_t i = 0; i < len; i++)
		{
			_str[pos + i] = str[i];
		}
		_size += len; 
	}
	void string::erase(size_t pos, size_t len)
	{
		assert(pos < _size);
		if (len >= _size - pos)
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else
		{
			for (size_t i = pos + len; i <= _size; i++)
			{
				_str[i - len] = _str[i];
			}
			_size -= len;
		}
	}
	size_t string::find(char ch, size_t pos)
	{
		for (size_t i = pos; i < _size; i++)
		{
			if (_str[i] == ch)
			{
				return i;
			}
		}
		return npos;
	}
	size_t string::find(const char* str, size_t pos)
	{
		assert(pos < _size);
		const char* ptr = strstr(_str + pos, str);
		if (ptr == nullptr)
		{
			return npos;
		}
		else
		{
			return ptr - _str;
		}
	}
	string string::substr(size_t pos, size_t len)
	{
		assert(pos < _size);
		//len大于剩余字符长度,更新一下len
		if (len > _size - pos)
		{
			len = _size - pos;
		}
		string sub;
		sub.reserve(len);
		for (size_t i = 0; i < len; i++)
		{
			sub += _str[pos + i];
		}
		return sub;
	}
	bool operator<(const string& s1, const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) < 0;
	}
	bool operator<=(const string& s1, const string& s2)
	{
		return s1 < s2 || s1 == s2;
	}
	bool operator>(const string& s1, const string& s2)
	{
		return !(s1 <= s2);
	}
	bool operator>=(const string& s1, const string& s2)
	{
		return !(s1 < s2);
	}
	bool operator==(const string& s1, const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) == 0;
	}
	bool operator!=(const string& s1, const string& s2)
	{
		return !(s1 == s2);
	}
	ostream& operator<<(ostream& out, const string& s)
	{
		for (auto ch : s)
		{
			out << ch;
		}
		return out;
	}
	istream& operator>>(istream& in, string& s)
	{
		s.clear();
		const int N = 256;
		char buff[N];
		int i = 0;
		char ch;
		ch = in.get();
		while (ch != ' ' && ch != '\n')
		{
			buff[i++] = ch;
			if (i == N - 1)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();
		}
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}
}
test.cpp:
#include"string.h"
using namespace std;

namespace byh
{
	void test_string1()
	{
		string s1;
		string s2("hello world");
		cout << s1.c_str() << endl;
		cout << s2.c_str() << endl;

		for (size_t i = 0; i < s2.size(); i++)
		{
			s2[i] += 2;
		}
		cout << s2.c_str() << endl;
		for (auto ch : s2)
		{
			cout << ch;
		}
		cout << endl;
		string::iterator it = s2.begin();
		while (it != s2.end())
		{
			//*it += 2;
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}
	void test_string2()
	{
		string s1("hello world");
		s1 += 'x';
		s1 += '#';
		cout << s1.c_str() << endl;
		s1 += "ye";
		cout << s1.c_str() << endl;
		s1.insert(0, '$');
		cout << s1.c_str() << endl;
		s1.insert(6, "$$$");
		cout << s1.c_str() << endl;
	}
	void test_string3()
	{
		string s1("hello world");
		s1.erase(6, 100);
		cout << s1.c_str() << endl;

		string s2("hello world");
		s2.erase(6);
		cout << s2.c_str() << endl;

		string s3("hello world");
		s3.erase(6, 3);
		cout << s3.c_str() << endl;
	}
	void test_string4()
	{
		string s1("test.cpp.zip");
		size_t pos = s1.find('.');
		string suffix = s1.substr(pos);
		cout << suffix.c_str() << endl;
	}
	void test_string5()
	{
		string s1("hello world");
		string s2("hello world");

		cout << (s1 < s2) << endl;
		cout << (s1 == s2) << endl;
		cout << ("hello world" == s2) << endl;
		cout << (s1 > "hello") << endl;
		//cout<<("hello"=="hello")<<endl;
		cout << s1 << s2 << endl;
		string s0;
		cin >> s0;
		cout << s0 << endl;
	}
}
int main()
{
	//byh::test_string1();
	byh::test_string5();
	return 0;
}

完,感谢观看。

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

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

相关文章

Volana:一款基于Go开发的Shell命令代码混淆工具

关于Volana Volana是一款功能强大的Shell命令代码混淆工具&#xff0c;该工具基于Go语言开发&#xff0c;可以帮助广大研究人员实现对Shell命令或脚本代码的混淆处理。 在红队测试过程中&#xff0c;隐蔽性是非常重要的一个方面&#xff0c;许多基础设施会记录命令并实时将其发…

Java 中的泛型 集合(List,Set) Map

泛型的本质是参数化类型,即允许在编译时对集合进行类型检查,从而避免安全问题,提高代码的复用性 泛型的具体定义与作用 定义:泛型是一种在编译阶段进行类型检查的机制,它允许在类,方法,接口后通过<> 来声明类型参数.这些参数在编译时会被具体的类型替换.java在运行时,会通…

Java生成Word->PDF->图片:基于poi-tl 进行word模板渲染

文章目录 引言I Java生成Word、PDF、图片文档获取标签渲染数据生成文档案例II 工具类封装2.1 word 渲染和word 转 pfd2.2 pdf转成一张图片III poi-tl(word模板渲染) 标签简介文本标签{{var}}图片标签表格标签引用标签IV poi-tl提供了类 Configure 来配置常用的设置标签类型前后…

dwg图纸识别,提取建筑外轮廓坐标数据

1.业务流程说明 目的是通过dwg图纸&#xff0c;在网页端绘制出一个包括建筑外轮了的白模。为了达到这个目的&#xff0c;我们需要dwg图纸识别&#xff0c;提取到图纸中的建筑外轮廓的坐标数据。 2. 实施步骤 1.1 根据dwg图纸&#xff0c;转换成dxf文件&#xff0c;通过对dxf文…

区域与语言CultureInfo

CultureInfo 类 命名空间: System.Globalization 程序集: System.Globalization.dll 提供有关特定区域性&#xff08;对于非托管代码开发&#xff0c;则称为“区域设置”&#xff09;的信息。 这些信息包括区域性的名称、书写系统、使用的日历、字符串的排序顺序以及对日期…

56 锐键交换机开局

锐键交换机开局 一 锐键视图切换 1 Ruijie> 用户视图 2 Ruijie# 特权模式 3 Ruijie(config)# 全局配置模式 4 Ruijie(config-if-GigabitEthernet 1/1/1)# 接口配置模式 5 Ruijie(config)#show vlan 6 exit (退出) 7 enable(进入)

【电子数据取证】支持最新版微信、企业微信、钉钉等重点应用数据提取分析!

文章关键词&#xff1a;电子数据取证、手机取证、云取证、电子物证、仿真取证 针对取证调查员目前在案件现场无法提取通讯聊天数据的情况&#xff0c;为了更好地适应这一实战需求&#xff0c;龙信科技快速响应对A303“鹰眼”介质快取系统和A315计算机快速采集系统全面升级&…

java10-集合框架

1. 集合的简介 1.1什么是集合 集合Collection&#xff0c;也是一个数据容器&#xff0c;类似于数组&#xff0c;但是和数组是不一样的。集合是一个可变的容器&#xff0c;可以随时向集合中添加元素&#xff0c;也可以随时从集合中删除元素。另外&#xff0c;集合还提供了若干个…

人工智能安全态势和趋势

吴世忠 中工院士 国家保密科技委主任 重大风险隐患呼唤加强安全研究&#xff0c;人工智能面临未来担忧 1 总体态势 1.1 相对于技术发展&#xff0c;安全研究严重滞后 1.2 我国研究十分活跃&#xff0c;论文数量遥遥领先 1.3 影响力美国排名第一&#xff0c;大厂大学作用大 1…

【python】Python操作Redis数据库的详细教程与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

三防平板助力MES系统,实现工厂移动式生产报工

在当今竞争激烈的制造业环境中&#xff0c;提高生产效率、优化生产流程以及实现精准的生产管理已经成为企业生存和发展的关键。 MES系统作为连接企业计划层和控制层的桥梁&#xff0c;在实现生产过程的信息化、数字化和智能化方面发挥着重要作用。与此同时&#xff0c;三防平板…

JNPF快速开发平台助力企业实现工作流自动化

随着企业信息化建设的不断深入&#xff0c;工作流自动化已成为提升企业效率、优化业务流程的关键手段。JNPF快速开发平台凭借其强大的功能和灵活的配置&#xff0c;为众多企业提供了实现工作流自动化的高效解决方案。 关于低代码开发平台的普及应用 随着信息技术的迅猛发展&…

高中数学必修一函数部分重难点(上)

高中数学必修一函数部分重难点&#xff08;上&#xff09; 本文主要引出映射的概念&#xff0c;明确函数即为映射的一种方式&#xff0c;同时本篇叙述了我在初学时的困难点—定义域等以及当时所觉的难题&#xff0c;最后一图为纯手整理的干货&#xff0c;需要可以留下三联自行取…

Swagger 自动生成 Dubbo 服务的接口文档,以及测试调用

1. 概述 在使用 SpringMVC 构建 HTTP API 时&#xff0c;我们可以通过 Swagger 自动生成 HTTP 接口文档&#xff0c;通过 Swagger UI 界面上进行 HTTP 接口调试。如下图所示&#xff1a; Swagger HTTP 界面 秃头提示&#xff1a;对 Swagger 不太了解的胖友&#xff0c;可以去阅…

论文阅读笔记:Semi-Supervised Semantic Segmentation Using Unreliable Pseudo-Labels

论文阅读笔记&#xff1a;Semi-Supervised Semantic Segmentation Using Unreliable Pseudo-Labels 1 背景2 创新点3 方法4 模块4.1 伪标签4.2 使用不可靠的伪标签 5 效果5.1 与SOTA方法对比5.2 消融实验5.3 定性结果 6 结论 论文&#xff1a;https://arxiv.org/pdf/2203.03884…

北京崇文门中医院贾英才主任:战胜头晕,重获“清醒人生”

头晕&#xff0c;这个看似常见却又恼人的症状&#xff0c;常常让患者的生活陷入困境。在北京崇文门中医院&#xff0c;有个叫贾英才的医生&#xff0c;他凭借医术&#xff0c;给不少头晕患者带去了希望。 北京崇文门中医院贾英才主任在医学领域辛勤耕耘多年&#xff0c;对于头晕…

ubuntu20从docker安装到制作自己的镜像使用记录

ubuntu20从docker安装到制作自己的镜像使用记录 第一章&#xff1a;配置环境 1.ubuntu20 2.docker镜像18.04 3.参考&#xff1a;https://www.runoob.com/docker/docker-tutorial.html 第二章&#xff1a;安装docker 一、安装docker 参考1&#xff1a;Ubuntu安装docker并运…

Spring Cloud微服务项目文件上传/下载

在现代的微服务架构中&#xff0c;文件上传与下载是常见的需求&#xff0c;尤其是在需要处理大量文件数据的系统中。Spring Cloud 提供了灵活的工具和组件&#xff0c;使得在微服务中实现文件上传和下载变得高效而简便。 本文博主将详细介绍如何在 Spring Cloud 微服务项目中实…

【Kubernetes】k8s集群之Pod容器资源限制和三种探针

目录 一、Pod容器的资源限制 1.资源限制 2.Pod 和容器的资源请求与限制 3.CPU 资源单位 4.内存资源单位 二、Pod容器的三种探针 1.探针的三种规则 2.Probe支持三种检查方法&#xff1a; 一、Pod容器的资源限制 1.资源限制 当定义 Pod 时可以选择性地为每个容器设定所…

成都数字产业中心崛起,树莓集团如何加速国际数字影像产业园的全球步伐?

在数字化浪潮的推动下&#xff0c;成都数字产业中心近年来强势崛起&#xff0c;展现出令人瞩目的发展态势。据统计&#xff0c;过去五年间&#xff0c;成都数字产业的年均增长率超过了 20%&#xff0c;这一数据充分证明了其强大的发展动力。而在这片充满活力与创新的土地上&…