Redis之与SSM集成Spring注解式缓存
🎉🎉欢迎来到我的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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/cachehttp://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操作模板,使用该对象可以操作redishibernate课程中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 keypublic static final int NO_PARAM_KEY = 0;public static final int NULL_PARAM_KEY = 53;@Overridepublic 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和eqaulskey.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 {@Autowiredprivate ClazzBiz clazzBiz;@Testpublic void test1(){System.out.println(clazzBiz.selectByPrimaryKey(10));System.out.println(clazzBiz.selectByPrimaryKey(10));}@Testpublic 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.获取 Redis 锁,如果没有获取到,则回到任务队列继续排队
- 2.获取到锁,从数据库拉取数据并放入缓存中
- 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系列博客分享到此结束啦
希望老铁关注加三连
这是对博客最大的支持鼓励
相关文章:

Redis之与SSM集成Spring注解式缓存
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《Redis实战开发》。🎯🎯 …...

Android 安卓 Soong构建系统——Blueprint Android.bp配置文件解析
文章目录 Android.bp起源Android.bp文件结构如何编写Android.bp文件实例详解实例1实例2 常见问题解答1. 如何确定使用哪种模块类型?2. 如何指定模块的依赖项?其他疑问可参考官方文档 参考文章:Android.bp 语法和使用 Android.bp起源 早期的A…...

【Redis】SSM整合Redis注解式缓存的使用
【Redis】SSM整合Redis&注解式缓存的使用 一、SSM整合Redis1.2.配置文件spring-redis.xml1.3.修改applicationContext.xml1.4.配置redis的key生成策略 二、Redis的注解式开发及应用场景2.1.什么是Redis注解式2.实列测试 三、Redis中的击穿、穿透、雪崩的三种场景 一、SSM整…...

lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别
lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别 介绍for循环参数ipairs和pairs whilerepeat until总结 介绍 这里我用while、for、repeat until分别输出1-20之间的奇数 ,具体的语法可以看下面的代码 for循环 参数 定义一个初始值为start…...

Linux 进程的管道通信
文章目录 无名管道pipe有名管道 进程之间的通信:Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到,所以进程之间不能相互访问,要交换数据必须通过…...
OpenGL和Vulkan比较
比较 见参考 参考 Reference GuidesCopyright 2022-2023 The Khronos Group Inc. :: Vulkan Documentation ProjectDifference Between OpenGL vs VulkanVulkan与OpenGL对比——Vulkan的全新渲染架构 图形程序接口:OpenGL、OpenCL、Vulkan、OpenGL ES、WebGL…...
OpenCV入门3:像素操作
在OpenCV中,图像的像素值是以一个多维数组的形式表示的。上一篇已经介绍了cv::Mat类。对于图像中的每一个像素,可以通过Mat对象中的at<type>(i,j)函数(type可以是uchar、int等)获得Mat对象的像素值。 访问像素值࿱…...

使用内网穿透工具,远程测试本地接口
学习目标: 目标 含义: 内网穿透工具是一种能够帮助没有公网IP或者动态IP用户进行远程访问内网应用的工具。通过内网穿透,用户无论身处任何网络环境,都可以方便地访问企业内部的ERP、OA、CRM等应用。内网穿透工具还支持默认的Htt…...

uniapp小程序才到第五层就报错navigateto:fail webview count limit exceed
错误截图 原因 小程序官方描述是说可以跳转10层,但是使用uniapp开发的程序在小程序中才运行到第五层就报错了,原因是因为没有设置appId。如果设置了就正常了。...

【C++】map set
map & set 一、关联式容器二、键值对三、树形结构的关联式容器1. set(1)set 的介绍(2)set 的使用 2. multiset3. map(1)map 的介绍(2)map 的使用 4. multimap 四、map 和 set 的…...

正点原子嵌入式linux驱动开发——Linux Regmap驱动
在前面学习I2C和SPI驱动的时候,针对I2C和SPI设备寄存器的操作都是通过相关的API函数进行操作的。这样Linux内核中就会充斥着大量的重复、冗余代码,但是这些本质上都是对寄存器的操作,所以为了方便内核开发人员统一访问I2C/SPI设备的时候&…...

京东商品详情API,页面信息采集,优惠券信息获取
京东开放平台提供了API接口来访问京东商品详情。通过这个接口,您可以获取到商品的详细信息,如商品名称、价格、库存量、描述等。额外还附加一个优惠券信息接口。代码如下: 京东获得JD商品详情 API 优惠券接口 公共参数 名称类型必须描述keyString是调…...

Visual Studio 2022 + OpenCV 4.5.2 安装与配置教程
目录 OpenCV的下载与配置Visual Studio 2022的配置新建工程新建文件新建项目属性表环境配置测试先写一个输出将OpenCV的动态链接库添加到项目的 x64 | Debug下测试配置效果 Other OpenCV的下载与配置 参考这个OpenCV的下载与环境变量的配置: Windows10CLionOpenCV4…...
docker 安装 mysql (单体架构)
文章归档:https://www.yuque.com/u27599042/coding_star/nckzqa73g47hgz3x 查询 MySQL 镜像 docker search mysql拉取 MySQL 镜像 docker pull mysql在宿主机创建映射目录 mkdir -p \ /home/docker/mysql/log \ /home/docker/mysql/data \ /home/docker/mysql/co…...

城市内涝怎么预警?万宾科技内涝积水监测仪
在城市运行过程中,城市内涝问题频繁出现,影响城市管理水平的提升,也会进一步减缓城市基础设施建设。尤其近几年来,城市内涝灾害频繁出现,在沿海地区内涝所带来的安全隐患成为城市应急管理部门的心头大患。城市内涝的背…...

Spring基础(2):放弃XML,走向注解
上一篇并没有实际地带大家去看源码,而是介绍了两个概念: BeanDefinitionBeanPostProcessor 当然,我介绍得非常笼统,不论是BeanDefinition还是BeanPostProcessor其实都有着较为复杂的继承体系,种类也很多。作为Spring…...

【线性代数】分块矩阵总结
...

Redis-命令操作Redis->redis简介,redis的安装(Linux版本windows版本),redis的命令
redis简介redis的安装(Linux版本&windows版本)redis的命令 1.redis简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。 它支持字符串、哈…...

17、Python虚拟环境:为何要用虚拟环境、如何使用virtualenv
文章目录 在Python开发中,虚拟环境是一个独立的目录树,可以在其中安装Python模块。每个虚拟环境都有自己的Python二进制文件和一组安装的库。使用虚拟环境的主要原因是为了避免项目间的依赖冲突,允许每个项目有其特定的依赖,而不影响全局安装的模块。 为何要用虚拟环境 依…...
elasticSearch 接口实现查询热词统计
前面讲过使用elasticsearch可视化工具可以直接写语法查询如下: GET robot-demand/_search { "size":10, //查询多少条数据 "aggs":{ "hot_words":{ "terms":{ "field": "title" } }…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...
raid存储技术
1. 存储技术概念 数据存储架构是对数据存储方式、存储设备及相关组件的组织和规划,涵盖存储系统的布局、数据存储策略等,它明确数据如何存储、管理与访问,为数据的安全、高效使用提供支撑。 由计算机中一组存储设备、控制部件和管理信息调度的…...
背包问题双雄:01 背包与完全背包详解(Java 实现)
一、背包问题概述 背包问题是动态规划领域的经典问题,其核心在于如何在有限容量的背包中选择物品,使得总价值最大化。根据物品选择规则的不同,主要分为两类: 01 背包:每件物品最多选 1 次(选或不选&#…...