山东省建设工程招投标网站/培训机构

山东省建设工程招投标网站,培训机构,dede做的网站怎样去换模版,fancy wordpress文章目录 4. string类的模拟实现4.1 构造 析构4.2 c_str4.3 下标遍历4.4 迭代器4.5 插入4.6 删除4.7 查找4.8 赋值4.9 交换4.10 提取子串4.11 比较大小4.12 流插入 && 流提取 5. 现代版写法的String类5.1 完整代码 6. 写时拷贝(了解) 4. string…

文章目录

    • 4. string类的模拟实现
      • 4.1 构造 + 析构
      • 4.2 c_str
      • 4.3 下标遍历
      • 4.4 迭代器
      • 4.5 插入
      • 4.6 删除
      • 4.7 查找
      • 4.8 赋值
      • 4.9 交换
      • 4.10 提取子串
      • 4.11 比较大小
      • 4.12 流插入 && 流提取
    • 5. 现代版写法的String类
      • 5.1 完整代码
    • 6. 写时拷贝(了解)

4. string类的模拟实现

首先,我们先补充一下关于编码的知识:

int main()
{char buff1[] = "abcd";char buff2[] = "比特";cout << sizeof(buff1) << endl;cout << sizeof(buff2) << endl;cout << buff1 << endl;cout << buff2 << endl;return 0;
}

编码
不同的string


如果严格按照标准的话,我们应该要实现成 basic_string ,但是这样难度太大,要考虑各种编码的拷贝,所以我们就实现的稍微简单一些,不要实现成模板了。

4.1 构造 + 析构

//string::string()
//{
//	_str = new char[1]{ '\0' };
//	_size = 0;
//	_capacity = 0;
//}string::string(const char* str):_size(strlen(str))
{_str = new char[_size + 1];_capacity = _size;strcpy(_str, str);
}//s2(s1)
string::string(const string& s)
{_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;
}string::~string()
{delete[] _str;_str = nullptr;_size = _capacity = 0;
}

4.2 c_str

const char* string::c_str() const
{return _str;
}

4.3 下标遍历

size_t string::size() const
{return _size;
}char& string::operator[](size_t pos)
{assert(pos < _size);return _str[pos];
}
const char& string::operator[](size_t pos) const
{assert(pos < _size);return _str[pos];
}

4.4 迭代器

string::iterator string::begin()
{return _str;
}string::iterator string::end()
{return _str + _size;
}

iterator封装的意义

string::const_iterator string::begin() const
{return _str;
}string::const_iterator string::end() const
{return _str + _size;
}

4.5 插入

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){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;
}//"hello"  "xxxxxxxxxxxxx"
void string::append(const char* str)
{size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}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;
}

插入示意图(1)

void string::insert(size_t pos, char ch)
{assert(pos <= _size);if (_size == _capacity){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}/*int end = _size;while (end >= (int)pos){_str[end + 1] = _str[end];--end;}*/size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];--end;}_str[pos] = ch;++_size;
}

插入示意图(2)

void string::insert(size_t pos, const char* str)
{assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}/*int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}*/size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];--end;}memcpy(_str + pos, str, len);_size += len;
}

4.6 删除

删除示意图

const size_t string::npos = -1;void string::erase(size_t pos, size_t len)
{assert(pos < _size);//len 大于等于后面字符个数时,有多少删多少if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}
}

4.7 查找

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)
{char* p = strstr(_str + pos, str);return p - _str;
}

4.8 赋值

赋值示意图

//s1 = s3
//s1 = s1
string& string::operator=(const string& s)
{if (this != &s){char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;
}

4.9 交换

交换示意图

//s1.swap(s3)
void string::swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}

4.10 提取子串

提取子串示意图

string string::substr(size_t pos, size_t len)
{//len大于后面剩余字符,有多少取多少if (len > _size - pos){string sub(_str + pos);return sub;}else{string sub;sub.reserve(len);for (size_t i = 0; i < len; i++){sub += _str[pos + i];}return sub;}
}

4.11 比较大小

bool string::operator<(const string& s) const
{return strcmp(_str, s._str) < 0;
}bool string::operator>(const string& s) const
{return !(*this <= s);
}bool string::operator<=(const string& s) const
{return *this < s || *this == s;
}bool string::operator>=(const string& s) const
{return !(*this < s);
}bool string::operator==(const string& s) const
{return strcmp(_str, s._str) == 0;
}bool string::operator!=(const string& s) const
{return !(*this == s);
}

4.12 流插入 && 流提取

void string::clear()
{_str[0] = '\0';_size = 0;
}//一个字符一个字符放入str里,会有很多次扩容,可以优化
//istream& operator>> (istream& is, string& str)
//{
//	str.clear();//	//流提取(>>)提取不了空格和换行,istream里的函数get()可以
//	char ch = is.get();
//	while (ch != ' ' && ch != '\n')
//	{
//		str += ch;
//		ch = is.get();
//	}//	return is;
//}istream& operator>> (istream& is, string& str)
{str.clear();char buff[128];int i = 0;char ch = is.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch;// 0 - 126if (i == 127){buff[i] = '\0';str += buff;i = 0;}ch = is.get();}if (i != 0){buff[i] = '\0';str += buff;}return is;
}ostream& operator<< (ostream& os, const string& str)
{for (size_t i = 0; i < str.size(); i++){os << str[i];}return os;
}

5. 现代版写法的String类

我们之前写的拷贝构造和赋值运算符重载是传统写法,其实还有现代写法:
拷贝构造现代写法

//现代写法(让别人干活,交换)
//s2(s1)
string::string(const string& s)
{string tmp(s._str);/*std::swap(tmp._str, _str);std::swap(tmp._size, _size);std::swap(tmp._capacity, _capacity);*///这个是我们写的string类里的交换函数swap(tmp);
}

赋值运算符重载的现代写法

/*string& string::operator=(const string& s)
{if (this != &s){string tmp(s._str);swap(tmp);}return *this;
}*///s1 = s3
string& string::operator=(string tmp)
{swap(tmp);return *this;
}

5.1 完整代码

//string.h#include <iostream>
#include <assert.h>
using namespace std;namespace bit
{class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin();iterator end();const_iterator begin() const;const_iterator end() const;//string();string(const char* str = "");string(const string& s);//string& operator=(const string& s);string& operator=(string tmp);~string();const char* c_str() const;size_t size() const;char& operator[](size_t pos);const char& operator[](size_t pos) const;void reserve(size_t n);void push_back(char ch);void append(const char* str);string& operator+=(char ch);string& operator+=(const char* str);void insert(size_t pos, char ch);void insert(size_t pos, const char* str);void erase(size_t pos = 0, size_t len = npos);size_t find(char ch, size_t pos = 0);size_t find(const char* str, size_t pos =  0);void swap(string& s);string substr(size_t pos = 0, size_t len = npos);bool operator<(const string& s) const;bool operator>(const string& s) const;bool operator<=(const string& s) const;bool operator>=(const string& s) const;bool operator==(const string& s) const;bool operator!=(const string& s) const;void clear();private://char _buff[16];char* _str = nullptr;size_t _size = 0;size_t _capacity = 0;const static size_t npos;//特例,const静态成员变量只有整型可以这样声明定义(了解即可,不建议这样写)//const static size_t npos = -1;//不支持//const static double N = 2.2;};istream& operator>> (istream& is, string& str);ostream& operator<< (ostream& os, const string& str);
}
//string.cpp#include "string.h"namespace bit
{const size_t string::npos = -1;//string::string()//{//	_str = new char[1]{ '\0' };//	_size = 0;//	_capacity = 0;//}string::iterator string::begin(){return _str;}string::iterator string::end(){return _str + _size;}string::const_iterator string::begin() const{return _str;}string::const_iterator string::end() const{return _str + _size;}string::string(const char* str):_size(strlen(str)){_str = new char[_size + 1];_capacity = _size;strcpy(_str, str);}//传统写法(实在人)//s2(s1)/*string::string(const string& s){_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;}*///现代写法(让别人干活,交换)//s2(s1)string::string(const string& s){string tmp(s._str);/*std::swap(tmp._str, _str);std::swap(tmp._size, _size);std::swap(tmp._capacity, _capacity);*///这个是我们写的string类里的交换函数swap(tmp);}//s1 = s3//s1 = s1/*string& string::operator=(const string& s){if (this != &s){char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;}*//*string& string::operator=(const string& s){if (this != &s){string tmp(s._str);swap(tmp);}return *this;}*///s1 = s3string& string::operator=(string tmp){swap(tmp);return *this;}string::~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}const char* string::c_str() const{return _str;}size_t string::size() const{return _size;}char& string::operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& string::operator[](size_t pos) const{assert(pos < _size);return _str[pos];}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){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;*/insert(_size, ch);}//"hello"  "xxxxxxxxxxxxx"void string::append(const char* str){/*size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;*/insert(_size, str);}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){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}/*int end = _size;while (end >= (int)pos){_str[end + 1] = _str[end];--end;}*/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 (_size + len > _capacity){reserve(_size + len);}/*int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}*/size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];--end;}memcpy(_str + pos, str, len);_size += len;}void string::erase(size_t pos, size_t len){assert(pos < _size);//len 大于等于后面字符个数时,有多少删多少if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_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){char* p = strstr(_str + pos, str);return p - _str;}//s1.swap(s3)void string::swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}string string::substr(size_t pos, size_t len){//len大于后面剩余字符,有多少取多少if (len > _size - pos){string sub(_str + pos);return sub;}else{string sub;sub.reserve(len);for (size_t i = 0; i < len; i++){sub += _str[pos + i];}return sub;}}bool string::operator<(const string& s) const{return strcmp(_str, s._str) < 0;}bool string::operator>(const string& s) const{return !(*this <= s);}bool string::operator<=(const string& s) const{return *this < s || *this == s;}bool string::operator>=(const string& s) const{return !(*this < s);}bool string::operator==(const string& s) const{return strcmp(_str, s._str) == 0;}bool string::operator!=(const string& s) const{return !(*this == s);}void string::clear(){_str[0] = '\0';_size = 0;}//一个字符一个字符放入str里,会有很多次扩容,可以优化//istream& operator>> (istream& is, string& str)//{//	str.clear();//	//流提取(>>)提取不了空格和换行,istream里的函数get()可以//	char ch = is.get();//	while (ch != ' ' && ch != '\n')//	{//		str += ch;//		ch = is.get();//	}//	return is;//}istream& operator>> (istream& is, string& str){str.clear();char buff[128];int i = 0;char ch = is.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch;// 0 - 126if (i == 127){buff[i] = '\0';str += buff;i = 0;}ch = is.get();}if (i != 0){buff[i] = '\0';str += buff;}return is;}ostream& operator<< (ostream& os, const string& str){for (size_t i = 0; i < str.size(); i++){os << str[i];}return os;}
}
//Test.cpp#include "string.h"namespace bit
{void test_string1(){string s1("hello world");cout << s1.c_str() << endl;for (size_t i = 0; i < s1.size(); i++){s1[i]++;}for (size_t i = 0; i < s1.size(); i++){cout << s1[i] << " ";}cout << endl;//封装:统一屏蔽了底层实现细节,提供了一种简单通用的访问容器的方式string::iterator it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";++it1;}cout << endl;for (auto e : s1){cout << e << " ";}cout << endl;string s2;cout << s2.c_str() << endl;const string s3("xxxxxxx");string::const_iterator it3 = s3.begin();while (it3 != s3.end()){//*it3 = 'y';//errcout << *it3 << " ";++it3;}cout << endl;for (size_t i = 0; i < s3.size(); i++){//s3[i]++;cout << s3[i] << " ";}cout << endl;}void test_string2(){string s1("hello world");cout << s1.c_str() << endl;s1.push_back('x');cout << s1.c_str() << endl;s1.append("yyyyy");cout << s1.c_str() << endl;s1 += 'z';s1 += "mmmmmm";cout << s1.c_str() << endl;}void test_string3(){string s1("hello world");cout << s1.c_str() << endl;s1.insert(6, 'x');cout << s1.c_str() << endl;s1.insert(0, 'x');cout << s1.c_str() << endl;string s2("hello world");cout << s2.c_str() << endl;s2.insert(6, "yyy");cout << s2.c_str() << endl;s2.insert(0, "yyy");cout << s2.c_str() << endl;string s3("hello world");cout << s3.c_str() << endl;//s3.erase(6, 10);s3.erase(6);cout << s3.c_str() << endl;string s4("hello world");cout << s4.c_str() << endl;s4.erase(6, 3);cout << s4.c_str() << endl;}void test_string4(){string s1("hello world");cout << s1.find('o') << endl;cout << s1.find("wor") << endl;}void test_string5(){string s1("hello world");string s2(s1);s1[0] = 'x';cout << s1.c_str() << endl;cout << s2.c_str() << endl;string s3("yyyy");s1 = s3;cout << s1.c_str() << endl;cout << s3.c_str() << endl;string s4("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");s1 = s4;cout << s1.c_str() << endl;cout << s4.c_str() << endl;s1 = s1;cout << s1.c_str() << endl;cout << s3.c_str() << endl;std::swap(s1, s3);cout << s1.c_str() << endl;cout << s3.c_str() << endl;s1.swap(s3);cout << s1.c_str() << endl;cout << s3.c_str() << endl;}void test_string6(){string url("https://gitee.com/ailiangshilove/cpp-class/blob/master/%E8%AF%BE%E4%BB%B6%E4%BB%A3%E7%A0%81/C++%E8%AF%BE%E4%BB%B6V6/string%E7%9A%84%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95%E5%8F%8A%E4%BD%BF%E7%94%A8/TestString.cpp");size_t pos1 = url.find(':');string url1 = url.substr(0, pos1 - 0);cout << url1.c_str() << endl;size_t pos2 = url.find('/', pos1 + 3);string url2 = url.substr(pos1 + 3, pos2 - (pos1 + 3));cout << url2.c_str() << endl;string url3 = url.substr(pos2 + 1);cout << url3.c_str() << endl;}void test_string7(){//string s1("hello world");//cout << s1 << endl;string s1;cin >> s1;cout << s1 << endl;}void test_string8(){string s1("hello world");string s2(s1);cout << s1 << endl;cout << s2 << endl;string s3("xxxxxxxxxxxxxxxxxxxxxxxxx");s1 = s3;cout << s1 << endl;cout << s3 << endl;}
}int main()
{bit::test_string8();return 0;
}

6. 写时拷贝(了解)

写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。

引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象时资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有其他对象在使用该资源。
写时拷贝
举个例子:

void copy_on_write()
{//如果计数不等于1,再去做深拷贝
}void string::push_back(char ch)
{//写时拷贝copy_on_write();/*if (_size == _capacity){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;*/insert(_size, ch);
}

可以用下面的代码来看是否是用了写时拷贝:

void test_string9()
{std::string s1("hello world");std::string s2(s1);cout << (void*)s1.c_str() << endl;cout << (void*)s2.c_str() << endl;
}

Windows的VS下没有用写时拷贝,而Linux的g++就使用了写时拷贝。

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

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

相关文章

win11本地部署deepseek大模型(安装ollama+docker+open-webui)最终实现自己的项目可通过API调用投喂数据后的模型

硬件配置&#xff1a;笔记本win11&#xff0c;内存32G&#xff0c;CPU锐龙7 &#xff0c;无独显&#xff1b;只能考虑deepseek-r1:1.5b模型。 第一步&#xff1a;安装Ollama 此处不过多累赘了&#xff0c;https://ollama.com/官网选择对应的系统版本下载即可。 需要注意的是…

WebSocket简单介绍 并接入deepseek

目录 什么是 WebSocket&#xff1f;工作原理&#xff1a; 为什么需要 WebSocket&#xff1f;WebSocket 的优势HTTP 和 WebSocket 的区别WebSocket 的劣势WebSocket 的应用场景WebSocket 握手过程1. 客户端发起握手请求2. 服务器响应握手请求3. 建立连接 WebSocket 事件处理WebS…

order by布尔盲注、时间盲注

pdo防御下&#xff0c;order by、limit不能参数绑定&#xff0c;可以进行sql注入 案例&#xff1a;靶场的less-46 布尔盲注&#xff1a; import requests from lxml import htmldef get_id_one(URL, paload):res requests.get(urlURL, paramspaload)tree html.fromstring(…

Visual Studio Code 跨平台安装与配置指南(附官方下载链接)

一、软件定位与核心功能 Visual Studio Code&#xff08;简称VS Code&#xff09;是微软开发的开源跨平台代码编辑器&#xff0c;支持超过50种编程语言的智能补全、调试和版本控制功能。2025版本新增AI辅助编程模块&#xff0c;可自动生成单元测试代码和API文档注释。 二、下载…

解决IDEA使用Ctrl + / 注释不规范问题

问题描述&#xff1a; ctrl/ 时&#xff0c;注释缩进和代码规范不一致问题 解决方式 设置->编辑器->代码样式->java->代码生成->注释代码

项目实践 之 pdf简历的解析和填充(若依+vue3)

文章目录 环境背景最终效果前端讲解左侧模块解析右侧上传模块解析前端步骤 后端讲解代码前端 环境背景 若依前后端分离框架 vue最后边附有代码哦 最终效果 前端讲解 左侧模块解析 1、左侧表单使用el-form 注意&#xff1a; 1、prop出现的字段&#xff0c;需要保证是该类所…

如何看待 Kaiming He 最新提出的 Fractal Generative Models ?

何恺明团队提出的分形生成模型(Fractal Generative Models) 引发了广泛关注,其核心思想是通过递归调用生成模型模块构建自相似结构,类似数学中的分形概念(如雪花结构),从而高效生成高分辨率数据(如图像)。 Fractal Generative Models即分形生成模型,是一种新型的生成…

Debian系统终端输入ifconfig报错

报错 bash: ifconfig: command not found 原因 Debian 上默认不安装 ifconfig 软件包。这是因为 ifconfig 已被弃用&#xff0c;取而代之的是新的 ip 命令。该 ip 命令现在负责修改或显示路由、网络设备、接口和隧道 如果仍然想使用旧的 ifconfig 命令&#xff0c;则必须显式…

【NLP 27、文本分类任务 —— 传统机器学习算法】

不要抓着枯叶哭泣&#xff0c;你要等待初春的新芽 —— 25.1.23 一、文本分类任务 定义&#xff1a;预先设定好一个文本类别集合&#xff0c;对于一篇文本&#xff0c;预测其所属的类别 例如&#xff1a; 情感分析&#xff1a; 这家饭店太难吃了 —> 正类 …

Lumoz Chain正式上线:AI 时代的新算力破局者

新的叙事和技术突破永远是推动行业前行的核心动力。当下&#xff0c;AI Agent无疑是最炙手可热的赛道之一。 当加密世界将目光投向AI领域时&#xff0c;大多数项目仍停留在以AI为工具或应用场景的层面&#xff0c;试图通过集成AI模型或优化链上功能来吸引用户。然而&#xff0c…

Python - Python连接数据库

Python的标准数据库接口为&#xff1a;Python DB-API&#xff0c;Python DB-API为开发人员提供了数据库应用编程接口。 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个实现库&#xff0c;Python2中则使用mysqldb。 PyMySQL 遵循 Python 数据库 API v2.0 规范&…

面试八股文--数据库基础知识总结(1)

1、数据库的定义 数据库&#xff08;DataBase&#xff0c;DB&#xff09;简单来说就是数据的集合数据库管理系统&#xff08;Database Management System&#xff0c;DBMS&#xff09;是一种操纵和管理数据库的大型软件&#xff0c;通常用于建立、使用和维护数据库。数据库系统…

关于在java项目部署过程MySQL拒绝连接的分析和解决方法

前言 在最近一次部署项目一次项目部署过程中&#xff0c;由于没有对MySQL数据库的部分权限和远程连接进行授权&#xff0c;导致了在执行项目功能API时&#xff0c;出现MySQL连接异常或MySQL拒绝连接的问题。 问题 以下是部分报错截图&#xff1a; 分析 根据日志提示&#xf…

PhotoLine绿色版 v25.00:全能型图像处理软件的深度解析

在图像处理领域,PhotoLine以其强大的功能和紧凑的体积,赢得了国内外众多用户的喜爱。本文将为大家全面解析PhotoLine绿色版 v25.00的各项功能,帮助大家更好地了解这款全能型的图像处理软件。 一、迷你体积,强大功能 PhotoLine被誉为迷你版的Photoshop,其体积虽小,但功能却…

002 Java操作kafka客户端

Java操作kafka客户端 文章目录 Java操作kafka客户端3.Java操作kafka客户端1.引入依赖2. Kafka服务配置3、生产者&#xff08;Producer&#xff09;实现1. 基础配置与发送消息2. 关键配置说明 4.消费者&#xff08;Consumer&#xff09;实现1. 基础配置与消费消息2. 关键配置说明…

【SRC实战】信息泄露导致越权会员功能

01 — 漏洞证明 1、VIP功能 2、SVIP功能 3、点击任意用户发起私聊&#xff0c;发现userId纯数字可遍历 4、返回包泄露身高范围height&#xff0c;星座constellation&#xff0c;属相zodiac&#xff0c;恋爱目标purpose&#xff0c;教育程度degree&#xff0c;成功越权VIP功能 …

游戏引擎学习第125天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾并为今天的内容做准备。 昨天&#xff0c;当我们离开时&#xff0c;工作队列已经完成了基本的功能。这个队列虽然简单&#xff0c;但它能够执行任务&#xff0c;并且我们已经为各种操作编写了测试。字符串也能够正常推送到队…

《OpenCV》——光流估计

什么是光流估计&#xff1f; 光流估计的前提&#xff1f; 基本假设 亮度恒定假设&#xff1a;目标像素点的亮度在相邻帧之间保持不变。这是光流计算的基础假设&#xff0c;基于此可以建立数学方程来求解光流。时间连续或运动平滑假设&#xff1a;相邻帧之间的时间间隔足够小&a…

信息系统的安全防护

文章目录 引言**1. 物理安全****2. 网络安全****3. 数据安全****4. 身份认证与访问控制****5. 应用安全****6. 日志与监控****7. 人员与管理制度****8. 其他安全措施****9. 安全防护框架**引言 从技术、管理和人员三个方面综合考虑,构建多层次、多维度的安全防护体系。 信息…