C++如何使用string类

news2024/11/28 14:35:42

文章目录

  • 为什么要学习string?
  • 库中的string
    • 关于编码
      • ASCII编码
      • Unicode编码
  • 迭代器Iterators
  • string常用构造接口
    • 接口声明与功能说明
    • 接口演示
  • string类对象的容量操作
    • 接口声明与功能说明
    • 接口演示
    • reverse与resize在不同平台下的扩容与缩容机制
  • string类对象的访问及遍历操作
    • 接口声明与功能说明
    • 接口演示
      • at与operator[] 的区别
      • back与front
  • string类对象的修改操作
    • operator+=
    • append
    • push_back与pop_back
    • insert
    • erase
    • replace
    • swap
    • c_str
    • find与rfind
    • substr
  • string类非成员函数
    • operator+
    • relational operators
    • getline ()
  • vs和g++下string结构的说明
    • vs下string的结构
    • g++下string的结构

为什么要学习string?

  提高效率!提高效率!提高效率!
  发展是滚滚向前的,我们是站在巨人肩膀上的一代,C++中有前辈为我们准备好的STL库,对于想要实现某种结构不再需要我们去手搓某一结构供我们使用,对于手搓某一已经被实现的结构再来使用这种行为是对生产力的浪费!


库中的string

  库中的string类是由basic_string类模板实例化而来,原因是因为string是专门用于表示字符序列的对象,而为了能够适应多种语言(汉语,英语,韩语…),basic_string类模也就实例化了不同编码方式的类。

在这里插入图片描述

string编码规则是使用单字节编码,通常采用 ASCII 或 UTF-8 编码
u16string编码规则是UTF-16 编码
u32string编码规则是UTF-32 编码
wstring编码规则是宽字符编码,可以是 UTF-16 或 UTF-32,具体取决于平台

关于编码

  大家思考在计算机中会存储像"哦豁,记得关注博主"这样的字符串内容吗?
  当然不会,在计算机底层存储的是二进制序列,像00001111这样的序列(实际上计算机存储的是一种可以用来表示1或0的状态)。

ASCII编码

  现在我们就来了解一下ASCII编码。
  以下是ASCII编码表:
  在ASCII编码规则中,一个英文字母用一个字节表示,一个汉字用多个字节表示(对于常见汉字一个汉字用两个字节表示)
  为什么出现这样的规则?
  对于英文来讲,无非就是26个英文字母大小写,一个字节就够用了,对于博大精深的汉语来讲,汉字数不胜数,一个字节最多才能表示256个汉字于是就用多个字节表示一个汉字,而在世界上有那么多种语言,那他们怎么表示呢?为了解决这个问题,也是就出现了多种编码方式,这也就是为什么basic_string要实例化多种类。
在这里插入图片描述

  我们可以通过内存存储与sizeof,验证ASCII编码规则。

#include<iostream>		
using namespace std;

int main()
{
	char Estr[] = "apple";
	char Cstr[] = "哦豁,记得关注博主哦";
	cout << sizeof(Estr) << endl;
	cout << sizeof(Cstr) << endl;
	return 0;
}

以下是内存窗口内容:
在这里插入图片描述
以下是运行结果:
(注意:字符串结尾有标识字符串末尾的’/0’)
在这里插入图片描述

Unicode编码

  Unicode编码有多种规范UTF-8、UTF-16、UTF-32。
  UTF-8为可变长度字符编码编码规则如如下:
在这里插入图片描述  UTF-16编码规则是两个字节表示一个字符
  UTF-32编码规则是四个个字节表示一个字符
  对于UTF-16与UTF-32来讲编码规则相较于UTF-8来讲更规范简单,但是空间浪费太大。


温馨提示,string的接口众多,请耐心阅读,对于过于鸡肋接口博主会一笔带过,本文重点讲解C++98的接口
为了方便大家理解,提前声明string的成员变量有哪些,以下为成员对象

size_t _capacity;//对象容量
size_t _size;//对象的有效字符数
char* _str;//字符串

为了方便大家了解string的相关接口,首先要了解string的迭代器

迭代器Iterators

在这里插入图片描述
对于string的迭代器来讲他可以说是STL容器中最简单的,这里提一下,他的迭代器实际为原生指针。后续我们会对string进行模拟实现,到时再详细讲解。

iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
begin() 函数返回一个指向字符串首字符的迭代器,而 end() 函数返回一个指向字符串末尾后一个字符的迭代器(末尾后的一个位置)。const 修饰符版本的函数用于在 const 对象上获取 const 迭代器。

reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
rbegin() 返回一个指向字符串末尾后一个字符的迭代器(末尾位置),而 rend() 函数返回一个指向字符串首字符前一个位置的逆向迭代器。const 修饰符版本的函数用于在 const 对象上获取 const 逆向迭代器。


string常用构造接口

接口声明与功能说明

接口声明功能说明
string();构造空的string类对象,即空字符串
string (const string& str);拷贝构造函数,用str拷贝构造string
string (const string& str, size_t pos, size_t len = npos);用str的pos位置后len长度的内容构造string对象(包括pos位置),如果len超过str长度则用pos位置后直到str末尾位置构造string对象,这里npos=-1
string (const char* s);用C-string来构造string类对象
string (const char* s, size_t n);用C-string来构造string类对象,内容为C-string前n个字符
string (size_t n, char c);string类对象中包含n个字符c
template string (InputIterator first, InputIterator last);使用迭代器范围 [first, last) 来构造一个新的string对象
string (initializer_list il);C++11后出现的构造接口,列表初始化string对象
string (string&& str) noexcept;C++11后出现的构造接口,移动构造string对象

接口演示

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s1;
	string s2("hello world!");
	string s3(s2);
	string s4(s2,1,7);
	string s5("hello world",8);
	string s6(10,'a');
	string s7(s2, 2, 3);
	string s8{ "hello world" };
	string s9(string("hello world"));
	cout << "string();" <<"     " << s1 << endl;
	cout << "string (const char* s);" << "     " << s2<<endl;
	cout << "string (const string& str);" << "     " << s3<<endl;
	cout << "string (const string& str, size_t pos, size_t len = npos);" << "     " << s4<< endl;
	cout << "string (const char* s, size_t n);" << "     " << s5<<endl;
	cout << "string (size_t n, char c);" << "     " << s6<< endl;
	cout << "template string (InputIterator first, InputIterator last);" << "     " << s7<< endl;
	cout << "string (initializer_list il);" << "     " << s8<< endl;
    cout << "string (string&& str) noexcept;" << "     " <<s9 << endl;

	return 0;
}

RUN:
在这里插入图片描述


string类对象的容量操作

接口声明与功能说明

接口声明功能说明
size_t size() const;返回字符串有效字符长度
size_t length() const;返回字符串有效字符长度
size_t capacity() const;返回空间总大小
bool empty() const;检测字符串释放为空串,是返回true,否则返回false
void clear();清空有效字符
void reserve (size_t n = 0);为字符串预留空间
void resize (size_t n);将容量修改成n,不修改有效字符,多余部分填入’\0’
void resize (size_t n, char c);将有效字符的个数改成n个,多出的空间用字符c填充

接口演示

void testCapacity()
{
	string s1("hello world");
	cout << "size()"<< "     " << s1.size() << endl;
	cout << "length()"<<"     " << s1.length() << endl;
	cout << "capacity()" << "     " << s1.capacity() << endl;
	cout << "empty()" << "     " << s1.empty() << endl;


	string s2("hello");
	cout << "扩容前" << endl;
	cout << "reverse()前有效元素数" << "     " << s2.size() << endl;
	cout << "reverse()前容量大小" << "     " << s2.capacity() << endl;
	s2.reserve(50);
	cout << "reserve()扩容机制" << endl;
	cout << "reverse()后有效元素数" << "     " << s2.size() << endl;
	cout << "reverse()后容量大小" << "     " << s2.capacity() << endl;

	s2.reserve(0);
	cout << "reserve()缩容机制" << endl;
	cout << "reverse()后有效元素数" << "     " << s2.size() << endl;
	cout << "reverse()后容量大小" << "     " << s2.capacity() << endl;


	string s3("hello");
	cout << "扩容前" << endl;
	cout << "resize()前有效元素数" << "     " << s3.size() << endl;
	cout << "resize()前容量大小" << "     " << s3.capacity() << endl;
	s3.resize(50);
	cout << "resize()扩容机制" << endl;
	cout << "resize()后有效元素数" << "     " << s3.size() << endl;
	cout << "resize()后容量大小" << "     " << s3.capacity() << endl;


	s3.resize(0);
	cout << "resize()缩容机制" << endl;
	cout << "resize()后有效元素数" << "     " << s3.size() << endl;
	cout << "resize()后容量大小" << "     " << s3.capacity() << endl;


	s3.clear();
	cout << "clear()后有效元素数" << "     " << s3.size() << endl;
	cout << "clear()后容量大小" << "     " << s3.capacity() << endl;
}

RUN:
注意:这是在Windows平台进行演示
在这里插入图片描述

RUN:
注意:这是在Linux(CentOS发行版)平台进行演示

在这里插入图片描述

reverse与resize在不同平台下的扩容与缩容机制

  扩容:

  Windows平台
  每次扩容以合理倍数扩容

  Linux平台
  简单粗暴,扩容至指定大小

  缩容:

  Windows平台:
   reverse无缩容效果
  resize将有效字符修改至指定个数

  Linux平台:
  reverse把容量调整到有效字符数大小
  resize将有效字符修改至指定个数


string类对象的访问及遍历操作

接口声明与功能说明

接口声明功能说明
char& operator[] (size_t pos);返回pos位置的字符,可修改pos位置字符
const char& operator[] (size_t pos) const;返回pos位置的字符,不可修改pos位置字符
char& at (size_t pos);返回pos位置的字符,可修改pos位置字符
const char& at (size_t pos) const;返回pos位置的字符
char& back();获取字符串的最后一个字符,可修改
const char& back() const;获取字符串的最后一个字符,不可修改
char& front();获取字符串的第一个字符,可修改
const char& front() const;获取字符串的第一个字符,不可修改

接口演示

at与operator[] 的区别

  at与operator[] 的区别在于边界检测,at检测出错抛异常,operator[]检测出错程序报错
  at:

void testElementAccessAt() {
	string s1("abcde");
	try {
		cout << s1.at(7) << endl;
	}
	catch (...)
	{

	}
}

RUN:
在这里插入图片描述
  operator[] :

void testElementAccessOperator()
{
	string s1("abcde");
	cout << s1[7] << endl;
}

RUN:
熟悉的警告窗口在这里插入图片描述

back与front

  出现了string的鸡肋接口!对的string的鸡肋接口多的是,本文尽量较少的介绍这种鸡肋接口,大家了解一下即可。

void testElementAccess()
{
	string s1("abcde");
	cout << s1.front() << s1.back() << endl;
}

RUN:
在这里插入图片描述


string类对象的修改操作

接口名称功能说明
operator+=在字符串后追加字符串str
append在字符串后追加一个字符串
push_back在字符串后尾插字符c
insert在指定位置 pos 处插入字符或字符序列
erase删除指定位置的字符或字符范围
replace替换指定位置或字符范围的字符
swap交换两个对象内容
pop_back删除字符串中的最后一个字符
c_str返回C格式字符串
find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

operator+=

string& operator+= (const string& str); //调用对象的末尾拼接一个str对象内容

string& operator+= (const char* s);//调用对象的末尾拼接一个s字符串内容

string& operator+= (char c);//调用对象的末尾拼接一个c字符

void test1()
{   
	string link("xxx");
	string s1;
	s1 += link;
	cout << s1 << endl;
	s1 += "yyy";
	cout << s1 << endl;
	s1 += 'z';
	cout << s1 << endl;
}

RUN:
在这里插入图片描述

append

string& append (const string& str);//将另一个对象的内容添加到当前字符串的末尾。

在这里插入图片描述

string& append (const string& str, size_t subpos, size_t sublen);//将另一个对象的subpos位置(包括subpos位置)后sublen长度的内容添加到当前字符串的末尾。

在这里插入图片描述

string& append (const char* s);//在当前字符串末尾添加一个字符串

在这里插入图片描述

string& append (const char* s, size_t n);//在当前字符串末尾添加一个字符串的前n个字符

在这里插入图片描述

string& append (size_t n, char c);//在当前字符串末尾添加n个c字符
在这里插入图片描述

template string& append (InputIterator first,InputIterator last);//在当前字符串末尾添加一个对象的迭代器区间[first, last) ,这个对象不局限于string对象,只要是数据类型相同的对象均可

在这里插入图片描述

push_back与pop_back

void push_back (char c);//在对象字符串末尾添加一个字符c
void pop_back();//删除对象的最后一个字符

在这里插入图片描述

insert

string& insert (size_t pos, const string& str);//在pos位置处插入一个对象内容
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);//在pos位置处插入一个对象的subpos位置后sublen长度的内容
在这里插入图片描述

string& insert (size_t pos, const char* s);//在pos位置处插入一个字符串内容
string& insert (size_t pos, const char* s, size_t n);//在pos位置处插入一个字符串的前n个字符
string& insert (size_t pos, size_t n, char c);//在pos位置处插入n个字符c
在这里插入图片描述

erase

string& erase (size_t pos = 0, size_t len =npos);
//删除字符串pos位置后len个字符,默认全部删除
iterator erase (iteratorp);
//删除一个迭代器位置,并返回一个指向删除后的下一个字符的迭代器
iterator erase (iterator first,iterator last);
//删除一个迭代器区间,并返回一个指向删除后的下一个字符的迭代器

在这里插入图片描述

replace

string& replace (size_t pos, size_t len, const string&str);
//将字符串的pos位置后len个字符替换为对象str内容
string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_tsublen);
//将字符串的pos位置后len个字符替换为对象str的一个子区间内容在这里插入图片描述

string& replace (size_t pos, size_t len, const char* s);
//将字符串的pos位置后len个字符替换为字符串s内容
string& replace (size_t pos, size_t len, const char* s, size_t n);
//将字符串的pos位置后len个字符替换为字符串s的前n个字符内容
在这里插入图片描述

swap

void swap (string& str);
//交换两个对象内容
在这里插入图片描述

c_str

const char* c_str() const;//这个函数返回一个指向以 null 结尾的字符数组(C 字符串)的指针,表示当前字符串的内容,不可对指针内容修改。
在这里插入图片描述

find与rfind

注意:这里仅对find进行讲解,rfind与find唯一区别就是查找方向不同。

size_t find (const string& str, size_t pos = 0) const;//从pos位置开始寻找一个类,返回其首个字符位置
size_t find (const char* s, size_t pos = 0) const;//从pos位置开始寻找一个字符串,返回其首个字符位置
size_t find (char c, size_t pos = 0) const;//从pos位置开始寻找一个字符,返回其字符位置
以上三个接口查找内容失败均返回npos;
在这里插入图片描述

substr

string substr (size_t pos = 0, size_t len = npos) const;//取子串pos位置后len个字符,返回一个string类
在这里插入图片描述


string类非成员函数

以下函数在模拟实现时博主会再次进行介绍

接口功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator>> ()输入运算符重载
operator<<()输出运算符重载
getline ()获取一行字符串
relational operators大小比较

operator+

该接口就是某一数据与某一数据相加然后返回相加结果
在这里插入图片描述

relational operators

在这里插入图片描述

getline ()

istream& getline (istream& is, string& str, char delim);
//用于从输入流is中读取一行字符串,并将其存储在str中。函数会在遇到指定的分隔符delim或者到达输入流的末尾时停止读取,delim默认是’\n’(换行符)。
istream& getline (istream& is, string& str);//用于从输入流is中读取一行字符串,并将其存储在str中。函数会在遇到换行符时停止
  getline ()具体效果需要自己实践体验

#include <iostream>  
#include <string>  
  
int main() {  
    std::string line;  
    std::getline(std::cin, line); // 读取一行,直到遇到换行符  
    std::cout << "You entered: " << line << std::endl;  
  
    char delimiter = ':';  
    std::getline(std::cin, line, delimiter); // 读取一行,直到遇到冒号  
    std::cout << "You entered up to delimiter: " << line << std::endl;  
  
    return 0;  
}

vs和g++下string结构的说明

vs下string的结构

注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节。
  vs下string的结构
  string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:
    当字符串长度小于16时,使用内部固定的字符数组来存放
    当字符串长度大于等于16时,从堆上开辟空间

union _Bxty
{ // storage for small buffer or pointer to larger one
 value_type _Buf[_BUF_SIZE];
 pointer _Ptr;
 char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

  这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量最后:还有一个指针做一些其他事情。
故总共占16+4+4+4=28个字节。
在这里插入图片描述这种实现技术被称为短字符串优化(SSO,Short String Optimization)

短字符串优化(SSO,Short String Optimization)是 std::string 实现中常见的一种技术,用于优化小字符串的存储和性能。它的基本思想是将小字符串直接存储在 std::string 对象内部,而不是在堆上动态分配内存。这避免了小字符串在堆和栈之间频繁分配和释放的开销,同时减少了内存碎片。

实现上,std::string 对象内部通常会包含一个固定大小的缓冲区(比如15或22个字符的空间),用于直接存储短字符串。当字符串的长度小于或等于这个缓冲区的大小时,字符串的内容就直接存放在这个缓冲区里,不需要额外的动态内存分配。当字符串的长度超过缓冲区的大小时,std::string 就会在堆上动态分配内存来存储字符串的内容,并释放之前使用的缓冲区空间(如果有的话)。

g++下string的结构

  g++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:

空间总大小
字符串有效长度
引用计数
指向堆空间的指针,用来存储字符串


本章到此结束,感谢您的阅读!

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

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

相关文章

stm32中的中断优先级

在工作中使用到多个定时器中断,由于中断的中断优先级不熟悉导致出错,下面来写一下中断的一些注意事项。 一、中断的分类 1、EXTI外部中断:由外部设备或外部信号引发,例如按键按下、外部传感器信号变化等。外部中断用于响应外部事件,并及时处理相关任务。 2、内部中断:…

3DGS渐进式渲染 - 离线生成渲染视频

总览 输入&#xff1a;环绕Object拍摄的RGB视频 输出&#xff1a;自定义相机路径的渲染视频&#xff08;包含渐变效果&#xff09; 实现过程 首先&#xff0c;编译3DGS的C代码&#xff0c;并跑通convert.py、train.py和render.py。教程如下&#xff1a; github网址&#xf…

如何安装 IntelliJ IDEA 最新版本——详细教程

IntelliJ IDEA 简称 IDEA&#xff0c;被业界公认为最好的 Java 集成开发工具&#xff0c;尤其在智能代码助手、代码自动提示、代码重构、代码版本管理(Git、SVN、Maven)、单元测试、代码分析等方面有着亮眼的发挥。IDEA 产于捷克&#xff0c;开发人员以严谨著称的东欧程序员为主…

利用大语言模型,矢量数据库实现数据库的智能搜索

目的 数据库使用SQL 语言查询数据&#xff0c;数据库的记录中要有一个关键字段&#xff08;通常称为主键字段&#xff0c;它的值在数据库列表中是唯一的&#xff09;,数据记录是结构化的. 如果你需要根据数据记录的内容来查询数据记录&#xff0c;就需要通过Select 语句在数据库…

SQL255 给出employees表中排名为奇数行的first_name

题目来源&#xff1a; 给出employees表中排名为奇数行的first_name_牛客题霸_牛客网 描述 对于employees表中&#xff0c;输出first_name排名(按first_name升序排序)为奇数的first_name CREATE TABLE employees ( emp_no int(11) NOT NULL, birth_date date NOT NULL, firs…

春藤实业启动SAP S/4HANA Cloud Public Edition项目,与工博科技携手数字化转型之路

3月11日&#xff0c;广东省春藤实业有限公司&#xff08;以下简称“春藤实业”&#xff09;SAP S/4HANA Cloud Public Edition&#xff08;以下简称“SAP ERP公有云”&#xff09;项目正式启动。春藤实业董事长陈董、联络协调项目经理慕总、内部推行项目经理陈总以及工博董事长…

【.Net动态Web API】背景与实现原理

&#x1f680;前言 本文是《.Net Core进阶编程课程》教程专栏的导航站&#xff08;点击链接&#xff0c;跳转到专栏主页&#xff0c;欢迎订阅&#xff0c;持续更新…&#xff09; 专栏介绍&#xff1a;通过源码实例来讲解Asp.Net Core进阶知识点&#xff0c;让大家完全掌握每一…

pt-archiver归档表数据

一 介绍 pt-archiver的原理主要是根据定义的时间间隔(sleep参数)&#xff0c;扫描要清理的数据表。它按照指定的规则分批(limit参数)将查询到的记录转移到其他表或文件中&#xff0c;发现它是按主键去删除的表数据&#xff0c;对数据库影响很小。 二 语法 /bin/pt-archiver …

关于外网java后端服务访问内网minio中间件,因连接minio超时,启动失败问题

注&#xff1a;服务器情况&#xff1a;2台服务器&#xff0c;内网服务器包含&#xff08;activemq、minio、nginx、redis、mysql、后端java服务&#xff09;。外网服务器只有后端java服务&#xff0c;访问内网的中间件&#xff08;内网服务器开放了部分指定端口&#xff09; 问…

GPT状态和原理 - 解密OpenAI模型训练

目录 1 如何训练 GPT 助手 1.1 第一阶段 Pretraining 预训练 1.2 第二阶段&#xff1a;Supervised Finetuning有监督微调 1.3 第三阶段 Reward Modeling 奖励建模 1.4 第四阶段 Reinforcement Learning 强化学习 1.5 总结 2 第二部分&#xff1a;如何有效的应用在您的应…

中文编程入门(Lua5.4.6中文版)第十二章 Lua 协程 参考《愿神》游戏

在《愿神》的提瓦特大陆上&#xff0c;每一位冒险者都拥有自己的独特力量——“神之眼”&#xff0c;他们借助元素之力探索广袤的世界&#xff0c;解决谜题&#xff0c;战胜敌人。而在提瓦特的科技树中&#xff0c;存在着一项名为“协同程序”的高级秘术&#xff0c;它使冒险者…

Go 语言中的 GIF 图像处理完全指南:`image/gif`的技术与实践

Go 语言中的 GIF 图像处理完全指南&#xff1a;image/gif的技术与实践 概述安装与基础设置导入 image/gif 包初步配置示例&#xff1a;设置一个简单的 GIF 编码环境 读取与解码 GIF 图像读取 GIF 文件解析 GIF 数据 创建与编码 GIF 图像创建 GIF 图像编码 GIF 图像 处理 GIF 动…

利用 Python 开发手机 App 实战

Python语言虽然很万能&#xff0c;但用它来开发app还是显得有点不对路&#xff0c;因此用Python开发的app应当是作为编码练习、或者自娱自乐所用&#xff0c;加上目前这方面的模块还不是特别成熟&#xff0c;bug比较多&#xff0c;总而言之&#xff0c;劝君莫轻入。 准备工作 …

BGP边界网关路由实验(华为)

一&#xff0c;技术简介 BGP&#xff08;边界网关路由协议&#xff09;是一种自治系统&#xff08;AS&#xff09;间的协议&#xff0c;主要用于在不同的AS之间交换路由信息。AS是一个由一组网络设备和路由器组成的网络集合&#xff0c;这些设备可以在一个共同的管理域中协同工…

通过本机电脑远程访问路由器loopback的ip

实验拓扑图 本机电脑增加路由信息 正常设置telnet用户&#xff0c;然后通过本地电脑telnet 软件ensp中的设备&#xff0c;尝试是否可以正常访问即可 测试通过本地电脑可以正常访问ensp里面设备的loopback的ip地址了 最重要的一点是本机需要增加一条路由route add ip mask 下…

.NET 发布,部署和运行应用程序

.NET应用发布 发布.Net应用有很多种方式&#xff0c;下面列举三种发布方式&#xff1a; 单文件发布跨平台发布Docker发布 单文件发布 右键工程&#xff0c;选择“发布”&#xff0c;部署模式选择“独立”&#xff0c;目标运行时选择自己想要部署到的系统&#xff0c;我这里用…

GIT上超火的阿里内部1000页Java核心笔记,啃完竟然拿到阿里P7offer!

除了ReetrantLock&#xff0c;你还接触过JUC中的哪些并发工具&#xff1f; 请谈谈ReadWriteLock 和StampedLock。 如何让Java的线程彼此同步&#xff1f;你了解过哪些同步器&#xff1f;请分别介绍下。 CyclicBarrier和CountDownLatch看起来很相似&#xff0c;请对比下呢&am…

分布式限流——Redis + Lua脚本实现令牌桶算法

主要思路概括如下&#xff1a; 定义数据结构&#xff1a; 使用Redis存储令牌桶的状态&#xff0c;包括当前令牌数&#xff08;KEYS[1]&#xff09;和上一次令牌填充的时间戳&#xff08;KEYS[1]:last&#xff09;。 计算新增令牌&#xff1a; 获取当前系统时间与上次令牌填充时…

type-cDP输入转双type-cDP输出,加type-c接口充电管理同时接两台显示器或者VR投屏,龙迅LT8712SX方案,龙迅桥接芯片方案

type-c的应用在各种设备上更加广泛&#xff0c;包括手机&#xff0c;电脑&#xff0c;游戏掌机&#xff0c; 因为type-c的功能非常强大&#xff0c;可以做到PD快充&#xff0c;DP信号输出&#xff0c;USB信号输出&#xff0c;所以很多设备为了做得更简洁都开始把其他的如HDMI接…

Docker应用推荐个人服务器实用有趣的项目推荐

Wallabag&#xff1a;是一个开源的、自托管的文章阅读和保存工具。它允许你保存网页文章并进行离线阅读&#xff0c;去除广告和不必要的内容&#xff0c;以提供更好的阅读体验。Wallabag支持多种导入和导出格式&#xff0c;并提供了一些实用的功能&#xff0c;如标签、阅读列表…