【c++】:STL模板中string的使用

news2024/11/18 21:50:02

 

 

文章目录

  • STL简介
  • 一.认识string
  • 二.string中基本功能的使用
  • 总结

 


STL简介

STL(standard template libaray-标准模板库): C++ 标准库的重要组成部分,不仅是一个可复用的组件库,而且 是一个包罗数据结构与算法的软件框架
STL 的版本
原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本--所有STL实现版本的始祖。
P. J. 版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。
RW 版本
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。
SGI 版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。
STL的六大组件
仿函数,空间配置器,算法,容器,迭代器,配接器。
STL的缺陷
1. STL库的更新太慢了。这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出来已经相隔了13年,STL才进一步更新。
2. STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。
3. STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。
4. STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语法本身导致的。

 

一、认识string

14bfa196b7844a04906cd15f8c0bf969.png

通过官方文档我们得知,string的原型是basic_string的类模板。

7d0c508d98934debb559a78bd5e790e4.png 我们发现wstring,u16string,u32string这些又是什么呢?string的本质是一个管理字符的顺序表只不过里面存的都是1个char类型的字符,而wstring里面存的是2字节的char,u16string也是2个字节,u32string是4个字节,为什么会有这么多的差异呢?因为我们有管理不同的字符数组的需求。在这里我们要了解ascll码,用ascll编码可以在计算机里面存储和显示英文信息,而在一开始的ascll码表中仅有128个值,用7个比特位就可以代表这128个值了,所以一开始的string中的字符仅为1个字节,如下图:

2885299c69f7471584e25fa39fdb25f3.png

 apple这个字符串存在char类型的数组中会消耗6个字节,多出来的1个字节用来存放\0,而字符a在ascll表中的值为97,内存中的16进制61转换过来就是97,所以字符确实是根据ascll的值在内存中一个一个存储的。而计算机不能只显示英文,如果只能显示英文计算机又如何卖到中国呢,所以为了显示其他国家的文字有人就发明了Unicode(万国码)能表示各个国家的文字,Unicode又分为utf-8,utf-16,uft-32,他们三个的区别是每个字符的字节数不同,比如utf-8的char就是1字节并且兼容ascll吗,utf-16用16个比特位也就是2个字节,utf-32则是4个字节表示一个字符。而string类就是因为这样的原因所以搞出了字节数不一样的模板。

总结:

1. 字符串是表示字符序列的类
2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
3. string类是使用char即作为它的字符类型,使用它的默认char_traits和分配器类型。
4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数。
5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
总结:
1. string是表示字符串的字符串类
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
4. 不能操作多字节或者变长字符的序列。
使用 string 类时,必须包含 #include 头文件以及 using namespace std;

二、string中基本功能的使用。

1.string的构造函数。

0a412adceb394dd3932c129d4521fd74.png

 我们可以看到string的构造函数有7个不同的重载,第一个可以直接定义一个字符串,比如:

885ebd4ae00c4c958754eaf203eaffd9.png

 我们可以发现一个空字符串里面是有一个\0的。

第二个可以直接用字符串初始化:

a5f4cd4183ad48ee848e5afd1a0ae678.png

 第二个是我们使用最多也是最方便的。第三个:给定一个字符串从这个字符串的某个位置及这个位置后面的len个长度初始化,如下:

e9945bbe35f3432fa10646fa29cff4ea.png

len这个参数给了缺省值,实际上如果我们不给len那么len默认就是npos,npos是size_t类型默认值是-1,我们都知道size_t类型是无符号整形,所以-1就是整形的最大值,也就是说如果你不写这个参数那么自动将从pos位置开始后的所有字符进行构造。 

707bb3228be14b7680ef8aecd444bf9b.png

40a94932423249b4a4b56e34cd8e112a.png 第四个:直接用字符串去构造。

ebf8768dd69042499d70f75b036e6a99.png

 这里发生了隐式类型转换,将const char* 转换为string,如果不想要编译器发生隐式类型转换我们可以在构造函数前面加上explicit,这点我们在前面的类和对象文章讲过。

第五个:给定一个字符串用它的前n个构造

2f7d9e00c2604baabda1dcd15be58552.png

 第六个:用n个字符去构造

781e8ed8133447bd9ec1944dbd4f5678.png

第七个:迭代器区间的构造:

8084085f02554c0ebb7276ff53ee7bb1.png

 下面我们先来看string容量部分的函数:

4f0b1ba99a814864a0601e07df03f2f3.png

 第一个:size代表字符串的长度,length与size一模一样。

d556db613be244cdbf87ce77dffd02ff.png

 那么为什么要设计一模一样的函数呢,这里是因为c++早期的历史遗留问题,在没有STL之前是用length计算长度,有了STL后要计算二叉树等再用长度这个名称就不合适了所以多加了一个函数size。

第二个:max_size

84325b7500da4f4b872a1e20d4437b8b.png

 max_size就是字符串的最大长度,它的理想是整形的最大值但实际上没有这么大因为要看堆的大小,并且这个借口并没有什么很大的作用。

我们先讲第四个:capacity

f5eed205d7dd455eb4c164e375a4f203.png

 capacity就是字符能存储多少个字节,在这里需要注意的是:capacity不包含\0也就是说如果字符串是:“hello”,那么capacity就是5不会再加上\0的一个字节大小。

第三个:resize 

23e1fe221c86473ab20af9bd2ca19ebe.png

 第一个作用:resize的作用是开空间并且初始化,并且resize会改变size和capacity的大小。

8362bc81e41a401aa2b06188bdadc119.png

3463ffe740bd4f9b89e4eeef3575d9a9.png

  我们可以看到,s1的长度从11变成了50,空间从15变成了63,当然如果我们不主动初始化为某个字符会默认初始化为\0。

4e3b8529775b42ce86a3bc2dc0906436.png

 第二个作用:当resize的大小比原来字符串的capacity要小,那么resize就会将字符串中的字符缩减为resize的大小。

2f735f6fcdc34f9eb7c07c9ea12661f8.png

 我们可以看到字符串只保留了前五个字符。

第五个:reserve  开空间,只改变capacity不改变size,并且不会初始化。

7dac6ba0cc38470ca8adc673f1cd7be8.png

 第六个:clear  清空字符串

dd4cc36670b446deaccad22874a437bd.png

可以看到字符串为空了。

第七个:empty  判断字符串是否为空

9080715c10944e5797a365c5dd302997.png 接下来我们看string中的modify接口:

b8dbb5a6957c4b9f8fd1af73c42fc055.png

 这里我们就不按照顺序进行演示了,因为有些接口不按照顺序效果会更好。

push_back  :尾插一个字符

931c15ed31b8455998f92f39f1d25717.png

append:尾插一个字符串

d325a35b788a4d5abb84a80e3d665e6c.png

第3个重载: 

e1216ff4127a44ca85e003088c2a3a60.png 这里也是有6个函数重载,实在太过冗余所以我们就演示经常使用的。

第2个重载,尾插一个字符串的从pos位置起的sublen个字符

a3836036663a4b4ca9c53672a6997706.png

 第4个重载,尾插一个字符串的前n个

40b4d72bb91a4d9a812937676f2b5c8e.png

第1个重载:

660839e7754f463a955bf2ca78522c33.png 当然以上的这些接口其实都不是很实用,最实用的是操作符重载中的+=符号。

496a9548cf8345d1bcfc9a401e93de54.png

可以看到+=符号实在是太方便了。

insert:插入字符串或者字符

239ddff20f2d4f50922888720512be05.png

下面演示一下如何使用:在第pos个位置插入一个string对象

6a5769391c5d4df6b2fcabcdd963c3c5.png

 在第pos个位置插入一个string对象的从subpos下标位置开始的sublen个字符

ec976bb293994ca99b9cc98d3db7044f.png

 在第pos个位置插入一个字符串bfbb69f0aabb4ea4a1bfd3be68bfa052.png

 在第pos个位置插入字符串的前n个。

f0a6c7cf791942cba5e7f68b7280f92e.png

当然我们是不推荐使用insert的,因为插入要往后挪数据,时间复杂度为O(N)。

有insert就会有erase,我们看一下erase接口:

73b332ead607414490bb56652e18bec7.png

从pos位置起删除len个字符:

cf42a82a4bdc4652a7b5c0c8161ca50c.png len有缺省值,如果我们不传则从pos位置开始后面全删,如下:

b1f9c500a704456ebd5c12f15cc7ff42.png

接下来我们看一下replace接口:

c39e46528a51433da8ae8b9063a819da.png replace的重载太多了并且冗余,我们会用一两个即可:

3d50d965ab59452fa471dd3a1260bffd.png

 上图是从下标为pos的位置开始的len个字符串。

我们先一下find接口:

852adc143d554e828502402cdb63fba1.png

 pos使用缺省值如果我们不写默认是0位置。

下面我们用find接口和replace接口做一道经典例题:将空格替换为%20

d457c25fe5f04f92aeb81bd6f695226e.png

 看到以上的代码我们还能在优化一下吗?答案是可以,我们每次查找完一个空格就没必要再重头开始查找了,我们从上一次的位置+3开始查找即可,为什么要+3不是+1呢?因为我们替换了%20是3个字符:

9cacef48108b44ae8d62608dbd7d8167.png

 那么我们还能继续优化吗?大家还记得我们讲的reserve函数吗,我们可以提前开好空间避免在替换字符的过程中持续开空间浪费时间。

1eab5d8b506a49f899b121a0f6ca639b.png

我们用另一种方法再做一次:

171be13d5eb54440979f5b4963c06b21.png 这次的效率很明显是高于上面那种方式的,当然这样的方式提前开好空间效率也会提升不少。

下面我们来看一下string中的字符串是如何扩容的:

int main()
{
	string s;
	size_t sz = s.capacity();
	cout << "making s grow:\n";
	cout << "capacity changed:" << sz << '\n';
	for (int i = 0; i < 100; i++)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed:" << sz << '\n';
		}
	}
	return 0;
}

f9da607b45ba45d9865a6e0eeda45ade.png

 我们可以看到在vs下是按照1.5倍进行扩容的。

接下来我们看一下一个字符串的大小:

59926004ec5846d994d4e6ded50d0706.png

为什么一个空字符串的大小为28呢?看下图:

223f5ffd66df4c8da411a178d82e9853.png 在VS下string的底层是这样实现的,当字符串很小的时候就不用频繁的开空间了直接用数组即可,当字符串很大就需要用_str开空间,所以大小为28,下面我们看看linux下的:

0c343ea9f04143e39db927e10848dcc7.png

同样的代码我们运行起来:

2b1e9469063e405ab4b5bec0e9a6f1b1.png

 我们发现在linux下是严格按照2倍扩容进行的,而且字符串大小为8,那么为什么linux下没有size和capacity变量呢?因为linux下的string是按照写时拷贝实现的,string对象内部只有一个指针,8字节是因为在64位地址下,该指针将来指向一块堆空间。

97ec132d4162486885a20c98e9d10dae.png

string迭代器的使用:

f6df5e898c2f41efb519194216126ed2.png

f12aff8b3abb4335a2ecb0d965ee5934.png 要注意的是迭代器的区间是左闭右开的如下图:

0cc76b2b12fa4cb2b014a8eee01b20bf.png

 把begin给it这里的it就相当于指针,只有解引用后才是指针指向的内容。而我们最喜欢使用的语法糖实际上就是用迭代器实现的,并且这个实现非常的简单,类似于宏替换。

073988f84bf74c698156af6bbe944ac9.png

0b9bfeeabbf54d71b322f9ffa6c26885.png

通过汇编我们也可以看到范围for实际上去调用迭代器的begin和end函数了。

接下来我们看反向迭代器的使用:

472266d30f1748a4acba8d43eaf35a26.png 反向迭代器只需要在前面加上reverse即可,相对应的begin和end前面也加上r,需要注意的是反向迭代器原来的反方向,还是++向前走。

那么像下面这种情况该怎么办呢?

2a5775771ec545319a7826741fcdb0dc.png

这种情况下我们就不能调普通迭代器了我们需要调用const迭代器。如下:

ad5c531d58664f899ac94462c84139d8.png 那么为什么存在const迭代器呢,因为我们有时候是不希望别人修改我们的代码的。

4ecd33f14ae24908ad21b8ba38dab9e8.png

正常的迭代器允许我们去修改,但是const不行。

3a213028b12648759f03f5fe3aea34ca.png 下面我们看一下string中用于访问的两个接口:

12906adc94ba4345a4ba15ff00ad4863.png

8ebd1d8b47664a82af30006f5a1977ca.png

 那么这两个接口有什么区别呢?

2bccb28a7076472c80de8ed1338c403e.png

032747ea4a8a4f3e9c81d1d53d379eda.png

955ebe13a5ed4f249e64b1ec8124a462.png 我们可以看到当用【】越界时会直接报错直接终止,而at则是抛异常。

下面我们来看一下swap这个接口:

a2a36cee5abd49ff89b585a9b04ea6c9.png

0e2621a5206b4317b1ac785080e7814d.png

c15e1f2180d34c5493bc982fea9e3967.png  

 string中的swap与std::swap是不一样的,string中的swap是直接换指针的指向,而std::swap则需要调用三次拷贝构造函数,所以string中的swap的效率是更高的。

下面演示一下c_str这个接口:

b4ee49b6672742cf85df8f405b0391ec.png

不知道大家是不是会有疑问,c_str和直接打印有什么区别呢?看下图:

786a1a5d36e0431097881e248545d277.png c_str是按字符串进行打印的,也就是说遇到\0就停止。而直接打印是按照字节数也就是size去打印,不去管\0.

接下来看substr这个接口:

74eb7ad8c6e548b89d87108330e0fd1d.png

substr是取从pos位置开始的len个字符的子串。find函数我们前面讲过,其实还有一个rfind函数,find函数是从前往后找,rfind函数是从后往前找。

3dc89c5c01f94d14824dabffac9382c7.png

482edc1662de47fca332f10376b2ed71.png 可以看到我们成功取到了文件的后缀。

find_first_of:  从前往后查找任意一个出现在字符串内的字符

d4e1fa982c184786a688795b8c83c3d4.png

23cd3ad2fdfd4d30bc9bfc11956d8d0b.png 可以看到我们成功将abcd全部替换为*,还有一个与之对应的函数find_first_not_of,这个接口的作用是找到不在字符串中任意一个字符的位置。如下图所示:

fc9311fa7dd04004bf4904b198429c3a.png

可以看到这个接口与find_first_of是相反的。

find_last_of: 从后往前查找任意一个出现在字符串内的字符

0fe0f3bb1ed64d82a0acd80288044679.png

 同样还有一个find_last_not_of接口是与find_last_of是相反的:

d9b7869a9b5a497ab7411fa33d4cc513.png

下面我们说一下字符串比较的几个接口,这里的比较与C语言一样都是通过比较字符的ascll码值来确定大小的,string中的接口compare是不经常用的,我们直接看运算符重载:

51df83aa6d17441594452c3d7932c325.png

这里又再次说明了string中的接口是在太冗余了,光是相等这个重载就有三个,实在是不得不让人去吐槽。下面我们看怎么使用:

665a16b6add64887b4339e217aecc578.png 也就是说我们可以直接对象与对象进行比较,对象与字符串进行比较,字符串与对象进行比较。后面的其他符号都与等于符号同理就不在一一演示了。

下面我们讲一下getline这个接口,这个接口在写字符串类型的题目的时候非常有用:

609e7a54378b489db95dbfe3ef01aef3.png

getline就是再我们用cin输入字符串的时候以换行作为结束标志,遇到空格不会结束。为什么要说这个问题呢,因为我们发现在做题的时候当输入一个字符串字符串中有多个空格的时候只会输出空格前的字符,而空格会被留在缓冲区。getline的第一个参数为cin,第二个参数为字符串。如下题:

 7994fc1029e24ee2ac29b6bc598108b1.png

不通过的原因就是cin只识别了空格前面的字符,下面我们用getline来试一下:

1f16b83ca7d54e25b0ec7c36d93bf9d1.png 看来getline成功解决了我们的问题,所以在遇到这样输入带多个空格的字符串要用getline才可以。看到这里我们就已经把string的常用接口都演示了一遍,string一共有一百多个接口而其实大部分都是冗余的平时用不上的接口,大家就只需要把这个常用的接口用熟就能很好地使用string了。

 


总结

string中的重要接口有以下几个:size()  reserve()   resize()  operator+=    c_str    find + npos   以及比较操作符的重载,当然即使会使用这些接口也很可能对接口云里雾里,下一篇我们用c++模拟实现一个string类,届时大家可以更深刻的了解string。

 

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

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

相关文章

15_MySQL存储过程与存储函数

MySQL从5.0版本开始支持存储过程和函数。存储过程和函数能够将复杂的SQL逻辑封装在一起&#xff0c;应用程序无须关注存储过程和函数内部复杂的SQL逻辑&#xff0c;而只需要简单地调用存储过程和函数即可。1. 存储过程概述1.1 理解含义&#xff1a;存储过程的英文是 Stored Pro…

JDK8新特性宝典

JDK8新特性 ​ Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台 课程内容的介绍 了解Java发展史Lambda表达式…

[深入理解SSD系列 闪存2.1.5] NAND FLASH基本读操作及原理_NAND FLASH Read Operation源码实现

前言 上面是我使用的NAND FLASH的硬件原理图,面对这些引脚,很难明白他们是什么含义, 下面先来个热身: 问1. 原理图上NAND FLASH只有数据线,怎么传输地址? 答1.在DATA0~DATA7上既传输数据,又传输地址 当ALE为高电平时传输的是地址, 问2. 从NAND FLASH芯片手册可知,要…

Apache DolphinScheduler GitHub Star 突破 10000!

点击蓝字 关注我们今天&#xff0c;Apache DolphinScheduler GitHub Star 突破 10000&#xff0c;项目迎来一个重要里程碑。这表明 Apache DolphinScheduler 已经在全球的开发者和用户中获得了广泛的认可和使用。DolphinScheduler 旨在解决公司日常运营中的大数据处理工作流调度…

Redis之持久化操作

目录 一、简介 二、RDB 1、自动触发 2、手动触发 3、RDB 的优点和缺点 三、AOF 1、AOF的工作流程 2、AOF的配置 3、AOF的优点和缺点 4、俩种持久化的方式如何选择&#xff1f; 一、简介 1、什么是持久化&#xff1f; 持久化是指将内存中的数据同步到磁盘中&#xf…

策略模式详解

文章目录策略模式&#xff08;行为模式&#xff09;1. 策略模式介绍2. 好处3. 场景案例4. 案例源码1. 代码结构2. 榜单服务接收消息入口3. 基础任务类4. 定义策略模式转发的规范5. 代理的第一层6. 代理的第二层抽象父类&#xff1a;定义视频聊榜单代理规范7. 代理的第二层实现子…

elasticsearch自定义企业词典

我们中文分词用的是ik&#xff0c;但是ik只是对基本的中文词进行了分词&#xff0c;而对于企业或者人名没有进行分词。比如&#xff0c;我搜索中国平安&#xff0c;那么ik只能分成中国、平安如果这样&#xff0c;这肯定是不行滴&#xff01;接下来&#xff0c;俺就教你&#xf…

历史上被发现的第一个真正的Bug - Grace Hopper

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

【bug】antd全局的主题色样式被覆盖,被修改为`antd`默认的主题色

背景&#xff1a; 项目本身修改了主题色,配置如下: // umi配置文件 export default {theme: {primary-color: #2F54EB, // 全局主色}, };需要对图片上传组件做封装,并在项目中统一引用,如下 import { TdsUpload } from tdsComponents;环境信息 node tiandstiandsdeMacBook…

【JavaEE】前后端分离实现博客系统(页面构建)

文章目录1 效果展示1.1 博客登录页面1.2 博客列表页面1.3 博客详情页面1.4 博客编辑页面2 页面具体实现2.1 博客列表页的实现2.2 博客详情页的实现2.3 博客登录页面的实现2.4 博客编辑页面的实现写在最后1 效果展示 1.1 博客登录页面 用于实现用户的登录功能&#xff0c;并展…

2023年3月西安/杭州/深圳/东莞NPDP产品经理认证考试报名

产品经理国际资格认证NPDP是国际公认的唯一的新产品开发专业认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年…

什么是量子计算?

什么是量子计算&#xff1f; 量子计算机仍处于起步阶段&#xff0c;正在影响已经在经典计算机上运行的新一代模拟&#xff0c;现在使用 NVIDIA cuQuantum SDK 进行加速。 在史蒂夫乔布斯 (Steve Jobs) 推出可以放入口袋的计算机之前 27 年&#xff0c;物理学家保罗贝尼奥夫 (P…

[MySQL核心]2.select单表查询常见操作

MySQL核心--select单表查询常见操作select单表查询常见操作关于通配符*的使用结合MySQL运算符去重distinct空值查询union合并查询带in子查询(重点)limit分页查询排序order by分组group by笔试实践问题&#xff08;新浪&#xff09;select单表查询常见操作 关于通配符*的使用 项…

记录实现操作系统互斥锁的一次思考

今天实现操作系统互斥锁的时候遇到一个有趣的问题。 场景 有两个进程分别名为 taskA&#xff0c;taskB&#xff0c;采取时间片轮转的方式交替运行——也即维护了一个 ready_queue&#xff0c;根据时钟中断来 FIFO 地调度任务。它们的任务是无限循环调用 sys_print() 来打印自…

华为OD机试题,用 Java 解【用户调度问题】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…

Java基础常识

目录 JDK和JRE和JVM分别是什么?有什么关系? 什么是字节码,采用字节码的好处是什么 ? Java 程序从源代码到运行的过程 为什么 Java语言"编译与解释并存" Java 和 C、Go 语言的区别&#xff0c;各自的优缺点&#xff1f; JDK和JRE和JVM分别是什么?有什么关系…

Flink相关介绍

简介 Flink的定位是&#xff1a;Apache Flink是一个框架和分布式处理引擎&#xff0c;如图所示&#xff0c;用于对无界和有界数据流进行有状态计算。Flink被设计在所有常见的集群环境运行&#xff0c;以内存执行速度和任意规模来执行计算。 Flink 框架处理流程应用场景 1、电…

程序员应该如何学习算法?

算法不是纯粹拼智商的&#xff0c;初学者不要上来直接撸《算法导论》&#xff01;这是血泪 建议一&#xff1a;首先你得会一门程序设计语言 建议二&#xff1a;基础知识&#xff0c;数据结构&#xff0c;推荐大家看一下《大话数据结构》这本书&#xff0c;这本书看过感觉&…

华为OD机试用Python实现 -【连续字母长度 or 求第 K 长的字符串长度】 | 2023.Q1 A卷

华为OD机试题 本篇题目:连续字母长度 or 求第 K 长的字符串长度题目输入描述输出描述示例一输入输出说明示例二输入输出说明示例三输入输出说明Code代码编写逻辑最近更新的博客 华为od 2023 | 什么是华为od,od

zookeeper使用场景实战

ZK java客户端 zk官方客户端没有和服务端分离&#xff0c;同一个jar文件&#xff0c;我们直接引入zk的maven即可。注意版本匹配兼容 Curator curator java语言编程的zk客户端框架&#xff0c;curator项目是现在zk客户端中使用最多。 将我们平时使用的zk服务开发进行了封装&a…