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

Java大师成长计划之第11天:Java Memory Model与Volatile关键字

📢 友情提示:

本文由银河易创AI(https://ai.eaigx.com)平台gpt-4o-mini模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。

在多线程编程中,线程的执行结果可能受到其他线程的影响,这就引出了一个重要主题:内存可见性和一致性。正确理解Java内存模型(Java Memory Model, JMM)及其相关的volatile关键字对于开发高效和安全的并发程序至关重要。今天,我们将深入探讨Java内存模型以及如何使用volatile关键字来解决可见性问题。

一、Java内存模型概述

Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范的一部分,旨在定义多线程环境下变量的访问规则。它规范了不同线程如何与内存进行交互,确保在多线程编程中,变量的读写操作是可预测的。理清Java内存模型的概念是理解Java并发编程的基础,也是实现线程安全的关键。

1.1 Java内存模型的基本构成

Java内存模型包含以下几个关键组成部分:

1.1.1 主内存和工作内存

在Java内存模型中,内存的划分主要有两个层次:主内存和工作内存。

  • 主内存:主内存是指系统的主内存区域,即共享内存,所有线程都在这个区域中存储共享变量的实际值。主内存相当于物理内存,用于存储对象实例和类静态数据。

  • 工作内存:每个线程拥有自己独立的工作内存(又称本地内存),如线程栈。工作内存保存了该线程对共享变量的局部副本(拷贝),线程对共享变量的读写操作首先是在工作内存中进行,这样做可以加速访问速度。

线程之间的通信通常通过主内存进行,任何线程要修改共享变量必须先将其从主内存读入工作内存,修改完后再将其写回主内存。

1.1.2 读写操作

Java内存模型对读写操作的行为有明确的规定。每个线程对共享变量的读写操作需要遵循以下步骤:

  1. 读取:把变量从主内存复制到工作内存。
  2. 更新:线程对共享变量进行修改(在工作内存中)。
  3. 写入:把更新后的共享变量写回到主内存。

这些步骤确保了数据在不同线程之间的跨线程通信。

1.1.3 内存屏障

为了控制对变量的读写顺序,Java内存模型引入了内存屏障(Memory Barriers),也被称为内存栅栏。内存屏障是硬件层面的指令,用于确保某些操作在屏障前完成,或者在屏障后操作不被提前执行。内存屏障防止了CPU或编译器对指令施加的重排序,确保了内存操作的有序性。

1.2 内存模型的主要目标

Java内存模型主要解决以下几个问题,以保证多线程程序的安全性和可预测性:

1.2.1 原子性

原子性是指一个操作的不可分割性。在多线程程序中,某些操作需要能够完全执行,不会被其他线程打断。Java内存模型确保对volatile变量的操作是原子的,而且对于simple variables(例如基本数据类型)在单一操作上的读写也具备原子性。但对复合操作(如自增等)则不具备原子特性,开发者需要额外实现线程安全的机制,如使用Atomic类或synchronized关键字。

1.2.2 可见性

可见性是指一个线程对共享变量的修改能够被其他线程看到。在没有适当同步机制的情况下,一个线程对共享变量的修改可能不会立刻在其他线程中体现,由于每个线程都有自己的工作内存。Java内存模型通过volatile关键字和同步机制来解决可见性问题,从而确保在一个线程对共享变量进行更新时,其他线程能够及时看到更新后的值。

1.2.3 有序性

有序性是指程序执行的顺序和代码的顺序一致。在Java中,编译器和CPU可能对指令的执行顺序进行优化,重排序可能会导致程序的执行顺序与预期不符。Java内存模型通过引入内存屏障和volatile关键字,规定了在特定条件下避免指令重排序,确保程序的执行顺序与代码逻辑一致。

1.3 总结

Java内存模型为多线程编程提供了一个清晰的框架,明确了主内存与工作内存之间的关系以及线程如何与这些内存区域交互。通过对原子性、可见性和有序性的定义,JMM帮助开发者在设计并发程序时考虑到线程之间的相互作用,从而避免了常见的并发问题。在多线程开发实践中,深入理解Java内存模型是确保系统稳定性和效率的基础。

通过学习Java内存模型的概念和原理,开发者能够更好地使用volatile关键字及其他并发构造,编写出高效、安全的并发代码。这不仅能提高程序的性能,还能帮助开发者在多线程编程的道路上迈出更稳健的步伐。

二、可见性问题

在多线程编程中,可见性问题是一个关键的概念,它描述了不同线程之间对共享变量的读写操作是否能够及时被其他线程所看到。在Java中,线程可能在自己的本地内存(即工作内存)中对共享变量进行缓存,这样就可能导致某个线程对共享变量的更改,不能被其他线程及时看到,从而引发一系列难以预料的问题。

2.1 可见性的问题

2.1.1 现象描述

考虑以下简单的示例,两个线程共享一个标志变量flag,一个线程负责修改这个变量,而另一个线程负责读取它:

public class VisibilityDemo {private static boolean flag = false;public static void main(String[] args) throws InterruptedException {Thread reader = new Thread(() -> {while (!flag) {// busy-waiting}System.out.println("Flag has been changed to true!");});Thread writer = new Thread(() -> {try {Thread.sleep(200); // 等待一段时间} catch (InterruptedException e) {e.printStackTrace();}flag = true; // 修改共享变量System.out.println("Flag changed to true.");});reader.start();writer.start();}
}

在上面的代码示例中,reader线程会持续检查flag的值,直到writer线程将其修改为true。由于flag变量存储在主内存中,而线程各自维护自己的工作内存,不并发的情况下,reader线程可能一直在工作内存中看到flag的旧值(即false),即使writer线程已经修改了它。

这种现象称为可见性问题,具体表现为一个线程对共享变量的修改在其他线程中不可见,从而导致reader线程无法正常退出循环。

2.1.2 可见性产生的原因

可见性问题的产生主要源于以下几个原因:

  1. 局部缓存:每个线程对共享变量的操作可能使用了其工作内存中的缓存值,而不是直接访问主内存。线程在运行时会将共享变量的值拷贝到工作内存进行操作,这种缓存机制虽然能够提高性能,但同时也引入了可见性问题。

  2. 编译优化:现代JVM和编译器会对代码进行优化,从而可能改变指令的执行顺序。某些情况下,编译器可能会重排序指令的执行顺序、合并读写操作等,导致线程看到的数据状态与预期不符。

  3. CPU缓存:在多处理器系统中,每个CPU核心都有自己的缓存,某个线程对共享变量所做的修改可能只在该线程的核心缓存中,其他线程可能永远无法看到这种修改。

2.2 可见性问题的后果

可见性问题会导致多种潜在的错误和不一致性,具体包括:

  • 逻辑错误:如果某个线程永远无法看到其他线程对共享变量的修改,则可能导致程序逻辑错误。例如,在某个条件下应结束循环,但线程依然在循环内等待。

  • 死锁风险:在某些情况下,可见性问题可能导致线程无限等待,从而增加了死锁的发生几率。

  • 状态不一致:多个线程操作共享变量时,可能会导致共享数据的状态不一致,影响整个系统的稳定性。

2.3 解决可见性问题的措施

为了有效解决可见性问题,Java提供了几种机制,最常用的包括synchronizedvolatile关键字和java.util.concurrent包中的并发工具。

2.3.1 使用synchronized关键字

synchronized关键字可以用来在方法或代码块中加锁。当一个线程获得锁时,其他线程无法进入被锁定的代码,这样可以确保对共享变量的操作是安全的。

public synchronized void increment() {count++; // 对共享变量的操作
}

2.3.2 使用volatile关键字

volatile关键字是解决可见性的轻量级方案。当一个变量被声明为volatile时,确保对该变量的写操作立即被其他线程看到:

private static volatile boolean flag = false;

在使用volatile时,一个线程对flag的修改会直接刷新到主内存中,其他线程的工作内存会立即刷新对应的缓存,从而避免可见性问题。

2.3.3 使用并发类

Java的java.util.concurrent包提供了许多线程安全的数据结构和工具,这些工具在内部已经考虑了可见性问题。例如,AtomicIntegerConcurrentHashMap等类都自带了可见性保障机制,适合多线程环境中的使用。

AtomicInteger atomicCount = new AtomicInteger(0);
atomicCount.incrementAndGet(); // 原子性地增值

2.4 小结

可见性问题是Java多线程编程中极为重要的一个概念,理解并有效应对可见性问题对于编写高效、可靠的多线程程序至关重要。通过合理使用synchronizedvolatile关键字,或java.util.concurrent包中的工具,可以确保跨线程的数据一致性和可见性。

在实际开发中,理解可见性问题的细节,能够帮助开发者更好地设计和实现并发程序,从而提高系统的稳定性和执行效率。持续探索和实践这些并发机制,将助力你在Java并发编程的道路上不断前行,向Java大师的目标迈进。

三、使用volatile关键字

在Java多线程编程中,确保共享变量的可见性和避免不必要的线程阻塞是设计高效代码的关键。volatile关键字的引入为解决可见性问题提供了一种轻量级的方式。通过了解volatile的特性、用法及其适用场景,开发者能够更加合理地控制线程对共享变量的访问,提升程序性能与稳定性。

3.1 volatile的基本概念

volatile是Java中的一个修饰符,可以修饰实例变量或类变量。它的主要作用是告诉Java虚拟机(JVM),该变量可能会被多个线程同时访问和修改。使用volatile标记的变量在以下两个方面具有特性:

  1. 可见性:当一个线程修改了一个被volatile修饰的变量,其他线程会立刻看到这个修改。这是因为对volatile变量的写操作会强制将该结果写回主内存,而不是仅在工作内存中。

  2. 禁止指令重排序:对volatile变量的读写操作不会被重排序,保证了对该变量的操作的有序性。这意味着变量在某种意义上是“最新的”,确保在并发执行时能够保持有效性。

3.2 基本用法

使用volatile关键字非常简单,只需在变量声明时加上volatile修饰符即可:

public class VolatileExample {private static volatile boolean flag = false;public static void main(String[] args) throws InterruptedException {Thread reader = new Thread(() -> {while (!flag) {// busy-waiting}System.out.println("Flag has been changed to true!");});Thread writer = new Thread(() -> {try {Thread.sleep(200); // 等待一段时间以确保reader先运行} catch (InterruptedException e) {e.printStackTrace();}flag = true; // 修改共享变量System.out.println("Flag changed to true.");});reader.start();writer.start();}
}

在这个例子中,flag被声明为volatile,保证了当writer线程对flag进行写操作时,reader线程能够及时看到这个变化。

3.3 volatile的应用场景

volatile关键字适合用于以下几种典型场景:

3.3.1 状态标志

当需要使用一个简单的状态标志来指示某个状态(如停止、标记等)时,volatile是一个完美的选择。由于volatile能够确保变量的可见性和有序性,因此特别适合使用这种方式来控制线程的执行。

private static volatile boolean running = true;public void stop() {running = false; // 设置停止标志
}public void run() {while (running) {// 执行任务}System.out.println("Stopped running.");
}

3.3.2 单例模式

在某些单例模式的实现中,使用volatile来确保单例对象的初始化安全。在双重检查锁定的实现中,通过将实例变量声明为volatile,可以防止由于指令重排序引起的潜在问题。

public class Singleton {private static volatile Singleton instance;private Singleton() { }public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton(); // 有可能被重排序}}}return instance;}
}

3.3.3 配合其他机制

在某些情况下,volatile可以与其他并发机制(如synchronizedLock)一起使用,以增强代码的可读性和性能。例如,在某个外部条件存在的情况下,可以使用volatile进行状态标志的管理,结合锁机制进行复杂的操作。

3.4 volatile的局限性

尽管volatile提供了一种轻量级的可见性保证,但它也有其局限性,并不适用于所有场景:

3.4.1 不满足原子性

volatile只保证了对单一变量的可见性,不保证复合操作的原子性。例如,volatile int count;在执行count++时,并不确保这是一种原子操作,可能会引入竞态条件。因此,涉及到多行操作的逻辑时,volatile并不是一个合适的选择。

3.4.2 复合操作不安全

对于需要检查和设置的操作(比如检查后再执行的业务逻辑),使用volatile无法保证执行的安全性。线程可能在读取之前的值后被其他线程所更改,导致业务逻辑不一致。

volatile int count = 0;
// 这里没有同步机制
count++; // 不是原子操作

3.4.3 不支持复杂的逻辑

由于volatile主要是针对单一变量的可见性,复杂的状态转移或者复杂的条件检查依然需要借助synchronizedLock等更强大的并发工具进行处理。

3.5 小结

volatile关键字在Java并发编程中扮演着重要的角色,允许开发者以一种简洁高效的方式来确保共享变量的可见性。理解volatile的工作机制及其适用场景,将有助于开发者编写出更安全和高效的多线程程序。

在实际开发中,合理使用volatile能够改善性能,避免不必要的锁竞争,对于某些简单的状态标志或者单例模式的实现尤为有效。然而,开发者也应当注意到它的局限性,对于复杂的并发场景,仍需借助其他同步机制,如synchronized或并发工具类,保障线程安全。

通过学习和掌握volatile的使用,开发者可以在Java并发编程的旅途中走得更远,逐步成长为一名真正的Java大师。

四、小结

在多线程编程中,理解Java内存模型及volatile关键字的作用非常重要。它不仅帮助开发者避免常见的可见性问题,还提升了程序的高效性和可靠性。合适地使用volatile,能够确保数据的及时可见并防止不必要的锁竞争,从而在一定程度上提升应用程序的性能。

掌握Java内存模型和volatile关键字将为你在并发编程领域的成长奠定扎实的基础。正如程序员需要理解底层的工作原理以编写出安全、稳定的并发代码,全面学习这些知识将帮助你在成为Java大师的道路上迈出更坚定的步伐。在接下来的学习中,建议结合具体的场景实践,进一步深化对这些概念的理解。

相关文章:

Java大师成长计划之第11天:Java Memory Model与Volatile关键字

📢 友情提示: 本文由银河易创AI(https://ai.eaigx.com)平台gpt-4o-mini模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。 在多线程编程中,线程的执…...

java学习之数据结构:一、数组

主要是对数组所有的东西进行总结,整理 适合小白~ 目录 1.什么是数组 1.1数组定义 1.2数组创建 1)静态创建 2)动态创建 1.3数组遍历 1)for和while遍历 2)foreach遍历 2.数组越界问题及解决 2.1数组越界问题 2…...

Oracle OCP认证考试考点详解083系列04

题记: 本系列主要讲解Oracle OCP认证考试考点(题目),适用于19C/21C,跟着学OCP考试必过。 16. 第16题: 题目 解析及答案: 关于使用恢复管理器(RMAN)恢复表,以下哪三项是…...

MARM:推荐系统中的记忆增强突破

文章目录 1. 背景1.1 模型规模与推荐系统的挑战1.2 缓存技术在推荐系统中的潜力1.3 推荐系统中的数据与计算需求1.4 复杂度对比1.5 MARM模型的创新性 2. 方法2.1 流程2.1.1 序列生成器2.1.2 外部缓存查找2.1.3 多目标注意力机制2.1.4 发结果到缓存 **2.2 MARM与SIM**2.2.1 SIM的…...

INP指标

什么是INP(Interaction to Next Paint) 参考网站:webVital-INP文档 定义与核心目标 INP 是一项稳定的 Core Web Vitals 指标,通过统计用户访问期间所有符合条件的互动约定时间,评估网页对用户操作的总体响应能力。最…...

Flink 的状态机制

在实时流处理领域,状态管理是构建复杂业务逻辑的核心能力。Apache Flink 通过统一的状态抽象和高效的容错机制,为开发者提供了从毫秒级窗口聚合到 TB 级历史数据关联的全场景支持。本文将深入剖析 Flink 状态机制的底层原理,结合实际案例展示…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】1.1 数据库核心概念与PostgreSQL技术优势

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 深度解析PostgreSQL核心架构与技术优势:从数据库原理到实战场景1.1 数据库核心概念与PostgreSQL技术优势1.1.1 关系型数据库核心架构解析1.1.1.1 数据库系统的底…...

linux下,ollama会把模型文件保存在哪里?

文章目录 运行ollama,有两种形式,估计得分开讨论首先是使用自动启动的ollama:先跑个“小一点的大模型”但是现在模型文件存在哪儿呢?运行ollama,有两种形式,估计得分开讨论 我们用两种方式,来运行ollama。 首先是使用自动启动的ollama: ps -aux | grep ollama系统自…...

EMMC存储性能测试方法

记于 2022 年 9 月 15 日 EMMC存储性能测试方法 - Wesley’s Blog 参考Android-emmc性能测试 | 一叶知秋进行实践操作 dd 命令 页面缓存 为了测试 emmc 的真实读写性能,我们需要先把页面缓存给清理: echo 1 > /proc/sys/vm/drop_caches console:…...

19. LangChain安全与伦理:如何避免模型“幻觉“与数据泄露?

引言:当AI成为企业"数字员工"时的责任边界 2025年某金融机构因AI客服泄露用户信用卡信息被罚款2300万美元。本文将基于LangChain的安全架构与Deepseek-R1的合规实践,揭示如何构建既强大又安全的AI系统。 一、AI安全风险矩阵 1.1 2025年最新威…...

5月3日日记

上午睡到自然醒(其实六点多被我爸叫起来抢火车票,发现明天中午的软卧候补上了,挺好的)然后继续睡到快10点。 中午吃的什么来着,好像是西红柿炒鸡蛋和藜麦饭,有个鱼不是很想吃就没吃 中午打了两把吃鸡&…...

C++类_构造函数

在 C11 里,类的构造函数有多种类型,下面为你详细介绍各类构造函数并给出示例代码。 1. 默认构造函数 默认构造函数是没有参数的构造函数,要是没有为类定义任何构造函数,编译器会自动生成一个默认构造函数。 2. 带参数的构造函数…...

【React】Hooks useReducer 详解,让状态管理更可预测、更高效

1.背景 useReducer是React提供的一个高级Hook,没有它我们也可以正常开发,但是useReducer可以使我们的代码具有更好的可读性,可维护性。 useReducer 跟 useState 一样的都是帮我们管理组件的状态的,但是呢与useState不同的是 useReducer 是集…...

Runnable组件重试机制降低程序错误率

一、LangChain 重试机制深度解析 当构建生产级AI应用时,with_retry() 机制可有效提升系统容错性,典型应用场景包括: API调用频率限制时的自动恢复模型服务临时不可用的故障转移网络波动导致的瞬时异常处理 参数详解与配置策略 1. 参数配置…...

纹理过滤方式和纹理包裹方式

纹理过滤方式 纹理过滤方式有临近过滤(Nearest)和双线性插值过滤(Linear),什么时候用什么过滤方式其实看个人选择,区别就是临近过滤是当需要的像素大于图片像素时候,一些像素点需要复用与他相近…...

55.[前端开发-前端工程化]Day02-包管理工具npm等

包管理工具详解 npm、yarn、cnpm、npx、pnpm 1 npm包管理工具 代码共享方案 包管理工具npm 2 package配置文件 npm的配置文件 方式二 常见的配置文件 常见的属性 常见的属性 常见的属性 依赖的版本管理 常见属性 npm install 命令 项目安装 3 npm install原理 npm instal…...

Maven安装配置以及Idea中的配置教程

一、下载Maven 我使用的是3.9.9的版本: 下载地址:Download Apache Maven – Maven 二、安装 将下载好的Maven压缩包解压到一个路径不包含中文的文件夹: 三、配置环境变量 以win11系统为例: 1.鼠标右键此电脑->属性->…...

【JavaScript】性能优化:打造高效前端应用

文章目录 一、执行效率优化(关键路径优化)1.1 算法时间复杂度控制1.2 Web Workers多线程计算二、内存管理(避免内存泄漏)2.1 定时器清理2.2 DOM引用释放三、DOM操作优化(渲染性能)3.1 批量DOM更新3.2 读写分离策略四、网络传输优化(加载性能)4.1 代码分割(Dynamic Imp…...

【C语言练习】018. 定义和初始化结构体

018. 定义和初始化结构体 018. 定义和初始化结构体1. 定义结构体示例1:定义一个简单的结构体输出结果2. 初始化结构体示例2:在声明时初始化结构体输出结果示例3:使用指定初始化器初始化结构体(C99及以上标准支持)输出结果3. 结构体数组示例4:定义和初始化结构体数组输出结…...

Three.js支持模型格式区别、建议

在 Three.js 中,3D 模型的种类和格式非常多样,每种格式都有其适用场景和优缺点。以下是常见的 Three.js 支持的模型格式、它们的区别、使用建议及推荐。 在这里推荐免费的blender工具,免费、占用空间不大,而且好用,前端打开模型时使用不错,或者有自己想做的模型也可以用它…...

JavaScript基础-流程控制概念

在JavaScript编程中,掌握如何控制程序的执行流程是编写功能强大、逻辑清晰代码的关键。流程控制语句允许我们根据不同的条件执行不同的代码块,或者重复执行某些操作,从而实现复杂的功能逻辑。本文将详细介绍JavaScript中的几种主要流程控制结…...

PowerBI企业运营分析——多维度日期指标分析

PowerBI企业运营分析——多维度日期指标分析 欢迎来到Powerbi小课堂,在竞争激烈的市场环境中,企业运营分析平台成为提升竞争力的核心工具。 通过整合多源数据、实时监控关键指标,该平台能够精准分析业务表现,快速识别问题与机会…...

施磊老师rpc(三)

文章目录 mprpc框架项目动态库编译框架生成动态库框架初始化函数-文件读取1. 为什么要传入 argc, argv2. 读取参数逻辑3. 配置文件设计 init部分实现 mprpc配置文件加载(一)配置文件加载类成员变量主要方法**src/include/mprpcconfig.h** 配置文件**bin/test.conf** 实现配置文…...

k8s 探针

Kubernetes 中的探针(Probes)用于检测容器的健康状态或就绪状态,确保应用在运行时的可靠性。Kubernetes 提供三种探针类型,它们的核心区别在于用途和失败后的处理逻辑。以下是它们的详细说明和对比: 1. 启动探针&…...

MIT6.S081-lab8

MIT6.S081-lab8 1. Large files 从 lecture 我们可以知道,我们目前的单个文件的最大大小很小,这是因为我们能够索引的索引块范围很小,实际上,目前的索引只有直接索引和一级索引,而这个实验就是需要我们去实现二级索引…...

【RabbitMQ】 RabbitMQ快速上手

文章目录 一、RabbitMQ 核心概念1.1 Producer和Consumer2.2 Connection和Channel2.3 Virtual host2.4 Queue2.5 Exchange2.6 RabbitMQ工作流程 二、AMQP协议三 、web界面操作4.1 用户相关操作4.2 虚拟主机相关操作 四、RabbitMQ快速入门4.1 引入依赖4.2 编写生产者代码4.2.1 创…...

使用Rust + WebAssembly提升前端渲染性能:从原理到落地

一、问题背景:为什么选择WebAssembly? 最近在开发数据可视化大屏项目时,我们遇到了一个棘手的问题:前端需要实时渲染10万数据点的动态散点图,使用纯JavaScript Canvas方案在低端设备上帧率不足15FPS。经过性能分析&a…...

【quantity】9 长度单位模块(length.rs)

代码是用Rust语言定义的一组长度单位类型&#xff0c;利用了泛型和类型别名来创建带不同SI前缀的长度量。下面是详细解释&#xff1a; 基础结构&#xff1a; 使用了Quantity<V, P, Meter>作为基础类型&#xff0c;表示一个带有值类型V、前缀P和单位Meter的量。 Meter是…...

网络通信领域的基础或流行协议

一、TCP(传输控制协议) 1. 宏观介绍 TCP:全称“Transmission Control Protocol”——传输控制协议,是互联网最基础的传输协议之一。传输层协议,提供面向连接、可靠的字节流传输服务。它通过三次握手建立连接、四次挥手断开连接,确保数据有序、完整地传输作用:让两个设备…...

STM32——GPIO

1、GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 可配置为8种输入输出模式 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 …...

AE模板 300个故障干扰损坏字幕条标题动画视频转场预设

这个AE模板提供了300个故障干扰损坏字幕条标题动画视频转场预设&#xff0c;让您的视频具有炫酷的故障效果。无论是预告片、宣传片还是其他类型的视频&#xff0c;这个模板都能带给您令人惊叹的故障运动标题效果。该模板无需任何外置插件或脚本&#xff0c;只需一键点击即可应用…...

2025-2026 XCPC

基本信息 本赛季由 jr-zlw \texttt{\color{#AA00AA}{jr-zlw}} jr-zlw, Skyzhou \texttt{\color{#03A89E} Skyzhou} Skyzhou 和 sunchaoyi \texttt{\color{#0000FF}sunchaoyi} sunchaoyi 组队&#xff0c;全靠大佬带飞~。 训练记录 2025.05.02 The 2023 Guangdong Provinci…...

list类的详细讲解

【本节目标】 1. list的介绍及使用 2. list的深度剖析及模拟实现 3. list与vector的对比 1. list的介绍及使用 1.1 list的介绍 1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list 的底层是双向链表结构&a…...

中小企业MES系统数据库设计

版本&#xff1a;V1.0 日期&#xff1a;2025年5月2日 一、数据库架构概览 1.1 数据库选型 数据类型数据库类型技术选型用途时序数据&#xff08;传感器读数&#xff09;时序数据库TimescaleDB存储设备实时监控数据结构化业务数据关系型数据库PostgreSQL工单、质量、设备等核心…...

wfp CommandParameter 详细解说

WPF 中的 CommandParameter 是命令模型中的关键属性,用于向命令的执行逻辑传递动态参数。以下是其主要特性和应用场景的详细解析: 1. ‌基本概念与用法‌ ‌数据传递机制‌ CommandParameter 通常与 Command 属性配合使用,允许在 XAML 中静态定义参数或在绑定中动态传递值。…...

正弦波、方波、三角波和锯齿波信号发生器——Multisim电路仿真

目录 Multisim使用教程说明链接 一、正弦波信号发生电路 1.1正弦波发生电路 电路组成 工作原理 振荡频率 1.2 正弦波发生电路仿真分析 工程文件链接 二、方波信号发生电路 2.1 方波发生电路可调频率 工作原理 详细过程 2.2 方波发生电路可调频率/可调占空比 调节占空比 方波产生…...

Java语言概述

Java语言概述 什么是程序&#xff1f; ​ 程序是计算机执行某些操作或解决某个问题而编写的一系列有序指令单集合。 ​ 举例&#xff1a; ​ 计算11&#xff0c;并把结果写在黑板上 ​ 计算11&#xff0c;并把结果显示在屏幕上&#xff08;按编程语言规定的语句&#xff0…...

截图软件、画图软件、左右分屏插件、快捷键

截图软件 画图软件 画图时候按字母可以改变颜色&#xff1a;红色r,蓝色b,绿色g,粉色p,橙色o 左右分屏&#xff1a; 快捷键 1.打开文件或文件夹&#xff1a; CtrlP&#xff1a;快速打开文件。CtrlR&#xff1a;快速打开文件或文件夹。 2.文件操作&#xff1a; CtrlN&…...

Linux 信号

一、生活中的信号 1.1、生活中的信号从产生到结束过程 例&#xff1a; ①、外卖电话响了&#xff08;信号产生&#xff09;-> 我接了电话并告诉外卖员说先放到楼下的架子上&#xff08;识别到这个信号&#xff0c;并记住&#xff0c;保存到我的脑海里面&#xff09; ->…...

AI 生成内容的版权困境:法律、技术与伦理的三重挑战

最近研学过程中发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…...

【愚公系列】《Manus极简入门》013-电影推荐专家:“银幕导航家”

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…...

MCP智能体意图识别与工具路由:让AI自主决策调用链路

目录 &#x1f680; MCP智能体意图识别与工具路由&#xff1a;让AI自主决策调用链路 &#x1f31f; 什么是意图识别与工具路由&#xff1f; &#x1f6e0;️ 1. 设计意图识别模块 1.1 简易关键字规则版&#xff08;基础版&#xff09; 1.2 使用大模型辅助意图识别&#xff…...

【Redis】List类型

文章目录 List的特点介绍lpush&#xff0c;lpushx&#xff0c;rpush&#xff0c;rpushx命令lrange命令lpop和rpoplindex命令linsert命令llen命令lrem 命令ltrim命令lset命令阻塞版本的命令blpop和brpop 命令小结list的内部编码List的应用场景 List的特点介绍 列表相当于一个数…...

Trae 安装第三方插件支持本地部署的大语言模型

Trae 安装第三方插件支持本地部署的大语言模型 0. 引言1. 安装插件 0. 引言 字节发布的 Trae IDE 一直不支持本地部署的的大语言模型。 Qwen3 刚刚发布&#xff0c;想在 Trae 中使用本地部署的 Qwen3&#xff0c;我们可以在 Trae 中安装其他插件。 1. 安装插件 我们可以安装…...

【免费】2010-2019年上市公司排污费数据

2010-2019年上市公司排污费数据 1、时间&#xff1a;2010-2019年 2、来源&#xff1a;上市公司披露报告 3、指标&#xff1a;代码、日期、名称、本期支出 4、范围&#xff1a;417家上市公司 5、相关研究&#xff1a;胡珺,宋献中,王红建.非正式制度、家乡认同与企业环境治理…...

第Y3周:yolov5s.yaml文件解读

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 本次任务&#xff1a;将yolov5s网络模型中的第4层的C3x2修改为C3x1&#xff0c;第6层的C3x3修改为C3x2。 首先输出原来的网络结构&#xff1a; from n pa…...

python 桌面程序开发简述及示例

Python桌面程序开发简述及示例 Python凭借其简洁的语法和丰富的库支持,非常适合开发跨平台的桌面应用程序。本文将介绍Python桌面开发的主要方法,并提供实际代码示例。 一、Python桌面开发主要方法 1.1 Tkinter(标准库) Python内置的GUI库,适合开发简单桌面应用 1.2 …...

【前端知识】Vue3状态组件Pinia详细介绍

Vue3状态组件Pinia详细介绍 关联知识 Pinia 组件介绍、核心原理及使用方式 Pinia 组件介绍 Pinia 是 Vue.js 的官方状态管理库&#xff0c;专为 Vue 3 设计&#xff0c;提供简洁的 API 和强大的 TypeScript 支持。其核心组件包括&#xff1a; • Store&#xff1a;状态存储容器…...

YOLO旋转目标检测之ONNX模型推理

YOLO旋转检测相较于目标检测而言&#xff0c;其只是最后的输出层网络发生了改变&#xff0c;一个最明显的区别便是&#xff1a;目标检测的检测框是xywh&#xff0c;而旋转检测则为xywha&#xff0c;其中&#xff0c;这个a代表angle&#xff0c;即旋转角度&#xff0c;其余的基本…...

C++八股--three day --设计模式之单例和工厂

对于C编程中的思想&#xff0c;最常见的就是考察设计模式了 那么我们在面试中常考的设计模式包含以下几种&#xff1a;单例模式&#xff0c; 接下来我们按顺序介绍 1.单例模式&#xff1a; 一个类只能创建一个实例&#xff1a;常应用于日志模块&#xff0c;数据库模块 …...