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

多线程下如何保证事务的一致性

以下是关于Java多线程的详细介绍,适合作为知识博客的内容。我将从基础概念开始,逐步深入到分布式场景、线程池配置以及Spring Cloud集成等高级主题,并提供丰富的业务场景示例。

Java多线程核心概念

1. 线程与进程的区别
  • 进程:程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。
  • 线程:进程中的一个执行单元,是CPU调度和分派的基本单位。一个进程可以包含多个线程。
2. 线程安全性

当多个线程访问共享资源时,若不采取同步措施,可能导致数据不一致或其他异常。常见的线程安全问题包括:

  • 竞态条件(Race Condition):多个线程竞争同一资源导致结果不确定。
  • 内存可见性:一个线程修改了共享变量,其他线程可能无法立即看到最新值。
  • 指令重排序:编译器或处理器为优化性能而重新排序指令,可能影响多线程执行顺序。

保证线程安全的方法

  • 同步机制:使用synchronized关键字或ReentrantLock
  • 原子类:如AtomicIntegerAtomicLong等。
  • volatile关键字:保证变量的可见性。
  • 并发容器:如ConcurrentHashMapCopyOnWriteArrayList等。

线程的创建方式

Java提供了三种创建线程的方式:

1. 继承Thread类
public class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程执行中...");}public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}
}
2. 实现Runnable接口
public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("线程执行中...");}public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start();}
}
3. 实现Callable接口(带返回值)
import java.util.concurrent.*;public class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {return "执行结果";}public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executor = Executors.newSingleThreadExecutor();Future<String> future = executor.submit(new MyCallable());System.out.println(future.get());executor.shutdown();}
}

线程池(ThreadPoolExecutor)

线程池是管理线程的最佳实践,避免频繁创建和销毁线程带来的性能开销。

核心参数
public ThreadPoolExecutor(int corePoolSize,                 // 核心线程数int maximumPoolSize,              // 最大线程数long keepAliveTime,               // 空闲线程存活时间TimeUnit unit,                    // 时间单位BlockingQueue<Runnable> workQueue, // 任务队列ThreadFactory threadFactory,      // 线程工厂RejectedExecutionHandler handler   // 拒绝策略
)
参数作用
  1. corePoolSize:线程池的基本大小,当提交的任务数小于此值时,直接创建新线程执行任务。
  2. maximumPoolSize:线程池允许的最大线程数,当任务队列满且线程数小于此值时,会创建新线程。
  3. keepAliveTime:当线程数大于核心线程数时,多余的空闲线程在终止前等待新任务的最长时间。
  4. workQueue:用于保存等待执行的任务的阻塞队列,常见类型有:
    • ArrayBlockingQueue:有界队列
    • LinkedBlockingQueue:无界队列(需注意OOM风险)
    • SynchronousQueue:直接提交队列
  5. threadFactory:创建线程的工厂,可自定义线程名称、优先级等。
  6. handler:当任务队列和线程池都满时的拒绝策略,默认有四种:
    • AbortPolicy:直接抛出异常(默认)。
    • CallerRunsPolicy:由调用线程处理任务。
    • DiscardPolicy:丢弃最新的任务。
    • DiscardOldestPolicy:丢弃最老的任务。

线程池配置最佳实践

1. 手动配置线程池
import java.util.concurrent.*;public class ThreadPoolConfig {public static ExecutorService createThreadPool() {return new ThreadPoolExecutor(5,                               // 核心线程数10,                              // 最大线程数60,                              // 空闲线程存活时间TimeUnit.SECONDS,new LinkedBlockingQueue<>(100),  // 任务队列大小Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略);}
}
2. Spring Boot自动配置

在Spring Boot项目中,可通过配置文件设置线程池参数:

spring:task:execution:pool:core-size: 5max-size: 10queue-capacity: 100keep-alive: 60sthread-name-prefix: my-task-
3. Spring Cloud中的线程池配置

在微服务架构中,线程池配置需考虑服务间调用的特性:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configuration
public class AsyncConfig {@Bean(name = "asyncExecutor")public ThreadPoolTaskExecutor asyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(50);executor.setQueueCapacity(200);executor.setKeepAliveSeconds(300);executor.setThreadNamePrefix("cloud-async-");executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();return executor;}
}

使用@Async注解启用异步方法:
@Async 是 Spring 框架提供的注解,用于标记一个方法为异步方法。当调用该方法时,Spring 会将其提交到线程池执行,而不是由调用线程同步执行。这在处理耗时操作时非常有用,可以避免阻塞主线程

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
public class MyService {@Async("asyncExecutor")public CompletableFuture<String> processAsync() {// 异步处理逻辑return CompletableFuture.completedFuture("处理完成");}
}

分布式场景下的线程安全

在分布式系统中,仅靠JVM级别的同步机制无法保证线程安全,需引入分布式锁:

1. Redis分布式锁
import redis.clients.jedis.Jedis;public class RedisLock {private static final String LOCK_KEY = "distributed_lock";private static final String RELEASE_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"   return redis.call('del', KEYS[1]) " +"else " +"   return 0 " +"end";private Jedis jedis;public RedisLock(Jedis jedis) {this.jedis = jedis;}public boolean acquireLock(String requestId, int expireTime) {String result = jedis.set(LOCK_KEY, requestId, "NX", "PX", expireTime);return "OK".equals(result);}public boolean releaseLock(String requestId) {Object result = jedis.eval(RELEASE_SCRIPT, 1, LOCK_KEY, requestId);return 1L.equals(result);}
}
2. ZooKeeper分布式锁

使用Apache Curator框架:

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;public class ZookeeperLock {private static final String LOCK_PATH = "/distributed_lock";private InterProcessMutex lock;public ZookeeperLock(String zkConnectString) {CuratorFramework client = CuratorFrameworkFactory.newClient(zkConnectString, new ExponentialBackoffRetry(1000, 3));client.start();lock = new InterProcessMutex(client, LOCK_PATH);}public void acquire() throws Exception {lock.acquire();}public void release() throws Exception {lock.release();}
}

10种需要多线程的业务场景

1. 高并发Web服务器
  • 场景:处理大量HTTP请求,每个请求独立处理。
  • 实现:使用线程池处理请求,避免频繁创建线程。
  • 示例:Tomcat、Netty等服务器的线程模型。
2. 批处理任务
  • 场景:批量处理大量数据(如ETL作业)。
  • 实现:将数据分片,每个线程处理一部分数据。
  • 优势:显著提高处理速度。
3. 异步IO操作
  • 场景:文件读写、网络通信等IO密集型操作。
  • 实现:使用异步线程执行IO操作,主线程继续处理其他任务。
  • 示例:数据库查询、HTTP请求调用。
4. 定时任务调度
  • 场景:定期执行任务(如数据备份、统计报表生成)。
  • 实现:使用ScheduledExecutorService或Spring的@Scheduled注解。
  • 示例:每天凌晨执行数据同步任务。
5. 实时数据处理
  • 场景:实时分析数据流(如日志分析、监控数据处理)。
  • 实现:使用多线程并行处理数据流。
  • 示例:电商平台实时计算商品销量排行。
6. 图形界面应用
  • 场景:保持UI响应性的同时执行耗时操作。
  • 实现:将耗时操作放在后台线程执行。
  • 示例:文件下载进度显示、复杂计算。
7. 分布式缓存更新
  • 场景:缓存失效时,异步更新缓存数据。
  • 实现:使用后台线程重新加载数据到缓存。
  • 优势:避免用户请求等待缓存更新。
8. 消息队列消费者
  • 场景:从消息队列(如Kafka、RabbitMQ)消费消息。
  • 实现:多线程并行消费,提高吞吐量。
  • 示例:订单处理、日志收集。
9. 搜索引擎索引构建
  • 场景:构建大规模索引(如Elasticsearch索引)。
  • 实现:多线程并行处理文档,加速索引构建。
  • 优势:缩短索引构建时间,提高搜索服务可用性。
10. 游戏服务器
  • 场景:处理多个玩家的并发操作。
  • 实现:每个玩家会话由独立线程处理。
  • 示例:多人在线游戏的服务器端逻辑。

线程参数详解

1. 线程优先级(Priority)
  • 作用:控制线程的调度优先级,范围1-10(默认5)。
  • 注意:优先级高的线程更可能被CPU调度,但不保证绝对顺序。
2. 守护线程(Daemon Thread)
  • 作用:为其他线程提供服务(如垃圾回收线程)。
  • 特性:当所有非守护线程结束时,守护线程自动终止。
  • 设置thread.setDaemon(true)必须在start()前调用。
3. 线程状态(State)

Java线程有6种状态:

  • NEW:线程创建但未启动。
  • RUNNABLE:就绪或运行中。
  • BLOCKED:等待获取锁。
  • WAITING:等待其他线程唤醒(如wait())。
  • TIMED_WAITING:定时等待(如sleep(long))。
  • TERMINATED:线程执行完毕。
4. 中断(Interruption)
  • 作用:通知线程应该终止,但线程可选择忽略。
  • 方法
    • thread.interrupt():中断线程。
    • Thread.interrupted():检查并清除中断状态。
    • thread.isInterrupted():检查中断状态。

总结

Java多线程是提升应用性能和响应性的关键技术,但需谨慎处理线程安全问题。在分布式场景中,需结合分布式锁等机制确保跨节点的一致性。合理配置线程池参数和选择合适的业务场景应用多线程,能显著提升系统吞吐量和用户体验。
在异步执行的场景下保证事务有效性是一个常见的挑战,因为Spring的事务管理基于线程绑定的TransactionSynchronizationManager,而异步方法会在独立线程中执行,导致事务上下文丢失。以下是详细解决方案:

问题根源

Spring事务依赖于线程上下文传递事务信息。当使用@Async时,方法在新线程中执行,与调用线程不在同一个事务上下文:

  1. 事务管理器失效:新线程没有绑定事务上下文。
  2. 数据库连接丢失:每个线程使用独立的数据库连接。
  3. 异常回滚失效:异步线程的异常无法触发调用线程的事务回滚。

解决方案

1. 独立事务(推荐)

为每个异步方法创建独立的事务,适用于可容忍部分失败的场景(如批量处理)。

配置示例

@Service
public class AsyncService {@Async("asyncExecutor")@Transactional(propagation = Propagation.REQUIRES_NEW)  // 创建新事务public CompletableFuture<Void> processData(Long recordId) {// 数据库操作repository.updateStatus(recordId, "PROCESSING");try {// 业务逻辑complexProcessing(recordId);repository.updateStatus(recordId, "SUCCESS");return CompletableFuture.completedFuture(null);} catch (Exception e) {repository.updateStatus(recordId, "FAILED");throw new RuntimeException("处理失败", e);  // 触发当前事务回滚}}
}

特点

  • 每个异步任务独立提交/回滚。
  • 适合批量处理大量数据,部分失败不影响整体。
2. 事件驱动架构

将异步操作转为事件,主线程提交事务后再处理事件,确保数据一致性。

实现步骤

  1. 定义事件
public class DataProcessEvent {private final Long recordId;public DataProcessEvent(Long recordId) { this.recordId = recordId; }// getter
}
  1. 发布事件(在事务内)
@Service
public class MainService {@Autowiredprivate ApplicationEventPublisher eventPublisher;@Transactionalpublic void createAndProcessData() {// 创建记录(事务内)Long recordId = repository.save(new Record()).getId();// 发布事件(事务提交后触发)eventPublisher.publishEvent(new DataProcessEvent(recordId));}
}
  1. 异步监听事件
@Component
public class DataProcessListener {@Async@EventListenerpublic void handleDataProcessEvent(DataProcessEvent event) {// 异步处理(无事务)processData(event.getRecordId());}
}

特点

  • 事务提交后才触发异步处理。
  • 适合耗时操作不影响主线程事务的场景。
3. 手动管理事务(高级)

在异步方法中手动获取和管理事务,适用于强一致性要求的场景。

示例代码

@Service
public class ManualTransactionService {@Autowiredprivate PlatformTransactionManager transactionManager;@Autowiredprivate TransactionDefinition transactionDefinition;@Async("asyncExecutor")public CompletableFuture<Void> processWithManualTx(Long recordId) {TransactionStatus status = transactionManager.getTransaction(transactionDefinition);try {// 数据库操作repository.updateStatus(recordId, "PROCESSING");complexProcessing(recordId);// 手动提交事务transactionManager.commit(status);return CompletableFuture.completedFuture(null);} catch (Exception e) {// 手动回滚事务transactionManager.rollback(status);throw new RuntimeException("处理失败", e);}}
}

特点

  • 完全控制事务边界。
  • 代码复杂度高,需谨慎处理异常。
4. 补偿事务(最终一致性)

通过补偿机制保证最终一致性,适用于分布式系统。

实现方案

  1. 记录操作日志:在主事务中记录所有操作。
  2. 异步执行:调用外部服务或执行复杂逻辑。
  3. 补偿逻辑:若异步操作失败,根据日志执行反向操作。

示例代码

@Service
public class CompensationService {@Transactionalpublic void createOrderWithCompensation(Order order) {// 1. 创建订单(主事务)Order savedOrder = orderRepository.save(order);// 2. 记录补偿日志(主事务)compensationLogRepository.save(new CompensationLog(savedOrder.getId(), "CREATE_ORDER", savedOrder));// 3. 异步处理库存、支付等(无事务)asyncService.processOrderAsync(savedOrder.getId());}
}@Service
public class AsyncService {@Asyncpublic void processOrderAsync(Long orderId) {try {// 扣减库存、调用支付等操作inventoryService.debitStock(orderId);paymentService.processPayment(orderId);} catch (Exception e) {// 触发补偿逻辑compensationService.rollbackOrder(orderId);}}
}

特点

  • 保证最终一致性,而非强一致性。
  • 适合跨服务、跨系统的操作。

最佳实践总结

  1. 优先使用独立事务:为每个异步任务创建独立事务,通过状态跟踪失败记录。
  2. 避免长事务:将耗时操作移出事务,减少锁持有时间。
  3. 使用可靠消息队列:如RabbitMQ、Kafka,确保事件不丢失。
  4. 实现幂等性:异步操作需支持重试(如唯一索引、状态校验)。
  5. 监控与告警:记录异步任务状态,及时发现并处理失败。

常见误区

  1. 错误配置传播行为

    • 使用Propagation.REQUIRED(默认)会导致异步方法加入调用者的事务(但实际上无法加入)。
    • 必须使用Propagation.REQUIRES_NEW创建新事务。
  2. 忽略异步异常

    • 未捕获的异常会导致事务无法回滚。
    • 确保在异步方法中处理异常或使用CompletableFuture的异常处理。
  3. 过度依赖同步事务

    • 在分布式系统中,强一致性难以实现,考虑最终一致性方案。

通过合理选择事务管理策略,结合异步编程模型,可以在保证系统性能的同时,有效维护数据一致性。

相关文章:

多线程下如何保证事务的一致性

以下是关于Java多线程的详细介绍&#xff0c;适合作为知识博客的内容。我将从基础概念开始&#xff0c;逐步深入到分布式场景、线程池配置以及Spring Cloud集成等高级主题&#xff0c;并提供丰富的业务场景示例。 Java多线程核心概念 1. 线程与进程的区别 进程&#xff1a;程…...

OpenCv高阶(8.0)——答题卡识别自动判分

文章目录 前言一、代码分析及流程讲解&#xff08;一&#xff09;初始化模块正确答案映射字典&#xff08;题目序号: 正确选项索引&#xff09;图像显示工具函数 &#xff08;二&#xff09;轮廓处理工具模块&#xff08;三&#xff09;几何变换核心模块 二、主处理流程图像读取…...

量子通信技术:原理、应用与未来展望

在当今数字化时代&#xff0c;信息安全是全球关注的焦点。随着量子计算技术的飞速发展&#xff0c;传统的加密方法面临着前所未有的挑战。量子通信技术作为一种新兴的通信手段&#xff0c;以其绝对安全的特性&#xff0c;为信息安全领域带来了新的希望。本文将深入探讨量子通信…...

Token的组成详解:解密数字身份凭证的构造艺术

在当今的互联网身份认证体系中&#xff0c;Token如同数字世界的"安全护照"&#xff0c;承载着用户的身份信息和访问权限。据统计&#xff0c;现代应用中80%以上的身份验证依赖于Token机制。本文将深入解析Token的各个组成部分&#xff0c;通过典型实例揭示其设计原理…...

【SFT监督微调总结】大模型SFT全解析:从原理到工具链,解锁AI微调的核心密码

文章目录 一. 什么是监督微调(SFT)?二. SFT的核心原理与流程2.1 基本原理2.2 训练流程三、SFT训练的常用方法四、SFT训练用的数据格式4.1、基础单轮指令格式1. Alpaca 格式2. 单轮QA格式3. 代码-注释对4.2、多轮对话格式1. ShareGPT 格式2. 层次化对话格式3. 角色扮演对话4.…...

MacBook Air A2179(Intel版)安装macOS Catalina所需时间

MacBook Air A2179&#xff08;Intel版&#xff09;安装macOS Catalina所需时间如下&#xff1a; 一、标准安装时间范围 常规安装&#xff08;通过App Store&#xff09; • 下载时间&#xff1a;约30-60分钟&#xff08;取决于网络速度&#xff0c;安装包约8GB&#xff09; •…...

Git的windows开发与linux开发配置

Git的基本配置 安装 linux可以使用包管理器安装windows可以使用 mingw的git&#xff1a;https://git-scm.com/downloadsTortoiseGit&#xff1a;https://tortoisegit.org/download/ 配置 分为系统配置–system、全局配置–global、项目配置–local 配置名称和邮箱 git co…...

使用Mathematica绘制一类矩阵的特征值图像

学习过线性代数的&#xff0c;都知道&#xff1a;矩阵的特征值非常神秘&#xff0c;但却携带着矩阵的重要信息。 今天&#xff0c;我们将展示&#xff1a;一类矩阵&#xff0c;其特征值集体有着很好的分布特征。 modifiedroots[c_List] : Block[{a DiagonalMatrix[ConstantAr…...

C++中的宏

0 资料 最值宏do{}while(0)的宏封装技巧 1 最值宏 - C最值的宏&#xff0c;在两个头文件中&#xff0c;分别为cfloat和climits。其中&#xff0c;float的最值宏在cfloat中&#xff0c;且cfloat没有负值的最小宏&#xff0c;而其他char、int和double是在climits中。如下// --…...

谷粒商城的三级分类实现

先查出全部的数据再分类 分类的一级分类是根据数据的Parent_id进行确定的&#xff0c;所以要进行筛选&#xff1a; 主方法&#xff1a; public List<CategoryEntity> listWithTree() {//1.查出所有分类List<CategoryEntity> entities baseMapper.selectList(nul…...

基于大模型预测的闭合性髌骨骨折诊疗全流程研究报告

目录 一、引言 1.1 研究背景与目的 1.2 研究意义与价值 二、大模型预测原理与方法 2.1 大模型概述 2.2 预测方法与数据输入 2.3 模型训练与优化 三、术前预测分析 3.1 骨折类型预测 3.2 损伤程度评估 3.3 潜在风险预测 四、手术方案制定 4.1 传统手术方案对比 4.…...

基于CodeBuddy的Craft完成一个数字华容道的小游戏

参考 CodeBuddy&#xff0c;AI 时代的智能编程伙伴 插件功能入门 总结 本文主要基于CodeBuddy的Craft 完成一个数字华容道的小游戏&#xff0c;如果读者还不清楚怎么安装&#xff0c;在本文的前面附上了CodeBuddy 编程助手的安装步骤。读者可以根据需求自行确定从那开始。 …...

一文掌握vue3基础,适合自学入门案例丰富

Vue3 本文从Vue3的基础语法出发&#xff0c;全面系统的介绍了Vue3的核心概念与应用&#xff0c;旨在帮助自学者更轻松地掌握Vue3。文章内容由浅入深&#xff0c;从通过CDN引入Vue3开始&#xff0c;逐步介绍了组合式API、模块化开发、以及常见的Vue3指令和功能并从单个html的使…...

OpenHarmony 5.0设置应用设置手势导航开关打开后重新关闭导航栏和设置界面重合

目录 1.背景 2.解决方案 1.背景 在OpenHarmony 5.0中从设置界面打开手势导航开关然后重新关闭&#xff0c;此时设置界面导航栏和设置列表主界面重合&#xff0c;导致设置界面无法点击最下面的关于设备 2.解决方案 首先参考之前的如何设置导航栏文档&#xff0c;我们可以自己…...

[ARM][汇编] 02.ARM 汇编常用简单指令

目录 1.数据传输指令 MRS - Move from Status Register 指令用途 指令语法 代码示例 读取 CPSR 到通用寄存器 在异常处理程序中读取 SPSR 使用场景 MSR - Move to Status Register 指令语法 使用场景 示例代码 改变处理器模式为管理模式 设置条件标志位 异常处理…...

系统架构设计(十七):微服务数据一致性和高可用策略

数据一致性问题 问题本质 由于每个微服务拥有独立数据库&#xff0c;跨服务操作不能用传统的数据库事务&#xff0c;面临“分布式事务”一致性挑战。 数据一致性策略 策略核心思想应用场景优缺点强一致性&#xff08;Strong Consistency&#xff09;所有操作实时同步成功&a…...

[Harmony]获取设备参数

获取屏幕宽度/屏幕高度/状态栏高度/导航栏高度/刘海高度/设备型号/系统版本号... DevicesUtil import window from ohos.window; import { common } from kit.AbilityKit; import display from ohos.display; import deviceInfo from ohos.deviceInfo; import i18n from ohos.…...

Python60日基础学习打卡D31

如何把一个文件&#xff0c;拆分成多个具有着独立功能的文件&#xff0c;然后通过import的方式&#xff0c;来调用这些文件&#xff1f;这样具有几个好处&#xff1a; 可以让项目文件变得更加规范和清晰可以让项目文件更加容易维护&#xff0c;修改某一个功能的时候&#xff0…...

命名常量集合接口INamedConstantCollection<T>实现

public interface INamedConstantCollection<TObject, TName> : IEnumerable<TObject>, IEnumerable where TName : IComparable{TObject this[TName name] { get; }TObject this[int index] { get; }int Count { get; }int Capacity { get; }} 这是一个泛型接口&…...

TYUT-企业级开发教程-第6章

这一章 考点不多 什么是缓存&#xff1f;为什么要设计出缓存&#xff1f; 企业级应用为了避免读取数据时受限于数据库的访问效率而导致整体系统性能偏低&#xff0c;通 常会在应用程序与数据库之间建立一种临时的数据存储机制&#xff0c;该临时存储数据的区域称 为缓存。缓存…...

反射在spring boot自动配置的应用

目录 一&#xff0c;背景 二&#xff0c;知识回顾 2.1 理解使用反射技术&#xff0c;读取配置文件创建目标对象&#xff08;成员变量&#xff0c;方法&#xff0c;构造方法等&#xff09; 三&#xff0c;springboot自动配置 3.1 反射在自动配置中的工作流程 3.2 浏览源码…...

项目进度延误,如何按时交付?

项目进度延误可以通过加强计划管理、优化资源分配、强化团队沟通、设置关键里程碑和风险管理机制等方式来实现按时交付。加强计划管理、优化资源分配、强化团队沟通、设置关键里程碑、风险管理机制。其中&#xff0c;加强计划管理尤为关键&#xff0c;因为明确而详细的计划能提…...

内网穿透:轻松实现外网访问本地服务

异步通知的是需要通过外网的域名地址请求到的&#xff0c;由于我们还没有真正上线&#xff0c;那支付平台如何请求到我们本地服务的呢&#xff1f; 这里可以使用【内网穿透】技术来实现&#xff0c;通过【内网穿透软件】将内网与外网通过隧道打通&#xff0c;外网可以读取内网…...

缺乏进度跟踪机制,如何掌握项目状态?

要有效掌握项目状态&#xff0c;必须建立明确的进度跟踪机制、使用专业的项目管理工具、定期召开沟通会议、设立清晰的关键里程碑和实施风险监控。其中&#xff0c;建立明确的进度跟踪机制是关键&#xff0c;通过系统地追踪项目各个阶段的完成情况&#xff0c;及时发现问题并采…...

ES 调优帖:关于索引合并参数 index.merge.policy.deletePctAllowed 的取值优化

最近发现了 lucene 9.5 版本把 merge 策略的默认参数改了。 * GITHUB#11761: TieredMergePolicy now allowed a maximum allowable deletes percentage of down to 5%, and the defaultmaximum allowable deletes percentage is changed from 33% to 20%. (Marc DMello)也就是…...

基于 STM32 单片机的实验室多参数安全监测系统设计与实现

一、系统总体设计 本系统以 STM32F103C8T6 单片机为核心,集成温湿度监测、烟雾检测、气体泄漏报警、人体移动监测等功能模块,通过 OLED 显示屏实时显示数据,并支持 Wi-Fi 远程传输。系统可对实验室异常环境参数(如高温、烟雾、燃气泄漏)及非法入侵实时报警,保障实验室安…...

Spring Boot-Swagger离线文档(插件方式)

Swagger2Markup简介 Swagger2Markup是Github上的一个开源项目。该项目主要用来将Swagger自动生成的文档转换成几种流行的格式以便于静态部署和使用&#xff0c;比如&#xff1a;AsciiDoc、Markdown、Confluence。 项目主页&#xff1a;https://github.com/Swagger2Markup/swagg…...

Linux下Docker使用阿里云镜像加速器

在中国大陆环境中配置 Docker 使用阿里云镜像加速器&#xff0c;并确保通过 Clash 代理访问 Docker Hub 我这里用的Debian12。 步骤 1&#xff1a;获取阿里云镜像加速器地址 登录阿里云容器镜像服务控制台&#xff1a;(qinyang.wang) 网址&#xff1a;阿里云登录 - 欢迎登录阿…...

每日c/c++题 备战蓝桥杯(洛谷P1440 求m区间内的最小值 详解(单调队列优化))

洛谷P1440 求m区间最小值&#xff1a;单调队列优化详解&#xff08;从暴力到O(n)的蜕变&#xff09; tags: [算法, 数据结构, 滑动窗口, 洛谷, C] 引言 在处理序列数据的区间查询问题时&#xff0c;暴力枚举往往难以应对大规模数据。本文以洛谷P1440为切入点&#xff0c;深入…...

从代码学习深度学习 - 预训练word2vec PyTorch版

文章目录 前言辅助工具1. 绘图工具 (`utils_for_huitu.py`)2. 数据处理工具 (`utils_for_data.py`)3. 训练辅助工具 (`utils_for_train.py`)预训练 Word2Vec - 主流程1. 环境设置与数据加载2. 跳元模型 (Skip-gram Model)2.1. 嵌入层 (Embedding Layer)2.2. 定义前向传播3. 训练…...

OpenCV图像边缘检测

1.概念 图像边缘检测是计算机视觉和图像处理中的基础任务&#xff0c;用于识别图像中像素值发生剧烈变化的区域&#xff0c;这些区域通常对应物体的边界、纹理变化或噪声。 1.1原理 图像中的边缘通常表现为灰度值的突变&#xff08;如从亮到暗或从暗到亮的急剧变化&#xff09…...

AI能源危机:人工智能发展与环境可持续性的矛盾与解决之道

AI对能源的渴求正在演变成一个巨大的挑战。这不仅仅关乎电费支出&#xff0c;其环境影响也十分严重&#xff0c;包括消耗宝贵的水资源、产生大量电子垃圾&#xff0c;以及增加温室气体排放。 随着AI模型变得越来越复杂并融入我们生活的更多领域&#xff0c;一个巨大的问题悬而…...

基于flask+vue的电影可视化与智能推荐系统

基于flaskvue爬虫的电影数据的智能推荐与可视化系统&#xff0c;能展示电影评分、评论情感分析等直观的数据可视化图表&#xff0c;还能通过协同过滤算法为用户提供个性化电影推荐&#xff0c;帮助用户发现更多感兴趣的电影作品&#xff0c;具体界面如图所示。 本系统主要技术架…...

初步认识HarmonyOS NEXT端云一体化开发

视频课程学习报名入口:HarmonyOS NEXT端云一体化开发 1、课程设计理念 本课程采用"四维能力成长模型"设计理念,通过“能看懂→能听懂→能上手→能实战”的渐进式学习路径,帮助零基础开发者实现从理论认知到商业级应用开发的跨越。该模型将学习过程划分为四个维度…...

基于单片机的车辆防盗系统设计与实现

标题:基于单片机的车辆防盗系统设计与实现 内容:1.摘要 随着汽车保有量的不断增加&#xff0c;车辆被盗问题日益严峻&#xff0c;车辆防盗成为人们关注的焦点。本研究的目的是设计并实现一种基于单片机的车辆防盗系统。采用单片机作为核心控制单元&#xff0c;结合传感器技术、…...

LSM Tree算法原理

LSM Tree(Log-Structured Merge Tree)是一种针对写密集型场景优化的数据结构,广泛应用于LevelDB、RocksDB等数据库引擎中。其核心原理如下: ‌1. 写入优化:顺序写代替随机写‌ ‌内存缓冲(MemTable)‌:写入操作首先被写入内存中的数据结构(如跳表或平衡树),…...

通过 API 获取 1688 平台店铺所有商品信息的完整流程

在电商运营和数据分析中&#xff0c;获取 1688 平台店铺的商品信息是一项重要的任务。1688 作为国内领先的 B2B 电商平台&#xff0c;提供了丰富的开放平台 API 接口&#xff0c;方便开发者获取店铺商品的详细信息。本文将详细介绍如何通过 Python 调用 1688 的 API 接口&#…...

Python代码加密与发布方案详解

更多内容请见: python3案例和总结-专栏介绍和目录 文章目录 一、基础加密方案二、商业级加密方案三、高级混淆方案四、商业化发布方案五、反逆向技术六、最佳实践建议七、常见问题解决Python作为解释型语言,其源代码容易被查看和修改。本文将详细介绍多种Python代码保护方案,…...

Tractor S--二维转一维,然后最小生成树

P3073 [USACO13FEB] Tractor S - 洛谷 转成一维点图&#xff0c;然后最小生成树&#xff0c;最后的最大值就是最后一个点&#xff0c;记得记录维护连通块 同样的二维转一维---Cow Ski Area G---二维图转一维tarjan缩点-CSDN博客 #include<bits/stdc.h> using namespac…...

5月20日day31打卡

文件的规范拆分和写法 知识点回顾 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 作业&#xff1a;尝试针对之前的心脏病项目&#xff0c;准备拆分的项目文件&#xff0c;思考下哪些部分可以未来复用。 补充介绍&#xff1a; pyc文件的介绍 知识点回顾 …...

基于Spring Boot + Vue的教师工作量管理系统设计与实现

一、项目简介 随着高校信息化管理的发展&#xff0c;教师工作量管理成为教务系统中不可或缺的一部分。为此&#xff0c;我们设计并开发了一个基于 Spring Boot Vue 的教师工作量管理系统&#xff0c;系统结构清晰&#xff0c;功能完备&#xff0c;支持管理员和教师两个角色。…...

海康工业相机白平衡比选择器对应的值被重置后,如何恢复原成像

做项目的时候&#xff0c;有时候手抖&#xff0c;一不小心把一个成熟稳定的项目的相机配置&#xff0c;重置了&#xff0c;如何进行恢复呢&#xff0c;在不知道之前配置数据的情况下。 我在做项目的时候&#xff0c;为了让这个相机成像稳定一点&#xff0c;尤其是做颜色检测时…...

VMWare清理后,残留服务删除方案详解

VMWare清理后&#xff0c;残留服务删除方案详解 在虚拟化技术日益普及的今天&#xff0c;VMWare作为行业领先的虚拟化软件&#xff0c;广泛应用于企业和服务器的管理中。然而&#xff0c;由于其复杂的架构和深层次的系统集成&#xff0c;VMWare的卸载过程往往并不顺利。即使通…...

STM32定时器简单采集编码器脉冲

MCU&#xff1a;STM32H723ZGT6 编码器&#xff1a;&#xff08;欧姆龙&#xff09;E6B2-CWZ1X&#xff1b;1000P/R&#xff1b;8根线信号线分别为 A A- B B- Z Z- 以及5V和GND&#xff1b; A 脉冲输出 B 脉冲输出 Z 零点信号 当编码器旋转到零点时&#xff0c;Z信号会发出一个脉…...

第 4 章:网络与总线——CAN / Ethernet / USB-OTG

本章目标: 深入理解三种关键通信总线(CAN、Ethernet、USB-OTG)的协议架构、硬件接口与软件驱动 掌握 STM32(或同类 MCU)中各总线的寄存器配置、中断/DMA 驱动框架 通过实战案例,实现基于 CAN 总线的节点通信、基于 Ethernet 的 TCP/IP 通信,以及基于 USB-OTG 的虚拟串口…...

【python进阶知识】Day 31 文件的规范拆分和写法

知识点 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 机器学习流程 - 数据加载&#xff1a;从文件、数据库、API 等获取原始数据。 - 命名参考&#xff1a;load_data.py 、data_loader.py - 数据探索与可视化&#xff1a;了解数据特性&#xff0c;初期…...

leetcode 162. Find Peak Element

题目描述 如果nums[i-1]<nums[i]并且nums[i]>nums[i1]&#xff0c;那么nums[i]就是峰值。除此情况之外&#xff0c;nums[i-1]和nums[i1]至少有一个大于nums[i]&#xff0c;因为题目已经保证相邻的元素不相等。坚持向上坡方向走一定能达到一个峰值&#xff0c;如果往两边走…...

2025系统架构师---案例题(押题)

1. 微服务相关的概念: 微服务是一种架构风格,它将单体应用划分为一组小服务,服务之间相互协作,实现业务功能每个服务运行在独立的进程中,服务间采用轻量级的通信机制协作(通常是HTTP/JSON),每个服务围绕业务能力进行构建,并且能够通过自动化机制独立的部署。 微服务有…...

t检验详解:原理、类型与应用指南

t检验详解&#xff1a;原理、类型与应用指南 t检验&#xff08;t-test&#xff09;是一种用于比较两组数据均值是否存在显著差异的统计方法&#xff0c;适用于数据近似正态分布且满足方差齐性的场景。以下从核心原理、检验类型、实施步骤到实际应用进行系统解析。 一、t检验的…...

使用 OpenCV 实现万花筒效果

万花筒效果&#xff08;Kaleidoscope Effect&#xff09;是一种图像处理效果&#xff0c;通过对图像进行对称旋转或镜像处理&#xff0c;产生具有多重反射和对称的艺术效果。它常用于视频编辑、视觉艺术、游戏设计等领域&#xff0c;为图像添加富有创意和视觉冲击力的效果。 在…...