【从零实现高并发内存池】Central Cache从理解设计到全面实现
📢博客主页:https://blog.csdn.net/2301_779549673
📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨
文章目录
- 🏳️🌈一、central cache
- 1.1 整体设计
- 1.2 不同之处
- 1.3 结构设计
- 1.3.1 Span 类
- 1.3.2 SpanList 类
- 1.4 Central Cache 类
- 1.4.1 单例模式
- 1.4.2 慢开始反馈调节算法
- 1.4.3 从中心缓存获取对象
- 👥总结
🏳️🌈一、central cache
1.1 整体设计
当线程申请某一大小的内存时,如果thread cache中对应的自由链表不为空,那么直接取出一个内存块进行返回即可,但如果此时该自由链表为空,那么这时thread cache就需要向central cache申请内存了。
./,
central cache
的结构与 thread cache
是相同的,都是哈希桶结构,并且它们遵循同样的的哈希桶对齐映射规则。这样的好处是: 当thread cache的某个桶中没有内存了,就可以直接到central cache申请内存。
1.2 不同之处
thread cache
与 central cache
有两个明显不同的地方。
-
thread cache是每个线程独享的,而central cache是所有线程共享的 ,因为每个线程的thread cache没有内存了都会去找central cache,因此 在访问central cache时是需要加锁的。
-
central cache在加锁时并不是将整个central cache全部锁上了,central cache在加锁时用的是桶锁,也就是说每个桶都有一个锁 ,也就是说每个桶都有一个锁。此时 只有当多个线程同时访问central cache的同一个桶时才会存在锁竞争,如果是多个线程同时访问central cache的不同桶就不会存在锁竞争。
-
thread cache的每个桶中挂的是一个个切好的内存块 ,而central cache的每个桶中挂的是一个个的span ,每个映射桶下面的span中的大内存块被按映射关系切成了一个个小内存块对象挂在span的自由链表中。
1.3 结构设计
1.3.1 Span 类
在内存池设计中,Span
是 管理大块内存的核心数据结构 ,它连接了中心缓存(Central Cache)与页堆(Page Heap),承担着内存块的分割、分配与回收的核心职责。
每个span管理的都是一个以页为单位的大块内存,每个桶里面的若干span是按照双链表的形式链接起来的,并且每个span里面还有一个自由链表,这个自由链表里面挂的就是一个个切好了的内存块,根据其所在的哈希桶这些内存块被切成了对应的大小。
但是,这样也会有一个难题,就是 页号的类型应该设置成什么呢?
每个程序运行起来后都有自己的进程地址空间,在32位平台下,进程地址空间的大小是232 ;而在64位平台下,进程地址空间的大小就是264。
页大小:操作系统默认页大小通常为 4KB(可配置为 2MB/1GB 大页)。
页号计算公式:
PAGE_ID = Physical_Address >> Page_Shift;
例如:物理地址 0x12345000,页大小为 4KB(Page_Shift=12),则页号 _PAGEID = 0x12345
若物理地址超过 32 位范围(如 0x2000000000),X86 的 uint32_t 会溢出,导致页号计算错误。
X86:32 位页号足够处理 4GB 内存的连续性检测。
X64:必须使用 64 位页号,否则大内存场景(如 128GB)会出现错误合并或无法合并。
所以我们可以通过 预编译指令 动态选择数据类型
#ifdef _WIN64typedef unsigned long long PAGE_ID;
#elif _WIN32typedef size_t PAGE_ID;
#endif
这里需要注意的是 先判断是否是 _WIN64,在判断是否是 _WIN32
原因在于
- 在 64 位 Windows 环境下,会先检查 _WIN32,由于 _WIN32 总是被定义,条件 #ifdef _WIN32 会直接成立
Span 类结构
struct Span {PAGE_ID _PAGEID = 0; // 大块内存起始页的页号size_t _n = 0; // 页的数量Span* _next = nullptr; // 双向链表的结构Span* _prev = nullptr; size_t _userCount = 0; // 切好小块内存,被分配给 thread cache 的计数void* _freeList = nullptr; // 切好小块内存的自由链表
};
_PAGEID:标识内存块在操作系统分页系统中的起始位置。
例如:_PAGEID=100 表示该内存块从第100页开始(每页大小通常为4KB或8KB)。
_n:表示该内存块包含的连续页数,用于计算总大小(总大小 = _n * 页大小)。
_next 与 _prev:双向链表结构。将多个 Span 组织成 双向链表,用于中心缓存(Central Cache)管理不同大小的内存块。
例如:Central Cache 中可能存在多个链表,每个链表管理相同页数(_n)的 Span。
_userCount:跟踪当前 Span 中有多少个小块内存被分配给线程缓存(Thread Cache)。
当 _userCount == 0 时,表示所有内存已归还,Span 可被回收至页堆。
_freeList:维护未分配的小块内存链表,供 Thread Cache 快速分配。
链表节点通过 NextObj(obj) 宏(即 (void*)obj)连接
1.3.2 SpanList 类
我们已经说了 每个Span都是一个双向链表,所以我们需要对他进行一个封装。
这个类成员需要有一个头节点(哨兵位),一个桶锁 。并有增删、判空等功能
构造函数
构造函数创建头结点,并设置成双向循环链表结构。
SpanList() {_head = new Span;_head->_next = _head;_head->_prev = _head;}
插入
void Insert(Span* pos, Span* newSpan) {assert(pos);assert(newSpan);Span* prev = pos->_prev;prev->_next = newSpan;newSpan->_prev = prev;newSpan->_next = pos;pos->_prev = newSpan;}
删除
注意:从双链表删除的span会还给下一层的page cache,相当于只是把这个span从双链表中移除,因此不需要对删除的span进行delete操作。
void Erase(Span* pos) {assert(pos);// 不能删除哨兵位assert(pos != _head);// 删除 pos 结点Span* prev = pos->_prev;Span* next = pos->_next;prev->_next = next;next->_prev = prev;}
1.4 Central Cache 类
central cache
的映射规则和 thread cache
是一样的,因此central cache里面哈希桶的个数也是208 ,但central cache每个哈希桶中存储就是我们上面定义的双链表结构。
1.4.1 单例模式
1、为了保证 CentralCache类
只能创建一个对象,我们需要将 central cache
的 构造函数 和 拷贝构造函数 设置为私有(C++98方法),或者在C++11中也可以在函数声明的后面加上=delete进行修饰。
2、CentralCache类当中还需要有一个CentralCache类型的静态的成员变量,程序运行起来后我们就立马创建该对象(类外创建),在此后的程序中就只有这一个单例了。当
// 单例模式
class CentralCache {public:static CentralCache* GetInstance() {return &_sInst;}private:SpanList _spanLists[NFREELIST];private:// C++98,构造函数私有CentralCache(){}// C++11,禁止拷贝CentralCache(const CentralCache&) = delete;static CentralCache _sInst;
};
1.4.2 慢开始反馈调节算法
当 thread cache
向 central cache
申请内存时,central cache应该给出多少个对象呢?
如果central cache给的太少,那么thread cache在短时间内用完了又会来申请;但如果一次性给的太多了,可能thread cache用不完也就浪费了。
根据上面的分析,我们在这里采用一个慢开始反馈调节算法。当thread cache向central cache申请内存时,如果申请的是较小的对象,那么可以多给一点,但是如果申请的是较大的对象,就可以少给一点(类似网络tcp协议拥塞控制的慢开始算法)。
慢开始反馈调节算法
- 最开始不会一次向 central cache 一次批量要太多,因为要太多了可能用不完
- 如果你不要这个 size 大小内存需求,那么 batchNum 就会不断增长,知道上线
- size 也越多,一次向 central cache 要的内存就越少 512
- size 也越少,一次向 central cache 要的内存就越多 2
// 一次 thread cache 从中心缓存中获取多少个static size_t NumMoveSize(size_t size) {assert(size > 0);// [2, 512], 一次批量多少个对象的上下限值int num = MAX_BYTES / size;if(num < 2) num = 2;if(num > 512) num = 512;return num;}
注意:该函数封装在SizeClass类中,且为静态成员函数,无需创建对象调用。
上面的函数确实可以让申请对象合理化,但是如果申请的是小对象,一次性给出512个也是比较多的,基于这个原因,我们可以在FreeList这个类中增加一个_maxSize的成员变量,该变量初始值设置为1,并且提供一个公有成员函数用于获取这个变量 (返回值需要使用引用,后序需要修改)。也就是说thread cache的每个自由链表都有自己的_maxSize。
class FreeList {public:// ...private:void* _freeList = nullptr;size_t _maxSize = 1;
};
1.4.3 从中心缓存获取对象
每次 thread cache
向 central cache
申请对象时,我们先通过慢开始反馈调节算法计算本次应该申请的对象个数,然后再向central cache进行申请。
void* ThreadCache::FetchFromCentralCache(size_t index, size_t size) {// 慢开始反馈调节算法// 1. 最开始不会一次向 central cache 一次批量要太多,因为要太多了可能用不完// 2. 如果你不要这个 size 大小内存需求,那么 batchNum 就会不断增长,知道上线// 3. size 也越多,一次向 central cache 要的内存就越少 512// 4. size 也越少,一次向 central cache 要的内存就越多 2size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));if (_freeLists[index].MaxSize() == batchNum) {_freeLists[index].MaxSize() += 1;}void* start = nullptr;void* end = nullptr;size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);assert(actualNum >= 1);// 申请到对象的个数是一个,则直接将这一个对象返回即可if (actualNum == 1) {assert(start == end);return start;}// 申请到对象的个数是多个,还需要将剩下的对象挂到thread cache中对应的哈希桶else {_freeLists[index].PushRange(NextObj(start), end);return start;}return nullptr;
}
该函数要从central cache获取n个指定大小的对象,这些对象肯定是从central cache对应的哈希桶的某个span中取出来的,因此取出来的n个对象是链接在一起的,我们只需要得到这段自由链表的头和尾即可,此处采用输出型参数进行获取。
// 从中心缓冲获取一定数量的对象给 thread cache
size_t CentralCache::FetchRangeObj(void*& start, void*& end, size_t batchNum, size_t size) {size_t index = SizeClass::Index(size);_spanLists[index]._mtx.lock();Span* span = GetOneSpan(_spanLists[index], size);assert(span);assert(span->_freeList);// 从 span 中获取 batchNum个对象// 如果不够 batchNum 个,有多少拿多少start = span->_freeList;end = start;size_t i = 0;size_t actualNum = 1;while (i < batchNum - 1 && NextObj(end) != nullptr) {end = NextObj(end);++i;++actualNum;}span->_freeList = NextObj(end);NextObj(end) = nullptr;span->_userCount += actualNum;_spanLists[index]._mtx.unlock();return actualNum;
}
由于central cache是所有线程共享的,所以我们在访问central cache中的哈希桶时,需要先给对应的哈希桶加上桶锁,在获取到对象后再将桶锁解除。
👥总结
本篇博文对 【从零实现高并发内存池】Central Cache从理解设计到全面实现 做了一个较为详细的介绍,不知道对你有没有帮助呢
觉得博主写得还不错的三连支持下吧!会继续努力的~
相关文章:
【从零实现高并发内存池】Central Cache从理解设计到全面实现
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
Dijkstra算法求解最短路径—— 从零开始的图论讲解(2)
前言 在本系列第一期:从零开始的图论讲解(1)——图的概念,图的存储,图的遍历与图的拓扑排序-CSDN博客 笔者给大家介绍了 图的概念,如何存图,如何简单遍历图,已经什么是图的拓扑排序 按照之前的学习规划,今天笔者将继续带大家深入了解图论中的一个核心问题&#x…...
Spring AI 发布了它的 1.0.0 版本的第七个里程碑(M7)
Spring AI 发布了它的 1.0.0 版本的第七个里程碑(M7),下个月就是 RC1,紧接着就是 GA!,对于我们 Java 开发者来说,这绝对是个值得关注的好消息! 但是对于 Java 学习者来说,…...
如何从 GitHub 镜像仓库到极狐GitLab?
最近 GitHub 封禁中国用户的事情闹得沸沸扬扬,虽然官方发布的报道说中国用户被限制登录是因为配置错误导致,已经撤回了更新,中国用户已经可以正常使用。但是这就像横在国内开发者和企业头上的“达摩克利斯之剑”。为了避免 GitHub 不可用而带…...
大象机器人推出myCobot 280 RDK X5,携手地瓜机器人共建智能教育机
摘要 大象机器人全新推出轻量级高性能教育机械臂 myCobot 280 RDK X5,该产品集成地瓜机器人 RDK X5 开发者套件,深度整合双方在硬件研发与智能计算领域的技术优势,实现芯片架构、软件算法、硬件结构的全栈自主研发。作为国内教育机器人生态合…...
在Android Studio中,`Settings`里的Gradle路径、环境变量以及`gradle - wrapper.properties`文件关联
在Android Studio中,Settings里的Gradle路径、环境变量以及gradle - wrapper.properties文件关联 Android Studio中Settings里的Gradle路径 在Android Studio的Settings(Preferences ) -> Build, Execution, Deployment -> Build Tools -> Gradle 中: Use defau…...
用react 写一个可左右滑动的柱状图
效果图 目录 效果图 ✅ 项目结构 🚀 创建项目步骤 1️⃣ 打开终端或命令行,创建新项目: 2️⃣ 安装 recharts 图表库: 3️⃣ 替换默认代码: 4️⃣ 启动项目: ✅ 项目结构 scrollable-bar-chart/ ├…...
【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——MIPI LCD测试
1)实验平台:正点原子ATK-DLMP257B开发板 2)浏览产品:www.alientek.com 3)全套实验源码手册视频下载:正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试——MIPI LCD测试4.3 MIPI LCD测试4.3.1 使…...
【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——RS485串口测试
1)实验平台:正点原子ATK-DLMP257B开发板 2)浏览产品:www.alientek.com 3)全套实验源码手册视频下载:正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试——RS485串口测试 第四章 ATK-DLMP257B功能…...
Sui 的工具生态简化了游戏开发者的 Web3 集成流程
希望利用 Web3 独特协同效应的游戏开发者,常常在强大的区块链功能与流畅的游戏体验之间难以权衡。许多区块链方案要求大幅重构游戏基础架构,增加了开发难度,甚至需要学习全新的智能合约语言。而 Sui 通过直观的工具消除这一阻力,使…...
Vue 3 的组合式 API-hooks
Vue 3 的组合式 API 组合式 API 是 Vue 3 的核心特性之一,它允许开发者将组件的逻辑拆分为可复用的函数。组合式 API 的主要特点是 逻辑复用:将逻辑提取到独立的函数中,方便在多个组件中复用。组织清晰:将相关的逻辑分组&#x…...
AOSP Android14 Launcher3——底部任务栏Taskbar详解
前言:Launcher3中底部Taskbar和Navbar,或者说中文里面的术语导航栏,这几个词是很容易让人混淆的地方。本文要介绍的是Taskbar。从字面上意思来看,Taskbar就是任务栏,任务栏是Launcher3中一个重要的组件,尤其…...
QGraphicsView、QGraphicsScene和QGraphicsItem图形视图框架(五)QGraphicsView的缩放和移动
QGraphicsView自带滚动条的显示,但是大部分的需求样式都不需要滚动条,并且要通过鼠标来控制视图的缩放和移动。需要重写QGraphicsView实现。 一、相关函数 1.scale void QGraphicsView::scale(qreal sx, qreal sy) 按(sx,sy&…...
算法——果蝇算法
果蝇算法(Fruit Fly Optimization Algorithm,FOA)是一种受果蝇觅食行为启发而开发的群智能优化算法。以下从算法原理、算法流程、算法特点等方面为你详细讲述: 算法原理 果蝇本身具有优于其他物种的嗅觉和视觉。在觅食过程中&am…...
重返JAVA之路——图书管理系统
目录 一、功能介绍 二、设计模块 三、系统构建 1.book模块 2.operation模块 输入循环和验证 查找图书并处理借阅状态 未找到图书的处理 查找删除图书功能实现 未找到图书的处理 图书查找与归还 work方法实现图书信息输出 3. user模块实现 四、主菜单 一、功能介绍 …...
【16】数据结构之基于树的排序算法篇章
目录标题 选择排序简单选择排序树形选择排序 堆排序堆的定义Heap小跟堆大根堆堆的存储堆的代码设计堆排序的代码设计 排序算法综合比较 选择排序 基本思想:从待排序的序列中选出最大值或最小值,交换该元素与待排序序列的头部元素,对剩下的元…...
Uniapp:确认框
目录 一、 出现场景二、 效果展示三、具体使用 一、 出现场景 在项目的开发中,会经常出现删除数据的情况,如果直接删除的话,可能会存在误删,用户体验不好,所以需要增加一个消息提示,提醒用户是否删除。 二…...
pyswmm实现洪涝模拟
准备好.inp文件作为SWMM模型输入,调用pyswmm模块执行模拟,返回节点溢流量(flooding)作为积水量的初步表征。 代码: from pyswmm import Simulation, Nodes import pandas as pddef run_swmm_simulation(inp_file, ou…...
My Diary Pro:记录生活,珍藏回忆
我的日记My Diary Pro是一个非常好用的手机日记软件,可以使用它来记录每日生活日常,不少的用户可能都知道在生活之中可能会发生一些比较的重要的事情,实际上我们都可以将这些内容记录下来。包括个人观点,旅行游记,心情…...
CSRF(跨站请求伪造)漏洞概述
CSRF(跨站请求伪造)漏洞概述 一、什么是 CSRF 攻击者诱导已登录用户在不知情的情况下,对受信任网站执行未授权操作。 简单说:你登录着网站A,攻击者诱导你访问某个恶意链接,使网站A误以为是你自己发出的操作(比…...
[Java实战经验]对象拷贝
目录 谨慎重写clone方法重写clone()支持深拷贝带来的问题 合适的深拷贝 首先,对于不可变的类,我们不应该实现Cloneable接口,因为不可变类不需要拷贝,直接引用即可,实现Cloneable接口只会造成浪费。 对于Java可变类来说…...
WAF防火墙:构筑Web应用安全的“隐形护盾”
在数字化时代,Web应用已成为企业服务与用户交互的核心窗口。然而,随之而来的SQL注入、跨站脚本攻击(XSS)、DDoS攻击等威胁,时刻考验着网站的安全防线。Web应用防火墙(WAF)作为关键防护工具&…...
开源智慧巡检——无人机油田AI视频监控的未来之力
油田巡检,关乎能源命脉,却常受困于广袤地形、高危环境和人工效率瓶颈。管道泄漏、设备故障、非法闯入——这些隐患稍有疏忽,便可能酿成大患。传统巡检已无法满足现代油田对安全与效率的需求,而无人机油田巡检系统正以智能化之力重…...
【2025年泰迪杯数据挖掘挑战赛】B题 完整论文 模型建立与求解
目录 2025年泰迪杯数据挖掘挑战赛 B题完整论文:建模与求解 Matlab代码一、问题重述二、模型假设与符号说明2.1 模型基本假设2.2 符号说明 三、数据预处理**问题一:志愿者身体活动信息的统计分析****问题二:身体活动MET值的实时估计模型构建**…...
Chromium 134 编译指南 macOS篇:安装 Xcode(二)
1. 引言 在Chromium开发的征程中,为macOS平台构建正确的开发环境是成功编译的关键基础。继上一篇系统环境准备后,本文将重点介绍Xcode的安装与配置过程。作为macOS上不可或缺的集成开发环境(IDE),Xcode为Chromium 134的编译提供了必要的编译…...
软件定义网络(SDN):重塑未来网络的革命性架构
在当今数字化时代,网络已成为企业、云计算、5G通信和物联网(IoT)的核心基础设施。然而,传统网络架构由于其封闭、静态和分布式的特性,难以应对快速变化的业务需求。软件定义网络(Software-Defined Networki…...
Java虚拟机面试题:类加载机制
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
OCCT 入门(3)核心模块与架构
文章目录 一、核心模块与架构1、架构概述2、核心模块3、数据流转3.1、几何创建(Geometric Primitives)3.2、拓扑构建(Topology Construction)3.3、模型处理(Modeling Algorithms)3.4、可视化(Vi…...
MAC-需求:10万订单异步执行库存扣减、短信通知。
批量任务并行处理 实现,通过拆分任务、异步执行和线程池管理提升处理。 10万订单异步处理方案设计 基于图中代码的批量处理框架,结合订单业务需求,以下是 库存扣减与短信通知的异步实现: 1. 代码实现(基于原有框架改造) @Service public…...
ArrayList vs LinkedList,HashMap vs TreeMap:如何选择最适合的集合类?
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 在 Java 开发中,集合类的选择直接影响程序的性能和代码的可维护性。不同的数据结构适用于不同的场景,盲目使用可能导致内存浪费、性能…...
使用Form.List且有Select组件
当在使用Form.List组件,且组件中有Select选项时,针对每一次选择,都要过滤掉那些已经选择过的选项,可能遇到的问题: 直接过滤会将每一个Select中的options选项都过滤掉,无法正常展示选择的选项 解决办法&a…...
大数据学习笔记
文章目录 1. 大数据概述1.1 大数据的特性1.2 大数据技术生态1.2.1 Hadoop 的概念特性1.2.2 Hadoop生态圈 — 核心组件与技术栈1.2.3 Hadoop生态演进趋势 2. 数据处理流程与技术栈2.1 数据采集2.1.1 日志采集工具2.1.2 实时数据流2.1.3 数据迁移 2.2 数据预处理2.2.1 批处理2.2.…...
Obsidian 文件夹体系构建 -INKA
Obsidian 文件夹体系构建 -INKA 本篇文章主要分享一下自己折腾学习实践过的 INKA 框架方法。原地址:Obsidian文件夹体系构建–INKA。 文章目录 Obsidian 文件夹体系构建 -INKA前言INKA简介INKA 理论最佳实践实际应用 反思 前言 上文 Obsidian文件夹体系构建-ACCES…...
QML与C++:基于ListView调用外部模型进行增删改查(性能优化版)
目录 引言相关阅读工程结构数据模型设计DataModel 类ContactProxyModel 类 为什么使用QSortFilterProxyModel?应用初始化与模型连接UI实现 性能分析与优化运行效果扩展思考总结下载链接 引言 在上一篇中介绍了基于ListView调用外部模型进行增删改查,本文…...
集合常用Stream操作
1、中间操作 filter()过滤 将流中的元素筛选出满足条件的元素 List<String> list Arrays.asList("abc","test","demo","frse","fesfes"); list.stream().filter(s -> s.startsWith("f")).forEach(Sy…...
ReactNative中处理安全区域问题
RN原生方案不支持android系统,所以在此使用三方组件react-native-safe-area-context 1、安装插件 yarn add react-native-safe-area-context2、安装完成后直接yarn ios可能会失败,需要先 cd ios && pod install && cd ..出来再继…...
二、The Power of LLM Function Calling
一、Function Calling 的诞生背景 1. 传统LLM的局限性 静态文本生成的不足:早期的LLM(如早期版本的ChatGPT)主要依赖预训练的知识库生成文本,但无法直接与外部系统或API交互。这意味着它们只能基于历史数据回答问题,…...
贪心算法day10(无重叠区间)
1.无重叠区间 435. 无重叠区间 - 力扣(LeetCode) 思路: 代码: class Solution {public static int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals,(v1,v2)->{return v1[0]-v2[0];});int left interva…...
reactive 解构赋值给 ref
在 Vue 3 中,当你执行以下操作时: javascript const applyBasicInfo ref(); applyBasicInfo.value { ...props.applyBasicInfo }; 最终的 applyBasicInfo.value 是响应式对象,但与原对象 props.applyBasicInfo 的响应性完全独立…...
MongoDB简单用法
图片中 MongoDB Compass 中显示了默认的三个数据库: adminconfiglocal 如果在 .env 文件中配置的是: MONGODB_URImongodb://admin:passwordlocalhost:27017/ MONGODB_NAMERAGSAAS💡 一、为什么 Compass 里没有 RAGSAAS 数据库?…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(4): 可能形(かのうけい)
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(4): 可能形(かのうけい) 1、前言(1)情况说明(2)工程师的信仰2、知识点(1)~んです 復習(ふくしゅう)(2)いただけませんか 復習(ふくしゅう)(3)可能形(かのうけい)(1)1グループ:(2)2グループ…...
Windows 下 MongoDB ZIP 版本安装指南
在开发和生产环境中,MongoDB 是一种非常流行的 NoSQL 数据库,以其灵活性和高性能而受到开发者的青睐。对于 Windows 用户来说,MongoDB 提供了多种安装方式,其中 ZIP 版本因其灵活性和轻量级的特点,成为很多开发者的首选…...
万字长篇————C语言指针学习汇总
经过一段时间的学习,我们已经接触到了C语言的很多知识了。不过目前我们接下来我们要接触C语言中一个最大的“门槛”:指针。 什么是指针? 在介绍指针之前,我们首先要明白变量与地址之间的关系。 举一个生活中的案例:一…...
day29图像处理OpenCV
文章目录 一、图像预处理6 图像色彩空间转换6.3灰色/BGR/HSV相互转化 7 彩图转灰图方法7.1 最大值法7.2 平均值法7.3 加权均值法7.4 案例 8 图像二值化处理8.1 阈值法(typecv2.THRESH_BINARY)8.2 反阈值法(THRESH_BINARY_INV)8.3 截断阈值法(THRESH_TRUNC)8.4 低阈值零处理(THR…...
Spring Boot 项目三种打印日志的方法详解。Logger,log,logger 解读。
目录 一. 打印日志的常见三种方法? 1.1 手动创建 Logger 对象(基于SLF4J API) 1.2 使用 Lombok 插件的 Slf4j 注解 1.3 使用 Spring 的 Log 接口(使用频率较低) 二. 常见的 Logger,logger,…...
KrillinAI:视频跨语言传播的一站式AI解决方案
引言 在全球内容创作领域,跨语言传播一直是内容创作者面临的巨大挑战。传统的视频本地化流程繁琐,涉及多个环节和工具,不仅耗时耗力,还常常面临质量不稳定的问题。随着大语言模型(LLM)技术的迅猛发展,一款名为Krillin…...
PDF处理控件Aspose.PDF指南:使用 C# 从 PDF 文档中删除页面
需要从 PDF 文档中删除特定页面?本快速指南将向您展示如何仅用几行代码删除不需要的页面。无论您是清理报告、跳过空白页,还是在共享前自定义文档,C# 都能让 PDF 操作变得简单高效。学习如何以编程方式从 PDF 文档中选择和删除特定页面&#…...
在 IntelliJ IDEA 中开发 Java Web 项目时,遇到包内明明存在某个类但类名仍然爆红(显示红色错误提示)
在 IntelliJ IDEA 中开发 Java Web 项目时,遇到包内明明存在某个类但类名仍然爆红(显示红色错误提示),而项目却能正常运行,重启 IDEA 后问题依旧,这通常是由以下原因及解决方法导致的: 1. 缓存…...
【4】k8s集群管理系列--harbor镜像仓库本地化搭建
一、harbor基本概念 Harbor是一个由VMware开源的企业级Docker镜像仓库解决方案,旨在解决企业在容器化应用部署中的痛点,提供镜像存储、管理、安全和分发的全生命周期管理。Harbor扩展了Docker Registry,增加了企业级功能,如…...
Active Directory域服务管理与高级应用技术白皮书
目录 一、Active Directory核心架构解析 1.1 AD域服务核心组件 1.2 域功能级别演进 1.3 AD LDS应用场景 二、企业级域环境部署最佳实践 2.1 域控制器部署规划 2.2 高可用架构设计 2.3 客户端入域优化 三、高级域管理技术 3.1 精细化权限管理 3.2 组策略深度配置 3.3…...