Redis学习汇总

news2024/10/5 20:28:33

目录

1.Linux环境下安装redis

2.redis的数据结构及命令

3.redis.conf配置文件常用配置

3.redis的事务操作

4.redis实现乐观锁

5.通过jedis操作redis

6.Springboot集成redis

7.自定义一个RedisTemplate

8.持久化策略 RDB和AOF

9.redis集群环境搭建

10.哨兵模式

11.缓存击穿,缓存穿透,缓存雪崩


1.Linux环境下安装redis

1. redis是由c语言写的,首先安装环境

yum install -y gcc-c++

2. 官网下载tar压缩包

官网下载

官网下载

3. 解压

tar -zxvf redis-6.2.7.tar.gz

4. 进入解压目录,进行编译和安装

make             编译
make install     安装

5. 启动redis服务器

redis-server redis.conf

6. 启动redis客户端

redis-cli -h 127.0.0.1 -p 6379  //举个例子

7. 设置密码

config set requirepass "123456"    可以在配置文件中设置,也可以通过这个命令设置
config get requirepass                   获取密码

8. 设置密码后登录

redis-cli -h 127.0.0.1 -p 6379  //举个例子
auth 123456

2.redis的数据结构及命令

(1)  String类型

1. 设置一个键值对 

set name zhangsan 

2. 获取键值对

get name

3. 设置一个10s后过期的键值对 

set name zhangsan ex 10   ex单位秒
setex name 10 zhangsan
set name zhangsan xx 10000   xx单位毫秒

4. 获取键值对的剩余存活时间

ttl name

5. 当key不存在时,才可以设置,可充当分布式锁

set name zhangsan nx
setnx name zhangsan 
set lock thread ex 10 nx;  // 设置分布式锁并设置过期时间

6.当存在key时,才可以设置,相当于更新操作,xx标识

set key value xx

7. 一次存储或获取多个key,value,减少网络通信次数

mset key1 value1 key2 value2 key3 value3
mget key1 key2 key3

8. 是否存在某个key 

exists name

9. 在value指定位置上替换或拼接字符串

setrange name 3 lisi

10. 获取value指定范围的字符串

getrange name 0 -1

11. 若key值存在,则返回原value值并更新为lisi,若不存在,则返回nil

getset name lisi

加减运算命令

1. 针对value为Integer类型

incr key   加一操作
decr key  减一操作
incrby key 10   加10   
incrby key -10  减10  或者使用decrby key 10

2. 针对小数

incrbyfloat key 1.1 加1.1
incrbyfloat key -1.1 减1.1

String适用场景

  1. 可以缓存用户会话信息,session等,将用户id作为键,将用户信息序列化为字符串作为值。
  2. 可以用来分布式锁setnx。将锁的标识称作为键,请求id作为值,并设置过期时间。
  3. 计数器,使用加减运算命令,如浏览量,点赞数等。

(2)  Hash类型

相当于一种key key value.

1. 设置一个hash类型

hset user id 1

2. 获取hash值

hget user id

3. 是否存在KK

hexists user id  

4. 删除一个或多个KK

hdel user id user name...  

5. 查找K对应的所有K(filed)

hkeys user  

6. 查找KK对应的所有value

hvals user  

7. 查找K对应的所有key-value键值对

hgetall user 

8. 一次设置或查找多个Hash类型的键值对

hmset user id 1 username lisi password 111
hmget user id username password 

9. 获取指定哈希表中键值对的个数   

hlen user 

10. 当这个filed对应的id不存在才能插入

hsetnx user id      

11. 获取value的长度

hstrlen user id 

12. 对hash表中的value进行加减运算

hincrby 针对Integer类型
hincrby user id 1  id值加一
hincrbyfloat 针对小数类型
incrbyfloat user money  1.1   

Hash哈希表适用场景

  • 可以存储用户的个人信息属性等,将用户id作为键(key),用户的各个属性作为键(field),属性对应的值作为field的值。这种存储有利于快速获取,更新用户的属性信息。

(3)  List类型

List底层数据结构是链表,redis中的l列表提供了头插(lpush),头删(lpop),尾插(rpush),尾删(rpop)。更像是一个双端队列。使用下标进行操作,元素可以重复,有顺序。

1. 头插尾插

lpush key value1 value2 ...

2. 头删尾删

lpop key 

3. 按范围查找列表id的所有value ,-1 表示最后一个元素的位置

lrange id 0 -1 

4. 查找下标为0的value

lindex key 0  

5. 在元素2的前面或后面插入一个元素10 ,如果指定的元素在list中是有多个的。则linsert会从左到右找到第一个元素进行插入

linsert id before/after 2 10   
lpushx,rpushx 当指定List数组存在时,才能插入
lpushx key value

6. 删除元素1,并且删除个数为5个。删除指定元素并且指定删除元素的个数 ,List是可以重复的。并且5的正负代表删除的方向,正数是从左到右找并删除,负数是从右到左找并删除

lrem id 5 1  

7. 截取并更新原value,更新的值就是截取后的值,闭区间

ltrim id start end 

8. 将下标为2的元素更新为10 下标越界会报错

lset id 2 10 

9. 获取指定列表中元素的个数

llen id 

10. blpop  brpop 带有阻塞性质的出队操作

  • 在列表有元素的情况下,和lpop,rpop表现是一样的。但如果列表中没有元素,非阻塞版本会立即返回nil,阻塞版本会等待阻塞一段时间timeout,若list中还是没有添加新的元素,才会返回nil。若在等待时间内有了新元素,则会立即返回,解除等待。并且阻塞期间也是可以执行其他命令。当 list 处于阻塞时,这时有多个客户端访问命令,后面list添加新元素了,会先来先到。并且这个超时等待时间是可以代码手动设置的,如下,获取过期时间为60s
blpop id 60 

即pop之前没有元素,会阻塞等待60s,60s内有元素进来,则弹出去,没有就返回空。

List列表适用场景

  • List提供了带有阻塞功能的出队(lpop,rpop)命令,可以用来做消息队列,以及最新消息展示等

(4)  Set类型

Set集合中的元素具有唯一性,无序性

1. 向id集合中插入多个元素 元素若重复,只插入一个

sadd id 1 2 3 4 5... 

2. 查看id集合中所有的元素

smembers id     

3. 查看id集合中元素1是否存在

sismember id 1   

4. 删除count个元素的个数

spop [count]  

5. 随机从集合中返回一个或多个元素

srandmember key [count]  

6. 将一个元素member从集合key1中移动到key2中,具体过程是key1中删除这个元素,key2中添加这个元素

smove key1 key2 member  

7. 从集合中一次性删除一个或多个元素

srem key member1,member2... 

8. 得到指定集合中元素的个数

scard key 

Set集合适用场景

  • 因为集合中提供了交并补,可以做一些个性化标签,共同好友,好友推荐等

(5)  Zset类型

有序集合,引入了score属性,就是按照这个分数进行排序(升序),元素有序,不重复

 zadd key [NX|XX] [CH] [INCR] score member [score member ...]  可以一次性插入多个

  • XX:更新操作,该元素之前存在才操作
  • NX:插入操作,即该元素之前不存在才操作
  • INCR: 修改元素对应的分数做加法/减法运算

1. 设置元素

zadd score 10 zhangsan 20 lisi 50 wangwu 70 liujiang 80 wangchegn

2. 查找范围内的元素并升序输出,加上withscores还会返回对应的分

zrange key 0 -1 [withscores]  

3. 同上,逆序输出,即降序

zrevrange key 0 -1 [withscores] 

4. 获取集合中所有元素的个数

zcard key 

5. 通过一个分数区间,返回在区间内的member个数,闭区间,若想要开区间,加左括号

zcount key (minscore (maxscore
zcount key minscore maxscore 

6. 同上,也是指定一个分数区间,但返回值不同,返回的是集合的元素,而非个数,withscores返回分数

zrangebyscore key minscore maxscore [withscores]
zrangebyscore key -inf +inf [withscores]

7. 删除并返回分数最高/最低的count个元素

zpopmax/zpopmin key count  

8. 带有阻塞性质的删除元素,超时等待,可以设置超时时间

bzpopmax/bzpopmin key timeout 

9. 获取到指定元素的排名(下标)

zrank  key member 

10. 也是获取到指定元素的下标

zrevrank  key member 

11. 根据指定的member查找并返回score分数

zscore key member 

 12. 删除有序集合中的一个或多个元素

rem key member1 member2.. 

13. 指定一个区间(下标),对这个闭区间内的所有元素进行删除

zremrangebyrank   start end

14. 同上 指定一个区间(分数score),对这个闭区间内的所有元素进行删除

zremrangebyscore  key 0 -1

15. 给指定的元素member对应的score加一个数字,即修改分数

zincrby key 10 member 分数加10

 有序集合zset适用场景

  • 有序集合可以用来做排行榜,计分系统等

(6)  全局命令

1. 删除所有数据库的所有键值对

flushall  

2. 删除当前数据库的所有数据

flushdb

3. 获取所有的key

keys *        

4. 删除一个或多个key

del key1 key2...  

5. 是否存在key

exists key  

6. key的存活时间 单位s -1表示不会过期  -2 表示已经过期

ttl key      

7. key的存活时间 单位ms -1表示不会过期  -2 表示已经过期

pttl key     

8. 设置key的存活时间 单位s

expire key 60

9. 设置key的存活时间 单位ms

pexpire key 1000

10. 查看key对应的value的类型 如none(查找不存在的key),string,list,set,zset(压缩set),hash,stream(消息队列)等

type key  

11. 查看key对应value的详细数据类型

object encoding key  

(7)  集合中的交并补

1. 对多个集合求交集 返回交集元素

sinter key1 key2 key3 ... 

2. 和上面一样也是求交集,不同的是此操作会将交集元素存放在destination这个指定的集合中,返回的是交集元素的个数

sinterstore destination key1 key2..  

3. 对多个集合求并集 返回并集元素

sunion key1 key2... 

4. 求并集,此操作会将并集元素存放在destination这个指定的集合中,返回的是交集元素的个数

sunionstore destination key1 key2.. 

5. 对多个集合求差集 返回并集元素

sdiff key1 key2... 

6. 求差集,此操作会将差集元素存放在destination这个指定的集合中,返回的是交集元素的个数

sdiffstore destination key1 key2..  

3.redis.conf配置文件常用配置

1. Redis默认不是以守护进程的方式运行,修改为yes启用守护进程

daemonize no

2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过以下配置项修改

pidfile /var/run/redis.pid

3. 指定Redis端口号,默认端口为6379

port 6379

4. 绑定的主机地址

bind 127.0.0.1

5.当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

timeout 300

6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose

loglevel verbose

7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null

logfile stdout 标准输出
logfile  /var/log/redis/redis-server.log 自定义

8. 设置Redis数据库的数量,默认有16个,默认使用0号数据库,可以使用SELECT 命令在连接上指定数据库id

databases 16

9. Redis持久化策略-RDB,持久化规则设置

save 900 1       900秒(15分钟)内有1个更改操作就将数据持久化到RDB文件中
save 300 10      表示300秒(5分钟)内有10个更改操作就将数据持久化到RDB文件中
save 60 10000    表示60秒内有10000个更改操作就将数据持久化到RDB文件中

10. 指定存储至本地数据库时是否压缩数据,默认为yes

rdbcompression yes

11. 指定本地数据库文件名,默认值为dump.rdb

dbfilename dump.rdb

12. 指定本地数据库存放目录

dir ./

13. redis集群,若该机为从节点,就设置下列配置项。可以在配置文件中修改,也可以使用命令指定。可实现从主节点的数据同步

slaveof ip port
slaveof no one  该命令可将从节点设置回主节点

14. redis集群,当主节点设置了密码保护时,从节点连接主节点的密码

masterauth masterpassword

15. 设置Redis连接密码,可以在配置文件里修改,也可以通过命令修改。设置密码后,登录是需要auth+密码登录

config set requirepass "123456"      设置密码命令
config get requirepass                     获取密码


登录(两步)
redis-cli -p 127.0.0.1 -h 6379
auth 123456

16. 设置同一时间客户端最大连接数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

maxclients 1000

17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作

maxmemory bytes

18. 持久化机制-AOF,默认为no,不开启。设置为yes开启,开启后会将每次的写操作命令保存到AOF文件中

appendonly no

19. 指定AOF文件名,默认为appendonly.aof

appendfilename appendonly.aof

20. AOF将命令数据保存到文件中的时机(规则)。共有3个可选值

appendfsync no          交给操作系统进行同步,每次同步时间间隔不一样
appendfsync always      存入aof缓冲区并立即同步到aof文件中
appendfsync everysec    每隔一秒保存一次  默认值

21. aof文件重写的时机(规则) ,重写的目的也是为了避免文件太大

auto-aof-rewrite-min-size 64mb      当文件最小达到64mb时重写
auto-aof-rewrite-percentage 100     当文件与上一个重写文件比值达到100时重写

3.redis的事务操作

在redis中,单条命令是原子性的,但是事务是不保证原子性的,并且也没有隔离级别这个概念。

redis事务操作步骤

  1. 开启事务 multi
  2. 命令入队
  3. 执行事务 exec
  4. 放弃事务 discard

 事务执行过程中可能会出现以下几个问题

  1. 多条命令入队时,有一条命令本身是错误的,就相当于是Java中的编译时异常。出现这种情况该事物中的所有命令都不会执行。
  2. 也是多条命令入队,命令本身没有问题,但在执行过程中会发生错误,比如对一个value为字符串的进行了加减运算。相当于运行时异常。出现这种情况时运行出现错误的命令不执行,其他运行正确的命令正常执行。

代码演示


4.redis实现乐观锁

乐观锁就是认为在任何情况下都保持乐观,都不会加锁。我们可以使用redis提供的 watch  命令对某个key进行监视,其原理和CAS一样,是通过比较所监视的值是否发生了变化,来判断是否应该执行操作,并且它也引入了version版本来避免ABA问题。unwatch命令放弃监视。

代码演示

开启两个客户端:一个在监视k1开启事务后,另一个客户端进行修改,最后当事务执行后,执行失败。原因就是在监视的过程中值被修改了。


5.通过jedis操作redis

  • 1.从Maven仓库中导入依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>
  • 2.创建jedis对象
Jedis jedis = new Jedis("127.0.0.1",6379); // 创建对象
jedis.auth("123456"); //登录密码 没有密码不写
jedis.set("111","111");
System.out.println(jedis.keys("*"));

6.Springboot集成redis

springboot已经整合了不同的Redis客户端,如lettuce,jedis,即SpringDataRedis。它提供了RedisTemple工具类,里面封装 了各种对Redis的操作。

  • 1.引入依赖
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  •  2.配置文件中配置redis
// 在yml配置信息中设置
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456
    database: 0 #默认是0号数据库
    lettuce:
      pool:
        max-active: 8 #最大连接
        max-idle: 8   #最大空闲连接
        min-idle: 0   #最小空闲连接
        max-wait: 1000ms #最大等待时间
  • 3.注入RedisTemple
    @Autowired
    private RedisTemplate redisTemple;

7.自定义一个RedisTemplate

通过源码观察,RedisTemplate的序列化器是jdk序列化,会将键值对转为字节形式存储,可读性差,并且内存占用也大。当value值为对象时,该实体类还必须实现Serializable接口,否则报错。由于传入的值都为Object类型,所以还需要类型强转。

除了jdk序列化,观察源码发现还有其他类型的序列化,如json序列化等等。

那如果我们想使用其他的序列化方式,可以自己定义一个RedisTemplate。将所有的key的序列化方式变为String序列化,将所有的value的序列化方式变为json序列化。因为一般情况下,key值都是字符串型的,不需要Object型,还需要强转。并且jdk序列化会使可读性变差,还占用空间大。

@Configuration
public class RedisConf {
    @Bean
    public RedisTemplate<String, Object> redisTemplates(RedisConnectionFactory redisConnectionFactory) {
        // key设置为String型
        RedisTemplate<String, Object> template = new RedisTemplate();
        // key值使用String序列化
        template.setKeySerializer(new StringRedisSerializer());
        // value值使用json序列化
        template.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
        // hashkey使用String序列化
        template.setHashKeySerializer(new StringRedisSerializer());
        // hashvalue使用json序列化
        template.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

使用:

@Autowired
@Qualifier("redisTemplates") //要跟你自定义的方法名相同
private RedisTemplate redisTemplate;

8.持久化策略 RDB和AOF

 redis是内存数据库,要是redis服务器宕机或者是断电,内存中的数据都会丢失。所以进行持久化是非常有必要的。redis中有两种持久化策略。一种是RDB,通过内存快照,将内存中的数据保存到rdb文件中,并且在下次redis服务器启动时,加载这些数据到内存中,并且在保存时是fork了一个子进程去执行写操作,不会影响性能。并且rdb文件可以进行压缩,占用空间相对来说小。另一种就是AOF,其则是将每一次的写操作命令存入AOF文件中,并且在下一次redis服务器启动时重新执行一遍这些命令。文件占荣空间相对RDB来说小。在默认情况下,在redis.conf配置文件中,AOF是关闭的。

RDB优点

  1. 手动bgsave或者是自动触发保存时会fork一个子进程去执行写操作,不会阻塞,不会影响性能。
  2. RDB文件可以压缩,占用空间相对来说较少。
  3. RDB是一个二进制压缩文件,所依数据恢复速度也是比较快的。

RDB缺点

  • 持久化实际是是有时间间隔的,如果在间隔内服务器发生问题,就会导致最后一次的数据丢失。

RDB文件保存的触发机制

  1. 配置文件中的save规则满足时触发
  2. 手动save后者是bgsave是触发
  3. 退出redis(shutdown命令)时触发
  4. 执行flushall命令时触发

AOF优点

  • 实时性,每次执行一个写操作命令,都会写入AOF缓存区中,然后会根据不同的策略同步到AOF文件。一种是存入AOF缓冲区并立即同步到AOF文件中,一种是每隔几秒再同步到AOF文件中,最后一种是同步交给操作系统,每次同步的时间间隔不一样。并且会进行文件重写,以达到压缩文件的目的。默认重写的时机是文件最小达到64mb,或者当前文件与上一个重写的aof文件比值达到100时重写文件。

AOF缺点

  1. 其恢复数据是在服务器启动时依次执行文件中的命令,比较耗时,耗性能,数据恢复速度慢。
  2. 文件占用空间相对较大。

9.redis集群环境搭建

Redis主从复制,读写分离。主节点负责写,从节点负责读。主节点写完后同步给从节点。同步操作是单向的,只能是由主节点向从节点同步。默认情况下,每个redis服务器都是主节点。可通过命令或者是在配置文件中修改为从节点。主节点不做任何操作。成为从节点后,只能进行读操作,不能进行写操作。redis集群一般至少有三个redis服务器,一主两从。

  • 查看当前服务器的节点信息
info replication
  • 配置从节点,在从节点服务器中执行该命令(以127.0.0.1为例)
slaveof 127.0.0.1 6379
  • 关闭服务器
shutdown
  • 将从节点设置回主节点
slaveof no one

10.哨兵模式

哨兵是一个独立的进程,独立运行。监视主节点的原理是向主节点发送请求信息,比如ping命令,通过主节点是否响应来判断主节点有没有宕机。一般情况下哨兵也要至少有三个,当多个哨兵都认为主节点宕机后,才会去更换主节点。更换主节点是通过投票(算法)实现的,剩下的从节点中谁的票数高,谁就成为主节点。主节点设置成功后,会通过发布订阅模式,来告诉所有哨兵该更换自己监控的主节点了。

  • 1.在哨兵配置文件中配置
// 1表示主节点挂了,从节点投票选主节点
sentinel monitor mymaster 127.0.0.1 6379 1  
  • 2.启动哨兵模式
// 启动配置文件
redis-sentinel sentinel.conf 

11.缓存击穿,缓存穿透,缓存雪崩

1.缓存穿透

即查询一个不存在的数据,在缓存和数据库中都不存在,有可能是恶意伪造。这样每次请求都会打到数据库,严重的话会使数据库宕机。

解决办法

  1. 缓存空数据
  2. 布隆过滤器

2.缓存击穿

指的是有一些热点key到达了过期时间,由于这些数据的请求量非常大,再加上如果这些数据量比较大的话,那缓存重建的时间就会较长,在这个缓存重建的时间段内,大量的请求都会到达数据库,会给数据库带来巨大压力。

解决办法

  1. 加互斥锁,setnx。当数据过期后,只有获得锁的线程进行缓存重建,其他未获得锁的只能阻塞等待,直到缓存重建完成。缺点是用户体验太差,要等很久。但保证了数据的实时性。
  2. 逻辑过期。并没有去真正设置过期时间,而是在数据中多加了一个过期时间属性,当某个线程查询到这个数据过期后,首先会获取互斥锁,获取成功后会开启一个新的线程来执行缓存重建操作,原来的线程也不会等待缓存重建完成,而是直接返回旧数据,其他未获取到锁的线程也是直接返回旧数据。缺点是数据不是最新的,优点是不用等待。

3.缓存雪崩

是指大量的热点数据同时失效或者是Redis服务器意外宕机,导致大量请求同时到达数据库,给数据库带来巨大压力。

解决办法

  1. 针对同时失效,可以设置不同的过期时间TTL,使用随机数。
  2. 针对Redis服务器宕机,可以进行Redis集群,部署多个Redis服务器,主从同步,读写分离,主节点负责写数据,从节点负责读数据。主从点写完后同步给从节点,并且为防止主节点发生宕机情况,可以使用哨兵模式进行监控,及时发现,及时更换主节点。

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

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

相关文章

Java面试题:多线程2

如何停止正在运行的线程 1,使用退出标志,使线程正常退出(run方法中循环对退出标志进行判断) 2,使用stop()方法强行终止(不推荐) 3,调用interrupt()方法中断线程 打断阻塞线程(sleep,wait,join),线程会抛出InterruptedException异常 打断正常的线程,可以根据打断状态来标记…

奶爸预备 |《P.E.T.父母效能训练:让亲子沟通如此高效而简单:21世纪版》 / 托马斯·戈登——读书笔记

目录 引出致中国读者译序前言第1章 父母总是被指责&#xff0c;而非受训练第2章 父母是人&#xff0c;不是神第3章 如何听&#xff0c;孩子才会说&#xff1a;接纳性语言第4章 让积极倾听发挥作用第5章 如何倾听不会说话的婴幼儿第6章 如何听&#xff0c;孩子才肯听第8章 通过改…

【春招特供】Unity面试题总结 | Unity基础篇

物体发生碰撞的必要条件&#xff1f; 两个物体都必须带有碰撞器&#xff08;Collider&#xff09;&#xff0c;其中一个物体还必须带有Rigidbody刚体&#xff0c;而且必须是运动的物体带有Rigidbody脚本才能检测到碰撞。 2. Unity3d中的碰撞器和触发器的区别&#xff1f; 碰…

【LeetCode 121】买卖股票的最佳时机

思路 思路&#xff1a; 所谓代码的复杂性来源于业务的复杂性&#xff0c;如果能够想清楚业务实现逻辑&#xff0c;就能够轻松写出代码&#xff1b; 假设当前是第i天&#xff0c;如何在第i天赚到最多的钱&#xff1f;需要在第i天之前以最低价买入股票&#xff1b; 所以需要求…

[渗透利器]全能工具=信息收集->漏洞扫描->EXP调用

前言 hxd开发的工具&#xff0c;大致模块有&#xff08;信息收集&#xff0c;漏洞扫描&#xff0c;暴力破解&#xff0c;POC/EXP&#xff0c;常用编码&#xff09; 工具使用 下载后解压 安装环境 pip install -r requirements.txt 注意&#xff0c;该工具继承了两种不同的使…

深入了解C/C++的内存区域划分

&#x1f525;个人主页&#xff1a;北辰水墨 &#x1f525;专栏&#xff1a;C学习仓 本节我们来讲解C/C的内存区域划分&#xff0c;文末会附加一道题目来检验成果&#xff08;有参考答案&#xff09; 一、大体有哪些区域&#xff1f;分别存放什么变量开辟的空间&#xff1f; …

Django高级表单处理与验证实战

title: Django高级表单处理与验证实战 date: 2024/5/6 20:47:15 updated: 2024/5/6 20:47:15 categories: 后端开发 tags: Django表单验证逻辑模板渲染安全措施表单测试重定向管理最佳实践 引言&#xff1a; 在Web应用开发中&#xff0c;表单是用户与应用之间进行交互的重要…

工厂模式+策略模式完成多种登录模式的实现

前提 &#xff08;简单工厂不属于设计模式&#xff0c;而是一种编程思想【抽象一层出来】&#xff09;工厂方法模式、抽象工厂模式 以上都是为了解耦&#xff0c;如果考虑多个纬度&#xff08;如需要同时考虑多种电器&#xff0c;多种品牌&#xff09;则优先考虑抽象工厂。 …

iMazing下载安装不了怎么办?

iMazing是一款可用于iPhone、iPad等ios移动设备管理软件&#xff0c;但需要注意的是&#xff0c;iMazing只能安装在Windows与Mac系统中&#xff0c;不能安装在iOS移动设备上。iOS移动设备可以通过USB线或Wi-Fi连接Windows或Mac系统上的iMazing软件。 iMazing的安装失败&#x…

Linux--IIC驱动编程实验

对于 I2C 主机驱动&#xff0c;一旦编写完成就不需要再做修改&#xff0c;其他的 I2C 设备直接调用主机驱动提供的 API 函数完成读写操作即可。这个正好符合 Linux 的驱动分离与分层的思想&#xff0c;因此 Linux内核也将 I2C 驱动分为两部分&#xff1a; ①、 I2C 总…

3.栈和队列(汇总版)

目录 1.栈&#xff08;一端插和删&#xff09; 2.队列&#xff08;一端插另一段删&#xff09; 2.1队列的概念及结构 2.2 队列的实现 队列的接口 1.初始化队列 2.销毁队列 3.插入元素 4.出队列&#xff08;头删&#xff09; 5.访问对头 6.访问队尾 7.判断队列是否为…

练习题(2024/5/6)

1路径总和 II 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], target…

【漏洞复现】某小日子太阳能系统DataCube3审计

漏洞描述 某小日子太阳能系统DataCube3终端测量系统 多个漏洞利用方式 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进…

一起了解开源自定义表单的优势表现

随着社会的进步和科技的发展&#xff0c;越来越多的中小企业希望采用更为先进的软件平台&#xff0c;助力企业实现高效率的流程化管理。低代码技术平台、开源自定义表单已经慢慢走入大众视野&#xff0c;成为一款灵活、高效的数字化转型工具。流辰信息专注于低代码技术平台的研…

GitOps介绍

基础设施即代码 IaC 在理解 GitOps 之前&#xff0c;需要先理解什么是基础设施即代码。 基础设施即代码&#xff08;Infrastructure as Code&#xff0c;简称IaC&#xff09;是一种软件工程实践&#xff0c;它将基础设施的管理和配置过程像管理代码一样进行版本控制、自动化和…

RabbitMQ是怎么做消息分发的?——Java全栈知识(14)

RabbitMQ是怎么做消息分发的&#xff1f; RabbitMQ 的消息分发分为五种模式&#xff1a;分别是简单模式、工作队列模式、发布订阅模式、路由模式、主题模式。 1、简单模式 publisher 直接发送消息到队列消费者监听并处理队列中的消息 简单模式是最基本的工作模式&#xff0c;…

C++:哈希表和unordered系列容器的封装

一、unordered系列关联式容器的介绍 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到log2N&#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好的查询是&…

软件测试必问的33个面试题

1.你为什么选择软件测试行业 因为之前有了解软件测试这个行业&#xff0c;觉得他的发展前景很好。 2.根据你以前的工作经验描述一下软件开发、测试过程&#xff0c;由那些角色负责&#xff0c;你做什么 要有架构师、开发经理、测试经理、程序员、测试员。我在里面主要是负责所…

软件公司为什么很少接二开项目?

前言 很多企业由于原有项目还在继续运营&#xff0c;但原有技术公司不想再合作或者不想再维持整个技术团队等原因&#xff0c;就需要找一个新的软件公司继续维护原有软件系统。但是一接触往往发现很多软件公司拒绝接手第三方的软件项目&#xff0c;这究竟是什么原因呢&#xff…

控制台调试 hover 后才出现的元素

调试 hover后才出现的元素 打开开发者工具&#xff0c;鼠标放在hover时才出现的元素上&#xff0c;然后点击右键&#xff1b; 不要选中任何选项&#xff0c;将鼠标移动到开发者工具的调试面板中&#xff1b; 按下N键&#xff0c;此时悬浮的元素不会消失&#xff0c;定位成功。…