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

Redis string类型hash类型

string类型

类型介绍

在Redis中的所有的key都是string类型,而value的类型有多种。

Redis中的字符串是直接按照二进制的方式进行存储的,也就是不会做任何的编码转换,存的是什么,取出来的就是什么。这样一般来说,Redis遇见乱码的可能性会变小。因为这里会出现乱码就只跟存入端和读取端有关,而像mysql这样自己会做编码转换的,那么出现的乱码的原因还可能跟mysql自身的编码转换有关。

另外因为Redis存储字符串是按二进制存储的,所以不仅仅只可以存文本数据,

甚至还可以存图片,音频。

set/get

再看一下set的语法:

SET key value [expiration EX seconds|PX milliseconds] [NX|XX]

 对于后面的选项语法格式:

 [expiration EX seconds|PX milliseconds] 也就是在设置key的时候,同时设置超时时间,EX就是以秒级单位的,PX就是毫秒。

[NX|XX] NX:表示 如果key存在,那么就不设置 ,返回nil;如果不存在,那么才设置。

XX:表示 key存在,才设置(相当于更新key);如果key不存在,那么就不设置。

这样的额外选项可以减少网络轮次,在客户端-服务器这样的程序下还是很有用的。 并且对于一条命令来说,它的执行效果是原子的,而分开的话就不好说了。

用命令

flushall

 可以进行删库操作,将所有的数据全部删除。这个操作非常危险,几乎不会用到。

mset/mget

mset:⼀次性设置多个 key 的值。

MSET key value [key value ...]

 mget:⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil。

MGET key [key ...]

这里的时间复杂度官方给的是:O(N),不过这里的N跟我们之前说的一样,指的是key的数目。 

这两个命令同样是为了减少请求的网络轮次的。

 

setnx/setex/psetex 

这三个命令其实就是对set的一些常见用法进行了缩写。

incr/incrby/decr/decrby/incrbyfloat

 incr只能针对一个整数使用,返回这个数加一后的值。相当于 ++i,其他的命令同理。

incrby可以针对value进行 + n的操作。并且这里的n可以是负数,如果是负数就相当于减法操作。

另外在Redis中的int是64位的。 

为什么Redis明明可以使用一套命令就可以实现加减法,为什么要设计两套呢?这一点跟刚刚的setnx那些命令是一样的,是为了让Redis的使用更加符合人的直觉,从而降低用户的使用门槛。

另外,如果我们 incr/incrby的key不存在时,它会帮我们插入一个value为0的值,然后进行对应的加减操作。

 剩下三个命令的使用原理跟incr和incrby差不多。这些命令的时间复杂度都是O(1)。

 另外这个 incrbyfloat 中的float其实是按double的标准来的。

append 

如果 key 已经存在并且是⼀个 string,命令会将 value 追加到原有 string 的后边。如果 key 不存在,则效果等同于 SET 命令。

APPEND KEY VALUE
时间复杂度:O(1). 追加的字符串⼀般⻓度较短, 可以视为 O(1).
返回值:追加完成之后 string 的字节大小。

注意:append这里的返回值 的单位是字节。

如果我们想让Redis客户端能够自动的把二进制数据尝试翻译,那么在启动客户端的时候要加上一个 --raw的选项

可以看到,当我们启动时没有带 --raw时,我们查出来的汉字是十六进制显示的,其中每个十六进制前的 \x 是转义字符,表示这是一个十六进制。 

getrange 

返回 key 对应的 string 的⼦串,由 start 和 end 确定(左闭右闭)。可以使⽤负数表⽰倒数。-1 代表倒数第⼀个字符,-2 代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据 string 的⻓度调整成正确的值。

GETRANGE key start end

 在C++和Java中,谈到一个区间大多都是左闭右开的 [x,y) 。而Redis这里都是闭区间 [x,y]

时间复杂度:O(N). N 为 [start, end] 区间的⻓度. 由于 string 通常⽐较短, 可以视为是 O(1)
返回值:string 类型的⼦串 (没有就返回空串)

注意:当我们存的值是汉字时,因为一个汉字占3个字节,所以使用这个切分的时候还需要考虑到这一点,不然切出来的可能是乱码

setrange 

覆盖字符串的⼀部分,从指定的偏移开始。 如果从指定偏移位置覆盖的字符串超出了原本能覆盖的大小,那么多余的字符串会以追加的形式覆盖。 

SETRANGE key offset value
时间复杂度:O(N), N 为 value 的⻓度. 由于⼀般给的 value ⽐较短, 通常视为 O(1).
返回值:替换后的 string 的⻓度。

注意:当value是一个中文字符串的时候,进行setrange是有可能出问题的。

另外,setrange对于不存在的key也是可以操作的, 不过会把 offset(偏移位置)之前的内容填充成:0x00。

strlen 

 获取 key 对应的 string 的⻓度。当 key 存放的类似不是 string 时,报错。

STRLEN key
时间复杂度:O(1)
返回值:string 的⻓度,单位依旧是字节。或者当 key 不存在时,返回 0。

 string编码方式

int:8 个字节的⻓整型。
embstr:⼩于等于 39 个字节的字符串。
raw:⼤于 39 个字节的字符串。

Redis 会根据当前值的类型和⻓度动态决定使⽤哪种内部编码实现。

不过不建议记住这样的数字,记住数字是没有意义的。

根据业务场景的不同,最佳的长度不一定是39字节,此时就需要自行修改这个数字的大小

关于修改: 

另外,我们发现Redis存储整形会用int类型(8字节大小),但是存储小数其实是用embstr的,也就是说存储小数本质还是当作字符串来存储的。

这样的差别其实是很大的,因为对于整形 进行算术运算的时候是比较方便的,但是如果是字符串存储,那么进行算术运算的时候,要先将字符串转化为小数,然后再进行算术运算,最后还要再转回字符串,开销就大多了。

string的应用场景

作为缓存

作为缓存的思路:应用服务器访问数据时,先查询Redis,如果Redis上有这个数据,那么就直接返回给应用服务器,如果没有,那么就去MySQL中去查找,在MySQL中找到后再返回给应用服务器,同时会把这个数据写入到Redis中,这个写入到Redis中的值,作为key往往被设置了过期时间

Redis这样的缓存经常存储热点数据,也就是高频被访问的数据。这样能够加速查询和缓解MySQL服务器的压力。

伪代码模拟业务数据访问过程:

1.根据用户uid获取用户信息:

UserInfo getUserInfo(long uid) {...
}

 2.⾸先从 Redis 获取⽤⼾信息,我们假设⽤⼾信息保存在 "user:info:<uid>" 对应的键中:

// 根据 uid 得到 Redis 的键
String key = "user:info:" + uid;
// 尝试从 Redis 中获取对应的值String value = Redis 执⾏命令:get key;
// 如果缓存命中(hit)
if (value != null) {// 假设我们的⽤⼾信息按照 JSON 格式存储UserInfo userInfo = JSON 反序列化(value);return userInfo;
}

 3.

如果没有从 Redis 中得到⽤⼾信息,及缓存 miss,则进⼀步从 MySQL 中获取对应的信息,随后写⼊缓存并返回:
// 如果缓存未命中(miss)
if (value == null) {// 从数据库中,根据 uid 获取⽤⼾信息UserInfo userInfo = MySQL 执⾏ SQL:select * from user_info where uid = 
<uid>// 如果表中没有 uid 对应的⽤⼾信息if (userInfo == null) {响应 404return null;}// 将⽤⼾信息序列化成 JSON 格式String value = JSON 序列化(userInfo);// 写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时(3600 秒)Redis 执⾏命令:set key value ex 3600// 返回⽤⼾信息return userInfo;
}
通过增加缓存功能,在理想情况下,每个⽤⼾信息,⼀个⼩时期间只会有⼀次 MySQL 查询,极⼤地提升了查询效率,也降低了 MySQL 的访问数。

注意: 

与 MySQL 等关系型数据库不同的是,Redis 没有表、字段这种命名空间,⽽且也没有对键名
有强制要求(除了不能使⽤⼀些特殊字符)。但设计合理的键名,有利于防⽌键冲突和项⽬
的可维护性,⽐较推荐的⽅式是使⽤ "业务名:对象名:唯⼀标识:属性" 作为键名。例如
MySQL 的数据库名为 vs,⽤⼾表名为 user_info,那么对应的键可以使⽤
"vs:user_info:6379"、"vs:user_info:6379:name" 来表⽰,如果当前 Redis 只会被⼀个业务

 使⽤,可以省略业务名 "vs:"。如果键名过程,则可以使⽤团队内部都认同的缩写替代,例如

"user:6379:friends:messages:5217" 可以被 "u:6379:fr:m:5217" 代替。毕竟键名过⻓,还
是会导致 Redis 的性能明显下降的。

 计数功能

许多应⽤都会使⽤ Redis 作为计数的基础⼯具,它可以实现快速计数、查询缓存的功能,同时数
据可以异步处理或者落地到其他数据源。

Redis将播放量同步到其他数据源的方式是异步的。

 不过Redis用作计数功能是挺不错的,但是让Redis统计数据就不行了,比如让Redis统计播放量前百的视频就很麻烦,如果让MySQL来的话一行sql就搞定了 (排序加limit 100)

实际中要开发⼀个成熟、稳定的真实计数系统,要⾯临的挑战远不⽌如此简单:防作弊、按
照不同维度计数、避免单点问题、数据持久化到底层数据源等。
比如要防作弊:一个用户对某一个视频播放量的贡献就有几百上千,这明显不合理。
不同的维度:比如视频的完播率,点赞量,转发量,评论数等

共享会话 

⼀个分布式 Web 服务将⽤⼾的 Session 信息(例如⽤⼾登录信息)保存在各⾃的服务器中,但这样会造成⼀个问题:出于负载均衡的考虑,分布式服务会将⽤⼾的访问请求均衡到不同的服务器上,并且通常⽆法保证⽤⼾每次请求都会被均衡到同⼀台服务器上,这样当⽤⼾刷新⼀次访问是可能会发现需要重新登录,这个问题是⽤⼾⽆法容忍的。

 

为了解决这个问题,可以使⽤ Redis 将⽤⼾的 Session 信息进⾏集中管理,如图 2-13 所⽰,在这种模式下,只要保证 Redis 是⾼可⽤和可扩展性的,⽆论⽤⼾被均衡到哪台 Web 服务器上,都集中从Redis 中查询、更新 Session 信息。

手机验证码 

很多应⽤出于安全考虑,会在每次进⾏登录时,让⽤⼾输⼊⼿机号并且配合给⼿机发送验证码,
然后让⽤⼾再次输⼊收到的验证码并进⾏验证,从⽽确定是否是⽤⼾本⼈。为了短信接⼝不会频繁访问,会限制⽤⼾每分钟获取验证码的频率,例如⼀分钟不能超过 5 次。
伪代码实现思路:
String 发送验证码(phoneNumber) {key = "shortMsg:limit:" + phoneNumber;// 设置过期时间为 1 分钟(60 秒)// 使⽤ NX,只在不存在 key 时才能设置成功bool r = Redis 执⾏命令:set key 1 ex 60 nxif (r == false) {// 说明之前设置过该⼿机的验证码了long c = Redis 执⾏命令:incr keyif (c > 5) {// 说明超过了⼀分钟 5 次的限制了// 限制发送return null;}}// 说明要么之前没有设置过⼿机的验证码;要么次数没有超过 5 次String validationCode = ⽣成随机的 6 位数的验证码();validationKey = "validation:" + phoneNumber;// 验证码 5 分钟(300 秒)内有效Redis 执⾏命令:set validationKey validationCode ex 300;// 返回验证码,随后通过⼿机短信发送给⽤⼾return validationCode ;
}// 验证⽤⼾输⼊的验证码是否正确bool 验证验证码(phoneNumber, validationCode) {validationKey = "validation:" + phoneNumber;String value = Redis 执⾏命令:get validationKey;if (value == null) {// 说明没有这个⼿机的验证码记录,验证失败return false;}if (value == validationCode) {return true;} else {return false;}
}
以上介绍了使⽤ Redis 的字符串数据类型可以使⽤的⼏个场景,但其适⽤场景远不⽌于此,开发
⼈员可以结合字符串类型的特点以及提供的命令,充分发挥⾃⼰的想象⼒,在⾃⼰的业务中去找到合适的场景去使⽤ Redis 的字符串类型。

hash类型 

类型介绍

⼏乎所有的主流编程语⾔都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数
组、映射。在 Redis 中,哈希类型是指值本⾝⼜是⼀个键值对结构,形如 key = "key",value = { {
field1, value1 }, ..., {fieldN, valueN } }。
注意:
哈希类型中的映射关系通常称为 field-value,⽤于区分 Redis 整体的键值对(key-value),
注意这⾥的 value 是指 field 对应的值,不是键(key)对应的值,请注意 value 在不同上下
⽂的作⽤。

基础命令 1:hset/hget/hexists/hdel

hset

设置 hash 中指定的字段(field)的值(value)。 

HSET key field value [field value ...]
时间复杂度:插⼊⼀组 field 为 O(1), 插⼊ N 组 field 为 O(N)
返回值:添加的字段的个数。

hget

获取 hash 中指定字段的值。 

HGET key field
时间复杂度:O(1)
返回值:字段对应的值或者 nil。

hexists

判断 hash 中是否有指定的字段。 

HEXISTS key field
时间复杂度:O(1)
返回值:1 表⽰存在,0 表⽰不存在。

hdel

删除 hash 中指定的字段。 

HDEL key field [field ...]
时间复杂度:删除⼀个元素为 O(1). 删除 N 个元素为 O(N).
返回值:本次操作删除的字段个数。

如果要删除所有字段,那么就是

del key

 

基础命令2:hkeys / hvals / hgetall 

hkeys 

获取 hash 中的所有字段。 

HKEYS key
时间复杂度:O(N), N 为 field 的个数.
返回值:字段列表。也就是这个key对应的所有的field。
hvals
获取 hash 中的所有的值。
HVALS key
时间复杂度:O(N), N 为 field 的个数.
返回值:所有的值。与hkeys相对,这里返回的是这个key对应的所有的value。

hgetall 

获取 hash 中的所有字段以及对应的值。 

HGETALL key
时间复杂度:O(N), N 为 field 的个数.
返回值:字段和对应的值。

 

 可以看到,查询出来的结果 是一对 field和value 的形式规律显示的。

上述的操作都是风险比较大的,数据量多大时就可能会导致Redis阻塞。

基础命令3:hmget / hlen / hsetnx /  hincrby

hmget

⼀次获取 hash 中多个字段的值 

HMGET key field [field ...]
时间复杂度:只查询⼀个元素为 O(1), 查询多个元素为 O(N), N 为查询元素个数.
返回值:字段对应的值或者 nil。

对于hmget命令,同样也还有一个hmset命令,可以同时设置多个 filed value,但是没必要,因为hset本身就已经有这个功能了。

hlen

获取 hash 中的所有字段的个数
HLEN key
时间复杂度:O(1)
返回值:字段个数。

hsetnx 

在字段不存在的情况下,设置 hash 中的字段和值。 

HSETNX key field value
时间复杂度:O(1)
返回值:1 表⽰设置成功,0 表⽰失败。

 hincrby

将 hash 中字段对应的数值添加指定的值。 

HINCRBY key field increment
时间复杂度:O(1)
返回值:该字段变化之后的值。

 hincrbyfloat

HINCRBY 的浮点数版本。
HINCRBYFLOAT key field increment
时间复杂度:O(1)
返回值:该字段变化之后的值。

使用示例:

hash的编码方式

哈希的内部编码有两种:
ziplist(压缩列表):当哈希类型元素个数⼩于 hash-max-ziplist-entries 配置(默认 512 个)、
同时所有值都⼩于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使⽤ ziplist 作为哈
希的内部实现,ziplist 使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐
hashtable 更加优秀。
hashtable(哈希表):当哈希类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ hashtable 作为哈希
的内部实现,因为此时 ziplist 的读写效率会下降,⽽ hashtable 的读写时间复杂度为 O(1)。
下⾯的⽰例演⽰了哈希类型的内部编码,以及响应的变化。

压缩的本质就是对数据进行重新编码,不同的数据有不同的特点,结合这些特点,进行精妙的设计,重新编码之后,就可以缩小体积。

示例:

 

哈希类型的应用场景 

作为缓存 

之前说过,string类型也可以作为缓存,哈希类型也可以作为缓存。

当存储结构化的数据时,使用hash作为缓存就更合适一些。

比如:

 如果用string来存储这样的具有表结构的数据的话,那么就得把数据转化为json的格式。

但是如果我们只想要操作某一对filed value,那么就需要将整个key (json)读取出来,然后解析成对象,然后对其进行修改,修改完之后,又需要将字符串重新转为json,再写回去。

但是如果此时是用hash存储的数据,那么就可以很方便的取出和修改数据了。

总结:使用hash的方式确实可以高效的对filed进行读写,但是hash也付出了更大的空间上的代价

其实还有一种缓存方式,那就是用原生字符串类型。每一个属性用一个键(key)

但是这种方式是不推荐的,因为它把同一个数据的各个属性给分散开了,也就是低内聚。这里不要把内聚和耦合混淆了。

 

一般写代码追求的是:高内聚,低耦合。 

但是需要注意的是哈希类型和关系型数据库有两点不同之处:
哈希类型是稀疏的,⽽关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的 field,⽽
关系型数据库⼀旦添加新的列,所有⾏都要为其设置值,即使为 null,如图 所⽰。
关系数据库可以做复杂的关系查询,⽽ Redis 去模拟关系型复杂查询,例如联表查询、聚合查询等
基本不可能,维护成本⾼。

还有一个问题就是:

 

 

缓存方式对比 

string类型缓存 

序列化字符串类型,例如JSON格式

优点:针对总是以整体作为操作的信息⽐较合适,编程也简单。同时,如果序列化⽅案选择合适,内存的使⽤效率很⾼。
缺点:本⾝序列化和反序列需要⼀定开销,同时如果总是操作个别属性则⾮常不灵活。

哈希类型缓存 

优点:简单、直观、灵活。尤其是针对信息的局部变更或者获取操作。

缺点:需要控制哈希在 ziplist 和 hashtable 两种内部编码的转换,可能会造成内存的较⼤消耗。

原生字符串类型 

使⽤字符串类型,每个属性⼀个键。  

优点:实现简单,针对个别属性变更也很灵活。

缺点:占⽤过多的键,内存占⽤量较⼤,同时⽤⼾信息在 Redis 中⽐较分散,缺少内聚性,所以这种⽅案基本没有实⽤性。

相关文章:

Redis string类型hash类型

string类型 类型介绍 在Redis中的所有的key都是string类型&#xff0c;而value的类型有多种。 Redis中的字符串是直接按照二进制的方式进行存储的&#xff0c;也就是不会做任何的编码转换&#xff0c;存的是什么&#xff0c;取出来的就是什么。这样一般来说&#xff0c;Redi…...

Solidity智能合约中的异常处理(error、require 和 assert)

Solidity 中的三种抛出异常方法&#xff1a;error、require 和 assert 在 Solidity 开发中&#xff0c;异常处理是确保智能合约安全性和正确性的关键步骤。Solidity 提供了三种主要方法来抛出异常&#xff1a;error、require 和 assert。本文将详细介绍这三种方法的用途、实现方…...

True NAS禁用ipv6

在 TrueNAS Scale 中&#xff0c;禁用 IPv6 的方法如下&#xff1a;12 进入 System->Advanced->Sysctl&#xff0c;设置一个 sysctl 可调整变量 net.ipv6.conf.all.disable_ipv6&#xff0c;值为 1&#xff0c;以完全禁用 IPv6。\...

笔记整理—linux进程部分(2)使用fork创建进程

为什么要创建进程&#xff0c;首先每个程序的运行都需要一个进程&#xff1b;多进程实现宏观上的并行。 fork的原理&#xff0c;是进程的分裂生长模式。如果操作系统需要一个新的进程&#xff0c;那么就会以cp的方法得到一个新的进程&#xff0c;此时老的进程是父进程&#xff…...

在Python中实现多目标优化问题(6)

在Python中实现多目标优化问题 在Python中实现多目标优化&#xff0c;除了传统的进化算法&#xff08;如NSGA-II、MOEA/D&#xff09;和一些基于机器学习的方法外&#xff0c;还有一些新的方法和技术。这些新方法通常结合了最新的研究成果&#xff0c;提供了更高效的解决方案。…...

Java EE中的编码问题及解决方案

Java EE中的编码问题及解决方案 在Java EE开发中&#xff0c;处理字符编码是确保数据正确传输和显示的重要环节。不同的编码不一致会导致乱码&#xff0c;影响用户体验。本文将总结在Java EE中可能遇到的编码问题及其解决方案。 1. 输入数据编码问题 在表单提交时&#xff0c…...

9月27日,每日信息差

第一、中国科学家团队在干细胞治疗领域取得重要突破&#xff0c;通过化学重编程技术成功制备出胰岛细胞&#xff0c;并用于移植治疗一名 1 型糖尿病患者&#xff0c;实现了临床功能性治愈。相关研究成果已发表在国际权威期刊《细胞》上。 第二、交通运输部公路局局长周荣峰在国…...

什么是 Angular 开发中的 Dumb components

Dumb components&#xff0c;在 Angular 开发中也被称为 Presentational components&#xff0c;它们的主要职责是通过展示数据和触发事件&#xff0c;把业务逻辑和 UI 表现分离开来。Dumb components 只通过 Input() 接收数据&#xff0c;Output() 向外发送事件&#xff0c;不…...

Docker 进入容器运行命令的详细指南

Docker 进入容器运行命令的详细指南 Docker 是一个开源的容器化平台&#xff0c;广泛应用于开发和生产环境中。它允许开发者打包应用程序及其依赖项到容器中&#xff0c;并能够在不同的平台上快速部署和运行。容器通常是独立且隔离的&#xff0c;但在开发、调试或维护过程中&a…...

如何禁止非真实用户的ip访问网站服务器

为了禁止非真实用户的IP访问网站服务器&#xff0c;可以采用多种技术手段和策略。以下是一些常用的方法&#xff1a; 1. 使用IP黑名单和白名单 黑名单&#xff1a;定期更新和维护一个IP黑名单&#xff0c;阻止已知的恶意IP地址或数据中心IP访问网站。白名单&#xff1a;对于特…...

探索SpringBoot:学科竞赛管理项目开发

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…...

ultralytics yolo v8 示例:加载官方模型进行推理

Ultralytics YOLO 是计算机视觉和 ML 领域专业人士的高效工具。 安装 ultralytics 库&#xff1a; pip install ultralytics 实现代码如下&#xff1a; import cv2 from ultralytics import YOLO# 加载预训练的 YOLOv8n 模型 ckpt_dir "./ckpt/" # 模型缓存地址…...

【中间件学习】Nginx快速入门(为了配置一个项目)

-----------------------------本文章借鉴遇见狂神说--------------------------- 一、一个产品出现瓶颈&#xff1f;&#xff1f; 在一个产品刚刚上线的时候&#xff0c;并发量小&#xff0c;用户使用的少&#xff0c;所以在低并发的情况下&#xff0c;一个jar包启动应该就够…...

鸿蒙harmonyos next flutter通信之MethodChannel获取设备信息

本文将通过MethodChannel获取设备信息&#xff0c;以此来演练MethodChannel用法。 建立channel flutter代码&#xff1a; MethodChannel methodChannel MethodChannel("com.xmg.test"); ohos代码&#xff1a; private channel: MethodChannel | null nullthis.c…...

【笔记】原子结构的近代理论

近代原子结构理论的建立是从氢原子光谱得到启示的。 一、氢原子光谱与波尔理论 1.氢原子光谱 在装有两个电极的真空玻璃管内通入极少量高纯氢气&#xff0c;通高压电使之放电&#xff0c;管中发出的光束通过分光棱镜&#xff0c;得到分立的谱线&#xff0c;称为线状光谱。 发…...

【python】循环中断:break 和 continue

目录&#xff1a; while 循环的基础语法while 循环的基础案例while 循环的嵌套应用while 循环的嵌套案例for 循环的基础语法for 循环的嵌套应用循环中断&#xff1a;break 和 continue综合案例 学习目标&#xff1a; 掌握使用 continue 和 break 关键字控制循环 思考&#…...

WIFI密码默认显示

文章目录 需求分析遇到问题问题原因解决方案 需求 在进入设置&#xff0c;点击某一个wifi,连接wifi 界面&#xff0c;显示密码默认选中状态&#xff0c;效果如下 分析 在 WiFi密码被输入法挡住 中我们已经分析了整个流程&#xff0c;布局文件和控制中心。 结局系统设置WIFI连…...

Emiya 家今天的饭C++

题目&#xff1a; 样例解释&#xff1a; 【样例 1 解释】 由于在这个样例中&#xff0c;对于每组 i,j&#xff0c;Emiya 都最多只会做一道菜&#xff0c;因此我们直接通过给出烹饪方法、主要食材的编号来描述一道菜。 符合要求的方案包括&#xff1a; 做一道用烹饪方法 1、主要…...

Mybatis缓存机制(图文并茂!)

目录 一级缓存 需求我们在一个测试中通过ID两次查询Monster表中的信息。 二级缓存 案例分许(和上述一样的需求) EhCache第三方缓存 在了解缓存机制之前&#xff0c;我们要先了解什么是缓存&#xff1a; ‌缓存是一种高速存储器&#xff0c;用于暂时存储访问频繁的数据&…...

Git 工作区、暂存区和版本库

Git 工作区、暂存区和版本库 Git 是一个强大的版本控制系统&#xff0c;它帮助开发者管理代码历史&#xff0c;协作开发&#xff0c;以及跟踪和合并更改。为了更好地理解 Git 的工作流程&#xff0c;我们需要了解 Git 中的三个核心概念&#xff1a;工作区&#xff08;Workspac…...

SSH 远程连接到 Linux 服务器上的 SQLite

通过 SSH 远程连接到 Linux 服务器上的 SQLite 数据库文件的流程&#xff0c;可以分为以下几个步骤&#xff1a; 通过 SSH 连接到远程 Linux 服务器。在远程服务器上执行 SQLite 命令行工具&#xff0c;操作数据库文件。在本地使用工具&#xff0c;通过 SSH 隧道间接访问远程的…...

使用ElasticSearch-dump工具进行ES数据迁移、备份

elasticsearch-dump基本使用 该工具基于第三方Elasticdump工具来实现&#xff0c;仓库地址&#xff1a;https://github.com/elasticsearch-dump/elasticsearch-dump/tree/master&#xff0c;用于更加快捷方便的将Elasticsearch不同集群的数据进行索引备份和还原。 一、安装 …...

SpringMVC源码-SpringMVC源码请求执行流程及重点方法doDispatch讲解

一、开始请求 在浏览器访问http://localhost:8080/spring_mymvc/userlist这个接口&#xff0c;是个get请求。 FrameworkServlet类的service方法会被请求到: 调用路径如下&#xff1a; service:945, FrameworkServlet (org.springframework.web.servlet) service:764, HttpSer…...

《深度学习》OpenCV 指纹验证、识别

目录 一、指纹验证 1、什么是指纹验证 2、步骤 1&#xff09;图像采集 2&#xff09;图像预处理 3&#xff09;特征提取 4&#xff09;特征匹配 5&#xff09;相似度比较 6&#xff09;结果输出 二、案例实现 1、完整代码 2、实现结果 调试模式&#xff1a; 三、…...

爬虫入门之爬虫原理以及请求响应

爬虫入门之爬虫原理以及请求响应 爬虫需要用到的库, 叫requests. 在导入requests库之前, 需要安装它, 打开cmd: 输入pip install 库名 pip install requests后面出现successful或requirement already就说明已经下载成功了!!! 下载出现的问题: 1.有报错或者是下载慢 修改镜像…...

CTF ciscn_2019_web_northern_china_day1_web1复现

ciscn_2019_web_northern_china_day1_web1 复现&#xff0c;环境源于CTFTraining 分析 拿到题目扫描&#xff0c;发现没有什么有用资产 扫描过程中注册账号登录&#xff0c;发现上传入口 上传文件&#xff0c;发现下载删除行为&#xff0c;寻找功能点&#xff0c;发现不能访问…...

docker命令汇总

Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者打包应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。 以下是一些常用的 Docker 命令…...

云计算在现代企业中的应用与优势

云计算在现代企业中的应用与优势 随着信息技术的飞速发展&#xff0c;云计算已经成为现代企业不可或缺的一部分。作为一种创新的计算模式&#xff0c;云计算为企业提供了前所未有的灵活性和可扩展性&#xff0c;极大地推动了企业的数字化转型。 一、云计算的基本概念 云计算…...

Android平台GB28181实时回传流程和技术实现

规范解读 GB28181 中的 “INVITE” 是会话初始协议&#xff08;SIP&#xff09;中的一种请求方法&#xff0c;主要用于邀请一个或多个参与者加入特定的会话。在 GB28181 标准中&#xff0c;“INVITE” 请求通常用于发起媒体流的传输请求。当一个设备想要接收来自另一个设备的媒…...

Text-to-SQL方法研究

有关Text-to-SQL实现细节&#xff0c;可以查阅我的另一篇文章text-to-sql将自然语言转换为数据库查询语句 1、面临的挑战 自然语言问题往往包含复杂的语言结构,如嵌套语句、倒装句和省略等,很难准确映射到SQL查询上。此外,自然语言本身就存在歧义,一个问题可能有多种解读。消除…...

新泰市住房和城乡建设局网站/广州seo网络推广员

2019独角兽企业重金招聘Python工程师标准>>> Error Boundaryrender方法新增返回类型Portals支持自定义DOM属性setState传入null时不会再触发更新更好的服务器端渲染新的打包策略...1. 使用Error Boundary处理错误组件 之前&#xff0c;一旦某个组件发生错误&#xf…...

珠海市建设工程质量监督检测站网站/亚马逊站外推广网站

今天学习了内部类的知识&#xff0c;知道内部类是可以持有外部类的this&#xff0c;从而在内部类中可以使用OuterClass.this.medthod()来引用相应外部类方法。但是我写出下代码&#xff0c;可以运行&#xff0c;然而其中的调用逻辑我不是很明白&#xff0c;望赐教&#xff01;p…...

河北建设集团有限公司 信息化网站/关键词排名优化怎么做

这是我们最新的JavaScript新闻通讯的社论&#xff0c;您可以在此处订阅 。 最近&#xff0c;安全研究人员分析了133,000个网站中过时的JavaScript库。 他们的发现发表在白皮书中&#xff0c; “您不应该依赖我&#xff1a;分析Web上过时的JavaScript库的使用” &#xff0c;这并…...

西安网约车公司排行榜/重庆百度推广优化

小哥哥、小姐姐&#xff0c;你们好&#xff0c;请把手伸出来&#xff0c;我给你们点东西。 1、JavaScript异步编程 同步与异步回调函数promisegeneratorasyncawait2、写一个符合规范的promise库 1、JavaScript异步编程 1-1、同步与异步 我们都知道js是单线程语言&#xff0c;这…...

网站设计的概述/镇江网站建设方案

[b]存储数据有两种基本方法&#xff1a;保存到普通文件&#xff0c;或者保存到数据库中。[/b] [b]数据写入&#xff1a;[/b] [list] [*]1、打开文件。如果文件不存在&#xff0c;需要先创建它。 [*]2、将数据写入这个文件。 [*]3、关闭这个文件。 [/list] [b]数据读出&#xff…...

微信网站公众平台/新浪体育世界杯

Centos是rpm和yum rpm相关 sudo apt install rpmrpm -qa&#xff1a;查询所安装的所有rpm包 rpm -q 软件包名&#xff1a;查询软件是否安装rpm -qi 软件包名&#xff1a;查询到安装软件的信息 rpm -ql 软件包名&#xff1a;查询软件包安装了哪些文件&#xff0c;安装到了哪里…...