目录
引言
1. 回顾 HashMap 和 LinkedHashMap
1.1 说一下 HashMap 的实现结构
1.2 说一下 LinkedHashMap 的实现结构
2. 认识 WeakHashMap
2.1 WeakReference 弱引用的特点
2.2 WeakHashMap 的特点
2.3 说一下 WeakHashMap 与 HashMap 和 LinkedHashMap 的区别?
2.4 重建 Key 对象不等价的问题
2.5 Key 弱引用和 Value 弱引用的区别
3. WeakHashMap 源码分析
3.1 WeakHashMap 的属性
3.2 WeakHashMap 如何清理无效数据?
总结
引言
在之前的文章里,我们聊到了 Java 标准库中 HashMap 与 LinkedHashMap 的实现原理。HashMap 是一个标准的散列表数据结构,而 LinkedHashMap 是在 HashMap 的基础上实现的哈希链表。
今天,我们来讨论 WeakHashMap,其中的 “Weak” 是指什么,与前两者的使用场景有何不同?我们就围绕这些问题展开。
学习路线图:
1. 回顾 HashMap 和 LinkedHashMap
其实,WeakHashMap 与 HashMap 和 LinkedHashMap 的数据结构大同小异,所以我们先回顾后者的实现原理。
1.1 说一下 HashMap 的实现结构
HashMap 是基于分离链表法解决散列冲突的动态散列表。
1、HashMap 在 Java 7 中使用的是 “数组 + 链表”,发生散列冲突的键值对会用头插法添加到单链表中;
2、HashMap 在 Java 8 中使用的是 “数组 + 链表 + 红黑树”,发生散列冲突的键值对会用尾插法添加到单链表中。如果链表的长度大于 8 时且散列表容量大于 64,会将链表树化为红黑树。
散列表示意图
HashMap 实现示意图
1.2 说一下 LinkedHashMap 的实现结构
LinkedHashMap 是继承于 HashMap 实现的哈希链表。
1、LinkedHashMap 同时具备双向链表和散列表的特点。当 LinkedHashMap 作为散列表时,主要体现出 O(1) 时间复杂度的查询效率。当 LinkedHashMap 作为双向链表时,主要体现出有序的特性;
2、LinkedHashMap 支持 FIFO 和 LRU 两种排序模式,默认是 FIFO 排序模式,即按照插入顺序排序。Android 中的 LruCache 内存缓存和 DiskLruCache 磁盘缓存也是直接复用 LinkedHashMap 提供的缓存管理能力。
LinkedHashMap 示意图
FIFO 与 LRU 策略
2. 认识 WeakHashMap
2.1 WeakReference 弱引用的特点
WeakHashMap 中的 “Weak” 指键 Key 是弱引用,也叫弱键。弱引用是 Java 四大引用类型之一,一共有四种引用类型,分别是强引用、软引用、弱引用和虚引用。我将它们的区别概括为 3 个维度:
维度 1 - 对象可达性状态的区别: 强引用指向的对象是强可达的,只有强可达的对象才会认为是存活的对象,才能保证在垃圾收集的过程中不会被回收;
维度 2 - 垃圾回收策略的区别: 不同的引用类型的回收激进程度不同,
强引用指向的对象不会被回收;
软引用指向的对象在内存充足时不会被回收,在内存不足时会被回收;
弱引用和虚引用指向的对象无论在内存是否充足的时候都会被回收;
维度 3 - 感知垃圾回收时机: 当引用对象关联的实际对象被垃圾回收时,引用对象会进入关联的引用队列,程序可以通过观察引用队列的方式,感知对象被垃圾回收的时机。
感知垃圾回收示意图
提示: 关于 “Java 四种引用类型” 的区别,在小彭的 Java 专栏中深入讨论过 《吊打面试官:说一下 Java 的四种引用类型》,去看看。
2.2 WeakHashMap 的特点
WeakHashMap 是使用弱键的动态散列表,用于实现 “自动清理” 的内存缓存。
1、WeakHashMap 使用与 Java 7 HashMap 相同的 “数组 + 链表” 解决散列冲突,发生散列冲突的键值对会用头插法添加到单链表中;
2、WeakHashMap 依赖于 Java 垃圾收集器自动清理不可达对象的特性。当 Key 对象不再被持有强引用时,垃圾收集器会按照弱引用策略自动回收 Key 对象,并在下次访问 WeakHashMap 时清理全部无效的键值对。因此,WeakHashMap 特别适合实现 “自动清理” 的内存活动缓存,当键值对有效时保留,在键值对无效时自动被垃圾收集器清理;
3、需要注意,因为 WeakHashMap 会持有 Value 对象的强引用,所以在 Value 对象中一定不能持有 key 的强引用。否则,会阻止垃圾收集器回收 “本该不可达” 的 Key 对象,使得 WeakHashMap 失去作用。
4、与 HashMap 相同,LinkedHashMap 也不考虑线程同步,也会存在线程安全问题。可以使用 Collections.synchronizedMap 包装类,其原理也是在所有方法上增加 synchronized 关键字。
WeakHashMap 示意图
2.3 说一下 WeakHashMap 与 HashMap 和 LinkedHashMap 的区别?
WeakHashMap 与 HashMap 都是基于分离链表法解决散列冲突的动态散列表,两者的主要区别在键 Key 的引用类型上:
HashMap 会持有键 Key 的强引用,除非手动移除,否则键值对会长期存在于散列表中。而 WeakHashMap 只持有键 Key 的弱引用,当 Key 对象不再被外部持有强引用时,键值对会被自动被清理。
WeakHashMap 与 LinkedHashMap 都有自动清理的能力,两者的主要区别在于淘汰数据的策略上:
LinkedHashMap 会按照 FIFO 或 LRU 的策略 “尝试” 淘汰数据,需要开发者重写 removeEldestEntry()
方法实现是否删除最早节点的判断逻辑。而 WeakHashMap 会按照 Key 对象的可达性淘汰数据,当 Key 对象不再被持有强引用时,会自动清理无效数据。
2.4 重建 Key 对象不等价的问题
WeakHashMap 的 Key 使用弱引用,也就是以 Key 作为清理数据的判断锚点,当 Key 变得不可达时会自动清理数据。此时,如果使用多个 equals
相等的 Key 对象访问键值对,就会出现第 1 个 Key 对象不可达导致键值对被回收,而第 2 个 Key 查询键值对为 null 的问题。这说明 equals
相等的 Key 对象在 HashMap 等散列表中是等价的,但是在 WeakHashMap 散列表中是不等价的。
因此,如果 Key 类型没有重写 equals 方法,那么 WeakHashMap 就表现良好,否则会存在歧义。例如下面这个 Demo 中,首先创建了指向 image_url1
的图片 Key1,再重建了同样指向 image_url1
的图片 Key2。在 HashMap 中,Key1 和 Key2 等价,但在 WeakHashMap 中,Key1 和 Key2 不等价。
Demo
class ImageKey {
private String url;
ImageKey(String url) {
this.url = url;
}
public boolean equals(Object obj) {
return (obj instanceOf ImageKey) && Objects.equals(((ImageKey)obj).url, this.url);
}
}
WeakHashMap map = new WeakHashMap<>();
ImageKey key1 = new ImageKey("image_url1");
ImageKey key2 = new ImageKey("image_url2");
// key1 equalsTo key3
ImageKey key3 = new ImageKey("image_url1");
map.put(key1, bitmap1);
map.put(key2, bitmap2);
System.out.println(map.get(key1)); // 输出 bitmap1
System.out.println(map.get(key2)); // 输出 bitmap2
System.out.println(map.get(key3)); // 输出 bitmap1
// 使 key1 不可达,key3 保持
key1 = null;
// 说明重建 Key 与原始 Key 不等价
System.out.println(map.get(key1)); // 输出 null
System.out.println(map.get(key2)); // 输出 bitmap2
System.out.println(map.get(key3)); // 输出 null
默认的 Object#equals
是判断两个变量是否指向同一个对象:
Object.java
public boolean equals(Object obj) {
return (this == obj);
}
2.5 Key 弱引用和 Value 弱引用的区别
不管是 Key 还是 Value 使用弱引用都可以实现自动清理,至于使用哪一种方法各有优缺点,适用场景也不同。
Key 弱引用: 以 Key 作为清理数据的判断锚点,当 Key 不可达时清理数据。优点是容器外不需要持有 Value 的强引用,缺点是重建的 Key 与原始 Key 不等价,重建 Key 无法阻止数据被清理;
Value 弱引用: 以 Value 作为清理数据的判断锚点,当 Value 不可达时清理数据。优点是重建 Key 与与原始 Key 等价,缺点是容器外需要持有 Value 的强引用。
类型
优点
缺点
场景
Key 弱引用
外部不需要持有 Value 的强引用,使用更简单
重建 Key 不等价
未重写 equals
Value 弱引用
重建 Key 等价
外部需要持有 Value 的强引用
重写 equals
举例 1: 在 Android Glide 图片框架的多级缓存中,因为图片的 EngineKey 是可重建的,存在多个 EngineKey 对象指向同一个图片 Bitmap,所以 Glide 最顶层的活动缓存采用的是 Value 弱引用。
EngineKey.java
class EngineKey implements Key {
// 重写 equals
@Override
public boolean equals(Object o) {
if (o instanceof EngineKey) {
EngineKey other = (EngineKey) o;
return model.equals(other.model)
&& signature.equals(other.signature)
&& height == other.height
&& width == other.width
&& transformations.equals(other.transformations)
&& resourceClass.equals(other.resourceClass)
&& transcodeClass.equals(other.transcodeClass)
&& options.equals(other.options);
}
return false;
}
}
举例 2: 在 ThreadLocal 的 ThreadLocalMap 线程本地存储中,因为 ThreadLocal 没有重写 equals,不存在多个 ThreadLocal 对象指向同一个键值对的情况,所以 ThreadLocal 采用的是 Key 弱引用。
ThreadLocal.java
static class Entry extends WeakReference> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal k, Object v) {
super(k);
value = v;
}
}
3. WeakHashMap 源码分析
这一节,我们来分析 WeakHashMap 中主要流程的源码。
事实上,WeakHashMap 就是照着 Java 7 版本的 HashMap 依葫芦画瓢的,没有树化的逻辑。考虑到我们已经对 HashMap 做过详细分析,所以我们没有必要重复分析 WeakHashMap 的每个细节,而是把重心放在 WeakHashMap 与 HashMap 不同的地方。
3.1 WeakHashMap 的属性
先用一个表格整理 WeakHashMap 的属性:
版本
数据结构
节点实现类
属性
Java 7 HashMap
数组 + 链表
Entry(单链表)
1、table(数组) 2、size(尺寸) 3、threshold(扩容阈值) 4、loadFactor(装载因子上限) 5、modCount(修改计数) 6、默认数组容量 16 7、最大数组容量 2^30 8、默认负载因子 0.75
WeakHashMap
数组 + 链表
Entry(单链表,弱引用的子类型)
9、queue(引用队列)
WeakHashMap.java
public class WeakHashMap extends AbstractMap implements Map {
// 默认数组容量
private static final int DEFAULT_INITIAL_CAPACITY = 16;
// 数组最大容量:2^30(高位 0100,低位都是 0)
private static final int MAXIMUM_CAPACITY = 1 << 30;
// 默认装载因子上限:0.75
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
// 底层数组
Entry[] table;
// 键值对数量
private int size;
// 扩容阈值(容量 * 装载因子)
private int threshold;
// 装载因子上限
private final float loadFactor;
// 引用队列
private final ReferenceQueue queue = new ReferenceQueue<>();
// 修改计数
int modCount;
// 链表节点(一个 Entry 等于一个键值对)
private static class Entry extends WeakReference implements Map.Entry {
// 与 HashMap 和 LinkedHashMap 相比,少了 key 的强引用
// final K key;
// Value(强引用)
V value;
// 哈希值
final int hash;
Entry next;
Entry(Object key, V value, ReferenceQueue queue, int hash, Entry next) {
super(key /*注意:只有 Key 是弱引用*/, queue);
this.value = value;
this.hash = hash;
this.next = next;
}
}
}
WeakHashMap 与 HashMap 的属性几乎相同,主要区别有 2 个:
1、ReferenceQueue: WeakHashMap 的属性里多了一个 queue 引用队列;
2、Entry: WeakHashMap#Entry
节点继承于 WeakReference
,表面看是 WeakHashMap 持有了 Entry 的强引用,其实不是。注意看 Entry 的构造方法,WeakReference 关联的实际对象是 Key。 所以,WeakHashMap 依然持有 Entry 和 Value 的强引用,仅持有 Key 的弱引用。
引用关系示意图
不出意外的话又有小朋友出来举手提问了♀️ :
♀️疑问 1:说一下 ReferenceQueue queue 的作用?
ReferenceQueue 与 Reference 配合能够实现感知对象被垃圾回收的能力。在创建引用对象时可以关联一个实际对象和一个引用队列,当实现对象被垃圾回收后,引用对象会被添加到这个引用队列中。在 WeakHashMap 中,就是根据这个引用队列来自动清理无效键值对。
♀️疑问 2:为什么 Key 是弱引用,而不是 Entry 或 Value 是弱引用?
首先,Entry 一定要持有强引用,而不能持有弱引用。这是因为 Entry 是 WeakHashMap 内部维护数据结构的实现细节,并不会暴露到 WeakHashMap 外部,即除了 WeakHashMap 本身之外没有其它地方持有 Entry 的强引用。所以,如果持有 Entry 的弱引用,即使 WeakHashMap 外部依然在使用 Key 对象,WeakHashMap 内部依然会回收键值对,这与预期不符。
其次,不管是 Key 还是 Value 使用弱引用都可以实现自动清理。至于使用哪一种方法各有优缺点,适用场景也不同,这个在前文分析过了。
3.2 WeakHashMap 如何清理无效数据?
在通过 put / get /size 等方法访问 WeakHashMap 时,其内部会调用 expungeStaleEntries()
方法清理 Key 对象已经被回收的无效键值对。其中会遍历 ReferenceQueu 中持有的弱引用对象(即 Entry 节点),并将该结点从散列表中移除。
private final ReferenceQueue queue = new ReferenceQueue<>();
// 添加键值对
public V put(K key, V value) {
...
// 间接 expungeStaleEntries()
Entry[] tab = getTable();
...
}
// 扩容
void resize(int newCapacity) {
// 间接 expungeStaleEntries()
Entry[] oldTable = getTable();
...
}
// 获取键值对
public V get(Object key) {
...
// 间接 expungeStaleEntries()
Entry[] tab = getTable();
...
}
private Entry[] getTable() {
// 清理无效键值对
expungeStaleEntries();
return table;
}
// ->清理无效键值对
private void expungeStaleEntries() {
// 遍历引用队列
for (Object x; (x = queue.poll()) != null; ) {
// 疑问 3:既然 WeakHashMap 不考虑线程同步,为什么这里要做加锁,岂不是突兀?
synchronized (queue) {
Entry e = (Entry) x;
// 根据散列值定位数组下标
int i = indexFor(e.hash /*散列值*/, table.length);
// 遍历桶寻找节点 e 的前驱结点
Entry prev = table[i];
Entry p = prev;
while (p != null) {
Entry next = p.next;
if (p == e) {
// 删除节点 e
if (prev == e)
// 节点 e 是根节点
table[i] = next;
else
// 节点 e 是中间节点
prev.next = next;
// Must not null out e.next;
// stale entries may be in use by a HashIterator
e.value = null; // Help GC
size--;
break;
}
prev = p;
p = next;
}
}
}
}
总结
1、WeakHashMap 使用与 Java 7 HashMap 相同的 “数组 + 链表” 解决散列冲突,发生散列冲突的键值对会用头插法添加到单链表中;
2、WeakHashMap 能够实现 “自动清理” 的内存缓存,其中的 “Weak” 指键 Key 是弱引用。当 Key 对象不再被持有强引用时,垃圾收集器会按照弱引用策略自动回收 Key 对象,并在下次访问 WeakHashMap 时清理全部无效的键值对;
3、WeakHashMap 和 LinkedHashMap 都具备 “自动清理” 的 能力,WeakHashMap 根据 Key 对象的可达性淘汰数据,而 LinkedHashMap 根据 FIFO 或 LRU 策略尝试淘汰数据;
4、WeakHashMap 使用 Key 弱引用,会存在重建 Key 对象不等价问题。
以上就是WeakHashMap 和 HashMap 的区别是什么,何时使用的详细内容,更多关于WeakHashMap HashMap区别的资料请关注脚本之家其它相关文章!
你可能感兴趣的:(WeakHashMap 和 HashMap 区别及使用场景)
目标检测——玉米叶感染数据集
Bryan Ding
人工智能
一、重要性首先,玉米作为世界上重要的粮食作物之一,其生长状况直接影响到粮食产量和粮食安全。玉米叶感染是玉米生长过程中常见的病害之一,会导致玉米叶片出现肿胀、皱缩、扭曲变形等症状,严重时甚至可能形成瘤状物。因此,及早检测玉米叶感染对于保障玉米的健康生长和提高产量具有重要意义。其次,通过玉米叶感染检测,农民和农业科研人员可以及时发现并采取有效的防治措施,防止病害的扩散和加重。这不仅可以减少因病害导致的
VB6 调用 JS 函数时数据传输json格式或a=1&b=s2字符串
专注VB编程开发20年
javascript json 开发语言 vb6 js
1.VB6调用JS函数时数据传输格式当从VB6调用JS设计的函数时,使用JSON字符串作为数据传输格式是一个不错的选择,但并非唯一选择。使用JSON字符串传输的优势通用性:JSON是一种轻量级的数据交换格式,具有良好的跨语言和跨平台特性。在VB6和JS之间使用JSON字符串传输数据,可以方便地表示复杂的数据结构,如对象、数组等。结构化:JSON可以清晰地表示数据的结构,便于在不同语言环境中解析和处
C++ 泛型编程
四代目 水门
C++学习笔记 c++ 开发语言
C++泛型编程一、泛型编程基础1.核心概念实现算法与数据结构的分离基于模板技术(函数模板/类模板)本质:类型参数化,减少重复代码典型应用:STL容器、迭代器、算法2.类型本质内存布局的抽象不同类型对应不同的内存分配策略二、函数模板1.基本语法cpptemplate//或template返回类型函数名(参数列表){//函数体}2.关键特性支持隐式推导和显式指定类型可重载(包括与普通函数重载)可声明为
【学习笔记5】Linux下cuda、cudnn、pytorch版本对应关系
longii11
linux pytorch 运维
一、cuda和cudnnNVIDIACUDAToolkit(CUDA)为创建高性能GPU加速应用程序提供了一个开发环境。借助CUDA工具包,您可以在GPU加速的嵌入式系统、桌面工作站、企业数据中心、基于云的平台和HPC超级计算机上开发、优化和部署您的应用程序。该工具包包括GPU加速库、调试和优化工具、C/C++编译器以及用于部署应用程序的运行时库。全球的深度学习研究人员和框架开发人员都依赖cuDN
python找色_Python获取图片位置像素色值及判断色值是否存在
weixin_39966941
python找色
#!/usr/bin/python#-*-coding:utf-8-*-fromPILimportImage#涛哥用代码看是那的错https://blog.kydbk.comimg=Image.open("test.png")#获取图片尺寸的大小(600,600)printimg.size#获取图片的格式pngprintimg.format#获取图片的图像类型RGBAprintimg.mode#显
【Elasticsearch】Index Lifecycle Management
risc123456
Elasticsearch elasticsearch
Elasticsearch的索引生命周期管理(IndexLifecycleManagement,简称ILM)是一种自动化管理索引生命周期的功能,旨在帮助用户根据索引的使用模式和数据价值,高效地管理和优化索引的存储、性能和成本。以下是关于Elasticsearch索引生命周期的详细说明:---1.索引生命周期的五个阶段Elasticsearch的ILM定义了五个主要阶段,每个阶段对应不同的索引使用模
LeetCode-Hot100-006三数之和
YQ_ZJH
LeetCode100题 leetcode 数据结构 排序算法 算法 c++ 蓝桥杯 java
思路先排序解决重复的问题。再三重循环遍历,但是第二重和第三重使用双指针的做法,复杂度降低为O(n2)O(n^2)O(n2)。代码本次代码来自于力扣官方题解评论区,非本人原创,请注意classSolution{publicList>threeSum(int[]nums){Arrays.sort(nums);//先排序List>res=newArrayList0&&nums[i]==nums[i-1]
【Qt】Qt Widgets和QML(Qt Quick)开发界面的区别
£އއ昔年
qt 开发语言
Qt提供了两种主要的UI技术:QtWidgets和QML(QtQuick)。它们的核心区别主要体现在使用方式、架构、性能、开发难度和适用场景等方面。1.QtWidgetsvs.QML总体对比对比项QtWidgetsQML(QtQuick)语言C++(带QtUI库)QML+JavaScript(底层C++)渲染方式传统窗口系统控件(原生或模拟)基于OpenGL,使用GPU加速UI风格经典桌面UI(W
大语言模型对程序员行业的影响及未来发展走势分析
Hello kele
人工智能 java 人工智能 AI编程
随着人工智能技术的快速发展,特别是大语言模型(如DeepSeek、OpenAI、Grok等)的出现,对程序员这个行业产生了深远的影响。在这篇文章中,我们将探讨这些变化,分析影响,并展望未来的发展趋势。一、当前影响1.自动化代码生成大语言模型的一个直接影响是代码自动化的能力。这些模型可以理解代码上下文,并生成功能性代码。例如,GitHubCopilot已经成为许多开发者的辅助工具,能够根据注释或部分
【AI辅助工具】Trae和Cursor 对比分析
Hello kele
人工智能 AI编程
Trae和Cursor都是旨在提升编程效率的AI辅助工具,但在功能、定位和用户体验上有所差异。Trae:Trae是字节跳动推出的AI集成开发环境(IDE),专为中文开发者设计,提供全中文界面,符合国人使用习惯。主要特点:智能问答与代码自动补全:支持通过自然语言描述需求,自动生成相应的代码,减少手动编写代码的时间。Builder模式:类似于Cursor的Composer功能,帮助用户从零开始构建完整
DeepSeek:AI赋能的无限可能——从日常生活到职业进阶的全场景探索
Hello kele
人工智能 人工智能
引言在人工智能技术飞速发展的今天,DeepSeek作为一款国产AI工具,凭借其强大的推理能力、自然语言处理效率和场景化应用潜力,正在重塑人类解决问题的方式。从撰写演讲稿到制定投资策略,从家庭教育到企业管理,DeepSeek通过“自然语言对话”的交互模式,将复杂任务简化为几步提示词的输入,真正实现了“所想即所得”。本文将从七大核心场景出发,系统解析DeepSeek如何成为个人与组织的智能助手,推动效
迷你世界脚本自定义UI接口:Customui
星空露珠
笔记 lua 游戏 数据结构
自定义UI接口:Customui彼得兔更新时间:2024-11-0715:12:42具体函数名及描述如下:(除前两个,其余的目前只能在UI编辑器内部的脚本使用)序号函数名函数描述1openUIView(...)打开一个UI界面(注意:继承自player对象)2hideUIView(...)隐藏一个UI界面(注意:继承自player对象)1setText(...)设置文本元件内容(只在UI局部脚本有
迷你世界脚本函数监听接口:ListenParam
星空露珠
笔记 游戏 数据结构 lua
函数监听接口:ListenParam彼得兔更新时间:2023-04-2610:20:18具体函数名及描述如下:序号函数名函数描述1AddGraphicsListenParam(...)添加图文信息监听触发器参数刷新的对象id参数信息回调方法AddGraphicsListenParam参数及类型:graphid:number已创建的图文信息IDfuncs:table监听函数列表param:table
Leetcode 刷题笔记1 动态规划part05
平乐君
leetcode 笔记 动态规划
开始完全背包不同于01背包,完全背包的特色在于元素可以重复拿取,因此在递归公式和遍历顺序上都有些许不同。leetcode518零钱兑换||在组合方式中所用到的递推公式是dp[j]=dp[j-coins[i]]+dp[j]对于coins[i]>j的情况,forjinrange(coin[i],amount+1)不会执行,即实现dp[i][j]=dp[i-1][j]classSolution:defc
IMT-2020(5G)推进组发布《5G-Advanced 场景需求与关键技术白皮书》
优橙教育
5G 面试 职场和发展 5g 网络
11月16日,由工业和信息化部、深圳市人民政府主办的2022年中国5G发展大会在深圳举行。本届大会以“5G领航新基建,构筑发展新底座”为主题。会上,IMT-2020(5G)推进组发布《5G-Advanced场景需求与关键技术白皮书》。中国工程院院士邬贺铨表示,5G商用三年来在国际上取得了网络部署与用户数领先的成绩。2022年9月中国建成5G基站数占基站总数的20.6%,占全球5G基站数60%。20
[数据结构] [C++ STL] vector使用详解
高亚奇
数据结构 数据结构 c++ 开发语言
一、概述vector(向量):是一种序列式容器,事实上和数组差不多,但它比数组更优越。一般来说数组不能动态拓展,因此在程序运行的时候不是浪费内存,就是造成越界。而vector正好弥补了这个缺陷,它的特征是相当于可分配拓展的数组(动态数组),它的随机访问快,在中间插入和删除慢,但在末端插入和删除快。二、定义及初始化使用之前必须加相应容器的头文件:#include//vector属于std命名域的,因
React 基础教程
阿贾克斯的黎明
前端 react.js 前端 前端框架
目录React基础教程一、React简介二、安装和设置三、创建第一个React组件(一)函数式组件(二)类组件四、渲染组件五、组件的属性和状态(一)属性(Props)(二)状态(State)六、组件的生命周期方法七、事件处理八、总结React是一个用于构建用户界面的JavaScript库。它以高效、灵活和可维护性而受到广泛的欢迎。本教程将介绍React的基础知识,帮助你快速上手React开发。一、
【贪心算法1】
m0_46150269
贪心算法 算法
力扣455.分发饼干链接:link思路尽可能让更多人吃到饼干并且尽可能少的造成浪费,大尺寸饼干能满足大胃口的人就应该优先分给大胃口的人。所以先将饼干和胃口大小排序,然后从后往前遍历。但是这时候又有一个问题,饼干和胃口哪个作为for循环哪个作为if呢?答案是只能胃口作为for,饼干作为if,因为for循环的i是固定每次移动,而饼干index只有满足条件才会移动。这里可以举一个反例,如果最大胃口大于最
RAG 检索增强生成:技术详解与应用展望
君君学姐
RAG检索增强生成
RAG检索增强生成:技术详解与应用展望一、引言随着人工智能技术的飞速发展,自然语言处理(NLP)领域迎来了前所未有的变革。其中,检索增强生成(Retrieval-AugmentedGeneration,简称RAG)作为一种新兴的技术框架,正逐渐成为大模型应用中的热门选择。RAG通过结合信息检索(IR)和自然语言生成(NLG)的能力,旨在提升模型在回答问题、生成文本等任务中的准确性和可靠性。本文将深
【python】软件更新:用conda或Poetry
无水先生
AI原理和python实现 python指南和应用 人工智能综合 python conda 开发语言
一、说明在实现anancoda的软件更新问题,需要明确几个问题:1)是python包吗?2)是C++包吗?更新的方法有别。python包可以pip访问。C++包必须是conda访问。二、更新C++包的循环依赖问题如果在Windows10上的Ananconda3.7上安装和更新软件包。运行代码时:condaupdate--all或者condainstallpandas收到以下错误:RemoveErr
CES Asia 2025:可持续科技论坛成焦点
赛逸展张胜
人工智能 大数据
随着全球对环境保护和可持续发展的关注度日益提升,科技领域在推动可持续发展方面扮演着愈发关键的角色。将在首都北京举办的CESAsia2025第七届亚洲消费电子技术贸易展(赛逸展),将目光聚焦于可持续科技,展会期间的相关论坛峰会吸引了众多企业的目光,有望成为展会一大亮点。近年来,科技行业面临着巨大的可持续转型压力。苹果、三星等行业巨头已明确要求供应商在2030年前实现碳中和,这使得整个行业供应链必须加
CES Asia 2025:5G与物联网成焦点,论坛峰会引企业关注
赛逸展张胜
5G 物联网
在科技飞速发展的当下,5G与物联网技术正深刻改变着人们的生活和产业格局。作为亚洲消费电子领域的年度盛会,CESAsia2025第七届亚洲消费电子技术贸易展(赛逸展)将在首都北京盛大开幕。此次展会以“科技新视界,创新赢未来”为主题,将全方位展示5G技术及其在物联网中的创新应用,展会期间的相关论坛峰会更是吸引了众多企业的目光,成为行业内交流合作的重要契机。在5G技术展示方面,CESAsia2025将汇
使用OpenCV和Python将图像读取为RGB
UixnContext
opencv python 人工智能 OpenCV
在计算机视觉和图像处理中,OpenCV是一个广泛使用的开源库,提供了许多功能强大的图像处理工具。其中一个常见的任务是将图像读取为RGB格式,以便进一步处理和分析。在本文中,我将向您展示如何使用OpenCV和Python来实现这个任务。首先,确保您已经安装了OpenCV库。您可以使用以下命令在Python中安装OpenCV:pipinstallopencv-python一旦安装完成,我们可以开始写代
贪心算法-字符串数组能拼接出的最小字典序(java)
SP_1024
算法 贪心算法 算法 java
最小字典序的贪心算法题目描述贪心算法的解题思路贪心算法自定义比较器贪心算法暴力递归解法题目描述给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果贪心算法的解题思路首先我们很自然的能想到,遍历数组,比较数组中每一个元素,字典序越小的,就放前面.但这里右一个陷阱,比如ba和b两个字符串,b的字典序小于ba,如果拼成bba就错了,显然bab字典序更小
全国首个高速公路5G-A通感一体基站在宁开通测试
NewsMash
5G
7月18日,江苏移动南京分公司联合南京市交通建设投资控股(集团)有限责任公司(以下简称南京交通集团)、南京聚变航天信息科技有限公司,共同完成了全国首个高速公路5G-A通感一体基站部署和低空管理场景的开通测试。5G-A通感一体基站的通信和感知能力不仅为低空无人飞行器的通信和监管提供了有效支撑手段,也将助力南京低空经济发展打开新空间。什么是5G-A?5G-A全称为5G-Advanced,是基于第五代移
大数据面试系列之——Hadoop
潜心_守道
大数据 面经 面试 大数据 Hadoop
Hadoop的三个核心:HDFS(分布式存储系统)MapReduce(分布式计算系统)YARN(分布式资源调度)1.Hadoop集群的几种搭建模式1.单机模式:直接解压安装,不存在分布式存储系统2.伪分布式:NameNode和DataNode安装于同一个节点,无法体现分布式处理的优势。3.完全分布式:一个主节点,多个从节点,存在如果主节点宕机,集群就无法使用的缺点。4.高可用模式:多个主节点,多个
动画 + 大白话讲清楚React渲染原理
梅花十三儿
react.js 前端 javascript
前言相信很多人跟我之前一样,看到源码两个字觉得触不可及,觉得离自己还很遥远,是需要非常多年的工作经验的大佬才能触及到的领域。就在去年我改变了这个想法,当时被react的几个生命周期执行顺序弄的睡不着觉,为什么有些时候生命周期的执行事与愿违?又为什么数组中必须要加上key属性?为啥在render中不能写setState等等问题…在一系列的问题中,我终于还是打开了那份久违的源码,并且Ctrl+F慢慢探
【无标题】Hollo world.Javascript
一一代码
python javascript
HelloWorld最简单JavaScript代码console.log("Hello,World!");变量和数据类型JavaScript中的变量声明和基本数据类型。```javascriptletname="Alice";//字符串constage=25;//数字letisStudent=true;//布尔值console.log(name,age,isStudent);```函数定义一个简单
基于python cv 库实现读取图片像素值
我是电脑高手
python小工具 python 开发语言 图像处理
--------在日常生活中,我们经常用简单的形容词来描述颜色,比如“红色”、“蓝色”、“绿色”等。然而,这种描述方法对于精确确定颜色是有限的,尤其是在设计、图像处理、Web开发等领域。为了更准确和科学地定义颜色,我们通常采用RGB值来表示颜色。什么是RGB值?RGB是指红色(Red)、绿色(Green)和蓝色(Blue)的组合方式,用来表示颜色。RGB是一种加色模型,也就是说,通过将红、绿、蓝三
拓展:核心对象成员访问操作符
神里流~霜灭
c++ c语言 数据结构 链表 顺序表 操作符
前言针对于核心对象成员访问操作符,这篇文章只简单介绍一下两者的区别以及优缺点,什么情况下使用操作符(->)、什么情况下使用操作符(.)。在C++中,操作符->(箭头操作符)和.(点操作符)是用于访问对象成员的核心操作符,但它们的使用场景和底层逻辑有明显区别。以下是详细分析:一、基本定义与区别操作符适用对象语法等价底层逻辑.对象实例(非指针)obj.member直接访问对象的成员->指向对象的指针p
项目中 枚举与注解的结合使用
飞翔的马甲
java enum annotation
前言:版本兼容,一直是迭代开发头疼的事,最近新版本加上了支持新题型,如果新创建一份问卷包含了新题型,那旧版本客户端就不支持,如果新创建的问卷不包含新题型,那么新旧客户端都支持。这里面我们通过给问卷类型枚举增加自定义注解的方式完成。顺便巩固下枚举与注解。
一、枚举
1.在创建枚举类的时候,该类已继承java.lang.Enum类,所以自定义枚举类无法继承别的类,但可以实现接口。
【Scala十七】Scala核心十一:下划线_的用法
bit1129
scala
下划线_在Scala中广泛应用,_的基本含义是作为占位符使用。_在使用时是出问题非常多的地方,本文将不断完善_的使用场景以及所表达的含义
1. 在高阶函数中使用
scala> val list = List(-3,8,7,9)
list: List[Int] = List(-3, 8, 7, 9)
scala> list.filter(_ > 7)
r
web缓存基础:术语、http报头和缓存策略
dalan_123
Web
对于很多人来说,去访问某一个站点,若是该站点能够提供智能化的内容缓存来提高用户体验,那么最终该站点的访问者将络绎不绝。缓存或者对之前的请求临时存储,是http协议实现中最核心的内容分发策略之一。分发路径中的组件均可以缓存内容来加速后续的请求,这是受控于对该内容所声明的缓存策略。接下来将讨web内容缓存策略的基本概念,具体包括如如何选择缓存策略以保证互联网范围内的缓存能够正确处理的您的内容,并谈论下
crontab 问题
周凡杨
linux crontab unix
一: 0481-079 Reached a symbol that is not expected.
背景:
*/5 * * * * /usr/IBMIHS/rsync.sh
让tomcat支持2级域名共享session
g21121
session
tomcat默认情况下是不支持2级域名共享session的,所有有些情况下登陆后从主域名跳转到子域名会发生链接session不相同的情况,但是只需修改几处配置就可以了。
打开tomcat下conf下context.xml文件
找到Context标签,修改为如下内容
如果你的域名是www.test.com
<Context sessionCookiePath="/path&q
web报表工具FineReport常用函数的用法总结(数学和三角函数)
老A不折腾
Web finereport 总结
ABS
ABS(number):返回指定数字的绝对值。绝对值是指没有正负符号的数值。
Number:需要求出绝对值的任意实数。
示例:
ABS(-1.5)等于1.5。
ABS(0)等于0。
ABS(2.5)等于2.5。
ACOS
ACOS(number):返回指定数值的反余弦值。反余弦值为一个角度,返回角度以弧度形式表示。
Number:需要返回角
linux 启动java进程 sh文件
墙头上一根草
linux shell jar
#!/bin/bash
#初始化服务器的进程PId变量
user_pid=0;
robot_pid=0;
loadlort_pid=0;
gateway_pid=0;
#########
#检查相关服务器是否启动成功
#说明:
#使用JDK自带的JPS命令及grep命令组合,准确查找pid
#jps 加 l 参数,表示显示java的完整包路径
#使用awk,分割出pid
我的spring学习笔记5-如何使用ApplicationContext替换BeanFactory
aijuans
Spring 3 系列
如何使用ApplicationContext替换BeanFactory?
package onlyfun.caterpillar.device;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import
Linux 内存使用方法详细解析
annan211
linux 内存 Linux内存解析
来源 http://blog.jobbole.com/45748/
我是一名程序员,那么我在这里以一个程序员的角度来讲解Linux内存的使用。
一提到内存管理,我们头脑中闪出的两个概念,就是虚拟内存,与物理内存。这两个概念主要来自于linux内核的支持。
Linux在内存管理上份为两级,一级是线性区,类似于00c73000-00c88000,对应于虚拟内存,它实际上不占用
数据库的单表查询常用命令及使用方法(-)
百合不是茶
oracle 函数 单表查询
创建数据库;
--建表
create table bloguser(username varchar2(20),userage number(10),usersex char(2));
创建bloguser表,里面有三个字段
&nbs
多线程基础知识
bijian1013
java 多线程 thread java多线程
一.进程和线程
进程就是一个在内存中独立运行的程序,有自己的地址空间。如正在运行的写字板程序就是一个进程。
“多任务”:指操作系统能同时运行多个进程(程序)。如WINDOWS系统可以同时运行写字板程序、画图程序、WORD、Eclipse等。
线程:是进程内部单一的一个顺序控制流。
线程和进程
a. 每个进程都有独立的
fastjson简单使用实例
bijian1013
fastjson
一.简介
阿里巴巴fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库;包括“序列化”和“反序列化”两部分,它具备如下特征:
【RPC框架Burlap】Spring集成Burlap
bit1129
spring
Burlap和Hessian同属于codehaus的RPC调用框架,但是Burlap已经几年不更新,所以Spring在4.0里已经将Burlap的支持置为Deprecated,所以在选择RPC框架时,不应该考虑Burlap了。
这篇文章还是记录下Burlap的用法吧,主要是复制粘贴了Hessian与Spring集成一文,【RPC框架Hessian四】Hessian与Spring集成
【Mahout一】基于Mahout 命令参数含义
bit1129
Mahout
1. mahout seqdirectory
$ mahout seqdirectory
--input (-i) input Path to job input directory(原始文本文件).
--output (-o) output The directory pathna
linux使用flock文件锁解决脚本重复执行问题
ronin47
linux lock 重复执行
linux的crontab命令,可以定时执行操作,最小周期是每分钟执行一次。关于crontab实现每秒执行可参考我之前的文章《linux crontab 实现每秒执行》现在有个问题,如果设定了任务每分钟执行一次,但有可能一分钟内任务并没有执行完成,这时系统会再执行任务。导致两个相同的任务在执行。
例如:
<?
//
test
.php
java-74-数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字
bylijinnan
java
public class OcuppyMoreThanHalf {
/**
* Q74 数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字
* two solutions:
* 1.O(n)
* see <beauty of coding>--每次删除两个不同的数字,不改变数组的特性
* 2.O(nlogn)
* 排序。中间
linux 系统相关命令
candiio
linux
系统参数
cat /proc/cpuinfo cpu相关参数
cat /proc/meminfo 内存相关参数
cat /proc/loadavg 负载情况
性能参数
1)top
M:按内存使用排序
P:按CPU占用排序
1:显示各CPU的使用情况
k:kill进程
o:更多排序规则
回车:刷新数据
2)ulimit
ulimit -a:显示本用户的系统限制参
[经营与资产]保持独立性和稳定性对于软件开发的重要意义
comsci
软件开发
一个软件的架构从诞生到成熟,中间要经过很多次的修正和改造
如果在这个过程中,外界的其它行业的资本不断的介入这种软件架构的升级过程中
那么软件开发者原有的设计思想和开发路线
在CentOS5.5上编译OpenJDK6
Cwind
linux OpenJDK
几番周折终于在自己的CentOS5.5上编译成功了OpenJDK6,将编译过程和遇到的问题作一简要记录,备查。
0. OpenJDK介绍
OpenJDK是Sun(现Oracle)公司发布的基于GPL许可的Java平台的实现。其优点:
1、它的核心代码与同时期Sun(-> Oracle)的产品版基本上是一样的,血统纯正,不用担心性能问题,也基本上没什么兼容性问题;(代码上最主要的差异是
java乱码问题
dashuaifu
java乱码问题 js中文乱码
swfupload上传文件参数值为中文传递到后台接收中文乱码 在js中用setPostParams({"tag" : encodeURI( document.getElementByIdx_x("filetag").value,"utf-8")});
然后在servlet中String t
cygwin很多命令显示command not found的解决办法
dcj3sjt126com
cygwin
cygwin很多命令显示command not found的解决办法
修改cygwin.BAT文件如下
@echo off
D:
set CYGWIN=tty notitle glob
set PATH=%PATH%;d:\cygwin\bin;d:\cygwin\sbin;d:\cygwin\usr\bin;d:\cygwin\usr\sbin;d:\cygwin\us
[介绍]从 Yii 1.1 升级
dcj3sjt126com
PHP yii2
2.0 版框架是完全重写的,在 1.1 和 2.0 两个版本之间存在相当多差异。因此从 1.1 版升级并不像小版本间的跨越那么简单,通过本指南你将会了解两个版本间主要的不同之处。
如果你之前没有用过 Yii 1.1,可以跳过本章,直接从"入门篇"开始读起。
请注意,Yii 2.0 引入了很多本章并没有涉及到的新功能。强烈建议你通读整部权威指南来了解所有新特性。这样有可能会发
Linux SSH免登录配置总结
eksliang
ssh-keygen Linux SSH免登录认证 Linux SSH互信
转载请出自出处:http://eksliang.iteye.com/blog/2187265 一、原理
我们使用ssh-keygen在ServerA上生成私钥跟公钥,将生成的公钥拷贝到远程机器ServerB上后,就可以使用ssh命令无需密码登录到另外一台机器ServerB上。
生成公钥与私钥有两种加密方式,第一种是
手势滑动销毁Activity
gundumw100
android
老是效仿ios,做android的真悲催!
有需求:需要手势滑动销毁一个Activity
怎么办尼?自己写?
不用~,网上先问一下百度。
结果:
http://blog.csdn.net/xiaanming/article/details/20934541
首先将你需要的Activity继承SwipeBackActivity,它会在你的布局根目录新增一层SwipeBackLay
JavaScript变换表格边框颜色
ini
JavaScript html Web html5 css
效果查看:http://hovertree.com/texiao/js/2.htm代码如下,保存到HTML文件也可以查看效果:
<html>
<head>
<meta charset="utf-8">
<title>表格边框变换颜色代码-何问起</title>
</head>
<body&
Kafka Rest : Confluent
kane_xie
kafka REST confluent
最近拿到一个kafka rest的需求,但kafka暂时还没有提供rest api(应该是有在开发中,毕竟rest这么火),上网搜了一下,找到一个Confluent Platform,本文简单介绍一下安装。
这里插一句,给大家推荐一个九尾搜索,原名叫谷粉SOSO,不想fanqiang谷歌的可以用这个。以前在外企用谷歌用习惯了,出来之后用度娘搜技术问题,那匹配度简直感人。
环境声明:Ubu
Calender不是单例
men4661273
单例 Calender
在我们使用Calender的时候,使用过Calendar.getInstance()来获取一个日期类的对象,这种方式跟单例的获取方式一样,那么它到底是不是单例呢,如果是单例的话,一个对象修改内容之后,另外一个线程中的数据不久乱套了吗?从试验以及源码中可以得出,Calendar不是单例。
测试:
Calendar c1 =
线程内存和主内存之间联系
qifeifei
java thread
1, java多线程共享主内存中变量的时候,一共会经过几个阶段,
lock:将主内存中的变量锁定,为一个线程所独占。
unclock:将lock加的锁定解除,此时其它的线程可以有机会访问此变量。
read:将主内存中的变量值读到工作内存当中。
load:将read读取的值保存到工作内存中的变量副本中。
schedule和scheduleAtFixedRate
tangqi609567707
java timer schedule
原文地址:http://blog.csdn.net/weidan1121/article/details/527307
import java.util.Timer;import java.util.TimerTask;import java.util.Date;
/** * @author vincent */public class TimerTest {
erlang 部署
wudixiaotie
erlang
1.如果在启动节点的时候报这个错 :
{"init terminating in do_boot",{'cannot load',elf_format,get_files}}
则需要在reltool.config中加入
{app, hipe, [{incl_cond, exclude}]},
2.当generate时,遇到:
ERROR