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

Redis2-事务 连接Java 整合springboot 注解缓存

一、订阅和发布

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

Redis 客户端可以订阅任意数量的频道。

Redis的发布和订阅

客户端订阅频道发布的消息

频道发布消息 订阅者就可以收到消息

发布订阅的代码实现

1、 打开一个客户端订阅channel1

SUBSCRIBE channel1

2、打开另一个客户端,给channel1发布消息hello

publish channel1 hello

返回的1是订阅者数量

3、打开第一个客户端可以看到发送的消息

二、事务

1.事务简介:

可以一次执行多个命令,本质是一组命令的集合。一个事务中的 所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

单独的隔离的操作

官网说明

https://redis.io/docs/interact/transactions/

MULTI、EXEC、DISCARD、WATCH。这四个指令构成了 redis 事务处理的基础。

1.MULTI 用来组装一个事务;将命令存放到一个队列里面

2.EXEC 用来执行一个事务;//commit

3.DISCARD 用来取消一个事务;//rollback

4.WATCH 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。

例子:

有关事务,经常会遇到的是两类错误:

1.调用 EXEC 之前的错误

“调用 EXEC 之前的错误”,有可能是由于语法有误导致的,也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况,redis 都会进行记录,在客户端调用 EXEC 时,redis 会拒绝执行这一事务

2.调用 EXEC 之后的错误

2.redis事务冲突

双十一去购物的时候使用同一张银行卡去付款

10000

一个请求想给金额减8000

一个请求想给金额减5000

一个请求想给金额减1000

解决方案

悲观锁

select * from biao where 1=1 for update;

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,

每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,

这样别人想拿这个数据就会block直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,

比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

12306抢票

乐观锁

version 1

查余额 10000 version:1

10000>8000 -8000 update uuuu set moner-=8000 where version=1 1.1

10000 -5000 UPDATE uuuuu SET MONTY-=5000 WHERE VERSION=1

2000 2000>1000 UPDATE uuuu SET MONTY-=1000 WHERE VERSION=1.1 1.2

version

select * from ttt where uid =1

version money

1 10000

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,

每次去拿数据的时候都认为别人不会修改,所以不会上锁,

但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

可以使用版本号等机制。乐观锁适用于多读的应用类型,

这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

3.WATCH

“WATCH”可以帮我们实现类似于“乐观锁”的效果,即 CAS(check and set)。

执行顺序:multi(begin) ->  exec(commit) ->  discard(rollback)

WATCH 本身的作用是“监视 key 是否被改动过”,而且支持同时监视多个 key,只要还没真正触发事务,WATCH 都会尽职尽责的监视,一旦发现某个 key 被修改了,在执行 EXEC 时就会返回 nil,表示事务无法触发。

代码如下:

事务回滚:

三、Java连接redis

1. 创建java项目

2. 添加redis的依赖

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version>
</dependency>

3. 连接redis

四、redis整合springboot项目

1. 创建项目

2. 添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.0</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>

 3. 编写配置文件

 4. 设置配置类

package org.example.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;import java.time.Duration;@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {/*** 连接池的设置** @return*/@Beanpublic JedisPoolConfig getJedisPoolConfig() {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();return jedisPoolConfig;}/*** RedisTemplate* @param factory* @return*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}/*** 缓存处理* @param factory* @return*/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}
}

五、注解缓存

spring缓存注解

从3.1开始,Spring引入了对Cache的支持。其使用方法和原理都类似于Spring对事务管理的支持。Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。所以在使用Spring Cache的时候我们要保证我们缓存的方法对于相同的方法参数要有相同的返回结果。

使用Spring Cache需要我们做两方面的事:

1. 声明某些方法使用缓存

2. 配置Spring对Cache的支持

和Spring对事务管理的支持一样,Spring对Cache的支持也有基于注解和基于XML配置两种方式。下面我们先来看看基于注解的方式。(基于配置的自己私下去了解即可)

基于注解的支持

@Cacheable

@Cacheable可以标记在一个方法上,也可以标记在一个类上。

当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable可以指定三个属性,value、key和condition。

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个

例如:

@Cacheable(value=”mycache”)

@Cacheable(value={”cache1”,”cache2”}

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@Cacheable(value=”testcache”,key=”#userName”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@Cacheable(value=”testcache”,condition=”#userName.length()>2”)

a. value属性指定Cache名称

value其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

 @Cacheable("cache1")//Cache是发生在cache1上的public User find(Integer id) {returnnull;}@Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的public User find(Integer id) {returnnull;}
b. 使用key属性自定义key

key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略

自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。下面是几个使用参数作为key的示例。

@Cacheable(value="users", key="#id")public User find(Integer id) {return  null;}// p  param 参数   0 @Cacheable(value="users", key="#p0")public User find(Integer id) {returnnull;}@Cacheable(value="users", key="#user.id")public User find(User user) {returnnull;}@Cacheable(value="users", key="#p0.id")public User find(User user) {returnnull;}

除了上述使用方法参数作为key之外,Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。

属性名称

描述

示例

methodName

当前方法名

#root.methodName

method

当前方法

#root.method.name

target

当前被调用的对象

#root.target

targetClass

当前被调用的对象的class

#root.targetClass

args

当前方法参数组成的数组

#root.args[0]

caches

当前被调用的方法使用的Cache

#root.caches[0].name

 当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:

 @Cacheable(value={"users", "xxx"}, key="caches[1].name")public User find(User user) {returnnull;}
condition属性指定发生的条件

有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存。

 @Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")public User find(User user) {System.out.println("find user by user " + user);return user;}
@CachePut

在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

一般使用在保存,更新方法中。

@CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟 @Cacheable是一样的。

 @Cacheable(cacheNames = "user", key = "#id")//每次都会执行方法,并将结果存入指定的缓存中public User find(Integer id) {return null;}
@CacheEvict

@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的(对应Cache的名称);key表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;condition表示清除操作发生的条件。下面我们来介绍一下新出现的两个属性allEntries和beforeInvocation。

1、 allEntries属性

allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

@CacheEvict(value="users",key = "#id", allEntries=true)
public void delete(Integer id) {System.out.println("delete user by id: " + id);
}
2、 beforeInvocation属性

清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

@CacheEvict(value="users",key = "#id", beforeInvocation=true)
public void delete(Integer id) {System.out.println("delete user by id: " + id);
}

六、springboot基于注解的redis缓存

1.开启注解缓存

 2. 添加缓存

3. 测试

第一次访问,控制台会打印数据

 缓存之后,清空控制台,再次访问,直接通过缓存获取

相关文章:

Redis2-事务 连接Java 整合springboot 注解缓存

一、订阅和发布 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 Redis的发布和订阅 客户端订阅频道发布的消息 频道发布消息 订阅者就可以收到消息 发布订阅的代…...

CHFS 文件服务器搭建小记

一、CHFS 简介 摘自官网&#xff1a;http://iscute.cn/chfs CuteHttpFileServer/chfs 是一个免费的、HTTP协议的文件共享服务器&#xff0c;使用浏览器可以快速访问。它具有以下特点&#xff1a; 单个文件&#xff0c;核心功能无需其他文件跨平台运行&#xff0c;支持主流平台…...

vue中图片不显示问题 - vue中静态资源加载

文章目录 vue中图片不显示问题静态资源URL 转换规则webpack 静态资源处理 图片不显示问题问题描述解决办法1&#xff1a;使用require引入require is not defined 解决办法2&#xff1a;使用import引入解决办法3&#xff1a;将图片放进公共文件夹static或public vue中图片不显示…...

IP报文格式

IP报文格式 报文格式 图1 IP头格式 表1 IP头字段解释 字段长度含义Version4比特 4&#xff1a;表示为IPV4&#xff1b;6&#xff1a;表示为IPV6。IHL4比特首部长度&#xff0c;如果不带Option字段&#xff0c;则为20&#xff0c;最长为60&#xff0c;该值限制了记录路由选项。…...

k8s 进阶实战笔记 | Pod 创建过程详解

Pod 创建过程详解 ​ 初始状态0 controller-manager、scheduler、kubelet组件通过 list-watch 机制与 api-server 通信并检查资源变化 第一步 用户通过 CLI 或者 WEB 端等方式向 api-server 发送创建资源的请求&#xff08;比如&#xff1a;我要创建一个replicaset资源&…...

使用MMYOLO中yolov8训练自己VOC数据集实战

概述 MMYOLO是商汤公司基于PyTorch框架和YOLO系列算法开源的工具箱 - 目前支持的任务 目标检测旋转框目标检测 - 支持的算法 YOLOv5YOLOv6YOLOv7YOLOv8YOLOXRTMDetRTMDet-Rotated - 支持的数据集 COCO Dataset VOC Dataset CrowdHuman Dataset DOTA 1.0 Dataset 安装…...

解决方案 | 基于SFTP协议的文件传输断点续传Java实现方案

背景 因项目需要&#xff0c;我们服务每天都需要通过SFTP协议来对接上下游进行文件传输&#xff0c;但是对于一些大文件&#xff0c;在与第三方公司的服务器对接过程中很可能会因为网络问题或上下游服务器性能问题导致文件上传或者下载被中断&#xff0c;每次重试都需要重新对…...

web前端项目-动画特效【附源码】

文章目录 一&#xff1a;赛车游戏动画HTML源码&#xff1a;JS源码&#xff1a;CSS源码&#xff1a;&#xff08;1&#xff09;normalize.css&#xff08;2&#xff09;style.css 二&#xff1a;吉普车动画演示HTML源码&#xff1a;CSS源码&#xff1a;&#xff08;1&#xff09…...

蓝桥杯备战——6.串口通讯

1.分析原理图 由上图我们可以看到串口1通过CH340接到了USB口上&#xff0c;通过串口1我们就能跟电脑进行数据交互。 另外需要注意的是STC15F是有两组高速串口的&#xff0c;而且可以切换端口。 2.配置串口 由于比赛时间紧&#xff0c;我们最好不要去现场查寄存器手册&#x…...

Redis为什么速度快:数据结构、存储及IO网络原理总结

Redis&#xff0c;作为内存数据结构存储的佼佼者&#xff0c;其高性能表现一直备受赞誉。那么&#xff0c;Redis究竟是如何实现这一点的呢&#xff1f;接下来&#xff0c;我们将更深入地探讨其背后的关键技术&#xff0c;并提供进一步的优化策略。 一、内存存储与数据结构设计…...

OSI七层模型 | TCP/IP模型 | 网络和操作系统的联系 | 网络通信的宏观流程

文章目录 1.OSI七层模型2.TCP/IP五层(或四层)模型3.网络通信的宏观流程3.1.同网段通信3.2.跨网段通信 1.OSI七层模型 在计算机通信诞生之初&#xff0c;不同的厂商都生产自己的设备&#xff0c;都有自己的网络通讯标准&#xff0c;导致了不同厂家之间各种协议不兼容&#xff0…...

Java集合总览

1.总览 Java中的集合分List、Set、Queue、Map 4种类型。 List&#xff1a;大多数实现元素可以为null&#xff0c;可重复&#xff0c;底层是数组或链表的结构&#xff0c;支持动态扩容 Set&#xff1a;大多数实现元素可以为null但只能是1个&#xff0c;不能重复&#xff0c; …...

C# 设置一个定时器函数

C#中&#xff0c;创建设置一个定时器&#xff0c;能够定时中断执行特定操作&#xff0c;可以用于发送心跳、正计时和倒计时等。 本文对C#的定时器简单封装一下&#xff0c;哎&#xff0c;以方便定时器的创建。 定义 using Timer System.Timers.Timer;class SetTimer {Timer …...

第十四届蓝桥杯省赛pythonB组题。 管道

5407. 管道 - AcWing题库 ​​​ 有一根长度为 len的横向的管道&#xff0c;该管道按照单位长度分为 len 段&#xff0c;每一段的中央有一个可开关的阀门和一个检测水流的传感器。 一开始管道是空的&#xff0c;位于 Li 的阀门会在 Si 时刻打开&#xff0c;并不断让水流入管道。…...

淘宝扭蛋机小程序:新时代的互动营销与娱乐体验

随着科技的快速发展&#xff0c;小程序已经成为人们日常生活中不可或缺的一部分。在众多的小程序中&#xff0c;淘宝扭蛋机小程序以其独特的互动性和趣味性&#xff0c;吸引了大量用户。本文将深入探讨淘宝扭蛋机小程序的特色、用户体验以及未来发展。 一、淘宝扭蛋机小程序的…...

深度强化学习(王树森)笔记02

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…...

【分布式技术专题】「分布式技术架构」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)

探索Tomcat技术架构设计模式的奥秘 Tomcat系统架构分析Tomcat 整体结构Tomcat总体结构图以 Service 作为“婚姻”1) Service 接口方法列表 2) StandardService 的类结构图方法列表 3) StandardService. SetContainer4) StandardService. addConnector 以 Server 为“居”1) Ser…...

常用的gpt-4 prompt words收集8

本文介绍我最近收集的一些好用的chatgpt-4的prompts&#xff0c;如果你也有好用的提示词可以互相交流一下。 1. I ran into some trouble on my way to work. 迟到原因 2. In my heart, the most delicious coffee is the Hawaii Dirty from Manner. Only the Nong series a…...

【GitHub项目推荐--开源2D 游戏引擎】【转载】

microStudio 是一个可在浏览器中运行的游戏引擎&#xff0c;它拥有一套精美、设计精良、全面的工具&#xff0c;可以非常轻松地帮助你创建 2D 游戏。 你可以在浏览器中访问 microStudio.dev 开始搭建你的游戏&#xff0c;当然你可以克隆现有项目或创建新游戏并开始编码&#x…...

鸿蒙APP的应用场景

鸿蒙APP可以用于多种场合和设备类型&#xff0c;这是鸿蒙系统的分布式能力和多终端适配的优势。以下是一些鸿蒙APP的应用场景&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.智能手机和平板电脑&am…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...