当前位置: 首页 > news >正文

(二十一)Java集合框架源码深度解析

一、集合框架概述

Java集合框架(Java Collections Framework, JCF)是Java语言中用于存储和操作数据集合的一套标准架构。它提供了一组接口、实现类和算法,使开发者能够高效地处理各种数据结构。

1.1 集合框架的历史演变

在Java 1.2之前,Java只有几种简单的集合类:

  • Vector

  • Hashtable

  • 数组

  • Properties

这些早期集合类存在诸多问题:

  • 命名不规范

  • 方法命名不一致

  • 缺乏统一的接口

  • 性能不佳

Java 1.2引入了全新的集合框架,主要设计者为Joshua Bloch。这个新框架具有以下特点:

  • 统一的接口层次结构

  • 高性能实现

  • 可扩展性

  • 类型安全(通过泛型)

1.2 集合框架的核心接口

Java集合框架的核心接口构成了一个层次结构:

Iterable
└── Collection├── List├── Set│   └── SortedSet└── Queue└── Deque

此外还有独立的Map接口及其子接口SortedMap。

二、Collection接口解析

Collection接口是集合框架的根接口之一,定义了所有集合类共有的基本操作。

2.1 核心方法分析

java

public interface Collection<E> extends Iterable<E> {// 基本操作int size();boolean isEmpty();boolean contains(Object o);Iterator<E> iterator();Object[] toArray();<T> T[] toArray(T[] a);// 修改操作boolean add(E e);boolean remove(Object o);// 批量操作boolean containsAll(Collection<?> c);boolean addAll(Collection<? extends E> c);boolean removeAll(Collection<?> c);boolean retainAll(Collection<?> c);void clear();// 比较和哈希boolean equals(Object o);int hashCode();// JDK 8新增的默认方法default boolean removeIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);boolean removed = false;final Iterator<E> each = iterator();while (each.hasNext()) {if (filter.test(each.next())) {each.remove();removed = true;}}return removed;}// 其他默认方法...
}

2.2 设计模式应用

Collection接口体现了多种设计模式:

  1. 迭代器模式:通过iterator()方法提供遍历集合的标准方式

  2. 模板方法模式:默认方法removeIf()提供了基于条件删除的通用实现

  3. 策略模式:通过传递Predicate实现不同的删除策略

三、List接口及其实现

List代表有序集合(序列),允许重复元素和null值。

3.1 ArrayList源码分析

ArrayList是基于动态数组的实现,是List最常用的实现类。

3.1.1 核心字段

java

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {// 默认初始容量private static final int DEFAULT_CAPACITY = 10;// 空数组实例,用于空实例private static final Object[] EMPTY_ELEMENTDATA = {};// 默认大小的空数组实例private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};// 存储ArrayList元素的数组缓冲区transient Object[] elementData;// ArrayList的大小(包含的元素数量)private int size;// 修改计数器,用于快速失败机制protected transient int modCount = 0;
}
3.1.2 扩容机制

ArrayList的核心扩容方法grow():

java

private void grow(int minCapacity) {// 溢出安全的代码int oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// 最小容量通常接近size,所以这是扩容操作elementData = Arrays.copyOf(elementData, newCapacity);
}

扩容过程:

  1. 计算新容量为旧容量的1.5倍

  2. 检查是否满足最小容量要求

  3. 检查是否超过最大数组大小限制

  4. 使用Arrays.copyOf()创建新数组并复制元素

3.1.3 添加元素

java

public boolean add(E e) {modCount++;add(e, elementData, size);return true;
}private void add(E e, Object[] elementData, int s) {if (s == elementData.length)elementData = grow();elementData[s] = e;size = s + 1;
}
3.1.4 删除元素

java

public E remove(int index) {Objects.checkIndex(index, size);final Object[] es = elementData;@SuppressWarnings("unchecked") E oldValue = (E) es[index];fastRemove(es, index);return oldValue;
}private void fastRemove(Object[] es, int i) {modCount++;final int newSize;if ((newSize = size - 1) > i)System.arraycopy(es, i + 1, es, i, newSize - i);es[size = newSize] = null;
}

3.2 LinkedList源码分析

LinkedList是基于双向链表的实现,同时实现了List和Deque接口。

3.2.1 节点结构

java

private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}
}
3.2.2 核心字段

java

transient int size = 0;
transient Node<E> first; // 头节点
transient Node<E> last;  // 尾节点
3.2.3 添加元素

java

public boolean add(E e) {linkLast(e);return true;
}void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;
}
3.2.4 删除元素

java

public E remove(int index) {checkElementIndex(index);return unlink(node(index));
}E unlink(Node<E> x) {final E element = x.item;final Node<E> next = x.next;final Node<E> prev = x.prev;if (prev == null) {first = next;} else {prev.next = next;x.prev = null;}if (next == null) {last = prev;} else {next.prev = prev;x.next = null;}x.item = null;size--;modCount++;return element;
}

3.3 Vector与ArrayList对比

Vector是线程安全的ArrayList,但性能较差。主要区别:

  1. 同步机制:Vector所有方法都是同步的

  2. 扩容策略:Vector默认增长一倍,ArrayList增长50%

  3. 遗留类:Vector是Java 1.0的遗留类

四、Set接口及其实现

Set是不包含重复元素的集合,最多包含一个null元素。

4.1 HashSet源码分析

HashSet是基于HashMap的实现,使用对象的hashCode()和equals()方法来确保唯一性。

4.1.1 核心字段

java

private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
4.1.2 构造方法

java

public HashSet() {map = new HashMap<>();
}public HashSet(int initialCapacity) {map = new HashMap<>(initialCapacity);
}
4.1.3 添加元素

java

public boolean add(E e) {return map.put(e, PRESENT)==null;
}

4.2 LinkedHashSet源码分析

LinkedHashSet继承自HashSet,但内部使用LinkedHashMap维护插入顺序。

4.2.1 构造方法

java

public LinkedHashSet(int initialCapacity) {super(initialCapacity, .75f, true);
}// HashSet中的特殊构造方法
HashSet(int initialCapacity, float loadFactor, boolean dummy) {map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

4.3 TreeSet源码分析

TreeSet是基于TreeMap的NavigableSet实现,元素按照自然顺序或Comparator排序。

4.3.1 核心字段

java

private transient NavigableMap<E,Object> m;
private static final Object PRESENT = new Object();
4.3.2 构造方法

java

public TreeSet() {this(new TreeMap<E,Object>());
}public TreeSet(Comparator<? super E> comparator) {this(new TreeMap<>(comparator));
}

五、Map接口及其实现

Map是键值对的集合,每个键最多映射到一个值。

5.1 HashMap源码分析

HashMap是基于哈希表的Map实现,允许null键和null值。

5.1.1 核心字段

java

// 默认初始容量 - 必须是2的幂
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 16// 最大容量
static final int MAXIMUM_CAPACITY = 1 << 30;// 默认负载因子
static final float DEFAULT_LOAD_FACTOR = 0.75f;// 链表转红黑树的阈值
static final int TREEIFY_THRESHOLD = 8;// 红黑树转链表的阈值
static final int UNTREEIFY_THRESHOLD = 6;// 最小树化容量
static final int MIN_TREEIFY_CAPACITY = 64;// 哈希表
transient Node<K,V>[] table;// 键值对集合
transient Set<Map.Entry<K,V>> entrySet;// 元素数量
transient int size;// 修改计数器
transient int modCount;// 扩容阈值 (capacity * load factor)
int threshold;// 负载因子
final float loadFactor;
5.1.2 节点结构

java

static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;V value;Node<K,V> next;// 构造方法和其他实现...
}
5.1.3 哈希计算

java

static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
5.1.4 put方法实现

java

public V put(K key, V value) {return putVal(hash(key), key, value, false, true);
}final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;// 表为空则创建if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;// 计算索引位置if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;// 键已存在if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;// 红黑树节点else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);// 链表节点else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}// 替换值if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;
}
5.1.5 扩容机制

java

final Node<K,V>[] resize() {Node<K,V>[] oldTab = table;int oldCap = (oldTab == null) ? 0 : oldTab.length;int oldThr = threshold;int newCap, newThr = 0;if (oldCap > 0) {if (oldCap >= MAXIMUM_CAPACITY) {threshold = Integer.MAX_VALUE;return oldTab;}else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&oldCap >= DEFAULT_INITIAL_CAPACITY)newThr = oldThr << 1; // 双倍扩容}else if (oldThr > 0) // 初始容量设为阈值newCap = oldThr;else {               // 零初始阈值表示使用默认值newCap = DEFAULT_INITIAL_CAPACITY;newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);}if (newThr == 0) {float ft = (float)newCap * loadFactor;newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?(int)ft : Integer.MAX_VALUE);}threshold = newThr;@SuppressWarnings({"rawtypes","unchecked"})Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];table = newTab;if (oldTab != null) {for (int j = 0; j < oldCap; ++j) {Node<K,V> e;if ((e = oldTab[j]) != null) {oldTab[j] = null;if (e.next == null)newTab[e.hash & (newCap - 1)] = e;else if (e instanceof TreeNode)((TreeNode<K,V>)e).split(this, newTab, j, oldCap);else { // 保持顺序Node<K,V> loHead = null, loTail = null;Node<K,V> hiHead = null, hiTail = null;Node<K,V> next;do {next = e.next;if ((e.hash & oldCap) == 0) {if (loTail == null)loHead = e;elseloTail.next = e;loTail = e;}else {if (hiTail == null)hiHead = e;elsehiTail.next = e;hiTail = e;}} while ((e = next) != null);if (loTail != null) {loTail.next = null;newTab[j] = loHead;}if (hiTail != null) {hiTail.next = null;newTab[j + oldCap] = hiHead;}}}}}return newTab;
}

5.2 LinkedHashMap源码分析

LinkedHashMap继承自HashMap,通过维护一个双向链表来保持插入顺序或访问顺序。

5.2.1 节点结构

java

static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after;Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}
}
5.2.2 核心字段

java

// 双向链表的头节点
transient LinkedHashMap.Entry<K,V> head;// 双向链表的尾节点
transient LinkedHashMap.Entry<K,V> tail;// 访问顺序(false=插入顺序, true=访问顺序)
final boolean accessOrder;
5.2.3 访问顺序维护

java

void afterNodeAccess(Node<K,V> e) { // 将节点移到链表末尾LinkedHashMap.Entry<K,V> last;if (accessOrder && (last = tail) != e) {LinkedHashMap.Entry<K,V> p =(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;p.after = null;if (b == null)head = a;elseb.after = a;if (a != null)a.before = b;elselast = b;if (last == null)head = p;else {p.before = last;last.after = p;}tail = p;++modCount;}
}

5.3 TreeMap源码分析

TreeMap是基于红黑树的NavigableMap实现,按键的自然顺序或Comparator排序。

5.3.1 节点结构

java

static final class Entry<K,V> implements Map.Entry<K,V> {K key;V value;Entry<K,V> left;Entry<K,V> right;Entry<K,V> parent;boolean color = BLACK;// 构造方法和其他实现...
}
5.3.2 红黑树操作

TreeMap实现了完整的红黑树操作,包括旋转、插入平衡和删除平衡等。

六、并发集合类

Java还提供了一系列线程安全的集合类,位于java.util.concurrent包中。

6.1 ConcurrentHashMap

ConcurrentHashMap是线程安全的HashMap实现,采用分段锁技术(JDK 7)或CAS+synchronized(JDK 8)。

6.1.1 JDK 8实现改进

JDK 8的ConcurrentHashMap摒弃了分段锁,改用:

  • CAS操作

  • synchronized锁单个桶

  • 更细粒度的并发控制

6.1.2 核心方法

java

public V put(K key, V value) {return putVal(key, value, false);
}final V putVal(K key, V value, boolean onlyIfAbsent) {if (key == null || value == null) throw new NullPointerException();int hash = spread(key.hashCode());int binCount = 0;for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh;if (tab == null || (n = tab.length) == 0)tab = initTable();else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {if (casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null)))break;                   // no lock when adding to empty bin}else if ((fh = f.hash) == MOVED)tab = helpTransfer(tab, f);else {V oldVal = null;synchronized (f) {if (tabAt(tab, i) == f) {if (fh >= 0) {binCount = 1;for (Node<K,V> e = f;; ++binCount) {K ek;if (e.hash == hash &&((ek = e.key) == key ||(ek != null && key.equals(ek)))) {oldVal = e.val;if (!onlyIfAbsent)e.val = value;break;}Node<K,V> pred = e;if ((e = e.next) == null) {pred.next = new Node<K,V>(hash, key,value, null);break;}}}else if (f instanceof TreeBin) {Node<K,V> p;binCount = 2;if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,value)) != null) {oldVal = p.val;if (!onlyIfAbsent)p.val = value;}}}}if (binCount != 0) {if (binCount >= TREEIFY_THRESHOLD)treeifyBin(tab, i);if (oldVal != null)return oldVal;break;}}}addCount(1L, binCount);return null;
}

6.2 CopyOnWriteArrayList

CopyOnWriteArrayList是线程安全的List实现,采用写时复制技术。

6.2.1 核心思想
  • 读操作无锁

  • 写操作复制底层数组

  • 适用于读多写少的场景

6.2.2 添加元素

java

public boolean add(E e) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;Object[] newElements = Arrays.copyOf(elements, len + 1);newElements[len] = e;setArray(newElements);return true;} finally {lock.unlock();}
}

七、集合框架的性能比较

7.1 List实现性能比较

操作ArrayListLinkedList
get(int)O(1)O(n)
add(E)O(1) 摊销O(1)
add(int, E)O(n)O(1)
remove(int)O(n)O(1)
remove(E)O(n)O(n)

7.2 Set实现性能比较

操作HashSetLinkedHashSetTreeSet
add(E)O(1)O(1)O(log n)
contains(E)O(1)O(1)O(log n)
remove(E)O(1)O(1)O(log n)
迭代顺序插入顺序排序顺序

7.3 Map实现性能比较

操作HashMapLinkedHashMapTreeMap
put(K,V)O(1)O(1)O(log n)
get(K)O(1)O(1)O(log n)
remove(K)O(1)O(1)O(log n)
迭代顺序插入/访问顺序排序顺序

八、集合框架的最佳实践

  1. 选择合适的集合类

    • 需要快速随机访问:ArrayList

    • 频繁插入删除:LinkedList

    • 去重:HashSet

    • 键值对:HashMap

    • 排序:TreeSet/TreeMap

  2. 初始化合适容量

    • 对于已知大小的集合,指定初始容量避免扩容开销

    • ArrayList: new ArrayList(100)

    • HashMap: new HashMap(256, 0.75f)

  3. 合理使用泛型

    java

    // 好
    List<String> list = new ArrayList<>();// 不好
    List list = new ArrayList();

  4. 遍历集合的选择

    • 随机访问列表:for循环

    • 顺序访问列表:增强for循环或迭代器

    • 并行处理:Java 8 Stream API

  5. 线程安全考虑

    • 单线程:普通集合类

    • 多线程读多写少:CopyOnWriteArrayList

    • 高并发Map:ConcurrentHashMap

    • 同步包装:Collections.synchronizedXXX()

  6. 避免在迭代中修改集合

    • 使用迭代器的remove()方法

    • 或使用CopyOnWriteArrayList

  7. 重写hashCode()和equals()

    • 作为HashMap键或HashSet元素的类必须正确实现这两个方法

    • 遵循约定:相等对象必须有相同hashCode

  8. 利用Java 8新特性

    java

    map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
    list.removeIf(e -> e == null);

九、常见问题与解决方案

9.1 集合与数组转换

java

// 集合转数组
List<String> list = new ArrayList<>();
String[] array = list.toArray(new String[0]);// 数组转集合
List<String> list = Arrays.asList(array); // 固定大小
List<String> list = new ArrayList<>(Arrays.asList(array)); // 可变

9.2 集合的不可变视图

java

List<String> immutableList = Collections.unmodifiableList(list);
Set<String> immutableSet = Collections.unmodifiableSet(set);
Map<K,V> immutableMap = Collections.unmodifiableMap(map);

9.3 空集合与单元素集合

java

List<String> emptyList = Collections.emptyList();
Set<String> singletonSet = Collections.singleton("item");
Map<String,String> singletonMap = Collections.singletonMap("key", "value");

9.4 集合排序

java

// 自然排序
Collections.sort(list);// 自定义排序
Collections.sort(list, (a, b) -> a.length() - b.length());// Java 8方式
list.sort(Comparator.comparing(String::length));

十、总结

Java集合框架是Java语言中最重要、最常用的API之一。通过深入理解其源码实现,我们可以:

  1. 更高效地使用集合类

  2. 根据场景选择最合适的实现

  3. 避免常见的陷阱和性能问题

  4. 编写更健壮、更高效的代码

从设计角度看,集合框架体现了多种优秀的设计原则和模式:

  • 接口与实现分离

  • 算法与数据结构分离

  • 迭代器模式

  • 策略模式

  • 模板方法模式

随着Java版本的演进,集合框架也在不断优化和改进,如Java 8引入的Stream API和Lambda表达式使集合操作更加简洁和强大。作为Java开发者,深入理解集合框架的内部机制是提升编程能力的重要一步。

相关文章:

(二十一)Java集合框架源码深度解析

一、集合框架概述 Java集合框架(Java Collections Framework, JCF)是Java语言中用于存储和操作数据集合的一套标准架构。它提供了一组接口、实现类和算法&#xff0c;使开发者能够高效地处理各种数据结构。 1.1 集合框架的历史演变 在Java 1.2之前&#xff0c;Java只有几种简…...

spark数据的提取和保存

Spark数据提取和保存 一、数据提取&#xff08;读取数据&#xff09; 1. 读取文件&#xff08;文本、CSV、JSON等&#xff09; scala // 读取文本文件 val textData spark.read.text("路径/文件.txt") // 读取CSV文件&#xff08;带表头&#xff09; val csvD…...

Graphics——基于.NET 的 CAD 图形预览技术研究与实现——CAD c#二次开发

一、Graphics 类的本质与作用 Graphics 是 .NET 框架中 System.Drawing 命名空间下的核心类&#xff0c;用于在二维画布&#xff08;如 Bitmap 图像&#xff09;上绘制图形、文本或图像。它相当于 “绘图工具”&#xff0c;提供了一系列方法&#xff08;如 DrawLine、FillElli…...

vue3_flask实现mysql数据库对比功能

实现对mysql中两个数据库的表、表结构、表数据的对比功能, 效果如下图 基础环境请参考 vue3flasksqlite前后端项目实战 代码文件结构变化 api/ # 后端相关 ├── daos/ │ ├── __init__.py │ └── db_compare_dao.py # 新增 ├── routes/ │ ├── _…...

【数据结构】2-3-1单链表的定义

数据结构知识点合集 知识点 单链表存储结构 优点&#xff1a;不要求大片连续空间&#xff0c;改变容量方便&#xff1b;缺点&#xff1a;不可随机存取&#xff0c;要耗费一定空间存放指针 /*单链表节点定义*/ typedef struct LNode{ElemType data;struct LNode *next; }LNo…...

面试题总结一

第一天 1. 快速排序 public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {// 分区操作&#xff0c;获取基准元素的最终位置int pivotIndex partition(arr, low, high);// 递归排序基准元素左边的部分quickSort(arr, …...

Ubuntu24.04下安装ISPConfig全过程记录

今天在网上看到ISPConfig&#xff0c;觉得不错&#xff0c;刚好手里又有一台没用的VPS,就顺手安装一个玩玩。具体安装步骤如下&#xff1a; 一、配置服务器hosts及hostname 【安装时候需要检查】 使用root账号登录VPS后 先安装vim编辑器&#xff0c;然后编辑hosts&#xff0…...

【NGINX】 -10 keepalived + nginx + httpd 实现的双机热备+ 负载均衡

文章目录 1、主架构图1.1 IP地址规划 2、web服务器操作3、配置nginx服务器的负载均衡4、配置keepalived4.1 master4.1 backup 5、测试双机热备5.1 两台keepalived服务器均开启5.2 模拟master节点故障 1、主架构图 1.1 IP地址规划 服务器IP地址web1192.168.107.193web2192.168.…...

NC016NC017美光固态芯片NC101NC102

NC016NC017美光固态芯片NC101NC102 在存储技术的演进历程中&#xff0c;美光科技的NC016、NC017、NC101与NC102系列固态芯片&#xff0c;凭借其技术创新与市场适应性&#xff0c;成为行业关注的焦点。本文将从技术内核、产品性能、行业动向、应用场景及市场价值五个维度&#…...

C++(22):fstream的一些成员函数

目录 1 遍历读取文件 1.1 eof()方法 2 读取文件大小 2.1 seekg() 2.2 tellg() 2.3 代码实例 3 存取文字 3.1 read() 3.2 write() 3.3 代码实例 3.3.1 存取文字 3.3.2 特殊方法存储 3.3.3 特殊方法读取 4 重载的输入输出 4.1 重载的输出 << 4.2 重载的输…...

【网络】Wireshark练习3 analyse DNS||ICMP and response message

ip.addr 172.16.0.100 && ip.addr 172.16.0.5 && (dns || icmp) 包号 22–31 之所以被选中&#xff0c;是因为在整个抓包文件里&#xff0c;与执行 ping cat.inx251.edu.au 这一事件相关的所有报文&#xff0c;恰好连续出现在第 22 到第 31 条记录中。具体分…...

GBS 8.0服装裁剪计划软件在线试用

1、全新升级内核8.0&#xff0c;分床更合理&#xff0c;铺布床数更少&#xff1b; 2、支持SS AUTONESTER排料引擎切换 3、支持ASTM AAMA及国产CAD&#xff08;如布衣&#xff09;导出的DXF&#xff0c;Prj文件等 4、核心引擎优化 拖料优化 省料优化 5、经实战对比人工&…...

顺 序 表:数 据 存 储 的 “ 有 序 阵 地 ”

顺 序 表&#xff1a;数 据 存 储 的 “ 有 序 阵 地 ” 线 性 表顺 序 表 - - - 顺 序 存 储 结 构顺 序 表 的 操 作 实 现代 码 全 貌 与 功 能 介 绍顺 序 表 的 功 能 说 明代 码 效 果 展 示代 码 详 解SeqList.hSeqList.ctest.c 总 结 &#x1f4bb;作 者 简 介&#xf…...

#Redis黑马点评#(七)实战篇完结

目录 一 达人探店 1 发布探店笔记 2 查看探店笔记 3 点赞功能 ​编辑 4 点赞排行榜&#xff08;top5&#xff09; ​编辑 二 好友关注 1 关注与取关 2 共同关注 3 Feed流实现关注推送 4 实现滚动分页查询 三 附近商店 1 GEO数据结构 2 附近商户搜索功能 四 用户…...

初始C++:类和对象(中)

概述&#xff1a;本篇博客主要介绍类和对象的相关知识。 1. 类的默认成员函数 默认成员函数就是用户没有显示实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。一个类&#xff0c;在不写任何代码的情况下编译器会默认生成以下六个默认函数&#xff0c;在六个默认…...

Java开发经验——阿里巴巴编码规范实践解析3

摘要 本文深入解析了阿里巴巴编码规范中关于错误码的制定与管理原则&#xff0c;强调错误码应便于快速溯源和沟通标准化&#xff0c;避免过于复杂。介绍了错误码的命名与设计示例&#xff0c;推荐采用模块前缀、错误类型码和业务编号的结构。同时&#xff0c;探讨了项目错误信…...

ChatGPT:OpenAI Codex—一款基于云的软件工程 AI 代理,赋能 ChatGPT,革新软件开发模式

ChatGPT&#xff1a;OpenAI Codex—一款基于云的软件工程 AI 代理&#xff0c;赋能 ChatGPT&#xff0c;革新软件开发模式 导读&#xff1a;2025年5月16日&#xff0c;OpenAI 发布了 Codex&#xff0c;一个基于云的软件工程 AI 代理&#xff0c;它集成在 ChatGPT 中&#xff0c…...

iOS 内存分区

iOS内存分区 文章目录 iOS内存分区前言五大分区static、extern、const关键字比较conststaticextern与.h文件的关系extern引用变量extern声明 static和const联合使用extern和const联合使用 前言 笔者之前学习OC源码的时候,发现对于这里的几个static,extern,const的内容有遗忘,所…...

LWIP的Socket接口

Socket接口简介 类似于文件操作的一种网络连接接口&#xff0c;通常将其称之为“套接字”。lwIP的Socket接口兼容BSD Socket接口&#xff0c;但只实现完整Socket的部分功能 netconn是对RAW的封装 Socket是对netconn的封装 SOCKET结构体 struct sockaddr { u8_t sa_len; /* 长…...

【Linux笔记】——线程同步条件变量与生产者消费者模型的实现

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;Linux &#x1f339;往期回顾&#x1f339;&#xff1a;【Linux笔记】——线程互斥与互斥锁的封装 &#x1f516;流水不争&#xff0c;争的是滔滔不息 一、线程同步的…...

Popeye

概览与定位 Popeye 是由 derailed 团队开源的 Kubernetes 集群资源 “Sanitizer”&#xff0c;它以只读方式扫描集群内的各种资源&#xff08;如 Pod、Service、Ingress、PVC、RBAC 等&#xff09;&#xff0c;并基于社区最佳实践给出问题等级及修复建议&#xff0c;覆盖配置误…...

ES(ES2023/ES14)最新更新内容,及如何减少内耗

截至2023年10月,JavaScript(ECMAScript)的最新版本是 ES2023(ES14)。 ES2023 引入了许多新特性,如findLast、toSorted等,同时优化了性能。通过减少全局变量、避免内存泄漏、优化循环、减少DOM操作、使用Web Workers、懒加载、缓存、高效数据结构和代码压缩,可以显著降低…...

电子数据取证(数字取证)技术全面指南:从基础到实践

为了后续查阅方便&#xff0c;推荐工具先放到前面 推荐工具 数字取证基础工具 综合取证平台 工具名称类型主要功能适用场景EnCase Forensic商业全面的证据获取和分析、强大的搜索能力法律诉讼、企业调查FTK (Forensic Toolkit)商业高性能处理和索引、集成内存分析大规模数据处…...

【通用智能体】Serper API 详解:搜索引擎数据获取的核心工具

Serper API 详解&#xff1a;搜索引擎数据获取的核心工具 一、Serper API 的定义与核心功能二、技术架构与核心优势2.1 技术实现原理2.2 对比传统方案的突破性优势 三、典型应用场景与代码示例3.1 SEO 监控系统3.2 竞品广告分析 四、使用成本与配额策略五、开发者注意事项六、替…...

基于 STM32 的手持式安检金属探测器设计与实现

一、硬件设计:芯片与功能模块选型及接线 1. 主控芯片选型 芯片型号:STM32F103C8T6 核心优势: 32 位 Cortex-M3 内核,主频 72MHz,满足实时数据处理需求64KB Flash+20KB SRAM,支持程序存储与数据缓存丰富外设:2 路 USART、2 路 SPI、1 路 I2C、12 位 ADC,适配多模块通信…...

虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系

虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系1.Default Pawn与Camera的关系1.1. Default Pawn 是什么&#xff1f;1.2. Default Pawn 的主要组件1.3. Default…...

Spring源码主线全链路拆解:从启动到关闭的完整生命周期

Spring源码主线全链路拆解&#xff1a;从启动到关闭的完整生命周期 一文看懂 Spring 框架从启动到销毁的主线流程&#xff0c;结合原理、源码路径与伪代码三位一体&#xff0c;系统学习 Spring 底层机制。 1. 启动入口与环境准备 原理说明 Spring Boot 应用入口是标准 Java 应…...

飞帆控件:可配置post/get接口

先上链接&#xff1a; post_get_ithttps://fvi.cn/796看一下这个控件的配置&#xff1a; 当 url 有某个 get 参数时&#xff0c;例如某些接口回传的参数。使用这个接口会发生这些&#xff1a; 如果检测到 url 中有该 url 参数则继续执行选择是否从 url 中删除该参数将这个参数…...

Android 自定义悬浮拖动吸附按钮

一个悬浮的拨打电话按钮&#xff0c;使用CardViewImageView可能会出现适配问题&#xff0c;也就是图片显示不全&#xff0c;出现这种问题&#xff0c;就直接替换控件了&#xff0c;因为上述的组合控件没有FloatingActionButton使用方便&#xff0c;还可以有拖动和吸附效果不是更…...

Spring AI Alibaba集成阿里云百炼大模型应用

文章目录 1.准备工作2.引入maven依赖3.application.yml4.调用4.1.非流式调用4.2.流式调用 阿里云百炼推出的智能体应用、工作流应用和智能体编排应用&#xff0c;有效解决了大模型在处理私有领域问题、获取最新信息、遵循固定流程以及自动规划复杂项目等方面的局限&#xff0c;…...

UI-TARS本地部署

UI-TARS本地部署 UI-TARS本地部署 UI-TARS 论文&#xff08;arXiv&#xff09; UI-TARS 官方仓库&#xff1a;包含部署指南、模型下载链接及示例代码。 UI-TARS-Desktop 客户端&#xff1a;支持本地桌面应用的交互控制。 模型部署框架&#xff1a;vLLM本地部署 1.下载项目…...

如何利用内网穿透实现Cursor对私有化部署大模型的跨网络访问实践

文章目录 前言1.安装Ollama2.QwQ-32B模型安装与运行3.Cursor安装与配置4. 简单使用测试5. 调用本地大模型6. 安装内网穿透7. 配置固定公网地址总结 前言 本文主要介绍如何在Windows环境下&#xff0c;使用Cursor接入Ollama启动本地部署的千问qwq-32b大模型实现辅助编程&#x…...

Linux的进程概念

目录 1、冯诺依曼体系结构 2、操作系统(Operating System) 2.1 基本概念 ​编辑 2.2 目的 3、Linux的进程 3.1 基本概念 3.1.1 PCB 3.1.2 struct task_struct 3.1.3 进程的定义 3.2 基本操作 3.2.1 查看进程 3.2.2 初识fork 3.3 进程状态 3.3.1 操作系统的进程状…...

(10)python开发经验

文章目录 1 cp35 cp36什么意思2 找不到pip3 subprocess编码错误4 导出依赖文件包含路径5 使用自己编译的python并且pyinstall打包程序 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发 &#x1f448;&#x1f449;python开发 &#x1f448; 1 cp35 cp36什…...

什么是时间戳?怎么获取?有什么用

时间戳的定义 时间戳&#xff08;Timestamp&#xff09;是指记录某个事件发生的具体时间点&#xff0c;通常以特定的格式表示。它可以精确到秒、毫秒甚至更小的单位&#xff0c;用于标识某个时刻在时间轴上的位置。 获取时间戳的方法 在不同的编程语言中&#xff0c;获取时间…...

Zookeeper 入门(二)

4. Zookeeper 的 ACL 权限控制( Access Control List ) Zookeeper 的ACL 权限控制,可以控制节点的读写操作,保证数据的安全性&#xff0c;Zookeeper ACL 权 限设置分为 3 部分组成&#xff0c;分别是&#xff1a;权限模式&#xff08;Scheme&#xff09;、授权对象&#xff08…...

[创业之路-361]:企业战略管理案例分析-2-战略制定-使命、愿景、价值观的失败案例

一、失败案例 1、使命方面的失败案例 真功夫创业者内乱&#xff1a;真功夫在创业过程中&#xff0c;由于股权结构不合理&#xff0c;共同创始人及公司大股东潘宇海与实际控制人、董事长蔡达标产生管理权矛盾。双方在公司发展方向、管理改革等方面无法达成一致&#xff0c;导致…...

dijkstra算法加训上 之 分层图最短路

来几个分层图的题练习下哈 P4568 [JLOI2011] 飞行路线 P4568 [JLOI2011] 飞行路线 - 洛谷https://www.luogu.com.cn/problem/P4568 题目描述 Alice 和 Bob 现在要乘飞机旅行&#xff0c;他们选择了一家相对便宜的航空公司。该航空公司一共在 n 个城市设有业务&#xff0c;设这…...

赋予AI更强的“思考”能力

刚刚&#xff01;北大校友、OpenAI前安全副总裁Lilian Weng最新博客来了&#xff1a;Why We Think 原文链接&#xff1a;Why We Think by Lilian Weng 这篇文章关注&#xff1a;如何让AI不仅仅是“知道”答案&#xff0c;更能“理解”问题并推导出答案。通过赋予AI更强的“思…...

微服务项目->在线oj系统(Java版 - 1)

相信自己,终会成功 目录 C/S架构与B/S架构 C/S架构&#xff08;Client/Server&#xff0c;客户端/服务器架构&#xff09; 特点&#xff1a; 优点&#xff1a; 缺点&#xff1a; 典型应用&#xff1a; B/S架构&#xff08;Browser/Server&#xff0c;浏览器/服务器架构&a…...

【深度学习】使用块的网络(VGG)

虽然 AlexNet 证明深层神经网络卓有成效&#xff0c;但它没有提供一个通用的模板来指导后续的研究人员设计新的网络。 也就是说尽管我知道了更深更大的网络更有效&#xff0c;但是不清楚怎么让它更深更大&#xff0c;从而起到一个更好的效果。 于是&#xff0c;研究人员开始从单…...

Python数据可视化 - Pyecharts绘图示例

文章目录 一、Pyecharts简介及安装1. Pyecharts简介2. 安装Pyecharts 二、准备数据三、饼图示例1. 初始化选项配置2. 饼图相关设置3. 全局配置项3.1 标题配置项3.2 图例配置项3.3 提示框配置项3.4 工具箱配置项3.5 视觉映射配置项 4. 系列配置项4.1 标签选项配置4.2 图元样式配…...

Day29

复习日 知识点回顾 类的装饰器装饰器思想的进一步理解&#xff1a;外部修改、动态类方法的定义&#xff1a;内部定义和外部定义 作业&#xff1a;复习类和函数的知识点&#xff0c;写下自己过去29天的学习心得&#xff0c;如对函数和类的理解&#xff0c;对python这门工具的理…...

Python列表全面解析:从入门到精通

文章目录 Python列表全面解析&#xff1a;从入门到精通一、列表基础1. 什么是列表&#xff1f;2. 列表特性总结表 二、列表的基本操作(基础)1. 访问元素2. 修改列表 三、列表的常用方法(基础)1. 添加元素的方法2. 删除元素的方法3. 查找和统计方法4. 排序和反转 四、列表的高级…...

Nacos数据写入流程

在 3 节点的 Nacos 集群中&#xff0c;数据写入流程和主节点&#xff08;Leader&#xff09;的角色基于 Nacos 的分布式一致性协议&#xff08;通常使用 Raft 协议&#xff09;来实现。以下以 Markdown 格式详细说明 3 节点 Nacos 集群的数据写入流程以及主节点的角色和确定方式…...

《P4551 最长异或路径》

题目描述 给定一棵 n 个点的带权树&#xff0c;结点下标从 1 开始到 n。寻找树中找两个结点&#xff0c;求最长的异或路径。 异或路径指的是指两个结点之间唯一路径上的所有边权的异或。 输入格式 第一行一个整数 n&#xff0c;表示点数。 接下来 n−1 行&#xff0c;给出…...

Ansible模块——文件属性查看,文件或目录创建和属性修改

ansible.builtin.stat 可以查看文件信息。 选项 类型 默认值 描述 pathstrnull 要检查的文件或目录的完整路径&#xff08;必需&#xff09;。 followboolfalse 如果是符号链接&#xff0c;是否跟随到目标路径上获取其状态。 get_attributesbooltrue 是否返回扩展属性&#…...

【图像生成大模型】Wan2.1:下一代开源大规模视频生成模型

Wan2.1&#xff1a;下一代开源大规模视频生成模型 引言Wan2.1 项目概述核心技术1. 3D 变分自编码器&#xff08;Wan-VAE&#xff09;2. 视频扩散 Transformer&#xff08;Video Diffusion DiT&#xff09;3. 数据处理与清洗 项目运行方式与执行步骤1. 环境准备2. 安装依赖3. 模…...

AGI大模型(25):LangChain提示词模版

我们也可以创建prompt template, 并引入一些变量到prompt template中,这样在应用的时候更加灵活。 1 代码实现 # 我们也可以创建prompt template, 并引入一些变量到prompt template中,这样在应用的时候更加灵活 from langchain_core.prompts import ChatPromptTemplate from…...

mybatis中的resultMap的association及collectio的使用

目录 1.reusltmap的说明 2.association的使用 3.collection的使用 4.总结 1.reusltmap的说明 resultmap定义了数据库的结果映射到java对象的规则&#xff0c;resultmap包含4个属性&#xff1a; id: ResultMap 的唯一标识 type: 映射到的 Java 类型&#xff08;全限定类名或…...