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

【C++游记】string的使用和模拟实现

 

枫の个人主页

你不能改变过去,但你可以改变未来

算法/C++/数据结构/C

Hello,这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕,我们继续来学习C++的内容呀。C++是接近底层有比较经典的语言,因此学习起来注定枯燥无味,西游记大家都看过吧~,我希望能带着大家一起跨过九九八十一难,降伏各类难题,学会C++,我会尽我所能,以通俗易懂、幽默风趣的方式带给大家形象生动的知识,也希望大家遇到困难不退缩,遇到难题不放弃,学习师徒四人的精神!!!故此得名【C++游记】

 话不多说,让我们一起进入今天的学习吧~~~ 

目录

1>>标准库的String

1.1>>auto和范围for小知识

1.2>>string常用接口(组件)这里都可以查找到

容量接口

访问和遍历

 string类对象的修改操作

非成员函数但会用到 

2>>string的模拟实现

 3>>Boos战——string重要接口的模拟实现

1.String.h

2.String.cpp 

3.wctest.cpp

4>>结语


1>>标准库的String

1.1>>auto和范围for小知识

师傅别怕,赠与“武器”一把 i

auto基本知识:

它声明引用类型时,必须在auto后加上&。

声明多个变量时,这些变量必须是相同的类型。

auto不能作为函数参数,可以作为返回值。

不能用于声明数组。

#include<iostream>
using namespace std;
int main() {auto a = 10;auto b = 'b';auto c = "asdofih";auto d = 11.11;auto& e = a;cout << a << endl;cout << b << endl;cout << c << endl;cout << d << endl;cout << e << endl;printf("%p %p", &a, &e);return 0;
}

范围for:

        对比C语言的for循环,C++使用更好用的范围for代替, 格式为:“for(auto  范围内用于迭代的变量 : 被迭代的范围)”,自动迭代、取数据、结束,这就是自动范围for。

#include<iostream>
using namespace std;
int main() {int arr[] = { 1,2,3,4,5 };for (auto& e : arr) {//若要更改里面的数值,那么就要用引用才能修改到数组本身e += 2;}for (auto e : arr) {cout << e << " ";}cout << endl;string str("hello world");for (auto ch : str) {cout << ch << " ";}cout << endl;return 0;
}

1.2>>string常用接口(组件)这里都可以查找到

师傅后面都会介绍,不必担心

String函数名称功能说明
string()构造空的string类对象,即空字符串
string(const char* s)用C-string(常量字符串)来构造string类对象
string(size_t n,char c)

string类对象中包含n个字符c

string(const string&s)

拷贝构造函数
void Test1() {string s1;//构造空的string类对象string s2("hello feng");//用常量字符串构造string类对象string s3(s2);//用s2拷贝构造s3
}

容量接口

若定义为string s,以下表size为例,就是s.size();

size返回字符串有效字符长度,使用范围比length广
length返回字符串有效字符长度
capacity返回总空间大小
empty检测字符串释放为空串,空返回true,非空返回false
clear清空有效字符
reserve为字符串预留空间
resize将有效字符个数设置为n个,多余用c填充

补充说明:size和length的区别只有在引入迭代器才能体现出来,一般都用size,length有使用限制。

clear只清空,不改大小

resize(size_t n,char c)用变量c的字符填充多余空间,resize(size_t)则是用0来填充。

reserve预留空间,小于string的空间大小时不作改动。

访问和遍历

函数名称功能说明
operator[]返回pos位置的字符,const string类对象调用
begin+endbegin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器
rbegin+rendrbegin获取最后一个字符的迭代器+rend获取一个字符的迭代器
范围forC++11的遍历方式

 string类对象的修改操作

函数名称

功能说明

push_back在字符串后尾插字符c(单个)
append在字符串后追加一个字符串(多个)
operator+=在字符串后追加一个字符串(多个)
c_str返回C格式字符串
find+npos从字符串pos位置往后查找字符c,返回它的位置
rfind从字符串pos位置往前查找字符c,返回它的位置
substr在str中从pos位置开始,截取n个字符,将其返回

非成员函数但会用到 

函数       功能说明       
operator+深拷贝,效率低
operator>>输入运算符重载
operator<<输出运算符重载
getline获取一行字符串
relational operators大小比较

2>>string的模拟实现

错误示范:

#include<iostream>
#include<assert.h>
using namespace std;
class MyString {
public:MyString(const char* str = "") {if (str == nullptr) {perror("flase");return;}_str = new char[strlen(str) + 1];//加1放\0strcpy(_str, str);}~MyString() {if (_str) {delete[] _str;_str = nullptr;}}
private:char* _str;
};
void Test2() {string s1("hello feng");string s2(s1);
}int main() {/*Test1();*/Test2();return 0;
}

上述过程会报错,因为没有写拷贝构造,s2会调用s1的默认构造,而在类和对象章节中我们知道默认构造都是浅拷贝,这里是一个字符数组,因此要调用深拷贝。

#include<iostream>
#include<assert.h>
using namespace std;
class MyString {
public:MyString(const char* str = "") {//构造if (str == nullptr) {perror("flase");return;}_str = new char[strlen(str) + 1];//加1放\0strcpy(_str, str);}MyString(const MyString& s)//拷贝构造:_str(nullptr){MyString tmp(s._str);swap(tmp._str, _str);}~MyString() {//析构if (_str) {delete[] _str;_str = nullptr;}}
private:char* _str;
};
void Test2() {string s1("hello feng");string s2(s1);
}int main() {/*Test1();*/Test2();return 0;
}

 3>>Boos战——string重要接口的模拟实现

这里直接附上上个文件源码,大部分已经注释完毕,请大家伙享用,感兴趣可以复制过去测试,不过还是自己敲一遍比较好。

1.String.h

#pragma once#include<iostream>
#include<assert.h>
#include<string.h>
using namespace std;namespace wc
{class string{public:typedef char* iterator;//手动自造迭代器,名字与库中相同,但在wc的命名空间里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;}void swap(string& s);//交换,直接套用标准库里的swapstring(size_t n, char ch);//设置相同字符多少个为一个字符串string(const char* str = "");//构造函数string(const string& s);//拷贝构造函数~string();//析构函数void clear()//清除{_str[0] = '\0';_size = 0;}string& operator=(string s);//string& operator=(const string& s);const char* c_str() const//常数直接返回自己地址,比较快因此调用内联{return _str;}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, size_t n, char ch);//在pos位置插入n个ch字符void insert(size_t pos, const char* str);//在pos位置插入一个字符串void erase(size_t pos = 0, size_t len = npos);//在pos位置删除len个字符size_t find(char ch, size_t pos = 0);size_t find(const char* str, size_t pos = 0);size_t size() const{return _size;}size_t capacity() const{return _size;}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}string substr(size_t pos, size_t len = npos);//从pos位置开始取len个作为子串返回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;private:char* _str = nullptr;//定义字符串数组_strsize_t _size = 0;//有效个数size_t _capacity = 0;//总容量const static size_t npos;//设置默认结束值};// cout<<s1ostream& operator<<(ostream& out, const string& s);// cin>>s1istream& operator>>(istream& in, string& s);istream& getline(istream& is, string& s, char delim = '\n');void test_string1();void test_string2();void test_string3();void test_string4();void test_string5();void test_string6();void test_string7();
}

2.String.cpp 

//#include<iostream>
//using namespace std;
//int main() {
//	auto a = 10;
//	auto b = 'b';
//	auto c = "asdofih";
//	auto d = 11.11;
//	auto& e = a;
//	cout << a << endl;
//	cout << b << endl;
//	cout << c << endl;
//	cout << d << endl;
//	cout << e << endl;
//	printf("%p %p", &a, &e);
//	return 0;
//}
//#include<iostream>
//using namespace std;
//int main() {
//	int arr[] = { 1,2,3,4,5 };
//	for (auto& e : arr) {//若要更改里面的数值,那么就要用引用才能修改到数组本身
//		e += 2;
//	}
//	for (auto e : arr) {
//		cout << e << " ";
//	}
//	cout << endl;
//	string str("hello world");
//	for (auto ch : str) {
//		cout << ch << " ";
//	}
//	cout << endl;
//	return 0;
//}//void Test1() {
//	string s1;//构造空的string类对象
//	string s2("hello feng");//用常量字符串构造string类对象
//	string s3(s2);//用s2拷贝构造s3
//}
//#include<iostream>
//#include<assert.h>
//using namespace std;
//class MyString {
//public:
//	MyString(const char* str = "") {//构造
//		if (str == nullptr) {
//			perror("flase");
//			return;
//		}
//		_str = new char[strlen(str) + 1];//加1放\0
//		strcpy(_str, str);
//	}
//	MyString(const MyString& s)//拷贝构造
//		:_str(nullptr)
//	{
//		MyString tmp(s._str);
//		swap(tmp._str, _str);
//	}
//	~MyString() {//析构
//		if (_str) {
//			delete[] _str;
//			_str = nullptr;
//		}
//	}
//private:
//	char* _str;
//};
//void Test2() {
//	string s1("hello feng");
//	string s2(s1);
//}
//
//int main() {
//	/*Test1();*/
//	Test2();
//	return 0;
//}#define _CRT_SECURE_NO_WARNINGS 1
#include"string.h"namespace wc
{const size_t string::npos = -1;void string::swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}string::string(size_t n, char ch):_str(new char[n + 1]), _size(n),_capacity(n){for (size_t i = 0; i < n; i++) {_str[i] = ch;}_str[_size] = '\0';}string::string(const char* str)//声明中写过默认值,这里就不能再写了 :_size(strlen(str)){_capacity = _size;_str = new char[_size + 1];strcpy(_str, str);//复制还没复制\0_str[_size] = '\0';}string::string(const string& s){string tmp(s._str);swap(tmp);}string::~string(){delete[] _str;_str = nullptr;_size = 0;_capacity = 0;}string& string::operator=(string s) {swap(s);return *this;}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 + 1 > _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);}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, size_t n, char ch){assert(pos <= _size);assert(n > 0);if (_size + n > _capacity){// 扩容size_t newCapacity = 2 * _capacity;if (_size + n > 2 * _capacity){newCapacity = _size + n;}reserve(newCapacity);}size_t end = _size + n;while (end > pos + n - 1) {_str[end] = _str[end - n];end--;}for (size_t i = 0; i < n; i++) {_str[pos + i] = ch;}_size += n;}void string::insert(size_t pos, const char* str){size_t n = strlen(str);insert(pos, n, 'x');//覆盖一下for (size_t i = 0; i < n; i++){_str[pos + i] = str[i];}}void string::erase(size_t pos, size_t len) {if (len > _size - pos) {//多删了_str[pos] = '\0';_size = pos;}else {size_t end = pos + len;while (end <= _size) {//\0也拷贝_str[end - len] = _str[end];end++;}_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){const char* p = strstr(_str + pos, str);if (p == nullptr){return npos;}else{return p - _str;}}string string::substr(size_t pos, size_t len){if (len > _size - pos)//若超出,就等于剩下长度len = _size - pos;string tmp;tmp.reserve(len);for (size_t i = 0; i < len; i++) {tmp += _str[pos + i];//直接加等,简单易懂}return tmp;}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 strcmp(_str, s._str) < 0;}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 !(*this < s);}ostream& operator<<(ostream& out, const string& s){for (size_t i=0;i<s.size();i++){out << s[i];}return out;}istream& operator>>(istream& in, string& s){s.clear();// 输入短串,不会浪费空间// 输入长串,避免不断扩容const size_t N = 1024;char buff[N];int i = 0;char ch = in.get();while (ch != ' ' && ch != '\n')//遇到空格和\n停止{buff[i++] = ch;if (i == N - 1){buff[i] = '\0';//最后一个复制为0然后加上s += buff;i = 0;}//也可以直接写s+=ch,不过占用内存高ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}return in;}istream& getline(istream& in, string& s, char delim){s.clear();const size_t N = 1024;char buff[N];int i = 0;char ch = in.get();while (ch != delim){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;}void test_string1(){string s1("hello world");cout << s1.c_str() << endl;string s2;cout << s2.c_str() << endl;s1 += ' ';s1 += '+';s1 += "hello ";s1 += "hello feng1111111111111111111111111";cout << s1.c_str() << endl;}void test_string2(){string s1("hello world");cout << s1.c_str() << endl;s1.insert(11, 3, 'x');cout << s1.c_str() << endl;s1.insert(6, 3, 'x');cout << s1.c_str() << endl;s1.insert(0, 3, 'x');cout << s1.c_str() << endl;string s2("hello world");cout << s2.c_str() << endl;s2.insert(11, "yyy");cout << s2.c_str() << endl;s2.insert(6, "yyy");cout << s2.c_str() << endl;s2.insert(0, "yyy");cout << s2.c_str() << endl;}void test_string3(){string s1("hello world");cout << s1.c_str() << endl;s1.erase(6, 2);cout << s1.c_str() << endl;s1.erase(6, 20);cout << s1.c_str() << endl;s1.erase(3);cout << s1.c_str() << endl;string s2("hello helleoo");cout << s2.find('e') << endl;cout << s2.find("helle") << endl;}void test_string4(){string s1("hello world");for (size_t i = 0; i < s1.size(); i++){s1[i]++;cout << s1[i] << " ";}cout << endl;string::iterator it = s1.begin();while (it != s1.end()){cout << *it << " ";++it;}cout << endl;for (auto e : s1){cout << e << " ";}cout << endl;const string s2("hello world");for (auto e : s2){cout << e << " ";}cout << endl;}void test_string5(){string s1("hello world");string sub1 = s1.substr(6, 3);cout << sub1.c_str() << endl;string sub2 = s1.substr(6, 300);cout << sub2.c_str() << endl;string sub3 = s1.substr(6);cout << sub3.c_str() << endl;string s2("hello fengxxxxxxxxxxxxxxxxxx");s1 = s2;cout << s1.c_str() << endl;cout << s2.c_str() << endl;s1 = s1;cout << s1.c_str() << endl;}void test_string6(){/*string s1("hello world");string s2("hello bit");cout << s1 << endl;cout << s2 << endl;string s3;cin >> s3;cout << s3 << endl;*/string s1, s2;cin >> s1 >> s2;cout << s1 << endl;cout << s2 << endl;string s3;//getline(cin, s3);getline(cin, s3, '!');cout << s3 << endl;}void test_string7(){string s1("1111111111111");string s2(s1);cout << s1 << endl;cout << s2 << endl;string s3("222222222222222222222222222");s1 = s3;cout << s1 << endl;cout << s3 << endl;//s1.swap(s2);//swap(s1, s2);cout << s1 << endl;cout << s2 << endl;}
}

3.wctest.cpp

#include"string.h"int main()
{//wc::test_string1();//wc::test_string3();wc::test_string5();return 0;
}

4>>结语

        今日C++到这里就结束啦,如果觉得文章还不错的话,可以三连支持一下。感兴趣的宝子们欢迎持续订阅小枫,小枫在这里谢谢宝子们啦~小枫の主页还有更多生动有趣的文章,欢迎宝子们去点评鸭~C++的学习很陡,时而巨难时而巨简单,希望宝子们和小枫一起坚持下去~你们的三连就是小枫的动力,感谢支持~

相关文章:

【C++游记】string的使用和模拟实现

枫の个人主页 你不能改变过去&#xff0c;但你可以改变未来 算法/C/数据结构/C Hello&#xff0c;这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕&#xff0c;我们继续来学习C的内容呀。C是接近底层有比较经典的语言&#xff0c;因此学习起来注定枯燥无味&#xf…...

DockerUI info存在未授权访问漏洞

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...

SQL,查询每天最接近指定时间的记录

Oracle 数据库的某表有一列是日期时间类型&#xff0c;每天对应多条数据&#xff1a; td1.1.2024 08:08:0811.1.2024 10:10:1021.1.2024 15:15:1531.1.2024 20:20:2042.1.2024 09:09:0952.1.2024 12:12:1262.1.2024 16:16:16712.12.2024 16:16:168 现在要从每天找出两条记录&…...

ElasticSearch如何做性能优化?

大家好&#xff0c;我是锋哥。今天分享关于【ElasticSearch如何做性能优化&#xff1f;】面试题。希望对大家有帮助&#xff1b; ElasticSearch如何做性能优化&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&#xff0c;性能优化是…...

【Linux】虚拟空间布局模型地址回填数据段合并(万字详解)

Ⅰ、虚拟空间布局模型 理论模型 包括上节的动态库与静态库&#xff0c;加上本节后面两个内容其实都是对gcc的扩展与补充知识&#xff0c;也是需要了解和掌握的知识。在开讲之前&#xff0c;我们先来说一下在32位x86的Linux系统中&#xff0c;虚拟地址空间布局模型&#xff1a…...

const和修饰指针的几种用法

昨天闲着没事去面试了一个C岗位&#xff0c;问了很多基础的东西都没答上来。主要原因是这些知识在硬件资源丰富的pc端用的不多&#xff0c;二来确实很久没温习之前的C相关的知识了。在面试官问了几次类似的问题没有答好的情况下&#xff08;还喜欢问你确不确定&#xff09;&…...

mybatis事务的自动提交与手动提交

MyBatis支持自动提交和手动提交两种事务管理方式。 自动提交事务 MyBatis默认使用自动提交模式&#xff0c;即每个SQL操作都会自动提交到数据库中。这意味着在执行完一条SQL语句后&#xff0c;MyBatis会自动调用commit()方法将更改持久化到数据库。 手动提交事务 可以通过Sq…...

网络安全协议之比较(SSH、PKI、SET、SSL)

一、SSH介绍 什么是SSH&#xff1f;   传统的网络服务程序&#xff0c;如&#xff1a;ftp、pop和telnet在本质上都是不安全的&#xff0c;因为它们在网络上用明文传送口令和数据&#xff0c; 别有用心的人非常容易就可以截获这些口令和数据。而且&#xff0c;这些服务程序的…...

Vue的生命周期方法

Vue 生命周期方法详解 beforeCreate 执行时机&#xff1a;在实例初始化之后&#xff0c;数据观测&#xff08;data observer&#xff09;和事件配置&#xff08;event/watcher setup&#xff09;之前被调用。内部状态&#xff1a;此时&#xff0c;组件的选项对象&#xff08;例…...

ISP和IQ调试(一)

系列文章目录 文章目录 系列文章目录前言一、ISP&#xff08;image signal process)二、ISP位置三、IQ总结 前言 一、ISP&#xff08;image signal process) image signal process 图像处理技术 image signal processor 图像信号处理器 设备 什么是图像信号&#xff1f; 代表…...

c# TaskScheduler

这里记录下 TaskScheduler 的简单用法。 使用场景&#xff1a; 使用 Task 的时候&#xff0c;大家知道用 TaskFactory.StartNew 可以用来创建一个 Task 。这里如果创建了 3 个&#xff0c;那么这3个 Task 就各自放飞直接运行了。 class Program {private static TaskFactory…...

可视化数据

数据科学家会直观呈现数据&#xff0c;以更好地理解数据。 他们可以扫描原始数据、检查摘要度量值&#xff08;如平均值&#xff09;或绘制数据图表。 图表是一种可视化数据的强有力方式&#xff0c;数据科学家经常使用图表快速了解适度复杂的模式。 直观地表示数据 绘制图表…...

【Redis】Redis缓存击穿

1. 概述 缓存击穿&#xff1a;缓存击穿问题也叫热点key问题&#xff0c;一个高并发的key或重建缓存耗时长&#xff08;复杂&#xff09;的key失效了&#xff0c;此时大量的请求给数据库造成巨大的压力。如下图&#xff0c;线程1还在构建缓存时&#xff0c;线程2&#xff0c;3&…...

厦门凯酷全科技有限公司深耕抖音电商运营

在数字经济飞速发展的今天&#xff0c;抖音电商平台以其独特的社交属性和庞大的用户基础&#xff0c;迅速成为众多品牌和商家的新战场。在这个充满机遇与挑战的市场中&#xff0c;厦门凯酷全科技有限公司凭借其专业的服务、创新的理念和卓越的执行力&#xff0c;成为了抖音电商…...

六西格玛DMAIC在企业得项目管理中有什么作用

六西格玛&#xff08;Six Sigma&#xff09;是一种以数据为基础的管理方法&#xff0c;旨在通过减少缺陷和变异来提高过程质量和效率。DMAIC 是六西格玛中一种常用的改进方法论&#xff0c;适用于现有过程的改进。DMAIC 代表五个阶段&#xff1a;定义&#xff08;Define&#x…...

vscode借助插件调试OpenFoam的正确的.vscode配置文件

正确的备份文件位置&#xff1a; /home/jie/桌面/理解openfoam/正确的调试爆轰单进程案例/mydebugblastFoam 调试爆轰案例流体 并且工作区和用户区都是openfoam-7版本 问题&#xff1a;F5以debug模式启动后不停在断点 解决方法&#xff1a; 这里备份一下.vsode正确的配置&…...

SpringBoot整合JWT(JSON Web Token)生成token与验证

目录 JWT 什么是JWT JWT使用流程 确定要传递的信息: 生成JWT: JWT传输: 客户端保存JWT: 客户端发送JWT: 服务器验证JWT: 服务器响应: Token的使用示例: 工具类 R结果集 返回一个生成的token 创建拦截器 JWT 什么是JWT JWT(JSON Web Token)是是目前最…...

把帕拉丁需要的.rom文件转成.bin

# 输入文件名 input_file_name = fw_payload.bin.rom # 输出文件名 output_file_name = fw_payload.bin.rom2 # 打开输出文件,准备写入翻转后的十六进制字符串 with open(output_file_name, w) as output_file: # 打开输入文件读取十六进制字符串 with open(input_f…...

Nginx 缓存那些事儿:原理、配置和最佳实践

Nginx 缓存那些事儿&#xff1a;原理、配置和最佳实践 在当今的互联网世界&#xff0c;网站的访问量和数据处理量不断攀升&#xff0c;如何确保用户能够快速、稳定地访问我们的网站&#xff0c;已经成为每个运维工程师面临的挑战。幸运的是&#xff0c;Nginx 作为一款高性能的…...

vue发展史

Vue.js发展史 Vue.js是一个渐进式JavaScript框架&#xff0c;自发布以来受到了广泛的关注和喜爱。以下是Vue.js的发展史&#xff1a; 1. 起源&#xff08;2013年&#xff09; Vue.js的创始人尤雨溪&#xff08;Evan You&#xff09;在2013年开始构思这个项目。当时&#xff0…...

基于Java和Vue开发的校园跑腿软件校园跑腿小程序系统源码

市场前景 学生需求多样化&#xff1a; 随着校园生活节奏的加快和学生需求的多样化&#xff0c;跑腿服务逐渐成为一种新兴的商业模式。学生群体对于便捷、高效的日常服务需求不断增加&#xff0c;如外卖送餐、快递代取、文件传递等。市场规模持续增长&#xff1a; 大学校园作为…...

MySQL(五)--- 事务

1、CURD操作不加控制时,可能会出现什么问题 即:类似于线程安全问题,可能会导致数据不一致问题。 因为,MySQL内部本身就是多线程服务。 1.1、CURD满足什么属性时,才能避免上述问题 1、买票的过程得是原子的吧。 2、买票互相应该不能影响吧。 3、买完票应该要永久有效吧。…...

llm chat场景下的数据同步

背景 正常的chat/im通常是有单点登录或者利用类似广播的机制做多设备间内容同步的。而且由于长连接的存在&#xff0c;数据同步&#xff08;想起来&#xff09;相对简单。而llm的chat在缺失这两个机制的情况下&#xff0c;没见到特别好的做到了数据同步的产品。 llm chat主要两…...

机器学习经典算法

机器学习经典算法学习和分享。 k近邻算法 线性回归 梯度下降法 PCA主成分分析法 多项式回归 逻辑回归 支撑向量机SVM 决策树 随机森林 评价分类指标...

Scala中的泛型

类型参数 ---- 泛型(数据类型是变化的) (1) 可以有多个 (2) 名称合法就行&#xff0c;没有固定的&#xff0c;一般用T(Type) 在Scala中&#xff0c;用[]表示。在Java中用<>表示 1. 与数据类型的区别 List是数据类型&#xff0c;表示一个列表。[Int]表示泛型&#xff0c;它…...

数据分析特征标准化方法及其Python实现

数据分析特征标准化方法及其Python实现 1、概述 在数据分析中,对特征进行标准化主要是: 1、消除量纲影响 不同特征可能具有不同的量纲和数量级。 例如,一个特征可能是以米为单位的长度,而另一个特征可能是以秒为单位的时间。直接使用这些具有不同量纲的原始数据进行分析…...

UnityShaderLab 实现程序化形状(一)

1.实现一个长宽可变的矩形&#xff1a; 代码&#xff1a; fixed4 frag (v2f i) : SV_Target{return saturate(length(saturate(abs(i.uv - 0.5)-0.13)))/0.03;} 2.实现一个半径可变的圆形&#xff1a; 代码&#xff1a; fixed4 frag (v2f i) : SV_Target{return (distance(a…...

前端数据安全防护(控制台)

目录 前言 禁用右键菜单 禁用快捷键 监控控制台 完整逻辑 前言 前端的数据在浏览器中一直处于一个裸奔的状态&#xff0c;只要是稍微懂一点计算机的人&#xff0c;都可以在浏览器的控制台中拿到前端页面的所有数据&#xff0c;包括和后端的交互数据。为了…...

自己玩虚拟机:vagrant,virtual box,centos

vagrant 访问Vagrant官网 https://www.vagrantup.com/ 点击Download Windows&#xff0c;MacOS&#xff0c;Linux等 选择对应的版本 AMD64 (x86_64) I686 (x86) 傻瓜式安装 命令行输入vagrant&#xff0c;测试是否安装成功 vagrant -v 可以查看当前版本 virtual box 访…...

Frida框架HOOK RegisterNatives函数

使用Frida框架HOOK RegisterNatives函数&#xff0c;获取动态注册的函数地址、名称、签名、class名称、所属的so文件名称、so文件加载基址、函数在so文件中的地址。 废话不多说&#xff0c;上代码&#xff1a; 运行命令&#xff1a;frida -U -f in.****** -l RegisterNatives…...

营销型网站制作方法/网页设计图片

WWW是一个Unity开发中非常常用到的工具类&#xff0c;主要提供一般Http访问的功能&#xff0c;以及动态从网上下载图片、声音、视频Unity资源等。主要支持的协议有: * http://* https://* file://(访问本地文件)* ftp://(只支持匿名账号)WWW加载网络资源&#xff1a;这里指…...

网站构架怎么做/能打开各种网站的浏览器下载

在Docker容器中找不到vi命令解决办法&#xff1a;1.通过命令获取最新的软件包apt-get-update2.安装vi命令apt-get install vim安装过程中提示是否进行输入Y即可。安装完毕即可使用vi...

全国建设地产网站/seo首页网站

判断App版本号/iOS系统版本号/4gWiFi环境判断当前设备类型://判断当前设备的类型改变左右两边约束的距离if([UIDevice currentDevice].userInterfaceIdiom UIUserInterfaceIdiomPhone){self.leftConstraint.constant 10;self.rightConstraint.constant 10;}判断是否是横屏: 1.i…...

泊头网站排名优化/平面设计主要做什么

使用文件安装密钥安装产品当您要安装 MathWorks 产品的计算机没有 Internet 连接时&#xff0c;请使用此过程。但是&#xff0c;您需要通过 Internet 连接来获取文件安装密钥和许可证文件&#xff0c;以及下载安装程序。如果您使用的是组织许可证&#xff0c;可以从您的系统或许…...

怎么做付款链接网站/账户竞价托管费用

20个二叉树面试高频 0. 几个概念1. 求二叉树中的节点个数2. 求二叉树的最大层数(最大深度)3. 先序遍历/前序遍历4. 中序遍历5. 后序遍历6. 分层遍历7. 求二叉树第K层的节点个数8. 求二叉树第K层的叶子节点个数9. 判断两棵二叉树是否结构相同10. 判断二叉树是不是平衡二叉树11.…...

凡科网网站怎么设置会员登录板块/保定seo排名优化

滚 &#xff0c;滚去搬砖 今天又一次发现&#xff0c;公司里搬砖和教研室的区别&#xff0c;想想还是教研室做的事情比较高大尚&#xff0c;做的事情都时多年的高级架构师做的事情&#xff0c;起点一下子就高了很多&#xff0c;而不是从底层一步步的往上进阶&#xff0c;所以&a…...