SSM整合redis及redis的注解式开发和解决Redis缓存问题

news2024/12/24 3:42:08

一.SSM整合Redis

1.pom配置

用于解决运行时没有将数据库配置信息jdbc.properites加载到target文件中

<resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>*.properties</include>
          <include>*.xml</include>
        </includes>
      </resource>

2.配置spring-redis.xml

2.1 注册redis.properties

redis.hostName=localhost
redis.port=6379
redis.password=123456
redis.timeout=10000
redis.maxIdle=300
redis.maxTotal=1000
redis.maxWaitMillis=1000
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=1024
redis.timeBetweenEvictionRunsMillis=30000
redis.testOnBorrow=true
redis.testWhileIdle=true
redis.expiration=3600

2.2 配置redis连接池

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!--最大空闲数-->
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <!--连接池的最大数据库连接数  -->
        <property name="maxTotal" value="${redis.maxTotal}"/>
        <!--最大建立连接等待时间-->
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
        <!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->
        <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/>
        <!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->
        <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/>
        <!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->
        <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/>
        <!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        <!--在空闲时检查有效性, 默认false  -->
        <property name="testWhileIdle" value="${redis.testWhileIdle}"/>
    </bean>

2.3 配置连接工厂

<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          destroy-method="destroy">
        <property name="poolConfig" ref="poolConfig"/>
        <!--IP地址 -->
        <property name="hostName" value="${redis.hostName}"/>
        <!--端口号  -->
        <property name="port" value="${redis.port}"/>
        <!--如果Redis设置有密码  -->
        <property name="password" value="${redis.password}"/>
        <!--客户端超时时间单位是毫秒  -->
        <property name="timeout" value="${redis.timeout}"/>
    </bean>

2.4 配置序列化器

 <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <!--开启事务  -->
        <property name="enableTransactionSupport" value="true"/>
    </bean>

2.5 配置缓存管理器

<bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate"/>
        <!--redis缓存数据过期时间单位秒-->
        <property name="defaultExpiration" value="${redis.expiration}"/>
        <!--是否使用缓存前缀,与cachePrefix相关-->
        <property name="usePrefix" value="true"/>
        <!--配置缓存前缀名称-->
        <property name="cachePrefix">
            <bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix">
                <constructor-arg index="0" value="-cache-"/>
            </bean>
        </property>
    </bean>

2.6 配置redis的key生成策略

在Spring框架中,缓存键生成器用于生成缓存中存储的键,以便于识别和检索缓存数据

package com.YU.ssm.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.util.ClassUtils;

import java.lang.reflect.Array;
import java.lang.reflect.Method;

@Slf4j
public class CacheKeyGenerator implements KeyGenerator {
    // custom cache key
    public static final int NO_PARAM_KEY = 0;
    public static final int NULL_PARAM_KEY = 53;

    @Override
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder key = new StringBuilder();
        key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
        if (params.length == 0) {
            key.append(NO_PARAM_KEY);
        } else {
            int count = 0;
            for (Object param : params) {
                if (0 != count) {//参数之间用,进行分隔
                    key.append(',');
                }
                if (param == null) {
                    key.append(NULL_PARAM_KEY);
                } else if (ClassUtils.isPrimitiveArray(param.getClass())) {
                    int length = Array.getLength(param);
                    for (int i = 0; i < length; i++) {
                        key.append(Array.get(param, i));
                        key.append(',');
                    }
                } else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) {
                    key.append(param);
                } else {//Java一定要重写hashCode和eqauls
                    key.append(param.hashCode());
                }
                count++;
            }
        }

        String finalKey = key.toString();
//        IEDA要安装lombok插件
        log.debug("using cache key={}", finalKey);
        return finalKey;
    }
}

生成逻辑:

  1. 如果方法没有参数,缓存键被设置为类名 + 方法名 + ":0"(NO_PARAM_KEY)。
  2. 如果方法有参数,缓存键由类名 + 方法名 + ":" + 参数的组合构成。参数之间用逗号分隔。具体的参数值会被加入到缓存键中,如果参数为null,则用NULL_PARAM_KEY(53)表示;如果参数是基本数据类型、包装类或字符串,则直接将参数值加入缓存键;如果参数是其他对象类型,则将其hashCode()的返回值加入缓存键。

这样生成的缓存键具有类似以下的形式:

com.example.SomeClass.someMethod:parameter1,parameter2,53,parameter4

这个缓存键生成器的实现允许在方法参数不同的情况下生成不同的缓存键,以便于确保缓存的正确性

3.Springcontext.xml中添加spring-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--1. 引入外部多文件方式 -->
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreResourceNotFound" value="true" />
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
                <value>classpath:redis.properties</value>
            </list>
        </property>
    </bean>


    <import resource="applicationContext-mybatis.xml"></import>
    <import resource="spring-redis.xml"></import>
    <import resource="applicationContext-shiro.xml"></import>
</beans>

 注意点:

1.当spring上下文中的注册信息文件出现两个及以上,不能在单独的配置文件信息中进行配置,要全部整合到spring上下文的配置文件中进行配置

2.当有*.properties文件需要编译时要到pom文件中进行配置

二.Redis的注解式开发

1.简介

  1. 简化代码:注解式开发可以显著减少与Redis相关的样板代码。通过使用注解,你可以在方法上直接标记缓存操作,而不必在每个方法中手动编写缓存逻辑。

  2. 提高开发效率:通过使用注解,开发者可以更容易地实现缓存功能,减少了手动处理缓存的复杂性。这使得开发者可以专注于业务逻辑的实现,而不必花费过多时间在缓存的管理和维护上。

  3. 降低错误风险:手动管理缓存可能会导致错误,例如忘记在适当的时机清除缓存,或者在更新数据时没有及时更新缓存。使用注解可以减少这些潜在的错误,提高了代码的可靠性。

  4. 提升性能:通过缓存常用数据,可以显著提升应用程序的性能和响应速度。注解式开发使得缓存的使用变得更加便捷,可以更灵活地选择何时以及如何使用缓存。

  5. 减少重复劳动:在传统的手动缓存管理中,你可能会在每个方法中都编写类似的缓存逻辑。通过使用注解,可以将缓存逻辑抽象到通用的注解中,从而减少了重复的劳动。

  6. 提升可维护性:通过使用注解,缓存的管理变得更加集中和清晰。开发者可以在方法上直接看到哪些操作会涉及到缓存,从而使得代码更易于理解和维护。

总的来说,使用Redis的注解式开发可以简化缓存管理,提高开发效率,降低错误风险,提升应用程序的性能,减少重复劳动,同时也提升了代码的可维护性

2.实际开发应用

2.1 测试方法

@CachePut(value = "xx",key = "'cid:'+#cid",condition = "#cid > 6")
    Clazz selectByPrimaryKey(Integer cid);

测试类

@Test
    public void test1(){
        System.out.println(clazzBiz.selectByPrimaryKey(10));
        System.out.println(clazzBiz.selectByPrimaryKey(10));
    }

 测试结果

结论:当我们使用redis注解式开发时,第一次执行会查询我们的关系型数据库,但是在执行完成后会加入我们的缓存中,在第二次进行查询时,会查询我们的缓存,也就是查询我们的redis,这样做大大提高了我们查询的效率,而且还可以减轻我们数据库的压力 

2.2 @Cacheable和Cacheput的区别

(1)@Cacheable

@Cacheable 注解用于标记一个方法的结果应该被缓存,以便下次相同的方法调用可以直接返回缓存的结果,而不必再次执行方法体。它有以下主要属性:

  • value:指定缓存的名称,通常用于区分不同的缓存。

  • key:用于指定缓存的键值,可以是 SpEL 表达式,根据方法的参数动态生成缓存的键。

  • condition:指定一个 SpEL 表达式,如果为 true,则进行缓存,否则不进行缓存。

  • unless:与 condition 相反,如果为 true,则不进行缓存。

 

(2)@CachePut:

@CachePut 注解用于标记一个方法的结果应该被存储到缓存中,通常在创建或更新操作后使用。与 @Cacheable 不同,它不检查缓存中是否已存在相同的键,而是强制将方法的结果存储到缓存中。它的主要属性包括:

  • value:指定缓存的名称。
  • key:用于指定缓存的键值,通常也可以使用 SpEL 表达式。
  • condition:指定一个 SpEL 表达式,如果为 true,则进行缓存,否则不进行缓存。
  • unless:与 condition 相反,如果为 true,则不进行缓存。

小结:

  • @Cacheable 用于从缓存中获取数据,如果数据已存在于缓存中,将直接返回缓存数据,否则执行方法体并将结果存储到缓存中。
  • @CachePut 用于强制将方法的结果存储到缓存中,无论之前是否存在相同的缓存键。
  • 两者都可以使用 value 属性来指定缓存的名称,以及 key 属性来指定缓存的键。条件判断可以使用 condition 和 unless 属性来控制是否执行缓存操作。

这些注解通常与缓存管理器(如EhCache、Redis等)一起使用,以配置和管理应用程序中的缓存

 

2.3 @CacheEvict

主要作用:在方法执行之后从缓存中移除特定的条目,以保持缓存的一致性。下面是 @CacheEvict 的一些主要特点和用法:

  1. 清除缓存条目:

    • @CacheEvict 主要用于清除指定缓存中的某个或某些缓存条目。
  2. 注解属性:

    • value:用于指定要清除的缓存的名称。
    • key:用于指定要清除的缓存条目的键,支持使用 SpEL 表达式动态生成。
    • allEntries:如果设置为 true,表示清除指定缓存中的所有条目。
    • beforeInvocation:指定是否在方法执行之前执行缓存清除操作。默认情况下,在方法执行之后清除缓存,但如果设置为 true,将在方法执行之前清除缓存。
  3. 条件清除:

    • 可以使用 condition 和 unless 属性来进行条件清除,类似于 @Cacheable 和 @CachePut
@CacheEvict(value = "myCache", key = "#userId")
public void deleteUserFromCache(String userId) {
    
}

三.解决Redis缓存问题

Redis的击穿、穿透、雪崩是三种与缓存相关的常见问题,它们通常被统称为"缓存问题三兄弟"

1.缓存查询

要理解缓存击穿,首先要理解redis的缓存查询

 

Redis 缓存查询是指在使用 Redis 作为缓存时,应用程序首先尝试从 Redis 缓存中获取数据,如果缓存中存在数据,那么可以直接返回,从而减轻后端数据库的负担。这是缓存的正常使用场景,它可以大大提高应用程序的性能和响应时间。

常见的 Redis 缓存查询流程如下:

  1. 应用程序检查 Redis 缓存中是否存在所需数据。
  2. 如果数据存在,应用程序直接从 Redis 中获取并返回数据。
  3. 如果数据不存在,应用程序从后端数据库中获取数据,并将其存储到 Redis 缓存中,以供后续查询使用。

2.Redis击穿

Redis 缓存击穿是指在大并发情况下,有大量的请求同时查询某个不存在于缓存中的数据,导致这些请求都穿透 Redis 缓存,直接访问后端数据库。这会导致数据库负载急剧增加,降低了性能,甚至可能导致数据库宕机。

主要原因是某个热点数据失效,然后有大量请求同时尝试获取相同的数据,而这个数据不在缓存中。解决 Redis 缓存击穿问题的方法包括:

  • 使用互斥锁:在缓存失效时,使用互斥锁来阻止多个线程同时访问后端数据库,只有一个线程去加载数据,其他线程等待加载完成后再从缓存中获取。
  • 设置短暂的缓存过期时间:即使数据失效,也不至于在短时间内导致大量请求穿透缓存。
  • 预热缓存:在启动应用程序时,加载一些热门数据到缓存中,以减少冷启动时的击穿问题。

小结:

Redis 缓存查询是一种有效的性能优化手段,但在高并发情况下可能会出现缓存击穿问题。为了解决击穿问题,可以采取锁、合理的缓存设置以及预热等策略,以保护后端数据库免受不必要的负担

3.Redis穿透

3.1 简介

Redis 缓存穿透是指恶意或异常请求,通常是查询一个不存在于缓存中的键,导致大量请求穿透 Redis 缓存,直接访问后端数据存储系统(通常是数据库)。这种情况会增加后端数据库的负担,降低性能,甚至导致数据库崩溃

  1. 恶意请求:攻击者故意发送不存在于缓存中的键来进行恶意攻击,例如通过构造恶意的查询参数。

  2. 异常查询:当应用程序中没有足够的保护来处理异常情况时,可能会导致查询非常频繁的不存在的键,例如使用无效的用户标识。

3.2 解决措施

  1. 缓存空对象或哨兵值:当一个请求查询到不存在的数据时,可以将一个特殊的哨兵值(如null)存储在缓存中,以表示该键确实在数据存储中不存在。这样,在下一次请求相同键时,可以立即从缓存中获取哨兵值而不访问数据库,从而减轻数据库负担。

  2. 使用布隆过滤器:布隆过滤器是一种数据结构,可以用于快速确定某个数据是否存在于缓存中。如果布隆过滤器显示数据不存在,可以直接拒绝查询,而不访问数据库或缓存。这可以有效减少缓存穿透。

  3. 合理设置缓存失效时间:设置合适的缓存失效时间,避免长时间持有无效的缓存数据。这样可以防止在失效期间频繁访问数据库。

  4. 限制请求频率:在应用程序层面,可以实施请求频率限制,以防止频繁的请求击穿缓存。

小结:

防止 Redis 缓存穿透需要综合考虑多种策略,包括设置合理的缓存策略、使用哨兵值或布隆过滤器,以及在应用程序中增加异常查询的保护

4.Redis雪崩

4.1 简介

Redis 雪崩是指在某个时间点,大量缓存键同时失效,导致大量请求直接访问后端数据存储系统,从而对系统性能和可用性造成严重影响的情况

  1. 大规模缓存失效:当大量的缓存键在相同时间内失效,通常是因为这些键设置了相同的失效时间,或者是由于系统维护操作(如 Redis 重启)导致的。这会导致大量请求同时涌入后端数据存储系统。

  2. 热门数据集:如果系统中有一组特别热门的缓存数据,当这些缓存键同时失效并被请求时,会导致大量请求竞争获取相同的数据,增加了后端存储的负载

4.2 解决措施

  1. 合理设置缓存失效时间:避免将所有缓存键设置相同的失效时间。通过将失效时间分散,可以减少大规模失效的概率。

  2. 使用随机失效时间:将缓存键的失效时间设置为一个随机值,而不是固定的时间,以避免同时失效。

  3. 持久化备份:定期将缓存数据持久化到磁盘,以防止 Redis 重启时丢失所有数据。

  4. 热点数据预热:对于热门的数据集,可以在合适的时机手动刷新缓存,而不是等待缓存失效。

  5. 分布式缓存:使用多台 Redis 服务器来分担负载,以降低单点故障的风险。

  6. 请求限流:在应用程序层面,实施请求限流措施,以避免过多的请求同时涌入 Redis。

  7. 监控和报警:建立监控系统,实时监控 Redis 的性能和状态,以及缓存键的失效情况,及时发现问题并采取措施应对

小结:

总之,防止 Redis 雪崩需要综合考虑多种策略,包括设置合理的失效时间、持久化备份、数据预热、请求限流以及监控系统

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

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

相关文章

《巧用ChatGPT快速提高职场晋升力》书籍推荐【包邮送书五本】

文章目录 书籍介绍内容介绍ChatGPT 在人工智能助手领域的应用1 智能客服2 语音助手3 个人助手4 内容创作与编辑5 数据分析与报告生成6 社交媒体管理7 智能编程助手 抽奖送书 书籍介绍 ★超实用 通过30多个实战案例和操作技巧&#xff0c;使读者能够快速上手并灵活运用ChatGPT技…

操作系统:银行家算法

文章目录 银行家算法一、实验目的二、实验要求与内容、过程与结果 系列文章 银行家算法 一、实验目的 1、理解银行家算法。 2、掌握进程安全性检查的方法及资源分配方法。 二、实验要求与内容、过程与结果 1、将图5-1补充完整&#xff0c;画出银行家算法的流程图。 图5-1 银…

el-table给某一行加背景色

数据列表中总价大于100的一行背景色为红色&#xff0c;效果图如下&#xff1a; 代码示例&#xff1a; <template><div id"app"><!-- 测试区域&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&am…

正式发布!万应低代码入选中国信通院《2023高质量数字化转型技术解决方案集》

随着科技的快速发展和市场竞争的日益激烈&#xff0c;数字化转型已成为企业持续发展和提升竞争力的关键。然而&#xff0c;在数字化转型的过程中&#xff0c;许多企业面临着诸多痛点&#xff0c;如缺乏先进的技术与方案、难以实现数据互通和集成、无法有效提升业务效率与规模。…

Redis-----SSM整合redis及redis的注解式开发以及redis的击穿,穿透,雪崩三种解决方案

目录 SSM项目整合Redis 导入pom依赖 配置文件spring-redis.xml redis.properties 配置redis的key生成策略 redis的注解式开发及应用场景 什么是redis的注解式 redis注解式的场景应用 Cacheable 自定义策略 Cacheable可以指定三个属性&#xff0c;value、key和condition…

自制圆形时钟⏰

如果想着做一个类似的家里的圆形时钟的样式的钟表&#xff0c;可以使用这样的方法&#xff1a; #import "ViewController.h" interface ViewController () property (nonatomic,weak)CALayer *second; property (nonatomic ,weak)CALayer *minute; property (nona…

内存卡读不出来怎么办?正确解决方法看这!

“不知道大家有没有遇到过内存卡读不出来的情况呀&#xff1f;我内存卡里还有很多重要的文件和材料&#xff0c;现在都无法读取&#xff0c;有什么方法可以帮我解决这个问题吗&#xff1f;” 内存卡的使用越来越频繁&#xff0c;可能很多用户会将比较重要的文件都保存在内存卡中…

【Python基础】 Python设计模式之单例模式介绍

单例模式 1.设计模式2.单例设计模式的应用场景3.new方法4. Python 中的单例 1.设计模式 设计模式 是 前人工作的总结和提炼&#xff0c;通常&#xff0c;被人们广泛流传的设计模式都是针对 某一特定问题 的成熟的解决方案使用 设计模式 是为了可重用代码、让代码更容易被他人理…

只需两步折叠GoLand的控制台中多余的信息,控制台显示无效内容太多(GOROOT、GOPATH)

一、问题&#xff1a;Goland控制台无效内容过多&#xff1a; GoLand的控制台显示无效内容太多&#xff08;GOROOT、GOPATH&#xff09;&#xff0c;一键将折叠控制台多余的信息&#xff0c;如图所示&#xff1a; 二、解决方法&#xff1a; 第一步&#xff1a;Window系统是&am…

【网络编程】如何将UDP协议变得更可靠

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

Verilog刷题[hdlbits] :Always case

题目&#xff1a;Always case Case statements in Verilog are nearly equivalent to a sequence of if-elseif-else that compares one expression to a list of others. Its syntax and functionality differs from the switch statement in C. Verilog中的Case语句几乎等同…

答题小程序排位pk答题怎么玩

答题小程序排位PK答题升级赛是一个备受喜爱的功能&#xff0c;它不仅增加了用户之间的互动和竞争&#xff0c;同时也为答题小程序增添了更多的趣味性和挑战性。那么&#xff0c;如何参与答题小程序的排位PK答题升级赛呢&#xff1f;本文将详细介绍答题小程序的排位PK答题升级赛…

网络安全与TikTok:年轻一代的数字素养

在数字时代&#xff0c;互联网成为我们生活的重要组成部分&#xff0c;而社交媒体平台则在年轻一代中变得日益流行。其中&#xff0c;TikTok作为一个短视频分享平台&#xff0c;吸引了全球数以亿计的用户&#xff0c;尤其年轻人。 然而&#xff0c;与其快速的普及相伴随的是网…

思维模型 首因效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。先入为主&#xff0c;一见钟情。 1 首因效应的应用 1.1 面试中的首因效应 小李是一名应届毕业生&#xff0c;他准备参加一家知名互联网公司的面试。在面试前&#xff0c;他做了充分的准备…

leetcode 215. 数组中的第K个最大元素

2023.11.7 本题两个思路&#xff0c;一个是先将数组排序&#xff0c;再从后往前数第k个元素即为第k个最大的元素。 或者使用优先队列&#xff0c;将数组元素放入队列中&#xff0c;当队列元素数量超过k时&#xff0c;弹出队列元素&#xff0c;由于优先队列的性质&#xff0c;每…

CodeWhisperer 的正确使用

1、重点&#xff1a; 重点1&#xff1a; 推出 Amazon Bedrock。这项新服务允许用户通过 API 访问来自 AI21 Labs、Anthropic、Stability AI 和亚马逊的基础模型。&#xff08;Anthropic 就是之前跟 ChatGPT 掰手腕的 Claude 的模型。Stability AI 就是 Stable Diffusion 背后的…

外汇天眼:如何识破网络交友诈骗套路? 看到这7大特征请提高警觉

随着各种社群平台与交友APP不断推陈出新&#xff0c;现代人愈来愈习惯透过网路建立人际关系甚至谈恋爱。 但由于网络具有极高的匿名性&#xff0c;因此也成为诈骗温床&#xff0c;对社会造成相当严重的损失。 有鉴于此&#xff0c;外汇天眼根据一直以来收到针对黑平台的投诉与…

各省市30米分辨率DEM数据,推荐下载!

今天给大家推荐一个新数据 —— 各省市30米分辨率DEM数据&#xff01; 各省市30米分辨率DEM数据广泛应用于国土资源调查、水利水电工程、地质灾害预警、城市规划等领域&#xff0c;对于了解区域内的地形地貌、地形分析、土地利用等具有非常重要的意义。 网站搜索“citybox城市…

数据时代的新引擎:数据治理与开发,揭秘数据领域的黄金机遇!

文章目录 一、数据时代的需求二、数据治理与开发三、案例分析四、黄金机遇《数据要素安全流通》《Python数据挖掘&#xff1a;入门、进阶与实用案例分析》《数据保护&#xff1a;工作负载的可恢复性 》《Data Mesh权威指南》《分布式统一大数据虚拟文件系统 Alluxio原理、技术与…

Microsoft 365 与Office 365 有什么区别?

从2020年起&#xff0c;部分Office 365 品牌的订阅计划整合到了Microsoft 365中&#xff0c;虽然这更符合微软对产品战略的定位&#xff0c;但却增加了用户分辨这两种产品的难度。 文章目录 Office 365包含哪些内容Microsoft 365包含哪些内容Microsoft 365包含哪些订阅Microso…