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

乐观锁与悲观锁的使用场景

悲观锁的应用场景
悲观锁的基本思想是假设并发冲突会发生,因此在操作数据时会先锁定数据,直到完成操作并提交事务后才释放锁。这种方式适用于写操作较多、并发冲突可能性较高的场景。

高写入比例的数据库操作:如果系统中有很多写操作,并且这些写操作可能会频繁地相互干扰,那么使用悲观锁可以有效避免数据不一致的问题。
对数据一致性要求高的场景:比如金融交易系统,银行转账,高并发点赞等,需要确保在任何时刻的数据都是一致的,不允许出现脏读、不可重复读等问题。
乐观锁的应用场景
乐观锁则假定并发冲突不会经常发生,因此它不会在开始操作时就锁定资源,而是在提交更新时检查是否有其他事务已经修改了该数据。如果检测到冲突,则拒绝此次操作。乐观锁更适用于读多写少的环境。

读操作远多于写操作的场景:例如在线阅读平台、新闻网站等,这类应用主要以读取信息为主,很少会有数据修改的需求,采用乐观锁可以减少锁带来的性能损耗。
低冲突概率的环境:当系统预期不同事务之间很少会对同一数据进行修改时,使用乐观锁可以获得更好的性能表现。比如库存管理系统中,对于非热销商品的库存调整。
选择哪种锁机制应基于具体的应用场景以及系统对性能和一致性的需求来决定。在实际开发过程中,还需要考虑死锁预防、锁的粒度等因素。

点赞悲观锁实现

以下是基于 Java 和 MyBatis-Plus 实现悲观锁的点赞功能的完整代码示例。

1. 数据库表设计

假设我们有一个 articles 表,包含以下字段:

id: 文章唯一标识。
title: 文章标题。
content: 文章内容。
likes: 点赞数。
sql
深色版本
CREATE TABLE articles (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
likes INT DEFAULT 0
);

2. 配置 MyBatis-Plus 和数据库连接

2.1 添加依赖
在 pom.xml 文件中添加 MyBatis-Plus 和 MySQL 驱动依赖(与之前一致)。

2.2 配置数据库连接
在 application.yml 中配置数据库连接信息(与之前一致)。

3. 实体类和 Mapper 接口

3.1 创建实体类
java
深色版本

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("articles")
public class Article {@TableIdprivate Long id;private String title;private String content;private Integer likes;
}

3.2 创建 Mapper 接口
java
深色版本

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;@Mapper
public interface ArticleMapper extends BaseMapper<Article> {/*** 悲观锁查询文章*/@Select("SELECT * FROM articles WHERE id = #{id} FOR UPDATE")Article selectForUpdate(Long id);/*** 更新点赞数*/@Update("UPDATE articles SET likes = likes + 1 WHERE id = #{id}")int incrementLikes(Long id);
}

4. 实现点赞功能

4.1 Service 层实现
悲观锁的核心在于使用 FOR UPDATE 锁定数据行,确保在事务提交前其他事务无法修改该行数据。

java
深色版本

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 使用悲观锁实现点赞*/@Transactional // 开启事务public String likeArticle(Long articleId) {// 使用悲观锁查询文章(锁定该行)Article article = articleMapper.selectForUpdate(articleId);if (article == null) {return "Article not found";}// 更新点赞数int rows = articleMapper.incrementLikes(articleId);if (rows > 0) {return "Like successful, new likes: " + (article.getLikes() + 1);} else {return "Failed to update likes";}}
}

4.2 Controller 层实现
java
深色版本

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/articles")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 点赞接口*/@PostMapping("/{id}/like")public String likeArticle(@PathVariable Long id) {return articleService.likeArticle(id);}
}

5. 测试接口

启动 Spring Boot 应用后,可以通过以下方式测试点赞功能:

请求示例
bash
深色版本
POST http://localhost:8080/articles/1/like
响应结果
成功时返回:“Like successful, new likes: X”
如果文章不存在,返回:“Article not found”

6. 核心原理

悲观锁的工作流程:
在查询文章时,使用 FOR UPDATE 锁定目标数据行。
在事务提交之前,其他事务无法对该行数据进行修改。
更新点赞数后提交事务,释放锁。
SQL 示例:
sql
深色版本
– 查询并锁定数据行
SELECT * FROM articles WHERE id = 1 FOR UPDATE;

– 更新点赞数
UPDATE articles SET likes = likes + 1 WHERE id = 1;
适用场景:
适用于写操作较多且并发冲突概率较高的场景。
例如,在高并发环境下对同一篇文章进行频繁点赞时,可以避免数据不一致的问题。

7. 注意事项

性能开销:
悲观锁会锁定数据行,可能导致其他事务阻塞,影响系统性能。
因此,只有在确实需要严格保证数据一致性时才使用悲观锁。
死锁风险:
如果多个事务同时尝试锁定不同的资源,可能会导致死锁。
需要合理设计事务逻辑,尽量减少死锁的可能性。
事务管理:
必须确保在事务中执行锁定和更新操作,否则锁定不起作用。
通过以上代码,我们可以利用悲观锁实现点赞功能,确保在高并发场景下的数据一致性。

点赞乐观锁实现

以下是使用 Java 和 MyBatis-Plus 实现乐观锁的代码示例。我们将基于 Spring Boot 和 MyBatis-Plus 框架完成点赞功能。

1. 数据库表设计

假设我们有一个 articles 表,包含以下字段:

id: 文章唯一标识。
title: 文章标题。
content: 文章内容。
likes: 点赞数。
version: 版本号(用于乐观锁)。
sql
深色版本
CREATE TABLE articles (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
likes INT DEFAULT 0,
version INT DEFAULT 0
);

2. 配置 MyBatis-Plus 和数据库连接

2.1 添加依赖
在 pom.xml 文件中添加 MyBatis-Plus 和 MySQL 驱动依赖:

xml
深色版本



org.springframework.boot
spring-boot-starter-web

<!-- MyBatis-Plus -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency><!-- MySQL Driver -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency><!-- Lombok (Optional for code simplification) -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
2.2 配置数据库连接 在 application.yml 中配置数据库连接信息:

yaml
深色版本
spring:
datasource:
url: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: your_username
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
mapper-locations: classpath:/mapper/*.xml
configuration:
map-underscore-to-camel-case: true

3. 实体类和 Mapper 接口

3.1 创建实体类
使用 @Version 注解来标识版本号字段。

java
深色版本

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;@Data
@TableName("articles")
public class Article {@TableIdprivate Long id;private String title;private String content;private Integer likes;@Versionprivate Integer version; // 版本号字段,用于乐观锁
}

3.2 创建 Mapper 接口
继承 MyBatis-Plus 提供的 BaseMapper 接口。

java
深色版本

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface ArticleMapper extends BaseMapper<Article> {
}

4. 配置乐观锁插件

在 Spring Boot 启动类中配置 MyBatis-Plus 的乐观锁插件。

java
深色版本

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
}

5. 实现点赞功能

5.1 Service 层实现
编写点赞逻辑,使用乐观锁更新点赞数。

java
深色版本

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;public String likeArticle(Long articleId) {// 查询文章信息Article article = articleMapper.selectById(articleId);if (article == null) {return "Article not found";}// 更新点赞数和版本号article.setLikes(article.getLikes() + 1);// 使用 MyBatis-Plus 自动处理乐观锁int rows = articleMapper.updateById(article);if (rows > 0) {return "Like successful, new likes: " + article.getLikes();} else {return "Optimistic lock conflict, please try again";}}
}

5.2 Controller 层实现
提供 RESTful API 接口。

java
深色版本

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/articles")
public class ArticleController {@Autowiredprivate ArticleService articleService;@PostMapping("/{id}/like")public String likeArticle(@PathVariable Long id) {return articleService.likeArticle(id);}
}

6. 测试接口

启动 Spring Boot 应用后,可以通过以下方式测试点赞功能:

请求示例
bash
深色版本
POST http://localhost:8080/articles/1/like
响应结果
成功时返回:“Like successful, new likes: X”
如果发生乐观锁冲突,返回:“Optimistic lock conflict, please try again”

7. 核心原理

乐观锁的核心思想:
在更新数据时,MyBatis-Plus 会自动检查 version 字段是否匹配。
如果匹配,则更新数据并递增 version。
如果不匹配,则更新失败,返回受影响行数为 0。
SQL 示例:
sql
深色版本
UPDATE articles
SET likes = likes + 1, version = version + 1
WHERE id = 1 AND version = current_version;
适用场景:
适用于读多写少且冲突概率较低的场景,如点赞、评论、浏览量统计等。
通过以上代码,我们可以轻松实现基于 MyBatis-Plus 的乐观锁功能,确保在高并发场景下的数据一致性。

银行转账悲观锁实现

在银行转账的场景中,悲观锁是一种非常合适的并发控制机制。由于银行转账涉及资金的流动,数据一致性至关重要,因此使用悲观锁可以确保在事务完成之前,相关账户不会被其他事务修改。

以下是基于 Java 和 MyBatis-Plus 实现银行转账功能的完整代码示例,其中使用了悲观锁来保证事务的安全性。

1. 数据库表设计

假设我们有一个 accounts 表,用于存储用户账户信息:

id: 账户唯一标识。
user_name: 用户名。
balance: 账户余额。
sql
深色版本
CREATE TABLE accounts (
id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(255) NOT NULL,
balance DECIMAL(10, 2) NOT NULL DEFAULT 0.00
);

2. 配置 MyBatis-Plus 和数据库连接

2.1 添加依赖
在 pom.xml 文件中添加 MyBatis-Plus 和 MySQL 驱动依赖(与之前一致)。

2.2 配置数据库连接
在 application.yml 中配置数据库连接信息:

yaml
深色版本
spring:
datasource:
url: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: your_username
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
mapper-locations: classpath:/mapper/*.xml
configuration:
map-underscore-to-camel-case: true

3. 实体类和 Mapper 接口

3.1 创建实体类
java
深色版本

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.math.BigDecimal;@Data
@TableName("accounts")
public class Account {@TableIdprivate Long id;private String userName;private BigDecimal balance;
}

3.2 创建 Mapper 接口
java
深色版本

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;@Mapper
public interface AccountMapper extends BaseMapper<Account> {/*** 悲观锁查询账户*/@Select("SELECT * FROM accounts WHERE id = #{id} FOR UPDATE")Account selectForUpdate(Long id);/*** 更新账户余额*/@Update("UPDATE accounts SET balance = balance + #{amount} WHERE id = #{id}")int updateBalance(Long id, BigDecimal amount);
}

4. 实现转账功能

4.1 Service 层实现
悲观锁的核心在于使用 FOR UPDATE 锁定账户行,确保在事务提交前其他事务无法修改账户余额。

java
深色版本

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.math.BigDecimal;@Service
public class AccountService {@Autowiredprivate AccountMapper accountMapper;/*** 使用悲观锁实现转账** @param fromAccountId 转出账户 ID* @param toAccountId   转入账户 ID* @param amount        转账金额*/@Transactional // 开启事务public String transfer(Long fromAccountId, Long toAccountId, BigDecimal amount) {if (amount.compareTo(BigDecimal.ZERO) <= 0) {return "Invalid transfer amount";}// 查询转出账户并加锁Account fromAccount = accountMapper.selectForUpdate(fromAccountId);if (fromAccount == null || fromAccount.getBalance().compareTo(amount) < 0) {return "Insufficient balance or invalid account";}// 查询转入账户并加锁Account toAccount = accountMapper.selectForUpdate(toAccountId);if (toAccount == null) {return "Invalid target account";}// 执行转账操作accountMapper.updateBalance(fromAccountId, amount.negate()); // 减少转出账户余额accountMapper.updateBalance(toAccountId, amount); // 增加转入账户余额return "Transfer successful";}
}

4.2 Controller 层实现
java
深色版本

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.math.BigDecimal;@RestController
@RequestMapping("/accounts")
public class AccountController {@Autowiredprivate AccountService accountService;/*** 转账接口*/@PostMapping("/transfer")public String transfer(@RequestParam Long fromAccountId,@RequestParam Long toAccountId,@RequestParam BigDecimal amount) {return accountService.transfer(fromAccountId, toAccountId, amount);}
}

5. 测试接口

启动 Spring Boot 应用后,可以通过以下方式测试转账功能:

请求示例
bash
深色版本
POST http://localhost:8080/accounts/transfer?fromAccountId=1&toAccountId=2&amount=100.00
响应结果
成功时返回:“Transfer successful”
如果余额不足或账户无效,返回相应的错误信息。

6. 核心原理

悲观锁的工作流程:
在查询账户时,使用 FOR UPDATE 锁定目标账户的数据行。
在事务提交之前,其他事务无法对该账户进行修改。
完成转账操作后提交事务,释放锁。
SQL 示例:
sql
深色版本
– 查询并锁定账户
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;

– 更新账户余额
UPDATE accounts SET balance = balance - 100.00 WHERE id = 1;
UPDATE accounts SET balance = balance + 100.00 WHERE id = 2;
适用场景:
适用于写操作较多且并发冲突概率较高的场景。
例如,在高并发环境下进行银行转账时,可以避免重复扣款或余额不一致的问题。

7. 注意事项

性能开销:
悲观锁会锁定数据行,可能导致其他事务阻塞,影响系统性能。
因此,只有在确实需要严格保证数据一致性时才使用悲观锁。
死锁风险:
如果多个事务同时尝试锁定不同的资源,可能会导致死锁。
需要合理设计事务逻辑,尽量减少死锁的可能性(例如,按照固定的顺序锁定账户)。
事务管理:
必须确保在事务中执行锁定和更新操作,否则锁定不起作用。
通过以上代码,我们可以利用悲观锁实现银行转账功能,确保在高并发场景下的数据一致性。

相关文章:

乐观锁与悲观锁的使用场景

悲观锁的应用场景 悲观锁的基本思想是假设并发冲突会发生&#xff0c;因此在操作数据时会先锁定数据&#xff0c;直到完成操作并提交事务后才释放锁。这种方式适用于写操作较多、并发冲突可能性较高的场景。 高写入比例的数据库操作&#xff1a;如果系统中有很多写操作&#x…...

金融级隐私安全之DeepSeek R1 模型去中心化存储和推理实现方案

目录 DeepSeek R1 进入去中心化存储网络意味着什么? 它是如何工作的? Atoma、Walrus和 Sui Atoma Network 已成功将 DeepSeek R1 670B 参数推理模型上传到 Walrus 去中心化存储网络。这标志着这种规模的模型首次在去中心化存储层上可用,确保无需依赖中心化基础设施即可实…...

基于django大数据平台的交通数据可视化设计与实现(源码+lw+部署文档+讲解),源码可白嫖!

摘要 时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;基于大数据平台的交通数据可视化系统当然不能排除在外。基于大数据平台的交通数据可视化系统是在实际应用和软件工程的开发原理之上&#…...

STM32 vs ESP32:如何选择最适合你的单片机?

引言 在嵌入式开发中&#xff0c;STM32 和 ESP32 是两种最热门的微控制器方案。但许多开发者面对项目选型时仍会感到困惑&#xff1a;到底是选择功能强大的 STM32&#xff0c;还是集成无线的 ESP32&#xff1f; 本文将通过 硬件资源、开发场景、成本分析 等多维度对比&#xf…...

柳宗元经典的10首唐诗

1、最孤独的诗&#xff1a;《江雪》 江雪 千山鸟飞绝&#xff0c;万径人踪灭。 孤舟蓑笠翁&#xff0c;独钓寒江雪。 这首诗被誉为“唐诗五绝最佳”之作。 富于理想的“永贞革新”失败后&#xff0c;柳宗元被贬永州&#xff0c;母亲也在半年后离世。年届三十&#xff0c;政…...

Windows11介绍(中英文版)

一、Windows 11 的发布背景与发展历程 Windows 11 是微软公司推出的一款重要的操作系统&#xff0c;它是 Windows 操作系统系列的最新版本之一。微软在操作系统领域拥有悠久的历史和丰富的经验&#xff0c;从早期的 Windows 95 开启了图形化操作系统的新时代&#xff0c;到 Wi…...

使用 VSCode 本地历史记录‌恢复误删除文件

vsCode未知操作意外删除项目根目录入口代码文件 使用vsCode多年&#xff0c; 第一次遇见这种情况&#xff0c; 只是下载了几个插件&#xff0c; 可能打开的窗口太多&#xff0c; 有几个代码版本比对的页面&#xff0c; 在没有察觉的时候&#xff0c; 意外删除了项目根目…...

前端面试宝典---数据类型

基本数据类型 对于基本类型在创建时无需使用 new 关键字 Bigint在实际开发不常用&#xff0c;如果对于精度要求高可以使用第三方库&#xff0c;如decimal.js 基本数据类型介绍 undefined&#xff1a;当变量被声明但未赋值&#xff0c;或者函数没有返回值时&#xff0c;就会呈现…...

Dinky 和 Flink CDC 在实时整库同步的探索之路

摘要&#xff1a;本文整理自 Dinky 社区负责人&#xff0c;Apache Flink CDC contributor 亓文凯老师在 Flink Forward Asia 2024 数据集成&#xff08;二&#xff09;专场中的分享。主要讲述 Dinky 的整库同步技术方案演变至 Flink CDC Yaml 作业的探索历程&#xff0c;并深入…...

【Proteus仿真】【32单片机-A008】MPX4115压力检测系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、压力检测与LCD显示 2、超过上限&#xff0c;降压模块启动 3、压力检测范围15kpa-115kpa 4、压力阈值设置 5、超限报警 二、使用步骤 系统运行后&#xff0c;LCD160…...

银河麒麟系统虚拟机网络ping不通的解决方法

问题描述&#xff1a;使用NAT模式搭建了银河麒麟系统虚拟主机&#xff0c;虚拟机内部可以联网&#xff0c;可以查询到具体的ip地址&#xff0c;同时也可以在虚拟机内部ping同宿主机ip&#xff0c;但使用宿主机却无法ping同银河麒麟虚拟机ip&#xff0c;使用ssh、ftp、sftp等工具…...

spark数据清洗案例:流量统计

一、项目背景 在互联网时代&#xff0c;流量数据是反映用户行为和业务状况的重要指标。通过对流量数据进行准确统计和分析&#xff0c;企业可以了解用户的访问习惯、业务的热门程度等&#xff0c;从而为决策提供有力支持。然而&#xff0c;原始的流量数据往往存在格式不规范、…...

关于AIGC stable diffusion 在图像超分上的算法整理

参考文档&#xff1a; c论文阅读基于Stable Diffusion的图像超分 - 知乎 十分钟读懂Stable Diffusion运行原理 - 知乎 1.difussion model 扩散模型的基本原理 diffusion model 扩散模型是一类生成模型的统称&#xff0c;基于扩散过程生成数据。这类模型的核心是通过逐步加噪…...

Stable Diffusion ComfyUI 基础教程(一) ComfyUI安装与常用插件

前言&#xff1a; 相信大家玩 Stable Diffusion&#xff08;以下简称SD&#xff09;都是用的 web UI 操作界面吧&#xff0c;不知道有没有小伙伴听说过 ComfyUI。ComfyUI 是 一个基于节点流程的 Stable Diffusion 操作界面&#xff0c;可以通过流程&#xff0c;实现了更加精准…...

[leetcode]差分算法

一.差分算法性质 1.1计算差分数组&#xff1a; b[i] a[i] - a[i - 1] 1.2差分数组的性质 1.2.1对差分数组的每一项作前缀和&#xff0c;可以得到原来的数组 ai ​a1​∑j1i−1​dj​ 1.2.2将差分数组的某一项加i,那么其后面的所有项都会相对于原数组加i 让2~4项加3 这个第三…...

大数据技术之SPARK

Spark Core 什么是 RDD 代码中是一个抽象类&#xff0c;它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合 弹性 存储的弹性&#xff1a;内存与磁盘的自动切换&#xff1b; 容错的弹性&#xff1a;数据丢失可以自动恢复&#xff1b; 计算的弹性&#xff1a;…...

S32K144的m_data_2地址不够存,重新在LD文件中配置地址区域

在开发平台软件的时候代码中超出了64K的内存&#xff0c;单纯在ld文件中&#xff0c;增加m_data_2的存储长度&#xff0c;原先是0x00007000,我将长度修改为0x00008000,起始地址还是0x20000000,软件编译没有报错堆栈超出&#xff0c;但是软件下载到单片机中之后&#xff0c;144不…...

Spyder、PyCharm、VS Code 和 Jupyter Notebook 对比分析

在进行 Python 编程时&#xff0c;Spyder、PyCharm、VS Code 和 Jupyter Notebook 是最常用的几款开发工具&#xff08;IDE/编辑器&#xff09;。以下是它们在不同维度下的对比分析 &#x1f527; 一、基础介绍 软件类型主要特点Spyder科学计算IDE类似 MATLAB&#xff0c;集成…...

vue3腾讯云直播 前端拉流(前端页面展示直播)

1、引入文件&#xff0c;在index.html <link href"https://tcsdk.com/player/tcplayer/release/v5.3.2/tcplayer.min.css" rel"stylesheet" /><!--播放器脚本文件--><script src"https://tcsdk.com/player/tcplayer/release/v5.3.2/t…...

应急物资仓库管理系统|基于GAV仓库管理的应用

基于AGV应用的应急物资管理系统(智物资DW-S300)建设的目标是实现应急物资管理的信息化、智能化、规范化,保证应急物资的安全性和使用时的高效性&#xff0c;做到应急物资可追踪、可溯源。 构建一个应急物资仓储管理系统实现包括系统基本信息管理、入库管理、出库管理、筹措管理…...

ArkTS语言入门之接口、泛型、空安全、特殊运算符等

前言 臭宝们&#xff0c;今天我们来学习ArkTS中最后的一些内容。 实现接口 包含implements子句的类必须实现列出的接口中定义的所有方法&#xff0c;但使用默认实现定义的方法除外。 interface DateInterface {now(): string; } class MyDate implements DateInterface {no…...

蓝桥杯c++每日刷题(洛谷)

目录 P10385 [蓝桥杯 2024 省 A] 艺术与篮球 - 洛谷 (luogu.com.cn) P8706 [蓝桥杯 2020 省 AB1] 解码 - 洛谷 (luogu.com.cn) P8711 [蓝桥杯 2020 省 B1] 整除序列 - 洛谷 (luogu.com.cn) P8722 [蓝桥杯 2020 省 AB3] 日期识别 - 洛谷 (luogu.com.cn) P10385 [蓝桥杯 2024…...

Python+Requests 企业级接口测试入门(1~3天)

PythonRequests 企业级接口测试入门 1、GET接口简单案例 我的答案&#xff1a; import time import requestsdef get_all_users():try:response requests.get(urlhttps://reqres.in/api/users, #接口地址timeout10 #超时时间)respons…...

【android bluetooth 框架分析 01】【关键线程 3】【bt_jni_thread 线程介绍】

1. bt_jni_thread 职责介绍 bt_jni_thread 这个线程的作用是专门负责处理蓝牙 JNI 层的消息循环&#xff0c;也可以说是 C 层和 Java 层交互的桥梁线程。 1.1 什么是 JNI 层&#xff1f;为什么需要这个线程&#xff1f; JNI&#xff08;Java Native Interface&#xff09;是 …...

CCF - GESP Python三级考试题目示例

CCF - GESP Python三级考试题目示例&#xff0c;你可以根据实际需求进行调整。 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 以下关于Python中函数的说法&#xff0c;错误的是&#xff08; &#xff09; A. 函数定义使用def关键字 B. 函数必须有返回值 C.…...

Windows10系统更改盘符

Windows10系统更改盘符 导航 文章目录 Windows10系统更改盘符导航更改盘符 更改盘符 按下wini,再按k进入磁盘管理器 右击你想更改的磁盘&#xff0c;选择“更改驱动器号”和路径&#xff0c;选择好驱动器号后确定即可...

软件功能性测试有多重要?功能性测试工具有哪些?

软件功能性测试是指对软件应用程序进行的测试&#xff0c;旨在验证软件的每一个功能是否按预定要求正常运作。功能性测试通常基于软件的需求文档&#xff0c;从用户的角度出发&#xff0c;确保所有功能都能够满足用户的需求。 软件功能性测试在软件开发生命周期中扮演着至关重…...

未来生态映像:杭州的科技自然协奏曲

故事背景 故事发生在2050年的中国杭州&#xff0c;这座千年古城已蜕变为科技与自然完美交融的未来生态之城。从晨曦微露的西湖到暮色中的良渚文化村&#xff0c;每个角落都上演着人类智慧与自然韵律的动人对话。 故事摘要 当第一缕阳光亲吻西湖的生态浮岛&#xff0c;无人机携带…...

电商核心指标解析与行业趋势:数据驱动的增长策略【大模型总结】

电商核心指标解析与行业趋势&#xff1a;数据驱动的增长策略 在电商领域&#xff0c;数据是决策的核心。从流量监测到用户行为分析&#xff0c;从价格策略到技术赋能&#xff0c;每一个环节的优化都离不开对核心指标的深度理解。本文结合行业最新趋势与头部平台实践&#xff0…...

ubuntu自动更新--unattended-upgrades

ubuntu自动更新--unattended-upgrades 1 介绍2 发展历程3 配置与使用4 disable Auto update服务命令 参考 1 介绍 Unattended-Upgrades 是一个用于自动更新 Debian 及其衍生系统&#xff08;如 Ubuntu&#xff09;的工具。它的主要功能是自动检查、下载并安装系统更新&#xf…...

在Ubuntu 22.04上配置【C/C++编译环境】

在Ubuntu 22.04上配置C/C编译环境 如果你想在Ubuntu 22.04上编译和运行C或C程序&#xff0c;首先需要安装一个合适的编译器和相关工具。本文将为你提供详细的安装建议和操作步骤&#xff0c;帮助你快速搭建开发环境。 准备工作 在开始之前&#xff0c;确保你的系统可以通过终…...

费马小定理

快速幂 理论 a n a a ⋯ a a^n a a \cdots a anaa⋯a&#xff0c;暴力的计算需要 O(n) 的时间。 快速幂使用二进制拆分和倍增思想&#xff0c;仅需要 O(logn) 的时间。 对 n 做二进制拆分&#xff0c;例如&#xff0c; 3 13 3 ( 1101 ) 2 3 8 ⋅ 3 4 ⋅ 3 1 3^{13}…...

什么是音频预加重与去加重,预加重与去加重的原理是什么,在什么条件下会使用预加重与去加重?

音频预加重与去加重是音频处理中的两个重要概念&#xff0c;以下是对其原理及应用条件的详细介绍&#xff1a; 1、音频预加重与去加重的定义 预加重&#xff1a;在音频信号的发送端&#xff0c;对音频信号的高频部分进行提升&#xff0c;增加高频信号的幅度&#xff0c;使其在…...

程序代码篇---时间复杂度空间复杂度

文章目录 前言一、时间复杂度&#xff08;Time Complexity&#xff09;定义1. 常见时间复杂度类型2. 计算规则忽略常数项保留最高阶项循环嵌套递归算法 3. 代码示例&#xff08;1&#xff09;&#x1d442;(1)&#xff1a;常数时间&#xff08;2&#xff09;&#x1d442;(&…...

化工企业数字化转型:从数据贯通到生态重构的实践路径

一、战略定位&#xff1a;破解行业核心痛点 化工行业面临生产安全风险高&#xff08;全国危化品企业事故率年增5%&#xff09;、能耗与排放压力大&#xff08;占工业总能耗12%&#xff09;、供应链协同低效&#xff08;库存周转率低于制造业均值30%&#xff09;三大挑战。《石…...

Mysql备忘记录

1、简介 Mysql操作经常忘记命令&#xff0c;本文将持续记录Mysql一些常用操作。 2、常见问题 2.1、忘记密码 # 1、首先停止Mysql服务 systemctl stop mysqld # windows 从任务管理器里面停 # 2、更改配置文件 my.cnf (windows是 ini文件) vim /etc/my.cnf 在[mysqld]下面添…...

Python 爬取 1688.item_get_factory 接口:获取工厂档案信息实战指南

在电商采购和供应链管理中&#xff0c;了解供应商的工厂信息是至关重要的一步。1688 作为国内领先的 B2B 平台&#xff0c;提供了丰富的供应商和工厂档案信息。通过 item_get_factory API 接口&#xff0c;开发者可以获取工厂的详细信息&#xff0c;包括工厂名称、地址、联系方…...

【Proteus仿真】【32单片机-A009】矩阵按键系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、按键值与LCD显示 2、矩阵按键 二、使用步骤 系统运行后&#xff0c;LCD1602显示当前的按键值&#xff1b; 当按下不同按键后显示屏更新对应的按键值。 三、硬件资…...

【11408学习记录】英语语法精析:主从复合句之定语从句完全指南——从规则到实战例句一网打尽

定语从句 英语语法总结——主从复合句定语从句定语从句的写法先行词的作用分类定语从句的使用补充 每日一句词汇第一步&#xff1a;找谓语第二步&#xff1a;断开第三步&#xff1a;简化第一句第二句第三句第四句 英语 语法总结——主从复合句 定语从句 定语从句就是一个句子…...

go游戏后端开发31:麻将游戏的碰牌与胡牌逻辑

以下是润色后的版本&#xff1a; 1. 碰牌逻辑 1.1 触发碰牌 当一个玩家弃牌后&#xff0c;其他玩家可以选择碰牌。如果当前玩家决定碰牌&#xff0c;系统需要通知所有玩家这一操作。碰牌操作完成后&#xff0c;当前玩家需要出一张牌&#xff0c;系统同样需要通知所有玩家。 …...

vLLM实战:多机多卡大模型分布式推理部署全流程指南

1. 环境准备与基础配置 1.1 系统要求 依赖组件&#xff1a; # 基础工具安装 sudo apt-get install -y lsof git-lfs nvidia-cuda-toolkit1.2 虚拟环境配置 使用conda创建隔离环境&#xff0c;避免依赖冲突&#xff1a; conda create -n vllm python3.10 -y conda activate…...

RAI Toolbox详解

RAI Toolbox详解 摘要 RAI Toolbox是一个综合性的工具集&#xff0c;旨在帮助开发者和AI系统利益相关者更负责任地开发和监控AI系统&#xff0c;并做出更好的数据驱动决策。本文将详细介绍RAI Toolbox的功能、使用场景以及与类似AI项目的对比&#xff0c;帮助读者全面了解RAI…...

Python高级爬虫之js逆向+安卓逆向1.3节:Python数据类型

目录 引言&#xff1a; 1.3.1 两大数据类型 1.3.2 不可变数据类型 1.3.3 可变数据类型 1.3.4 再不跳槽就老了 引言&#xff1a; 大神薯条老师的高级爬虫安卓逆向教程&#xff1a; 这套爬虫教程会系统讲解爬虫的初级&#xff0c;中级&#xff0c;高级知识&#xff0c;涵盖…...

The 2024 CCPC National Invitational Contest (Changchun),第17届吉林省赛 C

补题链接 题解是什么意思呢&#xff0c;首先我们需要知道的是&#xff0c;斐波那契数列可以用矩阵快速幂和矩阵乘法求解 ( F ( n 1 ) F ( n ) ) ( 1 1 1 0 ) ( F ( n ) F ( n − 1 ) ) M ( F ( n ) F ( n − 1 ) ) \begin{pmatrix}F(n1) \\ F(n)\end{pmatrix} \begin{pma…...

GPT-4o-image模型:开启AI图片编辑新时代

在生成式AI技术爆发式迭代的今天&#xff0c;智创聚合API率先突破多模态创作边界&#xff0c;正式发布集成GPT-4o-image模型的创作平台&#xff0c;以“文生图-图生图-循环编辑”三位一体的技术矩阵&#xff0c;重新定义数字内容生产流程。生成图像效率较传统工具提升300%&…...

Java流程控制【if分支三种形式】

if分支三种形式 ①if(条件表达式) 代码&#xff1b; }②if(条件表达式){ 代码1&#xff1b; }else{ 代码2&#xff1b; }③if(条件表达式1){ 代码1&#xff1b; }else if(条件表达式2){ 代码2&#xff1b; }else if(条件表达式3){ 代码3&#xff1b;...... }else{ 代码n&#…...

2025 年陕西消防设施操作员考试攻略:历史文化名城的消防传承与创新​

陕西拥有丰富的历史文化遗产&#xff0c;众多古建筑分布其中&#xff0c;同时也在不断推进现代化建设&#xff0c;消防工作面临传承与创新的双重任务&#xff0c;这在考试中也有所体现。​ 考点融合与特色&#xff1a;一方面&#xff0c;古建筑的消防保护是重点&#xff0c;包…...

关于node.js 隐式修改数组长度的问题

// 删除手牌 proto.remove function (handCards, _cards) { let saveHandCards this.deepCloneTL(handCards);//保存原先的牌 console.warn("删除手牌000:",JSON.stringify(handCards)); console.warn("删除手牌111:",JSON.stringify(_card…...

探索文件与流的世界:File、InputStream 和 OutputStream 的奇妙之旅

目录 一、File 类——文件管理的小能手 1. 创建和删除文件 2. 检查文件属性 3. 路径操作 二、InputStream——读取数据的管道 1. 读取单个字节 2. 批量读取字节 3. 关闭流 三、OutputStream——写入数据的通道 1. 写入单个字节 2. 批量写入字节 3. 刷新和…...

nginx镜像创建docker容器,及其可能遇到的问题

一、基本流程 1、目录准备 我喜欢把文件放在/data下。 # 进入根目录的data目录 cd /data# 创建nginx目录 mkdir nginx# 进入nginx目录 cd nginx# 创建conf目录 mkdir conf# 进入conf目录 cd conf# 创建conf.d目录 mkdir conf.d 2、文件准备 &#xff08;1&#xff09;nginx…...