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

【Spring学习】Spring Data Redis:RedisTemplate、Repository、Cache注解

1,spring-data-redis官网

1)特点

  1. 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  2. 提供了RedisTemplate统一API来操作Redis
  3. 支持Redis的发布订阅模型
  4. 支持Redis哨兵和Redis集群
  5. 支持基于Lettuce的响应式编程
  6. 支持基于JDK、JSON、字符串、Spring独享的数据序列化及反序列化
  7. 支持基于Redis的JDKCollection实现

2,RedisTemplate

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。

1)常用API

api说明
redisTemplate.opsForValue();操作字符串
redisTemplate.opsForHash();操作hash
redisTemplate.opsForList();操作list
redisTemplate.opsForSet();操作set
redisTemplate.opsForZSet();操作有序set
redisTemplate.expire(key, 60 * 10000 * 30, TimeUnit.MILLISECONDS);设置过期时间

1>API:String

redisTemplate.opsForValue().set("name","tom")
说明api备注
添加单值.set(key,value)
获取单值.get(key)
添加单值并返回这个值是否已经存在.setIfAbsent(key, value)
添加单值并返回旧值.getAndSet(key, value)
批量添加Map<String,String> maps;
.multiSet(maps)
批量获取List<String> keys;
.multiGet(keys)
数值型+1.increment(key,1)
设置过期时间set(key, value, timeout, TimeUnit.SECONDS)过期返回null
字符串追加.append(key,"Hello");

2>API:List数据

template.opsForList().range("list",0,-1)
说明api备注
单个插入Long leftPush(key, value);返回操作后的列表的长度
批量插入Long leftPushAll(K key, V… values);返回操作后的列表的长度;
values可以是String[]List<Object>
查看.range(key,0,-1)从左往右:0,1,2;
从右往左:-1,-2,-3;
可做分页
弹出最左边的元素.leftPop("list")弹出之后该值在列表中将不复存在
修改set(key, index, value)
key存在则插入Long rightPushIfPresent(K key, V value);返回操作后的列表的长度
求subList.trim(key,1,-1)
移除元素Long remove(key, long count, Object value);count> 0:删除从左到右共count个等于value的元素。
count <0:删除等于从右到左共count个等于value的元素。
count = 0:删除等于value的所有元素。
求长度.size(key)

3>API:Hash操作

一个key1对应一个Map,map中每个value中@class后面对应的值为类信息。
在这里插入图片描述

template.opsForHash().put("redisHash","name","tom");
说明api备注
单插入.put(redisKey,hashKey, value)
批量插入Map<String,Object> map
.putAll(key, map)
查单数据.get(redisKey,hashKey)
查所有数据.entries(redisHash)
查key是否存在Boolean hasKey(redisKey, Object hashKey);
批量获取Hash值List multiGet(redisKey, List<Object> kes);
获取key集合Set keys(redisKey)
批量删除Long delete(redisKey, Object… hashKeys)
数值型value + 5increment(redisKey, hashKey, 5)返回操作后的value值
hashkey不存在时设置valueBoolean putIfAbsent(redisKey,hashKey, value)存在返回true,不存在返回true

遍历:

Cursor<Map.Entry<Object, Object>> curosr = template.opsForHash().scan("redisHash", ScanOptions.ScanOptions.NONE);while(curosr.hasNext()){Map.Entry<Object, Object> entry = curosr.next();System.out.println(entry.getKey()+":"+entry.getValue());}

4>API:Set数据

template.opsForSet().add(k,v)
说明api备注
添加Long add(key, V… values);values可以是:String[]
查看所有.members(key)
查询长度.size(key)
查询元素是否存在Boolean isMember(key, Object o);
批量删除Long remove(key, Object… values);values可以是:String[]
随机移除V pop(K key);
将元素value 从 sourcekey所在集合移动到 destKey所在集合Boolean move(sourcekey, V value, destKey)移动后sourcekey集合再没有value元素,destKey集合去重。
求两个集合的交集Set intersect(K key, K otherKey);
求多个无序集合的交集Set intersect(K key, Collection otherKeys);
求多个无序集合的并集Set union(K key, Collection otherKeys);

遍历:

Cursor<Object> curosr = template.opsForSet().scan("setTest", ScanOptions.NONE);while(curosr.hasNext()){System.out.println(curosr.next());}

5>API:ZSet集合

有序的Set集合,排序依据是Score。

template.opsForZSet().add("zset1","zset-1",1.0)
说明api备注
添加单个元素Boolean add(k, v, double score)返回元素是否已存在
批量添加元素Long add(k, Set<TypedTuple> tuples)举例:见下文1.
批量删除Long remove(K key, Object… values);
排序按分数值asc,返回成员o的排名Long rank(key, Object o);排名从0开始
排序按分数值desc,返回成员o的排名Long reverseRank(key, Object o);排名从0开始
按区间查询,按分数值ascSet range(key, 0, -1);
增加元素的score值,并返回增加后的值Double incrementScore(K key, V value, double delta);
  1. 批量添加元素
ZSetOperations.TypedTuple<Object> objectTypedTuple1 = new DefaultTypedTuple<Object>("zset-5",9.6);ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<Object>("zset-6",9.9);Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>();tuples.add(objectTypedTuple1);tuples.add(objectTypedTuple2);System.out.println(template.opsForZSet().add("zset1",tuples));System.out.println(template.opsForZSet().range("zset1",0,-1));
  1. 遍历
Cursor<ZSetOperations.TypedTuple<Object>> cursor = template.opsForZSet().scan("zzset1", ScanOptions.NONE);while (cursor.hasNext()){ZSetOperations.TypedTuple<Object> item = cursor.next();System.out.println(item.getValue() + ":" + item.getScore());}

2)使用

1>依赖

<!--        Redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
<!--        连接池依赖--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>

2>配置文件

spring:redis:host: 127.0.0.1  # Redis服务器地址port: 6379       # Redis服务器连接端口 timeout:0        # 连接超时时间(毫秒)
#   database: 0      # Redis数据库索引(默认为0)
#   password:        # Redis服务器连接密码(默认为空)lettuce:         # 使用的是lettuce连接池pool:max-active: 8 # 连接池最大连接数(使用负值表示没有限制)max-idle: 8   # 连接池中的最大空闲连接min-idle: 0   # 连接池中的最小空闲连接max-wait: 100 # 连接池最大阻塞等待时间(使用负值表示没有限制)

1>序列化配置

RedisTemplate默认采用JDK的序列化工具,序列化为字节形式,在redis中可读性很差。
修改默认的序列化方式为jackson:

@Configuration
public class RedisConfig {@Bean     //RedisConnectionFactory不需要我们创建Spring会帮助我们创建public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
//        1.创建RedisTemplate对象RedisTemplate<String,Object> template = new RedisTemplate<>();
//        2.设置连接工厂template.setConnectionFactory(connectionFactory);
//        3.创建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//        4.设置Key的序列化template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());
//        5.设置Value的序列化   jsonRedisSerializer使我们第三步new出来的template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);
//        6.返回return template;}
}

但是json序列号可能导致一些其他的问题:JSON序列化器会将类的class类型写入到JSON结果中并存入Redis,会带来额外的内存开销。
为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key哈value,当要存储Java对象时,手动完成对象的序列化和反序列化。

4>java实现

public class RedisUtil {@Autowiredprivate RedisTemplate redisTemplate;/*** 批量删除对应的value* * @param keys*/public void remove(final String... keys) {for (String key : keys) {remove(key);}}/*** 批量删除key* * @param pattern*/public void removePattern(final String pattern) {Set<Serializable> keys = redisTemplate.keys(pattern);if (keys.size() > 0)redisTemplate.delete(keys);}public void remove(final String key) {if (exists(key)) {redisTemplate.delete(key);}}public boolean exists(final String key) {return redisTemplate.hasKey(key);}public String get(final String key) {Object result = null;ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();result = operations.get(key);if (result == null) {return null;}return result.toString();}public boolean set(final String key, Object value) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);result = true;} catch (Exception e) {e.printStackTrace();}return result;}public boolean set(final String key, Object value, Long expireTime) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {e.printStackTrace();}return result;}public boolean hmset(String key, Map<String, String> value) {boolean result = false;try {redisTemplate.opsForHash().putAll(key, value);result = true;} catch (Exception e) {e.printStackTrace();}return result;}public Map<String, String> hmget(String key) {Map<String, String> result = null;try {result = redisTemplate.opsForHash().entries(key);} catch (Exception e) {e.printStackTrace();}return result;}
}

3)StringRedisTemplate

key和value的序列化方式默认就是String方式,省去了我们自定义RedisTemplate的过程。

    @Autowiredprivate StringRedisTemplate stringRedisTemplate;
//  JSON工具private static final ObjectMapper mapper = new ObjectMapper();@Testvoid testStringTemplate() throws JsonProcessingException {
//      准备对象User user = new User("abc", 18);
//      手动序列化String json = mapper.writeValueAsString(user);
//      写入一条数据到RedisstringRedisTemplate.opsForValue().set("user:200",json);//      读取数据String s = stringRedisTemplate.opsForValue().get("user:200");
//      反序列化User user1 = mapper.readValue(s,User.class);System.out.println(user1);}

3,Redis数据序列化

4,Repository操作

类似jpa操作,只要Redis服务器版本在2.8.0以上,不用事务,就可以使用Repository做各种操作。
注意:Repository和jpa的Repository是同一个,意味着jpa支持的api在redis操作中通用。

1)注解

注解说明属性对比jpa
@RedisHash用来定义实体。value:定义了不同类型对象存储时使用的前缀,也叫做键空间,默认是全限定类名;
timeToLive定义缓存的秒数;
类似@Entity
@Id定义对象的标识符类似@Id
@Indexed定义二级索引,加在属性上可以将该属性定义为查询用的索引
@Reference缓存对象引用,一般引用的对象也会被展开存储在当前对象中,添加了该注解后会直接存储该对象在Redis中的引用

2)使用

  1. 不需要添加依赖。
    spring-boot自动添加了@EnableRedisRepositories注解。
  2. 实体
@RedisHash(value="menu",timeToLive=60)
public class RedisMenuItem implements Serializable{@Idprivste Long id;@Indexedprivate String name;private Size size;private Money price;
}
  1. 定义Repository接口
public interface RedisMenuRepository extends CrudRepository<RedisMenuItem, Long>{List<RedisMenuItem> findByName(String name);
}
  1. 查询
List<MenuItem> itemList = menuRepository.findAll();menuRepository.save(menuItem);

5,Spring Cache

Spring 3.1 引入了对 Cache 的支持,使用使用 JCache(JSR-107)注解简化开发。
注意:可支持幂等操作的接口才可以使用缓存注解,因为缓存和参数无关,即:不管什么参数,返回值一样。

1)org.springframework.cache.Cache接口

  1. 包含了缓存的各种操作集合;
  2. 提供了各种xxxCache 的实现,比如:RedisCache
    在这里插入图片描述

2)org.springframework.cache.CacheManager接口

  1. 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache。这些 Cache 存在于 CacheManager 的上下文中。
  2. 提供了各种xxxCacheManager 的实现,比如RedisCacheManager。

3)相关注解

1>@EnableCaching

  1. 开启基于注解的缓存;
  2. 作用在缓存配置类上或者SpringBoot 的主启动类上;

2>@Cacheable

缓存注解。

使用注意:

  1. 基于AOP去实现的,所以必须通过IOC对象去调用。
  2. 要缓存的 Java 对象必须实现 Serializable 接口。
@Cacheable(cacheNames = "usersBySpEL",//key通过变量拼接key="#root.methodName + '[' + #id + ']'",//id大于1才缓存。可缺省condition = "#id > 1",//当id大于10时,条件为true,方法返回值不会被缓存。可缺省unless = "#id > 10")public User getUserBySpEL(Integer id) {}@Cacheable(value = {"menuById"}, key = "'id-' + #menu.id")public Menu findById(Menu menu) {return menu;}
常用属性说明备注代码示例
cacheNames/value缓存名称,用来划分不同的缓存区,避免相同key值互相影响。可以是单值、数组;
在redis中相当于key的一级目录,支持:拼接多层目录
cacheNames = "users"
cacheNames = {"users","account"}
key缓存数据时使用的 key,默认是方法参数。
可以使用 spEL 表达式来编写
keyGeneratorkey 的生成器,统一管理key。key 和 keyGenerator 二选一使用,同时使用会导致异常。keyGenerator = "myKeyGenerator"
cacheManager指定缓存管理器,从哪个缓存管理器里面获取缓存
condition可以用来指定符合条件的情况下才缓存
unless否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存通过 #result 获取方法结果进行判断。
sync是否使用异步模式。默认是方法执行完,以同步的方式将方法返回的结果存在缓存中

spEL常用元数据:

说明示例备注
#root.methodName当前被调用的方法名
#root.method.name当前被调用的方法
#root.target当前被调用的目标对象
#root.targetClass当前被调用的目标对象类
#root.args[0]当前被调用的方法的参数列表
#root.cacheds[0].name当前方法调用使用的缓存区列表
#参数名 或 #p0 或 #a0方法的参数名; 0代表参数的索引
#result方法执行后的返回值如果没有执行则没有内容

3>@CachePut

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

  1. 区别于 @Cacheable,它每次都会触发真实方法的调用,可以保证缓存的一致性。
  2. 属性与 @Cacheable 类同。

4>@CacheEvict

根据一定的条件对缓存进行清空。

  1. 标记在类上时表示其中所有方法的执行都会触发缓存的清除操作;
常用属性说明备注代码示例
value
key
condition
allEntries为true时,清除value属性值中的所有缓存;默认为false,可以指定清除value属性值下具体某个key的缓存
beforeInvocation1. 默认是false,即在方法执行成功后触发删除缓存的操作;
2.如果方法抛出异常未能成功返回,不会触发删除缓存的操作
3.当改为true时,方法执行之前会清除指定的缓存,这样不论方法执行成功还是失败都会清除缓存

4)缓存实现

上文中基于注解的缓存接口,有一层CacheMananger抽象,其中用ConcurrentHashMap维护了多个Cache,通过cacheNames指定了哪个Cache。

相关文章:

【Spring学习】Spring Data Redis:RedisTemplate、Repository、Cache注解

1&#xff0c;spring-data-redis官网 1&#xff09;特点 提供了对不同Redis客户端的整合&#xff08;Lettuce和Jedis&#xff09;提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符…...

C语言:内存函数

创作不易&#xff0c;友友们给个三连吧&#xff01;&#xff01; C语言标准库中有这样一些内存函数&#xff0c;让我们一起学习吧&#xff01;&#xff01; 一、memcpy函数的使用和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); 1.1 使…...

Go+:一种简单而强大的编程语言

Go是一种简单而强大的编程语言&#xff0c;它是在Go语言之上构建的&#xff0c;旨在提供更加强大、灵活和易于使用的编程体验。Go与Go语言共享大部分语法和语义&#xff0c;因此Go开发人员可以很快上手Go&#xff0c;同时也可以使用Go来编写更加简洁和高效的代码。在本文中&…...

【开源】SpringBoot框架开发数字化社区网格管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、开发背景四、系统展示五、核心源码5.1 查询企事业单位5.2 查询流动人口5.3 查询精准扶贫5.4 查询案件5.5 查询人口 六、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的数字化社区网格管理系统&#xf…...

Lua可变参数函数

基础规则 lua传入参数给一个function时采用的是“多余部分被忽略&#xff0c;缺少部分有nil补足”的形式&#xff1a; function f(a, b)return a or b endCALL PARAMETERS f(3) a3, bnil f(3, 4) a3, b4 f(3, 4, 5) a3, b4 (5 is discarded) unpack/pack…...

Nginx实战:3-日志按天分割

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、方式1&#xff1a;定时任务执行分割脚本 1.分割日志脚本 2.添加定时任务 二、方式2&#xff1a;logrotate配置分割 1.logrotate简单介绍 2.新增切割ngi…...

springmvc中的数据提交方式

一、单个数据提交数据 jsp代码&#xff1a; <h2>1单个数据提交</h2> <form action"${pageContext.request.contextPath}/one.action">name<input name"myname"/><br>age<input name"age"><input type&…...

unity2017 遇到visual studio 2017(社区版) 30日试用期到了

安装unity2017 遇到visual studio 2017 30日试用期到了&#xff0c;网上百度搜了好多方法都没有成功。 最后用了这个方法&#xff1a; 1)启动vs2017&#xff0c;在弹出要登录的窗口之前&#xff0c;迅速的点击工具-》选项-》账户&#xff0c;勾选在添加账户或对账户重新进行身…...

Netty应用(六) 之 异步 Channel

目录 12.Netty异步的相关概念 12.1 异步编程的概念 12.2 方式1&#xff1a;主线程阻塞&#xff0c;等待异步线程完成调用&#xff0c;然后主线程发起请求IO 12.3 方式2&#xff1a;主线程注册异步线程&#xff0c;异步线程去回调发起请求IO 12.4 细节注释 12.5 异步的好处…...

STM32CubeMx+MATLAB Simulink串口输出实验,UART/USART串口测试实验

STM32CubeMxMATLAB Simulink串口输出实验...

【51单片机】串口通信实验(包括波特率如何计算)

目录 串口通信实验通信的基本概念串行通信与并行通信异步通信与同步通信单工、 半双工与全双工通信通信速率 51单片机串口介绍串口介绍串口通信简介串口相关寄存器串口工作方式方式0方式1方式 2 和方式 3 串口的使用方法&#xff08;计算波特率&#xff09; 硬件设计软件设计1、…...

Kafka零拷贝技术与传统数据复制次数比较

读Kafka技术书遇到困惑: "对比传统的数据复制和“零拷贝技术”这两种方案。假设有10个消费者&#xff0c;传统复制方式的数据复制次数是41040次&#xff0c;而“零拷贝技术”只需110 11次&#xff08;一次表示从磁盘复制到页面缓存&#xff0c;另外10次表示10个消费者各自…...

npm ERR! network This is a problem related to network connectivity.

遇到 ETIMEDOUT 错误时&#xff0c;这表明npm尝试连接到npm仓库时超时了&#xff0c;这通常是由网络连接问题引起的。这可能是因为网络不稳定、连接速度慢、或者你的网络配置阻止了对npm仓库的访问。以下是一些解决这个问题的步骤&#xff1a; 1. 检查网络连接 首先&#xff…...

【SQL高频基础题】619.只出现一次的最大数字

题目&#xff1a; MyNumbers 表&#xff1a; ------------------- | Column Name | Type | ------------------- | num | int | ------------------- 该表可能包含重复项&#xff08;换句话说&#xff0c;在SQL中&#xff0c;该表没有主键&#xff09;。 这张表的每…...

STM32F1 - GPIO外设

GPIO 1> 硬件框图2> 工作模式 1> 硬件框图 2> 工作模式 C语言描述 /** * brief Configuration Mode enumeration */typedef enum { GPIO_Mode_AIN 0x0, // Analog Input 模拟输入 GPIO_Mode_IN_FLOATING 0x04, // input floating 浮空输入GPIO_Mode_I…...

新增同步管理、操作日志模块,支持公共链接分享,DataEase开源数据可视化分析平台v2.3.0发布

2024年2月5日&#xff0c;DataEase开源数据可视化分析平台正式发布v2.3.0版本。 这一版本的功能升级包括&#xff1a;新增“同步管理”功能模块&#xff0c;用户可通过此模块&#xff0c;将传统数据库中的数据定时同步到Apache Doris中&#xff0c;让数据分析更快速&#xff1…...

跟着pink老师前端入门教程-day19

一、移动WEB开发之流式布局 1、 移动端基础 1.1 浏览器现状 PC端常见浏览器&#xff1a;360浏览器、谷歌浏览器、火狐浏览器、QQ浏览器、百度浏览器、搜狗浏览器、IE浏览器。 移动端常见浏览器&#xff1a;UC浏览器&#xff0c;QQ浏览器&#xff0c;欧朋浏览器&#xff0…...

ChatGPT学习第一周

&#x1f4d6; 学习目标 掌握ChatGPT基础知识 理解ChatGPT的基本功能和工作原理。认识到ChatGPT在日常生活和业务中的潜在应用。 了解AI和机器学习的基本概念 获取人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;的初步了解。理解这些技术是如何支撑…...

爬爬爬——今天是浏览器窗口切换和给所选人打钩(自动化)

学习爬虫路还很长&#xff0c;第一阶段花了好多天了&#xff0c;还在底层&#xff0c;虽然不是我专业要学习的语言&#xff0c;和必备的知识&#xff0c;但是我感觉还挺有意思的。加油&#xff0c;这两天把建模和ai也不学了&#xff0c;唉过年了懒了&#xff01; 加油坚持就是…...

Netty应用(五) 之 Netty引入 EventLoop

目录 第三章 Netty 1.什么是Netty&#xff1f; 2.为什么需要使用Netty&#xff1f; 3.Netty的发展历程 4.谁在使用Netty&#xff1f; 5.为什么上述这些分布式产品都使用Netty&#xff1f; 6.第一个Netty应用 7.如何理解Netty是NIO的封装 8.logback日志使用的加强 9.Ev…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…...

动态规划-1035.不相交的线-力扣(LeetCode)

一、题目解析 光看题目要求和例图&#xff0c;感觉这题好麻烦&#xff0c;直线不能相交啊&#xff0c;每个数字只属于一条连线啊等等&#xff0c;但我们结合题目所给的信息和例图的内容&#xff0c;这不就是最长公共子序列吗&#xff1f;&#xff0c;我们把最长公共子序列连线起…...