JavaWeb合集12-Redis

十二、Redis

1、Redis 入门

Redis是一个基于内存的key-valule 结构数据库。

特点:基于内存存储,读写性能高

场景:适合存储热点数据(热点商品、资讯、新闻)

Redis安装包分为Windows版和Linux版:

Windows版 下载地址: https://github.com/microsoftarchive/redis/releases

Linux版 下载地址: https://download.redis.io/releases/

Redis操作工具:https://gitee.com/qishibo/AnotherRedisDesktopManager/releases

Redis的Windows版属于绿色软件,直接解压即可使用,解压后目录结构如下:

在这里插入图片描述

Redis启动命令(cmd):服务名 配置文件名

redis-server.exe redis.windows.conf

在这里插入图片描述

启动客户端(cmd操作,可对其存取数据):

redis-cli.exe

可通过配置文件中参数的设置密码,如:requirepass 123456

2、Redis 数据类型

Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型。

5种常用数据类型:字符串string、哈希hash、列表list、集合set、有序集合sorted set/ zset

在这里插入图片描述

  • 字符串(string):普通字符串,Redis中最简单的数据类型。
  • 哈希(hash):也叫散列,类似于Java中的HashMap结构。可以用来存对象
  • 列表(list):按照插入顺序排序,可以有重复元素,类似于Java中的LinkedList,可以永来存有顺序的数据
  • 集合(set):无序集合,没有重复元素,类似于Java中的HashSet,可以进行集合间的计算(交集、并集)
  • 有序集合(sorted set / zset):集合中每个元素关联一个分数(score)根据分数升序排序,没有重复元素

3、Redis常用命令

3.1 字符串操作命令
set key value  //设置指定key的值(如果存在key,那么就修改value) 如:set name  小明  get key       //获取指定key的值 如:get  namesetex key seconds value //设置指定key的值,并将key的过期时间设为seconds秒,如:setex code 2 123setnx  key value     //只有在key不存在时设置key的值(如果存在key不能修改value)  setnx sex 男
3.2 哈希操作命令

Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,常用命令:

在这里插入图片描述

hset key field value  //将哈希表key中的字段field的值设为value
//如:hset 100 name 小明    hset 100 set 男hget key field    //获取存储在哈希表中指定字段的值
//如:hget  100 name   获取属性name的value值:小明hkeys key    //获取哈希表中所有字段
//如:hkeys 100   结果为:name、sethvals key    //获取哈希表中所有值
//如:hvals 100  结果为:小明、男hdel key field   //删除存储在哈希表中的指定字段
//如:hdel  100  sex  删除set属性
3.3 列表操作命令

Redis列表(list)是简单的字符串列表,按照插入顺序排序,常用命令

在这里插入图片描述

lpush key value1 [value2]  //将一个或多个值插入到列表头部(left左边插入)rpush key value1 [value2]  //将一个或多个值插入到列表头部(right右边插入)lrange key start stop   //获取列表指定范围内的元素(下标从0开始)
//lrange key 0 -1  可返回列表里的全部数据 rpop  key    //移除并获取列表最后一个元素lpop  key    //移除并获取列表最前面一个元素llen  key    //获取列表长度
3.4 集合操作命令

Redis set是string类型的无序集合。集合成员是唯大-的,集合中不能出现重复的数据,常用命令:

在这里插入图片描述

sadd key member1 [member2]   //向集合添加一个或多个成员smembers  key                //返回集合中的所有成员scard  key                   //获取集合的成员数sinter  key1 [key2]         //返回给定所有集合的交集sunion key1 [key2]            //返回所有给定集合的并集srem  key member1 [member2]  //删除集合中一个或多个成员
3.5 有序集合操作命令

Redis有序集合是string类型元素的集合(zset),且不允许有重复成员。每个元素都会关联一个double类型的分数。通过关联一个double类型的分数来对集合进行排序, 常用命令:

在这里插入图片描述

zadd key score1 member1 [score2 member2]     //向有序集合添加一个或多个成员zrange key start stop [WITHSCORES]          //通过索引区间返回有序集合中指定区间内的成员
//加上WITHSCORES 可以输出对应的member,zrange key 0 -1 输出全部的scorezincrby key increment member      //有序集合中对指定成员的分数加上增量ZREM key member [member ...]                //移除有序集合中的一个或多个成员
3.6 通用命令

Redis的通用命令是不分数据类型的,都可以使用的命令:

keys pattern    //查找所有符合给定模式(pattern)的key(正则表达式)exists key       //检查给定key是否存在type key         //返回key所储存的值的类型del key1 [key2]          //该命令用于在key存在时删除key 

4、在java中如何操作Redis

4.1 Redis的java客户端

Redis的Java客户端很多,常用的几种:Jedis(官方推荐的)、Lettuce、Spring Data Redis。

Spring Data Redis是Spring的一部分,对Redis底层开发包进行了高度封装。在Spring项目中,可以使用Spring Data Redis来简化操作。

4.2 Spring Date Redis使用方式

操作步骤:

  1. 导入Spring Data Redis的maven坐标

    <dependency>
    <groupId>org.springframework.boot</ groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 配置Redis数据源

    spring:data:redis:host: localhostport: 6379password: 123456
    
  3. 编写配置类,创建Redis Template对象

    // redis配置类
    @Configuration
    @Slf4j
    public class RedisConfiguration {// 配置redisTemplate@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){log.info("redisTemplate初始化中...");RedisTemplate redisTemplate = new RedisTemplate();// 设置redis的连接工厂对象redisTemplate.setConnectionFactory(redisConnectionFactory);// 设置redis字符串类型的key的序列化器redisTemplate.setKeySerializer(new StringRedisSerializer());return redisTemplate;}
    }
    
  4. 通过Redis Template对象操作Redis

    @SpringBootTest
    public class RedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testRedis() {//创建一个字符串类型的redis操作对象ValueOperations valueOperations = redisTemplate.opsForValue();// 创建一个哈希类型的redis操作对象HashOperations hashOperations = redisTemplate.opsForHash();// 创建一个列表类型的redis操作对象ListOperations listOperations = redisTemplate.opsForList();//创建一个集合类型的redis操作对象SetOperations setOperations = redisTemplate.opsForSet();//创建一个有序集合类型的redis操作对象ZSetOperations zSetOperations = redisTemplate.opsForZSet();}}
    
4.2.1 Redis字符存取串类型操作
   @Testvoid stringRedis(){/*** String类型Redis:set、get、setnx、setex*///创建一个字符串类型的redis操作对象ValueOperations valueOperations =redisTemplate.opsForValue();// 设置值valueOperations.set("name","yzhy");// 获取值String name =(String) valueOperations.get("name");System.out.println(name);// 设置值并设置过期时间(10分钟)valueOperations.set("code","12345",10, TimeUnit.MINUTES);// 设置值,如果key不存在,则设置值valueOperations.setIfAbsent("code", "4321");}
4.2.2 Redis操作Hash类型存取操作
    @Testvoid   ridisHash(){/*** Hash类型Redis:hset、hget、hkeys、hvals、hlen、hdel*/// 创建一个哈希类型的redis操作对象HashOperations hashOperations =redisTemplate.opsForHash();// 设置值hashOperations.put("user","name","yhzy");hashOperations.put("user","age","18");hashOperations.put("user","sex","男");//取值String age = (String) hashOperations.get("user","age");System.out.println(age);// 取keys的集合Set keys = hashOperations.keys("user");for (Object key : keys) {System.out.println(key);}//取values的集合List values = hashOperations.values("user");for(Object value : values){System.out.println(value);}// 取hash的长度Long size = hashOperations.size("user");System.out.println(size);// 删除hashOperations.delete("user","age");}
}
4.2.3 Redis操作List数据类型
    @Testvoid redisList(){/*** List类型Redis:lpush、rpush、lpop、rpop、lrange、lrem、lset、lindex、llen*/ListOperations listOperations = redisTemplate.opsForList();listOperations.rightPush("list","小明");listOperations.rightPush("list","小梅");listOperations.leftPushAll("list","小红","小刚");String name = (String) listOperations.index("list",0);System.out.println(name);List<String> list =listOperations.range("list",0,-1);for (String s : list) {System.out.println(s);}Long size = listOperations.size("list");System.out.println(size);listOperations.leftPop("list");}
}
4.2.4 Redis操作Set集合数据类型
   @Testvoid redisSet(){/*** Set类型Redis:sadd、srem、smembers、scard、sismember、srandmember、sinter、sunion*/// 创建一个集合类型的redis操作对象SetOperations setOper=  redisTemplate.opsForSet();setOper.add("fruitName1","苹果","香蕉","橘子");setOper.add("fruitName2","苹果","草莓","葡萄");Set<String> fruitNames= setOper.members("fruitName1");for (String fruitName : fruitNames){System.out.println(fruitName);}System.out.println(setOper.size("fruitName1"));// 判断是否包含System.out.println(setOper.isMember("fruitName1","香蕉"));//   求交集Set<String> fruitIntersect = setOper.intersect("fruitName1","fruitName2");for (String fruit : fruitIntersect){System.out.println(fruit);}System.out.println("=====================");// 求并集Set<String> fruitUnion = setOper.union("fruitName1","fruitName2");for (String fruit : fruitUnion){System.out.println(fruit);}}
4.2.5 Redis有序集合数据类型操作
   @Testvoid redisZSet(){/*** ZSet类型Redis:zadd、zrem、zrange、zrevrange、zcard、zscore、zrank、zrevrank、zcount、zrangebyscore、zremrangebyrank、zremrangebyscore*/// 创建一个有序集合类型的redis操作对象ZSetOperations zSetOper= redisTemplate.opsForZSet();zSetOper.add("scors","小明",100);zSetOper.add("scors","小红",90);zSetOper.add("scors","小刚",98);System.out.println(zSetOper.size("scors"));System.out.println(zSetOper.score("scors","小刚"));//默认升序排序Set  scors =  zSetOper.range("scors",0,-1);for (Object o : scors){System.out.println(o);}System.out.println("======================");// 倒序Set  scors1 =  zSetOper.reverseRange("scors",0,-1);for (Object o : scors1){System.out.println(o);}// 删除zSetOper.remove("scors","小刚","小红");}
4.2.6 Redis通用命令
    @Testvoid redisCommon(){/*** Redis通用操作:keys、etits、type、del*/// 获取所有的key(正则表达式)Set<String> keys = redisTemplate.keys("*");for (String key : keys) {System.out.print(redisTemplate.type(key)+" ");System.out.println(key);}// 判断key是否存在Boolean isExist = redisTemplate.hasKey("name");System.out.println(isExist);// 删除对应keyredisTemplate.delete("name");}

5、场景运用设计

5.1 存储营业状态

外卖商家,右自己的外卖管理端,可以添加菜品对外售卖,售卖前,需要将店铺的营业状态从打样中设置为营业中,其中这个状态,是保存到Redis中的。(0代表:打样中;1代表:营业中)

@RestController
@RequestMapping("/admin/shop")
public class ShopController {private static final String KEY="SHOP_STATUS_KEY";@Autowiredprivate RedisTemplate redisTemplate;/*** 设置店铺状态* @param status* @return*/@Operation(summary = "设置店铺状态")@PutMapping("/{status}")public Result setShopStatus(@PathVariable Integer status) {redisTemplate.opsForValue().set(KEY,status);return Result.success("设置成功",status);}/*** 获取店铺状态* @return*/@Operation(summary = "获取店铺状态")@GetMapping("/status")public Result getShopStatus(){Integer status =(Integer) redisTemplate.opsForValue().get(KEY);return Result.success("获取成功",status);}
}
5.2 存储和清除菜品数据

菜品分类喝套餐分类进行存储,其中分类ID作为存储的key,分类里面包含的数据作为value,来存储。

每当通过菜品分类id或者套餐分类id,来对数据进行查询时,进行先查询Redis里面是否有对应的数据,如果没有才查询数据库,从数据库里面查询出来的结果,再缓存到Redis中。

如果,对菜品,或者套装进行增删改操作时,就会将Redis中对应的一组key进行清除,如(dish_*、setmeal_*)

//查询数据@RestController("userDishController")
@RequestMapping("/user/dish")
public class DishController {@Autowiredprivate RedisTemplate redisTemplate;@Operation(summary = "根据分类ID菜品列表")@GetMapping("/list")public Result list(Long categoryId){//1、构建KeyString key = "dish_"+categoryId;//2、查询Redis缓存List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);//3、判断缓存是否存在,存在就获取缓存,并返回if(list!=null && list.size()>0){return Result.success(list);}//4、缓存不存在,查询数据库Dish dish = new Dish();dish.setCategoryId(categoryId);list = dishService.getDishWithFlavorListByCategoryId(dish);//5、将查询结果保存到Redis缓存中(存什么类型的数据,就用什么类型的变量接收)redisTemplate.opsForValue().set(key,list);return Result.success(list);}
}
//清除缓存
@RestController
@RequestMapping("/admin/dish")
@Slf4j
public class DishController {@Autowiredprivate RedisTemplate redisTemplate;/*** 添加菜品* @param dishDto* @return*/@Operation(summary = "添加菜品")@PostMappingpublic Result addDish(@RequestBody DishDTO dishDto) {int insert = dishService.addDish(dishDto);if (insert==0) {return Result.error("添加菜品失败");}//单独清除对应key的缓存String key="dish_"+dishDto.getCategoryId();clearCache(key);return Result.success();}/*** 批量删除菜品* @param ids* @return*/@Operation(summary = "批量删除菜品")@DeleteMappingpublic Result deleteDish(@RequestParam List<Long> ids) {int delete =  dishService.deleteBatch(ids);if (delete==0){return Result.error("删除失败");}//清理全部key以dish_开头缓存clearCache("dish_*");return Result.success();}@Operation(summary = "修改菜品")@PutMappingpublic  Result updateDishWithFlavor(@RequestBody DishDTO dishDto){log.info("修改菜品:"+dishDto.toString());int updateNum=dishService.updateDishWithFlavor(dishDto);if (updateNum==0){return Result.error("修改失败");}//清理全部key以dish_开头缓存clearCache("dish_*");return Result.success();}/*** 清理缓存* @param pattern*/private void clearCache(String pattern){//1、查询出要清理对应缓存的keys,keys方法的参数可以匹配一个通配符,如:dish_*Set<String> keys = redisTemplate.keys(pattern);//2、清理缓存(可以传入一个集合)redisTemplate.delete(keys);}
}

6、Spring Cache

Spring Cache是一个框架, 实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。

Spring Cache提供了一层抽象, 底层可以切换不同的缓存实现,例如:EHCache、Caffeine、Redis。

它会自动识别你所使用的缓存,只需要你导入对应缓存的jar包,如果你想使用Redis,做为缓存工具的话,你就导入Redis的jar包;如果你想使用EHCache作为缓存的话,你就导入 EHCache 的jar包。

<!--Spring Cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.7.3</version>
</dependency>
Spring Cache提供的注解说明
@EnableCaching开启缓存注解功能,通常加再启动类上面
@Cacheable通常加到方法上,在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,则调用方法并将方法返回值放到缓存中。
@CachePut加到方法上,将方法的放回值放到缓存中,只放不取
@CacheEvict将一条或多条数据从缓存中删除

具体的实现思路如下:

  1. 导入Spring Cache和Redis相关maven坐标。
  2. 在启动类上加入@EnableCaching注解, 开启缓存注解功能。
  3. 在用户端接口SetmealController的查询方法上加入@Cacheable注解。
  4. 在管理端接口Setmel控制器的保存、删除、更新、开始或停止等方法。上加入缓存事件注解。
6.1 @CachePut 注解

加到方法上,将方法的放回值放到缓存中,只放不取;使用步骤,及其注意事项

格式: @CachePut(cacheName="userCache",key="#user.id")

cacheName:就是Redis(或其他缓存工具)的key的前半部分,可以任意字符串,通常是:类名+Cache

key:就是Redis(或其他缓存工具)的key的后半部分,是动态的,这里使用的是Spring表达式来获取到对象的id属性,作为后半部分。#表示Spring表达式;user表示,形参里的user对象;id表示将数据添加到数据库后,返回到形参中user对象里id属性的值。

完整的key,中间由双冒号分隔如:userCache::1、userCache::2

  1. 在导入对应jar包后,在启动类上加上注解:@EnableCaching

    @SpringBootApplication
    @EnableCaching //开启缓存注解功能
    public class SkyServerApplication {public static void main(String[] args) {SpringApplication.run(SkyServerApplication.class, args);}
    }
    
  2. Mapper层

    @Mapper
    public interface UserMapper {@Insert("insert into user(name,sex,age) values(#{name},#{sex},#{age})")@Options(useGenteratedKeys=true,keyProperty="id")  //插入数据完成后将id返回到对象中void addUser(User user);
    }
    
  3. Service层不变,以前怎么写现在就怎么写

    @Service
    public UserServiceImpl implements UserService {@AutoWriteprivate UserMapper  userMapper;@Overridepublic User addUser(User user){userMapper.addUser(user); return;  }
    }
    
  4. Controller层

    将注解加入到Controller成的方法上

    @RestController
    @RequestMapping("/user")
    public class UserController {@Autowiredprivate UserService userService;/**
    cacheName:就是Redis(或其他缓存工具)的key的前半部分,可以任意字符串,通常是:类名+Cache
    key:就是Redis(或其他缓存工具)的key的后半部分,是动态的,这里使用的是Spring表达式来获取到对象的id属性,作为后半部分。#表示Spring表达式;user表示,形参里的user;id表示将数据添加到数据库后,返回到user对象里id属性的值。
    完整的key,中间由双冒号分隔如:userCache::1、userCache::2*/@PostMapping@CachePut(cacheName="userCache",key="#user.id")  //最常使用//@CachePut(cacheName="userCache",key="#result.id") //表示返回结果中的user对象的id//@CachePut(cacheName="userCache",key="#p0.id") //表示形参中的第一个参数中的id//@CachePut(cacheName="userCache",key="#a0.id") //表示形参中的第一个参数中的idpublic Result adduser(@RequesBody User user){userService.addUser(user)return Result.success(user);}}
    
6.2 @Cacheable注解

在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,则调用方法并将方法返回值放到缓存中。

格式: @CachePut(cacheName="userCache",key="#id") ,key的值要根据形参来变化,保证与存储的key所对应。

  1. Controller层
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping// //如果有缓存就获取对应key的缓存,如果没有就执行方法,获取数据库数据存入缓存@Cacheable(cacheName="userCache",key="id")  //生成的key如:userCache::2public Result getUserById(Long id){User user= userService.getUserById(id)return Result.success(user);}}
6.3 @CacheEvict注解

将一条或多条数据从缓存中删除

  1. Controller层

    @RestController
    @RequestMapping("/user")
    public class UserController {@Autowiredprivate UserService userService;/**删除指定key的缓存数据*/@DeleteMapping// 将对应key的缓存进行清除@CacheEvict(cacheName="userCache",key="id")  //生成的key如:userCache::2public Result deleteUserById(Long id){User user= userService.deleteUserById(id)return Result.success();}/**以某某key开头的全部缓存数据,这里是以:userCache开头的全部数据*/@DeleteMapping@CacheEvict(cacheName="userCache",allEntries=true)  //生成的key如:userCache::*public Result deleteAllUser(){User user= userService.deleteAllUser()return Result.success();}}
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/449998.html

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

相关文章

unity 屏幕波动反馈打击效果(附资源下载)

unity 屏幕波动反馈打击效果 一枪打出去整个屏幕都回波动的效果反馈。 知识点&#xff1a; 1、动画事件 2、屏幕后处理 效果如图&#xff1a;&#xff08;波动速度浮动都可调整&#xff09; 附件下载

Java 枚举类

枚举类型 在Java编程语言中&#xff0c;枚举类&#xff08;Enum Class&#xff09;是一种特殊的类&#xff0c;它用于表示一组固定的常量。这些常量通常用于定义变量的合法取值&#xff0c;比如一周的天数、交通信号灯的颜色等。枚举类提供了一种类型安全的方式来使用这些常量&…

CasADi库C++用法整理学习---以NMPC代码为例

参考几个使用方法博客 1 官方文档写的很清楚 对SM&#xff0c;DM&#xff0c;XM数据类型疑惑。什么时候使用什么样的类型&#xff0c;还是都可以&#xff1f; x MX.sym(“x”) 这将创建一个 11 矩阵&#xff0c;即一个包含名为 x 的符号基元的标量。这只是显示名称&#xff…

基于Java的免税商品优选购物商城设计与实现代码(论文+源码)_kaic

目 录 摘 要 Abstract 第一章 绪论 1.1 课题开发的背景 1.2 课题研究的意义 1.3 研究内容 第二章 系统开发关键技术 2.1 JAVA技术 2.2 MyEclipse开发环境 2.3 Tomcat服务器 2.4 Spring Boot框架 2.5 MySQL数据库 第三章 系统分析 3.1 系统可行性研究…

ClickHouse的原理及使用,

1、前言 一款MPP查询分析型数据库——ClickHouse。它是一个开源的&#xff0c;面向列的分析数据库&#xff0c;由Yandex为OLAP和大数据用例创建。ClickHouse对实时查询处理的支持使其适用于需要亚秒级分析结果的应用程序。ClickHouse的查询语言是SQL的一种方言&#xff0c;它支…

01数组算法/代码随想录

一、数组 好久没写算法题&#xff0c;之前喜欢按着习惯选择刷题&#xff0c;很早以前就听说代码随想录&#xff0c;今天跟着代码随想录再过一遍算法 1.1二分查找 常见疑问 middle一定是在[left, right]这个范围内标准代码不会越界&#xff0c;因为在else if中出现越界后&…

【windows个性化】在 Windows 10/11 上使 Windows 任务栏半透明/透明

实现目的&#xff1a;在 Windows 10/11 上使 Windows 任务栏半透明/透明. TranslucentTB plugin 描述 只需几 MB 内存&#xff0c;几乎不占用 CPU&#xff0c;便可以在 Windows 10/11 上使 Windows 任务栏半透明/透明的轻量小工具 功能 高级颜色选择器(color picker)&…

X(twitter)推特广告类型有哪些?如何选择?

X&#xff08;twitter&#xff09;推特是全球最热门的几大社交媒体平台之一&#xff0c;也是很多电商卖家进行宣传推广工作的阵地之一。在营销过程中不可避免地需要借助平台广告&#xff0c;因此了解其广告类型和适配场景也十分重要。 一、广告类型及选择 1.轮播广告 可滑动的…

JavaScript的100个概念

JavaScript对初学者来说既是福音&#xff0c;也是挑战。一方面&#xff0c;掌握它后可以构建各种项目&#xff0c;比如网站、应用程序和服务器&#xff0c;还能在很多行业找到工作。但另一方面&#xff0c;它又充满怪异之处&#xff0c;并被各种复杂的库和框架包围。在这段课程…

FLUX LoRA模型揭秘:COMFYUI中的AI绘画新动力!

嗨&#xff0c;艺术爱好者们&#xff01;今天我们要揭开一个神秘的面纱——FLUX LoRA模型&#xff0c;这个模型就像是一个神奇的魔法师&#xff0c;将COMFYUI中的AI绘画提升到了一个新的高度&#xff01; 想象一下&#xff0c;你有一个AI助手&#xff0c;它能够理解你的绘画梦…

【Redis】Zset类型常用命令

文章目录 一. Zset有序集合简介.二. 添加元素相关命令.2.1 向有序集合中添加元素(zadd) 三. 查询元素相关操作.3.1 查询有序集合中的元素个数( zcard zcount)3.2 查询指定区间内的元素(zrange zrevrange zrangebyscore)3.3 查询有序集合中指定成员的排名(zrank zrevrank )3.4 查…

钴粉Co纳米微球100nm|CoNP/CoN2-C催化剂

钴粉Co纳米微球100nm|CoNP/CoN2-C催化剂 钴粉Co纳米微球100nm是一种具有独特物理和化学性质的纳米材料&#xff0c;因其高比表面积、优良的磁性和化学稳定性&#xff0c;在多个领域展现出广阔的应用前景。以下是关于钴粉Co纳米微球100nm的相关信息&#xff1a; 性质 高比表面…

ubuntu20.04安装gerrit

1、update 2、updategrale 一&#xff1a;安装前准备 配置管理gerrit的专属账号&#xff1a;(本次测试安装我用的ROOT) sudo adduser gerrit sudo usermod -a -G sudo gerrit //分配sudo 权限 sudo su gerrit java、git环境&#xff1a; sudo apt-get update sudo apt-g…

群晖前面加了雷池WAF,安装失败,然后无法识别出用户真实访问IP

有nas的相信对公网都不模式&#xff0c;在现在基础上传带宽能有100兆的时代&#xff0c;有公网代表着家里有一个小服务器&#xff0c;像百度网盘&#xff0c;优酷这种在线服务都能部署为私有化服务。但现在运营商几乎不可能提供公网ip&#xff0c;要么自己买个云服务器做内网穿…

多jdk版本环境下,jenkins系统设置需指定JAVA_HOME环境变量

一、背景 由于不同项目对jdk版本的要求不同&#xff0c;有些是要求jdk11&#xff0c;有些只需要jdk8即可。 而linux机器上安装jdk的方式又多种多样&#xff0c;最后导致jenkins打包到底使用的是哪个jdk&#xff0c;比较混乱。 1、java在哪 > whereis java java: /usr/bin/…

测试人生 | 双非院校,2年工作经验年薪近20万

本人本科毕业于双非院校&#xff0c;大学毕业之后就开始从事软件测试工作&#xff0c;有两年多的工作经验&#xff0c;工作当中学习的测试技能较少&#xff0c;比较多重复的工作内容&#xff0c;主要对软件进行功能测试、简单的接口测试及专项测试&#xff0c;自学的测试知识零…

【STL】模拟实现list

目录 list需要实现的接口 结点类的创建 迭代器类的实现 构造函数 运算符的重载 --运算符的重载 !运算符重载和运算符重载 operator* operator-> list的模拟实现 构造函数 拷贝构造函数 赋值运算符重载函数 析构函数 迭代器相关函数 begin和end front和back …

【超详细】TCP协议

TCP(Transmission Control Protocol 传输控制协议) 传输层协议有连接可靠传输面向字节流 为什么TCP是传输控制协议呢&#xff1f; 我们以前所看到的write接口&#xff0c;都是把用户级缓冲区的数据拷贝到发送缓冲区中&#xff0c;然后数据就由TCP自主决定了&#xff0c;所以…

crashrpt3 开源项目的Vs 2022 C++20及其以上的编译

1. 首先从github 下载源代码 crashrpt3 2. 用CMake Gui 编译成vs studio 工程文件 2.1 点击 config 按钮 2.2 依次点击 Generate 按钮、Open Project 按钮.之后vs 2022 会打开编译好的sln工程文件 3.全选解决方案里面的所有项目,设置C语言标准,我这里设置是最新C,即启用的是…

【文档智能】文本文字识别、公式识别、表格文字识别核心算法及思路及实践-DBNet、CRNN、TrOCR

前言 OCR技术作为文档智能解析链路中的核心组件之一&#xff0c;贯穿整个技术链路&#xff0c;包括&#xff1a;文字识别、表格文字识别、公式识别&#xff0c;参看下面这张架构图&#xff1a; 前期介绍了很多关于文档智能解析相关核心技术及思路&#xff0c;本着连载的目的&a…