深入理解 Java ArrayList 扩缩容机制(含源码分析)
标签: Java, ArrayList, 集合框架, 源码分析, 扩容机制, 性能优化, CSDN
摘要: java.util.ArrayList
作为 Java 集合框架中最常用的类之一,其动态数组的特性深受开发者喜爱。然而,“动态”背后的扩容与缩容机制是怎样的?它如何影响程序性能?本文将带你深入 ArrayList
的内部,结合 JDK 源码,彻底搞懂其容量自动调整的秘密,并提供实用的性能优化建议。
文章目录
- 1. 引言:为什么 ArrayList 需要扩缩容?
- 2. 核心概念:`size` 与 `capacity`
- 3. 自动扩容(Expansion):当空间不足时
- 触发时机
- 核心源码解析:`grow()` 方法
- 扩容因子:为什么是 1.5 倍?
- 扩容的成本
- 4. 手动缩容(Contraction):`trimToSize()`
- ArrayList 会自动缩容吗?
- 源码解析:`trimToSize()` 方法
- 使用场景与注意事项
- 5. 性能考量与最佳实践
- 预设初始容量的重要性
- 理解均摊时间复杂度
- 谨慎使用 `trimToSize()`
- 6. 总结
1. 引言:为什么 ArrayList 需要扩缩容?
ArrayList
底层是基于数组 (Object[]
) 实现的。数组一旦创建,其长度是固定的。但我们使用 ArrayList
时,却可以动态地添加或删除元素,似乎没有长度限制。这正是 ArrayList
扩容机制在发挥作用。
- 灵活性需求: 业务场景中,我们往往无法预知一个列表最终会存储多少元素。
ArrayList
的动态性使得我们无需在创建时就精确指定大小。 - 数组的局限: 固定长度的数组无法满足动态添加的需求。当数组满时,必须有某种机制来“扩大”存储空间。
- 空间与时间的权衡: 扩容机制需要在“预留过多空间造成浪费”和“频繁扩容导致性能下降”之间找到平衡。
理解 ArrayList
的扩缩容机制,有助于我们编写更高效、内存使用更合理的 Java 代码。
2. 核心概念:size
与 capacity
在深入源码之前,必须明确 ArrayList
的两个核心属性:
size
: 表示ArrayList
中实际存储的元素数量。通过list.size()
方法获取。capacity
: 表示ArrayList
底层数组 (elementData
) 的长度(容量)。它通常大于或等于size
。ArrayList
没有直接提供getCapacity()
方法,但可以通过反射或调试查看内部elementData.length
。
// 内部存储元素的数组
transient Object[] elementData; // non-private to simplify nested class access// 实际存储的元素数量
private int size;
size
是我们直接关心的元素个数,而 capacity
则是 ArrayList
为了容纳更多元素而预留的内部空间大小。扩缩容操作主要就是围绕调整 capacity
(即 elementData
数组的长度)进行的。
3. 自动扩容(Expansion):当空间不足时
触发时机
ArrayList
的自动扩容主要在以下几种情况发生:
- 调用
add(E e)
或add(int index, E element)
时: 当添加元素前,发现size
等于elementData.length
(即数组已满),就会触发扩容。 - 调用
addAll(...)
时: 计算需要添加的元素数量,如果添加后所需的总容量 (size + numNew
) 超过当前capacity
,则触发扩容。 - 调用
ensureCapacity(int minCapacity)
时: 显式要求确保ArrayList
至少具有minCapacity
的容量,如果当前capacity
小于minCapacity
,则触发扩容。
核心逻辑通常在添加元素前调用一个检查容量并可能增长的方法,例如 ensureCapacityInternal(size + 1)
(对于 add(E e)
)。
核心源码解析:grow()
方法
扩容的核心逻辑位于私有方法 grow(int minCapacity)
中(以 JDK 8/11 为例,不同版本细节可能略有差异):
// java.util.ArrayList
private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;// 核心扩容逻辑:新容量 = 旧容量 + 旧容量 / 2 (即 1.5 倍)int newCapacity = oldCapacity + (oldCapacity >> 1); // >> 1 是右移一位,等效于除以2取整// 如果计算出的新容量仍然小于所需的最小容量 (例如 addAll 时),则直接使用最小容量if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 防止容量过大,超过数组允许的最大值 (Integer.MAX_VALUE - 8)// MAX_ARRAY_SIZE 通常是 Integer.MAX_VALUE - 8,因为一些VM在数组头会保留字if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity); // 处理非常大的容量请求// 最关键的一步:创建新数组并复制旧数组内容// elementData = Arrays.copyOf(elementData, newCapacity); // 这个方法内部会 new 一个新数组,然后 System.arraycopy
}// (辅助方法) 处理非常大的容量请求
private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();// 如果minCapacity已经大于MAX_ARRAY_SIZE,就取Integer.MAX_VALUE,否则取MAX_ARRAY_SIZEreturn (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
}
关键步骤解读:
- 计算新容量:
newCapacity = oldCapacity + (oldCapacity >> 1)
。这是ArrayList
扩容的核心策略——将容量增加到原来的 1.5 倍。使用位运算>> 1
比/ 2
效率略高。 - 最小容量检查: 如果期望的最小容量
minCapacity
(例如addAll
时需要一次性放入多个元素) 比 1.5 倍计算出的newCapacity
还大,则直接采用minCapacity
作为新容量。 - 最大容量检查: 防止整数溢出和超出 VM 对数组大小的限制 (
MAX_ARRAY_SIZE
)。 - 数据迁移: 调用
Arrays.copyOf(elementData, newCapacity)
。这是扩容操作中最耗时的部分。它会:- 创建一个新的、长度为
newCapacity
的Object
数组。 - 使用
System.arraycopy()
将旧数组 (elementData
) 中的所有元素(size
个)复制到新数组的开头。 - 将
elementData
引用指向这个新创建的数组。旧数组如果没有其他引用,将在后续被垃圾回收器回收。
- 创建一个新的、长度为
扩容因子:为什么是 1.5 倍?
选择 1.5 倍(而不是 2 倍或其他因子)是一个工程上的权衡:
- 增长太慢(如 1.2 倍): 会导致扩容操作更频繁,虽然单次复制的元素相对较少,但总体
System.arraycopy
的调用次数增多,时间开销增大。 - 增长太快(如 2 倍): 可以减少扩容次数,但可能导致容量长期远大于实际
size
,造成更大的内存空间浪费。
1.5 倍被认为是在扩容频率(时间成本)和空间利用率之间的一个比较好的折中点。
扩容的成本
- 时间成本: 主要来自于
Arrays.copyOf
中的System.arraycopy()
操作,其时间复杂度为 O(n),其中 n 是当前ArrayList
中的元素数量 (size
)。这意味着每次扩容都需要复制所有现有元素。 - 空间成本: 需要额外分配一个更大的新数组,旧数组在被 GC 回收前会暂时占用内存。
4. 手动缩容(Contraction):trimToSize()
ArrayList 会自动缩容吗?
答案是:不会。 当你调用 remove()
或 clear()
方法从 ArrayList
中删除元素时,size
会减小,并且被删除位置的引用会被置为 null
(帮助 GC),但底层 elementData
数组的 capacity
保持不变。
原因: 自动缩容同样需要创建新数组和复制元素(System.arraycopy
),如果频繁在添加和删除之间切换,可能会导致代价高昂的“抖动”(连续的扩容和缩容)。因此,Java 设计者决定不提供自动缩容功能。
源码解析:trimToSize()
方法
如果你确实希望释放 ArrayList
中未使用的容量(即让 capacity
等于 size
),可以手动调用 trimToSize()
方法:
// java.util.ArrayList
public void trimToSize() {modCount++; // 修改计数器增加// 只有当实际元素数量小于数组容量时才需要缩容if (size < elementData.length) {// 如果size为0,则直接用空数组常量;否则,创建刚好够大的新数组并复制元素elementData = (size == 0)? EMPTY_ELEMENTDATA // 通常是一个 static final Object[0]: Arrays.copyOf(elementData, size);}
}
逻辑很简单:
- 检查
size
是否小于当前的capacity
(elementData.length
)。 - 如果是,则使用
Arrays.copyOf(elementData, size)
创建一个长度刚好等于size
的新数组,并将旧数组中的size
个元素复制过去。 - 将
elementData
指向这个紧凑的新数组。
使用场景与注意事项
- 使用场景:
- 当
ArrayList
经历了大量的删除操作后,size
远小于capacity
。 - 你预期该
ArrayList
在未来很长一段时间内不会再有显著增长。 - 应用程序对内存占用非常敏感,需要及时回收不再使用的内存空间。
- 当
- 注意事项:
trimToSize()
本身也是一个 O(n) 的操作(因为Arrays.copyOf
),它需要时间和计算资源。- 不要频繁调用! 如果在缩容后马上又开始大量添加元素,会导致立刻再次触发扩容,得不偿失。仅在确实需要且后续增长可能性小时使用。
5. 性能考量与最佳实践
预设初始容量的重要性
ArrayList
提供了带初始容量的构造函数:ArrayList(int initialCapacity)
。
ArrayList<String> list = new ArrayList<>(100); // 创建一个初始容量为100的列表
好处: 如果你在创建 ArrayList
时能预估到它大致会存储多少元素,强烈建议使用此构造函数指定一个合适的初始容量。
- 避免或减少扩容: 如果初始容量足够大(或接近最终大小),可以显著减少甚至完全避免代价高昂的扩容操作(数组复制)。
- 提升添加性能: 特别是在需要一次性添加大量元素(如从数据库查询结果、文件读取)的场景下,性能提升非常明显。
经验法则: 如果不确定,可以稍微设置大一点,但也不要过大导致浪费。如果完全无法预估,则使用无参构造函数(默认初始容量在 JDK 8 中是 10,早期版本可能是 0 但第一次 add 时会变为 10)。
理解均摊时间复杂度
虽然单次扩容的时间复杂度是 O(n),但 ArrayList
的 add(E e)
操作的均摊时间复杂度(Amortized Time Complexity) 仍然是 O(1)。
简单理解: 考虑连续添加 n 个元素。假设从空列表开始,每次扩容容量翻倍(简化模型)。扩容发生在第 1, 2, 4, 8, …, 2^k 次添加时。总的复制成本大约是 1 + 2 + 4 + … + 2^k ≈ 2^(k+1) ≈ 2n。将这个总成本分摊到 n 次添加操作上,平均每次添加的成本是 O(2n / n) = O(2) = O(1)。
这意味着,尽管偶尔会有一次“昂贵”的扩容,但长期来看,ArrayList
的添加操作效率非常高。预设初始容量可以让你避免那些“昂贵的”操作。
谨慎使用 trimToSize()
再次强调,trimToSize()
是一个有成本的操作,且可能与后续的添加操作冲突。仅在明确需要回收内存且列表大小趋于稳定时使用。
6. 总结
ArrayList
使用动态数组实现,通过扩容机制来支持动态添加元素。- 扩容通常在
add()
、addAll()
等操作导致容量不足时触发。 - 核心扩容逻辑在
grow()
方法中,策略是增长为原容量的 1.5 倍 (oldCapacity + (oldCapacity >> 1)
)。 - 扩容的主要成本在于
Arrays.copyOf()
,需要创建新数组并复制所有现有元素 (O(n) 时间复杂度)。 ArrayList
不会自动缩容。删除元素只减少size
,不改变capacity
。- 可以通过手动调用
trimToSize()
来让capacity
等于size
,以回收内存,但此操作也有 O(n) 成本,需谨慎使用。 - 最佳实践: 尽可能使用
ArrayList(int initialCapacity)
构造函数预设初始容量,以减少或避免扩容,提高性能。 add
操作的均摊时间复杂度为 O(1)。
理解 ArrayList
的扩缩容机制,特别是扩容的触发条件、增长策略和成本,以及如何通过预设容量来优化,对于编写高性能、内存友好的 Java 应用至关重要。希望本文能帮助你更深入地掌握 ArrayList
的使用!
相关文章:
深入理解 Java ArrayList 扩缩容机制(含源码分析)
标签: Java, ArrayList, 集合框架, 源码分析, 扩容机制, 性能优化, CSDN 摘要: java.util.ArrayList 作为 Java 集合框架中最常用的类之一,其动态数组的特性深受开发者喜爱。然而,“动态”背后的扩容与缩容机制是怎样的ÿ…...
LeetCode详解之如何一步步优化到最佳解法:26. 删除有序数组中的重复项
LeetCode详解系列的总目录(持续更新中): LeetCode详解之如何一步步优化到最佳解法:前100题目录(更新中...)-CSDN博客 LeetCode详解系列的上一题链接: LeetCode详解之如何一步步优化到最佳解法…...
doris基础使用
目录 1、一般使用 2、数据源通过catalog连接 1、es 2、clickhouse 3、db2 3、问题 (1)doris连接es一直报错 1、一般使用 (1)查询doris的catalog show catalogs; (2)查询catlog的连接信息 以catalog…...
Python 3.x cxfreeze打包exe教程
Python 3.x cxfreeze打包exe教程 https://blog.csdn.net/qq_33704787/article/details/123926953 去官网 下载安装 pip install cx-Freeze7.2.9 https://pypi.org/project/cx-Freeze/7.2.9/ 安装到 你的 python 的 script文件夹下面 (全局或是 虚拟环境都行&#x…...
SQL开发的智能助手:通义灵码在IntelliJ IDEA中的应用
SQL 是一种至关重要的数据库操作语言,尽管其语法与通用编程语言有所不同,但因其在众多应用中的广泛使用,大多数程序员都具备一定的 SQL 编写能力。然而,当面对复杂的 SQL 语句或优化需求时,往往需要专业数据库开发工程…...
nginx或tengine服务器,配置HTTPS下使用WebSocket的线上环境实践!
问题描述: HTTPS 下发起WS连接,连接失败,Chrom 浏览器报错。 socket.js:19 Mixed Content: The page at https://app.XXX.com was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint ws://172.16.10.80:903…...
原创工具scoopex - scoop增强工具,提供github proxy和url净化功能
说明 scoop是一款十分优秀的windows下软件管理工具,但是在国内使用,总会遇到网络问题,不得不翻墙或者梯子才能解决。 网上有很多提供了cn版本的bucket,虽然解决了一些问题,但是也带来了默认proxy不可用问题࿰…...
TPS入门DAY03 服务器篇
1.创建按钮和对应的回调函数 /* 大厅按钮 */UPROPERTY(meta (BindWidget))UButton* HostButton;/* 加入会话按钮 */UPROPERTY(meta (BindWidget))UButton* JoinButton;private:UFUNCTION()void OnHostButtonClicked();UFUNCTION()void OnJoinButtonClicked(); 创建调试助手 …...
STM32单片机入门学习——第30节: [9-6] FlyMcu串口下载STLINK Utility
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.09 STM32开发板学习——第30节: [9-6] FlyMcu串口下载&STLINK Utility 前言开发…...
基于springboot钻孔数据管理系统的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
摘要 本钻孔数据管理系统采用B/S架构,数据库是MySQL,网站的搭建与开发采用了先进的Java语言、Hadoop、数据可视化技术进行编写,使用了Spring Boot框架。该系统从两个对象:由管理员和用户来对系统进行设计构建。用户主要功能包括&…...
asp.net core 项目发布到 IIS 服务器
目录 一、VS2022 发布 二、设置IIS服务 三、配置IIS管理器 (一)打开IIS管理器 (二)添加站台 (三)配置应用程式集区 四、安装ASP.NET Core Hosting Bundle 五、设定IIS的日志位置 六、测试 一、VS2…...
自动化 Markdown 图片上传到 GitHub
自动化 Markdown 图片上传到 GitHub 1. 代码介绍 本代码用于自动扫描指定目录下的 Markdown 文章,提取其中的本地图片,并上传到 GitHub 仓库,最后替换文章中的图片路径,实现图片的托管和访问加速。 2. 主要功能 读取本地配置文…...
Java中23种设计模式之代理模式
一、什么是代理模式? 代理模式(Proxy Pattern)是一种结构型设计模式,其核心思想是: 通过引入一个代理对象作为中间层,控制对目标对象(真实对象)的访问,并在访问前后添加…...
git单独跟踪远程分支及处理合并异常情况
在 Git 中,自动跟踪远程分支(Tracking Remote Branch)是指: 当你创建一个本地分支时,让它直接关联(绑定)到对应的远程分支。这样,后续的 git pull、git push 等操作可以省略参数&…...
口腔助手|口腔挂号预约小程序|基于微信小程序的口腔门诊预约系统的设计与实现(源码+数据库+文档)
口腔小程序 目录 基于微信小程序的口腔门诊预约系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序前台界面实现 2、后台管理员模块实现 四、数据库设计 1、实体ER图 2、具体的表设计如下所示: 五、核心代码 六、论文参考 七、最新计算…...
Windows本地账户后门被关,微软强制使用在线账户
初次接触Windows10或者Windows11的同学应该都被微软一开始激活注册的在线账户坑过吧。 一切都按照微软的正向指引激活步骤,但到了账户注册的步骤时,不明所以的小白会按照微软的步骤进行新注册账户。 但坑就在这里,由于微软的账户服务器在国外…...
分类算法的介绍和应用场景
分类算法 1.算法介绍 和聚类是有区别的聚类是没有标签的 数据集中必须包含明确的类别标签,即已知每个样本所属的类别。这些标签作为学习的目标,指导模型的训练过程。 2.应用场景 广泛应用于需要对数据进行明确分类和预测的场景,如医疗诊断…...
将 CrewAI 与 Elasticsearch 结合使用
作者:来自 Elastic Jeffrey Rengifo 学习如何使用 CrewAI 为你的代理团队创建一个 Elasticsearch 代理,并执行市场调研任务。 CrewAI 是一个用于编排代理的框架,它通过角色扮演的方式让多个代理协同完成复杂任务。 如果你想了解更多关于代理…...
n8n自动化之添加jenkins
n8n自动化之添加jenkins Jenkins添加Api Token 点击“账户”点击“设置” 添加API Token 找到API Token,点击“添加新 Token”输入用户名点击“生成” 复制并保存秘钥 用生成token的用户名和密码填充下面的用户名和密码Jenkins instance URL是Jenkins文件夹的…...
DFS--
数字的全排列 #include <bits/stdc.h> using namespace std;//最大的排列数目 const int N10; int n; //存储排列的路径 int path[N]; //标记数字是否已经被使用 bool st[N];void dfs(int u){//到达递归边界,输出一个排列if(un){//输出循环for(int i0; i<…...
Vue:路由切换表格塌陷
目录 一、 出现场景二、 解决方案 一、 出现场景 当路由切换时,表格操作栏会出现行错乱、塌陷的问题 二、 解决方案 在组件重新被激活的时候刷新表格 <el-table ref"table"></el-table>activated(){this.$nextTick(() > {this.$refs[t…...
Ubuntu进入Recovery模式遇到问题
Ubuntu进入Recovery模式需要按ESC,但是没人告诉你进入后并不显示Advanced option.... 这种菜单,而是下面这个界面: 我分别测试了Ubuntu18和24的版本,都存在这个问题,就是不管你按一次ESC还是一直按着ESC都会进入到这个模式里。 非…...
淘宝API驱动跨境选品:多语言详情页自动翻译与本地化定价
淘宝 API 驱动跨境选品实现多语言详情页自动翻译与本地化定价,为跨境电商业务带来诸多便利与优势,以下是详细介绍: 一、多语言详情页自动翻译 技术原理 借助淘宝的 API 接口,获取商品详情页的各类文本信息,包括标题、描…...
IDEA 2024 Maven 设置为全局本地仓库,避免新建项目重新配置maven
使用idea创建Java项目时每次都要重新配置Maven,非常麻烦。其实IDEA可以配置全局Maven。方法如下: 1.关闭所有项目进入初始页面 2.选择所有配置 3.设置为自己的路径...
C++类成员内存分布详解
本文将探讨C类中成员变量的内存分布情况,包括普通成员、静态成员、虚函数等不同情况下的内存布局。 一、基本成员内存布局 1. 普通成员变量 普通成员变量按照声明顺序在内存中连续排列(受访问修饰符和内存对齐影响): class Nor…...
【PVR】《Palm Vein Recognition and Large-scale Research based on Deep Learning》
邬晓毅. 基于深度学习的掌静脉识别及规模化研究[D]. 四川:电子科技大学,2024. 文章目录 1、背景2、相关工作3、创新点和贡献4、方法和实验4.1、知识介绍4.2、基于自适应损失函数的掌静脉识别算法研究4.3、退化图像的掌静脉识别鲁棒性提升研究4.4、掌静脉识别系统规模化 5、总结…...
【码农日常】vscode编码clang-format格式化简易教程
文章目录 0 前言1 工具准备1.1 插件准备1.2 添加.clang-format1.3 添加配置 2 快速上手 0 前言 各路大神都说clangd好,我也来试试。这篇主要讲格式化部分。 1 工具准备 1.1 插件准备 照图安装。 1.2 添加.clang-format 右键添加文件,跟添加个.h或者.c…...
CExercise_08_字符串_2统计该字符串中每个字符出现的次数,统计过程中忽略大小写的差异,并打印最终每个字符出现的次数。
题目:CExercise_ 给定一个字符串,要求它可能包含数字和字母。 请编写函数,统计该字符串中每个字符出现的次数,统计过程中忽略大小写的差异,并打印最终每个字符出现的次数。 提示: 用一个int数组存储字符出现…...
LabVIEW 中 JSON 数据与簇的转换
在 LabVIEW 编程中,数据格式的处理与转换是极为关键的环节。其中,将数据在 JSON 格式与 LabVIEW 的簇结构之间进行转换是一项常见且重要的操作。这里展示的程序片段就涉及到这一关键功能,以下将详细介绍。 一、JSON 数据与簇的转换功能 &am…...
分布式文件存储系统FastDFS
文章目录 1 分布式文件存储1_分布式文件存储的由来2_常见的分布式存储框架 2 FastDFS介绍3 FastDFS安装1_拉取镜像文件2_构建Tracker服务3_构建Storage服务4_测试图片上传 4 客户端操作1_Fastdfs-java-client2_文件上传3_文件下载4_获取文件信息5_问题 5 SpringBoot整合 1 分布…...
DNS域名解析(以实操为主)
目录 一.正向解析(在Linux下) 1.1什么是正向解析 1.2具体操作 1编辑主配置文件 /etc/named.conf 2编辑域名文件 /etc/named.rfc1912.zones 3根据域名文件中定义的名称,来建立数据库文件 4重启服务 5验证 二.正向解析(在…...
Spark运行架构 RDD相关概念Spark-Core编程
以下是今天学习的知识点: 第三节 Spark运行架构 运行架构 Spark 框架的核心是一个计算引擎,整体来说,它采用了标准 master-slave 的结构。 核心组件 对于 Spark 框架有两个核心组件: Driver Spark 驱动器节点,用…...
校园智能硬件国产化的现状与意义
以下是校园智能硬件国产化的现状与意义: 现状 政策支持力度大:近年来,国家出台了一系列政策推动教育数字化和国产化发展。如2022年教育部等六部门印发《关于推进教育新型基础设施建设构建高质量教育支撑体系的指导意见》,明确提出…...
Android里面如何优化xml布局
在 Android 开发中,以下是系统化的优化方案,从基础到高级分层解析: 一、基础优化策略 1. 减少布局层级 问题:每增加一层布局,测量/布局时间增加 1-2ms 解决方案: <!-- 避免嵌套 --> <LinearLayo…...
Android10.0 framework第三方无源码APP读写断电后数据丢失问题解决
1.前言 在10.0中rom定制化开发中,在某些产品开发中,在某些情况下在App用FileOutputStream读写完毕后,突然断电 会出现写完的数据丢失的问题,接下来就需要分析下关于使用FileOutputStream读写数据的相关流程,来实现相关 功能 2.framework第三方无源码APP读写断电后数据丢…...
LabVIEW驱动开发的解决思路
在科研项目中,常面临将其他语言开发的定制采集设备驱动转换为 LabVIEW 适用形式的难题。特别是当原驱动支持匮乏、开发人员技术支持不足时,如何抉择解决路径成为关键。以下提供具体解决思路,助力高效解决问题。 一、评估现有驱动死磕的可…...
【C++】 —— 笔试刷题day_13
一、牛牛冲钻五 题目描述 题目说,牛牛在玩炉石传说,现在牛牛进行了n场游戏,让我们判断牛牛上了几颗星。 首先输入一个T,表示T组数据; 然后输入n和k,表示一个进行了n场数据,k表示连胜三场及以上…...
【ROS】分布式通信架构
【ROS】分布式通信架构 前言环境要求主机设置(Master)从机设置(Slave)主机与从机通信测试本文示例启动ROS智能车激光雷达节点本地计算机配置与订阅 前言 在使用 ROS 时,我们常常会遇到某些设备计算能力不足的情况。例…...
【第39节】windows编程:打造MFC版本任务管理器
目录 一、项目概述 二、项目开发的各种功能关键 2.1 进程信息的获取 2.2 线程信息的获取 2.3 进程模块信息的获取 2.3.1 模块快照 2.3.2 枚举模块 2.4 进程堆信息的获取 2.5 窗口信息的获取 2.6 文件信息的获取 2.7 内存信息和CPU占用率的获取 2.7.1 内存信息相关结…...
1.认识C语言
上层:应用软件 下层:操作系统、硬件 C语言擅长于下层方面 计算机语言的发展:低级 ——> 高级 用计算机的二进制指令写代码(低级语言) —— > 汇编指令(低级语言,用到了助记符ÿ…...
MySQL下200GB大表备份,利用传输表空间解决停服发版表备份问题
MySQL下200GB大表备份,利用传输表空间解决停服发版表备份问题 问题背景 在停服发版更新时,需对 200GB 大表(约 200 亿行数据)进行快速备份以预防操作失误。 因为曾经出现过有开发写的发版语句里,UPDATE语句的WHERE条…...
《Sqoop 快速上手:安装 + 测试实战》
推荐原文 见:http://docs.xupengboo.top/bigdata/di/sqoop.html Sqoop(SQL-to-Hadoop) 是 Apache 开源的工具,专门用于在 Hadoop 生态系统(如 HDFS、Hive、HBase) 和 关系型数据库(如 MySQL、O…...
MySQL体系架构(二)
MySQL中的目录和文件 2.2.1.bin目录 在MysQL的安装目录下有一个特别特别重要的bin目录,这个目录下存放着许多可执行文件。 其他系统中的可执行文件与此的类似。这些可执行文件都是与服务器程序和客户端程序相关的。 2.2.1.1.启动MySQL服务器程序 在UNIX系统中用来启动MySO…...
为什么反激采用峰值电流控制模式而非电压模式
电压模式控制是传统的控制方法,通过检测输出电压,与参考电压比较,然后调整PWM的占空比。这种方法的优点是简单,只需要一个电压反馈环路。但缺点可能包括对输入电压变化的响应较慢,动态性能不足,尤其是在负载…...
JavaScript逆向工程中的插桩技术完全指南
一、什么是插桩技术? 插桩(Instrumentation)是逆向工程中的核心技术之一,指的是在不改变程序原有逻辑的前提下,向目标程序中插入额外的代码或监控点,用于收集运行时信息、修改程序行为或进行调试分析。 插…...
LLM应用实战1-基本概念
文章目录 基本概念1. 提示词工程(Prompt Engineering)2. AI Agent(智能代理)3. Model Context Protocol (MCP)4. Function Calling(函数调用)5. Retrieval-Augmented Generation (RAG)6. FineTuning&#x…...
数据结构--堆
一、堆的定义 堆是一棵完全二叉树,树中的每个结点的值都不小于(或不大于)其左右孩子结点的值。其中,如果父亲结点的值始终大于或等于孩子结点的值,那么称这样的堆为大顶堆,这时每个结点的值都是以它为根节…...
第37次CCF计算机软件能力认证 / T4 / 集体锻炼
题目 代码 #include <bits/stdc.h> using namespace std; using LL long long;const int N 1e6 10; const int mod 998244353; int a[N]; int st[N][22];int get(int l, int r) {int x r - l 1;int k log2(x);return __gcd(st[l][k], st[r - (1 << k) 1][…...
ES6规范新特性总结
ES6新特性 var、let和const不存在变量提升暂时性死区不允许重复声明 解构赋值用途:交换变量的值从函数返回多个值提取JSON数据遍历map结构输入模块的制定方法 字符串的扩展codePointAt()String.fromCharCode()at()includes(),startsWith(),endsWith()repeat()padSta…...
AI模型多阶段调用进度追踪系统设计文档
AI模型多阶段调用进度追踪系统设计文档 一、系统概述 为解决AI模型处理大型文件时响应时间长的问题,我们设计并实现了一套异步进度追踪系统。该系统采用Server-Sent Events (SSE) 技术,建立从服务器到客户端的单向实时通信通道,使前端能够实…...