ARM 架构下 cache 一致性问题整理
本篇文章主要整理 ARM 架构下,和 Cache 一致性相关的一些知识。
本文假设读者具备一定的计算机体系结构和 Cache 相关基础知识,适合有相关背景的读者阅读
1、引言
简单介绍一下 Cache 和内存之间的关系
在使能 Cache 的情况下,CPU 每次获取数据都会先访问 Cache,如果获取不到数据则把数据加载到 Cache 中进行访问
数据在 Cache 与 Memory 之间移动的最小单位通常在 32 - 128 字节之间。
- Memory 中对应的最小单位数据称为 Cache Block
- Cache 中与单个 Cache Block 对应的存储空间称为 Cache Line
在 Cache 中除了存储 Block 数据,还需要存储 Block 对应的唯一标识 (Tag),以及一个用于标记 Cache Line 是否有数据的有效位。完整对应关系如下图所示:

2、cache 的更新策略与写策略
Read-allocate cache:
A cache in which a cache miss on reading data causes a cache line to be allocated into the cache
Write-allocate cache:
A cache in which a cache miss on storing data causes a cache line to be allocated into the cache
Write-back cache:
A cache in which when a cache hit occurs on a store access, the data is only written to the cache. Data in the cache
can therefore be more up-to-date than data in main memory. Any such data is written back to main memory when
the cache line is cleaned or reallocated. Another common term for a write-back cache is a copy-back cache.
Write-through cache:
A cache in which when a cache hit occurs on a store access, the data is written both to the cache and to main memory. This is normally done via a write buffer, to avoid slowing down the processor
———《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》
因为后面的讲解会用到这些个概念,所以这里简单介绍下。详细的内容可以去研究 ARM 官方手册:
Write-through
- 定义:在 Write-through 策略中,每当数据被写入缓存时,系统会立即将数据同步写入主存。这意味着缓存和主存中的数据始终保持一致。
- 优点:数据的一致性较好,因为主存与缓存始终同步。即使系统崩溃或掉电,主存中的数据不会丢失。
- 缺点:性能较低,因为每次写入操作都要同时写入缓存和主存。这会导致更高的延迟和更多的存储带宽消耗。
Write-back
- 定义:在 Write-back 策略中,数据只有在从缓存中被替换或被其他操作所驱逐时,才会写回到主存。也就是说,数据在缓存中进行修改,但只有在必要时才会同步到主存。
- 优点:性能较高,因为数据写入缓存时无需立刻写入主存,这减少了写操作对主存的访问频率。
- 缺点:数据的一致性较差,因为主存中的数据可能与缓存中的数据不同步。若系统崩溃,缓存中的数据可能丢失。
3、单核 cache 和 内存之间一致性
单核处理器下的 Cache Policy 要解决的问题可以被概括为:
- CPU 从 Cache 中读到的数据必须是最近写入的数据
要满足定义,最简单的方式就是 Write-Through,即每次写入 Cache 时,也将数据写到 Memory 中。但是这样带来的问题,就是更高的延迟和更多的存储带宽消耗。现代 CPU 几乎都是采取 Write-back 策略来管理 Cache,可以提升系统性能,但是该策略带来了数据一致性问题,需要软件开发人员去注意、维护
3.1 DMA 带来的一致性问题
背景:某些外设(如网卡、磁盘控制器)会使用 DMA(Direct Memory Access)直接访问内存,而不会经过 CPU cache。
场景:
- CPU 先读取某块数据到 cache,并在 cache 里修改该数据
- DMA 设备直接从内存中读取数据,而此时的内存数据仍然是旧的(未更新的)
- 最终,CPU 看到的是缓存中的新数据,而 DMA 设备读取的却是旧数据,导致数据不一致
解决方案:
- Cache Flush(缓存刷新):在数据同步前,手动刷新 cache(如 clflush 指令)
- Memory Barrier(内存屏障):强制 CPU 在特定时间点刷新内存访问
这里推荐一篇文章《Stale data, or how we (mis-)manage modern caches》
,讲的很详细,关于 ARM 架构中,Cache 和 DMA 一致性相关问题。这里只讲结论:
- Step(2):因为那片内存可能有 dirty 位,当 dma 读的时候,可能会有 cache 淘汰,这样 dma 读的区域就会错,所以 dma 读的时候,如果读的内存可以被 cache 同时 cache 没有强一致性,那么就需要先 cache invalid 再进行 dma 读
- Step(4):有些 处理器在 DMA 传输过程中会随机预取,因为是传输过程中,buffer 肯定有部分没有数据、或是不稳定状态,这时如果发生了预取(将内存预取到 cache),就会预取到脏数据,所以,DMA read 之后,也要 invalid 一下
4、多核 cache 之间的一致性
在多核 CPU 模式下,对缓存数据的写入还可能带来缓存一致性的问题。
譬如核心 A 和 B 都同时运行两个线程,都操作相同的变量(全局变量),那么必然会带来一致性的问题,为了保证一致性,需要保证做到以下两点:
- 某个 CPU 核心里的 Cache 数据更新时,必须要传播到其他核心的 Cache,这个称为写传播(Write Propagation)
- 某个 CPU 核心对数据的操作顺序,必须在其他核心看起来顺序是一致的,这个称为事务串行化(Transaction Serialization)
对于第一点,写传播,可以这样理解。假设我们有一个含有 4 个核心的 CPU,这 4 个核心都需要依赖共同的变量 i(全局变量)。假设某时刻,CPU 0 将 i 修改成值 5,那么必须确保,其余几个核,也能收到变量 i 被修改成值 5 这个事件。
而对于第二点事务的串形化,我们举个例子来理解它。
假设我们有一个含有 4 个核心的 CPU,这 4 个核心都操作共同的变量 i(初始值为 0 )。A 号核心先把 i 值变为 100,而此时同一时间,B 号核心先把 i 值变为 200,这里两个修改,都会 “传播” 到 C 和 D 号核心。

那么问题就来了,C 号核心先收到了 A 号核心更新数据的事件,再收到 B 号核心更新数据的事件,因此 C 号核心看到的变量 i 是先变成 100,后变成 200。
而如果 D 号核心收到的事件是反过来的,则 D 号核心看到的是变量 i 先变成 200,再变成 100,虽然是做到了写传播,但是各个 Cache 里面的数据还是不一致的。
所以,我们要保证 C 号核心和 D 号核心都能看到相同顺序的数据变化,比如变量 i 都是先变成 100,再变成 200,这样的过程就是事务的串形化。
要实现事务串形化,要做到 2 点:
- CPU 核心对于 Cache 中数据的操作,需要同步给其他 CPU 核心(其实就是写传播)
- 要引入"锁" 的概念,如果两个 CPU 核心里有相同数据的 Cache,那么对于这个 Cache 数据的更新,只有拿到了「锁」,才能进行对应的数据更新。
4.1 MESI 协议
“写传播” 主要依赖于 MESI、MOESI 这些缓存一致性协议。
MESI 协议是处理多个 CPU 之间 cache 一致性常用的协议,基于 snooping 实现,该协议中有四个状态位来描述每一个 cache 行:
- M(modified),已修改位。状态就是我们前面提到的脏标记,代表该 Cache Block 上的数据已经被更新过,但是还没有写到内存里
- E(exclusive),独占位。独占状态的时候,数据只存储在一个 CPU 核心的 Cache 里,而其他 CPU 核心的 Cache 没有该数据
- S(shared),共享位。状态代表着相同的数据在多个 CPU 核心的 Cache 里都有,所以当我们要更新 Cache 里面的数据的时候,不能直接修改,而是要先向所有的其他 CPU 核心广播一个请求,要求先把其他核心的 Cache 中对应的 Cache Line 标记为「无效」状态,然后再更新当前 Cache 里面的数据
- 独占和共享状态都代表 Cache Block 里的数据是干净的,也就是说,这个时候 Cache Block 里的数据和内存里面的数据是一致性的
- I(invalid),已失效位。表示的是这个 Cache Block 里的数据已经失效了,不可以读取该状态的数据
MESI 只针对多核之间的 Dcache,不包括 Icache。因为 Icache 是只读的,不存在一致性问题
随着缓存一致性协议的发展,涌现出了诸如 MOESI、MESIF、Dragon 、ACE 、AXI 等诸多类型的缓存一致性协议。例如,Cortex-A7 中使用的就是 MOESI
Cortex-A7 MPCore processor supports between one and four individual processors with L1 data
cache coherency maintained by the SCU. The SCU is clocked synchronously and at the same
frequency as the processors.
The SCU maintains coherency between the individual data caches in the processor using ACE
modified equivalents of MOESI state, as described in Data Cache Unit on page 2-4.
——《 Cortex™-A7 MPCore Technical Reference Manual 》![]()
注:
有些处理器,需要单独去使能、配置 Snnop 单元,例如 Cortex-A9

4.2 事务串行化
回忆一下,上面提到的事务串行化的一个必要条件:
要引入"锁" 的概念,如果两个 CPU 核心里有相同数据的 Cache,那么对于这个 Cache 数据的更新,只有拿到了「锁」,才能进行对应的数据更新。
这里的,“锁” 主要指的是对共享资源的访问控制机制,可以通过硬件和软件两方面实现:
(1)硬件层面的锁(基于原子指令)
在 ARM 架构中,提供了一组特殊的原子操作指令来支持锁的实现,最常见的是:
- LDREX (Load Exclusive) / STREX (Store Exclusive)
- LDREX 读取某个内存地址,并标记该地址为“独占访问”
- STREX 试图将新值写回该地址,但如果在此期间该地址被其他核修改过,则 STREX 会失败,写入不生效,需要重新尝试。
这对指令确保了多核环境下的互斥访问,避免多个线程同时修改同一块内存时导致数据不一致。例如,Linux 下的自旋锁,使用的就是 LDREX/STREX 指令
Linux 内核 spinlock 的实现
(2)软件层面的锁(基于互斥量、信号量等)
在操作系统层面,我们可以使用互斥锁(Mutex)、自旋锁(Spinlock)、读写锁(RWLock)等机制来管理并发访问:
- 自旋锁(Spinlock):线程在获取锁时会一直循环检查,不会主动让出CPU(适用于短时间的临界区)
- 互斥锁(Mutex):如果锁被占用,线程会进入睡眠状态,等待锁释放(适用于长时间的临界区)
- 信号量(Semaphore):允许多个线程同时访问一定数量的资源(适用于资源共享场景)
- 读写锁(RWLock):允许多个线程同时读取数据,但写入时必须互斥(适用于读多写少的场景)
(3)内存屏障(Memory Barrier,确保事务的顺序)
ARM 还提供了一些内存屏障指令(Memory Barrier),用于确保CPU按照正确的顺序执行内存访问:
- DMB(Data Memory Barrier):保证所有CPU核心看到的内存访问顺序一致
- DSB(Data Synchronization Barrier):确保之前的所有内存访问完成后,才执行后续指令
- ISB(Instruction Synchronization Barrier):用于指令流水线刷新,确保指令执行的可见性。
4.3 关于 DMA buffer 对齐问题
操作系统在使用 DMA 时,DMA buffer 如果带 cache,则 DMA buffer 一定要 cacheline 对齐。原因如下:
int temp = 5;
char buffer[64] = { 0 };
假设,cacheline 大小是 64 字节。那么 temp 变量和 buffer 位于同一个 cacheline,buffer 横跨两个 cacheline。

假设现在想要启动 DMA 从外设读取数据到buffer中。我们进行如下操作:
- 我们先 invalid buffer 对应的 2 行 cacheline
- 启动 DMA 传输
- 当 DMA 传输到 buff[3] 时,程序改写 temp 的值为 6。temp 的值和 buffer[0]-buffer[60] 的值会被缓存到 cache 中,并且标记 dirty bit。
- DMA 传输还在继续,当传输到 buff[50] 的时候,其他程序可能读取数据导致 temp 变量所在的 cacheline 需要替换,由于cacheline 是 dirty 的。所以cacheline的数据需要写回。此时,将temp数据写回,顺便也会将 buffer[0]-buffer[60] 的值写回。
看到这里就会发现,第三步中,DMA 传输数据的过程中,内存中的脏值会被缓存到 buffer 对应的 cache 中。而后又因为其他程序对 temp 变量的读取,根据 MESI 一致性协议,temp 所在的 cacheline 会被写回内存,会造成脏数据又会被写到内存中的问题。
对于上面的操作,从另一个角度来看:
如果 temp 的值是被当前 CPU 标记为已修改状态,cache 中的 temp 是新数据而内存中是脏值。DMA 传输结束后会去 invalid 一整个 cacheline,而当 CPU 再次访问 temp 时,会出现 invalid、从内存拿脏值的问题。
而对于该问题的解决,通常操作系统内核在 cache invalid 操作中,会判断 start 和 end 是否 cacheline align,如果不对齐会执行 civac(先clean 再invalidate),如果对齐就执行 ivac(只执行invalidate操作)。
如果无法确定当前操作系统关于 cache invalid 的实现是否解决了上述问题,所以,实际开发中,建议申请 DMA buffer 时还是要 cache line 对齐
4.4 Icache 与 Dcache 之间的一致性
重定位时、debug 调试插入断点指令时,通常需要修改指令、修改数据。
这里需要知道两个前提:
- ARM 中,通常 iCache 是只读的,cpu 不会改写 icache 中的数据
- 修改指令时,会将指令 load 到 dcache 中,然后在 dcache 中去修改
这会面临 2 个问题:
- 如果旧指令已经缓存在 iCache 中。而修改后的指令在内存中。那么对于程序执行来说依然会命中 iCache。这不是我们想要的结果
- 如果 dCache 使用的是写回(write_back)策略,那么新指令数据依然缓存在 dCache 中。这种情况也不是我们想要的。
所以通常会这么做:
- 将需要修改的指令数据加载到 dCache 中
- 修改成新指令,写回 dCache
- clean dCache 中修改的指令对应的 cacheline,保证 dCache 中新指令写回主存(这里通常是 PoU)
- invalid iCache 中修改的指令对应的 cacheline,保证从主存中读取新指令
当然,对于多核来说,也需要通过像 IPI 核间中断这样的功能,去通知其它所有核去刷新 cache,即 clean dCache、invalid iCache
5、cache 伪共享问题
因为多个线程同时读写同一个 Cache Line 的不同变量时,而导致 CPU Cache 失效的现象称为伪共享(False Sharing)。
Cache Line 伪共享问题,就是由多个 CPU 上的多个线程同时修改自己的变量引发的。这些变量表面上是不同的变量,但是实际上却存储在同一条 Cache Line 里。
在这种情况下,由于 Cache 一致性协议(MESI),两个处理器都存储有相同的 Cache Line 拷贝的前提下,本地 CPU 变量的修改会导致本地 Cache Line 变成 Modified 状态。然后在其它共享此 Cache Line 的 CPU 上,引发 Cache Line 的 Invaidate 操作,导致 Cache Line 变为 Invalidate 状态,从而使 Cache Line 再次被访问时,发生本地 Cache Miss,从而伤害到应用的性能。

False sharing occurs when threads on different processors modify variables that reside on the same cache line. This invalidates the cache line and forces a memory update to maintain cache coherency. Threads 0 and 1 require variables that are adjacent in memory and reside on the same cache line. The cache line is loaded into the caches of CPU 0 and CPU 1 (gray arrows). Even though the threads modify different variables (red and blue arrows), the cache line is invalidated, forcing a memory update to maintain cache coherency.
6、TLB 一致性
TLB 本质上也是 Cache,那么它自然也会存在一致性问题。即:对于多核来说,
- 设置虚拟地址对应物理地址页面 flag 标志时,需要同步刷新所有 CPU TLB
- 将物理页面重新映射时,需要同步刷新所有 CPU TLB
- 设置指定逻辑地址的访问权限,需要同步刷新所有 CPU TLB
同步刷新所有 CPU TLB,一般会通过 IPI 核间中断来完成
如果不是上面这么操作,会存在,1 核 和 2 核 的 TLB 内容相斥,会访问到错误的物理地址,造成无法捕获的异常情况。
有些架构不需要通过 IPI,让其它核同步去刷 TLB,因为架构支持 maintiance broadcast 广播。例如 ARM:
不同处理器对 maintiance broadcast 操作的控制不同,例如,cortex-A9 需要手动设置 ACTLR.FW 和 ACTLR.SMP 寄存器位来使能 maintiance broadcast 功能。而 cortex-A7 不需要,默认支持 maintiance broadcast。
这里要注意,广播不是所有核都会去广播,必须是 Inner Shareable domain:
Maintenance operations can only be broadcast and received when the processor is configured to participate in the Inner Shareable domain, using the SMP bit in ACTLR. Only Inner Shareable operations are broadcast, for example :
● To invalidate TLB entry by virtual address.
● To clean or invalidate data cache line by virtual address
● To invalidate instruction cache line by virtual address
————《 ARM® Cortex™-A Series Programmer’s Guide 》
相关文章:
ARM 架构下 cache 一致性问题整理
本篇文章主要整理 ARM 架构下,和 Cache 一致性相关的一些知识。 本文假设读者具备一定的计算机体系结构和 Cache 相关基础知识,适合有相关背景的读者阅读 1、引言 简单介绍一下 Cache 和内存之间的关系 在使能 Cache 的情况下,CPU 每次获取数…...
算法-二分查找
二分查找 其实二分查找是一个很简单理解的东西,从他的名字就可以看出,就是要分为两段去查找一个元素 我们确定一个中间元素,然后将这一个元素和左边的部分和右边的部分做对比 然后根据实际情况来选择一个部分来继续做这么一个步骤 直到找…...
Python Cookbook-2.24 在 Mac OSX平台上统计PDF文档的页数
任务 你的计算机运行着比较新的MacOSX系统(10.3的“Panther”或更新的版本),现在需要知道一个 PDF 文档的页数。 解决方案 PDF格式和 Python都已经集成到了Mac OsX系统中(10.3或更高版本),因而这个问题解决起来也相对比较容易: #!/usr/bin python im…...
【MySQL】索引(页目录、B+树)
文章目录 1. 引入索引2. MySQL与磁盘交互的基本单位3. 索引的理解3.1 页目录3.2 B树 4. 聚簇索引、非聚簇索引5. 索引的操作5.1 索引的创建5.1.1 创建主键索引5.1.2 创建唯一索引5.1.3 普通索引的创建5.1.4 全文索引的创建 5.2 索引的查询5.3 删除索引 1. 引入索引 索引&#…...
工业AR眼镜的‘芯’动力:FPC让制造更智能【新立电子】
随着增强现实(AR)技术的快速发展,工业AR智能眼镜也正逐步成为制造业领域的重要工具。它不仅为现场工作人员提供了视觉辅助,还极大地提升了远程协助的效率、优化了仓储管理。FPC在AI眼镜中的应用,为工业AR智能眼镜提供了…...
开启mysql的binlog日志
mysql版本5.7 1.查看是否开启bin_log show global variables like’log_bin’; off的话需要先开启 在mysql的文件夹目录中找到my.ini 加一行log-bin“C:/ProgramData/MySQL/MySQL Server 5.7/logs/log-bin” 并提前创建好目录 2.数据库会把日志放进logs目录中 3.查看log日…...
SpringSecurity基于JWT实现Token的处理
前面介绍了手写单点登录和JWT的应用,本文结合SpringSecurity来介绍下在SpringBoot项目中基于SpringSecurity作为认证授权框架的情况下如何整合JWT来实现Token的处理。 一、认证思路分析 SpringSecurity主要是通过过滤器来实现功能的!我们要找到SpringSecurity实现认证和校验…...
数据结构与算法-图论-最短路-floyd扩展
floyd和它的拓展: 在计算机科学领域,Floyd通常指Floyd Warshall算法,由罗伯特弗洛伊德(Robert W. Floyd)提出,这是一种用于在加权有向图中查找所有顶点对之间最短路径的算法。 算法原理 Floyd Warsha…...
c++中所有构造函数的介绍与使用
C 中,构造函数是一种特殊的成员函数,用于在创建对象时对对象进行初始化。C 中有多种类型的构造函数,下面详细介绍这些构造函数及其特点和使用场景。 1. 默认构造函数 定义:默认构造函数是指在没有提供任何参数的情况下可以被调用…...
力扣1584. 连接所有点的最小费用
力扣1584. 连接所有点的最小费用 题目 题目解析及思路 题目要求返回最小生成树 最小生成树模版题 法一:prim 主要思想是每次找离树最近的顶点,将其加入树种,并更新其他所有点到该点的距离 代码 class Solution { public:int minCostCo…...
FPGA开发,使用Deepseek V3还是R1(8):FPGA的全流程(简略版)
以下都是Deepseek生成的答案 FPGA开发,使用Deepseek V3还是R1(1):应用场景 FPGA开发,使用Deepseek V3还是R1(2):V3和R1的区别 FPGA开发,使用Deepseek V3还是R1&#x…...
处理大数据的架构模式:Lambda 架构 和 Kappa 架构
Lambda 架构 和 Kappa 架构 是两种用于处理大数据的架构模式,尤其在实时数据处理场景中广泛应用。 1. Lambda 架构 核心思想 Lambda 架构将数据处理分为两条独立的流水线: 批处理层(Batch Layer): 处理全量数据&…...
Docker网络模式实战
docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分 docker安装后会自动创建3种网络:bridge、host、none docker原生bridge网路 docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口 docker安装时…...
Linux网络基础(协议 TCP/IP 网络传输基本流程 IP VS Mac Socket编程UDP)
文章目录 一.前言二.协议协议分层分层的好处 OSI七层模型TCP/IP五层(或四层)模型为什么要有TCP/IP协议TCP/IP协议与操作系统的关系(宏观上是如何实现的)什么是协议 三.网络传输基本流程局域网(以太网为例)通信原理MAC地址令牌环网 封装与解包分用 四.IP地址IP VS Mac地址 五.So…...
MFC: 控件根据文本内容大小自动调整
背景: 针对不同语言下,控件显示不全的现象; 例如: 现象1:中文下显示全部信息,英语下只能显示部分文字 现象2:中文下显示不全## 实现思路: 控件绑定按钮计算控件文本长度根据文本长…...
记一次线上Tomcat服务内存溢出的问题处理
背景:JavaWeb项目部署在Tomcat服务器上,服务器用的Windows。 问题表现:系统出现偶发性无法访问(隔几天就会在早上无法访问) Tomcat的日志catalina中,有如下报错信息。 java.lang.OutOfMemoryError: GC ov…...
go设计模式
刘:https://www.bilibili.com/video/BV1kG411g7h4 https://www.bilibili.com/video/BV1jyreYKE8z 1. 单例模式 2. 简单工厂模式 代码逻辑: 原始:业务逻辑层 —> 基础类模块工厂:业务逻辑层 —> 工厂模块 —> 基础类模块…...
通往 AI 之路:Python 机器学习入门-语法基础
第一章 Python 语法基础 Python 是一种简单易学的编程语言,广泛用于数据分析、机器学习和人工智能领域。在学习机器学习之前,我们需要先掌握 Python 的基本语法。本章将介绍 Python 的变量与数据类型、条件语句、循环、函数以及文件操作,帮助…...
【再谈设计模式】备忘录模式~对象状态的守护者
一、引言 在软件开发过程中,我们常常会遇到需要保存对象状态以便在之后恢复的情况。例如,在文本编辑器中,我们可能想要撤销之前的操作;在游戏中,玩家可能希望恢复到之前的某个游戏状态。备忘录模式(Memento…...
算法:判断链表是否有环
/*** brief 判断链表是否有环* * 该函数使用快慢指针法来判断链表中是否存在环。* 快指针每次移动两步,慢指针每次移动一步。* 如果链表中存在环,那么快指针最终会追上慢指针;* 如果链表中不存在环,快指针会先到达链表末尾。* * p…...
Android Logcat 高效调试指南
工具概览 Logcat 是 Android SDK 提供的命令行日志工具,支持灵活过滤、格式定制和实时监控,官方文档详见 Android Developer。 基础用法 命令格式 [adb] logcat [<option>] ... [<filter-spec>] ... 执行方式 直接调用(通过ADB守…...
【数据结构与算法】Java描述:第一节:ArrayList顺序表
这篇文章我们自己实现一个顺序表, 从而更好的认识它。 一、顺序表的本质 顺序表的本质其实就是一个数组,但是在插入,查找与删除上,有些复杂,顺序表通过对方法进行封装,方便了使用。 二、自己的顺序表 2.…...
报错The default superclass, “jakarta.servlet.http.HttpServlet“(已经配置好tomcat)
报错报错DescriptionResourcePathLocationType The default superclass,“jakarta.servlet.http.HttpServlet”, according to the project’s Dynamic Web Module facet version (5.0), was not found on the Java Build Path. 解决办法: 根据错误信息࿰…...
在笔记本电脑上用DeepSeek搭建个人知识库
最近DeepSeek爆火,试用DeepSeek的企业和个人越来越多。最常见的应用场景就是知识库和知识问答。所以本人也试用了一下,在笔记本电脑上部署DeepSeek并使用开源工具搭建一套知识库,实现完全在本地环境下使用本地文档搭建个人知识库。操作过程共…...
数学建模:MATLAB极限学习机解决回归问题
一、简述 极限学习机是一种用于训练单隐层前馈神经网络的算法,由输入层、隐藏层、输出层组成。 基本原理: 输入层接受传入的样本数据。 在训练过程中随机生成从输入层到隐藏层的所有连接权重以及每个隐藏层神经元的偏置值,这些参数在整个…...
Immich自托管服务的本地化部署与随时随地安全便捷在线访问数据
文章目录 前言1.关于Immich2.安装Docker3.本地部署Immich4.Immich体验5.安装cpolar内网穿透6.创建远程链接公网地址7.使用固定公网地址远程访问 前言 小伙伴们,你们好呀!今天要给大家揭秘一个超炫的技能——如何把自家电脑变成私人云相册,并…...
Python标准库【os】5 文件和目录操作2
文章目录 8 文件和目录操作8.7 浏览目录下的内容8.8 查看文件或目录的信息8.9 文件状态修改文件标志位文件权限文件所属用户和组其它 8.10 浏览Windows的驱动器、卷、挂载点8.11 系统配置信息 os模块提供了各种操作系统接口。包括环境变量、进程管理、进程调度、文件操作等方面…...
相控阵雷达
相控阵雷达 **1. 基本概念与数学模型**(1) **阵列信号模型**(2) **波束形成原理** **2. 经典波束形成算法****(1) 常规波束形成(Conventional Beamforming, CBF)****(2) 自适应波束形成(Adaptive Beamforming)****2.1 最小方差无失…...
Java 大视界 -- 基于 Java 的大数据分布式缓存一致性维护策略解析(109)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
AI: Cursor是否已奠定AI开发环境的龙头地位?
近年来,人工智能(AI)在软件开发领域的应用迅速升温,而Cursor作为一款AI驱动的代码编辑器,凭借其创新功能和市场表现,引发了广泛讨论。许多人认为,Cursor已经奠定了AI开发环境的龙头地位。然而&a…...
PHP:IDEA开发工具配置XDebug,断点调试
文章目录 一、php.ini配置二、IDEA配置 一、php.ini配置 [xdebug] zend_extension"F:\wamp64\bin\php\php7.4.0\ext\php_xdebug-2.8.0-7.4-vc15-x86_64.dll" xdebug.remote_enable on xdebug.remote_host 127.0.0.1 xdebug.remote_port 9001 xdebug.idekey"…...
回忆Redis的持久化机制
Redis的持久化机制 前言RDB触发方式配置方式手动触发bgsave的执行流程 缺点 AOF重写机制触发方式手动触发自动触发 MP-AOF RDB和AOF混合模式 前言 大家都知道,Redis是内存数据库,也就是说client与Redis交互的过程,无论是读key还是写key都是直…...
partner‘127.0.0.1:3200‘ not reached
在SAP虚拟机中,如果LRPSAP 0显示黄色,通常表示服务启动异常或存在配置问题。以下是一些可能的处理方法: 检查主机文件配置 确保主机文件(hosts)中已正确配置SAP服务的域名解析。例如,添加以下内容到hosts文…...
网络配置的基本信息
目录 一、网络接口信息 1、关闭虚拟化服务 2、配置临时IP 3、配置静态IP 4、常见网络命令 5、安装Wireshark 一、网络接口信息 输入 ip address,会出现下面的内容 网卡名称及其含义: 网卡名称说明lo 表示本地回环地址。 ens32 有线网卡,…...
SpringBoot集成Mybatis(包括Mybatis-Plus)和日志
一、使用Mybatis 1.添加依赖 <!--Mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version> <!-- 选择与Java 8兼容的版本 --&g…...
如何在 IntelliJ IDEA 中集成 DeepSeek
如何在 IntelliJ IDEA 中集成 DeepSeek 在本教程中,我们将带您一步步完成将 DeepSeek 集成到 IntelliJ IDEA 中的过程。通过此集成,您可以在IDE中利用DeepSeek强大的功能,提高开发工作效率。 步骤 1:安装 Proxy AI 插件 首先&a…...
【自学笔记】大数据基础知识点总览-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 大数据基础知识点总览1. 大数据概述2. 大数据处理技术3. 数据仓库与数据挖掘4. 大数据分析与可视化5. 大数据平台与架构6. 大数据安全与隐私 总结 大数据基础知识点…...
AWS ALB 实现灰度验证指南:灵活流量分配与渐进式发布
AWS Application Load Balancer (ALB) 作为七层负载均衡器,支持基于权重或内容的路由策略,是实施灰度验证(金丝雀发布)的核心工具。通过将部分流量导向新版本后端,可以安全验证功能稳定性。以下是使用 ALB 实现灰度发布的详细方案。 © ivwdcwso (ID: u012172506) 一…...
专线物流公共服务平台:全面提升专线物流效率
专线物流公共服务平台:全面提升专线物流效率 在物流行业高速发展的今天,专线物流作为物流供应链的重要环节,面临着效率低下、成本高企、信息孤岛等痛点。临沂呆马区块链网络科技有限公司(简称“呆马科技”)凭借其在大…...
行为型模式 - 观察者模式 (Publish/Subscribe)
行为型模式 - 观察者模式 (Publish/Subscribe) 又称作为订阅发布模式(Publish-Subscribe Pattern)是一种消息传递模式,在该模式中,发送者(发布者)不会直接将消息发送给特定的接收者(订阅者&…...
HTTP/2 服务器端推送:FastAPI实现与前端集成指南
HTTP/2 服务器端推送:FastAPI实现与前端集成指南 注意:本文末尾附有完整示例代码,文中仅展示核心关键代码。完整代码可在GitHub仓库获取。 本文将会讲解HTTP2协议和相关配置实践。但是不要混淆,SSE的实现完全基于HTTP/1.1的持久连…...
C++ 变量的输入输出教程
一、变量的基本概念 在 C 中,变量是用于存储数据的命名内存位置。在使用变量之前,需要先声明它的类型和名称,这样编译器才能为其分配适当大小的内存空间。例如: int age; // 声明一个整型变量 age double salary; // 声明一个…...
java作业
java作业 一. package shiyanbaogao; import java.util.Scanner; //给20块钱买可乐,每瓶可乐3块钱,喝完之后退瓶子可以换回1块钱,问最多可以喝到多少瓶可乐。请设计相应的Java程序。 public class BaoGaoDemo02 {public static void …...
LeeCode题库第四十题
40.组合总和II 项目场景: 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 示…...
list的模拟实现
目录 一、构造和扩容机制 二、普通迭代器 三、const迭代器 四、tip 有了前面vetcor的基础呢,我们在学习和使用list上就更加的方便快捷,浅显易懂了,所以相似的部分我就不做过多的言语阐述了,在使用方面呢,大家可以学…...
pandas DataFrame 数据筛选与排序
数据筛选: df[df[列标签] > xxx] 使用 &(与) |(或) 拼接多个条件代码应用: &(与)应用 # 引用 pandas import pandas as pd # 定义数据 data {"产品":["男装","女装","男鞋","女鞋"…...
elpis全栈课程学习之elpis-core学习总结
elpis全栈课程学习之elpis-core学习总结 核心原理 elpis-core是全栈框架elpis的服务端内核,主要应用于服务端接口的开发以及页面的SSR渲染,elpis-core基于约定优于配置的原理,通过一系列的loader来加载对应的文件,大大节约用户的…...
零基础deep seek+剪映,如何制作高品质的视频短片
以下是专为零基础学习者设计的 剪映专业版详细教程+Deep seek配合制 ,包含从入门到精通的系统化教学,配合具体操作步骤与实用技巧: 基于DeepSeek与剪映协同制作高品质视频短片的专业流程指南(2025年最新实践版&#x…...
解决单元测试 mock final类报错
文章目录 前言解决单元测试 mock final类报错1. 报错原因2. 解决方案3. 示例demo4. 扩展 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每天的运气都不会太差࿰…...
Git基本命令索引
GIT基本命令索引 创建代码库修改和提交代码日志管理远程操作操作分支 创建代码库 操作指令初始化仓库git init克隆远程仓库git clone 修改和提交代码 操作指令查看文件状态git status文件暂存git add文件比较git diff文件提交git commit回滚版本git reset重命名或者移动工作…...