原子操作CAS(Compare-And-Swap)和锁
目录
原子操作
优缺点
锁
互斥锁(Mutex)
自旋锁(Spin Lock)
原子性
单核单CPU
多核多CPU
存储体系结构
缓存一致性
写传播(Write Propagation)
事务串行化(Transaction Serialization)
MESI 一致性协议
原子序
原子操作
定义:原子操作指的是在执行过程中不可被中断的操作,该操作要么完整地执行完毕,要么完全不执行,不存在执行到一半的中间状态。 在多线程或者多进程环境里,原子操作能够保证在同一时刻仅有一个线程或者进程可以对共享资源进行访问和修改,从而避免数据竞争和不一致的问题。
优缺点
高性能:由于 CAS 是无锁算法,避免了锁的竞争和上下文切换带来的性能开销,因此在高并发场景下具有较高的性能。
避免死锁:传统的锁机制在使用不当的情况下可能会导致死锁问题,而 CAS 操作不存在死锁的风险。
ABA 问题:CAS 操作在比较内存位置的值时,只关注值是否相等,而不关心值的变化过程。如果一个值从 A 变为 B,再从 B 变回 A,CAS 操作会认为值没有发生变化,从而继续进行更新操作。这种情况被称为 ABA 问题。
自旋开销:在 CAS 操作失败时,通常会采用自旋的方式不断重试,直到操作成功。如果竞争非常激烈,自旋会消耗大量的 CPU 资源,降低系统性能。
锁
互斥锁(Mutex)
定义:互斥锁(Mutual Exclusion Lock)是一种用于保护共享资源的同步原语,确保同一时间只有一个线程可以访问该资源。当一个线程获取到互斥锁时,其他线程如果尝试获取该锁,会被阻塞,直到持有锁的线程释放锁。
工作原理
- 线程尝试获取互斥锁。如果锁当前未被持有,线程会成功获取锁并继续执行后续操作。
- 如果锁已经被其他线程持有,尝试获取锁的线程会被放入等待队列并进入阻塞状态,此时线程会放弃 CPU 资源,操作系统会调度其他线程执行。
- 当持有锁的线程完成对共享资源的操作后,会释放锁。此时,操作系统会从等待队列中唤醒一个等待的线程,让其获取锁并继续执行。
- 优点:
- 避免了多个线程同时访问共享资源,从而防止数据竞争和不一致的问题。
- 当锁的持有时间较长时,阻塞线程可以避免 CPU 资源的浪费,因为线程在阻塞期间不会占用 CPU 时间。
- 缺点:
- 线程阻塞和唤醒的过程涉及到操作系统的调度,会带来一定的上下文切换开销,尤其是在锁的竞争非常激烈的情况下,这种开销可能会比较大。
- 实现相对复杂,需要操作系统的支持。
应用场景:适用于锁的持有时间较长、线程竞争较为激烈的场景,例如对数据库的读写操作、文件的访问
自旋锁(Spin Lock)
定义:自旋锁是一种忙等待的锁机制。当一个线程尝试获取自旋锁时,如果锁已经被其他线程持有,该线程不会进入阻塞状态,而是会不断地循环检查锁的状态,直到锁被释放。
工作原理
- 线程尝试获取自旋锁。如果锁当前未被持有,线程会成功获取锁并继续执行后续操作。
- 如果锁已经被其他线程持有,尝试获取锁的线程会进入一个循环,不断地检查锁的状态,在这个过程中,线程会一直占用 CPU 资源。
- 当持有锁的线程释放锁后,自旋的线程会检测到锁的状态变化,从而成功获取锁并继续执行。
- 优点:
- 没有线程阻塞和唤醒的上下文切换开销,因此在锁的持有时间较短的情况下,性能较高。
- 实现相对简单,不需要操作系统的复杂调度。
- 缺点:
- 如果锁的持有时间较长,自旋的线程会一直占用 CPU 资源,导致 CPU 资源的浪费,降低系统的整体性能。
- 在多处理器系统中,如果多个线程同时自旋等待同一个锁,会导致多个 CPU 核心都处于忙等待状态,进一步降低系统效率。
应用场景:适用于锁的持有时间非常短、线程竞争不激烈的场景,例如在一些内核代码中对临界区的保护。
时间判断:临界资源访问时间和锁切换所花费的时间相比
原子性
原子性可以保证在同一时刻只有一个线程或进程能够对共享资源进行特定操作,避免了多个线程或进程同时修改共享资源而引发的错误。
单核单CPU
- 只需要保证操作指令不被打断(调用机制)
- 底层自旋锁
- 屏蔽中断
多核多CPU
- 除了不被打断
- 在0x86,lock指令锁总线,避免所有内存的访问
- 现在lock指令只需阻止其他核心对相关内存空间的访问
存储体系结构
三级缓存cache:为了解决CPU运算速度与内存访问速度不匹配的问题
写回策略(write-back)
1.写
2.读
基于写会策略会产生缓存不一致的问题
缓存一致性
问题产生的原因:CPU是多核的,会访问到未同步的数据
解决方法:
写传播(Write Propagation)
定义:写传播是解决缓存一致性问题的一种基本策略,其核心目标是确保在多处理器系统中,当一个处理器对共享数据进行写操作时,这个写操作的结果能够被其他处理器感知到,进而保证所有处理器的缓存中该数据副本的一致性。
工作原理:当一个处理器对其缓存中的数据进行写操作时,需要将这个写操作传播到其他处理器的缓存或者主存中。具体的传播方式可以分为写直达(Write-Through)和写回(Write-Back)两种:
- 写直达:处理器在对缓存进行写操作的同时,也会将数据写回到主存中。这样可以保证主存中的数据始终是最新的,但缺点是每次写操作都需要访问主存,会增加写操作的延迟。
- 写回:处理器只对缓存进行写操作,只有当缓存行被替换时,才将修改后的数据写回到主存中。这种方式减少了对主存的访问次数,提高了写操作的性能,但会增加缓存一致性协议的复杂度。
事务串行化(Transaction Serialization)
定义:事务串行化是数据库管理系统中用于保证事务并发执行正确性的一种隔离级别。事务是一组不可分割的数据库操作序列,事务串行化要求所有事务按照某种顺序依次执行,就好像这些事务是一个接一个串行执行的一样,从而避免了并发执行可能带来的数据不一致问题。
工作原理:在事务串行化隔离级别下,数据库系统会对事务进行排序,并按照这个顺序依次执行。为了实现这一点,数据库系统通常会使用锁机制来保证同一时间只有一个事务可以访问和修改共享数据。当一个事务获得了所需的锁后,其他事务必须等待该事务释放锁后才能继续执行。
优缺点
- 优点:可以保证事务的一致性和隔离性,避免了脏读、不可重复读和幻读等并发问题。
- 缺点:并发性能较低,因为事务必须串行执行,会导致大量的事务等待时间,降低了系统的吞吐量。
MESI 一致性协议
定义:MESI 协议是一种广泛使用的缓存一致性协议,它是基于总线监听机制实现的。MESI 协议定义了缓存行的四种状态:Modified(已修改)、Exclusive(独占)、Shared(共享)和 Invalid(无效),通过这四种状态的转换来保证缓存一致性。
四种状态
- Modified(已修改):表示该缓存行中的数据已经被修改,并且与主存中的数据不一致。此时,该处理器是唯一拥有该数据最新副本的处理器,并且负责将修改后的数据写回主存。
- Exclusive(独占):表示该缓存行中的数据只被一个处理器的缓存持有,并且与主存中的数据一致。如果该处理器对该数据进行写操作,它可以直接将状态转换为 Modified 状态,而不需要与其他处理器进行额外的通信。
- Shared(共享):表示该缓存行中的数据与主存中的数据一致,并且可能被多个处理器的缓存共享。当一个处理器对共享数据进行写操作时,需要先将其他处理器缓存中的该数据副本标记为 Invalid 状态。
- Invalid(无效):表示该缓存行中的数据是无效的,需要从主存或其他处理器的缓存中重新获取。
工作原理:每个处理器的缓存控制器会监听系统总线,当其他处理器对共享数据进行操作时,会通过总线广播相应的消息。缓存控制器根据接收到的消息和当前缓存行的状态,进行状态转换和数据更新。
原子序
为什么会有原子序的问题?
- 编译器优化重排
- cpu指令优化重排
内存序规定了什么?
- 规定了多个线程访问同一个内存地址时的语义
- 某个线程对内存地址的更新何时能被其他线程看见
- 某个线程对内存地址访问附近可以做怎样的优化
6种不同的内存序
- memory_order_relaxed:松散内存序,只用来保证对原子对 象的操作是原子的,在不需要保证顺序时使用;
- memory_order_release:释放操作,在写入某原子对象时, 当前线程的任何前面的读写操作都不允许重排到这个操作的后面 去,并且当前线程的所有内存写入都在对同一个原子对象进行获 取的其他线程可见;
- memory_order_acquire:获得操作,在读取某原子对象时,当前线程的任何后面的读写操作都不允许重排到这个操作的前面去,并且其他线程在对同一个原子对象释放之前的所有内存写入都在当前线程可见;
- memory_order_consume:不建议使用;
- memory_order_acq_rel:获得释放操作,一个读‐修改‐写操作 同时具有获得语义和释放语义,即它前后的任何读写操作都不允 许重排,并且其他线程在对同一个原子对象释放之前的所有内存 写入都在当前线程可见,当前线程的所有内存写入都在对同一个 原子对象进行获取的其他线程可见;
- memory_order_seq_cst:顺序一致性语义,对于读操作相当 于获得,对于写操作相当于释放,对于读‐修改‐写操作相当于获 得释放,是所有原子操作的默认内存序,并且会对所有使用此模 型的原子操作建立一个全局顺序,保证了多个原子变量的操作在 所有线程里观察到的操作顺序相同,当然它是最慢的同步模型。
在多线程情况下是否保证 | 可见性 | 顺序性 |
memory_order_relaxed | x | x |
memory_order_acquire | √ | √ |
memory_order_release | √ | √ |
memory_order_consume | - | - |
memory_order_acq_rel | √ | √ |
memory_order_seq_cst | √ | √ |
共享指针(shared_ptr)
std::shared_ptr
采用引用计数的方式来管理对象。当一个 std::shared_ptr
被创建并指向一个对象时,该对象的引用计数会被初始化为 1。每当有新的 std::shared_ptr
指向同一个对象时,引用计数就会加 1;而当一个 std::shared_ptr
被销毁(例如离开其作用域)或者被重新赋值指向其他对象时,引用计数会减 1。当引用计数变为 0 时,意味着没有任何 std::shared_ptr
再指向该对象,此时 std::shared_ptr
会自动释放该对象所占用的内存。
我们用原子变量来实现shared_ptr种引用技术的实现
#pragma once#include <atomic>// 自定义的 shared_ptr 模板类,用于管理动态分配的对象
template <typename T>
class shared_ptr {
public:// 默认构造函数,初始化 ptr_ 为 nullptr,ref_count_ 也为 nullptr// 表示这个 shared_ptr 不管理任何对象shared_ptr() : ptr_(nullptr), ref_count_(nullptr) {}// 带参数的构造函数,接受一个指向 T 类型对象的指针// 使用 explicit 关键字防止隐式转换// 如果传入的指针不为空,创建一个新的原子引用计数对象并初始化为 1// 否则,ref_count_ 为 nullptrexplicit shared_ptr(T* ptr) : ptr_(ptr), ref_count_(ptr ? new std::atomic<std::size_t>(1) : nullptr) {}// 析构函数,调用 release 方法来释放管理的对象和引用计数~shared_ptr() {release();}// 拷贝构造函数,用于创建一个新的 shared_ptr 并共享另一个 shared_ptr 管理的对象// 复制 ptr_ 和 ref_count_// 如果 ref_count_ 不为空,将引用计数加 1shared_ptr(const shared_ptr<T>& other) : ptr_(other.ptr_), ref_count_(other.ref_count_) {if (ref_count_) {// 使用 std::memory_order_relaxed 进行原子操作,只保证原子性,不保证顺序ref_count_->fetch_add(1, std::memory_order_relaxed);}}// 拷贝赋值运算符,用于将一个 shared_ptr 的值赋给另一个 shared_ptr// 首先检查是否是自我赋值,如果不是则释放当前管理的对象和引用计数// 然后复制 ptr_ 和 ref_count_,如果 ref_count_ 不为空,将引用计数加 1shared_ptr<T>& operator=(const shared_ptr<T>& other) {if (this != &other) {release();ptr_ = other.ptr_;ref_count_ = other.ref_count_;if (ref_count_) {ref_count_->fetch_add(1, std::memory_order_relaxed);}}return *this;}// noexcept 表示这个函数不会抛出异常,编译器可以生成更高效的代码// 移动构造函数,用于将另一个 shared_ptr 的所有权转移到当前 shared_ptr// 复制 ptr_ 和 ref_count_,并将原 shared_ptr 的 ptr_ 和 ref_count_ 置为 nullptrshared_ptr<T>(shared_ptr<T>&& other) noexcept : ptr_(other.ptr_), ref_count_(other.ref_count_) {other.ptr_ = nullptr;other.ref_count_ = nullptr;}// 移动赋值运算符,用于将另一个 shared_ptr 的所有权转移到当前 shared_ptr// 首先检查是否是自我赋值,如果不是则释放当前管理的对象和引用计数// 然后复制 ptr_ 和 ref_count_,并将原 shared_ptr 的 ptr_ 和 ref_count_ 置为 nullptrshared_ptr<T>& operator=(shared_ptr<T>&& other) noexcept {if (this != &other) {release();ptr_ = other.ptr_;ref_count_ = other.ref_count_;other.ptr_ = nullptr;other.ref_count_ = nullptr;}return *this;}// 解引用运算符重载,返回管理对象的引用// 允许像使用普通指针一样使用 shared_ptr 进行解引用操作T& operator*() const {return *ptr_;}// 箭头运算符重载,返回管理对象的指针// 允许像使用普通指针一样使用 shared_ptr 调用对象的成员函数T* operator->() const {return ptr_;}// 获取当前 shared_ptr 管理对象的引用计数// 如果 ref_count_ 不为空,使用 std::memory_order_acquire 加载引用计数的值// 否则返回 0std::size_t use_count() const {return ref_count_ ? ref_count_->load(std::memory_order_acquire) : 0;}// 获取管理对象的原始指针T* get() const {return ptr_;}// 重置 shared_ptr 管理的对象// 首先释放当前管理的对象和引用计数// 然后将 ptr_ 指向新的对象,如果新对象不为空,创建一个新的引用计数对象并初始化为 1void reset(T * p = nullptr) {release();ptr_ = p;ref_count_ = p ? new std::atomic<std::size_t>(1) : nullptr;}private:// 释放管理的对象和引用计数// 使用 std::memory_order_acq_rel 进行原子操作,保证操作的原子性和顺序// 如果引用计数减 1 后变为 1,表示这是最后一个引用,释放对象和引用计数void release() {if (ref_count_ && ref_count_->fetch_sub(1, std::memory_order_acq_rel) == 1) {delete ptr_;delete ref_count_;}}// 指向管理对象的指针T* ptr_;// 指向原子引用计数对象的指针std::atomic<std::size_t>* ref_count_;
};
相关文章:
原子操作CAS(Compare-And-Swap)和锁
目录 原子操作 优缺点 锁 互斥锁(Mutex) 自旋锁(Spin Lock) 原子性 单核单CPU 多核多CPU 存储体系结构 缓存一致性 写传播(Write Propagation) 事务串行化(Transaction Serialization&#…...
Aspose.Words导出word,服务器用内存流处理,不生成磁盘文件
框架集:.NET8 public async Task<IActionResult> ExportPDF(long? id) {var infoawait form_Dahui_ReportDao.GetAsync(id);if (info null){return Content("没找到数据");}//读取word模板string fileTemp Path.Combine(AppContext.BaseDirect…...
攻防世界——Web题ez_curl
目录 Express PHP和Node.js的解析差异 Python代码 这道题最终得不到flag,用了很多师傅的代码也不成功。但还是需要学习 下载的附件: const express require(express);const app express();const port 3000; const flag process.env.flag;app.ge…...
力扣面试150题--螺旋矩阵
Day 20 题目描述 思路 根据题目描述,我们需要顺时针输出矩阵元素,顺时针说明有四种输出状态,横向从左到右和从右到左,纵向从上到下和从下到上,唯一的难点在于,输出完成一层后,如何进入内层&am…...
智能指针之设计模式2
前面介绍了工厂模式控制了智能指针和资源对象的创建过程,现在介绍一下智能指针是如何利用代理模式来实现“类指针(like-pointer)”的功能,并控制资源对象的销毁过程的。 2、代理模式 代理模式是为其它对象提供一种代理以控制对这…...
【Redis】redis持久化
Redis 持久化 Redis:非关系型的内存数据库 持久化:将数据永久写入磁盘(内存→磁盘) Redis 默认开启了持久化,默认模式为 RDB 为什么需要持久化? Redis 是内存数据库,宕机或关机后数据会丢失。…...
AtCoder Beginner Contest 401 E题 题解
E - Reachable Sethttp://E - Reachable Set 题意概述 : 给定一个无向图, 对于每个 ,解决以下问题: -选择最少的一些顶点,使得删除这些顶点及其关联的所有边后 点1只能到达以内的所有点 牵制芝士 :头文…...
Kubernetes控制平面组件:API Server Webhook 授权机制 详解
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
【CodeMirror】系列(二)官网示例(六)自动补全、边栏
一、自动补全 codemirror/autocomplete 包提供了在编辑器中显示输入建议的功能。这个示例展示了如何启用该功能以及如何编写自己的补全来源。 自动补全是通过在编辑器的配置项中加入 autocompletion 扩展实现的。有些语言包支持内置的自动补全功能,比如HTML包。 默…...
CSS 表格样式学习笔记
CSS 提供了强大的工具来美化和定制 HTML 表格的外观。通过合理使用 CSS 属性,可以使表格更加美观、易读且功能强大。以下是对 CSS 表格样式的详细学习笔记。 一、表格边框 1. 单独边框 默认情况下,表格的 <table>、<th> 和 <td> 元…...
简单记录一下Android四大组件
1、Android Layout 1.1、LinearLayout 线性布局,子控件按照水平或垂直的方向依次排列,排列方向通过属性android:orientation控制,horizontal为水平排列,vertical为垂直排列。对于同一水平线上的控件,可以调整它的lay…...
在线地图支持天地图和腾讯地图,仪表板和数据大屏支持发布功能,DataEase开源BI工具v2.10.7 LTS版本发布
2025年4月11日,人人可用的开源BI工具DataEase正式发布v2.10.7 LTS版本。 这一版本的功能变动包括:数据源方面,Oracle数据源支持获取和查询物化视图;图表方面,在线地图支持天地图、腾讯地图;新增子弹图&…...
【图像处理基石】什么是通透感?
一、画面的通透感定义 画面的通透感指图像在色彩鲜明度、空间层次感、物体轮廓清晰度三方面的综合表现,具体表现为: 色彩鲜明:颜色纯净且饱和度适中,无灰暗或浑浊感;层次分明:明暗过渡自然,光…...
猫咪如厕检测与分类识别系统系列【六】分类模型训练+混合检测分类+未知目标自动更新
前情提要 家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠的如…...
NoSQL入门指南:Redis与MongoDB的Java实战
一、为什么需要NoSQL? 在传统SQL数据库中,数据必须严格遵循预定义的表结构,就像把所有物品整齐摆放在固定尺寸的货架上。而NoSQL(Not Only SQL)数据库则像一个灵活的储物间,允许存储各种类型的数据&#x…...
游戏引擎学习第223天
回顾 今天我们正在进行过场动画序列的制作,因此我想深入探讨这个部分。昨天,我们暂时停止了过场动画的制作,距离最终结局还有一些内容没有完成。今天的目标是继续完成这些内容。 我们已经制作了一个过场动画的系列,并把它们集中…...
【redis进阶二】分布式系统之主从复制结构(1)
目录 一 为什么要有分布式系统? 二 分布式系统涉及到的非常关键的问题:单点问题 三 学习部署主从结构的redis (1)创建一个目录 (2)进入目录拷贝两份原有redis (3)使用vim修改几个选项 (4)启动两个从节点服务器 (5)建立复制,要想配…...
(自用)若依生成左树右表
第一步: 在数据库创建树表和单表: SQL命令: 商品表 CREATE TABLE products (product_id INT AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(255) , price DECIMAL(10, 2) , stock INT NOT NULL, category_id INT NOT NULL); 商品分类…...
VectorBT量化入门系列:第六章 VectorBT实战案例:机器学习预测策略
VectorBT量化入门系列:第六章 VectorBT实战案例:机器学习预测策略 本教程专为中高级开发者设计,系统讲解VectorBT技术在量化交易中的应用。通过结合Tushare数据源和TA-Lib技术指标,深度探索策略开发、回测优化与风险评估的核心方法…...
5G网络下客户端数据业务掉线频繁
MCPTT(Mission Critical Push-to-Talk)客户端的日志,和界面在待机状态下(即没有做通话等业务操作),会频繁提示“离线”。 主要先看有没有丢网,UL BLER有没有问题。确认没有问题。看到业务信道释…...
CPU(中央处理器)
一、CPU的定义与核心作用 CPU 是计算机的核心部件,负责 解释并执行指令、协调各硬件资源 以及 完成数据处理,其性能直接影响计算机的整体效率。 核心功能: 从内存中读取指令并译码。执行算术逻辑运算。控制数据在寄存器、内存和I/O设备间的…...
Java从入门到“放弃”(精通)之旅——程序逻辑控制④
Java从入门到“放弃”(精通)之旅🚀:程序逻辑的完美理解 一、开篇:程序员的"人生选择" 曾经的我,生活就像一段顺序执行的代码: System.out.println("早上8:00起床"); Syste…...
[Dify] 基于明道云实现金融业务中的Confirmation生成功能
在金融业务的日常流程中,交易记录的处理不仅涉及数据录入、流程审批,更重要的是其最终输出形式——交易确认函(Confirmation)。本文将介绍如何通过明道云的打印模板功能,快速、准确地生成符合业务需求的交易Confirmation,提升工作效率与合规性。 为什么需要Confirmation?…...
Qt安卓设备上怎么安装两个不同的Qt应用?
在安卓设备上安装两个不同的Qt应用时,需要确保这两个应用在安卓系统中被视为独立的应用程序。以下是详细的步骤和注意事项,帮助你实现这一目标: 一、修改应用的包名 安卓系统通过应用的包名(package属性)来区分不同的…...
Prompt工程提示词(1-6章)
White graces:个人主页 🐹今日诗词:怅望千秋一洒泪,萧条异代不同时🐹 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 目录 🚀 第…...
0基础 | 硬件滤波 C、RC、LC、π型
一、滤波概念 (一)滤波定义 滤波是将信号中特定波段频率滤除的操作,是抑制和防止干扰的重要措施。通过滤波器实现对特定频率成分的筛选,确保目标信号的纯净度,提升系统稳定性。 (二)滤波器分…...
C++ 编程指南34 - C++ 中 ABI 不兼容的典型情形
一:概述 ABI(Application Binary Interface)是二进制层面的接口规范。如果一个库的 ABI 发生了变化,那么基于旧 ABI 编译的代码可能在运行时与新库不兼容(即使接口名字都一样也不行)。那么在C++中编程中,哪些情形会导致ABI不兼容呢?下面逐一列举一下。 二:C++ 中 ABI…...
【动态规划】深入动态规划:背包问题
文章目录 前言01背包例题一、01背包二、分割等和子集三、目标和四、最后一块石头的重量|| 完全背包例题一、完全背包二、 零钱兑换三、零钱兑换||四、完全平方数 前言 什么是背包问题,怎么解决算法中的背包问题呢? 背包问题 (Knapsack problem) 是⼀种组…...
NVIDIA AI Aerial
NVIDIA AI Aerial 适用于无线研发的 NVIDIA AI Aerial 基础模组Aerial CUDA 加速 RANAerial Omniverse 数字孪生Aerial AI 无线电框架 用例构建商业 5G 网络加速 5G生成式 AI 和 5G 数据中心 加速 6G 研究基于云的工具 优势100% 软件定义通过部署在数字孪生中进行测试6G 标准化…...
计算机视觉6——相机基础
一、数字相机基本工作原理 (一)像素概念 数字相机生成二维图像,图像最小单元是像素。 每个像素对应三维世界中某个特定方向,像素值衡量某一时刻来自该方向的光照强度/颜色 ,即相机度量每个像素的光照情况并保存到对…...
入门到精通,C语言十大经典程序
以下是十个经典的C语言程序示例,这些程序涵盖了从基础到稍复杂的应用场景,适合初学者和有一定基础的开发者学习和参考。 1. Hello, World! 这是每个初学者学习编程时的第一个程序,用于验证开发环境是否正确配置。 #include <stdio.h>…...
【毕设】Python构建基于TMDB电影推荐系统
个性化电影推荐系统 这是一个基于FastAPI开发的现代化电影推荐系统,结合了协同过滤和深度学习技术,为用户提供个性化的电影推荐服务。 主要功能 🎯 个性化电影推荐🔍 电影搜索与浏览⭐ 电影评分系统💝 收藏夹功能&a…...
嵌入式常见概念的介绍
目录 一、MCU、MPU、ARM (一)MCU(微控制器) (二)MPU(微处理器) (三)ARM(架构) 二、DSP (一)数字信号处理…...
富兴号:拨云见日,打造普洱品质典范
在高端普洱茶市场的混沌格局中,价格与品质的天平严重失衡,消费者往往深陷 “高价却难觅好茶” 的困境。而新兴品牌富兴号强势崛起,奋力冲破这一迷局,致力于重塑 “号级茶” 的卓越品质,为茶叶赋予珍贵的品鉴与收藏价值…...
【WORD】批量将doc转为docx
具体步骤进行: 打开Word文档,按下AltF11快捷键,打开VBA编辑器。在VBA编辑器中,左侧的“项目资源管理器”窗口会显示当前打开的Word文档相关项目。找到您要添加代码的文档项目(通常以文档名称命名)…...
Linux内存管理架构(1)
0.内存空间架构 1.用户空间 在 Linux 系统中,应用程序通过 malloc() 申请内存,并通过 free() 释放内存时,底层的内存管理是由 glibc(GNU C Library)中的内存分配器实现的。glibc 的内存分配器负责与操作系统的内核交互…...
Ubuntu 各个常见长期支持历史版本与代号
文章目录 1. Ubuntu 历史版本与代号2. 查看当前系统版本 在 Ubuntu 操作系统里,每个版本都有一个别具特色的名字。该名字由一个形容词与一个动物名称构成,且形容词和动物名称的首字母是一样的。例如 “Warty Warthog(长疣的疣猪)”…...
信息安全管理与评估2021年国赛正式卷答案截图以及十套国赛卷
2021年全国职业院校技能大赛高职组 “信息安全管理与评估”赛项 任务书1 赛项时间 共计X小时。 赛项信息 赛项内容 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 平台搭建与安全设备配置防护 任务1 网络平台搭建 任务2 网络安全设备配置与防护 第二…...
在线上定位1G日志文件中的异常信息时,我这样做合适吗
1G级线上日志文件 的异常定位系统性方案 一、快速定位流程 import datetime import randomdef generate_springboot_log(file_name, file_size_gb):# 模拟Spring Boot日志内容log_levels ["INFO", "DEBUG", "WARNING", "ERROR"]cla…...
Transformer模型中的两种掩码
模型训练通常使用 批处理batch来提升训练效率。而实际中Transformer的输入序列(如句子、文本片段)长度往往不一致。为了让这些样本可以组成一个统一的形状 [B, T] 的张量给GPU进行并行计算提高效率,需要将较短的序列填充(pad&…...
FastAPI-MPC正式发布,新的AI敏捷开发利器
FastAPI-MCP发布:零配置构建微服务控制平台的革命性实践 引言 在微服务架构日益复杂的今天,如何快速实现API接口的标准化管理与可视化控制成为开发者面临的核心挑战。近日,FastAPI-MCP工具的发布引发了技术社区广泛关注,其宣称能…...
Spring Boot 项目基于责任链模式实现复杂接口的解耦和动态编排!
全文目录: 开篇语前言一、责任链模式概述责任链模式的组成部分: 二、责任链模式的核心优势三、使用责任链模式解耦复杂接口1. 定义 Handler 接口2. 实现具体的 Handler3. 创建订单对象4. 在 Spring Boot 中使用责任链模式5. 配置责任链6. 客户端调用 四、…...
学习笔记八——内存管理相关
📘 目录 内存结构基础:栈、堆、数据段Rust 的内存管理机制(对比 C/C、Java)Drop:Rust 的自动清理机制Deref:为什么 *x 能访问结构体内部值Rc:多个变量“共享一个资源”怎么办?Weak&…...
Deepseek Bart模型相比Bert的优势
BART(Bidirectional and Auto-Regressive Transformers)与BERT(Bidirectional Encoder Representations from Transformers)虽然均基于Transformer架构,但在模型设计、任务适配性和应用场景上存在显著差异。以下是BART…...
Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM)
Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM) 问题模板解题思路1. 导入必要的库2. 加载数据3. 划分训练集和测试集4. 数据预处理5. 定义算法及其参数6. 存储算法和对应指标7. 训练模型并计算指标8. 找…...
达梦数据库-学习-20-慢SQL优化之CTE等价改写
目录 一、环境信息 二、介绍 三、优化过程 1、原始SQL 2、源SQL执行时间 3、原始SQL执行计划 4、拆分问题 5、过滤性 6、统计信息收集 7、改写思路一 8、改写SQL一 9、改写SQL一的执行计划 10、改写思路二 11、改写SQL二 12、改写SQL二的执行计划 一、环境信息…...
软件生命周期模型:瀑布模型、螺旋模型、迭代模型、敏捷开发、增量模型、快速原型模型
目录 1.软件生命周期 2.软件生命周期模型 2.1瀑布模型 缺点【存在的问题】: 优点: 2.2 螺旋模型 特点: 2.3 迭代模型 优点: 2.4 敏捷开发 2.5 增量模型 增量模型一般和迭代模型一起使用: 2.6 快速原型模型…...
AI agents系列之全面介绍
随着大型语言模型(LLMs)的出现,人工智能(AI)取得了巨大的飞跃。这些强大的系统彻底改变了自然语言处理,但当它们与代理能力结合时,才真正释放出潜力——能够自主地推理、规划和行动。这就是LLM代理大显身手的地方,它们代表了我们与AI交互以及利用AI的方式的范式转变。 …...
Ubuntu 下通过 Docker 部署 WordPress 服务器
最近想恢复写私人博客的习惯,准备搭建一个wordpress。 在这篇博客中,我将记录如何在 Ubuntu 环境下通过 Docker 部署一个 WordPress 服务器。WordPress 是一个流行的内容管理系统(CMS),它让用户能够轻松地创建和管理网…...
Elasticsearch生态
目录 Elasticsearch核心概念 Elasticsearch实现全文检索的原理 Elasticsearch打分规则 常用的查询语法 ES数据同步方案 Elasticsearch生态非常丰富,包含了一系列工具和功能,帮助用户处理、分析和可视化数据,Elastic Stack是其核心部分&a…...