redis主从复制【面试必看】

在分布式系统中,希望使用多个服务器来部署redis,存在以下几种redis的部署方式

  1. 主从模式
  2. 主从+哨兵
  3. 集群模式

主从模式

在若干个redis节点中,有的是主节点,有的是从节点

假设有三个物理服务器(称为是三个节点)

分别部署了一个redis-server进程,此时就可以把其中的一个节点作为主节点,另外两个作为从节点,从节点的数据跟随主节点变化,从节点的数据要和主节点保持一致,如果改了从节点的数据,不可以把从节点的数据同步到主节点中

如果从节点挂了,没有什么影响,但如果是主节点挂了,有一定影响,因为从节点只能读取数据,如果要写数据就没有节点可以写了,如果我们设置多个主节点的话,数据同步会比较麻烦

操作

正常来说,每个redis服务器程序,应该是在一个单独的主机上,由于我没有多个服务器,我就在一个服务器运行多个redis-server进程,此时需要保证多个redis-server端口是不同的

redis启动时指定启动端口的方法:

  1. 启动的时候,通过命令行来指定端口,- -port选项
  2. 直接在配置文件中,设定端口

我们把/etc/redis/redis.conf拷贝到一个目录下,然后对这两个配置文件进行修改

在这里插入图片描述

把slave1.conf中的port改为6380,daemonize改为yes(后台运行),slave2.conf中的port改为6381,daemonize改为yes

启动redis

在这里插入图片描述

使用redis-cli -p 6380,redis-cli -p 6381还有redis-cli启动三个redis,这个时候在主节点(6379)端口set key 111,6380端口的redis并不能看到,所以这个时候还没有达成主从复制

建立复制

想要达成主从复制有三种方式:

  1. 在配置⽂件中加⼊ slaveof {masterHost} {masterPort} 随 Redis 启动⽣效。→永久生效
  2. 在 redis-server 启动命令时加⼊ --slaveof {masterHost} {masterPort} ⽣效。
  3. 直接使⽤ redis 命令(在客户端中):slaveof {masterHost} {masterPort} ⽣效。→重启后就按照配置文件中的方案走

这里我们采用第一种方案:vim salve1.conf和vim salve2.conf,在最后面添加,这里以6379为主节点

在这里插入图片描述

这时候重新启动三个redis服务器才可以完成主从复制,通过 redis-cli 可以连接主 Redis 实例,通过 redis-cli -p 6380 连接从 Redis。并且观察复制关系。

127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> get hello
"world"
127.0.0.1:6380> get hello
"world"

从运⾏结果中看到复制已经⼯作了,针对主节点 6379 的任何修改都可以同步到从节点 6380 中,复制过程如图所示。

使用netstat -anp | grep redis-server查看redis进程

在这里插入图片描述

又上图可知,其实主从复制就是主节点和从节点创建TCP连接

1)主节点6379复制状态信息,用info replication查看

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=100,lag=0
master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:100
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:100

2)从节点 6380 复制状态信息

127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:170
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:170
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:170

这里介绍几个选项的含义:

  1. offset:相当于是从节点和主节点之间,同步数据的进度,因为主节点上会收到源源不断的"修改数据”请求,从节点就需要从主节点这里同步这些修改请求,从节点和主节点之问的数据同步,不是瞬问完成的!!
  2. lag:延迟
  3. master_replid:主节点的身份标识
  4. master_replid2:如果master节点宕机了,slave节点成功切换为master后,会将之前master_replid记录的值存储到master_replid2中,自己生成一个新的随机字符,作为自己的master标识,存储在master_replid中
  5. master_repl_offset:主节点数据修改了多少
  6. repl_backlog_active/repl_backlog_size/repl_backlog_first_byte_offset/repl_backlog_histlen:积压缓冲区,支持部分同步机制的实现
  7. slave_priority:主节点挂了,选择从节点作为主节点的优先级
  8. slave_read_only:从节点是否只读
  9. connected_slaves:从节点下面也可以再有从节点,也可以用从节点去同步从节点

关于master_replid和master_replid2可以看这篇文章:replication中的两个master_replid

断开复制

slaveof 命令不但可以建⽴复制,还可以在从节点执⾏ slaveof no one(在客户端中输入)来断开与主节点复制关系。
例如在 6380 节点上执⾏ slaveof no one 来断开复制。
断开复制主要流程:
1)断开与主节点复制关系。
2)从节点晋升为主节点。
从节点断开复制后并不会抛弃原有数据,只是⽆法再获取主节点上的数据变化。

通过 slaveof 命令还可以实现切主操作,将当前从节点的数据源切换到另⼀个主节点。执⾏
slaveof {newMasterIp} {newMasterPort} 命令即可。
切主操作主要流程:
1)断开与旧主节点复制关系。
2)与新主节点建⽴复制关系。
3)删除从节点当前所有数据。
4)从新主节点进⾏复制操作。

安全性

对于数据⽐较重要的节点,主节点会通过设置 requirepass 参数进⾏密码验证,这时所有的客户
端访问必须使⽤ auth 命令实⾏校验。从节点与主节点的复制连接是通过⼀个特殊标识的客户端来完
成,因此需要配置从节点的masterauth 参数与主节点密码保持⼀致,这样从节点才可以正确地连接到主节点并发起复制流程。

只读

默认情况下,从节点使⽤ slave-read-only=yes 配置为只读模式。**由于复制只能从主节点到从节
点,对于从节点的任何修改主节点都⽆法感知,修改从节点会造成主从数据不⼀致。**所以建议线上不
要修改从节点的只读模式。

传输延迟

主节点和从节点之间通过网络来传输(TCP),TCP内部支持了nagle算法(默认开启)

开启:会增加tcp的传输延迟,节省了网络带宽

关闭:会减少网络延迟,增加了网络带宽

这个nagle算法和捎带应答目的是一样的,针对较小的数据包进行合并,减少了包的个数

redis中repl-disable-tcp-nodelay选项用于在主从同步通信过程中,关闭tcp 的nagle 算法,从节点更快速的和主节点进行同步

拓扑结构

一主一从结构

⼀主⼀从结构是最简单的复制拓扑结构,⽤于主节点出现宕机时从节点提供故障转移⽀持,如图
所示。当应⽤写命令并发量较⾼且需要持久化时,可以只在从节点上开启 AOF,这样既可以保证数据安全性同时也避免了持久化对主节点的性能⼲扰。但需要注意的是,当主节点关闭持久化功能时,如果主节点宕机要避免⾃动重启操作。(如果自动重启,此时没有AOF文件,就会丢失数据,进一步的主从同步,会把从节点的数据也删除掉)

在这里插入图片描述

一主多从

⼀主多从结构(星形结构)使得应⽤端可以利⽤多个从节点实现读写分离。对于读⽐重较⼤的场景,可以把读命令负载均衡到不同的从节点上来分担压⼒。同时⼀些耗时的读命令可以指定⼀台专⻔的从节点执⾏,避免破坏整体的稳定性。对于写并发量较⾼的场景,多个从节点会导致主节点写命令的多次发送从⽽加重主节点的负载。(主节点上数据的修改,就会把改变的数据同步到从节点)

在这里插入图片描述

树形主从结构

树形主从结构(分层结构)使得从节点不但可以复制主节点数据,同时可以作为其他从节点的主
节点继续向下层复制。通过引⼊复制中间层,可以有效降低住系欸按负载和需要传送给从节点的数据
量数据写⼊节点 A 之后会同步给 B 和 C 节点,B 节点进⼀步把数据同步给 D 和 E 节点。当主节点需要挂载等多个从节点时为了避免对主节点的性能⼲扰,可以采⽤这种拓扑结构。

在这里插入图片描述

原理

如图所示,下⾯详细介绍建⽴复制的完整流程。从图中可以看出复制过程⼤致分为 6 个过程:
主从节点建⽴复制流程图

在这里插入图片描述

1)保存主节点(master)的信息。

开始配置主从同步关系之后,从节点只保存主节点的地址信息,此时建⽴复制流程还没有开始,

在从节点 6380 执⾏ info replication 可以看到如下信息:

master_host: 127.0.0.1
master_port: 6379
master_link_status: down

从统计信息可以看出,主节点的 ip 和 port 被保存下来,但是主节点的连接状态(master_link_status)是下线状态。

2)从节点(slave)内部通过每秒运⾏的定时任务维护复制相关逻辑,当定时任务发现存在新的主节

点后,会尝试与主节点建⽴基于 TCP 的⽹络连接。如果从节点⽆法建⽴连接,定时任务会⽆限重试直到连接成功或者⽤户停⽌主从复制。(TCP三次握手验证通信双方是否能正确读取数据,系统层面)

3)发送 ping 命令。连接建⽴成功之后,从节点通过 ping 命令确认主节点在应⽤层上是⼯作良好的。如果 ping 命令的结果 pong 回复超时,从节点会断开 TCP 连接,等待定时任务下次重新建⽴连接。

4)权限验证。如果主节点设置了 requirepass 参数,则需要密码验证,从节点通过配置 masterauth

参数来设置密码。如果验证失败,则从节点的复制将会停⽌。

5)同步数据集。对于⾸次建⽴复制的场景,主节点会把当前持有的所有数据全部发送给从节点,这步操作基本是耗时最⻓的,所以⼜划分称两种情况:全量同步和部分同步,下⼀节重点介绍。

6)命令持续复制。当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点执⾏修改命令,保证主从数据的⼀致性。

数据同步

Redis 使⽤ psync 命令完成主从数据同步,同步过程分为:全量复制和部分复制。

  • 全量复制:⼀般⽤于初次复制场景,Redis 早期⽀持的复制功能只有全量复制,它会把主节点全部数据⼀次性发送给从节点,当数据量较⼤时,会对主从节点和⽹络造成很⼤的开销。
  • 部分复制:⽤于处理在主从复制中因⽹络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发数据给从节点。因为补发的数据远⼩于全量数据,可以有效避免全量复制的过⾼开销。
  • 实时复制:从节点,已经和主节点,同步好了数据了(从节点这一时刻已经和主节点数据一致了)但是之后,主节点这边会源源不断的收到新的修改数据的请求,主节点上的数据就会随之改变,也需要能够同步给从节点

从节点使⽤ psync 命令完成部分复制和全量复制功能,命令格式:psync {replicationId} {offset},参数含义:replicationId 是从节点所复制的主节点的运⾏ ID、offset 是当前从节点已复制的数据偏移量。

全量复制

在这里插入图片描述

1)从节点发送 psync 命令给主节点,replicationId 和 offset 的默认值分别是 ? 和 -1。
2)主节点根据 psync 参数和⾃⾝数据情况决定响应结果:

  • 如果回复 +FULLRESYNC replicationId offset,则从节点需要进⾏全量复制流程。
  • 如果回复 +CONTINEU,从节点进⾏部分复制流程。
  • 如果回复 -ERR,说明 Redis 主节点版本过低,不⽀持 psync 命令。从节点可以使⽤ sync 命令进⾏全量复制。

psync 并不需要咱们⼿动执⾏,Redis 会在主从复制模式下⾃动调⽤执⾏。

在这里插入图片描述

1)从节点发送 psync 命令给主节点进⾏数据同步,由于是第⼀次进⾏复制,从节点没有主节点的运⾏ ID 和复制偏移量,所以发送 psync ? -1。
2)主节点根据命令,解析出要进⾏全量复制,回复 +FULLRESYNC 响应。
3)从节点接收主节点的运⾏信息进⾏保存。
4)主节点执⾏ bgsave 进⾏ RDB ⽂件的持久化。
5)主节点发送 RDB ⽂件给从节点,从节点保存 RDB 数据到本地。
6)主节点将从⽣成 RDB 到接收完成期间执⾏的写命令,写⼊缓冲区中,等从节点加载完 RDB ⽂件后,主节点再将缓冲区内的数据补发给从节点,保持主从⼀致性。
7)从节点清空⾃⾝原有旧数据。
8)从节点加载 RDB ⽂件得到与主节点⼀致的数据。
9)如果从节点加载 RDB 完成之后,并且开启了 AOF 持久化功能,它会进⾏ bgrewrite 操作,得到最近的 AOF ⽂件。

由于当前收到的是大批量的数据,此时产生的 aof 日志,整体来说,可能会存在一定的冗余信息,因此针对 aof 日志进行整理,也是必要的过程

Redis Bgrewriteaof 命令用于异步执行一个 AOF(AppendOnly File) 文件重写操作。重写会创建一个当前 AOF 文件的体积优化版本。
即使 Bgrewriteaof 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 Bgrewriteaof 成功之前不会被修改。

无硬盘模式:主节点生成的rdb二进制数据,不直接保存到文件中了,而是直接进行网络传输(节省了一系列的读硬盘和写硬盘的操作),从节点,直接把收到的数据进行加载

部分复制

部分复制主要是 Redis 针对全量复制的过⾼开销做出的⼀种优化措施,使⽤ psync replicationId offset 命令实现。当从节点正在复制主节点时,如果出现⽹络闪断或者命令丢失等异常情况时,从节点会向主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区存在数据则直接发送给从节点,这样就可以保持主从节点复制的⼀致性。补发的这部分数据⼀般远远⼩于全量数据,所以开销很⼩。整体流程如图所示。

在这里插入图片描述

1)当主从节点之间出现⽹络中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并终端 复制连接。
2)主从连接中断期间主节点依然响应命令,但这些复制命令都因⽹络中断⽆法及时发送给从节点,所以暂时将这些命令滞留在复制积压缓冲区中。
3)当主从节点⽹络恢复后,从节点再次连上主节点。
4)从节点将之前保存的replicationId 和 复制偏移量作为 psync 的参数发送给主节点,请求进⾏部分复制。
5)主节点接到 psync 请求后,进⾏必要的验证。随后根据 offset 去复制积压缓冲区查找合适的数据,并响应 +CONTINUE 给从节点。
6)主节点将需要从节点同步的数据发送给从节点,最终完成⼀致性。

积压缓冲区:

在这里插入图片描述

就是一个内存中的简单的队列,会记录最近一段时间修改的数据,总量有限,随着时间的推移,就会把之前的,旧的数据逐渐删掉。

replicationid 其实就是在描述"数据的来源",offset 描述"数据的复制的进度"
如果 replicationld 不一样,需要全量复制一下。
如果 replicationld 一样,offset 再判定。
offset 表示 从节点之前同步数据的进度是如何,主节点就看这个进度是否在当前的积压缓冲区之内
如果确实是在积压缓冲区之内,此时就可以直接进行部分复制,就只把最近这段时间的数据给复制过去即可,如果当前从节点的进度已经超出积压缓冲区的范围了,需要全量复制。

实时复制

从节点和主节点之间会建立 TCP 的长连接,然后主节点把自己收到的修改数据的请求,通过上述 连接,发给从节点从节点再根据这些修改请求,修改内存中的数据,这个过程也需要时间,正常来说延迟比较小,主从节点在建⽴复制连接后,它们之间需要维护⻓连接并彼此发送⼼跳命令。

1)主从节点彼此都有⼼跳检测机制,各⾃模拟成对⽅的客户端进⾏通信。
2)主节点默认每隔 10 秒对从节点发送 ping命令,判断从节点的存活性和连接状态。
3)从节点默认每隔 1 秒向主节点发送 replconf ack {offset} 命令,给主节点上报⾃⾝当前的复制偏移量。
如果主节点发现从节点通信延迟超过 repl-timeout 配置的值(默认 60 秒),则判定从节点下线,断开复制客户端连接。从节点恢复连接后,⼼跳机制继续进⾏

replication id/runid

多数资料对这两个的区分有所问题,一个redis服务器上,replication id和run id都是存在的

主节点:info replication

在这里插入图片描述

info server

在这里插入图片描述

从节点:info replication

在这里插入图片描述

info server

在这里插入图片描述

官方文档中psync replicationid offset而不是runid

runid主要是用在支持实现redis哨兵的功能的

主从复制总结

主从复制的特点:

  1. Redis 通过复制功能实现主节点的多个副本。
  2. 主节点⽤来写, 从节点⽤来读. 这样做可以降低主节点的访问压⼒.
  3. 复制⽀持多种拓扑结构,可以在适当的场景选择合适的拓扑结构。
  4. 复制分为全量复制和部分复制。
  5. 主从节点之间通过⼼跳机制保证主从节点通信正常和数据⼀致性。

主从复制的缺点:

  1. 从机多了, 复制数据的延时⾮常明显.
  2. 主机挂了, 从机不会升级成主机. 只能通过⼈⼯⼲预的⽅式恢复.

redis主节点无法重启

从节点和主节点断开连接有两种情况:

  1. 从节点主动和主节点断开连接:slaveof no one,这个时候从节点晋升为主节点
  2. 主节点挂了:从节点不会晋升为主节点,必须通过人工干预的方法,恢复主节点

这里有aof文件,这个文件是redis服务器重启的时候,需要加载的

在这里插入图片描述

在上文介绍中,我们三个redis服务器共用的是一个aof文件,这是错误的从节点是通过手动启动的方式运行的。 此时 root 用户下启动redis 服务器,于是生成的 aof 文件也就是root用户的文件。

通过service redis-server start启动的redis服务器,是通过redis这样的用户来启动的,redis server 需要按照可读可写的方式打开这个 aof 文件,而这个文件对于 root 之外的用户只有读权限,因此 service redis-server start 启动的redis 服务器无法打开这个文件,就启动失败了。

解决方法:

  1. 把三个不同的redis服务器生成的文件区分开
  2. 把三个redis服务器的工作目录区分开(修改配置文件中的dir选项)

这里采用第二种方案演示:

  1. 停止所有redis服务器
  2. 删除之前工作目录下已经生成的aof文件,或者chown更改权限

在这里插入图片描述

  1. 给从节点创建出新的目录,用来作为从节点的工作目录

在这里插入图片描述

vim slave1.conf和slave2.conf修改dir选项为/root/redis-conf

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

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

相关文章

(JSP)EL——优化登录界面,获取对象,获取数据

EL优化登录界面 <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <% String path request.getContextPath(); String basePath request.getScheme()"://"request.getServerName()":"reques…

生产工序(oj题)

很有趣的一道题 关键在于固定工序的整合 看样例是固定工序中间是不能插入其他工序的&#xff08;也不讲清楚&#xff09;&#xff0c;如果可以的话&#xff0c;只能说可能会更麻烦 注意固定工序是按照固定工序中的第一个工序进行排序的 整合完之后&#xff0c;就是递归列出…

Java中的IO流①——IO流的体系、字节流、try...catch异常处理

概述 IO流的分类 IO流的体系 这四个类都是抽象类&#xff0c;所以需要实现类对象才能使用---> 字节流 FileInputStream--> 书写细节 代码示范 此时文件a.txt内容为abcde 使用char强转和read方法调用五次read方法--> public static void main(String[] args) throws IO…

初出茅庐的小李博客之TobudOS移植到EVB_AIoT开发板

本博客参考教程&#xff1a; https://atomgit.com/OpenAtomFoundation/TobudOS/blob/master/doc/TobudOS_EVB_AIoT_STM32_Guide.md 介绍一下EVB_AIoT开发板 这个开发板是由TobudOS开源社区联合意法半导体、南京厚德物联网设计的一款高性能IoT开发平台&#xff0c;主控芯片是S…

SystemVerilog学习(0)——目录与传送门

一、验证导论 SystemVerilog学习&#xff08;1&#xff09;——验证导论-CSDN博客文章浏览阅读403次。SystemVerilog自学&#xff0c;验证系统概述&#xff0c;什么是SVhttps://blog.csdn.net/apple_53311083/article/details/133953016 二、数据类型 SystemVerilog学习&…

@FunctionalInterface、Lambda表达式和方法引用

知识不回顾是会被遗忘的&#xff01; 网上看了一些相关文章&#xff0c;这里记录一下&#xff0c;仅供参考 Java语言从JDK1.8开始引入了函数式编程。 函数式编程的核心特点是&#xff0c;函数作为一段功能代码&#xff0c;可以像变量一样进行引用和传递&#xff0c;以便在有需…

stm32 使用18B20 测试温度

用18b20 测试温度是非常常用的&#xff0c;不过18B20的调试不是这么容易的&#xff0c;有些内容网上很多的&#xff0c;不再重复说了&#xff0c;我先把波形说一下&#xff0c;再说程序部分&#xff1a; 整个都温度数据的顺序是&#xff1a; 1.700uS的低电平复位并测试18B20的…

mfc110u.dll丢失的解决方法,mfc110u.dll丢失原因是什么?

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“mfc110u.dll文件丢失”。那么&#xff0c;mfc110u.dll是什么&#xff1f;为什么会出现丢失的情况呢&#xff1f;本文将为您详细介绍mfc110u.dll文件的含义、丢失原因以及解决方法。 首先&…

MyBatis进阶之结果集映射注解版

文章目录 注解实现结果集映射注解实现关系映射常用功能注解汇总 注解实现结果集映射 注意 配置结果集映射&#xff0c;只用看 SQL 执行结果&#xff0c;不看 SQL 语句&#xff01; 注意 由于注解在映射结果集上没有实现 <resultMap> 的 100% 功能&#xff0c;因此&#x…

【车载开发系列】Visio工具使用小技巧

【车载开发系列】Visio工具使用小技巧 【车载开发系列】Visio工具使用小技巧 【车载开发系列】Visio工具使用小技巧一. Word中编辑Visio技巧二. Word中插入visio图形的问题三. 总结 一. Word中编辑Visio技巧 本节主要介绍了Microsoft Word中编辑Visio图形的具体方法。 在 Word…

单臂路由与三层交换机

单臂路由 划分VLAN后同一VLAN的计算机属于同一个广播域&#xff0c;同一VLAN的计算机之间的通信是不成问题的。然而&#xff0c;处于不同VLAN的计算机即使是在同一交换机上&#xff0c;它们之间的通信也必须使用路由器。 图&#xff08;a&#xff09;是一种实现VLAN间路由的方…

电脑中环境变量的设置方法

环境变量是在操作系统中一个具有特定名字的对象&#xff0c;它包含了一个或者多个应用程序所将使用到的信息。例如Windows和DOS操作系统中的path环境变量&#xff0c;当要求系统运行一个程序而没有告诉它程序所在的完整路径时&#xff0c;系统除了在当前目录下面寻找此程序外&a…

从赋码、防窜到私域营销,爱创科技助力西卡德高驶入发展快车道

在家居建材行业&#xff0c;西卡德高是一个绕不开的品牌。在瓷砖胶、美缝剂、防水等领域&#xff0c;西卡德高甚至一度成为这些细分产品的代名词。西卡德高的销售渠道以零售为主&#xff0c;其80%的产品是通过全国3000多个经销商、3000多家专卖店、4000多个装修师傅社群以及近2…

class_2:Java概念 java se ee me jdk jre jvm

一、什么是Java&#xff1f; Java是一门面向对象的编程语言&#xff0c;不仅吸收了C语言的各种优点&#xff0c;还摒弃了C里难以理解的多继承、指针等概念&#xff0c;因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表&#xff0c;极好地…

JDK 9 模块化系统 (Module System) 和 多版本兼容 Jar (Multi-Release Jar)

博文目录 文章目录 Module System原因JDK 模块化模块描述文件关键字 启用模块化测试结论 Multi-Release jar (MRJAR)原因原理结论用 IDEA 创建多版本兼容 Jar项目结构pom.xml测试 Module System 原因 Java 9引入了模块化系统的主要原因是为了解决Java平台面临的复杂性和可维…

C++中STL的容器vector

文章目录 什么是vectorvector与普通顺序表不同的点 vector的成员函数operatoroperator[]begin与end与iteratorsize()capacityresizeemptyreservepush_backpop_backinserteraseswapclear成员变量 总结 什么是vector vector&#xff1a;是数据结构里面的顺序表&#xff0c;开辟一…

【LeetCode刷题】数组篇2

&#x1f387;数组中等题Part &#x1f308; 开启LeetCode刷题之旅 &#x1f308; 文章目录 &#x1f387;数组中等题Part&#x1f370;229.多数元素II&#x1f451;思路分析1.哈希表法2.摩尔投票法(进阶) &#x1f370;15.三数之和&#x1f451;思路分析1.排序双指针 &#x…

音乐曲谱软件Guitar Pro 8.1.1 破解版下载和网盘补丁

Guitar Pro 8.1.1 for Mac 中文破解版是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xff0c;重现喜爱的歌曲或陪伴自己。可以帮助我们进行吉他的学习、绘谱与创作&#xff0c;它包含了几乎所有的吉他现有指法及音色&#xff0c;在做弹拨…

角谷定理 C语言xdoj32

角谷定理定义如下&#xff1a; 对于一个大于1的整数n&#xff0c;如果n是偶数&#xff0c;则n n / 2。如果n是奇数&#xff0c;则n 3 * n 1&#xff0c;反复操作后&#xff0c;n一定为1。 例如输入22的变化过程&#xff1a; 22 ->11 -> 34 -> 17 -> 52 -> 26 …

电源小白入门学习3——电源系统常见元件选型MOS管、二极管、电感篇

电源小白入门学习3——电源系统常见元件选型MOS管、二极管、电感篇 MOS管二极管电感 书接上文&#xff0c;上一期我们讲了电阻、电容选型中需要注意的事项&#xff0c;下面我们接着来介绍MOS管和二极管。 MOS管 关于MOS管的基本原理和内部的一些结构&#xff0c;PN结、半导体的…