Redis之与SSM集成Spring注解式缓存

news2024/11/23 22:21:55

🎉🎉欢迎来到我的CSDN主页!🎉🎉

🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚

🌟推荐给大家我的博客专栏《Redis实战开发》。🎯🎯

🎁如果感觉还不错的话请给我关注加三连吧!🎁🎁

💖期待你的加入,一起学习,一起进步!💖💖

目录

前言

一、Redis集成到SSM中

1. 导入pom.xml依赖配置

2. 注册一个redis.properties

 3. 新建spring-redis.xml文件

注意事项:

1.配置.properties文件注册事项

2. pom.xm配置注意事项 

3.  redisTemplate的使用

配置数据源

配置连接工厂 

配置序列化器

​编辑

配置缓存管理器

配置缓存生成键名的生成规则

CacheKeyGenerator.java

 4. spring-context.xml中配置

二、Redis注解开发及应用场景

1. 未使用注解开发

2. @Cacheable

2.1 概述及作用

 2.2 注解参数说明

2.3 案例演示

携带value参数的使用

 携带包含key参数的使用

携带 condition参数的使用

 情况一:符合条件

情况二:不符合触发条件 

3.  @CachePut

 3.2 参数说明

3.3 案例演示 

4. @CacheEvict

4.1 概述及作用

4.2 参数说明

 4.3 案例演示

三、Redis的三种极端现象

1. 击穿

概述

解决方案: 

2. 穿透

概述

解决方案

 3. 雪崩

概述

解决方案

本期的Redis系列博客分享到此结束啦

希望老铁关注加三连 

这是对博客最大的支持鼓励


前言

         在Redis系列的前面两期博客中带大家了解了有关Redis在Linux及Windows两个系统的安装及使用,然后有分享了java中如何去使用Redis操作Redis数据库。这期博客带大家一起了解SSM中集成Redis及其中的用法。

一、Redis集成到SSM中

1. 导入pom.xml依赖配置

        在项目的pom.xml中导入Redis的相关依赖。

         首先在properties标签中添加以下代码

<redis.version>2.9.0</redis.version>
    <redis.spring.version>1.7.1.RELEASE</redis.spring.version>

        然后在 dependencies的标签中添加以下依赖

<dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>${redis.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>${redis.spring.version}</version>
    </dependency>

         到此我们的pom.xml文件的配置就告一段落了

2. 注册一个redis.properties

        这个redis.properties文件是用于配置连接Redis客户端的文件,类似于我们之前配置MySQL数据库连接的jdbc.properties,用于编写连接的端口号、端口、账号、密码、最好连接数等等之类的,该文件也是用于后面有关redis.xml文件的配置。

redis.hostName=127.0.0.1--->(数据库名)
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

 3. 新建spring-redis.xml文件

        这是文件的作用是将Redis配置到我们的项目中去,以及读取redis.properties文件的信息。

<?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:cache="http://www.springframework.org/schema/cache"
       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/cache
       http://www.springframework.org/schema/cache/spring-cache.xsd">

    <!-- 1. 引入properties配置文件 -->
    <!--<context:property-placeholder location="classpath:redis.properties" />-->

    <!-- 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>

    <!-- 3. redis连接工厂 -->
    <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>

    <!-- 4. redis操作模板,使用该对象可以操作redis
        hibernate课程中hibernatetemplete,相当于session,专门操作数据库。
    -->
    <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>

    <!--  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>

    <!--6.配置缓存生成键名的生成规则-->
    <bean id="cacheKeyGenerator" class="com.zking.ssm.redis.CacheKeyGenerator"></bean>

    <!--7.启用缓存注解功能-->
    <cache:annotation-driven cache-manager="redisCacheManager" key-generator="cacheKeyGenerator"/>
</beans>

注意事项:

1.配置.properties文件注册事项

        当spring-context.xml文件中需要注册两个及两个以上的.peoperties文件时,不能在spring-*.xml中注册,因此只能在spring-context.xml文件中配置。因为一但分开单独注册则又一个文件的信息读取不到。

        因此我们会将spring-*.xml文件的注册代码注释掉(以spring-redis.xml为例)

        然后我们会在 spring-context.xml文件中进行总的设置配置

2. pom.xm配置注意事项 

        注意pom.xml文件中的resource标签的配置信息,resources的配置必须涵盖读取.properties结尾的文件。

3.  redisTemplate的使用

redisTemplate的使用可以参照jdbcTemplate/amqpTemplate...的使用,也就是序列化的配置

配置数据源

配置连接工厂 

配置序列化器

配置缓存管理器

        redis中有很多数据,例如:用户数据、数据字典数据、系统设置数据等,不同的数据有着不同的有效时间,用于设置时长当然这只是其中之一;也可以用于设置缓存的前缀

配置缓存生成键名的生成规则

CacheKeyGenerator.java
package com.zking.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;
    }
}

 4. spring-context.xml中配置

二、Redis注解开发及应用场景

1. 未使用注解开发

        我们编写一个测试类用于测试模拟从数据库中获取数据,以此来实现模拟数据库操作。

ClazzBizTest.java

package com.zking.shiro;

import com.zking.ssm.biz.ClazzBiz;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author小李飞刀
 * @site www.javaxl.com
 * @company xxx公司
 * @create  2022-10-26 15:29
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class ClazzBizTest {
    @Autowired
    private ClazzBiz clazzBiz;

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

    @Test
    public void test2(){
        clazzBiz.deleteByPrimaryKey(10);
    }
}

        当我们执行测试test1()方法时我们可以通过查看控制台输出的结果得知当我们调用两次查询方法时执行了两次数据库操作。(控制台输出如下图)

        接下来我们一起来看看使用Redis注解运行后的方法及应用场景 

2. @Cacheable

2.1 概述及作用

        @Cacheable用于具有返回值的方法,可以保存缓存键值对。一般用于查询操作。一般配置在方法或类上。简单的说就是即写入也读取。

        作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果, 下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找。

 2.2 注解参数说明

value:缓存位置的一段名称,不能为空
key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
condition:触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL 

2.3 案例演示

携带value参数的使用

        然后我们再在测试类去测试该方法,查看控制台的输出内容,看看是否与未使用注解式标签是一样。 

         由此看到第二次时我们访问的是缓存,如果我们再执行一次则一次都不会访问操作数据库,而是访问我们的缓存。

我们可以在Redis客户端上查看我们的缓存数据

 携带包含key参数的使用

        使用了key参数是表自定义生成key 

        当我们再次去执行被改标签使用了的方法时,会在Redis缓存库中重新生产一个根据自己定义的key。 

携带 condition参数的使用

        condition代表的是触发执行的条件,满足条件就执行方法加入缓存

        当我们分别执行一个符合条件一个不符合条件时,到redis缓存库中查看 

 情况一:符合条件

        查看redis的缓存库

 

情况二:不符合触发条件 

 

        由图可知,当我们未达到触发条件执行该方法则不会生成数据缓存在我们的redis库中生成数据缓存。

3.  @CachePut

3.1 概述及作用

        与@Cacheable类似,也可以保存缓存键值对。一般用于插入和修改操作。简单的说只写入不读取。

        作用:适用于写入或更新操作,需要将结果放入缓存并确保缓存的数据是最新的。每次调用被@CachePut注解的方法时,都会执行方法体内的逻辑,并将结果存入缓存中。

 3.2 参数说明

value :  缓存的名称,在 spring 配置文件中定义,必须指定至少一个
key :  缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
condition  :缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

3.3 案例演示 

        参数和Cacheable的用法一致,所以我来演示一下CachePut与Cacheable的区别

 

4. @CacheEvict

4.1 概述及作用

        用于void类型的方法,不需要保存任何值,一般用于删除缓存key的操作。

4.2 参数说明

value:缓存位置的一段名称,不能为空
key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
condition:触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL
allEntries:true表示清除value中的全部缓存,默认为false

 4.3 案例演示

        首先我们添加几条数据到我们的redis缓存数据库中,方便我们测试使用

 

        运行该方法在去查看redis缓存数据库 

        我们在redis客户端刷新数据库查看一下就会发现我们之前存储的数据被清理掉了 

三、Redis的三种极端现象

描述图

1. 击穿

概述

        在Redis中,击穿是指一个热点key,在高并发的请求下,由于这个key失效的瞬间,持续的高并发直接请求数据库。具体来说,当某个热点key失效或者被删除,而此时恰好有大量的请求正在访问这个key,这些请求就会直接穿透到数据库中,导致数据库压力骤增,甚至可能引发数据库崩溃等问题。

解决方案: 

  • 限流:请求redis之前做流量削峰
  • 设置热点key永不过期
  • 设置锁
  1. 1.获取 Redis 锁,如果没有获取到,则回到任务队列继续排队
  2. 2.获取到锁,从数据库拉取数据并放入缓存中
  3. 3.释放锁,其他请求从缓存中拿到数据

2. 穿透

概述

        在Redis中,缓存穿透是指查询一个根本不存在的数据,缓存层没有命中,然后去查数据库(持久层),数据库(持久层)也没有命中。 通常如果从存储层查不到数据则不写入缓存层。 比如:用户不断发起请求,通过文章的id来获取文章,如果这个id没有对应的数据,则每次都会请求到数据库。 如果这个用户是攻击者,在请求过多时会导致数据库压力过大,严重会击垮数据库。        

解决方案

1.规则排除
        可以增加一些参数检验。例如数据库数据 id 一般都是递增的,如果请求 id = -10 这种参数,势必绕过Redis。避免这种情况,可以对用户真实性检验等操作。

2.null值填充
        当缓存穿透时,redis存入一个类似null的值,下次访问则直接缓存返回空,当数据库中存在该数据的值则需要把redis存在的null值清除并载入新值,此方案不能解决频繁随机不规则的key请求。

3.双重检测加锁

        Redis在并发发情况下,发生多次访问数据库,可以使用双重检测加锁机制防止缓存击穿。

4.使用布隆过滤器

        布隆过滤器是一种数据结构,可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。如果想要判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定。同时检索速度也越来越慢。使用布隆过滤器可以避免将所有可能缓存的数据都保存下来,只需要将可能的数据保存即可,从而节省空间。

 3. 雪崩

概述

        在Redis中,雪崩是指缓存层发生故障或失效时,所有请求都会直接到达数据库层,导致数据库压力剧增,甚至崩溃的情况。缓存雪崩通常是由于缓存层承载了大量的请求,有效的保护了存储层,但如果缓存由于某些原因整体不能够提供服务,所有的请求就会到达存储层,存储层的调用量就会暴增,从而引发雪崩现象。缓存雪崩可能会发生在缓存服务器重启或者大量缓存集中在某一个时间段失效的情况下,此时大量数据会去直接访问数据库,给数据库带来很大的压力。

解决方案

  • 给不同的热点key设置不同的缓存策略
  • 使用分布式缓存
  • 使用锁来更新key

本期的Redis系列博客分享到此结束啦

希望老铁关注加三连 

这是对博客最大的支持鼓励

 

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

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

相关文章

大数据学习之Spark性能优化

文章目录 Spark三种任务提交模式宽依赖和窄依赖StageSpark Job的三种提交模式 Shuffle机制分析未优化的Hash Based Shuffle优化后的Hash Based ShuffleSort-Based Shuffle Spark之checkpointcheckpoint概述checkpoint与持久化的区别checkPoint的使用checkpoint源码分析 Spark程…

vue前端实现多个url下载并合并为zip文件

一、安装 npm install jszip npm install file-saver 二、引入 import axios from axios import JSZip from "jszip"; import FileSaver from "file-saver"; 三、核心代码 videoData:[/video/26519f026fc012521605563015227403.mp4,/video/f7b9cdae14…

聊聊芯片超净间的颗粒(particle)

在芯片制造领域&#xff0c;颗粒的存在可能对生产过程产生巨大影响。其中&#xff0c;每个微小的颗粒&#xff0c;无论是来自人员、设备&#xff0c;还是自然环境&#xff0c;都有可能在制程中引发故障&#xff0c;从而对产品性能产生负面影响。这就是为什么在芯片厂中&#xf…

【日积月累】SpringBoot 通过注解@CacheConfig @Cacheable @CacheEvict @CachePut @Caching使用缓存

目录 1.前言2.引入依赖3.启动类加入注解EnableCaching4.常用注解4.1CacheConfig4.2Cacheable4.3CacheEvict4.4CachePut4.5Caching 5.总结6.参考 文章所属专区 日积月累 1.前言 Spring在3.1版本&#xff0c;就提供了一条基于注解的缓存策略&#xff0c;实际使用起来还是很丝滑…

【内功修炼】详解函数栈帧的创建和销毁

文章目录 1. 什么是函数栈帧2. 理解函数栈帧能解决什么问题呢&#xff1f;3. 函数栈帧的创建和销毁解析3.1 什么是栈&#xff1f;3.2 认识相关寄存器和汇编指令常见寄存器常用汇编指令 3.3 详解函数栈帧的创建和销毁3.3.1 函数的调用堆栈&#xff08;main函数也是被其它函数调用…

手握“发展密钥”,TCL科技或迎价值重估?

在高度竞争且快速变化的泛半导体产业&#xff0c;每一次周期性或结构性的变化&#xff0c;都会对企业经营策略带来深远的影响。 2023年前三季度&#xff0c;泛半导体产业迎来结构性复苏。其中&#xff0c;主流显示领域供需关系趋向健康化&#xff0c;半导体显示行业整体上量价…

C语言 每日一题 PTA 11.7 day13

1.求e的近似值 自然常数 e 可以用级数 1 1 / 1! 1 / 2! ⋯ 1 / n! ⋯ 来近似计算。 本题要求对给定的非负整数 n&#xff0c;求该级数的前 n 1 项和。 代码实现 #include<stdio.h> void main() {int a, i, j; double b 1; double c 1;printf("请输入一个数\n…

零信任安全:构建无懈可击的网络防护体系

随着网络技术的飞速发展&#xff0c;信息安全问题日益凸显&#xff0c;传统的安全防护手段已经无法满足复杂多变的安全需求。在此背景下&#xff0c;零信任安全模型逐渐受到广泛关注。本文将探讨零信任安全的概念、优势以及如何构建无懈可击的网络防护体系。 一、零信任安全概念…

Go语言用Colly库编写的图像爬虫程序

下面是一个使用Colly库编写的Go语言图像爬虫程序&#xff0c;该程序会爬取news.qq上的图片&#xff0c;并使用proxy_host:duoip和proxy_port:8000的爬虫IP服务器进行抓取。 package mainimport ("fmt""net/http""github.com/crawlab-collective/go-co…

511-0101-08B 5136-PFB-VME DCS是工厂级数字化的核心

511-0101-08B 5136-PFB-VME DCS是工厂级数字化的核心 在一个预计到2023年全球将达到174亿美元的不断增长的市场中&#xff0c;行业分析公司ARC Advisory Group的一份市场分析报告证实&#xff0c;ABB将其在分布式控制系统(DCS)市场的份额增加到20.0%&#xff0c;保持了其在20世…

木牛第三代4D成像雷达,为高速/城市级NOA的普及化提速

为助力中国汽车行业高速、高质量的发展&#xff0c;推动中国汽车行业智能化向纵深发展&#xff0c;由《证券日报》社与江西省金融控股集团主办、轩元资本与江西省金控投资集团协办的“2023汽车资本论坛”于2023年10月27日在江西南昌举办&#xff0c;本次论坛指导单位为中国经济…

那些年遇到过的问题与解决方案

目录 一、当我们想进行数据回显并且只是让用户查看信息不能编辑时&#xff0c;置灰处理 二、多选框初始化加载问题 三、时间处理 获取当前年月日 时间自定义格式化 时间脱敏处理&#xff0c;去掉秒 四、input输入框处理 input输入框设定为只能输入0与正整数 刚进页面…

macOS磁盘分区调整软件--Paragon Camptune X 中文

Paragon Camptune X是一款专为Mac用户设计的强大分区大小调整工具。通过它&#xff0c;用户可以简便地调整Mac硬盘上的分区大小&#xff0c;实现存储空间的高效管理。无论是需要在Mac和Windows系统之间切换的双系统用户&#xff0c;还是有其他特定存储需求的用户&#xff0c;Ca…

携手创新算网应用:英特尔助力中国移动“算启新程”

10月11日&#xff0c;以“算启新程 智享未来”为主题的2023中国移动全球合作伙伴大会在中国广州保利世贸博览馆拉开帷幕。 大会围绕“CT、IT、DT技术融合”、“连接、算力、能力服务融合”、“新一代信息技术与生产、生活、治理应用融合”三个融合&#xff0c;聚焦科技创新、行…

(11_06)函数计算 FC 3.0 发布,全面降价,最高幅度达93%,阶梯计费越用越便宜

作为国内最早布局 Serverless 的云厂商之一&#xff0c;阿里云在 2017 年推出函数计算 FC&#xff0c;开发者只需编写代码并上传&#xff0c;函数计算就会自动准备好相应的计算资源&#xff0c;大幅简化开发运维过程。阿里云函数计算持续在 Serverless GPU 方面投入研发&#x…

Cmasher颜色包--共53种--全平台可用

Cmasher颜色包–共53种–全平台可用 往期推荐&#xff1a; ColorCET颜色包–共99种–全平台可用 ColorCET颜色包–共35种–全平台可用 Scientific colour maps颜色包–共35种–全平台可用 SciCoMap颜色包_共180种–全平台可用 海洋专用cmocean颜色包_共22种–全平台可用 Python…

pytoch安装指定版本教程pytorch1.3安装笔记

一、先生成一个环境 如果电脑里安装了其他的torch版本&#xff0c;另外生成一个环境可以防止原先torch版本被替换掉。 打开conda的终端窗口输入以下命令就可以生成一个名为torch_1.3的环境&#xff1a; conda create -n torch_1.3 python3.6 输入以下命令进入到torch_1.3的…

工作记录---(Explain执行计划详解--基于HS)--每天都要保持学习状态和专注的状态啊!!!

Explain详细说明&#xff1a; id列 id列的编号是 select 的序列号&#xff0c;有几个 select 就有几个id&#xff0c;并且id的顺序是按 select 出现的顺序增长的。MySQL将 select 查询分为简单查询(SIMPLE)和复杂查询(PRIMARY)。 复杂查询分为三类&#xff1a;简单子查询、派…

MXNet中图解稀疏矩阵(Sparse Matrix)的压缩与还原

1、概述 对于稀疏矩阵的解释&#xff0c;就是当矩阵里面零元素远远多于非零元素&#xff0c;且非零元素没有规律&#xff0c;这样的矩阵就叫做稀疏矩阵&#xff0c;反过来就是稠密矩阵&#xff0c;其中非零元素的数量与所有元素的比值叫做稠密度&#xff0c;一般稠密度小于0.0…

妙用Java 8中的 Function接口,消灭if...else(非常新颖的写法)

文章目录 Function 函数式接口Supplier供给型函数Consumer消费型函数Runnable无参无返回型函数Function函数的表现形式为接收一个参数&#xff0c;并返回一个值。Supplier、Consumer和Runnable可以看作Function的一种特殊表现形式 使用小技巧处理抛出异常的if处理if分支操作如果…