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

Redis 常问知识

1.Redis 缓存穿透问题

缓存穿透:当请求的数据在缓存和数据库中不存在时,该请求就跳出我们使用缓存的架构(先从缓存找,再从数据库查找、这样就导致了一直去数据库中找),因为这个数据缓存中永远也不会存在。导致后续所有的这个请求(被恶意的人发现后)都会直接请求数据库。恶意用户一直发送该请求会导致数据库服务宕机。

解决方法常用的两种

一:缓存空数据,二,使用布隆过滤器进行校验。

缓存空数据

在数据库查询到不存在的数据时,对该数据进行缓存为空(可以设置稍短的3~5分钟的TTL),之后相同的请求,就会在缓存中查到,而不去请求数据库。

代码案列

  /*** 查询商户信息* @param id* @return*/@Overridepublic Result queryById(Long id) {//查询缓存String string = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY+id);//hutool 工具类 符合条件“adc" 不符合条件“”,null, "/t/n"if (StrUtil.isNotBlank(string)){Shop shop = JSONUtil.toBean(string, Shop.class);return Result.ok(shop);}//若是 " " 上面已经判断了不是“” 不是null ,if(string != null){return Result.fail("商户不存在");}// 缓存不存在 查数据库Shop shop = getById(id);if (shop ==null) {//将空值写入缓存stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, "", CACHE_NULL_TTL, TimeUnit.MINUTES);return Result.fail("商户不存在");}//写入缓存stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY+ id, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);return Result.ok(shop);}

优点

  • 实现简单

缺点

  • 缓存空值,会占用redis的内存空间(可以设置过期时间),可能会导致短期数据不一致问题(除非在新增数据的时候,删除redis中的数据)。

布隆过滤器

扩展

其实不仅仅是这两种解决缓存穿透的方案。

此外还可以

  • 增强id的复杂性,避免id被猜到规律。
  • 加强用户权限校验
  • 做好热点数据限流。

此外,还应该做好数据的校验,对于一些不符合业务逻辑数据的请求直接拦截掉,不在请求数据库。

还可以采用对接口进行限流。甚至黑名单封禁。

2.Redis的哨兵模式

为了提高Redis的性能搭建主从集群后,当主节点出现问题,Redis服务就不可以进行写操作,服务就不可用,Redis提供了哨兵机制,来实现主从集群的自动故障恢复。	哨兵的结构和作用
  • 监控:Sentinel 会不断检查您的master和slave是否按预期工作。
    • 具体来说就是Sentinel 一直发送ping,接收pang,说明该节点正常可用,反之就是主观下线,当多个Sentinel (一般是一半哨兵监控redis节点为不可用)检测一个redis节点都说明该节点不可用后,该节点是客观下线(服务不可用)。
  • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主。
  • 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

补充

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:
主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线。
客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

哨兵选主规则
首先判断主与从节点断开时间长短,如超过指定值就排该从节点
然后判断从节点的slave-priority值,越小优先级越高
如果slave-prority一样,则判断slave节点的offset值,越大优先级越高
最后是判断slave节点的运行id大小,越小优先级越高。

脑裂问题

当哨兵网络与Redis主节不在同一个网络下,监控就会出问题,但是Redis主节点并没有问题,服务仍在Redis主节点写,由于网络问题哨兵通过监控认为Redis主节点出现了问题,就会在从节点选一个做为主节点,这样就出现了两个主节点,这就是脑裂问题,当网络原因回复后,原来的主节点为变成从节点,以新的主节点为主,原来的主节点会同步新的主节点信息,就会导致数据丢失。

解决方法 redis.config

min-replicas-to-write 1   表示最少的salve节点为1个
min-replicas-max-lag 5  表示数据复制和同步的延迟不能超过5秒

3.Redis 主从复制,同步流程

单节点的Redis服务并不可靠,并发有上限。
  • 如果服务器发生了宕机,由于数据恢复是需要点时间,那么这个期间是无法服务新的请求的;
  • 如果这台服务器的硬盘出现了故障,可能数据就都丢失了。为了提高Redis 服务的可靠性,以及高性能,采用集群模式------主从复制。在主节点进行写操作,在从节点进行读操作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

具体的主从Redis节点的同步流程是这样子,分为首次同步,和增量同步。

首次同步,也就是全量同步

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

增量同步

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid
  • offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

4.Redis持久化策略

Redis是内存服务,但是提供了两个持久化策略AOF,RDB来持久化Redis的数据。

AOF 日志文件

Redis 每执行一条写操作命令成功后,就把该命令以追加的方式写入到一个文件里,然后重启Redis 的时候,先去读取这个文件里的命令,并且执行它,这不就相当于恢复了缓存数据了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在Redis中AOF持久化功能默认是不开启的,在redis.config文件中设置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AOF的记录命令的频率可以通过redis.config文件来配置

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec 
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因为是记录命令,AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。

Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置:

# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写 
auto-aof-rewrite-min-size 64mb 

RDB

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据.

Redis 服务默认开启。用户可以手动备份

redis -cli
save # 由Redis主进程来执行RDB,会阻塞所有的命令
bgsave # 开启子进程执行RDB,避免主进程收到影响

当然Redis内部有自动触发RDB的机制,在redis.config中

# 900秒内,如果至少有1个key被修改,则执行bgsave 
save 900 1  
save 300 10  
save 60 10000 
这里提一点,Redis 的快照是全量快照,也就是说每次执行快照,都是把内存中的「所有数据」都记录到磁盘中。 所以可以认为,执行快照是一个比较重的操作,如果频率太频繁,可能会对 Redis 性能产生影响。如果频率太低,服务器故障时,丢失的数据会更 多。 通常可能设置至少 5 分钟才保存一次快照,这时如果 Redis 出现宕机等情况,则意味着最多可能丢失 5 分钟数据。 这就是 RDB 快照的缺点,在服务器发生故障时,丢失的数据会比 AOF 持久化的方式更多,因为 RDB 快照是全量快照的方式,因此执行的频率不能 太频繁,否则会影响 Redis 性能,而 AOF 日志可以以秒级的方式记录操作命令,所以丢失的数据就相对更少。

二者比较

这两种技术都会用各用一个日志文件来记录信息,但是记录的内容是不同的。

  • AOF 文件的内容是操作命令;
  • RDB 文件的内容是二进制数据。

RDB 快照就是记录某一个瞬间的内存数据,记录的是实际数据,而 AOF 文件记录的是命令操作的日志,而不是实际的数据。因此在 Redis 恢复数据时, RDB 恢复数据的效率会比 AOF 高些,因为直接将 RDB 文件读入内存就可以,不需要像 AOF 那样还需要额外执行操作 命令的步骤才能恢复数据

5.Redis与数据库数据一致性问题

为了提高查询效率引入了redis作为缓存,但是出现了新的问题就是,缓存中的数据和数据库中的数据不一致问题。解决数据不一致问题的方法,最简单的就是对缓存数据设置较短的过期时间,在过期时间后,会从数据库查询新的数据更新缓存,但是这种被动的等待过期时间,一致性是不符合大部分应用场景的。

业内的解决方案

  • Cache Aside Pattern 人工编码方式:缓存调用者在更新完数据库后再去更新缓存,也称之为双写方案。

  • Read/Write Through Pattern : 由系统本身完成,数据库与缓存的问题交由系统本身去处理。

  • Write Behind Caching Pattern :调用者只操作缓存,其他线程去异步处理数据库,实现最终一致。

    通常使用第一种方案,在更新数据库的同时更新缓存(删除缓存)。

    如果采用第一个方案,那么假设我们每次操作数据库后,都操作缓存,但是中间如果没有人查询,那么这个更新缓存动作实际上只有最后一次生效,中间的更新动作意义并不大,我们可以把缓存删除,等待再次查询时,将缓存中的数据加载出来。

我们需要考虑一下几点

  1. 在数据库更新时,缓存是更新还是删除?
    1. 更新缓存:每次更新数据库都更新缓存,无效写操作较多。
    2. 删除缓存:更新数据库时让缓存失效,查询时再更新缓存。
  2. 怎么确保数据库更新,缓存也更新(删除),
    1. 单体系统,将缓存与数据库操作放在一个事务
    2. 分布式系统,利用TCC等分布式事务方案
  3. 先操作缓存还是先操作数据库?

应该具体操作缓存还是操作数据库,我们应当是先操作数据库,再删除缓存,原因在于,如果你选择第一种方案,在两个线程并发来访问时,假设线程1先来,他先把缓存删了,此时线程2过来,他查询缓存数据并不存在,此时他写入缓存,当他写入缓存后,线程1再执行更新动作时,实际上写入的就是旧的数据,新的数据被旧数据覆盖了。

先操作数据库在删除缓存,理论上也会出现问题,线程1查询在缓存中没有的数据,就会查询数据库将数据库查到的age =20,写入缓存,但在这时还未写入缓存,线程2,操作数据库age=21,删除缓存。此时线程1继续写入缓存age=20,又会出现不一致现象。但是在实际中并不太可能发生,因为写入缓存的时间是极快的。- 先删除缓存,再操作数据库
- 先操作数据库,再删除缓存

6.Redis 缓存击穿

缓存击穿是指在高并发的情况下,当某个热点数据的缓存突然失效(过期或被删除)并且缓存重建业务较复杂,大量请求直接穿透到后端数据库,导致数据库负载过高,甚至崩溃的问题。由于并发用户特别多,同时读缓存没读到数据,又去数据库中取数据,引起数据库压力瞬间增大。

解决方法:互斥锁构建缓存和逻辑过期时间

互斥锁构建缓存

在热点key失效后,加锁,确保只有一个线程查询数据库并构建缓存。其他的线程等待并重试在缓存中取值。

优点

  • 一致性高

缺点

  • 由于使用了锁,线程等待,性能低,还可以能出现死锁。

代码实现

 /*** 获取锁* @param key* @return*/private boolean tryLock(String key){Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 20, TimeUnit.SECONDS);return BooleanUtil.isTrue(flag);}/*** 释放锁* @param key*/private  void unlock(String key){stringRedisTemplate.delete(key);}/*** 查询商户信息 缓存击穿互斥锁* @param id* @return*/public Shop queryWithMutex(Long id){String shopKey = CACHE_SHOP_KEY+ id;// 1. 从redis中查询店铺缓存String shopJson = stringRedisTemplate.opsForValue().get(shopKey);//2.判断是否命中缓存  isnotblank false: "" or "/t/n" or "null"if(StrUtil.isNotBlank(shopJson)){// 3.若命中则返回信息Shop shop = JSONUtil.toBean(shopJson, Shop.class);return shop;}//数据穿透判空   不是null 就是空串 ""if (shopJson != null){//返回错误信息
//            return  Result.fail("没有该商户信息(缓存)");return null;}//4.没有命中缓存,查数据库//todo :解决缓存击穿  不能直接查数据库。 利用互斥锁解决/*** 实现缓存重建* 1. 获取互斥锁* 2. 判断是否成功* 3. 失败就休眠重试* 4.成功 查数据库* 5 数据库存在该数据写入缓存* 6 不存在返回错误信息并写入缓存“”* 7 释放锁**///获取互斥锁 失败  休眠重试String lockKey = "lock:shop" + id;Shop shop=null;try {boolean isLock = tryLock(lockKey);//获取锁失败if (!isLock) {System.out.println("获取锁失败,重试");Thread.sleep(50);return queryWithMutex(id);//递归 重试}// 获取锁成功,再次检测缓存是否存在,存在就无需构建缓存,因为可能有的线程刚构建好缓存并释放锁,其他线程获取了锁//检测缓存是否存在  存在shopJson = stringRedisTemplate.opsForValue().get(shopKey);if (StrUtil.isNotBlank(shopJson)) {return JSONUtil.toBean(shopJson, Shop.class);}if (shopJson !=null){return null;}// 缓存不存在// 查数据库shop = super.getById(id);Thread.sleep(200);//模拟你测试环境 热点key失效模拟重建延迟if (shop == null){//没有该商户信息stringRedisTemplate.opsForValue().set(shopKey,"",CACHE_NULL_TTL,TimeUnit.SECONDS);return null;}//有该商户信息stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY+ id, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {unlock(lockKey);}return shop;}

逻辑过期时间

对热点key不设置过期时间,仅仅添加个expire 字段。

当使用该缓存时,根据过期字段判断是否更新缓存,若在期限内就直接使用改缓存,若不在期限内就更新缓存。

更新缓存的具体细节,利用锁确保一个线程重构缓存,防止数据库压力过大。在获得锁后,异步执行,新开线程执行重构缓存,同时原线程直接使用已经过期的数据。在此期间其他线程也发现缓存逻辑过期了,也会获得锁,但是获取锁失败,那就使用原来的老数据。

优点

  • 性能高

缺点

  • 数据不一致

代码实现

对类添加一个过期字段,为了满足开闭原则,可以自定义个新的类继承原来的类并添加expire字段,不过推荐如下写法

自定义个逻辑过期类,所有的逻辑过期类都可以使用(Object data 存原来的类)。

/*** 逻辑过期类*/
@Data
public class RedisData {private LocalDateTime expireTime;private Object data;
}

数据预热

 /*** 添加逻辑过期时间* @param id* @param expireSeconds*/public void savaShop2Redis(Long id ,Long expireSeconds){// 查询店铺数据Shop shop = getById(id);//封装逻辑过期时间RedisData redisData = new RedisData();redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireSeconds));redisData.setData(shop);//写入redisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY+id,JSONUtil.toJsonStr(redisData));}

正式代码

private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);
public Shop queryWithLogicalExpire( Long id ) {String key = CACHE_SHOP_KEY + id;// 1.从redis查询商铺缓存String json = stringRedisTemplate.opsForValue().get(key);// 2.判断是否存在if (StrUtil.isBlank(json)) {// 3.存在,直接返回return null;}// 4.命中,需要先把json反序列化为对象RedisData redisData = JSONUtil.toBean(json, RedisData.class);Shop shop = JSONUtil.toBean((JSONObject) redisData.getData(), Shop.class);LocalDateTime expireTime = redisData.getExpireTime();// 5.判断是否过期if(expireTime.isAfter(LocalDateTime.now())) {// 5.1.未过期,直接返回店铺信息return shop;}// 5.2.已过期,需要缓存重建// 6.缓存重建// 6.1.获取互斥锁String lockKey = LOCK_SHOP_KEY + id;boolean isLock = tryLock(lockKey);// 6.2.判断是否获取锁成功if (isLock){CACHE_REBUILD_EXECUTOR.submit( ()->{try{//重建缓存this.saveShop2Redis(id,20L);}catch (Exception e){throw new RuntimeException(e);}finally {unlock(lockKey);}});}// 6.4.返回过期的商铺信息return shop;
}

7.内存淘汰策略(Redis内存满了怎么办)

Redis中,在配置文件有设置maxmemory大小,当超过这个大小,Redis回触发内存淘汰机制,默认的淘汰策略就是noeviction

Redis服务中提供的内存淘汰策略有八种

  • noeviction :它表示当运行内存超过最大设置内存时,不淘汰任何数据,而是不再提供服务,直接返回错误。
  • volatile-ttl:优先淘汰更早过期的键值。
  • allkeys-random: 对所有key随机删除。
  • volatile-random :对设置ttl的key随机删除
  • allkeys-lru :对所有最近最久使用的key随机删除
  • volatile-lru : 对设置ttl并且最近最久使用的key随机删除
  • allkeys-lfu : 所有使用最近最少使用的key随机删除
  • volatile-lfu 设置ttl的并且最近最少使用的key随机删除

8.Redis 缓存雪崩

缓存雪崩出现的原因是同一时间内大量的key同时失效或者Redis服务宕机,导致所有的请求都到数据库,数据库压力过大宕机。

根据产生雪崩的原因进行分析

key同时失效导致的雪崩

我们在做缓存预热时和添加缓存时,设置有效期的同时,额外的增加(1~3)的随机过期时间。

同时当key过期后,构建缓存,利用互斥锁构建缓存,防止数据库压力过大。

Redis服务宕机

利用Redis集群提高服务的可用性。

  • 哨兵模式
  • 集群模式

其他

给业务添加多级缓存, 如Guava或者Caffeine.

使用服务熔断或请求限流机制

我们可以启动服务熔断机制,暂停业务应用对缓存服务的访问,直接返回错误,不用再继续访问数据库,从而降低对数据库的访问压力,保证数据库系统的正常运行,然后等到 Redis 恢复正常后,再允许业务应用访问缓存服务。

但是这样在Redis服务宕机期间所有的业务都不可用,为了减少对业务的影响,可以启用请求限流机制,只将少部分请求发送到数据库,

更多的请求就只能拒绝服务,等Redis服务正常后并缓存预热完成在解除请求限流机制

9.Redis 数据过期删除策略

Redis 对 key 设置过期时间后,需要有相应的机制将已过期的键值对删除,而做这个工作的就是过期键值删除策略。

Redis的过期策略:惰性删除和定期删除相配合使用。

惰性删除

在设置该key过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。

  • 优点 :对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查
  • 缺点 :对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放

定期删除

redis中的一个定时任务(100ms)执行一次,扫描设置了过期时间的键并判断是否过期。

具体细节:

redis并不会一次性扫描所有的设置过期时间的键,因为这样会浪费大量的过cpu资源,它会每次扫描时限制扫扫秒时间和数量,以免性能过大对redis正常的使用产生影响。

默认的话,每次获取20个key判断是否过期,如果过期的key占比超过25%,则继续拉20个,如果小于25%则停止。还有一次删除时间不能超过25ms,如果发现占比超过25%,就要判断目前是否花费了25ms,如果到时间也会结束。

定期清理有两种模式:

  • SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf 的hz 选项来调整这个次数
  • FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms。

优缺点:

  • 优点:能有效释放过期键占用的内存,可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。
  • 缺点:难以确定删除操作执行的时长和频率。如果执行的太频繁,就会对 CPU 不友好;如果执行的太少,那又和惰性删除一样了,过期 key 占用的内存不会及时得到释放。

可以看到上面两种各自的优点,所以Redis使用惰性删除和定期删除两种策略相互使用,以求在合理的使用cpu和避免使用内存浪费之前取平衡。

10.Redis 的脑裂问题

Redis脑裂(Split-Brain)是指在主从集群中,由于网络分区导致出现多个主节点同时接受写请求的情况,造成数据不一致的严重问题。

典型场景:主节点与部分从节点和哨兵网络断开,认为主节点客观下线,哨兵集群选举出新主节点,原主节点未真正下线,继续接受写请求,网络恢复后出现两个"主节点"。

脑裂问题的危害
数据不一致:两个主节点同时接受不同客户端的写入,相同key在不同节点有不同值

数据丢失:网络恢复后,旧主节点会被降级为从节点,其上的新写入数据会被清空(重新同步新主节点数据)

系统混乱:客户端可能连接到不同主节点

脑裂问题的主要原因
网络分区:主节点与哨兵/从节点间网络中断,但主节点与部分客户端连接仍保持

哨兵配置不当:quorum值设置过小,down-after-milliseconds时间过短

缺乏防护机制:未设置min-slaves参数,客户端未实现写失败处理

解决方案

  1. Redis服务端配置
    关键参数配置:
主节点必须有至少1个从节点才能写入
min-slaves-to-write 1
从节点延迟不超过10秒
min-slaves-max-lag 10
哨兵至少需要2个节点认为主节点不可用
sentinel monitor mymaster 127.0.0.1 6379 2
主节点失联30秒后才触发故障转移
sentinel down-after-milliseconds mymaster 30000
  1. 架构设计优化
    多机房部署:哨兵和从节点分布在不同的物理机房,避免单机房故障导致误判

网络冗余:主节点与哨兵间多条网络路径,使用心跳检测+冗余网络

更多更新的知识:Redis 面试题
如果有用请点赞收藏关注。

相关文章:

Redis 常问知识

1.Redis 缓存穿透问题 缓存穿透:当请求的数据在缓存和数据库中不存在时,该请求就跳出我们使用缓存的架构(先从缓存找,再从数据库查找、这样就导致了一直去数据库中找),因为这个数据缓存中永远也不会存在。…...

UnityUI:Canvas框架获取鼠标悬浮UI

将下面脚本挂在主体Canvas上,Canvas会对下面所有Image挂上PointerHandler脚本,并且可以通过GetPointEnter方法判断当前鼠标是否悬停在UI上 public class BaseCanvas : MonoBehaviour {public static BaseCanvas Main;private void Awake(){Main this;I…...

NLP实战(3):RNN英文名国家分类

目录 1. 项目需求 2. 模型解析 2.1 网络模型 2.2 准备数据 2.3 双向循环神经网络 3. 代码解析 4. 完整代码 5. 结果 1. 项目需求 对名字的分类,几千个名字,总共来自于18个国家 2. 模型解析 对于自然语言处理来说,输入是一个序列&am…...

东方博宜OJ ——1335 - 土地分割

递归 入门 ————1335 - 土地分割 1335 - 土地分割题目描述输入输出样例问题分析递归解法(欧几里得算法)代码实现总结 1335 - 土地分割 题目描述 把一块m * n米的土地分割成同样大的正方形,如果要求没有土地剩余,分割出的正方形…...

在轨道交通控制系统中如何实现μs级任务同步

轨道交通作为现代城市化进程中的重要支柱,承载着数以亿计的乘客出行需求,同时也是城市经济运行的命脉。无论是地铁、轻轨还是高速铁路,其控制系统的稳定性和可靠性直接关系到运营安全和效率。在这样一个高风险、高复杂度的环境中,…...

【C++教程】进制转换的实现方法

在C中进行进制转换可以通过标准库函数或自定义算法实现。以下是两种常见场景的转换方法及示例代码&#xff1a; 一、使用C标准库函数 任意进制转十进制 #include <string> #include <iostream>int main() {std::string num "1A3F"; // 十六进制数int…...

日志文件爆满_配置使用logback_只保留3天日志文件_每天定时生成一个日志文件---SpringCloud工作笔记206

日志文件爆满,springCloud微服务架构中的,日志爆满如何解决,使用脚本直接删除,会导致, 如果要删除的日志文件,还正在被进程占用,那么你即使使用脚本定时删除了,这个日志文件,那么这个日志文件实际上还是不会删除的,他的大小,依然占用磁盘,就是因为,有进程还在占用它,所以之前说…...

DICOM通讯(ACSE->DIMSE->Worklist)

DICOM 通讯协议中的 ACSE → DIMSE → Worklist 这条通讯链路。DICOM 通讯栈本身是一个多层的协议结构&#xff0c;就像 OSI 模型一样&#xff0c;逐层封装功能。 一、DICOM 通讯协议栈总体架构 DICOM 通讯使用 TCP/IP 建立连接&#xff0c;其上面封装了多个协议层次&#xf…...

QML与C++:基于ListView调用外部模型进行增删改查(附自定义组件)

目录 引言相关阅读项目结构文件组织 核心技术实现1. 数据模型设计联系人项目类 (datamodel.h)数据模型类 (datamodel.h)数据模型实现 (datamodel.cpp) 2. 主程序入口点 (main.cpp)3. 主界面设计 (Main.qml)4. 联系人对话框 (ContactDialog.qml)5. 自定义组件CustomTextField.qm…...

# linux 设置宽容模式

linux 设置宽容模式 在Linux系统中&#xff0c;通常没有直接称为“宽容模式”的设置选项&#xff0c;但你可以通过几种方式来模拟或调整系统行为&#xff0c;使其表现得更加“宽容”&#xff0c;特别是在处理错误、权限问题或其他潜在问题时。以下是一些常见的方法&#xff1a…...

#1 理解物联网

物联不是一个新概念&#xff0c;物联网如其中文译名&#xff0c; 虚拟和物的对应和联接。 对于人类的梦想而言&#xff0c;总是希望自己无比强大&#xff0c;但受限于外部条件而只能为此悻悻念念。 所以人们的目光聚焦在&#xff0c;上世纪70年代发展的传感器、大规模电路、通…...

物联网场景实战:智能电表数据管理与分析(二)

数据管理 数据清洗与预处理 智能电表在数据采集、传输和存储过程中&#xff0c;不可避免地会引入噪声、出现缺失值和异常值等问题&#xff0c;这些问题会严重影响数据的质量和后续分析的准确性&#xff0c;因此数据清洗至关重要。 噪声数据通常是由于测量误差、通信干扰等原…...

linux一次启动多个jar包

linux一次启动多个jar包并且可以自定义路径和端口号 代码使用 分享公司大神使用的一个脚步,可以一次启动多个jar包,也可以指定启动jar包 代码 #! /bin/sh # 端口号 PORTS(8080 8081 8082 8083) # 模块 MODULES(gateway auth system file) # 模块名称 MODULE_NAMES(网关服务 认…...

自然语言交互:NAS进化的下一站革命

自然语言交互&#xff1a;NAS进化的下一站革命 在数据爆炸式增长的数字时代&#xff0c;网络附加存储设备&#xff08;NAS&#xff09;早已突破企业级应用的边界&#xff0c;成为个人数字资产管理的核心枢纽。当全球NAS市场年复合增长率稳定在15%之际&#xff0c;耘想科技推出…...

go中我遇到的问题总结

go问题总结 1 - go中的nil等于java中的null吗 在 Go 和 Java 中,nil 和 null 都用于表示“空值”,但它们的实现和使用方式有所不同。 以下是 Go 中的 nil 和 Java 中的 null 之间的对比: 1. Go 中的 nil 在 Go 中,nil 是一个预定义的常量,表示零值。它的行为根据数据类…...

java面试题带答案2025最新整理

文章目录 一、java面试题集合框架1. 请简要介绍 Java 集合框架的体系结构2. ArrayList 和 LinkedList 的区别是什么3. HashMap 的工作原理是什么&#xff0c;它在 JDK 7 和 JDK 8 中有哪些不同4. 如何解决 HashMap 的线程安全问题5. TreeSet 是如何保证元素有序的 二、java面试…...

第七届浙江省大学生网络与信息安全竞赛决赛Unserialize深度解析 1.0

花还会重新开&#xff0c;不同的春来了又来。 - 2025.4.11 0x01 声明 仅作为个人学习使用&#xff0c;仅供参考&#xff0c;欢迎交流 可能是新生赛缘故&#xff0c;突发奇想&#xff0c;想好好梳理此题&#xff0c;顺便写成参考&#xff0c;于是有了这篇文章 当然很多理解可…...

onlyoffice 在线编辑集成

onlyoffice 在线编辑集成 项目中要使用word在线编辑功能&#xff0c;记录一下过程 安装使用docker版本 docker run -itd -p 8001:80 --name kodoffice --restart always registry.cn-hangzhou.aliyuncs.com/kodcloud/kodoffice:7.4.1.1 启动后http://192.168.x.x:8001/web/…...

2.4goweb 项目1

mysql库和表 CREATE DATABASE IF NOT EXISTS book_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;USE book_manager;-- 用户表&#xff08;用于登录&#xff09; CREATE TABLE IF NOT EXISTS users (user_id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(…...

ESP-ADF外设子系统深度解析:esp_peripherals组件架构与核心设计(系列开篇)

目录 ESP-ADF外设子系统深度解析&#xff1a;esp_peripherals组件架构与核心设计&#xff08;系列开篇&#xff09;简介模块概述功能定义架构位置核心特性 接口分析公共API概述1. 外设集合管理API2. 单个外设管理API3. 事件通信API4. 定时器管理API 数据结构关键数据结构分析枚…...

供应链管理:供应链管理的边界

一、追根溯源&#xff0c;什么是真正的财富 序号财富解释1土地作为生产资料&#xff0c;土地是农业、工业、商业的基础 城市中心的土地因稀缺性而价值连城&#xff0c;农业土地的肥沃程度直接影响粮食产量。2资源、矿产提供能源和原材料&#xff0c;支撑工业生产和经济发展。 …...

【Linux网络编程】TCP Echo Server的实现

本文专栏&#xff1a;linux网络编程 本文的基础知识是基于上篇文章&#xff1a;UDP Echo Server的实现 传送门&#xff1a; 【Linux网络编程】UDP Echo Server的实现 -CSDN博客 目录 一&#xff0c;InetAddr类的编写 二&#xff0c;客户端代码编写 创建套接字&#xff08;s…...

信奥赛CSP-J复赛集训(数学思维专题)(11):P9585 「MXOI Round 2」酒店

信奥赛CSP-J复赛集训&#xff08;数学思维专题&#xff09;&#xff08;11&#xff09;&#xff1a;P9585 「MXOI Round 2」酒店 题目描述 小 C 开了一家酒店&#xff0c;叫做 CC Hotel。 一天&#xff0c;CC Hotel 来了 n n n 位客人。小 C 需要把他们都安排在酒店的某一层…...

python: audioFlux XXCC 提取梅尔频率倒谱系数 MFCC

承上一篇&#xff1a;python&#xff1a;audioFlux 使用教程 XXCC: 倒谱系数&#xff0c;支持所有频谱类型. 可以提取梅尔频率倒谱系数&#xff08;MFCC&#xff09; Cepstrum coefficients, supports all spectrum types. 以下是使用 audioflux 库中 XXCC 类计算倒谱系数…...

PHP + Go 如何协同打造高并发微服务?

为什么需要 PHP Go 协同&#xff1f; 在微服务架构中&#xff0c;PHP 和 Go 看似是“两个世界”的语言&#xff0c;但它们的互补性极强&#xff1a; PHP&#xff1a;开发效率高、生态成熟&#xff0c;适合快速实现复杂业务逻辑&#xff08;如电商订单、用户系统&#xff09;…...

k8s工具使用

Kubectl Cheat Sheet k8s的命令级别 1.基础命令(初级) 2.基础命令(中级) 3.部署命令 4.集群管理命令 5.故障排查和调试命令 6.高级命令 7.设置命令 8.其它命令 命令行提示 为了使用kubectl命令更加高效,我们可以选择安装一下开源软件来增加操作kubectl命令的快捷方式,同…...

uml制做参考-以代码画UML图

【PlantUML系列】类图&#xff08;一&#xff09;_plantuml skin-CSDN博客 UML入门以及Plant UML工具介绍_plantuml-CSDN博客 UML类图详解-CSDN博客 【PlantUML】-类图-CSDN博客 【掌握绘图艺术】用PlantUML绘制完美UML图表&#xff0c;编程开发者的福音 - 知乎 如何优化P…...

深入解析B站androidApp接口:从bilibili.api.ticket.v1.Ticket/GetTicket到SendMsg的技术分析

前言 最近一段时间&#xff0c;我对B站的App接口进行了深入分析&#xff0c;特别是关注了认证机制和私信功能的实现。通过逆向工程和网络抓包&#xff0c;发现了B站移动端API的底层工作原理&#xff0c;包括设备标识生成机制、认证流程和消息传输协议。本文将分享这些研究成果…...

[AI ][Dify] 构建一个自动化新闻编辑助手:Dify 工作流实战指南

在内容创作行业中,自动化辅助工具已成为提升编辑效率的重要利器。本文将通过 Dify 平台,演示如何构建一个**“新闻编辑助手”**,实现从网页抓取、文本翻译、标题生成,到新闻配图的全流程自动化。 🎯 目标概览 这个工作流旨在实现如下功能: 从指定网页抓取新闻内容; 使…...

Unity中国战略调整简讯:Unity6下架 团结引擎接棒

Unity中国战略调整简讯&#xff1a;Unity6下架 团结引擎接棒 免费版 2025年4月9日 —— Unity中国宣布自即日起&#xff0c;中国大陆及港澳地区停止提供Unity 6及后续版本下载与服务&#xff0c;相关功能由国产引擎“团结引擎”承接。国际版2022 LTS及更早版本仍由Unity中国维护…...

司美格鲁肽用SNAC市场报告:2024年全球市场销售额达到了0.14亿美元

引言&#xff1a;了解司美格鲁肽与SNAC的重要性 在当前的医药领域&#xff0c;司美格鲁肽&#xff08;Semaglutide&#xff09;作为一种创新性的治疗2型糖尿病和肥胖症的药物&#xff0c;受到了广泛关注。而SNAC&#xff08;N-&#xff08;8-&#xff08;2-羟苯基&#xff09;…...

自动驾驶第一性原理

所谓的第一性原理&#xff1a; 就是指从最基本的物理规律&#xff0c;数据逻辑及工程约束条件出发&#xff0c;剥离所有的非本质的假设&#xff0c;直接推导出自动驾驶最核心的要素。 自动驾驶核心框架分解&#xff1a; 1、根本目标&#xff1a; 安全高效的将人/物从A地运送…...

《UE5_C++多人TPS完整教程》学习笔记36 ——《P37 拾取组件(Pickup Widget)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P37 拾取组件&#xff08;Pickup Widget&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09; Steph…...

Uniswap V2/V3/V4 流动性与价格计算详解

Uniswap V2/V3/V4 流动性与价格计算详解 一、核心概念对比 Uniswap V2 流动性模型: 恒定乘积公式 (x * y = k)价格决定: 完全由池子中的代币数量决定 (price = y/x)流动性衡量: 总储备量代表流动性,直接通过 getReserves() 获取流动性分布: 均匀分布在所有价格点交易费用: 固…...

yum安装MySQL数据库

yum安装方式 优点&#xff1a;操作简单易用。不用单独下载&#xff0c;服务器可以联网且yum源没有问题即可(可以选择国内的163/阿里源) 安装步骤&#xff1a; 1.关闭防火墙和selinux: systemctl stop firewalld ##关闭防火墙 systemctl disable firewalld …...

大联盟(特别版)双端互动平台完整套件分享:含多模块源码+本地部署环境

这是一套结构清晰、功能完整的互动平台组件&#xff0c;适合有开发经验的技术人员进行模块参考、结构研究或本地部署实验使用。 该平台覆盖前端展示、后端服务、移动端资源以及完整数据库&#xff0c;采用模块化架构&#xff0c;整体部署流程简单清晰&#xff0c;适合自研团队参…...

【Code】《代码整洁之道》笔记-Chapter15-JUnit内幕

第15章 JUnit内幕 JUnit是最有名的Java框架之一。就像别的框架一样&#xff0c;它概念简单&#xff0c;定义精确&#xff0c;实现优雅。但它的代码是怎样的呢&#xff1f;本章将研判来自JUnit框架的一个代码例子。 15.1 JUnit框架 JUnit有很多位作者&#xff0c;但它始于K…...

【Java八股】

JVM JVM中有哪些引用 在Java中&#xff0c;引用&#xff08;Reference&#xff09;是指向对象的一个变量。Java中的引用不仅仅有常规的直接引用&#xff0c;还有不同类型的引用&#xff0c;用于控制垃圾回收&#xff08;GC&#xff09;的行为和优化性能。JVM中有四种引用类型…...

深入探究AI编程能力:ChatGPT及其大规模模型的实现原理

&#x1f4e2; 友情提示&#xff1a; 本文由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;平台gpt-4-turbo模型辅助创作完成&#xff0c;旨在提供灵感参考与技术分享&#xff0c;文中关键数据、代码与结论建议通过官方渠道验证。 随着人工智能的快速发展&#xff0c…...

高德地图 JS-SDK 实现教程

高德地图 JS-SDK 实现教程&#xff1a;定位、地图选点、地址解析等 适用地点选择、地址显示、表单填写等场景&#xff0c;全面支持移动端、手机浏览器和 PC端环境 一、创建应用&Key 前端&#xff08;JS-SDK、地图组件&#xff09; 登陆 高德开放平台创建应用&#xff0c;…...

【信息系统项目管理师】高分论文:论信息系统项目的整合管理(银行数据仓库项目)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 正文一、制定项目章程二、制定项目管理计划三、指导和管理项目的实施四、管理项目知识五、监控项目工作六、实施整体变更控制七、结束项目或阶段正文 2023年6月,我以项目经理的身份,参加了 xx银行xx省分行数…...

dev中使用auto的方法

在dev-c中使用新特性是一样的道理&#xff0c;在他启动编译器来编译代码的时候我们让他加上这个参数就行了&#xff0c;设置方法是:在Tools里面找到Compiler Options打开它&#xff0c;然后把那个Add the following commands when calling compiler:选上勾&#xff0c;在里面加…...

C 语言中经典的数据结构

在 C 语言中&#xff0c;经典的数据结构通常包括以下几种&#xff0c;每种都有其特定的应用场景和实现方式&#xff1a; 1. 数组&#xff08;Array&#xff09; 定义&#xff1a;连续内存空间存储相同类型的数据。 特点&#xff1a;随机访问快&#xff08;O(1)&#xff09;&am…...

小白学习java第12天(下):网络编程

上面我们了解TCP就是三次握手&#xff01;&#xff01;&#xff01; 下面我们就详细介绍一下UDP&#xff0c;就是进行发包&#xff08;TCP协议类似于就是打电话&#xff0c;你必须进行连接才能进行传输&#xff0c;但是UDP类似于发消息&#xff0c;连不连接我都是可以的&#…...

论文精度:双分支图Transformer网络:视频驱动的3D人体网格重建新突破

论文地址:https://arxiv.org/pdf/2412.01179 目录 一、背景与问题定义 1.1 3D人体网格重建的意义 1.2 现有方法的困境 二、核心创新:DGTR网络架构 2.1 整体框架设计 2.2 全局运动感知分支(GMA) 2.3 局部细节优化分支(LDR) 2.3.1 局部信息聚合 2.3.2 调制图卷积…...

华三IRF堆叠技术

IRF&#xff08;Intelligent Resilient Framework&#xff0c;智能弹性架构&#xff09;是华三通信&#xff08;H3C&#xff09;自主研发的网络设备虚拟化技术&#xff0c;通过将多台物理设备整合为单一逻辑设备&#xff0c;实现统一管理、高可靠性和灵活扩展。以下是其核心要点…...

第一阶段补充知识

目录 书写脚本使用的相关知识&#xff1f; 备份和冗灾的区别&#xff1f;什么叫DD备份&#xff0c;什么叫DD冗灾&#xff1f; 关于Linux系统优化以及Linux的安全加固&#xff1f; 系统优化 硬件系统优化&#xff1a; 内核参数优化&#xff1a; 网络性能优化&#xff1a; 进程管…...

STM32 HAL库 L298N电机驱动模块实现

一、引言 在机器人、自动化设备等众多应用场景中&#xff0c;电机驱动是一个关键的部分。L298N 是一款常用的电机驱动模块&#xff0c;它可以驱动两个直流电机或一个步进电机。STM32F407 是一款高性能的 ARM Cortex-M4 内核微控制器&#xff0c;结合 HAL 库可以方便地实现对 L…...

Redis的Key的过期策略

我们都知道Redis的键值对是可以设置过期时间的&#xff0c;那么就会涉及到一个问题&#xff0c;Redis到底是如何做到响应快的同时有能快速地释放掉过期的键值对的呢&#xff1f;不卖关子了&#xff0c;直接说答案&#xff0c;那就是Redis两个策略&#xff1a;定期删除和惰性删除…...

ubuntu桌面版使用root账号进行登录

这里写自定义目录标题 第一步&#xff1a;给root账户设置密码&#xff0c;并切换至root账户第二步&#xff1a;注释gdm-autologin文件内的相关内容第三步&#xff1a;注释gdm-password文件内的相关内容第四步&#xff1a;重启系统即可使用root账户登录 第一步&#xff1a;给roo…...