SpringBoot中使用Spring-Retry重试框架 - 第454篇

news2025/1/18 1:51:29

悟纤:最近我看到自己之前的try/catch、while代码进行请求的重试,看着很不舒服。

师傅:确实了,为师以前也是写出过这样的一堆难看的代码。

悟纤:那师傅这个事情有解吗?

​师傅:徒儿,你只要记住一个问题,但凡一个问题是普遍的问题,那么一定会有解决方案的。

悟纤:还能这么思考,棒极了。

师傅:那你去找找解决方案,输出文章让大家一起学习下呗。

悟纤:好勒,马上行动起来~~~

导读

不小心看到很久很久的历史代码:

这个代码逻辑实现了网络异常或者没有获取到想要的状态,就根据一定的策略进行重试。

如果代码中很多地方都有这样的代码,那将是一场灾难。

对于上面的场景Spring-Retry就能轻松的搞定。

一、何为Spring-Retry

在实际工作中,重处理是一个非常常见的场景。通常来说,会用try/catch,while循环之类的语法来进行重处理,但是这样的做法缺乏统一性,并且不是很方便,要多写很多代码。然而spring-retry却可以通过注解,在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。

1.1 使用场景

重处理场景很多,比如:

(1)发送消息失败。

(2)调用远程服务失败。

(3)争抢锁失败。

1.2 Spring-Retry是什么?

spring-retry是是spring提供的一个重试框架,原本自己实现的重试机制,现在spring帮封装好提供更加好的编码体验。

二、Spring-Retry基本使用

2.1 基本使用

基本思路是引入spring-retry,由于spring-retry使用到了aop,所以也要把aop的依赖进行添加。

大体使用步骤:

(1)创建一个项目

(2)添加依赖

(3)启用Spring-Retry

(4)使用@Retryable

(5)测试

2.1 创建一个项目

使用idea创建项目springboot-retry-demo。

2.2 添加依赖

在pom.xml文件中添加依赖:

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code><span style="color:#afafaf"><?xml version="1.0" encoding="UTF-8"?></span></code><code><span style="color:#0e9ce5"><<span style="color:#0e9ce5">project</span> <span style="color:#0e9ce5">xmlns</span>=<span style="color:#dd1144">"http://maven.apache.org/POM/4.0.0"</span> <span style="color:#0e9ce5">xmlns:xsi</span>=<span style="color:#dd1144">"http://www.w3.org/2001/XMLSchema-instance"</span></span></code><code>         xsi:schemaLocation=<span style="color:#dd1144">"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"</span>></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">modelVersion</span>></span>4.0.0<span style="color:#0e9ce5"></<span style="color:#0e9ce5">modelVersion</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">parent</span>></span></code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">groupId</span>></span>org.springframework.boot<span style="color:#0e9ce5"></<span style="color:#0e9ce5">groupId</span>></span></code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">artifactId</span>></span>spring-boot-starter-parent<span style="color:#0e9ce5"></<span style="color:#0e9ce5">artifactId</span>></span></code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">version</span>></span>2.7.6<span style="color:#0e9ce5"></<span style="color:#0e9ce5">version</span>></span></code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">relativePath</span>/></span> <span style="color:#afafaf"><em><!-- lookup parent from repository --></em></span></code><code>    <span style="color:#0e9ce5"></<span style="color:#0e9ce5">parent</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">groupId</span>></span>com.kfit<span style="color:#0e9ce5"></<span style="color:#0e9ce5">groupId</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">artifactId</span>></span>springboot-retry-demo<span style="color:#0e9ce5"></<span style="color:#0e9ce5">artifactId</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">version</span>></span>0.0.1-SNAPSHOT<span style="color:#0e9ce5"></<span style="color:#0e9ce5">version</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">name</span>></span>springboot-retry-demo<span style="color:#0e9ce5"></<span style="color:#0e9ce5">name</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">description</span>></span>springboot-retry-demo<span style="color:#0e9ce5"></<span style="color:#0e9ce5">description</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">properties</span>></span></code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">java.version</span>></span>1.8<span style="color:#0e9ce5"></<span style="color:#0e9ce5">java.version</span>></span></code><code>    <span style="color:#0e9ce5"></<span style="color:#0e9ce5">properties</span>></span></code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">dependencies</span>></span></code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">dependency</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">groupId</span>></span>org.springframework.boot<span style="color:#0e9ce5"></<span style="color:#0e9ce5">groupId</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">artifactId</span>></span>spring-boot-starter-web<span style="color:#0e9ce5"></<span style="color:#0e9ce5">artifactId</span>></span></code><code>        <span style="color:#0e9ce5"></<span style="color:#0e9ce5">dependency</span>></span></code><code>​</code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">dependency</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">groupId</span>></span>org.springframework.retry<span style="color:#0e9ce5"></<span style="color:#0e9ce5">groupId</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">artifactId</span>></span>spring-retry<span style="color:#0e9ce5"></<span style="color:#0e9ce5">artifactId</span>></span></code><code>        <span style="color:#0e9ce5"></<span style="color:#0e9ce5">dependency</span>></span></code><code>​</code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">dependency</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">groupId</span>></span>org.springframework.boot<span style="color:#0e9ce5"></<span style="color:#0e9ce5">groupId</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">artifactId</span>></span>spring-boot-starter-aop<span style="color:#0e9ce5"></<span style="color:#0e9ce5">artifactId</span>></span></code><code>        <span style="color:#0e9ce5"></<span style="color:#0e9ce5">dependency</span>></span></code><code>​</code><code>​</code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">dependency</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">groupId</span>></span>org.springframework.boot<span style="color:#0e9ce5"></<span style="color:#0e9ce5">groupId</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">artifactId</span>></span>spring-boot-starter-test<span style="color:#0e9ce5"></<span style="color:#0e9ce5">artifactId</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">scope</span>></span>test<span style="color:#0e9ce5"></<span style="color:#0e9ce5">scope</span>></span></code><code>        <span style="color:#0e9ce5"></<span style="color:#0e9ce5">dependency</span>></span></code><code>    <span style="color:#0e9ce5"></<span style="color:#0e9ce5">dependencies</span>></span></code><code>​</code><code>    <span style="color:#0e9ce5"><<span style="color:#0e9ce5">build</span>></span></code><code>        <span style="color:#0e9ce5"><<span style="color:#0e9ce5">plugins</span>></span></code><code>            <span style="color:#0e9ce5"><<span style="color:#0e9ce5">plugin</span>></span></code><code>                <span style="color:#0e9ce5"><<span style="color:#0e9ce5">groupId</span>></span>org.springframework.boot<span style="color:#0e9ce5"></<span style="color:#0e9ce5">groupId</span>></span></code><code>                <span style="color:#0e9ce5"><<span style="color:#0e9ce5">artifactId</span>></span>spring-boot-maven-plugin<span style="color:#0e9ce5"></<span style="color:#0e9ce5">artifactId</span>></span></code><code>            <span style="color:#0e9ce5"></<span style="color:#0e9ce5">plugin</span>></span></code><code>        <span style="color:#0e9ce5"></<span style="color:#0e9ce5">plugins</span>></span></code><code>    <span style="color:#0e9ce5"></<span style="color:#0e9ce5">build</span>></span></code><code>​</code><code><span style="color:#0e9ce5"></<span style="color:#0e9ce5">project</span>></span></code><code>​</code></span></span>

2.3 启用Spring-Retry

在启动类添加注解@EnableRetry启用Spring-Retry:

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code><span style="color:#afafaf">@SpringBootApplication</span></code><code><span style="color:#afafaf">@EnableRetry</span></code><code><span style="color:#ca7d37">public</span> <span style="color:#ca7d37">class</span> <span style="color:#0e9ce5">SpringbootRetryDemoApplication</span> {</code><code>    <span style="color:#ca7d37">public</span> <span style="color:#ca7d37">static</span> <span style="color:#ca7d37">void</span> <span style="color:#dd1144">main</span>(String[] args) {</code><code>        SpringApplication.run(SpringbootRetryDemoApplication.class, args);</code><code>    }</code><code>}</code><code>​</code></span></span>

2.4 使用@Retryable

在需要重试的方法添加@Retryable注解:

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code><span style="color:#ca7d37">package</span> <span style="color:#ca7d37">com</span>.kfit.demo;</code><code><span style="color:#ca7d37">import</span> <span style="color:#ca7d37">org</span>.springframework.retry.annotation.Retryable;</code><code><span style="color:#ca7d37">import</span> <span style="color:#ca7d37">org</span>.springframework.stereotype.Service;</code><code><span style="color:#ca7d37">import</span> <span style="color:#ca7d37">java</span>.util.Date;</code><code>​</code><code>@<span style="color:#ca7d37">Service</span></code><code>public class Demo1Service {</code><code>    @<span style="color:#ca7d37">Retryable</span></code><code>    public void call() {</code><code>        <span style="color:#ca7d37">System</span>.out.println("准备发起<span style="color:#ca7d37">RPC</span>调用..."+<span style="color:#ca7d37">new</span> <span style="color:#ca7d37">Date</span>());</code><code>        <span style="color:#ca7d37">throw</span> <span style="color:#ca7d37">new</span> <span style="color:#ca7d37">RuntimeException</span>("<span style="color:#ca7d37">RPC</span>调用异常");</code><code>    }</code><code>}</code><code>​</code></span></span>

2.5 测试

编写测试类或者在controller调用service进行测试,可以在控制台看到结果:

 

基本使用是不是很简单~ 从这里可以看出最大重试次数为3次。

三、Spring-Retry进阶使用

基本使用很简单,实际项目中需要思考的会更多,所以需要了解@Retryable可以配置的属性。

3.1 常用属性

看下常见的属性:

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code><span style="color:#afafaf"><em>/**</em></span></code><code><span style="color:#afafaf"><em> * value:抛出指定异常才会重试</em></span></code><code><span style="color:#afafaf"><em> * include:和value一样,默认为空,当exclude也为空时,默认所有异常</em></span></code><code><span style="color:#afafaf"><em> * exclude:指定不处理的异常</em></span></code><code><span style="color:#afafaf"><em> * maxAttempts:最大重试次数,默认3次</em></span></code><code><span style="color:#afafaf"><em> * backoff:重试等待策略,</em></span></code><code><span style="color:#afafaf"><em> * 默认使用<span style="color:#dd1144">@Backoff</span>,<span style="color:#dd1144">@Backoff</span>的value默认为1000L,我们设置为2000; 以毫秒为单位的延迟(默认 1000)</em></span></code><code><span style="color:#afafaf"><em> * multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。</em></span></code><code><span style="color:#afafaf"><em> * <span style="color:#dd1144">@return</span></em></span></code><code><span style="color:#afafaf"><em> */</em></span></code><code><span style="color:#afafaf">@Retryable</span>(value = Exception.class,maxAttempts = <span style="color:#0e9ce5">3</span>,backoff = <span style="color:#afafaf">@Backoff</span>(delay = <span style="color:#0e9ce5">2000</span>,multiplier = <span style="color:#0e9ce5">1.5</span>))</code><code><span style="color:#ca7d37">public</span> <span style="color:#ca7d37">void</span> <span style="color:#dd1144">call</span>() {</code><code>    System.out.println(<span style="color:#dd1144">"准备发起RPC调用..."</span>+<span style="color:#ca7d37">new</span> Date());</code><code>    <span style="color:#ca7d37">throw</span> <span style="color:#ca7d37">new</span> RuntimeException(<span style="color:#dd1144">"RPC调用异常"</span>);</code><code>}</code><code>​</code></span></span>

* value:抛出指定异常才会重试

* include:和value一样,默认为空,当exclude也为空时,默认所有异常

* exclude:指定不处理的异常

* maxAttempts:最大重试次数,默认3次

* backoff:重试等待策略,

默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000; 以毫秒为单位的延迟(默认 1000)

* multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。

3.2 重试耗尽回调

当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallback。Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法。如果不需要回调方法,可以直接不写回调方法,那么实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code>@Retryable(<span style="color:#ca7d37">value</span> = Exception.class,maxAttempts = <span style="color:#0e9ce5">3</span>,backoff = @Backoff(delay = <span style="color:#0e9ce5">2000</span>,multiplier = <span style="color:#0e9ce5">1.5</span>),recover = <span style="color:#dd1144">"recover"</span>)</code><code><span style="color:#ca7d37">public</span> <span style="color:#ca7d37">void</span> <span style="color:#dd1144">call</span>() {</code><code>    System.<span style="color:#ca7d37">out</span>.println(<span style="color:#dd1144">"准备发起RPC调用..."</span>+<span style="color:#ca7d37">new</span> Date());</code><code>    <span style="color:#ca7d37">throw</span> <span style="color:#ca7d37">new</span> RuntimeException(<span style="color:#dd1144">"RPC调用异常"</span>);</code><code>}</code><code>​</code><code>@Recover</code><code><span style="color:#ca7d37">public</span> <span style="color:#ca7d37">void</span> <span style="color:#dd1144">recover</span>(Exception e) {</code><code>    System.<span style="color:#ca7d37">out</span>.println(<span style="color:#dd1144">"recover-->记日志到数据库 或者调用其余的方法"</span>);</code><code>}</code><code>​</code></span></span>

当有多个的时候,可以通过属性recover来指定要回调的方法,执行结果如下:

这里会发现如果定义了回调方法,那么就不会抛出“RPC调用异常”信息了。

3.3 RetryTemplate的使用

Spring-Retry也提供了编码的方式RetryTemplate,先注入这个类:

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code><span style="color:#afafaf">@Bean</span></code><code><span style="color:#ca7d37">public</span> RetryTemplate <span style="color:#dd1144">retryTemplate</span>() {</code><code>    RetryTemplate retryTemplate = <span style="color:#ca7d37">new</span> RetryTemplate();</code><code>​</code><code>    SimpleRetryPolicy retryPolicy = <span style="color:#ca7d37">new</span> SimpleRetryPolicy(); <span style="color:#afafaf"><em>//设置重试策略</em></span></code><code>    retryPolicy.setMaxAttempts(<span style="color:#0e9ce5">3</span>);</code><code>    retryTemplate.setRetryPolicy(retryPolicy);</code><code>​</code><code>​</code><code>    FixedBackOffPolicy fixedBackOffPolicy = <span style="color:#ca7d37">new</span> FixedBackOffPolicy(); <span style="color:#afafaf"><em>//设置退避策略</em></span></code><code>    fixedBackOffPolicy.setBackOffPeriod(<span style="color:#0e9ce5">2000L</span>);</code><code>    retryTemplate.setBackOffPolicy(fixedBackOffPolicy);</code><code>​</code><code>    <span style="color:#ca7d37">return</span> retryTemplate;</code><code>}</code><code>​</code></span></span>

然后进行使用:

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code><span style="color:#ca7d37">public</span> <span style="color:#ca7d37">void</span> call(){</code><code>    <span style="color:#ca7d37">try</span> {</code><code>        retryTemplate.execute(<span style="color:#ca7d37">new</span> RetryCallback<<span style="color:#ca7d37">Object</span>, IllegalAccessException>() {</code><code>            <span style="color:#afafaf">@Override</span></code><code>            <span style="color:#ca7d37">public</span> <span style="color:#ca7d37">Object</span> doWithRetry(RetryContext context) throws IllegalAccessException {</code><code>                System.out.println(<span style="color:#dd1144">"准备发起RPC调用..."</span>+<span style="color:#ca7d37">new</span> <span style="color:#ca7d37">Date</span>());</code><code>                <span style="color:#ca7d37">throw</span> <span style="color:#ca7d37">new</span> RuntimeException(<span style="color:#dd1144">"RPC调用异常"</span>);</code><code>                <span style="color:#afafaf"><em>//return null;</em></span></code><code>            }</code><code>        });</code><code>    } <span style="color:#ca7d37">catch</span> (IllegalAccessException e) {</code><code>        <span style="color:#ca7d37">throw</span> <span style="color:#ca7d37">new</span> RuntimeException(e);</code><code>    }</code><code>}</code><code>​</code></span></span>

总结

spring-retry通过注解,在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。

如果重试多次失败之后,尽量进行回调处理,将这一次的失败信息进行记录,方便后续跟进和优化代码。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

博客网页制作基础大二dw作业 web课程设计网页制作 个人网页设计与实现 我的个人博客网页开发

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

2022全年度平板电视十大热门品牌销量榜单

随着社会的发展&#xff0c;近年来&#xff0c;平板电视成为了彩电转型升级的新方向。随着我国传统彩电进入存量竞争阶段&#xff0c;平板电视已成为我国彩电行业结构调整和转型升级的主要方向。 根据鲸参谋数据统计&#xff0c;今年京东平台平板电视的年度累计销量达到1300多万…

< 在element-ui中: 使用el-tree + el-table组件,联动请求用户数据表格组件 (基础版,后续可能更新) >

文章目录&#x1f449; 前言&#x1f449; 一、效果演示&#x1f449; 二、原理&#x1f449; 三、实现代码往期内容 &#x1f4a8;&#x1f449; 前言 在 Vue elementUi 开发中&#xff0c;实现通过树状组织机构&#xff0c;点击查询用户信息联动效果&#xff01; 组件较为简…

MySQL数据库学习(6)

一、MySQL索引简介 索引是一种特殊的数据库结构&#xff0c;由数据表中的一列或多列组合而成&#xff0c;可以用来快速查询数据表中有某一特定值的记录。 通过索引&#xff0c;查询数据时不用读完记录的所有信息&#xff0c;而只是查询索引列。不然的话&#xff0c;数据库系统将…

强化学习_06_pytorch-doubleDQN实践(Pendulum-v1)

环境描述 环境是倒立摆&#xff08;Inverted Pendulum&#xff09;&#xff0c;该环境下有一个处于随机位置的倒立摆。环境的状态包括倒立摆角度的正弦值&#xff0c;余弦值&#xff0c;角速度&#xff1b;动作为对倒立摆施加的力矩(action Box(-2.0, 2.0, (1,), float32))。…

windows11安装cuda+cudnn

安装Nvidia显卡驱动 如需安装显卡驱动&#xff0c;在官方驱动下载网站找到自己的显卡型号对应的驱动下载并安装:官方驱动 | NVIDIA 安装CUDA 前言 windows10 版本安装 CUDA &#xff0c;首先需要下载两个安装包 CUDA toolkit&#xff08;toolkit就是指工具包&#xff09;cu…

Qt扫盲-QLineEdit理论总结

QLineEdit理论总结1. 简述2. 输入模式3. 输入限制4. 文本操作槽函数3. 信号4. 快捷键5. 外观1. 简述 QLineEdit 是一个有用的编辑功能类&#xff0c;主要是处理输入和编辑单行纯文本 &#xff0c;主要是单行哦&#xff0c;就用来输入简单&#xff0c;短小的字符串。内部其实已…

极客时间Kafka - 09 Kafka Java Consumer 多线程开发实例

文章目录1. Kafka Java Consumer 设计原理2. 多线程方案3. 代码实现4. 问题思考目前&#xff0c;计算机的硬件条件已经大大改善&#xff0c;即使是在普通的笔记本电脑上&#xff0c;多核都已经是标配了&#xff0c;更不用说专业的服务器了。如果跑在强劲服务器机器上的应用程序…

JSP ssh科研管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh科研管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myec…

Core Scheduling

Core Scheduling要解决什么问题&#xff1f; core scheduling是v5.14中新增的功能&#xff0c;下图是内核数据结构为该功能所添加的字段。 为什么有core scheduling呢&#xff1f;因为当开启超线程(HyperThreading)时&#xff0c;一个物理核就变成了两个逻辑核&#xff0c;但&…

postgres 源码解析43 元组的插入流程详解 heap_insert

本文讲解postgres中元组的插入流程&#xff0c;深入了解其实现原理。同时此过程涉及元组xmin/xmax与标识位的设置细节&#xff0c;与事务的可见性部分密切相关相关&#xff0c;借此复习一下。 heappage结构 执行流程框架图 heap_prepare_insert 该函数执行内容较为简单&#…

课设项目之——教学辅助系统(学生考试监考系统)

在考试场中为学生监考十分枯燥&#xff0c;因此&#xff0c;建立一个可靠的作弊检测系统来识别学生是否存在作弊行为。 使用一个名为 Yolo3 的训练模型和一个名为 coco 的数据集&#xff0c;我们测试了考场中学生的书籍和手机&#xff0c;并将他们标记为作弊者。 使用haarcasc…

如何将dxf或dwg等CAD文件与卫星影像地图叠加进行绘图设计?

引言&#xff1a; 在测绘、电力、水利、规划或道路设计等GIS相关行业中&#xff0c;通常会用AutoCAD进行矢量地图数据的绘制&#xff0c;而这些地图数据通常又是建立在投影平面坐标的基础上进行绘制的。 为了确保地图数据的准确性与精度的要求&#xff0c;这些地图数据经常会…

将一个乱序数组变为有序数组的最少交换次数

给定一个包含1-n的数列&#xff0c;通过交换任意两个元素给数列重新排序。求最少需要多少次交换&#xff0c;能把数组排成按1-n递增的顺序 总之就是将这个位置应该出现的元素和这个位置现在的元素交换位置 代码实现&#xff1a; 核心&#xff1a;记住一点&#xff0c;hashmap用…

【debug】时序预测的结果都是一个趋势

时序预测的结果都是一个趋势现象原因solutionother solutions现象 预测的是一个序列。 在测试集中随机取20个来看&#xff0c;所有的预测序列都是一个趋势&#xff0c;但是大小有所区别。 举例图片 原因 目前来看是数据的问题&#xff0c;应该是样本不均衡&#xff0c;某一…

简单个人网页制作 个人介绍网页模板 静态HTML留言表单页面网站模板 大学生个人主页网页

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

[ Linux ] 一篇带你理解Linux下线程概念

目录 1.Linux线程的概念 1.1什么是线程 1.1.1如何验证一个进程内有多个线程&#xff1f; 1.2线程的优点 1.3线程的缺点 1.4 线程异常 1.5 线程用途 2.Linux进程与线程 2.1进程和线程 2.2 进程和线程的关系 2.3如何看待之前学习的单进程&#xff1f; 1.Linux线程的概…

迪杰斯特拉算法求图的最短路径(java)

迪杰斯特拉算法 图的最短路径的解法 单源最短路径 从一个点开始&#xff0c;可以找到其中任意一个点的最短路径。 多源最短路径 从任何一个点开始&#xff0c;可以找到其中任何一个点的最短路径。 解题过程 给定一个带权有向图G(G, V), 另外&#xff0c;还给定 V 中的一…

力扣(LeetCode)1832. 判断句子是否为全字母句(C++)

哈希集合1 哈希集合记录 262626 个字母是否出现&#xff0c;一次遍历字符串&#xff0c;维护哈希集合&#xff0c;同时维护答案。遍历完成&#xff0c;仅当答案等于 262626 &#xff0c;句子是全字母句。 class Solution { public:bool checkIfPangram(string sentence) {boo…

轻松提高性能和并发度,springboot简单几步集成缓存

目录 1、缘由 2、技术介绍 2.1、技术调研 2.2、spring支持的cache 2.3、cache的核心注解 2.3.1 EnableCaching 2.3.2 Cacheable 2.3.3 CachePut 2.3.4 CacheEvict 2.4 cache的架构 2.5 cachemanager的实现类 3、搞个例子 3.1 为什么使用redis 作为缓存 3.2 代码走起…