在这里插入图片描述

文章目录

  • 前言
  • spring cache 常用注解
  • 整合两级缓存(guava、redis)
  • 演示
  • 总结

前言

缓存在开发中是一个必不可少的优化点,近期在公司的项目重构中,关于缓存优化了很多点,比如在加载一些数据比较多的场景中,会大量使用缓存机制提高接口响应速度,简介提升用户体验。关于缓存,很多人对它都是既爱又恨,爱它的是:它能大幅提升响应效率,恨的是它如果处理不好,没有用好比如LRU这种策略,没有及时更新数据库的数据就会导致数据产生滞后,进而产生用户的误读。

spring cache 常用注解

  • @CacheConfig

这个注解的的主要作用就是全局配置缓存,比如配置缓存的名字(cacheNames),只需要在类上配置一次,下面的方法就默认以全局配置为主,不需要二次配置,节省了部分代码。

  • @Cacheable

这个注解是最重要的,主要实现的功能再进行一个读操作的时候。就是先从缓存中查询,如果查找不到,就会走数据库的执行方法,这是缓存的注解最重要的一个方法,基本上我们的所有缓存实现都要依赖于它。它具有的属性为cacheNames:缓存名字,condtion:缓存的条件,unless:不缓存的条件。可以指定SPEL表达式来实现,也可以指定缓存的key,缓存的内部实现一般都是key,value形式,类似于一个Map(实际上cacheable的缓存的底层实现就是concurrenHashMap),指定了key,那么缓存就会以key作为键,以方法的返回结果作为值进行映射。

  • @CacheEvict

这个注解主要是配合@Cacheable一起使用的,它的主要作用就是清除缓存,当方法进行一些更新、删除操作的时候,这个时候就要删除缓存。如果不删除缓存,就会出现读取不到最新缓存的情况,拿到的数据都是过期的。它可以指定缓存的key和conditon,它有一个重要的属性叫做allEntries默认是false,也可以指定为true,主要作用就是清除所有的缓存,而不以指定的key为主。

  • @CachePut

这个注解它总是会把数据缓存,而不会去每次做检查它是否存在,相比之下它的使用场景就比较少,毕竟我们希望并不是每次都把所有的数据都给查出来,我们还是希望能找到缓存的数据,直接返回,这样能提升我们的软件效率。

  • @cache

这个注解它是上面的注解的综合体,包含上面的三个注解(cacheable、cachePut、CacheEvict),可以使用这一个注解来包含上面的所有的注解,看源码如下

在这里插入图片描述

  • 一个例子

主要需要注意的是我们上述讲述的缓存注解都是基于service层(不能放在contoller和dao层),首先我们在类上配置一个CacheConfig,然后配置一个cacheNames,那么下面的方法都是以这个缓存名字作为默认值,他们的缓存名字都是这个,不必进行额外的配置。当进行select查询方法的时候,我们配置上@Cacheable,并指定key,这样除了第一次之外,我们都会把结果缓存起来,以后的结果都会把这个缓存直接返回。而当进行更新数据(删除或者更新操作)的时候,使用@CacheEvict来清除缓存,防止调用@Cacheabel的时候没有更新缓存

@Service
@CacheConfig(cacheNames = "articleCache")
public class ArticleService {private AtomicInteger count =new AtomicInteger(0);@Autowiredprivate ArticleMapper articleMapper;/*** 增加一篇文章 每次就进行缓存* @return*/@CachePutpublic Integer addArticle(Article article){Integer result = articleMapper.addArticle(article.getTitle(), article.getAuthor(), article.getContent(), article.getFileName());if (result>0) {Integer lastInertId = articleMapper.getLastInertId();System.out.println("--执行增加操作--id:" + lastInertId);}return result;}/*** 获取文章  以传入的id为键,当state为0的时候不进行缓存* @param id 文章id* @return*/@Cacheable(key = "#id",unless = "#result.state==0")public Article getArticle(Integer id) {try {//模拟耗时操作Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}final Article artcile = articleMapper.getArticleById(id);System.out.println("--执行数据库查询操作"+count.incrementAndGet()+"次"+"id:"+id);return artcile;}/*** 通过id更新内容 清除以id作为键的缓存** @param id* @return*/@CacheEvict(key = "#id")public Integer updateContentById(String contetnt, Integer id) {Integer result = articleMapper.updateContentById(contetnt, id);System.out.println("--执行更新操作id:--"+id);return result;}/*** 通过id移除文章* @param id  清除以id作为键的缓存* @return*/@CacheEvict(key = "#id")public Integer removeArticleById(Integer id){final Integer result = articleMapper.removeArticleById(id);System.out.println("执行删除操作,id:"+id);return result;}}

整合两级缓存(guava、redis)

大概的流程,如下图所示:

在这里插入图片描述

  • 重写org.springframework.cache.CacheManager
public class RedisGuavaCacheManager implements CacheManager {private final Logger logger = LoggerFactory.getLogger(RedisGuavaCacheManager.class);private ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>();private CacheRedisGuavaProperties cacheRedisGuavaProperties;private RedisTemplate<Object, Object> stringKeyRedisTemplate;private boolean dynamic = true;private Set<String> cacheNames;public RedisGuavaCacheManager(CacheRedisGuavaProperties cacheRedisGuavaProperties,RedisTemplate<Object, Object> stringKeyRedisTemplate) {super();this.cacheRedisGuavaProperties = cacheRedisGuavaProperties;this.stringKeyRedisTemplate = stringKeyRedisTemplate;this.dynamic = cacheRedisGuavaProperties.isDynamic();this.cacheNames = cacheRedisGuavaProperties.getCacheNames();}@Overridepublic Cache getCache(String name) {Cache cache = cacheMap.get(name);if (cache != null) {return cache;}if (!dynamic && !cacheNames.contains(name)) {return cache;}cache = new RedisGuavaCache(name, stringKeyRedisTemplate, guavaCache(name), cacheRedisGuavaProperties);Cache oldCache = cacheMap.putIfAbsent(name, cache);logger.debug("create cache instance, the cache name is : {}", name);return oldCache == null ? cache : oldCache;}public com.google.common.cache.Cache<Object, Object> guavaCache(String cacheName) {CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();long expireAfterAccess = cacheRedisGuavaProperties.getGuava().getExpireAfterAccess();Map<String, Long> expires = cacheRedisGuavaProperties.getGuava().getExpires();Long cacheNameExpire = expires.get(cacheName);long expire = cacheNameExpire == null ? expireAfterAccess : cacheNameExpire;if (expire > 0) {cacheBuilder.expireAfterAccess(cacheRedisGuavaProperties.getGuava().getExpireAfterAccess(),TimeUnit.MILLISECONDS);}if (cacheRedisGuavaProperties.getGuava().getExpireAfterWrite() > 0) {cacheBuilder.expireAfterWrite(cacheRedisGuavaProperties.getGuava().getExpireAfterWrite(),TimeUnit.MILLISECONDS);}int initialCapacity = cacheRedisGuavaProperties.getGuava().getInitialCapacity();Map<String, Long> capacityMap = cacheRedisGuavaProperties.getGuava().getCapacityMap();Long capacity = capacityMap.get(cacheName);long capacityResult = capacity == null ? initialCapacity : capacity;if (capacityResult > 0) {cacheBuilder.initialCapacity(cacheRedisGuavaProperties.getGuava().getInitialCapacity());}if (cacheRedisGuavaProperties.getGuava().getMaximumSize() > 0) {cacheBuilder.maximumSize(cacheRedisGuavaProperties.getGuava().getMaximumSize());}if (cacheRedisGuavaProperties.getGuava().getRefreshAfterWrite() > 0) {cacheBuilder.refreshAfterWrite(cacheRedisGuavaProperties.getGuava().getRefreshAfterWrite(),TimeUnit.MILLISECONDS);}return cacheBuilder.build();}@Overridepublic Collection<String> getCacheNames() {return this.cacheNames;}public void clearLocal(String cacheName, Object key) {Cache cache = cacheMap.get(cacheName);if (cache == null) {return;}RedisGuavaCache redisGuavaCache = (RedisGuavaCache) cache;redisGuavaCache.clearLocal(key);}
}
  • 重写org.springframework.cache.support.AbstractValueAdaptingCache,主要是重写redis和guava cache的更新策略。
public class RedisGuavaCache extends AbstractValueAdaptingCache {private final Logger logger = LoggerFactory.getLogger(RedisGuavaCache.class);private String name;private RedisTemplate<Object, Object> stringKeyRedisTemplate;private com.google.common.cache.Cache<Object, Object> loadingCache;private String cachePrefix;private long defaultExpiration = 0;private Map<String, Long> expires;private String topic = "cache:redis:guava:topic";private Map<String, ReentrantLock> keyLockMap = new ConcurrentHashMap<String, ReentrantLock>();public RedisGuavaCache(boolean allowNullValues) {super(allowNullValues);}public RedisGuavaCache(String name, RedisTemplate<Object, Object> stringKeyRedisTemplate,com.google.common.cache.Cache<Object, Object> loadingCache,CacheRedisGuavaProperties cacheRedisGuavaProperties) {super(cacheRedisGuavaProperties.isCacheNullValues());this.name = name;this.stringKeyRedisTemplate = stringKeyRedisTemplate;this.loadingCache = loadingCache;this.cachePrefix = cacheRedisGuavaProperties.getCachePrefix();this.defaultExpiration = cacheRedisGuavaProperties.getRedis().getDefaultExpiration();this.expires = cacheRedisGuavaProperties.getRedis().getExpires();this.topic = cacheRedisGuavaProperties.getRedis().getTopic();}@Overridepublic String getName() {return this.name;}@Overridepublic Object getNativeCache() {return this;}@SuppressWarnings("unchecked")@Overridepublic <T> T get(Object key, Callable<T> valueLoader) {Object value = lookup(key);if (value != null) {return (T) value;}ReentrantLock lock = keyLockMap.get(key.toString());if (lock == null) {logger.debug("create lock for key : {}", key);lock = new ReentrantLock();keyLockMap.putIfAbsent(key.toString(), lock);}try {lock.lock();value = lookup(key);if (value != null) {return (T) value;}value = valueLoader.call();Object storeValue = toStoreValue(value);put(key, storeValue);return (T) value;} catch (Exception e) {throw new ValueRetrievalException(key, valueLoader, e.getCause());} finally {lock.unlock();}}@Overridepublic void put(Object key, Object value) {if (!super.isAllowNullValues() && value == null) {this.evict(key);return;}long expire = getExpire();if (expire > 0) {stringKeyRedisTemplate.opsForValue().set(getKey(key), toStoreValue(value), expire, TimeUnit.MILLISECONDS);} else {stringKeyRedisTemplate.opsForValue().set(getKey(key), toStoreValue(value));}push(new CacheMessage(this.name, key));loadingCache.put(key, value);}@Overridepublic ValueWrapper putIfAbsent(Object key, Object value) {Object cacheKey = getKey(key);Object prevValue = null;// 考虑使用分布式锁,或者将redis的setIfAbsent改为原子性操作synchronized (key) {prevValue = stringKeyRedisTemplate.opsForValue().get(cacheKey);if (prevValue == null) {long expire = getExpire();if (expire > 0) {stringKeyRedisTemplate.opsForValue().set(getKey(key), toStoreValue(value), expire, TimeUnit.MILLISECONDS);} else {stringKeyRedisTemplate.opsForValue().set(getKey(key), toStoreValue(value));}push(new CacheMessage(this.name, key));loadingCache.put(key, toStoreValue(value));}}return toValueWrapper(prevValue);}@Overridepublic void evict(Object key) {// 先清除redis中缓存数据,然后清除guava中的缓存,避免短时间内如果先清除guava缓存后其他请求会再从redis里加载到guava中stringKeyRedisTemplate.delete(getKey(key));push(new CacheMessage(this.name, key));loadingCache.invalidate(key);}@Overridepublic void clear() {// 先清除redis中缓存数据,然后清除guava中的缓存,避免短时间内如果先清除guava缓存后其他请求会再从redis里加载到guava中Set<Object> keys = stringKeyRedisTemplate.keys(this.name.concat(":*"));for (Object key : keys) {stringKeyRedisTemplate.delete(key);}push(new CacheMessage(this.name, null));loadingCache.invalidateAll();}@Overrideprotected Object lookup(Object key) {Object cacheKey = getKey(key);Object value = loadingCache.getIfPresent(key);if (value != null) {logger.debug("get cache from guava, the key is : {}", cacheKey);return value;}value = stringKeyRedisTemplate.opsForValue().get(cacheKey);if (value != null) {logger.debug("get cache from redis and put in guava, the key is : {}", cacheKey);loadingCache.put(key, value);}return value;}private Object getKey(Object key) {return this.name.concat(":").concat(StringUtils.isEmpty(cachePrefix) ? key.toString() : cachePrefix.concat(":").concat(key.toString()));}private long getExpire() {long expire = defaultExpiration;Long cacheNameExpire = expires.get(this.name);return cacheNameExpire == null ? expire : cacheNameExpire.longValue();}/*** @description 缓存变更时通知其他节点清理本地缓存*/private void push(CacheMessage message) {stringKeyRedisTemplate.convertAndSend(topic, message);}/*** @description 清理本地缓存*/public void clearLocal(Object key) {logger.debug("clear local cache, the key is : {}", key);if (key == null) {loadingCache.invalidateAll();} else {loadingCache.invalidate(key);}}
}
  • 重写 org.springframework.data.redis.connection.MessageListener,由于多节点部署,本地缓存可能会出现不一致,这个时候需要监听redis中缓存的改变,这里底层用的是redis的发布订阅模式。
public class CacheMessageListener implements MessageListener {private final Logger logger = LoggerFactory.getLogger(CacheMessageListener.class);private RedisTemplate<Object, Object> redisTemplate;private RedisGuavaCacheManager redisGuavaCacheManager;public CacheMessageListener(RedisTemplate<Object, Object> redisTemplate,RedisGuavaCacheManager redisGuavaCacheManager) {super();this.redisTemplate = redisTemplate;this.redisGuavaCacheManager = redisGuavaCacheManager;}@Overridepublic void onMessage(Message message, byte[] pattern) {CacheMessage cacheMessage = (CacheMessage) redisTemplate.getValueSerializer().deserialize(message.getBody());logger.debug("recevice a redis topic message, clear local cache, the cacheName is {}, the key is {}", cacheMessage.getCacheName(), cacheMessage.getKey());redisGuavaCacheManager.clearLocal(cacheMessage.getCacheName(), cacheMessage.getKey());}}

由于篇幅问题,这里的整合不一一指出,只是把核心代码给了。具体的可以看我的github。

演示

  • service 代码编写,跟使用spring cache 一样,跟着之前的套路是一样的。只不过这里多的是本地缓存的更新策略。
public class CacheRedisGuavaService {private final Logger logger = LoggerFactory.getLogger(CacheRedisGuavaService.class);@Cacheable(key = "'cache_user_id_' + #id", value = "userIdCache", cacheManager = "cacheManager", sync = true)public UserVO get(long id) {logger.info("get by id from db");UserVO user = new UserVO();user.setId(id);user.setName("name" + id);user.setCreateTime(new Date());return user;}@Cacheable(key = "'cache_user_name_' + #name", value = "userNameCache", cacheManager = "cacheManager")public UserVO get(String name) {logger.info("get by name from db");UserVO user = new UserVO();user.setId(new Random().nextLong());user.setName(name);user.setCreateTime(new Date());return user;}@CachePut(key = "'cache_user_id_' + #userVO.id", value = "userIdCache", cacheManager = "cacheManager")public UserVO update(UserVO userVO) {logger.info("update to db");userVO.setCreateTime(new Date());return userVO;}@CacheEvict(key = "'cache_user_id_' + #id", value = "userIdCache", cacheManager = "cacheManager")public void delete(long id) {logger.info("delete from db");}
}
  • controller层
public class CacheRedisGuavaController {@Resourceprivate CacheRedisGuavaService cacheRedisGuavaService;@GetMapping("id/{id}")public UserVO get(@PathVariable long id) {return cacheRedisGuavaService.get(id);}@GetMapping("name/{name}")public UserVO get(@PathVariable String name) {return cacheRedisGuavaService.get(name);}@GetMapping("update/{id}")public UserVO update(@PathVariable long id) {UserVO user = cacheRedisGuavaService.get(id);cacheRedisGuavaService.update(user);return user;}@GetMapping("delete/{id}")public void delete(@PathVariable long id) {cacheRedisGuavaService.delete(id);}
}
  • 配置
spring.redis.host=192.168.56.121
spring.redis.port=6379spring.cache.multi.guava.expireAfterAccess=10000
spring.cache.multi.redis.defaultExpiration=60000spring.cache.cache-names=userIdCache,userNameCache

测试controller,即可看到缓存的写入与更新。

总结

本篇博客介绍了springBoot中缓存的一些使用方法,如何在开发中使用二级缓存?希望起到抛砖引玉的作用。

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 论文翻译:Multi-frequency Electromagnetic Tomography for Acute Stroke Detection Using Frequency-Constrain

    Multi-frequency Electromagnetic Tomography for Acute Stroke Detection Using Frequency-Constrained Sparse Bayesian Learning 多频电磁层析成像在急性脑卒中诊断中的应用 (未翻译完全的章节已标注。主要为了自己学习用,所以有的章节就没有翻译,因为翻了也不会,可以去…...

    2024/4/28 1:46:07
  2. 快餐降脾土之气而使脾胃更差赵旭

    这样的习惯成为自然后,导致生活越来越累,身体素质迅速下降,最后积忧成疾。 注重内在修为的人,习惯专注于当下的事,不因外部环境的不稳定而心乱,并且常“以财发身”提升自己的修养,能敏锐觉察身体的异常,对自身的状态了如指掌,以饮食起居调整到最佳状态,根本没有机会看…...

    2024/4/15 3:33:50
  3. 【转】医学图像领域相关会议和期刊-仅个人记录使用。

    医学图像领域相关会议和期刊首推MICCAI(International Conference on Medical Image Computing andComputer-Assisted Intervention) MICCAI is a unified conference formed by the merger of (CVRMed) Computer Vision, Virtual Reality and Robotics in Medicine (MRCAS) Me…...

    2024/4/24 13:48:33
  4. Netty:原理架构解析

    1、Netty是什么? Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性、高可定制性。 2、为什么不直接基于 JDK 的 NIO 类库编程呢? 既然 “Netty 是一个基于 JAVA NIO 类库的异步通信框架”,为什么不直接使用JDK的…...

    2024/4/24 13:48:33
  5. 2020高压电工证考试及高压电工考试软件

    题库来源:安全生产模拟考试一点通公众号小程序2020高压电工证考试及高压电工考试软件,包含高压电工证考试答案解析及高压电工考试软件练习。由安全生产模拟考试一点通公众号结合国家高压电工考试最新大纲及高压电工考试真题出具,有助于高压电工模拟考试题库考前练习。1、【判…...

    2024/4/24 13:48:30
  6. 2020N1叉车司机考试题及N1叉车司机模拟考试软件

    题库来源:安全生产模拟考试一点通公众号小程序2020N1叉车司机考试题及N1叉车司机模拟考试软件,包含N1叉车司机考试题答案解析及N1叉车司机模拟考试软件练习。由安全生产模拟考试一点通公众号结合国家N1叉车司机考试最新大纲及N1叉车司机考试真题出具,有助于N1叉车司机在线考…...

    2024/4/24 13:48:29
  7. 【tomcat】08 Server组件与Service组件

    一、介绍 1、Server组件和Service组件是Tomcat核心组件中最外层级的两个组件,Server组件可以看成Tomcat的运行实例的抽象,而Service组件则可以看成Tomcat内的不同服务的抽象。 2、Server组件包含若干Listener组件、GlobalNamingResources组件及若干Service组件。 3、Service组…...

    2024/4/24 13:48:28
  8. Python笔记(爬虫)(一)—— 入门

    下载器 官方库urllib2和第三方库request 解析器 Beautiful Soup(第三方库),用于从HTML或XML中提取数据,官网http://www.crummy.com/software/BeautifulSoup/ 安装并测试beautifulsoup4 安装:pip install beautifulsoup4 测试: import bs4 print bs4实例(确定目标、分析目…...

    2024/4/24 13:48:27
  9. 实验五 动态链接库的建立与调用

    实验五 动态链接库的建立与调用 一、实验目的理解动态链接库的实现原理。 掌握Windows系统动态链接库的建立方法。 掌握Windows环境下动态链接库的调用方法。二、实验准备 动态连接库介绍: 动态链接库(Dynamic Link Library DLL)是一个可执行模块,它包含的函数可以由Windows…...

    2024/4/24 13:48:26
  10. 实验六 系统内存使用统计

    实验六 系统内存使用统计 一、实验目的了解Windows内存管理机制,理解页式存储管理技术。 熟悉Windows内存管理基本数据结构。 掌握Windows内存管理基本API的使用。二、实验准备 相关数据结构及API函数介绍相关系统数据结构说明系统结构MEMORYSTATUS中包含当前物理内存和虚拟…...

    2024/4/24 13:48:25
  11. Vue课程学习笔记-day04

    复习1、表单<select v-model=form.categoryId><option :value=item.id v-for="item in category" :key=item.id>{{item.name}}</option></select><input type=checkbox v-model=form.options value=css>css<input type=checkbox v-…...

    2024/4/24 13:48:27
  12. 股指期货、股指期权与股票有何不同?

    普通投资者最初进入资本市场选择投资标的时,往往首先想到股票。不过,在全球金融产品日益丰富的今天,投资者在进行资产配置时拥有更多的选择,其中包括股指期货、股指期权等金融衍生品,了解各产品间的差异就显得十分重要。本文将主要阐述股指期货、股指期权以及股票之间的差…...

    2024/4/24 13:48:25
  13. promise经典面试题

    上期讲了promise基本概念和用法,今天结合上期的内容,讲解几道经典的相关面试题。 promise基本规则: 1. 首先Promise构造函数会立即执行,而Promise.then()内部的代码在当次事件循环的结尾立即执行(微任务)。 2. promise的状态一旦由等待pending变为成功fulfilled或者失败rej…...

    2024/4/24 13:48:23
  14. Vue课程学习笔记-day05

    复习1、过滤器1. 定义data(){},methods:{},// 局部过滤器filters:{dateFormat(time){return xxx;}}// 全局过滤器Vue.filter(dateFormat,function(time){return xxx;})需要在vue实例创建之前2. 使用{{date | dateFormat}}v-bind:id=item.id | idFormat3. 就近原则2、监听器1. 定…...

    2024/4/24 13:48:23
  15. 重学 Java 设计模式:实战责任链模式「模拟618电商大促期间,项目上线流程多级负责人审批场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章沉淀、分享、成长,让自己和他人都能有所收获!😄一、前言 场地和场景的重要性 射击🏹需要去靶场学习、滑雪🏂需要去雪场体验、开车🚗需要能上路实践,而编程开发除了能完成产品的功能流程,还需要保证系统的…...

    2024/4/24 13:48:23
  16. 将本地代码上传到github

    首先进入要上传代码的目录,例如,我要将test文件夹下的代码上传到gitlab,则,cd test通常需要创建README.md文件,echo "# test" >> README.md执行git命令,此命令会在当前目录下创建一个.git文件夹,git init将项目的所有文件添加到仓库中,git add .这个命令会把当…...

    2024/4/24 13:48:19
  17. 使用JavaScript获取图像大小(高度和宽度)

    为了使用JavaScript获取图像大小(高度和宽度),可使用Element.clientHeight和Element.clientWidth属性。下面本篇文章就来给大家介绍一下,希望对大家有所帮助。Element.clientHeight:我们可以使用此属性访问元素的内部高度。此高度包括填充,但不包括边距和边框。Element.c…...

    2024/4/24 13:48:18
  18. js变量提升(语法小坑)

    正如《你不知道的javascript》一书中说的,js是一门脚本语言,使用者不需要像学java一样完全语法等,甚至只会其中的一些简单的命令就可以直接开发了。 但是开发越久越发现,在前端框架如此多的情况下,js基础等才是作为一个前端经久不衰的秘诀。 看下方示例代码运行结果是什么…...

    2024/4/24 13:48:18
  19. CRC16的生产及应用

    一、CRC16校验码的使用现选择最常用的CRC-16校验,说明它的使用方法。根据Modbus协议,常规485通讯的信息发送形式如下:地址 功能码 数据信息 校验码1byte 1byte nbyte 2byteCRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。例如:信息字段…...

    2024/4/15 3:34:02
  20. vue push方法重写解决路由错误问题

    vue重写路由push方法 /**重写路由的push方法 解决,相同路由跳转时,报错 添加,相同路由跳转时,触发watch (仅限string方式传参,形如"view?id=5") */const routerPush = Router.prototype.push Router.prototype.push = function push(location) {if(typeof(loca…...

    2024/4/18 9:32:40

最新文章

  1. Codeforces Round 934 (Div. 2) D

    C o d e f o r c e s R o u n d 934 ( D i v . 2 ) \Huge{Codeforces Round 934 (Div. 2)} CodeforcesRound934(Div.2) D . N o n − P a l i n d r o m i c S u b s t r i n g \large{D. Non-Palindromic Substring} D.Non−PalindromicSubstring 文章目录 题意思路标程 题意 …...

    2024/4/28 4:23:54
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. A股企业数据要素利用水平数据集(2001-2022年)

    参照史青春&#xff08;2023&#xff09;的做法&#xff0c;团队对上市公司-数据要素利用水平进行测算。统计人工智能技术、区块链技术、云计算技术、大数据技术、大数据技术应用五项指标在企业年报中的披露次数&#xff0c;求和后衡量数据要素投入水平。 一、数据介绍 数据名…...

    2024/4/27 8:53:14
  4. [C++][算法基础]模拟队列(数组)

    实现一个队列&#xff0c;队列初始为空&#xff0c;支持四种操作&#xff1a; push x – 向队尾插入一个数 x&#xff1b;pop – 从队头弹出一个数&#xff1b;empty – 判断队列是否为空&#xff1b;query – 查询队头元素。 现在要对队列进行 M 个操作&#xff0c;其中的每…...

    2024/4/22 21:35:57
  5. Python读取文件里内容

    如果要读取一个文件里的内容是 # 文件名&#xff1a;db.txt 1 2 3 4代码如下 import requests f open("db.txt", mode"rb") content f.read() f.close()data content.decode(utf-8)# 存到 list 里 data_list data.split(\r\n) print(data_list)# 结果…...

    2024/4/23 6:37:22
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/26 18:09:39
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/28 3:28:32
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/26 23:05:52
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/27 4:00:35
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/27 9:01:45
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/28 1:22:35
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/25 18:39:00
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/26 19:46:12
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/27 11:43:08
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/27 8:32:30
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57