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

谷粒商城【成神路】-【10】——缓存

目录

🧂1.引入缓存的优势

🥓2.哪些数据适合放入缓存 

🌭3.使用redis作为缓存组件 

🍿4.redis存在的问题 

🧈5.添加本地锁 

🥞6.添加分布式锁

🥚7.整合redisson作为分布式锁


🚗🚗🚗1.引入缓存的优势

为了系统性能的提升,我们一般都会将部分数据放入缓存中,加速访问。而db承担数据落盘工作。

🚗🚗🚗2.哪些数据适合放入缓存 

  • 即时性、数据—致性要求不高的
  • 访问量大且更新频率不高的数据(读多,写少)

🚗🚗🚗3.使用redis作为缓存组件 

先确保reidis正常启动

3.1配置redis

  • 1.引入依赖
        <!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
  • 2.配置reids信息
springredis:port: 6379host: ip地址password: XXX

3.2优化查询 

之前都是从数据库查询的,现在加入缓存逻辑~

 /*** 使用redis缓存*/@Overridepublic Map<String, List<Catalog2Vo>> getCatalogJson() {//1.加入缓存,缓存中存的数据全都是jsonString catalogJson = redisTemplate.opsForValue().get("catalogJson");if (StringUtils.isEmpty(catalogJson)) {//2.缓存中如果没有,再去数据库查找Map<String, List<Catalog2Vo>> catalogJsonFromDB = getCatalogJsonFromDB();//3.将数据库查到的数据,将对象转换为json存放到缓存String s = JSON.toJSONString(catalogJsonFromDB);redisTemplate.opsForValue().set("catalogJson", s);}//4.从缓存中获取,转换为我们指定的类型Map<String, List<Catalog2Vo>> result = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catalog2Vo>>>() {});return result;}/*** 从数据库查询并封装的分类数据** @return*/public Map<String, List<Catalog2Vo>> getCatalogJsonFromDB() {/*** 优化:将数据库查询的多次变为一次*/List<CategoryEntity> selectList = baseMapper.selectList(null);//1.查出所有1级分类List<CategoryEntity> leve1Categorys = getParent_cid(selectList, 0L);//2.封装数据Map<String, List<Catalog2Vo>> parentCid = leve1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {//1.每一个一级分类List<CategoryEntity> categoryEntities = getParent_cid(selectList, v.getCatId());List<Catalog2Vo> catalog2Vos = null;if (categoryEntities != null) {catalog2Vos = categoryEntities.stream().map(l2 -> {Catalog2Vo vo = new Catalog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName());//找二级分类的三级分类List<CategoryEntity> categoryEntities3 = getParent_cid(selectList, l2.getCatId());if (categoryEntities3 != null) {List<Catalog2Vo.Catalog3Vo> collect = categoryEntities3.stream().map(l3 -> {Catalog2Vo.Catalog3Vo catalog3Vo = new Catalog2Vo.Catalog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());return catalog3Vo;}).collect(Collectors.toList());vo.setCatalog3List(collect);}return vo;}).collect(Collectors.toList());}return catalog2Vos;}));return parentCid;}

3.3测试 

在本地第一次查询后,查看redis,发现redis已经存储

使用JMeter压测一下

🚗🚗🚗4.redis存在的问题 

4.1缓存穿透

  • 缓存穿透:  查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是数据库也无此记录,我们没有将这次查询的null写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义
  • 解决方案:null结果缓存,并加入短暂过期时间

4.2缓存雪崩 

  • 缓存雪崩: 在我们设置缓存时key采用了相同的过期时间,导致缓存在某一时刻同时失效,大量请求全部转发到DB, DB瞬时压力过重雪崩。
  • 解决方案:原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

4.3缓存击穿 

缓存击穿 :对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。如果这个key在大量请求同时进来前正好失效,那么所有对这个key的数据查询都落到db,我们称为缓存击穿。

解决方案:枷锁    大量并发只让一个去查,其他人等待,查到以后释放锁,其他人获取到锁,先查缓存,就会有数据,不用去db

🚗🚗🚗5.添加本地锁 

若在缓存redis中没有查到,也去数据库查询,在查询数据库时,添加本地锁,在查之前,再次判断缓存reids中是否有数据,如果有,直接返回,如果没有,在查数据库,在查完数据库后,由于延迟原因,我们查完数据库时,将数据存放到缓存中,然后在释放锁

/*** 使用redis缓存*/@Overridepublic Map<String, List<Catalog2Vo>> getCatalogJson() {//1.使用redis缓存,存储为json对象String catalogJson = redisTemplate.opsForValue().get("catalogJson");//2.判断缓存中是否有if (StringUtils.isEmpty(catalogJson)) {System.out.println("缓存没有命中~查询数据库...");//3.如果缓存中没有,从数据库Map<String, List<Catalog2Vo>> catalogJsonFromDB = getCatalogJsonFromDB();return catalogJsonFromDB;}System.out.println("缓存命中....直接返回");//5.如果缓存中有,转换为我们需要的类型Map<String, List<Catalog2Vo>> result = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catalog2Vo>>>() {});return result;}/*** 从数据库查询并封装的分类数据** @return*/public Map<String, List<Catalog2Vo>> getCatalogJsonFromDB() {/*** 优化:将数据库查询的多次变为一次*///TODO 本地锁,在分布式下,必须使用分布式锁//加锁,防止缓存击穿,使用同一把锁synchronized (this) {//加所以后,我们还要去缓存中确定一次,如果缓存中没有,才继续查数据库String catalogJson = redisTemplate.opsForValue().get("catalogJson");if (!StringUtils.isEmpty(catalogJson)) {//如果缓存中有,从缓存中获取Map<String, List<Catalog2Vo>> result = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catalog2Vo>>>() {});return result;}System.out.println("查询了数据库~");List<CategoryEntity> selectList = baseMapper.selectList(null);//1.查出所有1级分类List<CategoryEntity> leve1Categorys = getParent_cid(selectList, 0L);//2.封装数据Map<String, List<Catalog2Vo>> parentCid = leve1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {//1.每一个一级分类List<CategoryEntity> categoryEntities = getParent_cid(selectList, v.getCatId());List<Catalog2Vo> catalog2Vos = null;if (categoryEntities != null) {catalog2Vos = categoryEntities.stream().map(l2 -> {Catalog2Vo vo = new Catalog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName());//找二级分类的三级分类List<CategoryEntity> categoryEntities3 = getParent_cid(selectList, l2.getCatId());if (categoryEntities3 != null) {List<Catalog2Vo.Catalog3Vo> collect = categoryEntities3.stream().map(l3 -> {Catalog2Vo.Catalog3Vo catalog3Vo = new Catalog2Vo.Catalog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());return catalog3Vo;}).collect(Collectors.toList());vo.setCatalog3List(collect);}return vo;}).collect(Collectors.toList());}return catalog2Vos;}));//4.将从数据库中获取的数据,转换为Json存储到redisString s = JSON.toJSONString(parentCid);//设置缓存时间,方式雪崩redisTemplate.opsForValue().set("catalogJson", s, 1, TimeUnit.DAYS);return parentCid;}}

🚗🚗🚗6.添加分布式锁

使用分布式锁 步骤

  • 1.先去redis中设置一个key,为了保持原子性,同时设置过期时间
  • 2.判断是否设置成功,成功则继续业务操作,失败则自选再次获取
  • 3.执行业务之后,需要删除key释放锁,为了保持原子性,使用lua脚本
 /*** 使用redis缓存*/@Overridepublic Map<String, List<Catalog2Vo>> getCatalogJson() {//1.使用redis缓存,存储为json对象String catalogJson = redisTemplate.opsForValue().get("catalogJson");//2.判断缓存中是否有if (StringUtils.isEmpty(catalogJson)) {System.out.println("缓存没有命中~查询数据库...");//3.如果缓存中没有,从数据库Map<String, List<Catalog2Vo>> catalogJsonFromDB = getCatalogJsonFromDBWithRedisLock();return catalogJsonFromDB;}System.out.println("缓存命中....直接返回");//5.如果缓存中有,转换为我们需要的类型Map<String, List<Catalog2Vo>> result = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catalog2Vo>>>() {});return result;}/*** 从数据库中获取数据,使用分布所锁** @return*/public Map<String, List<Catalog2Vo>> getCatalogJsonFromDBWithRedisLock() {//1.占分布式锁,去redis占位String uuid = UUID.randomUUID().toString();//2.设置过期时间,必须和加锁同步Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);if (lock) {System.out.println("获取分布式锁成功..." + redisTemplate.opsForValue().get("lock"));//加锁成功...执行业务Map<String, List<Catalog2Vo>> dataFromDb;try {dataFromDb = getDataFromDb();} finally {String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";//删除锁,原子性Long lock1 = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList("lock"), uuid);}return getDataFromDb();} else {//加锁失败...重试//休眠100毫秒try {Thread.sleep(2000);} catch (InterruptedException e) {}return getCatalogJsonFromDBWithRedisLock();//自旋方式}}/*** 提起方法,从数据库中获取** @return*/private Map<String, List<Catalog2Vo>> getDataFromDb() {//加所以后,我们还要去缓存中确定一次,如果缓存中没有,才继续查数据库String catalogJson = redisTemplate.opsForValue().get("catalogJson");if (!StringUtils.isEmpty(catalogJson)) {//如果缓存中有,从缓存中获取Map<String, List<Catalog2Vo>> result = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catalog2Vo>>>() {});return result;}System.out.println("查询了数据库~");List<CategoryEntity> selectList = baseMapper.selectList(null);//1.查出所有1级分类List<CategoryEntity> leve1Categorys = getParent_cid(selectList, 0L);//2.封装数据Map<String, List<Catalog2Vo>> parentCid = leve1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {//1.每一个一级分类List<CategoryEntity> categoryEntities = getParent_cid(selectList, v.getCatId());List<Catalog2Vo> catalog2Vos = null;if (categoryEntities != null) {catalog2Vos = categoryEntities.stream().map(l2 -> {Catalog2Vo vo = new Catalog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName());//找二级分类的三级分类List<CategoryEntity> categoryEntities3 = getParent_cid(selectList, l2.getCatId());if (categoryEntities3 != null) {List<Catalog2Vo.Catalog3Vo> collect = categoryEntities3.stream().map(l3 -> {Catalog2Vo.Catalog3Vo catalog3Vo = new Catalog2Vo.Catalog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());return catalog3Vo;}).collect(Collectors.toList());vo.setCatalog3List(collect);}return vo;}).collect(Collectors.toList());}return catalog2Vos;}));//4.将从数据库中获取的数据,转换为Json存储到redisString s = JSON.toJSONString(parentCid);//设置缓存时间,方式雪崩redisTemplate.opsForValue().set("catalogJson", s, 1, TimeUnit.DAYS);return parentCid;}

🚗🚗🚗7.整合redisson作为分布式锁

7.1引入依赖

       <!--redisson作为所有分布式锁--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.12.0</version></dependency>

7.2程序化配置

在配置地址时,一定要添加reds://

@Configuration
public class MyRedissonConfig {@Bean(destroyMethod = "shutdown")public RedissonClient redissonClient() throws IOException {//1.创建配置Config config = new Config();config.useSingleServer().setAddress("redis://192.168.20.130:6379");//2.根据config创建redisson实例RedissonClient redissonClient = Redisson.create(config);return redissonClient;}
}

7.3实例解析

  • 1.锁的自动续期,如果业务超长,运行期间自动给锁续上新的30秒,不用担心业务超长,所自动过期被删除掉
  • 2.加锁的业务只要运行完成,就不会给当前锁续期,即使不手动解锁,锁默认在30秒后自动删除
 @AutowiredRedissonClient redissonClient;@ResponseBody@GetMapping("/hello")public String hello() {//1.设置redis的key获取一把锁,只要名字相同,就是同一把锁RLock lock = redissonClient.getLock("my-lock");//2.手动枷锁lock.lock();//阻塞式等待,默认30秒try {//3.执行业务System.out.println("枷锁成功!" + Thread.currentThread().getName());//4.模拟业务消耗时间Thread.sleep(20000);} catch (Exception e) {} finally {//3.释放锁System.out.println("释放锁~"+Thread.currentThread().getName());lock.unlock();//不删除,默认30秒后过期,自动删除}return "hello";}
  • 3.如果我们传递了锁的超时时间,就发送给redis执行脚本,进行占锁,默认超时就是我们指定的时间
  • 4.如果未指定锁的超时时间,就使用30*1000【LockWatchingTimeOut看门狗默认时间】 
    • 只要占锁成功,就会启动一个定时任务【重新给锁设置过期时间,新的过期时间就是看门狗的默认时间】,每隔(【LockWatchingTimeOut看门狗默认时间】/3)折磨长时间自动续期;

7.4读写锁 

  • 1.保证一定能读到最新数据,修改期间,写锁是一个排他锁,读锁是一个共享锁
  • 2.读+读:相当于并发,在redis中记录好,都会读取成功
  • 3.写+读:等待写锁释放
  • 4.写+写:阻塞方式
  • 5.读+写:有读锁,写也需要等待
 @GetMapping("/write")@ResponseBodypublic String write() {RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWrite-lock");String word = "";RLock rLock = readWriteLock.writeLock();try {//该数据加写锁,读数据加读锁rLock.lock();word = UUID.randomUUID().toString();Thread.sleep(3000);redisTemplate.opsForValue().set("writeValue", word);} catch (InterruptedException e) {e.printStackTrace();} finally {rLock.unlock();}return word;}/*** 读写锁* @return*/@GetMapping("/read")@ResponseBodypublic String read() {String word = "";RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWrite-lock");//加读锁RLock rLock = readWriteLock.readLock();rLock.lock();try {word = redisTemplate.opsForValue().get("writeValue");} catch (Exception e) {e.printStackTrace();}finally {rLock.unlock();}return word;}

相关文章:

谷粒商城【成神路】-【10】——缓存

目录 &#x1f9c2;1.引入缓存的优势 &#x1f953;2.哪些数据适合放入缓存 &#x1f32d;3.使用redis作为缓存组件 &#x1f37f;4.redis存在的问题 &#x1f9c8;5.添加本地锁 &#x1f95e;6.添加分布式锁 &#x1f95a;7.整合redisson作为分布式锁 &#x1f697…...

Facebook、亚马逊账号如何养号?

之前我们讨论过很多关于代理器的问题。它们的工作原理是什么?在不同的软件中要使用那些代理服务器?这些代理服务器之间的区别是什么?什么是反检测浏览器等等。 除了这些问题&#xff0c;相信很多人也会关心在使用不同平台的时代理器的选择问题。比如&#xff0c;为什么最好…...

Milvus的相似度指标

官网&#xff1a;https://milvus.io/docs/metric.md版本: v2.3.x 在 Milvus 中&#xff0c;相似度度量用于衡量向量之间的相似度。选择良好的距离度量有助于显着提高分类和聚类性能。下表展示了这些广泛使用的相似性指标如何与各种输入数据形式和 Milvus 索引相匹配。 一、浮…...

如何在unity中实现倒计时

public class showtime : MonoBehaviour {public TextMeshProUGUI Countdown;void Update(){if (Input.GetKeyDown(KeyCode.Space))//如果按下空格后开始倒计时{StartCoroutine(hahaha());}}IEnumerator hahaha()//声明了一个协程函数 hahaha{int time 10;Countdown.text tim…...

蓝桥杯简单题,公司名称

题目链接&#xff08;需要登录&#xff09; #include <iostream> #include <cstring> #include <algorithm> using namespace std; bool lanqiao(string str,int len){ sort(str.begin(),str.end());//对str按照ascii排序if(str.find("Laainoq")s…...

【linux】02 :Linux基础命令

1.掌握linux系统的目录结构 linux只有一个顶级目录&#xff0c;称之为&#xff1a;根目录。 windows系统有多个顶级目录&#xff0c;即各个盘符。 2.linux路径的描述方式 /在Linux中的表示&#xff1a;出现在开头表示根目录&#xff0c;出现在后面表示层级关系。 3.什么是命…...

AOP切面编程,以及自定义注解实现切面

AOP切面编程 通知类型表达式重用表达式切面优先级使用注解开发&#xff0c;加上注解实现某些功能 简介 动态代理分为JDK动态代理和cglib动态代理当目标类有接口的情况使用JDK动态代理和cglib动态代理&#xff0c;没有接口时只能使用cglib动态代理JDK动态代理动态生成的代理类…...

C70600 CuNi10Fe1Mn铜合金深冲性能好

C70600 CuNi10Fe1Mn铜合金深冲性能好CW608N-R460、CW608N-H135、CuZn36Pb2As-R370、CuZn38Pb1-R460、CW607N-H120、CuZn38Pb1-H120、CW602N-H080、CW608N-H105、CuZn39Pb0.5-R460、CuZn39Pb0.5-H120、CW608N-H120、CuZn38Pb1-R470、CW607N-H080、CW607N-R470、CW607N-H105、CuZ…...

算法学习05:离散化、区间合并

算法学习05&#xff1a;离散化、区间合并 文章目录 算法学习05&#xff1a;离散化、区间合并前言需要记忆的模版&#xff1a;一、离散化1.例题&#xff1a;离散化 区间和&#xff1a;拓展: 二、区间合并&#xff08;贪心&#xff09;1.例题&#xff1a; 总结 前言 需要记忆的模…...

内部审计2.0时代:数字化工具和方法全面升级

文章目录 一、内部审计的发展阶段二、内部审计的逻辑架构三、内部审计数字化转型面临的问题&#xff08;1&#xff09;缺少内部审计数字化转型规划和方案&#xff08;2&#xff09;非结构化数据的采集和后续利用不足&#xff08;3&#xff09;依赖编程或使用新工具的数据分析能…...

五子棋小游戏(sut实验报告)

实验目的 实现人与人或人与电脑进行五子棋对弈 实验内容 启动游戏&#xff0c;显示游戏参数设置界面&#xff0c;用户输入参数后进入游戏界面&#xff0c;显示棋盘及双方博弈过程&#xff0c;游戏过程中可选择退出游戏。判定一方获胜后结束本局游戏&#xff0c;可选择继续下…...

图像超分辨率算法ESRGAN原理及应用

前言 图像超分辨率算法是一种用于增加图像分辨率的算法,与传统的图像缩放算法不同的是,超分算法在放大图像的同时根据原图纹理生成更多细节,确保图像在放大后仍然有清晰的纹理细节。 一、模型简介 1、模型开源地址 GitHub - xinntao/ESRGAN: ECCV18 Workshops - Enhance…...

excel 动态列导出

excel动态列&#xff0c;只好用poi来写了&#xff0c;也并不复杂&#xff0c;一样就这个件事情抽像为几步&#xff0c;就是套路了&#xff0c;开发效率就上去了。 1 准备空模板 导出操作与excel模板的导出一样&#xff0c;可以参考excel导出标准化 2 自定义SheetWriteHandler …...

Java零基础入门到精通_Day 1

01 Java 语言发展史 Java语言是美国Sun公司(StanfordUniversity Network)在1995年推出的 计算机语言Java之父:詹姆斯高斯林(ames Gosling) 重要的版本过度&#xff1a; 2004年 Java 5.0 2014年 Java 8.0 2018年 9月 Java 11.0 &#xff08;目前所使用的&#xff09; 02 J…...

Spring Cloud集成nacos配置中心

1.添加Nacos Config依赖 打开nacos-config-demo的pom.xml文件并添加以下两个依赖项 项目的配置文件中通常包括数据库连接配置项、日志输出配置项、Redis连接配置项、服务注册配置项等内容&#xff0c;如spring-cloud-alibaba-nacos-config-base-demo项目中就包含数据库连接配置…...

【AI视频教程】只需5步,AI作出鸡你太美视频

1.视频效果 2.准备工作 制作视频效果&#xff0c;需要准备下面3个条件&#xff1a; 准备stable diffusion的环境剪辑一段【鸡你太美】原版视频stable diffusion安装sd-webui-IS-NET-pro插件 2.1部署stable diffusion环境 这里还是建议大家用云平台部署stable diffusion&am…...

C# OpenCvSharp DNN FreeYOLO 密集行人检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN FreeYOLO 密集行人检测 效果 模型信息 Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Float[1, 3, 192, 320] --------------------------------------------------------------- …...

一次HW红初面试

一、描述外网打点的流程&#xff1f; 靶标确认、信息收集、漏洞探测、漏洞利用、权限获取。最终的目的是获取靶标的系统权限/关键数据。 在这个过程中&#xff0c;信息收集最为重要。掌握靶标情报越多&#xff0c;后续就会有更多的攻击方式去打点。比如&#xff1a;钓鱼邮件、…...

网络攻防中nginx安全配置,让木马上传后不能执行、让木马执行后看不到非网站目录文件、命令执行后权限不能过高

网络攻防中nginx安全配置,让木马上传后不能执行、让木马执行后看不到非网站目录文件、命令执行后权限不能过高。 0x01 Nginx介绍 nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发…...

ctfshow web入门 php特性 web146-web150

1.web146 :被过滤了&#xff0c;三元运算符用不了&#xff0c;还可以用位运算符&#xff0c;逻辑运算符,等&#xff0c;逻辑运算符要注意或运算符的短路性 eval(return 1|phpinfo()|1) eval(return 1phpinfo()|1) payload&#xff1a; v11&v20&v3(~%8C%86%8C%8B%9A%92…...

基于Redis Sorted Set与前缀匹配的智能搜索组件实战

1. Redis Sorted Set为何适合智能搜索场景 Redis的Sorted Set&#xff08;有序集合&#xff09;是构建智能搜索组件的绝佳选择&#xff0c;这源于它独特的分数排序和范围查询能力。每个存储在Sorted Set中的元素都会关联一个分数&#xff08;score&#xff09;&#xff0c;系统…...

别再让CPU冒烟了!手把手教你用FFmpeg + NVIDIA显卡搞定H265转H264硬件加速

释放NVIDIA显卡潜能&#xff1a;FFmpeg硬件加速实现H265到H264的高效转码指南 1. 为什么需要硬件加速转码&#xff1f; 视频转码是许多应用场景中的核心需求&#xff0c;无论是流媒体服务、安防监控还是视频编辑&#xff0c;都需要将视频从一种编码格式转换为另一种。然而&…...

自动螺丝供料技术:自动送钉系统的核心功能解析

新能源汽车三电系统、车灯等高节拍装配这类高端制造场景里&#xff0c;人工螺丝供料一直有不少问题&#xff1a;效率低&#xff0c;容易漏装错装&#xff0c;生产节拍也稳不住。人工上料环节能占到装配工位总耗时的25%以上&#xff0c;错装率最高能到1.2%&#xff0c;直接拖慢量…...

ICCV-2025 | 同济上海AILab VLN-PE:多模态感知与物理仿真融合的具身导航新范式

1. 当机器人学会"看图说话"&#xff1a;VLN-PE如何重新定义导航 想象一下&#xff0c;你正指挥一台人形机器人在陌生大楼里找会议室。传统导航系统可能需要精确的坐标输入&#xff0c;而VLN-PE让机器人能像人类一样&#xff0c;通过"往前走20米&#xff0c;在第…...

3分钟掌握Markdown浏览器插件:让技术文档阅读变得简单高效

3分钟掌握Markdown浏览器插件&#xff1a;让技术文档阅读变得简单高效 【免费下载链接】markdown-viewer Markdown Viewer / Browser Extension 项目地址: https://gitcode.com/gh_mirrors/ma/markdown-viewer 还在为浏览器中打开Markdown文件显示原始代码而烦恼吗&…...

【C++原创开源】formort.h:一行头文件,实现比JS模板字符串更爽的链式拼接+响应式变量

文章目录一、先看效果&#xff1a;比JS模板字符串更爽的写法二、核心功能&#xff1a;不止是拼接&#xff0c;还有响应式1. 任意类型|链式拼接2. Cast响应式变量绑定三、核心实现&#xff1a;几十行代码&#xff0c;看懂原理四、使用方法&#xff1a;零门槛&#xff0c;直接上手…...

RWKV7-1.5B-g1a开源可部署价值:企业私有化部署,数据不出内网安全合规保障

RWKV7-1.5B-g1a开源可部署价值&#xff1a;企业私有化部署&#xff0c;数据不出内网安全合规保障 1. 模型概述 rwkv7-1.5B-g1a是基于新一代RWKV-7架构的多语言文本生成模型&#xff0c;专为企业级应用场景优化设计。该模型在1.5B参数规模下实现了优异的性能表现&#xff0c;特…...

【2026奇点智能技术大会权威指南】:LLM生产部署的7大避坑红线与3套已验证SLO达标方案

第一章&#xff1a;2026奇点智能技术大会&#xff1a;LLM生产环境部署指南 2026奇点智能技术大会(https://ml-summit.org) 在真实业务场景中&#xff0c;将大语言模型&#xff08;LLM&#xff09;从实验环境迁移至高可用、低延迟、可审计的生产环境&#xff0c;需系统性权衡推…...

QQ空间历史说说备份终极指南:一键永久保存你的青春记忆

QQ空间历史说说备份终极指南&#xff1a;一键永久保存你的青春记忆 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾试图找回多年前的QQ空间说说&#xff0c;却发现那些承载青春…...

使用 HTML + JavaScript 实现组织架构图

文章目录一、组织架构图二、效果演示三、系统分析1.页面结构1.1 操作区域1.2 组织结构图区域2 核心功能实现2.1 数据结构定义2.2 节点渲染逻辑2.3节点展开/收起功能2.4 全部展开/收起四、扩展建议五、完整代码一、组织架构图 在企业管理系统或团队协作平台中&#xff0c;组织结…...