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

SpringBoot实现接口防刷的5种高效方案详解

目录

前言:接口防刷的重要性

方案一:基于注解的访问频率限制

实现原理

核心代码实现

使用示例

优缺点分析

方案二:令牌桶算法实现限流

算法原理

核心实现

配置使用

适用场景分析

方案三:分布式限流(Redis + Lua脚本)

技术架构

Lua脚本实现

Java服务层实现

注解式应用

方案四:集成Sentinel实现全方位防护

Sentinel核心功能

配置示例

注解使用

方案五:验证码与行为分析防刷

复合防护体系

行为分析核心逻辑

验证码集成

方案对比与选型指南

最佳实践建议

总结


前言:接口防刷的重要性

在当今互联网应用中,接口安全是系统设计中不可忽视的重要环节。恶意用户或自动化脚本的高频请求不仅会消耗宝贵的服务器资源,还可能导致数据异常、服务不可用甚至系统崩溃。本文将详细介绍在SpringBoot框架下实现接口防刷的5种技术方案,帮助开发者构建更加健壮的应用系统。

方案一:基于注解的访问频率限制

实现原理

这种方案通过自定义注解和AOP切面编程实现,利用Redis作为计数器存储访问次数,是最简单直接的防刷方案。

核心代码实现

// 1. 定义限流注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimit {int time() default 60;       // 限制时间段(秒)int count() default 10;      // 允许的最大请求次数String key() default "";     // 限流key(支持SpEL)String message() default "操作太频繁,请稍后再试";
}// 2. 实现限流切面
@Aspect
@Component
@Slf4j
public class RateLimitAspect {@Autowiredprivate StringRedisTemplate redisTemplate;@Around("@annotation(rateLimit)")public Object around(ProceedingJoinPoint pjp, RateLimit rateLimit) throws Throwable {String limitKey = getLimitKey(pjp, rateLimit);boolean limited = isLimited(limitKey, rateLimit.time(), rateLimit.count());if (limited) throw new RuntimeException(rateLimit.message());return pjp.proceed();}private boolean isLimited(String key, int time, int count) {Long currentCount = redisTemplate.opsForValue().increment(key, 1);if (currentCount == 1) redisTemplate.expire(key, time, TimeUnit.SECONDS);return currentCount > count;}
}

使用示例

@RestController
@RequestMapping("/api")
public class UserController {@RateLimit(time = 60, count = 3, message = "请求太频繁,请稍后再试")@GetMapping("/user/{id}")public User getUser(@PathVariable Long id) {return userService.getUser(id);}// 使用SpEL表达式动态生成key@RateLimit(time = 60, count = 1, key = "#id + '_' + #request.remoteAddr")@PostMapping("/user/{id}/update")public Result updateUser(@PathVariable Long id, HttpServletRequest request) {return userService.updateUser(id);}
}

优缺点分析

✅ 优点

  • 实现简单,上手容易

  • 注解式使用,对业务代码无侵入

  • 可精确控制接口粒度

  • 支持灵活的限流策略配置

❌ 缺点

  • 限流逻辑相对简单

  • 缺少预警机制

  • 分布式环境下需要依赖Redis

方案二:令牌桶算法实现限流

算法原理

令牌桶算法是一种更灵活的限流算法,系统以恒定速率向桶中添加令牌,请求需要获取令牌才能被处理,允许突发流量但限制长期平均流量。

核心实现

@Component
public class RateLimiter {private final ConcurrentHashMap<String, com.google.common.util.concurrent.RateLimiter> rateLimiterMap = new ConcurrentHashMap<>();public boolean tryAcquire(String key, double permitsPerSecond, long timeout, TimeUnit unit) {com.google.common.util.concurrent.RateLimiter rateLimiter = rateLimiterMap.computeIfAbsent(key, k -> RateLimiter.create(permitsPerSecond));return rateLimiter.tryAcquire(1, timeout, unit);}
}// 拦截器实现
@Component
public class TokenBucketInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String key = getIpAddress(request) + ":" + request.getRequestURI();boolean acquired = rateLimiter.tryAcquire(key, 2.0, 100, TimeUnit.MILLISECONDS);if (!acquired) {response.getWriter().write("{"code":429,"message":"请求过于频繁"}");return false;}return true;}
}

配置使用

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate TokenBucketInterceptor tokenBucketInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(tokenBucketInterceptor).addPathPatterns("/api/**");}
}

适用场景分析

令牌桶算法特别适合需要允许短时突发流量的场景,如:

  • 秒杀活动开始时的瞬间高并发

  • 定时任务集中触发时段

  • 用户短时间内多次操作

方案三:分布式限流(Redis + Lua脚本)

技术架构

分布式限流架构图

Lua脚本实现

-- 限流Key
local key = KEYS[1]
-- 限流窗口,单位秒
local window = tonumber(ARGV[1])
-- 限流阈值
local threshold = tonumber(ARGV[2])
-- 当前时间戳
local now = tonumber(ARGV[3])-- 移除过期的请求记录
redis.call('ZREMRANGEBYSCORE', key, 0, now - window * 1000)-- 获取当前窗口内的请求数
local count = redis.call('ZCARD', key)-- 如果请求数超过阈值,拒绝请求
if count >= threshold thenreturn 0
end-- 添加当前请求记录
redis.call('ZADD', key, now, now .. '-' .. math.random())
-- 设置过期时间
redis.call('EXPIRE', key, window)-- 返回当前窗口剩余可用请求数
return threshold - count - 1

Java服务层实现

@Service
public class RedisRateLimiterService {@Autowiredprivate StringRedisTemplate redisTemplate;private DefaultRedisScript<Long> rateLimiterScript;@PostConstructpublic void init() {rateLimiterScript = new DefaultRedisScript<>();rateLimiterScript.setLocation(new ClassPathResource("scripts/rate_limiter.lua"));rateLimiterScript.setResultType(Long.class);}public long isAllowed(String key, int window, int threshold) {return redisTemplate.execute(rateLimiterScript, Collections.singletonList(key),String.valueOf(window),String.valueOf(threshold),String.valueOf(System.currentTimeMillis()));}
}

注解式应用

@DistributedRateLimit(window = 60, threshold = 30, mode = "ip")
@GetMapping("/products")
public List<Product> getProducts() {return productService.findAll();
}@DistributedRateLimit(prefix = "pay:", window = 3600, threshold = 5, mode = "user")
@PostMapping("/payment")
public Result createPayment(@RequestBody PaymentRequest paymentRequest) {return paymentService.createPayment(paymentRequest);
}

方案四:集成Sentinel实现全方位防护

Sentinel核心功能

  1. 流量控制:QPS/并发线程数控制

  2. 熔断降级:异常比例/响应时间熔断

  3. 系统保护:Load/BBR自适应保护

  4. 热点防护:参数级别流控

配置示例

@Configuration
public class SentinelConfig {@PostConstructpublic void init() {List<FlowRule> rules = new ArrayList<>();// 普通流控规则FlowRule apiRule = new FlowRule();apiRule.setResource("/api/data");apiRule.setGrade(RuleConstant.FLOW_GRADE_QPS);apiRule.setCount(20);rules.add(apiRule);// 热点参数规则ParamFlowRule hotspotRule = new ParamFlowRule("/api/product").setParamIdx(0).setCount(5);ParamFlowRuleManager.loadRules(Collections.singletonList(hotspotRule));FlowRuleManager.loadRules(rules);}
}

注解使用

@SentinelResource(value = "getUserById", blockHandler = "getUserBlockHandler",fallback = "getUserFallback")
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {return userService.getUser(id);
}// 限流处理方法
public User getUserBlockHandler(Long id, BlockException e) {throw new RuntimeException("请求频率过高,请稍后再试");
}// 熔断方法
public User getUserFallback(Long id, Throwable t) {return new User(id, "Fallback User");
}

方案五:验证码与行为分析防刷

复合防护体系

  1. 图形验证码:阻止简单自动化工具

  2. 行为分析:识别异常访问模式

  3. 二次验证:关键操作额外验证

行为分析核心逻辑

@Service
public class BehaviorAnalysisService {public boolean isSuspicious(HttpServletRequest request) {// 1. 检查访问频率String freqKey = "behavior:freq:" + getIpAddress(request);Long count = redisTemplate.opsForValue().increment(freqKey, 1);if (count > 30) return true;// 2. 分析User-AgentString ua = request.getHeader("User-Agent");if (ua == null || ua.length() < 40) return true;// 3. 检测请求间隔模式if (isUniformInterval(getIpAddress(request))) return true;// 4. 其他高级分析...return false;}
}

验证码集成

@RestController
@RequestMapping("/api/captcha")
public class CaptchaController {@Autowiredprivate CaptchaService captchaService;@GetMappingpublic Map<String, String> getCaptcha(HttpServletResponse response) {return Map.of("captcha", captchaService.generateCaptcha(response));}
}@CaptchaRequired
@PostMapping("/login")
public Result login(@RequestParam String captchaCode) {// 登录逻辑
}

方案对比与选型指南

方案实现难度防刷效果分布式支持用户体验适用场景
注解限流⭐⭐需Redis⭐⭐⭐简单接口防护
令牌桶⭐⭐⭐⭐⭐单机⭐⭐⭐⭐允许突发的场景
Redis+Lua⭐⭐⭐⭐⭐⭐⭐支持⭐⭐⭐分布式精确限流
Sentinel⭐⭐⭐⭐⭐⭐⭐⭐⭐需配置可配置复杂系统防护
验证码+行为分析⭐⭐⭐⭐⭐⭐⭐⭐⭐支持⭐⭐敏感操作防护

最佳实践建议

  1. 分层防护:结合多种方案,对不同重要性的接口采用不同防护强度

  2. 动态调整:根据监控数据实时调整限流阈值

  3. 优雅降级:被限流时提供友好的提示或备用服务

  4. 监控告警:建立完善的监控体系,及时发现异常流量

  5. 黑白名单:结合IP/用户黑白名单机制

总结

本文详细介绍了SpringBoot框架下5种接口防刷方案,从简单的注解限流到复杂的Sentinel集成,开发者可以根据实际需求选择合适的方案。在实际项目中,通常需要组合多种方案来构建全方位的防护体系。

技术选型关键点

  • 评估系统规模(单机/分布式)

  • 分析业务场景特点

  • 考虑用户体验影响

  • 评估运维复杂度

希望本文能帮助您构建更加安全可靠的SpringBoot应用系统。如果您有任何问题或建议,欢迎在评论区留言讨论。

相关文章:

SpringBoot实现接口防刷的5种高效方案详解

目录 前言&#xff1a;接口防刷的重要性 方案一&#xff1a;基于注解的访问频率限制 实现原理 核心代码实现 使用示例 优缺点分析 方案二&#xff1a;令牌桶算法实现限流 算法原理 核心实现 配置使用 适用场景分析 方案三&#xff1a;分布式限流&#xff08;Redis …...

DeepSearch复现篇:QwQ-32B ToolCall功能初探,以Agentic RAG为例

DeepSearch复现篇&#xff1a;QwQ-32B ToolCall功能初探&#xff0c;以Agentic RAG为例 作者&#xff1a;CyPaul Space 原文地址&#xff1a;https://zhuanlan.zhihu.com/p/30289363967 全文阅读约3分钟~ 背景 今天看到 论文&#xff1a;Search-R1: Training LLMs to Reason …...

项目实战-贪吃蛇大作战【补档】

这其实算是一个补档&#xff0c;因为这个项目是我在大一完成的&#xff0c;但是当时没有存档的习惯&#xff0c;今天翻以前代码的时候翻到了&#xff0c;于是乎补个档&#xff0c;以此怀念和志同道合的网友一起做项目的日子 ₍ᐢ ›̥̥̥ ༝ ‹̥̥̥ ᐢ₎♡ 这里面我主要负责…...

power bi获取局域网内共享文件

power bi获取局域网内共享文件 需求&#xff1a; 数据源并不一定都是在本地&#xff0c;有可能在云端&#xff0c;也有可能在其他服务器&#xff0c;今天分享如果数据源在另外一台服务器&#xff0c;如何获取数据源的方法。 明确需求&#xff1a;需要通过PowerBI获取局域网中的…...

100%提升信号完整性:阻抗匹配在高速SerDes中的实践与影响

一个高速信号SerDes通道&#xff08;例如PCIe、112G/224G-PAM4&#xff09;包含了这些片段&#xff1a; 传输线连通孔&#xff08;PTH or B/B via&#xff09;连接器高速Cable锡球&#xff08;Ball and Bump&#xff09; 我们会希望所有的片段都可以有一致的阻抗&#xff0c;…...

第六章:Tool and LLM Integration

Chapter 6: Tool and LLM Integration 从执行流到工具集成&#xff1a;如何让AI“调用真实世界的技能”&#xff1f; 在上一章的执行流框架中&#xff0c;我们已经能让多个代理协作完成复杂任务。但你是否想过&#xff1a;如果用户要求“查询实时天气”或“打开网页搜索”&…...

prompt提示词编写技巧

为什么学习prompt编写 目的&#xff1a;通过prompt的编写&#xff0c;提升LLM输出相关性、准确性和多样性&#xff0c;并对模型输出的格式进行限制&#xff0c;满足我们的业务需求。 学过提示词工程的人&#xff1a;像“专业导演”&#xff0c;通过精准指令控制 AI 输出&#…...

Nginx配置SSL详解

文章目录 Nginx配置SSL详解1. SSL/TLS 基础知识2. 准备工作3. 获取SSL证书4. Nginx SSL配置步骤4.1 基础配置4.2 配置说明 5. 常见配置示例5.1 双向认证配置5.2 多域名SSL配置 6. 安全优化建议7. 故障排查总结参考资源下载验证的完整实例 Nginx配置SSL详解 1. SSL/TLS 基础知识…...

网络安全之红队LLM的大模型自动化越狱

前言 大型语言模型&#xff08;LLMs&#xff09;已成为现代机器学习的重要支柱&#xff0c;广泛应用于各个领域。通过对大规模数据的训练&#xff0c;这些模型掌握了多样化的技能&#xff0c;展现出强大的生成与理解能力。然而&#xff0c;由于训练数据中难以完全剔除有毒内容&…...

【技术笔记】通过Cadence Allegro创建一个PCB封装(以SOT23为例)

【技术笔记】通过Cadence Allegro创建一个PCB封装&#xff08;以SOT23为例&#xff09; 一、焊盘创建二、PCB封装设计三、丝印位号及标识添加 更多内容见专栏&#xff1a;【硬件设计遇到了不少问题】、【Cadence从原理图到PCB设计】 一、焊盘创建 首先要找到元器件的相关手册&…...

新环境注册为Jupyter 内核

1. ​​确认环境是否已注册为内核​​ 在终端运行以下命令&#xff0c;查看所有已注册的内核&#xff1a; jupyter kernelspec list2. ​​为自定义环境注册内核 步骤 1&#xff1a;激活目标虚拟环境 conda activate your_env_name # 替换为你的环境名步骤 2&#xff1a;安装…...

[Spring] Seata详解

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

使用JDK的数据校验和Spring的自定义注解校验前端传递参数的两种方法

第一种&#xff1a;JDK的数据校验注解 PostMapping("/test")public String test(QueryParam param, RequestHeader(value "App_key") String App_key,RequestHeader(value "App_secret") String App_secret) throws IOException {param.setApp…...

JS错误处理的新方案 (不使用try-catch)

错误处理一直是JavaScript开发者需要认真对待的问题&#xff0c;传统的try-catch语法虽然简单直观&#xff0c;但在异步代码中使用时存在诸多限制。 try-catch的局限性 传统try-catch模式在现代JavaScript开发中面临的问题&#xff1a; 1. 异步错误捕获的缺陷 try-catch无法…...

前端实现商品放大镜效果(Vue3完整实现)

前端实现商品放大镜效果&#xff08;Vue3完整实现&#xff09; 前言 在电商类项目中&#xff0c;商品图片的细节展示至关重要。放大镜效果能显著提升用户体验&#xff0c;允许用户在不跳转页面的情况下查看高清细节。本文将基于Vue3实现一个高性能的放大镜组件&#xff0c;完整…...

redis未授权访问漏洞学习

一、Redis常见用途 1. Redis介绍 全称与起源: Redis全称Remote Dictionary Service(远程字典服务)&#xff0c;最初由antirez在2009年开发&#xff0c;用于解决网站访问记录统计的性能问题。发展历程: 从最初仅支持列表功能的内存数据库&#xff0c;经过十余年发展已支持多种…...

阿里qiankun微服务搭建

主服务 chat vue3 ts vite 子服务 ppt react 18 vite 子服务 agent 主服务 npm i vite-plugin-qiankun mian.ts import ./style/base.scss import virtual:svg-icons-register import { createApp } from vue import { createPinia } from piniaimport App from ./App.vue im…...

【CodeSprint】第二章-2.1 简单模拟

第二章 2.1 简单模拟 ✏️ 关于专栏&#xff1a;专栏用于记录 prepare for the coding test。 1. 简单模拟 简单模拟题目不需要复杂算法&#xff0c;直接按照题意一步步模拟即可。 1.1 促销计算 题目描述 某百货公司为了促销&#xff0c;采用购物打折的优惠方法&#xff1a…...

Golang实现函数默认参数

golang原生不支持默认参数 在日常开发中&#xff0c;我们有时候需要使用默认设置&#xff0c;但有时候需要提供自定义设置 结构体/类&#xff0c;在Java我们可以使用无参、有参构造函数来实现&#xff0c;在PHP中我们也可以实现(如 public function xxx($isCName false, $sec…...

【Python Web开发】03-HTTP协议

文章目录 1. HTTP协议基础1.1 请求-响应模型1.2 请求方法1.3 请求和响应结构1.4 状态码 2. Python 发送 HTTP 请求2.1 urllib库2.2 requests 库 3. Python 构建 HTTP 服务器3.1 http.server模块3.2 Flask 框架 4. HTTP 协议的安全问题5. 缓存和性能优化 HTTP&#xff08;Hypert…...

提高营销活动ROI:大数据驱动的精准决策

提高营销活动ROI:大数据驱动的精准决策 大家好,我是Echo_Wish。今天我们来聊聊如何通过大数据来提高营销活动的ROI(投资回报率)。我们都知道,随着市场的日益竞争,营销的成本不断增加,如何在这片红海中脱颖而出,不仅需要精准的营销策略,还需要依靠先进的技术,尤其是大…...

前端excel导出

在数据可视化和管理日益重要的今天&#xff0c;前端实现 Excel 导出功能已经成为众多项目中的刚需。 一、Excel 导出的常见场景​ 数据报表导出&#xff1a;在企业管理系统、数据分析平台中&#xff0c;用户经常需要将系统中的数据以 Excel 表格的形式导出&#xff0c;便于离…...

pymsql(SQL注入与防SQL注入)

SQL注入&#xff1a; import pymysql# 创建数据库连接 返回一个对象 conn pymysql.connect(host"localhost", # MySQL服务器地址 本地地址 127.0.0.1user"root", # 用户名 &#xff08;账号&#xff09;password"155480", # 密码database&qu…...

基于Springboot + vue + 爬虫实现的高考志愿智能推荐系统

项目描述 本系统包含管理员和学生两个角色。 管理员角色&#xff1a; 个人中心管理&#xff1a;管理员可以管理自己的个人信息。 高校信息管理&#xff1a;管理员可以查询、添加或删除高校信息&#xff0c;并查看高校详细信息。 学生管理&#xff1a;管理员可以查询、添加或…...

delphi使用sqlite3

看了一下delphi调用sqlite3最新版本的调用&#xff0c;网上说的都很片面&#xff0c;也没有完整的资料了。 我自己研究了一下&#xff0c;分享出来。 在调用demo中&#xff0c;官方也给了一个demo但是功能很少&#xff0c;没有参考价值。 1.定义&#xff1a; 首先把sqlite3…...

高压开关柜局部放电信号分析系统

高压开关柜局部放电信号分析系统 - 开发笔记 1. 项目概述 这个项目是我在2025年实现的高压开关柜局部放电信号分析系统&#xff0c;目的是通过采集分析局部放电信号&#xff0c;判断设备的工作状态和潜在故障。系统包含从信号模拟生成、特征提取、到深度学习模型训练的全流程…...

ai环境conda带torch整体迁移。

conda打包好的GPU版torch环境&#xff0c;其实很简单&#xff0c;就是conda装好的torch环境env整体打包&#xff0c;然后到新机器上再解压到env路径。 打开搭建好的环境&#xff0c;找自己路径&#xff0c;我默认的是这个。 cd/root/anaconda3/envs/ 然后整个文件夹打包。tar -…...

电价单位解析与用电设备耗电成本计算

一、电价单位 元/kWh 的解析 定义&#xff1a; 元/kWh 表示每千瓦时电能的费用&#xff0c;即1度电的价格。例如&#xff0c;若电价为0.5元/kWh&#xff0c;则使用1千瓦的电器1小时需支付0.5元。 电价构成&#xff1a; 中国销售电价由四部分组成&#xff1a; 上网电价&#xf…...

辛格迪客户案例 | 华道生物细胞治疗生产及追溯项目(CGTS)

01 华道&#xff08;上海&#xff09;生物医药有限公司&#xff1a;细胞治疗领域的创新先锋 华道&#xff08;上海&#xff09;生物医药有限公司&#xff08;以下简称“华道生物”&#xff09;是一家专注于细胞治疗技术研发与应用的创新型企业&#xff0c;尤其在CAR-T细胞免疫…...

C++(初阶)(十三)——继承

继承 继承概念示例 定义格式 继承和访问方式继承方式访问方式实例 继承类模板基类和派生类之间的转换继承中的作用域隐藏规则选择题 派生类的默认成员函数默认成员函数派生类中的实现 实现一个不能被继承的类继承与友元继承与静态成员多继承及其菱形继承问题虚继承多继承指针偏…...

S09-电机运行时间

感谢粉丝网友的支持&#xff0c;也欢迎你们的讨论和分享。昨天我们简单讨论了一下标准功能块的重要性&#xff0c;仅仅是拿电机块举了一个例子&#xff0c;有粉丝问能否把电机运行时间做到块里面&#xff0c;完善一下功能呢&#xff1f;那是绝对当然的100%可以的啊&#xff01;…...

大语言模型(LLMs)微调技术总结

文章目录 全面总结当前大语言模型&#xff08;LLM&#xff09;微调技术1. 引言2. 为什么需要微调&#xff1f;3. 微调技术分类概览4. 各种微调技术详细介绍4.1 基础微调方法4.1.1 有监督微调&#xff08;Supervised Fine-Tuning, SFT&#xff09;4.1.2 全参数微调&#xff08;F…...

python练习:求数字的阶乘

求数字的阶乘 eg:5的阶乘 54321 """ 求数字的阶乘 eg:5的阶乘 5*4*3*2*1 """count 1 for i in range(1,6):count count * iprint(count)运行结果&#xff1a;...

综合练习一

背景 某银行监管系统&#xff0c;需要设计并实现用户登入记录功能&#xff0c;每个用户登入系统时&#xff0c;系统自动记录登入用户的账户、登入时间、登入失败成功与否信息等&#xff0c;普通用户只能登入登出&#xff0c;管理员可以登入后查看日志及分析统计信息等。 用户…...

List--链表

一、链表 1.1 什么是List&#xff1f; 在C语言中&#xff0c;我们需要使用结构体struct来进行List(链表&#xff09;的实现&#xff1a; struct ListNode {DataType Data;//DataType是任意类型的变量定义struct ListNode* next;//指向下一个结点的指针变量 }; 与之前的vect…...

SpeedyAutoLoot

SpeedyAutoLoot自动拾取插件 SpeedyAutoLoot.lua local AutoLoot CreateFrame(Frame)SpeedyAutoLootDB SpeedyAutoLootDB or {} SpeedyAutoLootDB.global SpeedyAutoLootDB.global or {}local BACKPACK_CONTAINER BACKPACK_CONTAINER local LOOT_SLOT_CURRENCY LOOT_SLOT…...

编程日志4.23

栈的C顺序表实现 #include<iostream> #include<stdexcept> using namespace std; //模板声明&#xff0c;表明Stack类是一个通用的模板&#xff0c;可以用于存储任何类型的元素T template<typename T> //栈的声明 //Stack类的声明&#xff0c;表示一个栈的…...

打印所有字段

package com.volvo.midend.vehicle;import com.volvo.midend.vehicle.dto.out.vista.VistaDemoVO;import java.lang.reflect.Field;public class TestAllFiled {// 递归打印类的所有字段public static void printAllFields(Class<?> clazz, int indentLevel) {// 根据缩…...

4G FS800DTU上传图像至巴法云

目录 1 前言 2 准备工作 2.1 硬件准备 2.2 软件环境 2.3 硬件连接 3 实现方案 4 巴法云平台账号创建与设备联网配置 4.1 创建账号 4.2 进入巴法云 4.3 获取联网参数 4.4 连接巴法云 5 拍照上传至巴法云 6 ESP32-CAM程序 7 总结 1 前言 巴法云(Bemfa Cloud)是一个…...

一键叠图工具

写了个拼图小工具 供大家测试 APP安卓的 测试下载 点击下载 百度网盘: https://pan.baidu.com/s/17B5KVIMMZlOAsF7a16KNug?pwd1234 提取码: 1234 拼图步骤&#xff1a;选图--选择变亮或变暗--滤镜发色 在正式开始之前&#xff0c;我们来定义几条原则先&#xff08;熟悉…...

【OSG学习笔记】Day 12: 回调机制——动态更新场景

UpdateCallback 在OpenSceneGraph&#xff08;OSG&#xff09;里&#xff0c;UpdateCallback是用来动态更新场景的关键机制。 借助UpdateCallback&#xff0c;你能够实现节点的动画效果&#xff0c;像旋转、位移等。 NodeCallback osg::NodeCallback 是一个更通用的回调类&…...

快速上手Prism WPF 工程

1、Prism 介绍 ​定位​&#xff1a; Prism 是 ​微软推出的框架&#xff0c;专为构建 ​模块化、可维护的复合式应用程序​ 设计&#xff0c;主要支持 WPF、Xamarin.Forms、UWP 等平台。​核心功能​&#xff1a; ​模块化开发​&#xff1a;将应用拆分为独立模块&#xff0c…...

Dockerfile讲解与示例汇总

容器化技术已经成为应用开发和部署的标准方式,而Docker作为其中的佼佼者,以其轻量、高效、可移植的特性,深受开发者和运维人员的喜爱。本文将从实用角度出发,分享各类常用服务的Docker部署脚本与最佳实践,希望能帮助各位在容器化之路上少走弯路。 无论你是刚接触Docker的…...

MATLAB Coder代码生成(工业部署)——MATLAB技巧

MATLAB Coder是MATLAB生态中用于将算法代码转换为C/C++代码的核心工具,其生成的代码可直接部署到嵌入式硬件、工业控制器或企业级应用中,尤其在智能制造、物联网和实时控制领域具有广泛应用。 通过 MATLAB Coder,可以轻松地将 MATLAB 代码转换为高效的 C/C++ 代码,适用于嵌…...

3、CMake语法:制作和使用动态库和静态库

动态库和静态库 1 动态库和静态库简介1.1 静态库静态库文件类型.lib 文件.pdb 文件 1.2 动态库动态库文件类型 1.3 总结 2. 制作和使用静态库2.1 CMake指定输出的路径 2.2 VS利用第三方库编译静态库 2.3 使用静态库CMake链接静态库VS链接静态库 3. 制作和使用动态库3.1 CMake指…...

使用双端队列deque模拟栈stack

使用双端队列deque模拟栈stack 今天的内容有点简单~ 众所周知&#x1f913;&#x1f446;&#xff0c;栈作为一个先进后出的结构&#xff0c;在计算机的世界确实能够发挥很多的作用。 而我们C祖师爷本贾尼是第一批把这个结构作为实实在在的容器做进std的人~ 那为了更好的了解…...

Spring系列四:AOP切面编程第三部分

&#x1f40b;AOP-JoinPoint 1.通过JoinPoint可以获取到调用方法的签名 2.其他常用方法 ●代码实现 1.com.zzw.spring.aop.aspectj.SmartAnimalAspect Aspect //表示是一个切面类 Component //会将SmartAnimalAspect注入到容器 public class SmartAnimalAspect {//给Car配置…...

为什么使用ThreadLocal后要调用remove()方法呢?

ThreadLocalMap中包含一个数组&#xff0c;每个节点对应的类名叫Entry&#xff0c;这个类继承WeakReference<ThreadLocal<?>>&#xff0c;entry中有两个属性&#xff1a;key和value。特别需要指出的是key来自于父类中的threadLocal对象。 为了避免内存泄露&#…...

如何在idea 中写spark程序

在 IntelliJ IDEA 中编写 Spark 程序可以通过以下步骤进行&#xff1a; 1. **安装 Scala 插件**&#xff1a;首先确保已经安装了 Scala 插件。在 IntelliJ IDEA 中选择 File -> Settings -> Plugins -> 搜索 Scala -> 安装插件。 2. **创建新项目**&#xff1a;在…...

国产全兼容ADS131E08芯片---LHA7878

LHA787X是一系列多通道同步采样、24位A-∑模数转换器(ADC)&#xff0c;内置可编程增益放大器(PGA)、内部基准和振荡器。凭借ADC的宽动态范围、可扩展数据传输速率以及内部故障检测监测计&#xff0c;LHA787X受到工业电源监测和保护以及测试和测量应用的青睐。真正的高阻抗输入支…...