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

【C++初阶】--- string类模拟实现

1.基础函数

1.1成员函数

成员函数主要是_str、_size、_capacity这三个。npos是size_t 的最大值,用于当作后续成员函数的参数的缺省值。

class string
{
private:char* _str = nullptr;//指向字符串的指针size_t _size = 0;//字符串长度size_t _capacity = 0;//空间大小static const size_t npos;
};

1.2默认构造函数

默认构造我们给str一个缺省值"",即没有传参的时候字符串为空,只有一个’\0’,因为strcpy会把’\0’拷贝过来

//默认构造
string(const char* str = "")//如果没传值的话会拷贝'\0''
{_capacity = _size = strlen(str);_str = new char[_capacity + 1];strcpy(_str, str);
}

1.3拷贝构造

拷贝构造有两种写法,一种是普通写法,一种是现代写法

  1. 普通写法:
    我们先根据要拷贝的对象确认空间大小,然后new一块空间,new出空间后利用strcpy将字符串中的内容拷贝过来
//拷贝构造
string(const string& s)
{_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;
}
  1. 现代写法:
    我们利用要拷贝的那个字符串构造一个string对象tmp,然后我们自己写一个swap函数用于交换两个string对象的内容,这样我们就可以将tmp中的内容交换到我们要拷贝构造的这个对象中。
    需要注意的是注意相关成员变量需要给缺省值,否则交换后tmp的_str可能是野指针。因为tmp是个局部对象,出了拷贝构造就要调用析构函数。
//交换两个字符串的值
void swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}
//现代写法,拷贝构造
string(const string& s)
{//利用s._str构造tmp,再使用tmp与this交换//注意相关成员变量需要给缺省值,否则交换后tmp的_str可能是野指针string tmp(s._str);swap(tmp);
}

1.4赋值运算符重载

赋值运算符重载也分为普通写法和现代写法

  1. 普通写法:
    在不是给自己赋值的情况下,我们先delete原对象字符串的的空间,然后new一个和赋值对象字符串一样大的空间,在利用strcpy拷贝内容,更新长度和空间大小。
//赋值运算符重载
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;
}
  1. 现代写法
    写法1我们可以利用对象的字符串来构造tmp,或者直接用对象拷贝构造tmp。构造出tmp后交换此对象与tmp对象,两者内容也就交换了。
    写法2更为简介,首先我们参数不再是引用,而是传值,则tmp只是一份拷贝。传值传参,对形参的的改变不会影响实参,我们直接用传过来的tmp进行交换。
//现代写法,赋值运算符重载
//写法1
string& operator=(const string& s)//不用引用,则tmp只是一份拷贝
{if (this != &s){//string tmp(s._str);//用s._str构造tmpstring tmp(s);//用s拷贝构造tmpswap(tmp);}return *this;
}//写法2,优化
string& operator=(string tmp)//不用引用,则tmp只是一份拷贝
{//交换tmp不会对tmp原本的值造成影响swap(tmp);return *this;
}

1.5析构函数

因为我们有资源的申请,需要显示写析构函数将new的空间delete

//析构
~string()
{//不析构空指针if (_str){delete[] _str;_str = nullptr;_size = _capacity = 0;}
}

2.可以写在类里的成员函数

短小的函数和频繁调用的函数可以直接写在类中,在类中写的成员函数函数默认是inline函数(内联函数)

2.1size()和capacity()

size()返回的是字符串的长度,capacity返回的是空间的大小

size_t size() const
{return _size;
}size_t capacity() const
{return _capacity;
}

2.2empty()、clear()、c_str()

  1. empty()用于判断字符串是否为空,空返回true,非空返回false
  2. clear()用于清除字符串中的内容,一般不会清除空间
  3. c_str()用于获取等效的字符串
//判空
bool empty() const
{return _size == 0;
}//清除字符串,不清除空间
void clear()
{_str[0] = '\0';_size = 0;
}//获取等效的字符串
const char* c_str() const
{return _str;
}

2.3operator[]

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

[]重载,可以获取字符串中对应下标的元素,前提确保不能越界,const重载返回的元素不能逆行修改。

char& operator[](size_t index)
{//确保有效位置assert(index < _size);return _str[index];
}
const char& operator[](size_t index) const
{assert(index < _size);return _str[index];
}

3.迭代器iterator

迭代器的底层我们暂且可以认为是指针

typedef char* iterator;//正向迭代器
typedef const char* const_iterator;//正向只读迭代器

3.1begin()和end()

  1. begin()会返回一个指向字符串的第一个字符的迭代器。
  2. end()会返回一个指向字符串的最后一个字符的下一个位置的迭代器,即’\0’位置
const_iterator begin() const
{return _str;
}const_iterator end() const
{return _str + _size;
}iterator begin()
{return _str;
}iterator end()
{return _str + _size;
}

4.修改空间大小的函数

4.1resver()

void reserve (size_t n = 0);

resver()用于请求更改容量
• 如果 n 大于当前字符串容量,则该函数会导致容器将其容量增加到 n 个字符(或更大)。
• 如果n <= 当前字符串容量,容量是否变化取决于编译器。
• 此函数对字符串长度没有影响,也无法更改其内容。

void string::resver(size_t n)
{//n <= _capacity的话我们选择不改变容量if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}
}

4.2resize()

resize()用于调整字符串大小
• 将字符串大小调整为 n 个字符的长度。
• 如果 n 小于当前字符串长度,则当前值将缩短为其前 n 个字符,并删除第 n个字符以外的字符。
• 如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容,以达到 n 的大小。如果指定了 c,则新元素将初始化为 c 的副本,否则,它们是值初始化字符(空字符)。

memset将 ptr 指向的内存块的前num字节数设置为指定值value

void * memset ( void * ptr, int value, size_t num );
//调整字符串大小
void string::resize(size_t newSize, char c)
{//n 大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容if (newSize > _size){//newSize比空间大,需要进行扩容if (newSize > _capacity){resver(newSize);memset(_str + _size, c, newSize - _size);}else{memset(_str + _size, c, _capacity - _size);}}//n 小于当前字符串长度,则当前值将缩短为其前 n 个字符,并删除第 n个字符以外的字符else{_str[newSize] = '\0';_size = newSize;}_capacity = newSize;_str[newSize] = '\0';
}

5.用于修改字符串内容的函数

5.1push_back()

push_back()用于尾插一个字符

void push_back (char c);

插入字符前我们先考虑容量是否足够,不够的话我们就2倍扩容,不要忘了结尾加上’\0’

//尾插字符
void string::push_back(char c)
{//考虑扩容if (_size == _capacity){resver(_capacity == 0 ? 4 : 2 * _capacity);}_str[_size++] = c;_str[_size] = '\0';
}

5.2operator+=()

operator+=()用于尾插字符、字符串、string对象,我们模拟实现尾插字符和字符串。

string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);

尾插字符我们可以直接复用push_back(),两者功能一样

//在末尾追加字符
string& string::operator+=(char c)
{//直接复用push_back(c);return *this;
}

在末尾追加字符串我们可以直接复用append(),这个等下讲,append()用于尾插字符串。

//在末尾追加字符串
string& string::operator+=(const char* str)
{//直接复用append(str);return *this;
}

5.3append()

依旧先考虑扩容问题,但因为我们是2倍扩容,如果_size + len比2倍还大,那空间依旧不够用,那就他要多少我们扩多少。扩容完我们strcpy将字符串中内容进行拷贝。

//在末尾追加字符串
void string::append(const char* str)
{//考虑扩容size_t len = strlen(str);if (_size + len > _capacity){//比2倍大就按需扩容,否则就直接2倍扩resver(_size + len > 2 * _capacity ? _size + len : 2 * _capacity);}strcpy(_str + _size, str);_size += len;
}

5.4insert()

insert()用于将其他字符插入字符串中 pos(或 p)指示的字符之前,并返回该字符的位置

string& insert (size_t pos, const char s);
string& insert (size_t pos, const char* s);

需要注意pos不能越界,然后考虑扩容,然后移动pos位置及之后的数据向后移动一位('\0’一起移动),移动完后在pos位置放入对应字符。

//在pos位置插入字符
string& string::insert(size_t pos, const char c)
{//pos可以在尾部,相当于尾插assert(pos <= _size);//考虑扩容if (_size == _capacity){resver(_capacity == 0 ? 4 : 2 * _capacity);}//'\0'一起移size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];end--;}_str[pos] = c;_size++;return *this;
}

在pos位置插入字符串和插入字符操作差不多,不同的是扩容的操作和向后移动的距离。

//在pos位置插入字符串
string& string::insert(size_t pos, const char* str)
{assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){resver(_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[i + pos] = str[i];}_size += len;_str[_size] = '\0';return *this;
}

5.5erase()

erase()用于擦除字符串的一部分,减少其长度

const size_t string::npos = -1;
string& erase (size_t pos = 0, size_t len = npos);

先判断pos是否越界,如果要删除的长度超过字符剩余长度,说明pos位置及之后的字符都需要删除,我们直接将pos位置的数据修改成’\0’,即字符串的结尾。
如果要删除的长度小于字符剩余长度,则说明说明后面还剩余有效字符,需要将这些字符向前移动len长度。

//删除pos位置开始的len个元素
string& string::erase(size_t pos, size_t len)
{assert(pos < _size);//len超过剩余长度,则说明后面全删了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;}return *this;
}

6.查找字符串中的内容

6.1find()

find()用于在字符串中搜索和参数(字符或者字符串)匹配的第一个匹配项,并返回其在字符串中的下标。

size_t find (const char* s, size_t pos = 0) const;
size_t find (char c, size_t pos = 0) const;

判断pos是否越界,然后从pos位置开始向后找,找到就返回下标,没找到则返回npos。

//从pos位置开始往后找字符c,返回下标
size_t string::find(char c, size_t pos) const
{//pos有效性assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == c)return i;}//没有找到return npos;
}

strstr()函数可以返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回 null 指针。

char * strstr (char * str1, const char * str2 );

如果tmp不为nullptr,则说明子串存在,返回的则是str2第一次出现的指针,将tmp指针与字符串指针_str相减,两指针相减即地址相减,可以得出下标。

//返回字串在string中第一次出现的位置
size_t string::find(const char* str, size_t pos) const
{assert(pos < _size);const char* tmp = strstr(_str + pos, str);if (tmp == nullptr)return npos;elsereturn tmp - _str;		
}

6.2substr()

substr()用于生成子字符串,可以生成一个从pos位置开始,长度为len的字符串,如果剩余长度小于len,则拷贝至末尾停止。
如果没有给定len,则按照缺省值拷贝,npos是个无符号整型,-1转换成无符号整型是INT_MAX,即从pos位置拷贝至末尾

const size_t string::npos = -1;
string substr (size_t pos = 0, size_t len = npos) const;

确定拷贝长度,然后为子字符串开空间,并拷贝字符。

//生成子字符串
string string::substr(size_t pos, size_t len)
{assert(pos < _size);//len大于剩余长度,将len更新为剩余长度if (len > _size - pos){len = _size - pos;}string sub;sub.resver(len);//开空间for (size_t i = 0; i < len; i++){sub += _str[i + pos];}return sub;
}

7.运算符重载

7.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);
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 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 !(s1 == s2);
}

7.2流插入、流提取运算符重载

ostream& operator<< (ostream& os, const string& str);//流插入
istream& operator>> (istream& is, string& str);//流提取

流插入我们使用范围for将字符串一个一个插入即可

	ostream& operator<<(ostream& out, const string& s){//范围forfor (auto ch : s){out << ch;}return out;}

流提取我们则要先清除对象字符串中的字符,buff的作用是为了避免插入字符过程中的频繁扩容,使用用buff先存储输入的字符,满了之后我们将buff字符串尾插到对象s的字符串中。
cin遇到空格或者换行就不读取了,我们模拟实现也是遇到空格或者换行即停止。
我们读取字符的时候使用ch = in.get();而不是cin>>ch是因为cin默认空格和换行是间隔符,不会进行读取,也就是说我们永远读取不到空格和换行,程序将陷入死循环,而get()可以读到空格和换行。
注意循环结束后如果i>0说明buff中还有字符,我们需要将其尾插至对象s的字符串中。

istream& operator>>(istream& in, string& s){//先清除s中的字符s.clear();const int N = 256;char buff[N];int i = 0;//不能用in>>ch,因为读不到空格和换行,默认是间隔符char ch = in.get();while(ch != ' ' && ch != '\n'){buff[i++] = ch;//满了,最后一个填'\0'if (i == N - 1){buff[i] = '\0';s += buff;i = 0;}//继续读下一个字符ch = in.get();}//不足256个不会尾插,将剩下的尾插进去if (i > 0){buff[i] = '\0';s += buff;}return in;}
}

相关文章:

【C++初阶】--- string类模拟实现

1.基础函数 1.1成员函数 成员函数主要是_str、_size、_capacity这三个。npos是size_t 的最大值,用于当作后续成员函数的参数的缺省值。 class string { private:char* _str nullptr;//指向字符串的指针size_t _size 0;//字符串长度size_t _capacity 0;//空间大小static c…...

Pythia 使用说明

Pythia 是一个由非营利研究组织 EleutherAI 开发的开源语言模型套件&#xff0c;专注于透明性和可复现性。它是为了推动自然语言处理&#xff08;NLP&#xff09;领域的开放研究而设计&#xff0c;尤其在模型训练过程和性能分析方面提供了详尽的文档和数据。 Pythia 的核心特点…...

python:获取某路径下所有图片的名称

可以使用 Python 的 os 模块或者 pathlib 模块来获取指定路径下所有图片的名称。以下是使用这两种方法实现的代码示例&#xff1a; 使用 os 模块 import osdef get_image_names_os(path):image_extensions (.jpg, .jpeg, .png, .gif, .bmp)image_names []for root, dirs, f…...

一个开源的 VS Code 大模型聊天插件:Light-at

这篇文章是一个开发杂谈。对于有经验的开发者来说&#xff0c;可能这个项目并不算特别复杂或者高技术&#xff0c;只是对我个人来说算一个里程碑&#xff0c;因此写篇杂谈文章记录一下。也许也能给起步者一些参考。 项目地址&#xff1a;https://github.com/HiMeditator/light-…...

图论学习笔记2

请先阅读图论学习笔记 1。 在这篇文章里&#xff0c;我们将继续以前 tarjan 求解的强连通分量和双连通分量&#xff0c;讲解其缩点相关内容。 也会讲解一些特殊的图&#xff1a;基环树与仙人掌图、最小树形图。 缩点 我们知道&#xff0c;将强连通分量、双连通分量缩点之后…...

蓝桥杯备赛---真题训练之15届省赛产品360度展示

题目 介绍 在电子商务网站中&#xff0c;用户可以通过鼠标或手势交互实现 360 度全方位查看产品&#xff0c;提升用户体验。现在需要你设计一个 Pipeline 管道函数&#xff0c;用于控制 360 度展示产品的动画序列&#xff0c;通过管道连接各个动画步骤&#xff0c;使产品以流畅…...

图论:单源最短路(BF算法+迪杰斯特拉算法+spfa算法)

单源最短路 概念 dijkstra实现&#xff08;解决不了负权值&#xff09; P3371 【模板】单源最短路径&#xff08;弱化版&#xff09; - 洛谷 #include<iostream> #include<vector> #include<cstring> using namespace std;typedef pair<int, int> PII…...

嵌入式学习(35)-TTS语音模块FT-VBM-OS支持ModbusRTU

一、概述 FT-TTS-R-01 &#xff08;下简简“模块”&#xff09;是一款可将串口传入的文本信息转成语音播报的控制器。块”可下接收任意字 符或者汉字&#xff0c;并通过 TTS 语音合成功能&#xff0c;清晰、准确、自然的合成并播放音频。该块”还带有 1 路继电器输出&#xff0…...

【Vue-组件】学习笔记

目录 <<回到导览组件1.项目1.1.Vue Cli1.2.项目目录1.3.运行流程1.4.组件的组成1.5.注意事项 2.组件2.1.组件注册2.2.scoped样式冲突2.3.data是一个函数2.4.props详解2.5.data和prop的区别 3.组件通信3.1.父子通信3.1.1.父传子&#xff08;props&#xff09;3.1.2.子传父…...

Github上一些使用技巧(缩写、Issue的Highlight)自用

1. GIthub中的一些缩写 LGTM ! 最近经常看到一些迷之缩写&#xff0c;感觉挺有意思的&#xff0c;但是有时候看到一些没见过的缩写还是有点懵逼&#xff0c;不过缩写确实也是很方便去review&#xff0c;这里就记录汇总一下&#xff1b;顺便加了一些git的基操单词&#xff08;加…...

【团体程序涉及天梯赛】L1~L2实战反思合集(C++)

实战反思汇总记录 仔细审题&#xff0c;想好再写 L1-104 九宫格 - 团体程序设计天梯赛-练习集 易忽略的错误&#xff1a;开始习惯性地看到n就以为是n*n数组了&#xff0c;实际上应该是9*9的固定大小数组&#xff0c;查了半天没查出来 L1-101 别再来这么多猫娘了&#xff01…...

ubuntu下的node.js的安装

安装 node-v22.14.0-linux-x64.tar.xz 的步骤如下&#xff1a; 1. 下载和解压 如果尚未下载文件&#xff0c;可以通过 wget 下载&#xff08;替换为实际下载链接&#xff09;&#xff1a; wget https://nodejs.org/dist/v22.14.0/node-v22.14.0-linux-x64.tar.xz解压文件&…...

VMware-workstation-full-12.5.2 install OS X 10.11.1(15B42).cdr

手把手虚拟机安装苹果操作系统 VMware_workstation_full_12.5.2 unlocker208 Apple Max OS X(M&#xff09;-CSDN博客 vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1180 FILE: FileCreateDirectoryRetry: Non-retriable error encountered (C:\ProgramData\VMware): Cann…...

Linux下创建svn库 和 svn安装与操作

1.介绍 SVN是Subversion的简称&#xff0c;是一个开放源代码的版本控制系统&#xff0c;相较于RCS、CVS&#xff0c;它采用了分支管理系统&#xff0c;它的设计目标就是取代CVS。适合中小公司的开发人员不多的项目使用,相比git管理工具更简单. 2.安装svn 2.1 国际惯例 首先看…...

React-04React组件状态(state),构造器初始化state以及数据读取,添加点击事件并更改state状态值

1.React组件状态&#xff08;state&#xff09; 组件可以拥有状态&#xff08;state&#xff09;&#xff0c;它是组件数据的私有部分&#xff0c;可以用来管理动态数据。状态仅适用于类组件&#xff0c;或者使用 React 的 Hook 时可以在函数组件中使用。 注意 组件中render方…...

第3课:MCP协议接口定义与开发实践

MCP协议接口开发实战&#xff1a;从标准化设计到跨语言SDK落地 一、引言&#xff1a;为什么接口标准化是多智能体协作的“刚需” 在多智能体系统中&#xff0c;不同语言开发的智能体、异构服务之间的通信效率往往受制于接口兼容性问题。MCP&#xff08;Model Context Protoco…...

Perl语言的WebAssembly

Perl语言的WebAssembly&#xff1a;将古老的语言带入新世纪 引言 在编程语言发展的历史长河中&#xff0c;Perl作为一门早期广泛使用的脚本语言&#xff0c;以其灵活性和丰富的文本处理能力而闻名。然而&#xff0c;随着互联网和Web技术的迅猛发展&#xff0c;许多开发者开始…...

[ISP] ISP 中的 GTM 与 LTM:原理、算法与与 Gamma 校正的对比详解

在现代图像信号处理&#xff08;ISP&#xff09;流水线中&#xff0c;图像增强是提升视觉质量的核心手段之一。尤其是在高动态范围&#xff08;HDR&#xff09;内容、弱光环境或复杂光照条件下&#xff0c;Tone Mapping&#xff08;色调映射&#xff09;技术的引入成为关键。To…...

健身管理小程序|基于java微信开发健身管理小程序的系统设计与实现(源码+数据库+文档)

健身管理小程序目录 基于微信开发健身管理小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 小程序端&#xff1a; 后台 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码…...

批量将文本合并成单个文件,支持按文件夹合并文本文档

我们的文件夹中有零零碎碎的多个小的文本文件&#xff0c;这对我们存档记录是非常不方便&#xff0c;不友好的。如果我们能够将多个小的文本文件合并成一个完整的大的文本文件&#xff0c;那不管是在共享还是在存档起来都更加的方便。今天给大家介绍一下如何批量将多个文本文件…...

ROS云课三分钟-差动移动机器人巡逻报告如何撰写-中等报告

评语&#xff1a; 成绩中等&#xff08;70/100&#xff09;&#xff0c;具体如下&#xff1a; 1. 摘要部分 问题描述&#xff1a; 内容空洞&#xff1a;摘要过于简短&#xff0c;仅简要概述了研究内容和实现方法&#xff0c;未突出研究的创新点或重要性。缺乏细节&#xff1…...

forms实现推箱子小游戏

说明: forms实现推箱子小游戏 效果图&#xff1a; step0:游戏规则 # 推箱子游戏规则说明## &#x1f3af; 游戏目标 - 通过控制角色移动&#xff0c;将所有**棕色箱子(3)**推到**红色目标点(4)**上 - 当所有箱子都变为**绿色(7)**时&#xff0c;即完成当前关卡 - 完成全部关…...

图的储存+图的遍历

图的存储 邻接矩阵 #include <iostream>#include <cstring>using namespace std;const int N 1010;int n, m;int edges[N][N];int main() {memset(edges, -1, sizeof edges);cin >> n >> m; // 读⼊结点个数以及边的个数 for(int i 1; i < m; i)…...

蓝桥杯—数字接龙(dfs+减枝)

一.题目 二.思路 一看就是迷宫问题的变种&#xff0c;从左上角到达右下角&#xff0c;要解决 1.8个方向的方向向量&#xff0c;用dx&#xff0c;dy数组代表方向向量 2.要按照一个规律的数值串进行搜索0&#xff0c;1&#xff0c;2&#xff0c;k-1&#xff0c;0&#xff0c;1…...

Solidity智能合约漏洞类型与解题思路指南

一、常见漏洞类型与通俗解释 1. 重入攻击(Reentrancy) 🌀 通俗解释:就像你去银行取钱,柜台人员先给你钱,然后再记账。你拿到钱后立即又要求取钱,由于账还没记,柜台又给你一次钱,这样循环下去你就能拿走银行所有的钱。 漏洞原理:合约在更新状态前调用外部合约,允许…...

临床 不等于 医学-《分析模式》漫谈52

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的第4章“企业财务观察”有这么一句话&#xff1a; An important point about this model——a reflection of its clinical background 2004&#xff08;机械…...

鸿蒙应用开发中的 Stack 布局模式

在鸿蒙(HarmonyOS)应用开发中&#xff0c;Stack 布局模式是一种非常灵活的布局方式&#xff0c;类似于其他开发框架中的 StackPanel 或 AbsoluteLayout。它允许子组件按照层级关系进行堆叠&#xff0c;后添加的组件会覆盖在先添加的组件之上。开发者可以通过设置组件的位置、大…...

仿modou库one thread one loop式并发服务器

源码&#xff1a;田某super/moduo 目录 SERVER模块&#xff1a; Buffer模块&#xff1a; Socket模块&#xff1a; Channel模块&#xff1a; Connection模块&#xff1a; Acceptor模块&#xff1a; TimerQueue模块&#xff1a; Poller模块&#xff1a; EventLoop模块&a…...

【AI学习】初步了解Gradio

Gradio 是一个开源的 Python 库&#xff0c;专注于快速构建交互式 Web 界面&#xff0c;特别适用于机器学习模型、数据科学项目或任意 Python 函数的演示与部署。它通过极简的代码实现前后端一体化&#xff0c;无需前端开发经验即可创建功能丰富的应用。以下是 Gradio 的核心特…...

C++11QT复习 (十四)

文章目录 Day9 数据结构学习笔记&#xff08;2025.04.01&#xff09;一、C基础快速回顾二、STL&#xff08;标准模板库&#xff09;三、常见容器及其对应的数据结构四、容器操作演示1. 基本容器使用2. 异构类型容器 五、迭代器详解特点示例用户自定义结构体访问成员 六、算法库…...

ThreadCache

目录 一、Freelist 二、ThreadCache 三、哈希桶映射规则 一、Freelist 在之前整体框架介绍的时候&#xff0c;我们曾说过ThreadCache是一个哈希桶的结构。每一个桶都要存同一个大小的对象块&#xff08;即最小块的内存&#xff09;。 那么我们使用FreeList来…...

c++中同步和异步,阻塞和非阻塞原理以及机制

在C中&#xff0c;同步与异步、阻塞与非阻塞是并发编程中的重要概念&#xff0c;它们描述了程序在执行任务时的行为模式。理解这些概念对于设计高效、响应良好的并发程序至关重要。下面我将详细介绍这些概念的原理和机制。 1. 同步与异步 同步&#xff08;Synchronous&#x…...

Python项目打包指南:PyInstaller与SeleniumWire的兼容性挑战及解决方案

前言 前段时间做一个内网开发的需求&#xff0c;要求将selenium程序打包成.exe放在内网的win7上运行&#xff0c;在掘金搜了一圈也没有发现相关文章&#xff0c;因此将过程中踩到的坑记录分享一下。 本文涵盖了具体打包操作、不同模块和依赖项的兼容性解决方案&#xff0c;以…...

浅谈微信视频号推荐算法

这次可能会稍微有点干货&#xff0c;但保证不晦涩~ 一、算法推荐的本质&#xff1a;猜你喜欢 vs 社交绑架​ 视频号的推荐系统本质上在做两件事&#xff1a; ​预测你的兴趣​&#xff1a;通过你的浏览、点赞、评论、分享等行为&#xff0c;分析你的偏好。​满足社交需求​&…...

selenium 常用方法

selenium 库的常用方法&#xff1a; 方法说明示例代码webdriver.Chrome()初始化 Chrome 浏览器实例。driver webdriver.Chrome()driver.get(url)访问指定的 URL 地址。driver.get("https://example.com")driver.find_element(By, value)查找第一个匹配的元素。elem…...

springboot中使用async实现异步编程

目录 1.说明 2.实现原理 3.示例 4.总结 1.说明 Async 是 Spring 框架提供的一个注解&#xff0c;用于标记方法为异步执行。被标记的方法将在调用时立即返回&#xff0c;而实际的方法执行将在单独的线程中进行。 Async 注解有一个可选属性&#xff1a;指定要使用的特定线程…...

【2024年蓝桥杯Java B组】省赛真题详细解析

【2024年蓝桥杯Java B组】省赛真题 距离比赛仅剩5天&#xff0c;大多数省份可能完成3-4题即可拿到省奖&#xff0c;2025年想要拿到省奖&#xff0c;需要高效利用时间&#xff0c;重点突破关键知识点和题型。这里以【2024年蓝桥杯Java B组省赛真题】为例&#xff0c;梳理我们最后…...

SQL:DDL(数据定义语言)和DML(数据操作语言)

目录 什么是SQL&#xff1f; 1. DDL&#xff08;Data Definition Language&#xff0c;数据定义语言&#xff09; 2. DML&#xff08;Data Manipulation Language&#xff0c;数据操作语言&#xff09; DDL和DML的区别 什么是SQL&#xff1f; SQL&#xff08;Structured …...

机器学习核心概念、算法分类与应用场景全解析

文章目录 一、基础任务与算法分类1. 分类任务&#xff08;监督学习&#xff09;2. 回归任务&#xff08;监督学习&#xff09;3. 聚类任务&#xff08;无监督学习&#xff09; 二、关键流程与技术细节1. 数据预处理2. 特征工程3. 数据集划分与评估 三、进阶技术1.深度学习2.强化…...

【leetcode】—416.分割等和子集

✏️ 关于专栏&#xff1a;专栏用于记录 LeetCode 中做题与总结 文章目录 分割等和子集▐ 题目描述▐ 题目示例▐ 题目提示▐ 思路&代码方法&#xff1a;动态规划 分割等和子集 ▐ 题目描述 题目链接&#xff1a;分割等和子集 给你一个 只包含正整数 的 非空 数组 nums …...

jemeter 之mysql驱动问题

问题 java.sql.SQLException: No suitable driver found for jdbc:mysql 解决 先把jar放到lib下 检查 JMeter 的 Classpath 在 JMeter 中&#xff0c;JDBC 驱动需要手动添加到 Classpath 中。 打开 JMeter 安装目录下的 bin/jmeter.properties 文件&#xff0c;找到 user.cla…...

隐私计算的崛起:数据安全的未来守护者

在信息技术&#xff08;IT&#xff09;的滚滚浪潮中&#xff0c;一种新兴技术正以惊人速度崭露头角——隐私计算&#xff08;Privacy-Preserving Computation&#xff09;。2025 年&#xff0c;随着数据泄露事件频发、全球隐私法规日益严格&#xff0c;以及企业对数据协作需求的…...

Excel计数、求和、统计、计算类函数

目录 一、计数函数1. COUNT2. COUNTA3. COUNTBLANK4. COUNTIF5. COUNTIFS 二、求和函数1. SUM2. SUMIF3. SUMIFS4. SUMPRODUCT 三、统计函数1. AVERAGE2. AVERAGEA3. AVERAGEIF 函数4. AVERAGEIFS 函数 四、其他常用计算函数1. MAX 与 MIN2. RANK3. MOD4. ROUND5. FLOOR6. INT7…...

解决 Kubernetes 中容器 `CrashLoopBackOff` 问题的实战经验

在 Kubernetes 集群中&#xff0c;容器状态为 CrashLoopBackOff 通常意味着容器启动失败&#xff0c;并且 Kubernetes 正在不断尝试重启它。这种状态表明容器内可能存在严重错误&#xff0c;如应用异常、依赖服务不可用、配置错误等。本文将分享一次实际排障过程&#xff0c;并…...

北师大具身AI的虚拟世界扩展!UNREALZOO:为具身智能打造高逼真度的虚拟世界

作者&#xff1a;Fangwei Zhong, Kui Wu, Churan Wang, Hao Chen, Hai Ci, Zhoujun Li, Yizhou Wang 单位&#xff1a;北京师范大学&#xff0c;北京航空航天大学&#xff0c;北京大学&#xff0c;BIGAI&#xff0c;澳门城市大学&#xff0c;新加坡国立大学 论文标题&#xf…...

2025 年浙江保安员职业资格考试高效备考指南​

浙江以创新活力著称&#xff0c;保安行业也在不断革新。2025 年考试报考条件常规&#xff0c;报名主要通过浙江省保安服务监管信息系统&#xff0c;方便快捷。​ 理论考试在传统知识基础上&#xff0c;加大对智能安防技术应用的考查&#xff0c;如人脸识别系统、智能监控报警系…...

创意设计:动态彩色数学爱心

设计理念 数学之美&#xff1a;使用心形线的数学方程&#xff08;心形曲线&#xff09;生成爱心形状。视觉吸引力&#xff1a;通过 Python 的 colorama 库添加颜色渐变效果。动态感&#xff1a;加入简单的动画&#xff0c;让爱心“跳动”。技术魅力&#xff1a;结合模块化编程…...

C++动态内存管理完全指南:从基础到现代最佳实践

一、动态内存基础原理 1.1 内存分配层次结构 内存类型生命周期分配方式典型使用场景静态存储区程序整个运行期编译器分配全局变量、静态变量栈内存函数作用域自动分配/释放局部变量堆内存手动控制new/malloc分配动态数据结构 1.2 基本内存操作函数 // C风格 void* malloc(s…...

ebpf: CO-RE, BTF, and Libbpf(一)

本文内容主要来源于Learning eBPF&#xff0c;可阅读原文了解更全面的内容。 概述 一个ebpf程序可以在一个kernel版本中编译&#xff0c;而在另外一个kernel版本上运行&#xff0c;即便两个kernel版本中有些结构体有变化。而BTF(BPF Type Format) 是能让ebpf有这种强大兼容性…...

Linux 递归查找并删除目录下的文件

在 Linux 中&#xff0c;可以使用 find 命令递归查找并删除目录下的文件 1、示例命令 find /path/to/directory -type f -name "filename_pattern" -exec rm -f {} 2、参数说明 /path/to/directory&#xff1a;要查找的目标目录type f&#xff1a;表示查找文件&am…...