文章目录

    • 1. 线程模型
    • 2. 数据类型
      • 2.1 String
      • 2.2 Hash
      • 2.3 List
      • 2.4 Set
      • 2.5 Sorted Set
      • 2.6 高级用法
        • 2.6.1 Bitmap
        • 2.6.2 HyperLogLog
        • 2.6.3 Geospatial
        • 2.6.4 Pub/Sub
        • 2.6.5 Pipeline
        • 2.6.6 Lua
    • 3. 事务
    • 4. 持久化
      • 4.1 RDB
      • 4.2 AOF
        • 4.2.1 AOF重写
      • 4.3 RDB与AOF
    • 5. 缓存
      • 5.1 缓存类型
      • 5.2 缓存问题
        • 5.2.1 缓存雪崩
        • 5.2.2 缓存击穿
        • 5.2.3 缓存穿透
      • 5.3 一致性
    • 6. 内存淘汰
      • 6.1 失效机制
      • 6.2 内存淘汰机制
    • 7. 复制
      • 7.1 旧版复制
      • 7.2 新版复制
        • 7.2.1 部分重同步
          • 7.2.1.1 复制偏移量
          • 7.2.1.2 复制积压缓冲区
          • 7.2.1.3 服务器运行ID
    • 8. Sentinal
    • 9. Cluster
    • 10. 底层数据结构
      • 10.1 简单动态字符串
        • 10.1.1 相比C字符串优势
          • 10.1.1.1 常数复杂度获取字符串长度
          • 10.1.1.2 杜绝缓冲区溢出
          • 10.1.1.3 减少修改字符串的内存重新分配次数
          • 10.1.1.4 二进制安全
          • 10.1.1.5 兼容部分 C 字符串函数
      • 10.2 字典
      • 10.3 跳跃表
      • 10.4 整数集合
      • 10.5 压缩列表
      • 10.6 数据类型底层实现
        • 10.6.1 String
        • 10.6.2 List
        • 10.6.3 Hash
        • 10.6.4 Set
        • 10.6.5 Sorted Set
    • 11. 与Memcache区别
    • 12. 学习思路
    • 13. 命令
      • keys
      • scan
      • del
      • unlink
      • flushall/flushdb async

Redis是基于内存的单进程单线程模型的KV数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。

它完全基于内存,绝大部分请求都是内存操作。数据也存在内存,类似于HashMap(HashMap的优势就是查找和操作的时间复杂度都是O(1));支持许多数据结构,例如String,Hash,List,Set,Sort Set,BitMap,Hyperloglog和Geospatial等。

Redis具有内置的复制,Lua脚本,LRU逐出,事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster自动分区提供了高可用性。

1. 线程模型

基于Reactor模式实现了自己的网络事件处理器,称为文件事件处理器(File Event Handler)。这个文件事件处理器是单线程的,所以Redis才叫做单线程的模型。

文件事件处理器采用I/O多路复用机制同时监听多个Socket,根据Socket上的事件来选择对应的事件处理器进行处理。
文件事件处理器
文件事件处理器的结构包含4个部分:

  1. 多个Socket;
  2. IO多路复用程序;
  3. 文件事件分派器;
  4. 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)。

多个Socket可能会并发产生不同的操作,每个操作对应不同的文件事件; I/O多路复用程序会监听多个Socket,会将Socket产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理。

2. 数据类型

基础数据类型:字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。

还有HyperLogLog、Geo、Pub/Sub,Redis Module(BloomFilter,RedisSearch,Redis-ML)

2.1 String

字符串,普通的set和get,做简单的KV缓存。

应用场景:

  1. 缓存功能:利用Redis作为缓存,再配合其它数据库作为存储层。利用Redis支持高并发的特点,可以大大加快系统的读写速度、以及降低后端数据库的压力。
  2. 计数器:使用Redis作为系统的实时计数器,可以快速实现计数和查询的功能。而且最终的数据结果可以按照特定的时间落地到数据库等存储介质当中进行永久保存。
  3. 共享Session:利用Redis将Session集中管理,每次Session的更新和获取都可以快速完成,大大提高效率。

2.2 Hash

字典,类似Map的一种结构。

应用场景:

  1. 将结构化的数据给缓存在Redis里,比如一个对象(前提是这个对象没嵌套其他的对象),然后每次读写缓存的时候,可以就操作Hash里的某个字段。

2.3 List

有序列表。

应用场景:

  1. 列表型的数据结构:如粉丝列表。通过lrange命令,读取某个闭区间内的元素,列表不但有序同时还支持按照范围内获取元素,实现基于Redis的高性能分页。
  2. 异步队列:使用右进左出的命令组成来完成队列的设计。例如:数据的生产者可以通过Rpush命令从右边插入数据,多个数据消费者,可以使用BLpop命令阻塞的“抢”列表头部的数据。

2.4 Set

自动去重的无序集合。

应用场景:

  1. 全局去重。
  2. 交集、并集、差集的操作。比如把两个人的好友列表整一个交集。

2.5 Sorted Set

zset,去重可排序的Set。写进去的时候给一个分数score,自动根据分数排序,利用分数进行成员间的排序,而且是插入时就排序好。

应用场景:

  1. 排行榜:有序集合经典使用场景。例如微博热搜榜,后面的热度值为score。
  2. 带权重的队列:比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务,让重要的任务优先执行。
  3. 延迟队列:时间戳作为score,消息内容作为key,调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。

2.6 高级用法

2.6.1 Bitmap

位图是支持按bit位来存储信息,可以用来实现布隆过滤器(BloomFilter)。

2.6.2 HyperLogLog

基数统计。供不精确的去重计数功能,比较适合用来做大规模数据的去重统计,例如统计UV

2.6.3 Geospatial

地理信息。可以用来保存地理位置,并作位置距离计算或者根据半径计算位置等

2.6.4 Pub/Sub

发布订阅 。功能是订阅发布功能,可以用作简单的消息队列

2.6.5 Pipeline

管道。可以批量执行一组指令,一次性返回全部结果,可以减少频繁的请求应答。

Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:

  1. 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
  2. 服务端处理命令,并将结果返回给客户端。

Redis管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。

使用redis-benchmark进行压测的时候可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。

2.6.6 Lua

脚本。Redis支持提交Lua脚本来执行一系列的功能

3. 事务

Redis通过MULTI、EXEC、WATCH等命令来实现事务功能。事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制。

Redis只保证串行执行命令,并且能保证全部执行,但是执行命令失败时并不会回滚,而是会继续执行下去。

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令执行完毕后,才去处理其他客户端的命令请求。

一个事务从开始到结束通常会经历三个阶段:事务开始,命令入队和事务执行。

  1. MULTI命令的执行标志着事务的开始,将执行该命令的客户端从非事务状态切换成事务状态;
  2. 客户端发送的是EXEC、DISCARD、WATCH和MULTI四个命令以外的其他命令,服务器会将这个命令放入一个事务队列里面,然后向客户端返回QUEUE回复。
  3. 当一个处于事务状态的客户端向服务端发送EXEC命令式,这个EXEC命令会立即被执行。服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将执行命令所得结果全部返回给客户端。

4. 持久化

Redis是内存数据库,它将自己的数据库状态存在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。

Redis提供了两种持久化方式,都可以把Redis内存中的数据持久化到磁盘上:

  1. RDB(redis database):全量持久化,对Redis中的数据执行周期性的持久化。
  2. AOF(append only file):增量持久化,对每条写入命令作为日志,以append-only的模式写入一个日志文件中。这个方式是只追加的方式,所以没有任何磁盘寻址的开销。

4.1 RDB

RDB通过保存数据库中的键值对来记录数据库状态。

有两个Redis命令用于生成RDB文件,一个是SAVE,一个是BGSAVE。

  1. SAVE:阻塞Redis服务器进程,直到RDB文件创建完毕,在服务器进程阻塞期间,服务器不能处理任何命令请求。
  2. BGSAVE:派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求。子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。

用户可以通过save选项设置多个保存条件,只要有任意一个条件满足,服务器就会执行BGSAVE命令。

优点

  1. 生成多个数据文件,每个数据文件分别都代表了某一时刻Redis里面的数据。
  2. 对Redis的性能影响非常小,在同步数据的时候派生了一个子进程去做持久化的。
  3. 采用二进制压缩存储,数据恢复的速度比AOF快。

缺点

  1. RDB都是快照文件,都是默认五分钟甚至更久的时间才会生成一次,意味着这次同步到下次同步中间五分钟的数据都很可能全部丢失掉,而AOF则最多丢一秒的数据。

4.2 AOF

AOF通过保存Redis服务器所执行的写命令来记录数据库状态。

AOF分为命令追加,文件写入和文件同步三个步骤:

  1. 命令追加:服务器执行完写命令后,添加命令转成协议,追加到AOF缓冲区末尾;
  2. 文件写入与同步:根据 appendfsync 的值进行选择,默认everysec。
appendfsync 描述 效率 安全性
always 将AOF缓冲区中的所有内容写入并同步到AOF文件。 最低 最安全,只丢失一个时间循环中所产生的命令数据
everysec 将AOF缓冲区中的所有内容写入到AOF文件,如果上次同步AOF文件的时间距离现在超过一秒,那么再次将AOF文件进行同步(由一个线程专门负责)。 足够快 只丢失一秒的命令数据
no 将AOF缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,由操作系统决定。 最快 将丢失上次同步AOF文件之后的所有写命令数据

文件同步:在现代操作系统中,当用户调用write函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满,或者超过指定的时限之后,才真正的将缓冲区写入到磁盘中。

优点

  1. AOF在对日志文件写入操作是以追加模式,少了磁盘寻址的开销,写入性能惊人,文件也不容易破损。
  2. 有灵活的同步策略,支持每秒同步、每次修改同步和不同步。
  3. RDB默认五分钟一次生成快照,AOF默认是一秒一次去通过一个后台的线程fsync操作,那最多丢这一秒的数据。

缺点

  1. 相同规模的数据集,AOF要大于RDB,AOF在运行效率上往往会慢于RDB。

4.2.1 AOF重写

AOF重写是生成新AOF文件,并替换旧AOF文件的功能。使用BGREWIRTEAOF,来创建子进程进行AOF重写。但实际上,AOF文件重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作,这个功能是通过读取服务器当前的数据库状态来实现的。它将原来可能保存一个键所需的多个命令减少为一条,来代替之前记录的这个键值对。如果超过常量值64,就会将一条命令转成多条。

步骤:

  1. 发送BGREWIRTEAOF,创建子进程,执行AOF文件重写;
  2. 执行客户端发来的命令过,追加写命令到AOF缓冲区,AOF重写缓冲区;
  3. 完成AOF文件重写,向父进程发送信号;
  4. 接收到子进程信号,将缓冲区追加到AOF文件的末尾;
  5. 用新AOF文件覆盖旧AOF文件。

4.3 RDB与AOF

AOF文件的更新频率通常比RDB文件的更新频率高,所以如果服务器开启AOF,就会优先使用AOF还原;只有在AOF关闭时,才会使用RDB文件还原数据库状态。

5. 缓存

缓存是高并发场景下提高热点数据访问性能的一个有效手段。

5.1 缓存类型

缓存的类型分为:本地缓存、分布式缓存和多级缓存。

本地缓存
本地缓存就是在进程的内存中进行缓存,比如我们的JVM堆中,可以用LRUMap来实现,也可以使用Ehcache这样的工具来实现。

本地缓存是内存访问,没有远程交互开销,性能最好,但是受限于单机容量,一般缓存较小且无法扩展。

分布式缓存
分布式缓存可以很好得解决这个问题。

分布式缓存一般都具有良好的水平扩展能力,对较大数据量的场景也能应付自如。缺点就是需要进行远程请求,性能不如本地缓存。

多级缓存
为了平衡这种情况,实际业务中一般采用多级缓存,本地缓存只保存访问频率最高的部分热点数据,其他的热点数据放在分布式缓存中。

5.2 缓存问题

5.2.1 缓存雪崩

产生的原因是缓存挂掉,所有的请求都直接到数据库。

解决方法:

  1. 在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效;
    setRedis(Key,value,time + Math.random() * 10000);
    
  2. 如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题;
  3. 设置热点数据永远不过期,有更新操作就更新缓存;
  4. 使用快速失败的熔断策略,减少 DB 瞬间压力;
  5. 使用主从模式和集群模式来尽量保证缓存服务的高可用;

5.2.2 缓存击穿

缓存击穿是指一个Key非常热点,在不停的扛着大并发,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库。

解决方法:

  1. 设置热点数据永远不过期;
  2. 使用互斥锁更新,保证同一个进程中针对同一个数据不会并发请求到数据库,减小数据库压力;
  3. 使用随机退避方式,失效时随机sleep一个很短的时间,再次查询,如果失败再执行更新;

5.2.3 缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,数据库的id都是1开始自增上去的,如发起为id值为-1的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。

解决方法:

  1. 在接口层增加参数校验。
  2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null、位置错误、稍后重试这样的值,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击,我们要知道正常用户是不会在单秒内发起这么多次请求的,那网关层Nginx可以对单个IP每秒访问次数超出阈值的IP都拉黑。
  3. 使用布隆过滤器(Bloom Filter),特点是存在性检测,利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在就return,存在你就去查了DB刷新KV再return。

5.3 一致性

最经典的缓存+数据库读写的模式,就是Cache Aside Pattern。

读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
更新的时候,先更新数据库。如果涉及很多其他的逻辑操作,应该删除缓存;如果只是更改缓存中的值,无其他逻辑操作,可以直接更新。

6. 内存淘汰

6.1 失效机制

Redis 的key可以设置过期时间,过期后Redis采用主动和被动结合的失效机制,一种是在定期的主动删除,另一种是访问时触发惰性删除。

最大内存 maxmemory 可以设置内存使用限制为指定的字节数。当达到内存限制时,Redis将根据选择的淘汰机制尝试删除密钥。如果Redis无法根据策略删除密钥,或者策略为设置为’noeviction’,Redis将开始回复命令错误将使用更多的内存,例如SET,LPUSH等,并将继续回复诸如GET之类的只读命令。

  1. 定期删除:默认100s就随机抽一些设置了过期时间的key,去检查是否过期,过期了就删了;
  2. 惰性删除:查询key的时候,判断是否过期,过期就删掉返回空。

6.2 内存淘汰机制

内存淘汰机制 解释
noeviction 不要逐出任何东西,只需在写操作中返回错误。
allkeys-lru 尝试回收最近最少使用的键(LRU),使得新添加的数据有空间存放。
volatile-lru 尝试回收最近最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
allkeys-lfu 尝试回收最少使用的键(LFU),使得新添加的数据有空间存放。
volatile-lfu 尝试回收最少使用的键(LFU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
allkeys-random 回收随机的键,使得新添加的数据有空间存放。
volatile-random 回收随机的键,但仅限于在过期集合的键,使得新添加的数据有空间存放。
volatile-ttl 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

7. 复制

在Redis中,可通过执行SLAVEOF命令或设置slaveof选项,让一个服务器去复制另一个服务器。被复制的称为主服务器,对主服务器进行复制的称为从服务器。

复制功能分为同步(sync)和命令传播(command propagate):

  1. 同步:用于将从服务器的数据库状态更新至主服务器当前所处的服务器状态。
  2. 命令传播:当主服务器的数据库状态被修改,导致主从服务器的数据库状态不一致时,让主从服务器的数据库重新回到一致状态。

7.1 旧版复制

同步

  1. 从服务器连接主服务器,发送SYNC命令;
  2. 主服务器接收到SYNC命名后,开始执行BGSAVE命令,在后台生成RDB文件,并使用缓冲区记录从现在开始执行的所有写命令;
  3. 主服务器BGSAVE执行完后,将生成的RDB文件发送给从服务器,并在发送期间继续记录被执行的写命令;
  4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的RDB文件;
  5. 主服务器在发送RDB文件完毕后,开始向从服务器发送缓冲区中的写命令;
  6. 从服务器完成对RDB文件的载入,并执行来自主服务器缓冲区的写命令。

命令传播
在同步操作执行完毕后,主从服务器的数据库将达到一致状态。但是当主服务器执行客户端发送的写命令时,主从数据库状态又不一致了。所以主服务器需要将写命令发送给从服务器去执行,让主从数据库状态再次回到一致。

缺陷

  1. 从服务器初次复制可以很好完成任务,但对于断线后重新复制,虽然最终能回到一致状态,但是效率很低。

7.2 新版复制

为了解决旧版复制功能来处理断线重复复制情况时的低效问题,Redis使用PSYNC命令来代替SYNC命令来执行复制时的同步操作。

PSYNC命令具有完整重同步(full resynchronization)和部分重同步(patial resynchronization)两种模式:

  1. 完整重同步:用于处理初次同步情况。和SYNC命令执行步骤一样,通过让主服务器创建并发送RDB文件,以及向
    从服务器发送保存在缓冲区里面的写命令来进行同步
  2. 部分重同步:用于处理断线后重复制情况。当从服务器在断线后重新连接主服务器,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前状态。

7.2.1 部分重同步

部分重同步通过复制偏移量,复制积压缓冲区,服务器运行ID三个部分来实现。

7.2.1.1 复制偏移量

主从服务器都分别维护一个复制偏移量,主服务器每次向从服务器传播N个字节的数据,就会在自己的服务偏移量上加N;从服务器每次收到主服务器传播来的N个字节的数据,也会在自己的服务偏移量上加N。

7.2.1.2 复制积压缓冲区

主服务器维护的一个固定长度的先进先出队列,默认为1M,通过repl-backlog-size选项进行修改复制积压缓冲区大小。当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列。

当主服务器进行命令传播时,不仅将写命令发送给所有从服务器,还会将写命令入队到复制积压缓冲区中。主服务器的复制积压缓冲区里面会保存一部分最近传播的写命令,并且会为每个字节记录偏移量。

当从服务器重新连上主服务器,从服务器通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量决定进行何种同步。
如果offset偏移量之后的数据(即offset+1)仍然在复制积压缓冲区中,那么进行部分重同步;否则进行完成重同步。

7.2.1.3 服务器运行ID

每个服务器,无论主从,都有自己的运行ID,在启动时自动生成。

当从服务器对主服务器进行初次复制,主服务器会将自己的运行ID发送给从服务器,从服务器会将这个运行ID保存起来。
当从服务器断线并重新脸上一个主服务器,从服务器将向当前连接的主服务器发送之前保存的运行ID。如果断线前后的主服务器运行ID相同,主服务器继续尝试执行部分重同步;相反,主服务器执行完成重同步。

主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从服务器一致。
而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测。

8. Sentinal

Sentinal(哨兵)是Redis的高可用解决方案:由一个或多个Sentinal实例组成Sentinal系统,通过Raft协议来保证自身的高可用。

Sentinal系统可以监控任意多个主服务器,以及这些主服务器属下的所有从服务器。在被监控的主服务器进入下线状态时,Sentinal系统会选出Sentinal Leader,负责执行故障转移操作,将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

Sentinal选主策略

  1. slave的priority设置的越低,优先级越高;
  2. 同等情况下,slave复制的数据越多优先级越高;
  3. 相同的条件下运行id越小越容易被选中。

哨兵组件的主要功能

  1. 集群监控:负责监控Redis master和slave进程是否正常工作。
  2. 消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
  3. 故障转移:如果master node挂掉了,会自动转移到slave node上。
  4. 配置中心:如果故障转移发生了,通知client客户端新的 master 地址。

9. Cluster

Redis 集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。

集群的整个数据库被分为16384个槽(slot),数据库中的每个键都属于这16384个槽的其中一个,集群中的每个节点可以处理0个或最多16384个槽。

复制与故障转移
Redis集群中的节点分为主节点(Master)和从节点(Slave),其中主节点用于处理槽,而从节点则用于复制某个主节点,并在被复制的主节点下线时,在从节点中通过Raft协议选举新的主节点,代替下线主节点继续处理命令请求。

10. 底层数据结构

10.1 简单动态字符串

Redis没有直接使用C语言传统的字符串标识,而是使用简单动态字符串(simple dynamic string),并将SDS用于默认字符串表示。SDS 还可以作为缓冲区:包括 AOF 模块中的AOF缓冲区以及客户端状态中的输入缓冲区。

struct sdshdr{// 记录buf数组中已使用字节的数量,等于SDS保存字符串的长度int len; // 记录 buf 数组中未使用字节的数量int free; // 字节数组,用于保存字符串char buf[];
}

10.1.1 相比C字符串优势

10.1.1.1 常数复杂度获取字符串长度

C 语言,获取字符串的长度通常是经过遍历计数来实现的,时间复杂度为 O(n);SDS有len 属性,获取 SDS 字符串的长度只需要读取 len 属性。

10.1.1.2 杜绝缓冲区溢出

C 语言中使用 strcat 函数来进行两个字符串的拼接,一旦没有分配足够长度的内存空间,就会造成缓冲区溢出;SDS 数据类型,在进行字符修改的时候,会首先根据记录的 len 属性检查内存空间是否满足需求,如果不满足,会进行相应的空间扩展,然后再进行修改操作。

10.1.1.3 减少修改字符串的内存重新分配次数

C语言由于不记录字符串的长度,所以如果要修改字符串,必须要重新分配内存(先释放再申请),因为如果没有重新分配,字符串长度增大时会造成内存缓冲区溢出,字符串长度减小时会造成内存泄露。

对于SDS,由于len属性和free属性的存在,对于修改字符串SDS实现了空间预分配和惰性空间释放两种策略:

  1. 空间预分配(优化字符串增长):SDS在进行修改,还会为SDS分配额外的未使用空间。当len小于1MB,那么分配和len同样大小的未使用空间;当len大于1MB,那么分配1MB未使用空间。通过空间预分配,Redis可以减少连续执行字符串增长操作所需的内存重分配。
  2. 惰性空间释放(优化字符串缩短):SDS要缩短保存的字符串时,不会立即使用内存重分配回收缩短出来的字节,而是使用free属性将这些字节数量记录下来,并等待将来使用。避免缩短字符串时所需的内存重分配操作,并为将来的增长提供优化。SDS也提供了相应的API,可以手动释放这些未使用的空间。
10.1.1.4 二进制安全

C字符串以空字符作为字符串结束的标识,而对于一些二进制文件(如图片等),内容可能包括空字符串,因此C字符串无法正确存取;SDS 的API 都是以处理二进制的方式来处理 buf 里面的元素,并且 SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。

10.1.1.5 兼容部分 C 字符串函数

SDS 是二进制安全的,但是一样遵从每个字符串都是以空字符串结尾的惯例,这样可以重用 C 语言库<string.h> 中的一部分函数。

10.2 字典

Redis的字典使用哈希表作为底层实现,类似HashMap。

一个哈希表里面可以有多个哈希表节点,而每个哈希节点就保存了字典中的一个键值对。在这里插入图片描述

10.3 跳跃表

跳跃表(SkipList)是基于有序链表的扩展,通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。支持平均O(logN),最坏O(N)复杂度的节点查找,还可以通过顺序性操作来批量处理节点。

Redis使用跳表不用b+树,是因为跳表相比b+树实现简单,占用内存小。

性质

  1. 由很多层结构组成;
  2. 每一层都是一个有序的链表,排列顺序为由高层到底层,都至少包含两个链表节点,分别是前面的head节点和后面的nil节点;
  3. 最底层的链表包含了所有的元素;
  4. 如果一个元素出现在某一层的链表中,那么在该层之下的链表也全都会出现(上一层的元素是当前层的元素的子集);
  5. 链表中的每个节点都包含两个指针,一个指向同一层的下一个链表节点,另一个指向下一层的同一个链表节点;

跳跃表有很多层组成,每层都是链表,并且是有序的,每个节点保存这指向同层下一个节点和指向下一层同一个节点的指针。其中最底层的链表保存了所有的数据,通过分层优化搜索存储在最底层的数据,进行搜索和插入。

  1. 搜索:从最高层的链表节点开始,如果比当前节点要大和比当前层的下一个节点要小,那么则往下找。也就是和下一层的同节点的下一个节点进行比较,以此类推,一直找到最底层的最后一个节点,如果找到则返回,反之则返回空。
  2. 插入:首先确定插入的层数,一种方法是假设抛一枚硬币,如果是正面就累加,直到遇见反面为止,最后记录正面的次数作为插入的层数。当确定插入的层数k后,则需要将新元素插入到从底层到k层。
  3. 删除:在各个层中找到包含指定值的节点,然后将节点从链表中删除即可,如果删除以后只剩下头尾两个节点,则删除这一层。

10.4 整数集合

整数集合(intset)是集合的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合的底层实现。

struct inset{// 编码方式uint32_t encoding;// 集合包含元素数量uint32_t length;// 保存元素的数组int8_t contents[];
}

intset可以保存int16_t、int32_t或int64_t的整数值,并且保证集合中不会出现重复元素(通过二分查找整数判断是否已存在)。

升级
当新元素要添加到整数集合,并且新元素的类型比整数集合现有所有元素的类型要长时,整数集合会先进行升级,然后才能将新元素添加到里面,所以添加元素的时间复杂度为O(N)。

新元素小于所有现有元素时,新元素添加到最开头(索引0);相反,新元素添加到最末尾(索引length-1)。

升级策略可以提升整数集合的灵活性,并且可以尽可能的节约内存;但不支持降级,升级后会一直保持升级状态。

10.5 压缩列表

压缩列表(zipList)是Redis为了节约内存而开发,是由一系列特殊编码的连续内存块组成的顺序型数据结构。当一个列表只包含少量列表项或一个哈希只包含少量键值对,Redis就会使用压缩列表来做列表和哈希的底层实现。

一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值。

10.6 数据类型底层实现

判断对象类型

type key

查看值对象的编码

object encoding key

10.6.1 String

String的编码可以是int,embstr或raw。

  1. int 编码:保存的是可以用 long 类型表示的整数值。
  2. embstr 编码:保存长度小于44字节的字符串(Redis 3.2 版本之前是39字节,之后是44字节)。
  3. raw 编码:保存长度大于44字节的字符串(Redis 3.2 版本之前是39字节,之后是44字节)。

当 int 编码保存的值不再是整数,或大小超过了long的范围时,自动转化为raw。

对于 embstr 编码,由于 Redis 没有对其编写任何的修改程序(embstr 是只读的),在对embstr对象进行修改时,都会先转化为raw再进行修改,因此,只要是修改embstr对象,修改后的对象一定是raw的,无论是否达到了44个字节。

10.6.2 List

List的编码可以是压缩列表,双端链表。

当同时满足下面两个条件时,使用压缩列表编码:

  1. 每个元素长度小于64字节(redis.conf 中的 list-max-ziplist-value 选项);
  2. 列表保存元素个数小于512个(redis.conf 中的 list-max-ziplist-entries 选项)。

不能满足这两个条件的时候使用双端链表编码。

10.6.3 Hash

Hash的编码可以是压缩列表,字典。

当同时满足下面两个条件时,使用压缩列表编码:

  1. 每个元素长度小于64字节;
  2. 列表保存元素个数小于512个(redis.conf 中的 set-max-intset-entries 选项)。

不能满足这两个条件的时候使用字典编码。

10.6.4 Set

Set的编码可以是整数集合,字典。

当同时满足下面两个条件时,使用整数集合编码:

  1. 集合对象中所有元素都是整数;
  2. 集合对象所有元素数量不超过512(redis.conf 中的 set-max-intset-entries 选项)。

不能满足这两个条件的就使用字典编码。

10.6.5 Sorted Set

Sorted Set的编码可以是压缩列表,跳跃表+字典。

当同时满足下面两个条件时,使用压缩列表编码:

  1. 元素长度都小于64字节(redis.conf 中的 zset-max-ziplist-value 选项);
  2. 元素数量小于128(redis.conf 中的 zset-max-ziplist-entries 选项)。

不能满足上面两个条件的使用跳跃表+字典编码。

以上两个条件也可以通过Redis配置文件zset-max-ziplist-entries 选项和 zset-max-ziplist-value 进行修改。

11. 与Memcache区别

Memcache

  1. 使用多线程异步IO的方式,可以合理利用CPU多核的优势,性能非常优秀;
  2. 功能简单,使用内存存储数据;
  3. 对缓存的数据可以设置失效期,过期后的数据会被清除;
  4. 失效的策略采用延迟失效,就是当再次使用数据时检查是否失效;
  5. 当容量存满时,会对缓存中的数据进行剔除,剔除时除了会对过期key进行清理,还会按LRU策略对数据进行剔除。

Memcache限制

  1. key不能超过250个字节;
  2. value不能超过1M字节;
  3. key的最大失效时间是30天;
  4. 只支持K-V结构,不提供持久化和主从同步功能。

Redis支持复杂的数据结构
Redis相比Memcached来说,拥有更多的数据结构,能支持更丰富的数据操作。

Redis原生支持集群模式
在redis 3.x版本中,就能支持Cluster模式,而Memcached没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据。

性能对比
由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起 Remcached,还是稍有逊色。

12. 学习思路

  1. 事前:Redis 高可用,主从+哨兵,Redis cluster,避免全盘崩溃;
  2. 事中:本地ehcache缓存 + Hystrix限流+降级,避免MySQL被打死;
  3. 事后:Redis 持久化RDB+AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据;

数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。只要数据库不死,就是说,对用户来说,3/5的请求都是可以被处理的。 只要有3/5的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。

13. 命令

keys

获取指定模式key列表。由于Redis单线程,如果Key很多,执行keys命令就会阻塞直到完成。

scan

无阻塞获取指定模式的key列表,会有一定的重复概率,需要在客户端做一次去重,整体所花费的时间会比直接用keys指令长。

scan命令仅对返回的元素提供有限保证,因为递增迭代的集合可以在迭代过程中更改。

del

删除命令del是阻塞的。

unlink

异步删除一个key。

flushall/flushdb async

异步删除数据库所有key。

参考:
Redis基础
缓存雪崩、击穿、穿透
Redis哨兵、持久化、主从、手撕LRU
双写一致性、并发竞争、线程模型
Redis常见面试题
Redis的最全知识点
I/O多路复用技术(multiplexing)是什么?
缓存,究竟是淘汰,还是修改?
究竟先操作缓存,还是数据库?
Redis 的主从同步,及两种高可用方式
Redis 教程
Redis 中文官网 redis.conf
漫画:什么是跳跃表?
Redis 设计与实现
Redis数据结构——压缩列表
Redis详解(四)------ redis的底层数据结构
Redis详解(五)------ redis的五大数据类型实现原理

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 代码的搬运工,Java 8新内容整理

    目录一、Java 8 Lambda 表达式1.1 语法1.2 Lambda 表达式实例(常见)二、Java 8 Stream2.1 什么是 Stream?2.2生成流2.3 forEach2.4 map2.5 filter2.6 limit2.7 sorted2.8 并行(parallel)程序2.9 Collectors2.10 统计2.11 其他还有2.12 Stream 综合实例三、Java …...

    2024/5/5 11:48:37
  2. 无法被检测到的Linux恶意软件

    网络安全研究人员今天发现了一种完全无法被检测到的Linux恶意软件,该恶意软件利用未公开的技术来监视并瞄准以流行的云平台(包括AWS,Azure和阿里云)托管的可公开访问的Docker服务器。 Docker是一种流行的针对Linux和Windows的平台即服务(PaaS)解决方案,旨在使开发人员更…...

    2024/5/5 9:21:06
  3. 中国信通院:2020年云计算发展白皮书

    中国信通院云计算与大数据研究所副所长栗蔚在会上正式发布并解读白皮书,总结出的2020年云计算发展六大关键词,以及六大关键词背后的重要趋势。 白皮书指出:未来,云计算仍将迎来下一个黄金十年,进入普惠发展期。一是随着新基建的推进,云计算将加快应用落地进程,在互联网、…...

    2024/5/5 4:18:31
  4. CSS样式小结

    CSS样式小结(不定期更新) 首行缩进:em-字符单位 text-indent:20px; text-indent:2em;阴影: *20px:水平阴影的位置 *10px:垂直阴影的位置 8px:模糊距离 5px:阴影的尺寸 outset/inset:外阴影/内阴影 box-shadow: 20px 10px 8px 5px #888888 inset;文字超出盒子长度,后面显…...

    2024/5/5 17:35:09
  5. 树生成器V2

    树生成器V2示例HTMLCSSJS 更多有趣示例 尽在小红砖社区 示例HTML <div id="controls"><button id="generate" class="btn btn-secondary" onclick="generateTree()">New Tree</button><br><br><butt…...

    2024/5/5 20:54:13
  6. LeetCode 题解 - 01.Two Sum

    Leetcode 第 01. Two Sum 题,题目难度 Easy。 一. 题目要求 Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same …...

    2024/5/6 1:23:52
  7. 关于锁的总结,不是很深入,以后再细化吧

    Synchronized原理:作用:是一个独占锁,用来实现线程同步。 作用对象:主要修饰静态方法、非静态方法、代码块; 如何实现:即实现java的monitor机制,当Synchronized修饰代码块时,会在代码块的开始和结束位置插入monitorentry和monitorexit指令。如果修饰方法,会在flag标志…...

    2024/5/6 20:23:46
  8. vnc的使用方法,5步掌握vnc批量管理功能的使用方法

    vnc的使用方法不知道大家找到过没有,毕竟在网上这种教程是很少的,因为使用的人都是一些经常使用的,但是对于小编这种基础能力差的,还是需要vnc的使用方法教程的,所以小编也是努力了很久才弄明白,接下来就给大家介绍vnc的使用方法吧。 IIS7服务器管理工具能让你轻松控制远…...

    2024/5/6 19:58:38
  9. STM32三轮全向底盘

    STM32三轮全向底盘 最近在实验室培训,玩过麦克纳姆四轮底盘后,玩三轮全向底盘也有一段时间了,于是来分享一下自己的心得。 附图 这是去年参加robocon的底盘,三个大疆3508电机,一个全场定位模块,一个实验室焊的遥控器[^1]: (怕出问题所以没用DEVO10)。 1.底盘公式 三轮全…...

    2024/5/6 20:20:51
  10. 【openVINO】windows10下openvino_toolkit版本的推理机兼容问题

    【openVINO】windows10下openvino_toolkit版本的推理机兼容问题1.背景2.对比2019.3.379版本与2020.3.194版本3.对比2020.3.194版本与2020.4.287版本4.总结 1.背景 目前openvino_toolkit已经快速更新迭代了很多版本,intel这个节奏是真快,如下图,目前已经更新到2020.4 本博客的…...

    2024/5/5 19:52:29
  11. 运营商的利润来自定时关闭基站?物联网设备如何长连接?

    为什么关基站?进入5G时代以来,设想中的那些美好场景还没出现,但一个意想不到的窘境却最先爆发——运营商被昂贵的5G基站的电费压得喘不过气。 近日,中国联通结合5G用户分布和终端使用状况,分别对已经入网的3种不同基站射频单元设备(AAU),分不同时段定时开启空载状态下的…...

    2024/5/5 13:45:41
  12. Pytorch资源学习列表

    网站 英文版官方手册:https://pytorch.org/tutorials/ PyTorch官方教程中文版: http://pytorch123.com/ PyTorch中文文档:https://pytorch-cn.readthedocs.io/zh/latest/ fendouai/pytorch1.0-cn:https://github.com/fendouai/pytorch1.0-cn 书籍 《Deep Learning with PyTo…...

    2024/5/6 1:03:00
  13. 如何跟女孩聊天?这样跟心仪的女孩聊天才更有效

    当你面对心仪的女孩,你很想开口,把自己内心的真实情感吐露出来,但是又害怕讲太多了,女生会逃离自己。今天给大家几个聊天惯例,一起来看看如何跟女孩聊天?1、释放聊天情绪张力和性张力几乎所有的枯燥乏味的聊天,都缺乏一个叫做“张力”的东西,而这样的聊天的主人,往往是…...

    2024/5/5 17:39:20
  14. 一篇文章给你把布隆过滤器的讲的明明白白

    不知道从什么时候开始,本来默默无闻的布隆过滤器一下子名声大燥,在面试中面试官问到怎么避免缓存穿透,你的第一反应可能就是布隆过滤器,缓存穿透=布隆过滤器成了标配,但具体什么是布隆过滤器,怎么使用布隆过滤器不是很清楚,那今天我们就来把它说清楚,讲明白。。缓存穿透…...

    2024/5/7 0:48:51
  15. 在VMware中安装android-x86-9.0-r2

    android x86(https://www.android-x86.org/) 是一个自由而开源的项目,将谷歌制作的安卓系统从ARM架构移植到x86架构,可以让用户在他们的桌面电脑上运行安卓系统来享受所有的安卓功能和应用程序及游戏。 -- M.hanny Sabbagh(作者)2019-11-15,android x86项目发布了pie-x8…...

    2024/5/7 4:21:33
  16. 一位小姑娘要下沉项目,是孤芳自赏,还是敞开胸怀?

    文 / 王不留(微信公众号:程序员生存指南)公司新中标一个头号软件集成系统工程,需要赶在11月底全网上线。从8月初正式启动,目前已投入30人。作为集团级项目,系统建设的工程浩大,架构复杂,涉及众多厂家的联调,对系统并发性要求极高。由于项目经理是从技术直接转入管理,…...

    2024/5/6 20:52:45
  17. Http协议及Https协议及特性的简单描述

    引入(摘自百度百科) 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的…...

    2024/5/5 16:04:01
  18. Windows中隨身碟無法格式化的解決辦法

    有時,當我們需要對USB隨身碟進行格式化時,卻被提「Windows無法完成格式化」。 那USB隨身碟無法格式化應該怎麼辦呢?,閱讀本文,快速了解USB隨身碟無法格式化的問題!隨身碟無法格式化的原因隨身碟無法格式化的可能原因:1. 隨身碟資料的損壞2. 作業系統與隨身碟不相容或讀寫…...

    2024/5/5 12:26:43
  19. 学习笔记(5):IDEA开发工具+Maven使用详解视频课程(适合初学者的教程)-在IDE中使用Maven

    立即学习:https://edu.csdn.net/course/play/7907/162054?utm_source=blogtoedu五、在IDE中使用Maven1. IDE工具 MyEclipse集成Maven插件 EclipseEclipse For Java EE IDEA集成maven插件2. MyEclipse2.1 配置maveninstallationsUser Settings2.2 创建maven项目new——>…...

    2024/5/7 4:13:50
  20. HTML内容知识详解!

    HTML介绍Web服务本质 import socketsk = socket.socket()sk.bind(("127.0.0.1", 8080)) sk.listen(5)while True:conn, addr = sk.accept()data = conn.recv(8096)conn.send(b"HTTP/1.1 200 OK\r\n\r\n")conn.send(b"<h1>Hello world!</h1&g…...

    2024/5/7 3:09:59

最新文章

  1. Autoxjs 实践-Spring Boot 集成 WebSocket

    概述 最近弄了福袋工具&#xff0c;由于工具运行中&#xff0c;不好查看福袋结果&#xff0c;所以我想将福袋工具运行数据返回到后台&#xff0c;做数据统计、之后工具会越来越多&#xff0c;就弄了个后台&#xff0c;方便管理。 实现效果 WebSocket&#xff1f; websocket是…...

    2024/5/9 4:51:28
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. 【php快速上手(四)】

    目录 PHP快速上手&#xff08;四&#xff09;PHP 类型比较1.松散比较&#xff08;Loose Comparison&#xff09;2.严格比较&#xff08;Strict Comparison&#xff09;3.类型转换 PHP 常量PHP字符串函数1. 字符串长度和截取2. 字符串查找和替换3. 字符串转换和格式化4. 字符串分…...

    2024/5/1 9:38:40
  4. windows更新驱动导致Linux虚拟机网卡找不到

    windows更新驱动导致Linux虚拟机网卡找不到 1、现象2、解决过程3、参考 1、现象 原先虚拟机配置了静态IP&#xff0c;更新windows驱动后xshell连接不上这台虚拟机&#xff08;其他几台也是&#xff09;。 2、解决过程 service network restart出现一下报错&#xff1a; Rest…...

    2024/5/7 21:24:52
  5. 招投标系统简介 企业电子招投标采购系统源码之电子招投标系统 —降低企业采购成本

    功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…...

    2024/5/7 14:12:08
  6. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/8 19:32:33
  7. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/7 22:31:36
  8. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/9 2:44:26
  9. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/8 20:33:13
  10. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/9 3:15:57
  11. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/7 16:57:02
  12. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/7 14:58:59
  13. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/8 20:58:56
  14. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/9 1:35:21
  15. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/9 4:12:16
  16. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/7 16:05:05
  17. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/8 18:06:50
  18. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/8 1:37:32
  19. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/9 1:42:21
  20. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/8 1:37:31
  21. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/9 4:31:45
  22. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/8 12:44:41
  23. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/8 9:51:44
  24. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/8 1:37:29
  25. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/9 4:33:29
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57