string模拟实现:
string模拟实现:
上一篇博客,我们对String类有了一个基本的认识,本篇博客我们来从0~1去模拟实现一个String类,当然我们实现的都是一些常用的接口。
❓我们这里定义了一个string类型,然后STL标准库里面也有string,两个名字一样我们分不清楚怎么办呢?
- 为了跟库的string区分开,我们可以定义一下命名空间
namespace st
{class string{public:private:char* _str;size_t _size;size_t _capacity;};
}
有了类的成员变量,我们需要对这些成员变量进行初始化和释放,我们来写一下string的构造函数和析构函数
首先来观察一下string类的成员变量,string类有三个成员变量_str(字符指针)、__size和 _capacity。
_size和 _capacity都比较容易初始化,直接置为0就好。
_str作为字符指针比较麻烦,具体的原因往下看!
1深浅拷贝:
我们来写一下我们自己string类的构造和析构函数
class string{public:string(const char* str):_str(str),_size(str._size), _capacity(str._capacity){}private:char* _str;size_t _size;size_t _capacity; }
❓上面这种构造函数我们调用的时候是否能编译通过呢?
💡这是不行的,因为你初始化这个 string 时,比如我们通常情况会这么写:
string s1("hello world");
❓我们为string的初始化提供构造函数,这里为什么报错呢?
💡原因是这里权限放大了,str是一个const char *类型,而_str只是一个char * 类型,这里赋值过来会直接权限放大报错了,同理可得:常量字符串是不可以直接赋值给char *类型的(
char*b="bcd";
)解决方法将_str也设为const char*就好啦
- 🔥
const char*
类型这里是只允许读,不允许写的
但是我们写的String类需要有增删查改的功能,因此上述的写法不可以的
我们可以这样写:
string(const char* str): _str(new char[strlen(str) + 1]) { // 开strlen大小的空间strcpy(_str, str);
}
- 🔥strlen函数是计算字符串的有效长度,是不含
\0
的!!!!!
我们这里strlen+1是为了给字符串的\0
预先留一个位置的
析构函数:
~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}
拷贝构造函数:
void TestString()
{String s1("hello xiaolu!!!");String s2(s1);
}
我们来运行一下,通过s1来拷贝构造s2
🚩 运行结果如下:
❓这里显示strcpy是unsafe(不安全的)的,这是为什么呢?如何解决呢?(当前完整代码如下)
#include<string.h>
namespace xiaolu
{class string{public:string(const char* str): _str(new char[strlen(str) + 1]){ // 开strlen大小的空间strcpy(_str, str);}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}private:char* _str;size_t _size;size_t _capacity;};void TestString(){string s1("hello xiaolu!!!");string s2(s1);}
}
int main()
{xiaolu::TestString();return 0;
}
🔑详细解析:
首先我们先来了解一下strcpy函数,strcpy函数是一个值拷贝函数,她将hello xiaolu的字符一个一个按字节拷贝到s1
这里其实不是strcpy函数的问题,而是
当string s2(s1);
这里是发生拷贝构造,而这里我没有写拷贝构造,因此编译器调用的就是默认拷贝构造,也就是浅拷贝,因为_str是char*类型,它发生值拷贝将地址直接拷贝过去,因此s1和s2指向同一块地址
解决方法:我们这里写一个拷贝构造,来进行深拷贝!
因为这里涉及到深浅拷贝的问题,因此我们来探讨一下深浅拷贝:
深浅拷贝的区别:
简单来说:
- 🔥浅拷贝就是编译器自己执行值拷贝(按照字节,一个一个字节拷贝)
举个例子
当发生拷贝的是指针,编译器会将指针的4个字节依次拷贝另外一个变量,这样会导致两个变量指向一个地址,而当delete的时候,这一块地址会被释放两次地址,就会报错了!!!
当一个类有动态内存的时候,类的拷贝有构造函数、赋值运算符重载以及析构函数基本上不可以用浅拷贝,会出现上面的问题,要用到深拷贝。
- 🔥深拷贝:深拷贝就是让编译器按照我们的想法进行拷贝或者赋值,一般来说是(开一块一样大的空间,再把数据拷贝下来,指向我自己开的空间)
我们自己需要写一个string的深拷贝:
string(const string& str):_size(str._size), _capacity(str._capacity){_str = new char[str._capacity + 1];strcpy(_str, str._str);}
void TestString(){string s1("hello xiaolu!!!");string s2;s2 = s1;}
这里的我们没有提供默认的构造函数,当我们需要创建一个新的空白的string对象的时候,就会报错,我们可以给构造函数提供缺省值
string(const char* str = ""):_size(strlen(str)){_capacity = _size == 0 ? 3 : _size;_str = new char[_capacity + 1];strcpy(_str, str);}
深拷贝的常用情景,不止经常在拷贝构造,在赋值下也很经常!
赋值的深拷贝:
赋值的深拷贝思路跟拷贝构造一样是否可以呢?他们都是拿一个已有的变量来定义一个新的变量
string& operator=(const string& str){delete[] _str; _str = new char[strlen(str._str) + 1]; strcpy(_str, str._str); }
显然这里报错了,我们来分析一下:
🔑详细解析:
这里我们先释放了原来的_str,然后new了一块新的对象,再strcpy
首先我们new了一块新的空间,new失败了会怎么样?
会抛异常!抛异常!抛异常!无关紧要
失败了没问题,也不会走到 strcpy,但问题是我们已经把原有的空间释放掉了,
神不知鬼不觉地,走到析构那里二次释放可能会炸,所以我们得解决这个问题!
我们将开辟空间的步骤提前,然后释放向后移动
string& operator=(const string& str){if (&str == this)return *this;//防止自己给自己赋值char* tmp = new char[str._capacity + 1];//防止开辟失败strcpy(tmp, str._str);delete[] this->_str;_str = tmp;_size = str._size;_capacity = str._capacity;return *this;}
再提供一种相对现代一点的写法:
String& operator=(String s){swap(_str, s._str);return *this;}
写时拷贝
在我们经常使用的STL标准模板库中的string类,也是一个具有写时才拷贝技术的类。C++曾在性能问题上被广泛地质疑和指责过,为了提高性能,STL中的许多类都采用了Copy-On-Write技术。这种偷懒的行为的确使使用STL的程序有着比较高要性能。
Copy-On-Write一定使用了“引用计数”,是的,必然有一个变量类似于RefCnt。当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,当有类析构时,这个计数会减一,直到最后一个类析构时,此时的RefCnt为1或是0,此时,程序才会真正的Free这块从堆上分配的内存。
是的,引用计数就是string类中写时才拷贝的原理!
2.string类常用接口的实现:
size()和capacity()
size_t size()const
{return _size;
}
size_t capacity()const
{return _capacity;
}
clear函数
对于 clear() 而言就是去清除当前对象的数据,我们直接在_str[0]
这个位置放上一个\0即可,并且再去修改一下它的_size = 0即可
- 不过这个接口来说我们不要去加【const成员】,因为修改了其成员变量
_size
void clear()
{_str[0] = '\0';_size = 0;
}
c_str函数
返回一个指向数组的指针,该数组包含一个以空字符结尾的字符序列(即C-string),表示string对象的当前值。
这个数组包含的字符序列与string对象的值相同,另外还包含一个以空字符(‘\0’)结尾的字符串。
- 🔥c_str返回的是一个const char*的数组指针,只读不写
const char* c_str()const
{return _str;
}
❓调试到这个地方就直接崩了,不应该直接打印null吗?
如果我们换成std中的string,不会报错,说明我们初始化存在问题
namespace st
{class string{public:string():_str(nullptr), _size(0), _capacity(0){}string(const char* str):_str(str), _size(strlen(str)), _capacity(strlen(str)){}const char* c_str(){return _str;}private:const char* _str;size_t _size;size_t _capacity;};void test_string1(){string s1;string s2("hello world");std::cout << s1.c_str() << std::endl;std::cout << s2.c_str() << std::endl;}
}
int main()
{st::test_string1();return 0;
}
2.1全缺省构造函数
我们还要考虑不带参数的构造函数,如下:
void test_string1() {string s1("hello world"); // 带参string s2; // 不带参
}
当我们要给一个空的字符串定义时,s2应该是‘\0’,我们可以直接在缺省值上设置
string(const char* str = ""):_size(strlen(str)){_capacity = _size == 0 ? 3 : _size;_str = new char[_capacity + 1];strcpy(_str, str);}
🔥这里值得注意的是缺省值,我们给了一个“”
🔑详细解析:
str是一个char*类型,正常情况下,我们会给缺省值为nullptr
string(const char* str = nullptr)
这里运行后会崩!!!
strlen是不会去检查空的,它是一直找到 \0为止的
也就相当于直接对这个字符串进行解引用了,这里的字符串又是空,所以会引发空指针问题。
所以我们这里给的是一个空的字符串 " ",常量字符串默认就带有 \0,这样就不会出问题:
string(const char* str = "")
❓为什么我们用new char[1]而不是直接用new char,都是一个啊为什么啊?
🔥为了跟有参构造那里匹配析构函数,这样就方便释放
string():_str(new char[1]), _size(0), _capacity(0){_str[0] = '\0';}string(const char* str):_size(strlen(str)){_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}
❓这里可以优化吗?
string(const char*str=nullptr) string(const char* str = '\0')
🔑详细解析:
这两个都不可以,不可以解引用空指针
string(const char* str = "\0")
这样是可以的,给常量字符串,但是没必要这样,可以下面这样
string(const char* str = "")
如果我们不写拷贝构造函数,默认生成了一个拷贝构造函数,会报错!
void test_string2(){string s1;string s2("hello world");string s3(s2);std::cout << s1.c_str() << std::endl;std::cout << s2.c_str() << std::endl;std::cout << s3.c_str() << std::endl;}
这里发生浅拷贝,同一块空间会被释放两次
string(const string& str):_size(str._size),_capacity(str._capacity){_str = new char[str._capacity+ 1];strcpy(_str, str._str);}
2.2拷贝构造函数
2.3operator[]的实现
❓[]重定向,这里有什么问题呢?
char& operator[](size_t pos){assert(pos < _size);return _str[pos];}
//成员变量
private:const char* _str;size_t _size;size_t _capacity;
普通对象可以调用,但是 const 对象呢?所以我们还要考虑一下 const 对象。
我们可能会修改pos位置的字符,也可能加字符,这里会报错,因为str为const char*类型
const char& operator[](size_t pos)const{assert(pos < _size);return _str[pos];}char& operator[](size_t pos)//构成函数重载{assert(pos < _size);return _str[pos];}
2.4operator=的实现及其必要性
赋值的话,不写拷贝构造的话也是值拷贝(浅拷贝)
s1 = s3;
下图拷贝构造分为三种:
第一种:s1的空间和s3的空间一样大
第二种:s1的空间比s3的空间大
第三种:s1的空间比s3的空间小
显然:这里第三种情况内存不够,要先释放防止内存泄漏,第二种是内存浪费,干脆全部都重新开空间就好了
string& operator=(const string& str){if (&str == this)return *this;//防止自己给自己赋值char*tmp = new char[str._capacity + 1];//防止开辟失败strcpy(tmp, str._str);delete[] this->_str;_str = tmp;_size = str._size;_capacity = str._capacity;return *this;}
2.5Print函数
这里权限放大了
const char& operator[](size_t pos)const{assert(pos < _size);return _str[pos];}size_t size()const {return _size;}
const函数,修饰this指针,但是这样另外一个地方又报错了
构成函数重载就可以解决问题了,各调用各的,这里调用第二个就可以了,this没有const修饰,并且返回类型没有const,就可以进行++等修改操作了
const char& operator[](size_t pos)const{assert(pos < _size);return _str[pos];}char& operator[](size_t pos)//构成函数重载{assert(pos < _size);return _str[pos];}
3.迭代器的实现
我们先来看看STL库中的string类的迭代器
3.1begin和end的实现
typedef char* iterator;iterator begin(){return _str;}iterator end(){//返回迭代器最后一个位置的下一个位置return _str + _size;}
3.2迭代器的扩展引用——范围for
for (auto ch : s1){std::cout << ch << " ";}std::cout << std::endl;
这里可以支持范围for,范围for的底层是迭代器实现的
🔥范围for遇上const类型的对象,会报错,因此要提供const迭代器
typedef const char* const_iterator;
const迭代器,自己可以修改,指向的对象不可以修改,有点像const指针
4.一些常用的运算符重载
bool operator>(const string&str){return strcmp(_str, str._str) > 0;}bool operator==(const string& str){return strcmp(_str, str._str) == 0;}bool operator>=(const string& str){return *this > str || *this == str;}bool operator<(const string& str){return !(*this >= str);}bool operator<=(const string& str){return !(*this > str);}
5.string类的增删查改
5.1reserve函数
reserve是一个增容函数
我们先来实现一下reserve函数,再来检验一下实用性
void reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}
5.2push_back函数
这是一个增加字符到字符串的函数
首先检查是否需要增容,如果需要就调用我们上面实现的 reserve 函数,
参数传递可以用三目操作符,防止容量是0的情况,0乘任何数都是0从而引发问题的情况。
然后在 \0 处插入要追加的字符 append_ch,然后 _size++ 并手动添加一个新的 \0 即可。
void push_back(char ch){if (_size + 1 > _capacity){reserve(_capacity * 2);}_str[_size] = ch;++_size;_str[_size] = '\0';}
5.3append函数
append函数是追加字符串的函数
void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;}
5.4 operator+= 的实现
比起push_back和append函数,我们更加喜欢用+=运算符来追加字符串或字符
string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char* str){append(str);return *this;}
5.5insert函数
🔥如果npos是const可以在类内初始化,这种情况只能出现在整形的情况,double不可以
static const size_t npos=-1;
但是不推荐这样写,推荐老老实实写,这里语法有点冲突,但是不会报错
void insert(size_t pos, char ch){assert(pos <= _size);if (_size + 1 > _capacity){reserve(2 * _capacity);}size_t end = _size;//size_t是一个无符号整数while (end >= pos){_str[end + 1] = _str[end];--end;}_str[pos] = ch;++_size;}
🔑详细解析:
上面代码是错的,end是一个无符号整数,-1的话变为max-1了,这里是等号两边的类型不同,会发生整形提升,有符号会变成无符号的
string& insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 3 : 2 * _capacity;reserve(newcapacity);}//int cur = pos;size_t end = _size + 1;//size_t是一个无符号整数while (end > pos){_str[end] = _str[end - 1];--end;}_str[pos] = ch;++_size;return *this;}string& insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){size_t newcapacity = _capacity == 0 ? 3 : 2 * _capacity;reserve(newcapacity);}size_t str_cur = 0;//str的下标size_t end = _size + 1;return *this;}
5.6resize函数
n有三种情况
void resize(size_t n, char ch = '\0'){if (n <= _size){_size = n;_str[n] = '\0';}else {if (n > _capacity){reserve(n);}size_t i = _size;while (i < n){_str[i] = ch;++i;}_size = n;_str[n] = '\0';}}
5.7erase函数
erase的三种情况
string& erase(size_t pos, size_t len = npos){assert(pos < _size);if (pos + len >= _size || len == npos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}return *this;}
5.8find函数
size_t find( char ch,size_t pos=0){assert(pos < _size);for (size_t i = pos; i < _size; ++i){if (_str[i] == ch)return i;}return npos;}size_t find(const char* str, size_t pos = 0){assert(pos < _size);char* p = strstr(_str + pos, str);if (p == nullptr){return npos;}else{return p - _str;}}
在这里插入代码片
相关文章:
![](https://img-blog.csdnimg.cn/a80fe11e958a41ba8ce1a881ce56e06d.gif#pic_center)
string模拟实现:
string模拟实现: 上一篇博客,我们对String类有了一个基本的认识,本篇博客我们来从0~1去模拟实现一个String类,当然我们实现的都是一些常用的接口。 ❓我们这里定义了一个string类型,然后STL标准库里面也有string&#…...
![](https://www.ngui.cc/images/no-images.jpg)
系统与软件安全研究(八)
FUZZ101入门 Detail gcc,clang,llvm都有啥区别GCC (GNU Compiler Collection), Clang, 和 LLVM 都是用于编译代码的工具链。它们在某些方面有相似之处,但也有一些重要的区别。 GCC (GNU Compiler Collection):GCC 是由 GNU 组织开发的,是一个非常流行的开源编译器集合。它…...
![](https://img-blog.csdnimg.cn/img_convert/741bd520edd94429faa51eb53975efe2.png)
jmeter测试rpc接口-使用dubbo框架调用【杭州多测师_王sir】
1.基于SOAP架构。基于XML规范。基于WebService协议。特点:接口地址?wsdl结尾2.基于RPC架构,基于dubbo协议,thrift协议。SpringCloud微服务。3.基于RestFul架构,基于json规范。基于http协议(我们常用的都是这种,cms平台也是) Rest…...
![](https://img-blog.csdnimg.cn/769d67b7c6f74eab8a2f29a6329d29f3.png#pic_center)
Java8中forEach()里使用return的效果
先总结:使用forEach()处理集合时不能使用break和continue这两个方法,可以使用无返回值的return跳出此次循环,效果同标准for循环的continue。 首先,forEach()先对入参判空,然后使用增强for循环调用action.accept(t)&am…...
![](https://img-blog.csdnimg.cn/fccfcf8be66340cd9e1cdd9f2ee4ee40.png)
MVC配置原理
如果你想保存springboot的mvc配置并且还想自己添加自己的配置就用这个。 视图解析器原理,它会从IOC容器里获取配置好视图解析器的配置类里的视图解析器集合, 然后遍历集合,生成一个一个的视图对象,放入候选 视图里,…...
![](https://www.ngui.cc/images/no-images.jpg)
rabbitmq安装
安装erlang方案二 vi /etc/yum.repos.d/rabbitmq-erlang.repo 文件内容: In /etc/yum.repos.d/rabbitmq-erlang.repo [rabbitmq-erlang] namerabbitmq-erlang baseurlhttps://dl.bintray.com/rabbitmq-erlang/rpm/erlang/22/el/7 gpgcheck1 gpgkeyhttps://dl.bi…...
![](https://img-blog.csdnimg.cn/fb7d0ed7e0834cc8a4e756f01838bcfe.png)
轻松抓取网页内容!API助力开发者,快速数据采集
在如今这个信息爆炸的时代,人们需要从各种渠道获取数据来支持自己的业务需求。而对于开发者们来说,如何快速、准确地从互联网上抓取所需的数据也成为了一项重要的技能。而抓取网页内容 API 则是一种能够帮助开发者轻松实现数据抓取的工具。 一、什么是抓…...
![](https://img-blog.csdnimg.cn/8f73f0aa3a304036b312268084333cc1.png)
CSDN 直播:腾讯云大数据 ES 结合 AI 大模型与向量检索的新一代云端检索分析引擎 8月-8号 19:00-20:30
本次沙龙围绕腾讯云大数据ES产品展开,重点介绍了腾讯云ES自研的存算分离技术,以及能与AI大模型和文本搜索深度结合的高性能向量检索能力。同时,本次沙龙还将为我们全方位介绍腾讯云ES重磅推出的Elasticsearch Serverless服务,期待…...
![](https://www.ngui.cc/images/no-images.jpg)
区块链智能合约代码示例
以下是一个简单的区块链智能合约代码示例: pragma solidity ^0.4.17;contract SimpleContract {uint public myData;function setMyData(uint newData) public {myData newData;} }该合约具有以下功能: 定义了一个名为 SimpleContract 的合约。定义了一…...
![](https://img-blog.csdnimg.cn/img_convert/f99b80613d00525a27cde4cadb9c475e.png)
Spring Boot介绍--快速入门--约定优于配置
文章目录 SpringBoot 基本介绍官方文档Spring Boot 是什么?SpringBoot 快速入门需求/图解说明完成步骤快速入门小结 Spring SpringMVC SpringBoot 的关系总结梳理关系如何理解-约定优于配置 SpringBoot 基本介绍 官方文档 官网: https://spring.io/projects/spring-boot 学习…...
![](https://img-blog.csdnimg.cn/9d5f05e9db0a4733805fd3f6f9f6636b.png)
Scons编译lib库
实例目录结构: include文件夹:test.hsrc文件夹:test.cSConscriptSConstruct 如下图所示: SConstruct: #执行当前目录下的SConscript SConscript(SConscript);SConscript: import os from SCons.Script…...
![](https://img-blog.csdnimg.cn/6d793acb79b445a79572f0870c92eb87.png)
React源码解析18(1)------ React.createElement 和 jsx
1.React.createElement 我们知道在React17版本之前,我们在项目中是一定需要引入react的。 import React from “react” 即便我们有时候没有使用到React,也需要引入。原因是什么呢? 在React项目中,如果我们使用了模板语法JSX&am…...
![](https://img-blog.csdnimg.cn/aca698b317a448deb2cfacb12a23a030.png)
系列3-常见的高可用MySQL解决方案
高可用主要解决两个问题,如何实现数据共享和同步数据、如何处理failover,数据共享的解决方案一般是SAN,数据同步通过rsync和drbd技术来实现。 1、主从复制解决方案 这是MySQL自身的高可用解决方案,数据同步方法采用的是MySQL rep…...
![](https://www.ngui.cc/images/no-images.jpg)
C#登录后携带cookie爬取数据
前一段时间,公司以前的一个数据采集任务突然之间采集下来的数据都是0了,也就是未登录状态能够获取到的数据,于是猜想肯定是网站的服务升级了,升级了数据接口的逻辑,于是便开始解决此问题。 此采集程序是由.net core开…...
![](https://www.ngui.cc/images/no-images.jpg)
自动驾驶国家新一代人工智能开放创新平台产业化应用
【摘要】:当前,全球新一轮科技革命和产业变革正孕育兴起,自动驾驶作为人工智能最重要的应用载体之一,对于加快交通强国、智能汽车强国建设,具有十分突出的战略意义。我国自动驾驶研发应用,面临技术、资金、应用等诸多挑战,为此,需要打造一套符合我国国情的自动驾驶系统…...
![](https://img-blog.csdnimg.cn/69d34eee608f44b4b4deff02fb197b94.png)
Maven分模块-继承-聚合-私服的高级用法
Maven分模块-继承-聚合-私服的高级用法 JavaWeb知识,介绍Maven的高级用法!!! 文章目录 Maven分模块-继承-聚合-私服的高级用法1. 分模块设计与开发1.1 介绍1.2 实践1.2.1 分析1.2.2 实现 1.3 总结 2. 继承与聚合2.1 继承2.1.1 继承…...
![](https://img-blog.csdnimg.cn/ca67b0c9cad549a09401267791d9719b.png)
Spring 是如何解决循环依赖问题的?
项目场景: 提示:这里简述项目相关背景: 例如:项目场景:示例:通过蓝牙芯片(HC-05)与手机 APP 通信,每隔 5s 传输一批传感器数据(不是很大) 问题描述 我们都知道,如果在代码中,将两个…...
![](https://img-blog.csdnimg.cn/img_convert/a2861737434238e8a061f17e8b02b2d8.png)
Spring-2-深入理解Spring 注解依赖注入(DI):简化Java应用程序开发
今日目标 掌握纯注解开发依赖注入(DI)模式 学习使用纯注解进行第三方Bean注入 1 注解开发依赖注入(DI)【重点】 问题导入 思考:如何使用注解方式将Bean对象注入到类中 1.1 使用Autowired注解开启自动装配模式(按类型) Service public class StudentS…...
![](https://www.ngui.cc/images/no-images.jpg)
java 强密码验证策略工具类
java 强密码验证策略工具类 package com.neusoft.caeid.common.utils;import java.util.regex.Matcher; import java.util.regex.Pattern;/*** author dume*/ public class PasswordUtil {public static final String REGEX "^\\S*(?\\S{6,})(?\\S*\\d)(?\\S*[a-zA-Z…...
![](https://img-blog.csdnimg.cn/80d5857bea8c402a8aa65b7404cc40f2.png)
CI/CD—K8S 基本理解与部署
1 K8S 是什么 Kubernetes 是一款容器的编排调度工具,来源于 Google 开源的 Brog 系统。Kubernetes简称K8S,是用8代替8个字符 “ubernete” 而成的缩写,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化…...
![](https://img-blog.csdnimg.cn/5f559b0aef1b41359302ceff92ce47d6.png)
2023网络安全常用工具汇总(附学习资料+工具安装包)
几十年来,攻击方、白帽和安全从业者的工具不断演进,成为网络安全长河中最具技术特色的灯塔,并在一定程度上左右着网络安全产业发展和演进的方向,成为不可或缺的关键要素之一。 话不多说,网络安全10款常用工具如下 1、…...
![](https://img-blog.csdnimg.cn/9b73cc1a99ae4a09a53107475464f67f.png#pic_center)
OpenStack监控工具
OpenStack是一个开源的云计算管理平台项目,是一系列软件开源项目的组合。由NASA和Rackspace合作研发并发起,以Apache许可证(Apache软件基金会发布的一个自由软件许可证)授权。 OpenStack为私有云和公有云提供可扩展的弹性的云计算…...
![](https://www.ngui.cc/images/no-images.jpg)
讲解密码学综合应用
密码学综合应用是指将密码学的理论和技术应用于各种场景中,以保障信息的安全性、完整性和可靠性。密码学的应用范围非常广泛,包括通信安全、网络安全、电子商务、数字签名、认证、密钥管理等。下面将简要介绍一些密码学综合应用的实例: 1. 加…...
![](https://img-blog.csdnimg.cn/3025399ab5894f2f985ce6c074f8d1ee.png)
Flamingo
基于已有的图像模型和文本模型构建多模态模型。输入是图像、视频和文本,输出是文本。 Vision encoder来自预训练的NormalizerFree ResNet (NFNet),之后经过图文对比损失学习。图片经过图像模型的输出是2D grid,视频按1FPS的频率采样后经过图…...
![](https://img-blog.csdnimg.cn/5d3159b673774ea284b709c04b8e8657.png)
Leetcode-每日一题【剑指 Offer 12. 矩阵中的路径】
题目 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 例如,在下面的 34 的矩阵中包含单词 "ABCCED"(单词中的字母…...
![](https://img-blog.csdnimg.cn/7af21aa95aaf49e8809405e43388dc0b.png)
安全渗透知识总结二
目录 一、html实体编码 1、Unicode字符编码 2、字符的数字表示 3、常见实体编码 4、url 协议 主机 http状态码 http常用的状态码 端口 常见协议端口 查询参数 锚点 url字符 urlcode字符 绝对url和相对url 二、字符编码 Ascll字符集 html字符集 html的url编码 …...
![](https://www.ngui.cc/images/no-images.jpg)
【线程】wait()+notifyAll()实现多个线程交替遍历,输出ABCABC
背景 有三个线程,每个线程分别循环输出A、B、C,各线程循环10次,要求输出结果是ABCABCABC这样的 代码 Data public class PrintThread extends Thread {private String string; // 输出的字符串private int order; …...
![](https://img-blog.csdnimg.cn/946277a8274147ffa5faae605b404128.png)
MyBatis 缓存机制复习及项目中的应用经历
背景 想起前两年工作中因为二级缓存默认开启导致的问题,完整的看了一个介绍 MyBatis 缓存机制的视频《MyBatis 缓存基础知识讲解》。 总计知识点: 缓存的类型及开关这是个形同虚设的功能,线上环境应该禁用缓存 MyBatis 缓存分类 MyBasit…...
![](https://img-blog.csdnimg.cn/b9f9dd08a9fc46348eddf0f6cd86c8fe.png#pic_center)
匈牙利算法详解
匈牙利算法(Hungarian Algorithm)是一种组合优化算法(combinatorial optimization algorithm),用于求解指派问题(assignment problem),算法时间复杂度为O(N^3)。Harold Kuhn发表于1955年,由于该算法基于两位匈牙利数学家的早期研究成果&#…...
![](https://www.ngui.cc/images/no-images.jpg)
script的三种加载模式
默认加载:阻断dom树构建(html文档解析),下载资源,然后立即执行,完毕后再进行dom树构建defer 加载:下载照旧,但执行延后。即下载资源和dom构建同时进行,但等dom树构建完再执行async:下…...
![](/images/no-images.jpg)
github个人网站模板/推广seo优化公司
基本词义 ◎ 免 miǎn 〈动〉 (1) (会意。金文字形,下面是“人”,上面象人头上戴帽形,是冠冕的“冕”本字。由于假借为“免除”义,另造“冕”字。假借义:免除,避免) (2) 脱掉;脱落 [take off] 免…...
![](/images/no-images.jpg)
莆田哪里有做网站的/如何进行搜索引擎优化
不敢发首页,放在家里纯属观摩 上回:博客园的故事-愤怒时的呐喊 上回说到,摩登女郎并不安分,偶尔制造“门事件”扩大影响,一时和尚门看到也颇感新鲜,竞相传阅,一时不亦乐乎…...
![](/images/no-images.jpg)
网站建设师/网络新闻发布平台
专栏 | 九章算法网址 | http://www.jiuzhang.com2016年2月12日,旧的17个月OPT延期政策将失去其效力。符合条件的STEM专业的童鞋们,抓紧时间搭上最后一班顺风车吧!早前,在旧的17个月OPT延期法案被撤销时,法官在做出裁决…...
![](/images/no-images.jpg)
织梦开发网站/网站设计培训
开始学习tensorflow了,张量是tensorflow最基础的概念,我发现自己还不会。学习的视频中,老师也没讲到,只是一带而过,刚刚参考了几篇博客,对张量大概有个了解,但是里面的数学用语还是不懂…...
![](http://tool.chinaitlab.com/UploadFiles_9734/200605/20060508115026932.jpg)
初学者怎么做php网站/东莞网站建设推广技巧
七种办法减少Word容量(转)利用Word生成的文档,每页在20KB左右,但看到用记事本生成的文档,相同的内容只有1KB左右,能让Word也减减肥吗?其实我们可以采用一些行之有效的方法来减小Word文档的容量。 1.取消快速…...
![](/images/no-images.jpg)
用户权限网站/网站关键词在哪里看
TCP协议不是有keep-alive机制吗,那为什么基于TCP的应用还需要在应用层加入心跳包机制? 参考: 为什么基于TCP的应用需要心跳包(TCP keep-alive原理分析) TCP中已有SO_KEEPALIVE选项,为什么还要在应用层加入…...