天机学堂3-ES+Caffeine
文章目录
- day05-问答系统
- 表
- 用户端分页查询问题
- 目标效果
- 代码实现
- 3.6.管理端分页查询问题
- ES相关
- 管理端互动问题分页实现
- 三级分类
- 3.6.5.2.多级缓存
- 3.6.5.3.Caffeine
- TODO:使用Caffeine作为本地缓存,另外使用redis或者memcache作为分布式缓存,构造多级缓存体系
- 4.评论相关接口
- 目标效果
- 新增回答或评论
day05-问答系统
效果:

表
互动提问的问题表:
CREATE TABLE IF NOT EXISTS `interaction_question` (`id` bigint NOT NULL COMMENT '主键,互动问题的id',`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '互动问题的标题',`description` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '问题描述信息',`course_id` bigint NOT NULL COMMENT '所属课程id',`chapter_id` bigint NOT NULL COMMENT '所属课程章id',`section_id` bigint NOT NULL COMMENT '所属课程节id',`user_id` bigint NOT NULL COMMENT '提问学员id',`latest_answer_id` bigint DEFAULT NULL COMMENT '最新的一个回答的id',`answer_times` int unsigned NOT NULL DEFAULT '0' COMMENT '问题下的回答数量',`anonymity` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否匿名,默认false',`hidden` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否被隐藏,默认false',`status` tinyint DEFAULT '0' COMMENT '管理端问题状态:0-未查看,1-已查看',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '提问时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`) USING BTREE,KEY `idx_course_id` (`course_id`) USING BTREE,KEY `section_id` (`section_id`),KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='互动提问的问题表';
回答或评论表:
CREATE TABLE IF NOT EXISTS `interaction_reply` (`id` bigint NOT NULL COMMENT '互动问题的回答id',`question_id` bigint NOT NULL COMMENT '互动问题问题id',`answer_id` bigint DEFAULT '0' COMMENT '回复的上级回答id',`user_id` bigint NOT NULL COMMENT '回答者id',`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '回答内容',`target_user_id` bigint DEFAULT '0' COMMENT '回复的目标用户id',`target_reply_id` bigint DEFAULT '0' COMMENT '回复的目标回复id',`reply_times` int NOT NULL DEFAULT '0' COMMENT '评论数量',`liked_times` int NOT NULL DEFAULT '0' COMMENT '点赞数量',`hidden` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否被隐藏,默认false',`anonymity` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否匿名,默认false',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`) USING BTREE,KEY `idx_question_id` (`question_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='互动问题的回答或评论';
KEY 关键字用于定义索引,而 USING BTREE 是一个可选的子句,用于显式指定索引的存储类型。如果不指定 USING BTREE,MySQL 会默认使用 B-Tree 索引结构
用户端分页查询问题
目标效果

代码实现

3.6.管理端分页查询问题
ES相关
Feign接口
package com.tianji.api.client.search;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;import java.util.List;@FeignClient("search-service")
public interface SearchClient {@GetMapping("/courses/name")List<Long> queryCoursesIdByName(@RequestParam(value = "keyword", required = false) String keyword);
}
Controller:
package com.tianji.search.controller;import com.tianji.common.domain.dto.PageDTO;
import com.tianji.search.domain.query.CoursePageQuery;
import com.tianji.search.domain.vo.CourseVO;
import com.tianji.search.service.ICourseService;
import com.tianji.search.service.ISearchService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;@RestController
@RequestMapping("courses")
@Api(tags = "课程搜索接口")
@RequiredArgsConstructor
public class CourseController {private final ISearchService searchService;private final ICourseService courseService;@ApiOperation("用户端课程搜索接口")@GetMapping("/portal")public PageDTO<CourseVO> queryCoursesForPortal(CoursePageQuery query){return searchService.queryCoursesForPortal(query);}@ApiIgnore@GetMapping("/name")public List<Long> queryCoursesIdByName(@RequestParam("keyword") String keyword){return searchService.queryCoursesIdByName(keyword);}

管理端互动问题分页实现
管理端互动问题分页: Admin可以通过关键字搜索课程,但由于问题表中没有课程名称字段,所以通过
课程ID获取课程名字,课程ID可以从Feign获取
QuestionAdminPageQuery.getCourseName是课程名称的关键字
课程ID可以从Feign获取:接受课程关键字,搜ES
public PageDTO<QuestionAdminVO> getInterationQuestionByAdminPage(QuestionAdminPageQuery pageQuery) {// 如果用户传了课程名称参数,则从es中获取该名称对应的课程idList<Long> courseIdList = null;if (StringUtils.isNotBlank(pageQuery.getCourseName())) {// feign远程调用,从es中获取该名称对应的课程idcourseIdList = searchClient.queryCoursesIdByName(pageQuery.getCourseName());// 判断查询结果是否为空if (CollUtil.isEmpty(courseIdList)) {return PageDTO.empty(0L, 0L);}}// 查询互动问题表Page<InteractionQuestion> questionPage = lambdaQuery().eq(pageQuery.getStatus() != null, InteractionQuestion::getStatus, pageQuery.getStatus()).ge(pageQuery.getBeginTime() != null, InteractionQuestion::getCreateTime, pageQuery.getBeginTime()).le(pageQuery.getEndTime() != null, InteractionQuestion::getCreateTime, pageQuery.getEndTime()).in(!CollUtil.isEmpty(courseIdList), InteractionQuestion::getCourseId, courseIdList) // 实现课程名称模糊查询.page(pageQuery.toMpPageDefaultSortByCreateTimeDesc());// 查询到的列表为空,则返回空集List<InteractionQuestion> records = questionPage.getRecords();if (CollUtil.isEmpty(records)) {return PageDTO.of(questionPage, Collections.emptyList());}// 这里用for循环而不是Stream流,减少循环次数Set<Long> userIds = new HashSet<>();Set<Long> courseIds = new HashSet<>();Set<Long> chapterAndSections = new HashSet<>();for (InteractionQuestion question : records) {userIds.add(question.getUserId());courseIds.add(question.getCourseId());chapterAndSections.add(question.getChapterId());chapterAndSections.add(question.getSectionId());}// feign远程调用用户服务,获取用户信息List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);if (CollUtil.isEmpty(userDTOS)) {throw new BizIllegalException("用户不存在");}Map<Long, UserDTO> userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, userDTO -> userDTO));// feign远程调用课程服务,获取课程信息List<CourseSimpleInfoDTO> courseDTOs = courseClient.getSimpleInfoList(courseIds);if (CollUtil.isEmpty(courseDTOs)) {throw new BizIllegalException("课程不存在");}Map<Long, CourseSimpleInfoDTO> courseMap = courseDTOs.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, courseDTO -> courseDTO));// feign远程调用课程服务,获取章节信息List<CataSimpleInfoDTO> catalogueDTOs = catalogueClient.batchQueryCatalogue(chapterAndSections);if (CollUtil.isEmpty(catalogueDTOs)) {throw new BizIllegalException("章节不存在");}// 封装为章节id,章节名称(需要根据章节id赋值章节名称)Map<Long, String> catalogueMap = catalogueDTOs.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));// 封装VO并返回List<QuestionAdminVO> voList = new ArrayList<>();for (InteractionQuestion record : records) {QuestionAdminVO questionAdminVO = BeanUtils.copyBean(record, QuestionAdminVO.class);UserDTO userDTO = userMap.get(record.getUserId());if (userDTO != null) {questionAdminVO.setUserName(userDTO.getName()); // 用户昵称}CourseSimpleInfoDTO courseDTO = courseMap.get(record.getCourseId());if (courseDTO != null) {questionAdminVO.setCourseName(courseDTO.getName()); // 课程名称// 获取课程的三级分类id,根据三级分类id拼接分类名称String categoryName = categoryCache.getCategoryNames(courseDTO.getCategoryIds());questionAdminVO.setCategoryName(categoryName); // 课程所述分类名称}// 使用getOrDefault防止异常questionAdminVO.setChapterName(catalogueMap.getOrDefault(record.getChapterId(), "")); // 章节名称questionAdminVO.setSectionName(catalogueMap.getOrDefault(record.getSectionId(), "")); // 小节名称voList.add(questionAdminVO);}return PageDTO.of(questionPage, voList);}
三级分类

表里设置parent_id代表上级是谁

都是IT-互联网下面的二级分类(红框里的)
因为分类信息的改动量比较小,一般都不会动了,所以就缓存起来
- 课程分类数据在很多业务中都需要查询,这样的数据如此频繁的查询,有没有性能优化的办法呢?
3.6.5.2.多级缓存
相信很多同学都能想到借助于Redis缓存来提高性能,减少数据库压力。非常好!不过,Redis虽然能提高性能,但每次查询缓存还是会增加网络带宽消耗,也会存在网络延迟。
而分类数据具备两大特点:
- 数据量小
- 长时间不会发生变化。
像这样的数据,除了建立Redis缓存以外,还非常适合做本地缓存(Local Cache)。这样就可以形成多级缓存机制:
- 数据查询时优先查询本地缓存
- 本地缓存不存在,再查询Redis缓存
- Redis不存在,再去查询数据库。
本地缓存简单来说就是JVM内存的缓存,比如你建立一个HashMap,把数据库查询的数据存入进去。以后优先从这个HashMap查询,一个本地缓存就建立好了。
本地缓存由于无需网络查询,速度非常快。不过由于上述缺点,本地缓存往往适用于数据量小、更新不频繁的数据。而课程分类恰好符合。
3.6.5.3.Caffeine
当然,我们真正创建本地缓存的时候并不是直接使用HashMap之类的集合,因为维护起来不太方便。而且内存淘汰机制实现起来也比较麻烦。
所以,我们会使用成熟的框架来完成,比如Caffeine:
Caffeine是一个基于Java8开发的,提供了近乎最佳命中率的高性能的本地缓存库。目前Spring内部的缓存使用的就是Caffeine。


第二次get就不会执行了
Caffeine提供了三种缓存驱逐策略:
- 基于容量:设置缓存的数量上限
// 创建缓存对象
Cache<String, String> cache = Caffeine.newBuilder().maximumSize(1) // 设置缓存大小上限为 1.build();
- 基于时间:设置缓存的有效时间
// 创建缓存对象
Cache<String, String> cache = Caffeine.newBuilder()// 设置缓存有效期为 10 秒,从最后一次写入开始计时 .expireAfterWrite(Duration.ofSeconds(10)) .build();
Caffeine.newBuilder().initialCapacity(1) // 初始容量 缓存初始化时会分配足够的内存来存储1个键值对。.maximumSize(10_000) // 最大容量 缓存最多可以存储10,000个键值对。.expireAfterWrite(Duration.ofMinutes(30)) // 指定了缓存项在写入后多长时间过期。Duration.ofMinutes(30)是一个静态方法,用于创建一个表示30分钟的时间持续对象.build();
和上面明星例子一样,如果缓存没有则远程调用获取放到缓存中 下次30分钟查 直接返回【一级分类id、二级分类id、三级分类id】:
public Map<Long, CategoryBasicDTO> getCategoryMap() {return categoryCaches.get("CATEGORY", key -> {// 1.从CategoryClient查询List<CategoryBasicDTO> list = categoryClient.getAllOfOneLevel();if (list == null || list.isEmpty()) {return CollUtils.emptyMap();}return list.stream().collect(Collectors.toMap(CategoryBasicDTO::getId, Function.identity()));});
}
拼接三级分类名称,用/分隔:
/*** 根据三级分类id拼接三级分类名称* @param ids 一级分类id、二级分类id、三级分类id* @return 拼接三级分类名称,用/分隔*/public String getCategoryNames(List<Long> ids) {if (ids == null || ids.size() == 0) {return "";}// 1.读取分类缓存Map<Long, CategoryBasicDTO> map = getCategoryMap();// 2.根据id查询分类名称并组装StringBuilder sb = new StringBuilder();for (Long id : ids) {sb.append(map.get(id).getName()).append("/");}// 3.返回结果return sb.deleteCharAt(sb.length() - 1).toString();}
调用:
questionAdminVO.setCourseName(courseDTO.getName()); // 课程名称
// 获取课程的三级分类id,根据三级分类id拼接分类名称
String categoryName = categoryCache.getCategoryNames(courseDTO.getCategoryIds());
questionAdminVO.setCategoryName(categoryName); // 课程所述分类名称
SpringBoot的自动加载机制启动缓存生效这一系列流程:

Feign客户端的实现类是由Feign在运行时动态生成的,你不需要手动编写实现类。只要你的项目配置正确,Feign会自动处理接口的实现,并通过HTTP请求调用远程服务。

TODO:使用Caffeine作为本地缓存,另外使用redis或者memcache作为分布式缓存,构造多级缓存体系

4.评论相关接口
目标效果
回答
评论是 回答下面的

新增回答或评论

@Data
@ApiModel(description = "互动回答信息")
public class ReplyDTO {@ApiModelProperty("回答内容")@NotNull(message = "回答内容不能为空")private String content;@ApiModelProperty("是否匿名提问")private Boolean anonymity;@ApiModelProperty("互动问题id")@NotNull(message = "问题id不能为空")private Long questionId;// 该字段为null,表示是回答;否则表示评论@ApiModelProperty("回复的上级回答id,没有可不填")private Long answerId;@ApiModelProperty("回复的目标回复id,没有可不填")private Long targetReplyId;@ApiModelProperty("回复的目标用户id,没有可不填")private Long targetUserId;@ApiModelProperty("标记是否是学生提交的回答,默认true")private Boolean isStudent = true;
}
@Transactional
public void addReply(ReplyDTO replyDTO) {// 拷贝实体InteractionReply reply = BeanUtil.toBean(replyDTO, InteractionReply.class);if (reply.getAnswerId() == null) { // 当前是回答的话,不需要target_user_id字段reply.setTargetUserId(null);}// 获取当前登录用户Long userId = UserContext.getUser();reply.setUserId(userId);// 保存评论或回答this.save(reply);// 查询关联的问题InteractionQuestion question = questionMapper.selectById(reply.getQuestionId());if (question == null) {throw new BizIllegalException("参数异常");}// 根据answerId是否为null判断是回答还是评论,如果是需要在`interaction_question`中记录最新一次回答的idif (reply.getAnswerId() == null) { // answerId为null表示当前是回答question.setLatestAnswerId(reply.getId()); // 更新问题的最新回答idquestion.setAnswerTimes(question.getAnswerTimes() + 1); // 该问题的回答数量+1} else { // 如果是评论// 获取评论关联的回答InteractionReply interactionReply = this.getById(reply.getAnswerId());interactionReply.setReplyTimes(interactionReply.getReplyTimes() + 1); // 该回答的评论数量+1// 更新评论关联的回答this.updateById(interactionReply);}// 如果是学生提交,则需要更新问题状态为未查看if (replyDTO.getIsStudent()) {question.setStatus(QuestionStatus.UN_CHECK);}// 更新问题questionMapper.updateById(question);// 发送MQ消息,新增积分rabbitMqHelper.send(MqConstants.Exchange.LEARNING_EXCHANGE,MqConstants.Key.WRITE_REPLY,SignInMessage.of(userId,5)); // 一个问题+5积分}

相关文章:
天机学堂3-ES+Caffeine
文章目录 day05-问答系统表 用户端分页查询问题目标效果代码实现 3.6.管理端分页查询问题ES相关 管理端互动问题分页实现三级分类3.6.5.2.多级缓存3.6.5.3.CaffeineTODO:使用Caffeine作为本地缓存,另外使用redis或者memcache作为分布式缓存,构…...
FPGA车牌识别
基于FPGA的车牌识别主要包含以下几个步骤:图像采集、颜色空间转换、边缘检测、形态学处理(腐蚀和膨胀)、特征值提取、模板匹配、结果显示。先用matlab对原理进行仿真,后用vivado和modelsim进行设计和仿真。 一、1.图像采集采用ov…...
Pandas库的常用内容归纳
Pandas 是一个强大的 Python 数据分析库,提供了大量用于数据处理和分析的功能。以下是一些 Pandas 库中常用的功能: 数据创建和操作 Series 和 DataFrame:创建一维的 Series 和二维的 DataFrame 对象。数据导入:从 CSV、Excel、…...
R语言的并发编程
R语言的并发编程 引言 在现代计算中,如何有效地利用计算资源进行数据处理和分析已成为一个重要的研究方向。尤其在大数据时代,数据量的急剧增加让单线程处理方式显得力不从心。为了解决这一问题,各种编程语言都开展了并发编程的研究和应用。…...
STM32 FreeRTOS中断管理
目录 FreeRTOS的中断管理 1、STM32中断优先级管理 2、FreeRTOS任务优先级管理 3、寄存器和内存映射寄存器 4、BASEPRI寄存器 5、FreeRTOS与STM32中断管理结合使用 vPortRaiseBASEPRI vPortSetBASEPRI 6、FromISR后缀 7、在中断服务函数中调用FreeRTOS的API函数需注意 F…...
数据结构-栈和队列
文章目录 一、栈1.概念与结构2.数组栈的实现2.1 栈的结构定义2.2 栈的初始化2.3 栈的销毁2.4 栈的判空2.5 栈的入栈2.6 栈的出栈2.7 查看栈顶元素2.8 栈的大小 3.两种栈的图示结构 二、队列1.概念与结构2.链式队列的实现2.1 队列的结构定义2.2 队列的初始化2.3 队列的销毁2.4 队…...
RabbitMQ---TTL与死信
(一)TTL 1.TTL概念 TTL又叫过期时间 RabbitMQ可以对队列和消息设置TTL,当消息到达过期时间还没有被消费时就会自动删除 注:这里我们说的对队列设置TTL,是对队列上的消息设置TTL并不是对队列本身,不是说队列过期时间…...
第4章 Kafka核心API——Kafka客户端操作
Kafka客户端操作 一. 客户端操作1. AdminClient API 一. 客户端操作 1. AdminClient API...
Python爬虫学习前传 —— Python从安装到学会一站式服务
早上好啊,大佬们。我们的python基础内容的这一篇终于写好了,啪唧啪唧啪唧…… 说实话,这一篇确实写了很久,一方面是在忙其他几个专栏的内容,再加上生活学业上的事儿,确实精力有限,另一方面&…...
Lora理解QLoRA
Parameter-Efficient Fine-Tuning (PEFT) :节约开销的做法,fine-tune少量参数,而不是整个模型; Low-Rank Adaptation (LoRA) :是PEFT的一种;冻结原参数矩阵,只更新2个小参数矩阵。 原文经过对比…...
Linux测试处理fps为30、1920*1080、一分钟的视频性能
前置条件 模拟fps为30、1920*1080、一分钟的视频 项目CMakeLists.txt cmake_minimum_required(VERSION 3.30) project(testOpenGl)set(CMAKE_CXX_STANDARD 11)add_executable(testOpenGl main.cpptestOpenCl.cpptestOpenCl.hTestCpp.cppTestCpp.hTestCppThread.cppTestCppTh…...
Flink (六):DataStream API (三) 窗口
1. 窗口 窗口(Window)是处理无界流的关键所在。窗口可以将数据流装入大小有限的“桶”中,再对每个“桶”加以处理。 下面展示了 Flink 窗口在 keyed streams 和 non-keyed streams 上使用的基本结构。 我们可以看到,这两者唯一的…...
MYSQL学习笔记(二):基本的SELECT语句使用(基本、条件、聚合函数查询)
前言: 学习和使用数据库可以说是程序员必须具备能力,这里将更新关于MYSQL的使用讲解,大概应该会更新30篇,涵盖入门、进阶、高级(一些原理分析);这一篇是讲解SELECT语句使用,包括基本、条件、聚合函数查询,…...
PCL 点到面的ICP算法实现点云配准(C++详细过程版)
ICP算法 一、算法原理1、算法概述2、实现流程3、参考文献二、代码实现三、结果展示四、相关链接一、算法原理 1、算法概述 实现的算法与 PCL 点到面的ICP精配准(线性最小二乘优化)一文相同,使用C++代码复现线性优化的求解过程,求解过程如下所示,由于原版英文文献的计算过…...
MarsCode青训营打卡Day1(2025年1月14日)|稀土掘金-16.最大矩形面积问题
资源引用: 最大矩形面积问题 - MarsCode 打卡小记录: 今天是开营第一天,和小伙伴们组成了8人的团队,在接下来的数十天里相互监督,打卡刷题! 稀土掘金-16.最大矩形面积问题(16.最大矩形面积问题…...
我的世界-与门、或门、非门等基本门电路实现
一、红石比较器 (1) 红石比较器结构 红石比较器有前端单火把、后端双火把以及两个侧端 其中后端和侧端是输入信号,前端是输出信号 (2) 红石比较器的两种模式 比较模式 前端火把未点亮时处于比较模式 侧端>后端 → 0 当任一侧端强度大于后端强度时,输出…...
【FISCO BCOS】二十三、部署WeBASE-Node-Manager
WeBASE-Node-Manager是WeBASE的子组件之一,可以处理前端页面所有web请求,管理各个节点的状态,管理链上所有智能合约,对区块链的数据进行统计、分析,对异常交易的审计,私钥管理等,今天我们来部署WeBASE-Node-Manager。 环境:ubuntu 22 、已搭建单机四节点(节点已启动)…...
app版本控制java后端接口版本管理
java api version 版本控制 java接口版本管理 1 自定义 AppVersionHandleMapping 自定义AppVersionHandleMapping实现RequestMappingHandlerMapping里面的方法 public class AppVersionHandleMapping extends RequestMappingHandlerMapping {Overrideprotected RequestCondit…...
Go语言strings包与字符串操作:从基础到高级的全面解析
Go语言strings包与字符串操作:从基础到高级的全面解析 引言 Go语言以其简洁、高效和强大的标准库而闻名,其中strings包是处理字符串操作的核心工具。本文将深入探讨Go语言中strings包的功能及其在实际开发中的应用,帮助开发者更好地理解和使用这一工具。 1. strings包概述…...
使用redis-cli命令实现redis crud操作
项目场景: 线上环境上redis中的key影响数据展示,需要删除。但环境特殊没办法通过 redis客户端工具直连。只能使用redis-cli命令来实现。 操作步骤: 1、确定redis安装的服务器; 2、找到redis的安装目录下 ##找到redis安装目…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
