【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+end | begin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器 |
rbegin+rend | rbegin获取最后一个字符的迭代器+rend获取一个字符的迭代器 |
范围for | C++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的使用和模拟实现
枫の个人主页 你不能改变过去,但你可以改变未来 算法/C/数据结构/C Hello,这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕,我们继续来学习C的内容呀。C是接近底层有比较经典的语言,因此学习起来注定枯燥无味…...
DockerUI info存在未授权访问漏洞
免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...
SQL,查询每天最接近指定时间的记录
Oracle 数据库的某表有一列是日期时间类型,每天对应多条数据: 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如何做性能优化?
大家好,我是锋哥。今天分享关于【ElasticSearch如何做性能优化?】面试题。希望对大家有帮助; ElasticSearch如何做性能优化? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中,性能优化是…...
【Linux】虚拟空间布局模型地址回填数据段合并(万字详解)
Ⅰ、虚拟空间布局模型 理论模型 包括上节的动态库与静态库,加上本节后面两个内容其实都是对gcc的扩展与补充知识,也是需要了解和掌握的知识。在开讲之前,我们先来说一下在32位x86的Linux系统中,虚拟地址空间布局模型:…...
const和修饰指针的几种用法
昨天闲着没事去面试了一个C岗位,问了很多基础的东西都没答上来。主要原因是这些知识在硬件资源丰富的pc端用的不多,二来确实很久没温习之前的C相关的知识了。在面试官问了几次类似的问题没有答好的情况下(还喜欢问你确不确定)&…...
mybatis事务的自动提交与手动提交
MyBatis支持自动提交和手动提交两种事务管理方式。 自动提交事务 MyBatis默认使用自动提交模式,即每个SQL操作都会自动提交到数据库中。这意味着在执行完一条SQL语句后,MyBatis会自动调用commit()方法将更改持久化到数据库。 手动提交事务 可以通过Sq…...
网络安全协议之比较(SSH、PKI、SET、SSL)
一、SSH介绍 什么是SSH? 传统的网络服务程序,如:ftp、pop和telnet在本质上都是不安全的,因为它们在网络上用明文传送口令和数据, 别有用心的人非常容易就可以截获这些口令和数据。而且,这些服务程序的…...
Vue的生命周期方法
Vue 生命周期方法详解 beforeCreate 执行时机:在实例初始化之后,数据观测(data observer)和事件配置(event/watcher setup)之前被调用。内部状态:此时,组件的选项对象(例…...
ISP和IQ调试(一)
系列文章目录 文章目录 系列文章目录前言一、ISP(image signal process)二、ISP位置三、IQ总结 前言 一、ISP(image signal process) image signal process 图像处理技术 image signal processor 图像信号处理器 设备 什么是图像信号? 代表…...
c# TaskScheduler
这里记录下 TaskScheduler 的简单用法。 使用场景: 使用 Task 的时候,大家知道用 TaskFactory.StartNew 可以用来创建一个 Task 。这里如果创建了 3 个,那么这3个 Task 就各自放飞直接运行了。 class Program {private static TaskFactory…...
可视化数据
数据科学家会直观呈现数据,以更好地理解数据。 他们可以扫描原始数据、检查摘要度量值(如平均值)或绘制数据图表。 图表是一种可视化数据的强有力方式,数据科学家经常使用图表快速了解适度复杂的模式。 直观地表示数据 绘制图表…...
【Redis】Redis缓存击穿
1. 概述 缓存击穿:缓存击穿问题也叫热点key问题,一个高并发的key或重建缓存耗时长(复杂)的key失效了,此时大量的请求给数据库造成巨大的压力。如下图,线程1还在构建缓存时,线程2,3&…...
厦门凯酷全科技有限公司深耕抖音电商运营
在数字经济飞速发展的今天,抖音电商平台以其独特的社交属性和庞大的用户基础,迅速成为众多品牌和商家的新战场。在这个充满机遇与挑战的市场中,厦门凯酷全科技有限公司凭借其专业的服务、创新的理念和卓越的执行力,成为了抖音电商…...
六西格玛DMAIC在企业得项目管理中有什么作用
六西格玛(Six Sigma)是一种以数据为基础的管理方法,旨在通过减少缺陷和变异来提高过程质量和效率。DMAIC 是六西格玛中一种常用的改进方法论,适用于现有过程的改进。DMAIC 代表五个阶段:定义(Define&#x…...
vscode借助插件调试OpenFoam的正确的.vscode配置文件
正确的备份文件位置: /home/jie/桌面/理解openfoam/正确的调试爆轰单进程案例/mydebugblastFoam 调试爆轰案例流体 并且工作区和用户区都是openfoam-7版本 问题:F5以debug模式启动后不停在断点 解决方法: 这里备份一下.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 缓存那些事儿:原理、配置和最佳实践 在当今的互联网世界,网站的访问量和数据处理量不断攀升,如何确保用户能够快速、稳定地访问我们的网站,已经成为每个运维工程师面临的挑战。幸运的是,Nginx 作为一款高性能的…...
vue发展史
Vue.js发展史 Vue.js是一个渐进式JavaScript框架,自发布以来受到了广泛的关注和喜爱。以下是Vue.js的发展史: 1. 起源(2013年) Vue.js的创始人尤雨溪(Evan You)在2013年开始构思这个项目。当时࿰…...
基于Java和Vue开发的校园跑腿软件校园跑腿小程序系统源码
市场前景 学生需求多样化: 随着校园生活节奏的加快和学生需求的多样化,跑腿服务逐渐成为一种新兴的商业模式。学生群体对于便捷、高效的日常服务需求不断增加,如外卖送餐、快递代取、文件传递等。市场规模持续增长: 大学校园作为…...
MySQL(五)--- 事务
1、CURD操作不加控制时,可能会出现什么问题 即:类似于线程安全问题,可能会导致数据不一致问题。 因为,MySQL内部本身就是多线程服务。 1.1、CURD满足什么属性时,才能避免上述问题 1、买票的过程得是原子的吧。 2、买票互相应该不能影响吧。 3、买完票应该要永久有效吧。…...
llm chat场景下的数据同步
背景 正常的chat/im通常是有单点登录或者利用类似广播的机制做多设备间内容同步的。而且由于长连接的存在,数据同步(想起来)相对简单。而llm的chat在缺失这两个机制的情况下,没见到特别好的做到了数据同步的产品。 llm chat主要两…...
机器学习经典算法
机器学习经典算法学习和分享。 k近邻算法 线性回归 梯度下降法 PCA主成分分析法 多项式回归 逻辑回归 支撑向量机SVM 决策树 随机森林 评价分类指标...
Scala中的泛型
类型参数 ---- 泛型(数据类型是变化的) (1) 可以有多个 (2) 名称合法就行,没有固定的,一般用T(Type) 在Scala中,用[]表示。在Java中用<>表示 1. 与数据类型的区别 List是数据类型,表示一个列表。[Int]表示泛型,它…...
数据分析特征标准化方法及其Python实现
数据分析特征标准化方法及其Python实现 1、概述 在数据分析中,对特征进行标准化主要是: 1、消除量纲影响 不同特征可能具有不同的量纲和数量级。 例如,一个特征可能是以米为单位的长度,而另一个特征可能是以秒为单位的时间。直接使用这些具有不同量纲的原始数据进行分析…...
UnityShaderLab 实现程序化形状(一)
1.实现一个长宽可变的矩形: 代码: fixed4 frag (v2f i) : SV_Target{return saturate(length(saturate(abs(i.uv - 0.5)-0.13)))/0.03;} 2.实现一个半径可变的圆形: 代码: fixed4 frag (v2f i) : SV_Target{return (distance(a…...
前端数据安全防护(控制台)
目录 前言 禁用右键菜单 禁用快捷键 监控控制台 完整逻辑 前言 前端的数据在浏览器中一直处于一个裸奔的状态,只要是稍微懂一点计算机的人,都可以在浏览器的控制台中拿到前端页面的所有数据,包括和后端的交互数据。为了…...
自己玩虚拟机:vagrant,virtual box,centos
vagrant 访问Vagrant官网 https://www.vagrantup.com/ 点击Download Windows,MacOS,Linux等 选择对应的版本 AMD64 (x86_64) I686 (x86) 傻瓜式安装 命令行输入vagrant,测试是否安装成功 vagrant -v 可以查看当前版本 virtual box 访…...
Frida框架HOOK RegisterNatives函数
使用Frida框架HOOK RegisterNatives函数,获取动态注册的函数地址、名称、签名、class名称、所属的so文件名称、so文件加载基址、函数在so文件中的地址。 废话不多说,上代码: 运行命令:frida -U -f in.****** -l RegisterNatives…...
营销型网站制作方法/网页设计图片
WWW是一个Unity开发中非常常用到的工具类,主要提供一般Http访问的功能,以及动态从网上下载图片、声音、视频Unity资源等。主要支持的协议有: * http://* https://* file://(访问本地文件)* ftp://(只支持匿名账号)WWW加载网络资源:这里指…...
网站构架怎么做/能打开各种网站的浏览器下载
在Docker容器中找不到vi命令解决办法: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 连接时,请使用此过程。但是,您需要通过 Internet 连接来获取文件安装密钥和许可证文件,以及下载安装程序。如果您使用的是组织许可证,可以从您的系统或许…...
怎么做付款链接网站/账户竞价托管费用
20个二叉树面试高频 0. 几个概念1. 求二叉树中的节点个数2. 求二叉树的最大层数(最大深度)3. 先序遍历/前序遍历4. 中序遍历5. 后序遍历6. 分层遍历7. 求二叉树第K层的节点个数8. 求二叉树第K层的叶子节点个数9. 判断两棵二叉树是否结构相同10. 判断二叉树是不是平衡二叉树11.…...
凡科网网站怎么设置会员登录板块/保定seo排名优化
滚 ,滚去搬砖 今天又一次发现,公司里搬砖和教研室的区别,想想还是教研室做的事情比较高大尚,做的事情都时多年的高级架构师做的事情,起点一下子就高了很多,而不是从底层一步步的往上进阶,所以&a…...