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

openfeign 拦截器实现微服务上下文打通

目录

  • openfeign 拦截器实现微服务上下文打通
    • 需求分析:
    • 代码实现:
      • subject 服务:
        • controller
        • Feign 拦截器:
          • 将 Feign 拦截器注册为一个Bean:
      • auth 鉴权服务:
        • 全局配置类:
        • 登录拦截器:
        • 上下文对象:
    • 测试:
      • subject 服务的拦截器:
      • auth 服务的前置拦截:
      • 上下文对象:
      • 成功实现远程调用时,携带 loginId
    • 备注:
      • auth 对外提供的 feign 远程调用接口

openfeign 拦截器实现微服务上下文打通

需求分析:

subject 服务 通过 openfeign 调用 auth 鉴权服务 :subject 服务接收到前端发来的请求,这个请求需要远程调用 auth 鉴权服务,所以我们需要发送一个 feign 请求 进行远程调用 auth 鉴权服务的某一个接口:
期间需要携带 loginId(用户唯一标识id)思路:subject 服务:
1、需要在 subject 服务中 定义一个 feign 拦截器,把当前请求中携带的 loginId ,放入到 Feign 请求中,用来传递给下游服务auth 鉴权服务:2、auth 鉴权服务 定义一个 LoginInterceptor 拦截器,在执行 preHandle 前置拦截时,将 loginId 存放到 LoginContextHolder 这个自定义的登录上下文对象中。
3、这个 LoginContextHolder 登录上下文对象,主要通过 ThreadLocal 来实现,为每个线程存储数据。
4、在原有的 GlobalConfig (spring mvc 的全局处理 -- 消息转换器)中,重写 addInterceptors 方法,拦截每一个请求,让所有请求都进入到 LoginInterceptor 登录拦截器里面

代码实现:

subject 服务:

controller

首先写一个简单的测试 controller ,这个方法会进行远程调用 auth 服务

在这里插入图片描述

Feign 拦截器:

作用:在当前服务使用 Feign 发送请求时,自动将前端传来的 loginId 添加到 Feign 请求的 header 中,实现用户身份的“透传”

在这里插入图片描述


/*** Feign 请求拦截器: 把当前请求中的 loginId 自动加入 Feign 的请求头,实现跨服务身份传递** 在微服务中,用户请求经过多个服务(A 调 B,再调 C),每一层都需要知道当前用户是谁(loginId),所以需要透传这个字段** @author lujinhong* @since 2025-05-14*/@Component
public class FeignRequestInterceptor implements RequestInterceptor {/*** 在当前服务使用 Feign 发送请求时,自动将前端传来的 loginId 添加到 Feign 请求的 header 中,实现用户身份的“透传”*/@Overridepublic void apply(RequestTemplate requestTemplate) {// 从当前线程上下文中拿到原始的 HTTP 请求(比如前端请求当前服务时的请求)ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = requestAttributes.getRequest();if (Objects.nonNull(request)) {// 获取请求头中的 loginId。String loginId = request.getHeader(SubjectConstants.LOGIN_ID);if (StringUtils.isNotBlank(loginId)) {// 将这个 loginId 放入 Feign 请求的 header 中,传递给下游服务requestTemplate.header(SubjectConstants.LOGIN_ID, loginId);}}}
}
将 Feign 拦截器注册为一个Bean:

在这里插入图片描述

/*** 将自定义的 FeignRequestInterceptor 注册为 Spring Bean,使其在 Feign 请求中生效** 让自定义的 Feign 拦截器真正生效,自动为每次 Feign 调用加上想加的 header,比如 loginId** @author lujinhong* @since 2025-05-14*/
//声明一个配置类,用于配置 Feign 相关内容
@Configuration
public class FeignConfiguration {/*** 将 FeignRequestInterceptor 注册为一个 Bean*/@Beanpublic RequestInterceptor requestInterceptor() {return new FeignRequestInterceptor();}}

auth 鉴权服务:

全局配置类:

在这里配置这个 addInterceptors 添加拦截器的方法,让每个请求都进入到 LoginInterceptor 拦截器里面

在这里插入图片描述


/*** spring mvc 的全局处理 -- 消息转换器** @author lujinhong* @since 2025-01-09* <p>* WebMvcConfigurationSupport 提供了一些默认的 Spring MVC 配置方法,包括消息转换器、视图解析器、拦截器等。* 通过继承这个类,可以修改默认配置,来满足项目特定的需求*///@Configuration 用于标注一个类为配置类
@Configuration
public class GlobalConfig extends WebMvcConfigurationSupport {/*** 该是一个用于配置消息转换器的方法,消息转换器用于将请求的 JSON 或 XML 数据转换为 Java 对象,或者将 Java 对象转换为 JSON 或 XML 数据*/@Overrideprotected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {/** super 关键字用于访问当前类的父类(超类)成员(字段、方法或构造器)* 重写父类的这个方法,仍然推荐再调用父类的这个configureMessageConverters方法,是为了保留继承和扩展父类未来可能增加的任何配置的潜力,即使现在这个父类的这个方法是空的。*/super.configureMessageConverters(converters);//在原有的消息转换器列表基础上,添加自定义的 MappingJackson2HttpMessageConverter。该转换器的作用是处理 JSON 数据,将其与 Java 对象进行相互转换converters.add(mappingJackson2HttpMessageConverter());}/*** 这是 Spring MVC 中重写 WebMvcConfigurer 的方法,用来注册拦截器。** addInterceptor(...):在拦截器链路中 添加自己写的 LoginInterceptor 拦截器。* addPathPatterns("/**"):给 LoginInterceptor 这个拦截器设置拦截规则 --> 拦截所有路径,/** 表示所有接口(包括子路径)。* 每次请求进入 Controller 之前,都会先执行 LoginInterceptor 中的 preHandle() 方法。*/@Overrideprotected void addInterceptors(InterceptorRegistry registry) {// /** 拦截所有请求,每个请求都需要进入到 LoginInterceptor 这个自定义拦截器中registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**");}/*** 自定义 mappingJackson2HttpMessageConverter,用于配置 JSON 数据的处理方式* 作用:空值忽略,空字段可返回* 空值忽略:指的是如果字段的值是 null,该字段不会出现在 JSON 中。* 空字段返回:比如一些空的list集合,虽然也没值,但是会被序列化后返回一个{} ,该list集合类型的字段依然会在 JSON 输出中出现*/private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {//ObjectMapper 是 Jackson 序列化和反序列化 JSON 数据的核心类ObjectMapper objectMapper = new ObjectMapper();//作用:在序列化一个 空的 Java 对象(即没有任何属性或字段的对象)时,不会抛出异常,而是直接返回一个空的 JSON 对象({})//适用于处理一些空的 Bean 对象,避免因空对象序列化失败而导致异常objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//这个配置会使得在序列化对象为 JSON 时,忽略值为 null 的字段。也就是说,如果某个字段的值是 null,它不会出现在最终的 JSON 输出中objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);return new MappingJackson2HttpMessageConverter(objectMapper);}
}
登录拦截器:

LoginInterceptor 登录拦截器:在前置拦截方法中进行处理,将 loginId 存到 当前线程的上下文对象中

在这里插入图片描述


/*** 自定义一个登录拦截器,用来拦截登录的header头信息** @author lujinhong* @since 2025/5/14  星期三*/
@Component
public class LoginInterceptor implements HandlerInterceptor {/*** 前置拦截器* 执行时机:在请求达到 controller 之前进行拦截处理,一般用于: 登录验证、权限校验、拦截*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取请求头的 loginIdString loginId = request.getHeader(AuthConstants.LOGIN_ID);// 把 loginId 存放到上下文里面,然后上下文类LoginContextHolder,就会把loginId 放到 ThreadLocal 里面,保证各线程的 loginId 互相不被其他线程干扰影响。LoginContextHolder.set("loginId", loginId);return true;}/*** 后置拦截器:Controller 执行完毕,但视图还未渲染时执行,就是数据还没有返回给前端* 一般用于:添加模型数据、封装响应,在数据查询出来还没有返回给前端之前,我们还可以添加一些数据或者做一些操作*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 暂时用不到,做下解释HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}/*** 请求完全结束后处理:一般用于:记录日志、异常处理、清资源*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 移除此线程局部变量的值,这里就是移除掉 loginIdLoginContextHolder.remove();}
}
上下文对象:

在这里插入图片描述

package cn.ljh.auth.application.context;import cn.ljh.auth.application.constants.AuthConstants;import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;/*** 登录的上下文对象* <p>* ThreadLocal解释:* ThreadLocal是java.lang下面的一个类,是用来解决java多线程程序中并发问题的一种途径;* 通过为每一个线程创建一份共享变量的【副本】来保证各个线程之间的变量的访问和修改互相不影响;* <p>* ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递。* <p>* 比如 共享变量num=10 , A线程拿到num,改成100;B线程拿到num,改成200,然后A线程打印num,依然是100,线程之间是互斥的* <p>* 线程内共享:比如A线程有多个方法:方法1,方法2;方法3,:方法1把num改成100,方法2把num改成200,然后方法方法3打印num=200* <p>* 存储位置:每个线程在执行时,都有一个独立的线程局部存储空间,这个空间是用于存储该线程的线程局部变量(即 ThreadLocal 的副本)的** @author lujinhong* @since 2025/5/14  星期三*/public class LoginContextHolder {// 只对当前线程有效,子线程无法访问,线程池更不行。// private static final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<>();// 只适合临时新建的子线程,缺点:线程池中的线程是复用的,容易导致数据泄露private static final InheritableThreadLocal<Map<String, Object>> THREAD_LOCAL = new InheritableThreadLocal<>();// 线程池场景专用: 作用:比如num=10,A线程拿到num=10,B线程拿到num后改成15,当线程切换回A线程时,A线程持有的num依然是10// 实际项目用的一定是这个TransmittableThreadLocal,不过视频演示先用InheritableThreadLocal了解一下// private static final TransmittableThreadLocal<Map<String,Object>> transmitThreadLocal = new TransmittableThreadLocal<>();/*** 将此线程局部变量的当前线程副本中的值设置为指定值。(就是会将当前线程的 ThreadLocal 变量副本的值设置为你传入的指定值)* 当前线程副本中的值是存储在“局部变量”中的,不过这个局部变量是线程局部的,即它只属于当前线程,并且由 ThreadLocal 管理,而不是普通的局部变量* 许多应用程序不需要这项功能,它们只依赖于initialValue()方法来设置线程局部变量的值*/public static void set(String key, Object value) {Map<String, Object> map = getThreadLocalMap();// concurrenthashmap 的value不能为nullif (value != null) {map.put(key, value);}}/*** 返回此线程局部变量的当前线程副本中的值。如果这是线程第一次调用该方法,则创建并初始化此福副本。*/public static Object get(String key) {Map<String, Object> map = getThreadLocalMap();Object object = map.get(key);return object;}/*** 获取当前线程的局部变量的值,做判断*/public static Map<String, Object> getThreadLocalMap() {// get() : 返回此线程局部变量的当前线程副本中的值。如果这是线程第一次调用该方法,则创建并初始化此副本。Map<String, Object> map = THREAD_LOCAL.get();if (Objects.isNull(map)) {// 保证线程安全map = new ConcurrentHashMap<>();THREAD_LOCAL.set(map);}return map;}/*** 移除此线程局部变量的值*/public static void remove() {THREAD_LOCAL.remove();}/*** 获取当前线程的loginId*/public static String getLoginId() {String loginId = (String) getThreadLocalMap().get(AuthConstants.LOGIN_ID);return loginId;}}

测试:

subject 服务的拦截器:

先走 subject 服务的拦截器,把请求的 loginId 塞到 feign 请求的 请求头中

在这里插入图片描述

auth 服务的前置拦截:

来到 auth 服务的登录拦截器的 前置拦截

在这里插入图片描述

上下文对象:

正常将数据存到上下文对象中

在这里插入图片描述

成功实现远程调用时,携带 loginId

最后成功实现远程调用,把数据从 auth 服务中查询出来了

在这里插入图片描述

备注:

auth 对外提供的 feign 远程调用接口

在这里插入图片描述

相关文章:

openfeign 拦截器实现微服务上下文打通

目录 openfeign 拦截器实现微服务上下文打通需求分析&#xff1a;代码实现&#xff1a;subject 服务&#xff1a;controllerFeign 拦截器&#xff1a;将 Feign 拦截器注册为一个Bean&#xff1a; auth 鉴权服务&#xff1a;全局配置类&#xff1a;登录拦截器&#xff1a;上下文…...

【MySQL】变更缓冲区:作用、主要配置以及如何查看

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

TCP/IP-——C++编程详解

1. TCP/IP 编程基本概念 TCP&#xff08;传输控制协议&#xff09;&#xff1a;面向连接、可靠的传输层协议&#xff0c;保证数据顺序和完整性。IP&#xff08;网际协议&#xff09;&#xff1a;负责将数据包路由到目标地址。Socket&#xff08;套接字&#xff09;&#xff1a…...

微服务如何实现服务的高可用

背景&#xff1a;微服务分层需要考虑高可用和高并发的问题 微服务如何实现服务的高可用 先说结论&#xff1a;微服务实现高可用主要通过集群冗余故障自动转移来实现的具体可以从底下几种方案来实现。 “端”到“反向代理”的高可用“反向代理”到“站点应用”的高可用“站点…...

微服务调试问题总结

本地环境调试。 启动本地微服务&#xff0c;使用公共nacos配置。利用如apifox进行本地代码调试解决调试问题。除必要的业务微服务依赖包需要下载到本地。使用mvn clean install -DskipTests进行安装启动前选择好profile环境进行启动&#xff0c;启动前记得mvn clean清理项目。…...

egpo进行train_egpo训练时,keyvalueError:“replay_sequence_length“

def execution_plan(workers: WorkerSet, config: TrainerConfigDict) -> LocalIterator[dict]: if config.get(“prioritized_replay”): prio_args { “prioritized_replay_alpha”: config[“prioritized_replay_alpha”], “prioritized_replay_beta”: config[“prior…...

Hadoop的组成

&#xff08;一&#xff09;Hadoop的组成 对普通用户来说&#xff0c; Hadoop就是一个东西&#xff0c;一个整体&#xff0c;它能给我们提供无限的磁盘用来保存文件&#xff0c;可以使用提供强大的计算能力。 在Hadoop3.X中&#xff0c;hadoop一共有三个组成部分&#…...

Android锁

引言 &#x1f512; 在 Android 应用的开发过程中&#xff0c;随着业务需求的复杂度不断提升&#xff0c;多线程并发场景层出不穷。为了保证数据一致性与线程安全&#xff0c;锁&#xff08;Lock&#xff09;成为了不可或缺的工具。本篇博客将深入剖析 Android 中常用的锁机制…...

XD08M3232接近感应单片机的接近感应模块的工作原理

XD08M3232接近感应单片机的接近感应模块基于电容式感应原理&#xff0c;通过硬件电路与软件配置实现对物体接近的检测。以下是其工作原理的详细解析&#xff1a; 一、硬件架构与核心组件 1. 核心电路组成 接近感应模块由三大关键部分构成&#xff1a; 两个轨到轨运算放大器&…...

编程日志5.6

串的习题 1.2236. 判断根结点是否等于子结点之和 - 力扣(LeetCode) /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * Tr…...

量子计算实用化突破:从云端平台到国际竞合,开启算力革命新纪元

在硅谷某生物医药实验室&#xff0c;研究员艾米丽正盯着量子计算模拟界面露出微笑 —— 搭载中电信 "天衍" 量子计算云平台的 880 比特超导量子处理器&#xff0c;用 17 分钟完成了传统超算需 3 个月才能跑完的新型抗生素分子键合模拟。这个场景标志着量子计算正从 &…...

Made with Unity | 拓展“双点”宇宙版图

双点工作室&#xff08;Two Point Studios&#xff09;团队成立于2016年&#xff0c;其创立初衷是打造一个完美的游戏IP&#xff1a;构建一个既能持续吸引玩家&#xff0c;又具备足够扩展空间&#xff0c;同时经得起时间考验的虚拟世界。2018年&#xff0c;团队以《双点医院&am…...

3D 数据可视化系统是什么?具体应用在哪方面?

目录 一、3D 数据可视化系统的定义与内涵 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;核心要素 二、3D 数据可视化系统的优势 三、3D 数据可视化系统的应用领域 &#xff08;一&#xff09;城市规划与管理 &#xff08;二&#xff09;工业制造 &am…...

2025-5-14渗透测试:利用Printer Bug ,NTLMv2 Hash Relay(中继攻击),CVE-2019-1040漏洞复现

python3 printerbug.py test.com/test192.168.186.131 192.168.186.134 sudo python2 MultiRelay.py -t 192.168.186.132 -u ALLPrinter Bug 原理 PrinterBug&#xff08;CVE-2018-0886&#xff09;是Windows打印系统服务&#xff08;Spooler&#xff09;的一个设计缺陷&…...

OracleLinux7.9-ssh问题

有套rac环境&#xff0c;db1主机无法ssh db1和db1-priv&#xff0c;可以ssh登录 db2和db2-priv [rootdb1 ~]# ssh db1 ^C [rootdb1 ~]# ssh db2 Last login: Wed May 14 18:25:19 2025 from db2 [rootdb2 ~]# ssh db2 Last login: Wed May 14 18:25:35 2025 from db1 [rootdb2…...

《AI大模型应知应会100篇》第64篇:构建你的第一个大模型 Chatbot

第64篇&#xff1a;构建你的第一个大模型 Chatbot 手把手教你从零开始搭建一个基于大模型的聊天机器人 摘要 你是否想过&#xff0c;自己也能构建一个像 ChatGPT 一样能对话、能思考的聊天机器人&#xff08;Chatbot&#xff09;&#xff1f;别担心&#xff0c;这并不需要你是…...

鸿蒙OSUniApp 实现精美的用户登录和注册页面#三方框架 #Uniapp

UniApp 实现精美的用户登录和注册页面 前言 在开发鸿蒙APP时&#xff0c;登录注册页面作为用户与应用交互的第一道门槛&#xff0c;其体验与质量往往决定了用户的第一印象。去年我接手了一个电商小程序项目&#xff0c;产品经理特别强调要做一个既美观又实用的登录注册页面。…...

c#中equal方法与gethashcode方法之间有何关联?

文章目录 前言一、对hash运算的深入思考二、equal与gethashcode的关联三、 equal与gethashcode不同步的后果四、 规范的重写gethashcode 前言 大家有没有遇到过&#xff0c;当你重写了c#对象的equal方法之后&#xff0c;编译器会提示你对相应的gethashcode进行重写&#xff0c…...

查询公网IP地址的方法:查看自己是不是公网ip,附内网穿透外网域名访问方案

本地搭建服务并提供互联网连接时&#xff0c;较为传统的方法是使用公网IP地址。因此&#xff0c;如何查询本地自己是不是公网IP&#xff0c;是必须要掌握的一种技巧。当面对确实无公网IP时&#xff0c;则可以通过内网穿透方案&#xff0c;如nat123网络映射工具&#xff0c;将本…...

【轻松学 C:编程小白的大冒险】— 16 函数的定义与调用

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【轻松学 C&#xff1a;编程小白的大冒险…...

【Tools】CPU 分析

CPU 分析 Windows SDK 本指南提供了可用于调查影响评估指标的中央处理单元 (CPU) 相关问题的详细技术。 特定于评估的分析指南中的各个指标或问题部分确定了需要调查的常见问题。 本指南提供了可用于调查这些问题的技术和工具。 本指南中的技术使用 Windows Performance Too…...

进阶2_1:QT5多线程与定时器共生死

1、在widget.ui中使用 LCD Number控件 注意&#xff1a;若 LCD 控件不是多线程&#xff0c;LCD控件则会瞬间自增到最大的数值&#xff0c;如上图&#xff0c;说明两者都是多线程处理 2、实现方式 1、创建 LCD 控件并修改为 LCD1 2、创建任务类 mytask. h&#xff0c;对任务类…...

ECharts:数据可视化的强大引擎

在当今这个信息爆炸的时代&#xff0c;如何有效地展示和理解复杂的数据成为了每一个开发者和技术爱好者面临的挑战。Apache ECharts 作为一款基于 JavaScript 的开源可视化库&#xff0c;以其强大的功能、丰富的图表类型以及高度的可定制性&#xff0c;迅速成为了数据可视化领域…...

记录 QT 在liunx 下 QFileDialog 类调用问题 ()Linux下QFileDialog没反应)

1. 2025.05.14 踩坑记录 因为QT 在 liunx 文件系统不同导致的 Windows &#xff1a; QString filePath QFileDialog::getOpenFileName(nullptr, "选择文件", ".", "文本文件 (*.txt);所有文件 (*.*)"); 没问题 liunx 下 打不开&#xff…...

通用软件项目技术报告 - 导读III

现在,我们正式进入报告的第六个主要领域:6. 领域六:与第三方服务/API 集成 (含 LLM API)。 连接: 在现代软件开发中,很少有应用程序是完全孤立的。我们经常需要与各种外部的第三方服务或 API 进行集成,以利用它们提供的特定功能(如支付处理、地图服务、社交媒体登录、云…...

Kali Linux 桌面环境安装与配置指南

一、为什么选择 Kali Linux&#xff1f; Kali Linux 由 Offensive Security 维护&#xff0c;集成了数百种安全测试工具&#xff08;如 Metasploit、Nmap 和 Burp Suite&#xff09;&#xff0c;非常适合安全研究。但需要注意的是&#xff0c;Kali 默认以 root 用户运行&#…...

FFmpeg视频编码的完整操作指南

步骤如下&#xff1a; 安装和准备FFmpeg&#xff1a;确保包含所需编码器&#xff08;如libx264&#xff09;。基本命令行编码&#xff1a;使用ffmpeg命令进行转码&#xff0c;设置视频编码器、CRF、预设等。API编码流程&#xff08;针对开发者&#xff09;&#xff1a; a. 注册…...

【网络协议】TCP、HTTP、MQTT 和 WebSocket 对比

从协议本质、工作原理、特点、应用场景等方面详细对比 TCP、HTTP、MQTT 和 WebSocket。 1. TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09; 本质 协议类型&#xff1a;传输层协议&#xff08;OSI模型第4层&#xff09;。核心功能&#x…...

Leetcode数组day1

704 二分查找 注意点&#xff0c;左闭右闭 class Solution { public:int search(vector<int>& nums, int target) {//整数类型的动态数组的引用。int left0;int right nums.size()-1;while (left < right){int middle (rightleft)/2;if (nums[middle]>targ…...

leetcode2934. 最大化数组末位元素的最少操作次数-medium

1 题目&#xff1a;最大化数组末位元素的最少操作次数 官方标定难度&#xff1a;中 给你两个下标从 0 开始的整数数组 nums1 和 nums2 &#xff0c;这两个数组的长度都是 n 。 你可以执行一系列 操作&#xff08;可能不执行&#xff09;。 在每次操作中&#xff0c;你可以选…...

常见相机焦段的分类及其应用

相机焦段是指镜头的焦距范围&#xff0c;决定了拍摄时的视角、画面范围和透视效果。不同焦段适合不同的拍摄场景和主题&#xff0c;以下是常见焦段的分类及其应用&#xff1a; 一、焦段的核心概念 焦距&#xff1a;镜头光学中心到成像传感器的距离&#xff08;单位&#xff1a…...

FPGA在光谱相机中的核心作用

FPGA&#xff08;现场可编程门阵列&#xff09;作为光谱相机的核心控制与加速单元&#xff0c;通过硬件级并行处理能力和动态可编程特性&#xff0c;实现高速、高精度的光谱数据采集与处理。以下是其具体作用分类&#xff1a; 一、高速光电信号处理 ‌实时光谱复原‌ 通过硬…...

【证书与信任机制​】证书透明度(Certificate Transparency):如何防止恶意证书颁发?​​

证书透明度&#xff08;Certificate Transparency, CT&#xff09;的核心原理 证书透明度&#xff08;CT&#xff09;是一项由Google主导的开放标准&#xff0c;旨在通过公开记录所有SSL/TLS证书的颁发行为&#xff0c;防止恶意CA错误或故意颁发虚假证书。其核心机制如下&#…...

【RabbitMq C++】消息队列组件

RabbitMq 消息队列组件 1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C客户端库4. AMQP-CPP 库的简单使用4.1 使用4.1.1 TCP 模式4.1.2 扩展模式 4.2 常用类与接口介绍4.2.1 Channel4.3.2 ev 5. RabbitMQ样例编写5.1 发布消息5.2 订阅消息 1. RabbitMq介绍 RabbitMq - …...

基于SpringBoot+Vue的房屋租赁管理系统源码包(完整版)开发实战

基于SpringBootVue的房屋租赁管理系统源码包&#xff08;完整版&#xff09;开发实战 一、引言 随着城市化进程加速&#xff0c;房屋租赁市场规模持续扩大&#xff0c;传统管理方式已无法满足高效、精准的业务需求。本文基于SpringBootVue框架&#xff0c;设计并实现了一套完…...

《AI大模型应知应会100篇》第61篇:FastAPI搭建大模型API服务

第61篇&#xff1a;FastAPI搭建大模型API服务 摘要 随着大语言模型&#xff08;LLM&#xff09;在各行各业的广泛应用&#xff0c;构建一个高性能、可扩展的大模型 API 服务变得尤为重要。FastAPI 以其异步支持、类型安全、自动生成文档等优势&#xff0c;成为当前最流行的选择…...

Java 源码 HashMap源码分析

Java 源码 HashMap源码分析 1 初始容量 /*** The default initial capacity - MUST be a power of two.* 默认的初始容量&#xff0c;必须为2的幂*/static final int DEFAULT_INITIAL_CAPACITY 1 << 4; // aka 16容量表示哈希表中槽的数量&#xff08;即哈希数组的长度…...

requestAnimationFrame 与 requestIdleCallback 对比

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、背景与问题场景二、核心API对比分析三、选择 requestIdleCallback 的核心原因四、特殊场景处理建议五、最佳实践总结六、结论前言 看过埋点库 sunshine-track ,很多人疑惑为啥批量上报埋点信息的时候,用的是 request…...

【C/C++】自定义类型:结构体

文章目录 前言自定义类型&#xff1a;结构体1.结构体类型的声明1.1 结构体回顾1.1.1 结构的声明 1.1.2 结构体变量的创建和初始化1.2 结构的特殊声明1.3 结构的自引用 2.结构体内存对齐2.1 对⻬规则2.2 为什么存在内存对齐&#xff1f;2.3 修改默认对⻬数 3. 结构体传参4.结构体…...

视频编解码学习十二之Android疑点

一、android.view.SurfaceControl.setDisplaySurface的作用 android.view.SurfaceControl.setDisplaySurface 是 Android 系统中一个 native 层级别的 API&#xff0c;主要用于 设置某个物理显示屏&#xff08;Display&#xff09;的输出 Surface&#xff0c;属于 SurfaceFlin…...

web第三次课后作业--基于JDBC对mysql数据库的增删查改操作

一、工程搭建步骤 1.新建java项目&#xff0c;添加jdbc依赖 2.写java程序 3.添加mysql数据源&#xff0c;连接本地数据库 4.运行程序二、运行结果 三、代码 代码解析 加载数据驱动 try {Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundExceptio…...

fiftyone-数据库配置和config与app_config配置文件

一数据库配置&#xff1a;&#xff08;以本地为例&#xff09; fiftyone数据库信息存在配置文件中&#xff1a; 配置文件地址&#xff1a; ~/.fiftyone/config.json 这个配置文件的作用&#xff1a;存放数据库地址信息&#xff1b;&#xff08;如果不配置&#xff0c;fiftyon…...

Nginx的核心功能--正向代理、反向代理、缓存和Rewrite

Nginx作为高性能的Web服务器&#xff0c;其核心功能主要体现在以下四大模块&#xff1a; 一、正向代理 主要用于客户端访问外部网络的中转服务。典型配置示例&#xff1a; server {listen 8080;resolver 8.8.8.8;location / {proxy_pass http://$http_host$request_uri;prox…...

mac latex vscode 配置

mac latex vscode 配置 安装mactex.pkg 这里有个快速下载的镜像 https://mirrors.aliyun.com/CTAN/systems/mac/mactex/ 可以检查是否将 PATH 写入 export PATH"/Library/TeX/texbin:$PATH"vscode 下载插件 Latex Workshop 在配置文件 settings.json 中输入如下的…...

【GESP真题解析】第 4 集 GESP一级 2023 年 3 月编程题 1:每月天数

大家好&#xff0c;我是莫小特。 这篇文章给大家分享 GESP 一级 2023 年 3 月编程题第 1 题&#xff1a;每月天数。 题目链接 洛谷链接&#xff1a;B3835 每月天数 一、完成输入 根据题目要求&#xff0c;我们需要输入两个整数&#xff0c;分别表示一个日期的年份和月份。 年…...

国产免费工作流引擎star 6.5k,Warm-Flow升级1.7.2(新增案例和修复缺陷)

文章目录 主要更新内容项目介绍功能思维导图设计器流程图演示地址官网Warm-Flow视频 主要更新内容 [feat] 开启流程实例&#xff0c;新增流程定义是否存在校验[feat] 新增合同签订流程案例[feat] 新增企业采购流程案例[update] mybatis-plus逻辑删除&#xff0c;删除值和未删除…...

计算机网络:移动通信蜂窝网络指的是什么?

无线基站的蜂窝网络(Cellular Network)是现代移动通信系统的核心架构,其核心思想是通过蜂窝状小区划分和频率复用,实现广域覆盖、高效频谱利用和动态资源管理。以下从设计原理、网络架构、关键技术及实际挑战等方面深入解析蜂窝网络。 一、蜂窝网络的设计原理 1. 蜂窝结构…...

scratch基础-外观模块

一、本次任务 二、内容详解 1、模块介绍 1、说[你好] (2)秒&#xff1a;临时对话框&#xff0c;短暂对话 2、说[你好]&#xff1a;持续显示对话框&#xff0c;长文本显示 3、思考[嗯…] (2)秒&#xff1a;临时显示思考气泡&#xff0c;用于角色思考 4、思考[嗯…] &#xff1a…...

前端服务器部署分类总结

目前所了解的部署有三种方式&#xff1a; 一是本地服务器部署&#xff1b;二是 nginx 服务器部署&#xff1b;三是云服务器部署 本地部署&#xff0c;准备好部署的包 以Vue项目为例&#xff0c;执行npm run build 命令打成前端包 第二步&#xff1a;将打包结果交给服务器(本地…...

精益数据分析(58/126):移情阶段的深度实践与客户访谈方法论

精益数据分析&#xff08;58/126&#xff09;&#xff1a;移情阶段的深度实践与客户访谈方法论 在创业的漫长旅途中&#xff0c;正确识别和验证问题是成功的第一步。今天&#xff0c;我们继续围绕《精益数据分析》中创业阶段的核心内容&#xff0c;深入探讨移情阶段的关键实践…...