RedisTemplate的配置和讲解以及和StringRedisTemplate的区别
本文主要讲redisTempalte的几种常用的序列化方式
- string,我们大部分情况下都希望存入redis的数据可读性强一些,并且value也不总是一个规则的类型,所以这里也是不用json序列化的原因,可以更自由方便,下边提供配置方法
package sca.pro.core.redis.configuration;import cn.hutool.core.convert.Convert; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@Configuration @EnableCaching public class RedisTemplateConfig {@Value("${spring.redis.database}")private int database;@Value("${spring.redis.host}")private String host;@Value("${spring.redis.password}")private String password;@Value("${spring.redis.port}")private String port;@Value("${spring.redis.timeout}")private String timeout;@Value("${spring.redis.lettuce.pool.max-idle}")private String maxIdle;@Value("${spring.redis.lettuce.pool.min-idle}")private String minIdle;@Value("${spring.redis.lettuce.pool.max-active}")private String maxActive;@Value("${spring.redis.lettuce.pool.max-wait}")private String maxWait;@Beanpublic LettuceConnectionFactory lettuceConnectionFactory() {GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();genericObjectPoolConfig.setMaxIdle(Convert.toInt(maxIdle));genericObjectPoolConfig.setMinIdle(Convert.toInt(minIdle));genericObjectPoolConfig.setMaxTotal(Convert.toInt(maxActive));genericObjectPoolConfig.setMaxWaitMillis(Convert.toLong(maxWait));genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(100);RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();redisStandaloneConfiguration.setDatabase(database);redisStandaloneConfiguration.setHostName(host);redisStandaloneConfiguration.setPort(Convert.toInt(port));redisStandaloneConfiguration.setPassword(RedisPassword.of(password));LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(Convert.toLong(timeout))).poolConfig(genericObjectPoolConfig).build();LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);return factory;}@Beanpublic RedisTemplate<String, String> redisTemplate(LettuceConnectionFactory factory) {// 配置redisTemplateRedisTemplate<String, String> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化redisTemplate.setValueSerializer(new StringRedisSerializer());//value序列化//设置hash的key的序列化方式redisTemplate.setHashKeySerializer(new StringRedisSerializer());//设置hash的value的序列化方式redisTemplate.setHashValueSerializer(new StringRedisSerializer());redisTemplate.afterPropertiesSet();//使上面参数生效return redisTemplate;} }
其实如果key和value都是string,那就等效于我们直接引入StringRedisTemplate
- 如果使用字节数组的形式序列化,redistemplate默认使用的jdk的序列化方式,但是jdk的序列化后的字节数组不仅重,而且序列化和反序列化我们用的是protobuf,如下
pom
<!-- 工具库 -->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>18.0</version>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><!-- 序列化 -->
<dependency><groupId>com.dyuproject.protostuff</groupId><artifactId>protostuff-core</artifactId><version>1.1.3</version>
</dependency>
<dependency><groupId>com.dyuproject.protostuff</groupId><artifactId>protostuff-runtime</artifactId><version>1.1.3</version>
</dependency>
2.自己编写序列化工具
@Slf4j
public class ProtoStuffUtil {/*** 序列化对象** @param obj* @return*/public static <T> byte[] serialize(T obj) {if (obj == null) {log.error("Failed to serializer, obj is null");throw new RuntimeException("Failed to serializer");}@SuppressWarnings("unchecked") Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(obj.getClass());LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);byte[] protoStuff;try {protoStuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);} catch (Exception e) {log.error("Failed to serializer, obj:{}", obj, e);throw new RuntimeException("Failed to serializer");} finally {buffer.clear();}return protoStuff;}/*** 反序列化对象** @param paramArrayOfByte* @param targetClass* @return*/public static <T> T deserialize(byte[] paramArrayOfByte, Class<T> targetClass) {if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {log.error("Failed to deserialize, byte is empty");throw new RuntimeException("Failed to deserialize");}T instance;try {instance = targetClass.newInstance();} catch (InstantiationException | IllegalAccessException e) {log.error("Failed to deserialize", e);throw new RuntimeException("Failed to deserialize");}Schema<T> schema = RuntimeSchema.getSchema(targetClass);ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);return instance;}/*** 序列化列表** @param objList* @return*/public static <T> byte[] serializeList(List<T> objList) {if (objList == null || objList.isEmpty()) {log.error("Failed to serializer, objList is empty");throw new RuntimeException("Failed to serializer");}@SuppressWarnings("unchecked") Schema<T> schema =(Schema<T>) RuntimeSchema.getSchema(objList.get(0).getClass());LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);byte[] protoStuff;ByteArrayOutputStream bos = null;try {bos = new ByteArrayOutputStream();ProtostuffIOUtil.writeListTo(bos, objList, schema, buffer);protoStuff = bos.toByteArray();} catch (Exception e) {log.error("Failed to serializer, obj list:{}", objList, e);throw new RuntimeException("Failed to serializer");} finally {buffer.clear();try {if (bos != null) {bos.close();}} catch (IOException e) {e.printStackTrace();}}return protoStuff;}/*** 反序列化列表** @param paramArrayOfByte* @param targetClass* @return*/public static <T> List<T> deserializeList(byte[] paramArrayOfByte, Class<T> targetClass) {if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {log.error("Failed to deserialize, byte is empty");throw new RuntimeException("Failed to deserialize");}Schema<T> schema = RuntimeSchema.getSchema(targetClass);List<T> result;try {result = ProtostuffIOUtil.parseListFrom(new ByteArrayInputStream(paramArrayOfByte), schema);} catch (IOException e) {log.error("Failed to deserialize", e);throw new RuntimeException("Failed to deserialize");}return result;}}
3.RedisTemplate的工具类方法
@Component
public class RedisClient {private final RedisTemplate<String, String> redisTemplate;@Autowiredpublic RedisClient(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;}/*** get cache** @param field* @param targetClass* @param <T>* @return*/public <T> T get(final String field, Class<T> targetClass) {byte[] result = redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.get(field.getBytes()));if (result == null) {return null;}return ProtoStuffUtil.deserialize(result, targetClass);}/*** put cache** @param field* @param obj* @param <T>* @return*/public <T> void set(String field, T obj) {final byte[] value = ProtoStuffUtil.serialize(obj);redisTemplate.execute((RedisCallback<Void>) connection -> {connection.set(field.getBytes(), value);return null;});}/*** put cache with expire time** @param field* @param obj* @param expireTime 单位: s* @param <T>*/public <T> void setWithExpire(String field, T obj, final long expireTime) {final byte[] value = ProtoStuffUtil.serialize(obj);redisTemplate.execute((RedisCallback<Void>) connection -> {connection.setEx(field.getBytes(), expireTime, value);return null;});}/*** get list cache** @param field* @param targetClass* @param <T>* @return*/public <T> List<T> getList(final String field, Class<T> targetClass) {byte[] result = redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.get(field.getBytes()));if (result == null) {return null;}return ProtoStuffUtil.deserializeList(result, targetClass);}/*** put list cache** @param field* @param objList* @param <T>* @return*/public <T> void setList(String field, List<T> objList) {final byte[] value = ProtoStuffUtil.serializeList(objList);redisTemplate.execute((RedisCallback<Void>) connection -> {connection.set(field.getBytes(), value);return null;});}/*** put list cache with expire time** @param field* @param objList* @param expireTime* @param <T>* @return*/public <T> void setListWithExpire(String field, List<T> objList, final long expireTime) {final byte[] value = ProtoStuffUtil.serializeList(objList);redisTemplate.execute((RedisCallback<Void>) connection -> {connection.setEx(field.getBytes(), expireTime, value);return null;});}/*** get h cache** @param key* @param field* @param targetClass* @param <T>* @return*/public <T> T hGet(final String key, final String field, Class<T> targetClass) {byte[] result = redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.hGet(key.getBytes(), field.getBytes()));if (result == null) {return null;}return ProtoStuffUtil.deserialize(result, targetClass);}/*** put hash cache** @param key* @param field* @param obj* @param <T>* @return*/public <T> boolean hSet(String key, String field, T obj) {final byte[] value = ProtoStuffUtil.serialize(obj);return redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.hSet(key.getBytes(), field.getBytes(), value));}/*** put hash cache** @param key* @param field* @param obj* @param <T>*/public <T> void hSetWithExpire(String key, String field, T obj, long expireTime) {final byte[] value = ProtoStuffUtil.serialize(obj);redisTemplate.execute((RedisCallback<Void>) connection -> {connection.hSet(key.getBytes(), field.getBytes(), value);connection.expire(key.getBytes(), expireTime);return null;});}/*** get list cache** @param key* @param field* @param targetClass* @param <T>* @return*/public <T> List<T> hGetList(final String key, final String field, Class<T> targetClass) {byte[] result = redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.hGet(key.getBytes(), field.getBytes()));if (result == null) {return null;}return ProtoStuffUtil.deserializeList(result, targetClass);}/*** put list cache** @param key* @param field* @param objList* @param <T>* @return*/public <T> boolean hSetList(String key, String field, List<T> objList) {final byte[] value = ProtoStuffUtil.serializeList(objList);return redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.hSet(key.getBytes(), field.getBytes(), value));}/*** get cache by keys** @param key* @param fields* @param targetClass* @param <T>* @return*/public <T> Map<String, T> hMGet(String key, Collection<String> fields, Class<T> targetClass) {List<byte[]> byteFields = fields.stream().map(String::getBytes).collect(Collectors.toList());byte[][] queryFields = new byte[byteFields.size()][];byteFields.toArray(queryFields);List<byte[]> cache = redisTemplate.execute((RedisCallback<List<byte[]>>) connection -> connection.hMGet(key.getBytes(), queryFields));Map<String, T> results = new HashMap<>(16);Iterator<String> it = fields.iterator();int index = 0;while (it.hasNext()) {String k = it.next();if (cache.get(index) == null) {index++;continue;}results.put(k, ProtoStuffUtil.deserialize(cache.get(index), targetClass));index++;}return results;}/*** set cache by keys** @param field* @param values* @param <T>*/public <T> void hMSet(String field, Map<String, T> values) {Map<byte[], byte[]> byteValues = new HashMap<>(16);for (Map.Entry<String, T> value : values.entrySet()) {byteValues.put(value.getKey().getBytes(), ProtoStuffUtil.serialize(value.getValue()));}redisTemplate.execute((RedisCallback<Void>) connection -> {connection.hMSet(field.getBytes(), byteValues);return null;});}/*** get caches in hash** @param key* @param targetClass* @param <T>* @return*/public <T> Map<String, T> hGetAll(String key, Class<T> targetClass) {Map<byte[], byte[]> records = redisTemplate.execute((RedisCallback<Map<byte[], byte[]>>) connection -> connection.hGetAll(key.getBytes()));Map<String, T> ret = new HashMap<>(16);for (Map.Entry<byte[], byte[]> record : records.entrySet()) {T obj = ProtoStuffUtil.deserialize(record.getValue(), targetClass);ret.put(new String(record.getKey()), obj);}return ret;}/*** list index** @param key* @param index* @param targetClass* @param <T>* @return*/public <T> T lIndex(String key, int index, Class<T> targetClass) {byte[] value =redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.lIndex(key.getBytes(), index));return ProtoStuffUtil.deserialize(value, targetClass);}/*** list range** @param key* @param start* @param end* @param targetClass* @param <T>* @return*/public <T> List<T> lRange(String key, int start, int end, Class<T> targetClass) {List<byte[]> value = redisTemplate.execute((RedisCallback<List<byte[]>>) connection -> connection.lRange(key.getBytes(), start, end));return value.stream().map(record -> ProtoStuffUtil.deserialize(record, targetClass)).collect(Collectors.toList());}/*** list left push** @param key* @param obj* @param <T>*/public <T> void lPush(String key, T obj) {final byte[] value = ProtoStuffUtil.serialize(obj);redisTemplate.execute((RedisCallback<Long>) connection -> connection.lPush(key.getBytes(), value));}/*** list left push** @param key* @param objList* @param <T>*/public <T> void lPush(String key, List<T> objList) {List<byte[]> byteFields = objList.stream().map(ProtoStuffUtil::serialize).collect(Collectors.toList());byte[][] values = new byte[byteFields.size()][];redisTemplate.execute((RedisCallback<Long>) connection -> connection.lPush(key.getBytes(), values));}/*** 精确删除key** @param key*/public void deleteCache(String key) {redisTemplate.delete(key);}/*** 排行榜的存入** @param redisKey* @param immutablePair*/public void zAdd(String redisKey, ImmutablePair<String, BigDecimal> immutablePair) {final byte[] key = redisKey.getBytes();final byte[] value = immutablePair.getLeft().getBytes();redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.zAdd(key, immutablePair.getRight().doubleValue(), value));}/*** 获取排行榜低->高排序** @param redisKey 要进行排序的类别* @param start* @param end* @return*/public List<ImmutablePair<String, BigDecimal>> zRangeWithScores(String redisKey, int start, int end) {Set<RedisZSetCommands.Tuple> items = redisTemplate.execute((RedisCallback<Set<RedisZSetCommands.Tuple>>) connection -> connection.zRangeWithScores(redisKey.getBytes(), start, end));return items.stream().map(record -> ImmutablePair.of(new String(record.getValue()), BigDecimal.valueOf(record.getScore()))).collect(Collectors.toList());}/*** 获取排行榜高->低排序** @param redisKey 要进行排序的类别* @param start* @param end* @return*/public List<ImmutablePair<String, BigDecimal>> zRevRangeWithScores(String redisKey, int start, int end) {Set<RedisZSetCommands.Tuple> items = redisTemplate.execute((RedisCallback<Set<RedisZSetCommands.Tuple>>) connection -> connection.zRevRangeWithScores(redisKey.getBytes(), start, end));return items.stream().map(record -> ImmutablePair.of(new String(record.getValue()), BigDecimal.valueOf(record.getScore()))).collect(Collectors.toList());}
}
- 最推荐的一种序列化方式GenericJackson2JsonRedisSerializer,org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer 使用Jackson 实现JSON的序列化方式,Generic单词翻译过来表示:通用的意思,可以看出,是支持所有类。
@Bean@ConditionalOnMissingBean(name = "redisTemplate")public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);//String的序列化方式StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// 使用GenericJackson2JsonRedisSerializer 替换默认序列化(默认采用的是JDK序列化)GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();//key序列化方式采用String类型template.setKeySerializer(stringRedisSerializer);//value序列化方式采用jackson类型template.setValueSerializer(genericJackson2JsonRedisSerializer);//hash的key序列化方式也是采用String类型template.setHashKeySerializer(stringRedisSerializer);//hash的value也是采用jackson类型template.setHashValueSerializer(genericJackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}}
运行下边的测试类测试GenericJackson2JsonRedisSerializer,发现不管是字符串还是对象还是数组都很通用
@Test
void redisTemplateSerializeTest() {String redisTemplateStringKey = "redisTemplateStringKey";String redisTemplateUserObjectKey = "redisTemplateUserObjectKey";String redisTemplateUserArrayObjectKey = "redisTemplateUserArrayObjectKey";String redisTemplateJSONObjectKey = "redisTemplateJSONObjectKey";String redisTemplateJSONArrayKey = "redisTemplateJSONArrayKey";//序列化String类型和反序列化String类型redisTemplate.opsForValue().set(redisTemplateStringKey, "austin");String austin = (String) redisTemplate.opsForValue().get(redisTemplateStringKey);System.out.println("stringGet: " + austin);//序列化Object对象类型和反序列化Object对象类型 (User对象)User user = new User("123", "austin", 25);redisTemplate.opsForValue().set(redisTemplateUserObjectKey, user);User userGet = (User) redisTemplate.opsForValue().get(redisTemplateUserObjectKey);System.out.println("userGet: " + userGet);//序列化Object对象数组类型和反序列化Object对象数组类型 (User[]对象数组)User user1 = new User("1", "austin1", 25);User user2 = new User("2", "austin2", 25);User[] userArray = new User[]{user1, user2};redisTemplate.opsForValue().set(redisTemplateUserArrayObjectKey, userArray);User[] userArrayGet = (User[]) redisTemplate.opsForValue().get(redisTemplateUserArrayObjectKey);System.out.println("userArrayGet: " + userArrayGet);//序列化JSONObject对象类型和反序列化JSONObject对象类型JSONObject jsonObject = new JSONObject();jsonObject.put("id", "123");jsonObject.put("name", "austin");jsonObject.put("age", 25);redisTemplate.opsForValue().set(redisTemplateJSONObjectKey, jsonObject);JSONObject jsonObjectGet = (JSONObject) redisTemplate.opsForValue().get(redisTemplateJSONObjectKey);System.out.println("jsonObjectGet: " + jsonObjectGet);//序列化JSONArray对象类型和反序列化JSONArray对象类型JSONArray jsonArray = new JSONArray();JSONObject jsonObject1 = new JSONObject();jsonObject1.put("id", "1");jsonObject1.put("name", "austin1");jsonObject1.put("age", 25);JSONObject jsonObject2 = new JSONObject();jsonObject2.put("id", "1");jsonObject2.put("name", "austin2");jsonObject2.put("age", 25);jsonArray.add(jsonObject1);jsonArray.add(jsonObject2);redisTemplate.opsForValue().set(redisTemplateJSONArrayKey, jsonArray);JSONArray jsonArrayGet = (JSONArray) redisTemplate.opsForValue().get(redisTemplateJSONArrayKey);System.out.println("jsonArrayGet: " + jsonArrayGet);
}
key- value :
字符串类型
Key: redisTemplateStringKey
Value: "austin"
对象类型
Key: redisTemplateUserObjectKey
Value:
{
"@class": "com.example.jedisserializefrombytestojson.User",
"id": "123",
"name": "austin",
"age": 25
}
对象数组类型
Key: redisTemplateUserArrayObjectKey
Value:
[
"[Lcom.example.jedisserializefrombytestojson.User;",
[
{
"@class": "com.example.jedisserializefrombytestojson.User",
"id": "1",
"name": "austin1",
"age": 25
},
{
"@class": "com.example.jedisserializefrombytestojson.User",
"id": "2",
"name": "austin2",
"age": 25
}
]
]
JSONObject类型
Key: redisTemplateJSONObjectKey
Value:
{
"@class": "com.alibaba.fastjson.JSONObject",
"name": "austin",
"id": "123",
"age": 25
}
JSONArray类型
Key: redisTemplateJSONArrayKey
Value:
[
"com.alibaba.fastjson.JSONArray",
[
{
"@class": "com.alibaba.fastjson.JSONObject",
"name": "austin1",
"id": "1",
"age": 25
},
{
"@class": "com.alibaba.fastjson.JSONObject",
"name": "austin2",
"id": "1",
"age": 25
}
]
]
相关文章:

RedisTemplate的配置和讲解以及和StringRedisTemplate的区别
本文主要讲redisTempalte的几种常用的序列化方式 string,我们大部分情况下都希望存入redis的数据可读性强一些,并且value也不总是一个规则的类型,所以这里也是不用json序列化的原因,可以更自由方便,下边提供配置方法 …...

在oracle中的scn技术
SCN可以说是Oracle中一个很基础的部分,但同时它也是一个很重要的。它是系统中维持数据的一致性和顺序恢复的重要标志,是数据库非常重要的一种数据结构。 转载:深入剖析 - Oracle SCN机制详细解读 - 知乎 (zhihu.com)https://zhuanlan.zhihu.…...

LINUX 嵌入式C编程--信号编程
基本概念 信号是事件发生时对进程的通知机制,也可以把它称为软件中断。信号与硬件中断的相似之处在于能够打断程序当前执行的正常流程,其实是在软件层次上对中断机制的一种模拟。信号提供了一种处理异步事件的方法。 信号目的 **信号的目的是用来通信…...

Linux:优化原则
web系统的优化原则: 从单机到集群 对Linux系统自身的优化原则:...

HarmonyOs 4 (一) 认识HarmonyOs
目录 一 HarmonyOs 背景1.1 发展时间线1.2 背景分析1.2.1 新场景1.2.2 新挑战1.2.3 鸿蒙生态迎接挑战 二 HarmonyOS简介2.1 OpenHarmony2.2 HarmonyOS Connect2.3 HarmonyOS Next**2.4 ArkTS (重点掌握)****2.5 ArkUI** 三 鸿蒙生态应用核心技术理念**3.…...

System.out.println隐藏字符串
昨天开发的时候遇到一个坑,这个坑几乎浪费了我一整天时间,我甚至现在都不知道其原因。 开发环境 macOS Ventura 13.4 IntelliJ IDEA 2023.1.2 现象 我用java的各种httpclient获取网络上的一个文本文件,获取的文本文件的内容使用System.ou…...

Java中的线程池你了解多少?
🌈🌈🌈今天给大家分享的是Java标准库中的线程池,以及线程池的自定义实现。 清风的CSDN博客 🛩️🛩️🛩️希望我的文章能对你有所帮助,有不足的地方还请各位看官多多指教,…...

leetCode 131.分割回文串 + 动态规划 + 回溯算法 + 优化 + 图解 + 笔记
我的往期文章: leetCode 647.回文子串 动态规划 优化空间 / 中心扩展法 双指针-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/133883091?spm1001.2014.3001.5501leetCode 131.分割回文串 回溯算法 图解 笔记-CSDN博客https://blog.csdn.n…...

【傻瓜级JS-DLL-WINCC-PLC交互】3.JS-DLL进行交互
思路 JS-DLL-WINCC-PLC之间进行交互,思路,先用Visual Studio创建一个C#的DLL控件,然后这个控件里面嵌入浏览器组件,实现JS与DLL通信,然后DLL放入到WINCC里面的图形编辑器中,实现DLL与WINCC的通信。然后PLC与…...

深度学习手势识别算法实现 - opencv python 计算机竞赛
文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习手势识别算法实现 - opencv python 该项目较为新颖…...

2023-12-01 AIGC-自动生成ppt的AI工具
摘要: 2023-12-01 AIGC-自动生成ppt-记录 自动生成ppt: BoardMix boardmix 一键生成ppt boardmix是一款基于云的ai设计软件,允许创建用于各种目的的自定义演示文稿、ai绘画,ai生成思维导图等。以下是它的一些功能: 可定制的模板 - 它有一个…...

NoSQL 数据建模错误会降低性能
数据建模错误是破坏性能的最简单方法之一。当您使用 NoSQL 时,特别容易搞砸,(讽刺的是)NoSQL 往往用于对性能最敏感的工作负载。NoSQL 数据建模最初可能看起来非常简单:只需对数据进行建模以适应应用程序的访问模式。但…...

在Android上搭建一个NDK项目
首先New Project,选择Native C,点击Next。 填入项目名称和包名,点击Next。 这里我们选择Cmake默认的C版本。 创建好的项目目录,里面比我们正常的Android项目多了一个cpp目录 打开MainActivity。里面定义了一个jni方法stringFromJN…...

TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析
TOP-K问题 TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大 比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等 对于Top-K问题,能想到的最简单直接的方式就是排序,但是…...

3、服务器性能剖析
性能优化简介 **我们将性能定义为完成某件任务所需要的时间度量,换句话说,性能即响应时间,这是一个非常重要的原则。**我们通过任务和时间而不是资源来测量性能。数据库服务器的目的是执行sql语句,所以他关注的任务是查询或者语句…...

xxl-job 分布式任务调度框架
文章目录 分布式任务调度XXL-Job 简介XXL-Job 环境搭建XXL-Job (源码说明)配置部署调度中心docker安装 Bean模式任务(方法形式)-入门案例任务详解任务详解-执行器任务详解-基础配置任务详解-调度配置任务详解-基础配置任务详解-阻塞处理策略任务详解-路由策略 路由策略路由策略…...

软件使用-stm32入门
这节主要是介绍大家使用两个软件。这两个软件也是比较常用的,里面也有很多有意思的功能,可以给大家介绍一下。 1. FlyMcu 软件 这个软件可以通过串口给 STM32 下载程序,如果你没有 STLINK,就可以用这个软件通过串口下载程序。 …...

使用MAT分析内存泄漏(mac)
前言 今天主要简单分享下Eclipse的Memory Analyzer在mac下的使用。 一、Mat(简称)干什么的? 就是分析java内存泄漏的工具。 二、使用步骤 1.下载 mac版的现在也分芯片,别下错了。我这里是M2芯片的,下载的Arch64的。 …...

【Vue】Linux 运行 npm run serve 报错 vue-cli-service: Permission denied
问题描述 在Linux系统上运行npm run serve命令时,控制台报错: sudo npm run serve project50.1.0 serve vue-cli-service serve sh: 1: vue-cli-service: Permission denied错误截图如下: 原因分析 该错误是由于vue-cli-service文件权限不…...

LeetCode的几道题
一、捡石头 292 思路就是: 谁面对4块石头的时候,谁就输(因为每次就是1-3块石头,如果剩下4块石头,你怎么拿,我都能把剩下的拿走,所以你就要想尽办法让对面面对4块石头的倍数, 比如有…...

NLP/Natural Language Processing
一、NLP是什么 自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向,也就是人们常说的「自然语言处理」,就是研究如何让计算机读懂人类语言,即将人的自然语言转换为计算机可以阅读的指令。它研…...

【教学类-06-12】20231202 0-9数字分合-房屋样式(一)-下右空-升序-抽7题
作品展示-屋顶分合(0-9之间随机抽取7个不重复分合) 背景需求: 大班幼儿学分合题,通常区角里会设计一个“房屋分合”的样式 根据这种房屋样式,设计0-9内的升序分合题模板 素材准备 WORD样式 代码展示: 2-9…...

uni-app 微信小程序 电子签名及签名图片翻转显示功能
文章目录 1. 需求背景2. 开始撸2.1 点击 重写 进入签名页面(上图一)2.2 书写签名,点击确认返回,及图片翻转显示(上图二,三) 3. 图片进行翻转,返回翻转后的图片 1. 需求背景 接的一个…...

MySQL 8.0关键字和保留字
官网地址: https://dev.mysql.com/doc/refman/8.0/en/keywords.html 可以粘贴出去自己排版整理 {accessible} {account} {action} {active} {add} {admin} {after} {against} {aggregate} {algorithm} {all} {alter} {always} {analyse} {analyze} …...

PyLMKit(3):基于角色扮演的应用案例
角色扮演应用案例RolePlay 0.项目信息 日期: 2023-12-2作者:小知课题: 通过设置角色模板并结合在线搜索、记忆和知识库功能,实现典型的对话应用功能。这个功能是大模型应用的基础功能,在后续其它RAG等功能中都会用到这个功能。功…...

JAVA全栈开发 集合详解(day14+day15汇总)
一、数组 数组是一个容器,可以存入相同类型的多个数据元素。 数组局限性: 长度固定:(添加–扩容, 删除-缩容) 类型是一致的 对象数组 : int[] arr new int[5]; … Student[] arr …...

Linux Spug自动化运维平台本地部署与公网远程访问
文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台,整合了主机管理、主机批量执行、主机在线终端、文件…...

zookeeper集群和kafka集群
(一)kafka 1、kafka3.0之前依赖于zookeeper 2、kafka3.0之后不依赖zookeeper,元数据由kafka节点自己管理 (二)zookeeper 1、zookeeper是一个开源的、分布式的架构,提供协调服务(Apache项目&…...

Java——》JSONObjet 数据顺序
推荐链接: 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…...

【个人记录】NGINX反向代理grpc服务
最开始使用proxy_pass去代理了grpc服务,结果请求时候报错提示: rpc error: code Unavailable desc connection error: desc "error reading server preface: http2: frame too large"后来才知道代理grpc服务需要使用grpc_pass,…...