编程语言Java——核心技术篇(四)集合类详解

言不信者行不果,行不敏者言多滞.

目录

4. 集合类

4.1 集合类概述

4.1.1 集合框架遵循原则

4.1.2 集合框架体系

 4.2 核心接口和实现类解析

4.2.1 Collection 接口体系

4.2.1.1 Collection 接口核心定义

4.2.1.2 List接口详解

4.2.1.3 Set 接口详解

4.2.1.4 Queue/Deque接口详解

4.2.2 Map 接口体系详解

 4.3 集合类选择

4.3.1 集合类选择指南

4.3.2 集合类选择决策树

4.4 性能优化建议

4.5 总结


续前篇:编程语言Java——核心技术篇(三)异常处理详解-CSDN博客

4. 集合类

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

4.1 集合类概述

4.1.1 集合框架遵循原则

集合框架的设计遵循了几个重要原则:

  • 接口与实现分离:所有具体集合类都实现自标准接口(如List、Set、Map),这使得程序可以灵活切换不同的实现而不影响业务逻辑。

  • 算法复用:Collections工具类提供了大量通用算法(如排序、查找、反转等),这些算法可以应用于任何实现了相应接口的集合类。

  • 性能优化:针对不同使用场景提供了多种实现,如需要快速随机访问选择ArrayList,需要频繁插入删除选择LinkedList。

  • 扩展性:通过迭代器模式(Iterator)和比较器(Comparator)等设计,使集合框架易于扩展和定制。

  • 类型安全:通过泛型机制在编译期检查类型一致性,避免了运行时的类型转换错误。

4.1.2 集合框架体系

这张图很清楚了,两个顶级父类接口Iterable和Map,剩下的List,Set和Queue等都是两个接口的实现子接口,在下来才是各种实现类。如果只但看各个接口之间的继承关系还有下面这张图:

我感觉这两个图可以详细地记一下,因为适用性挺广的,存放数据和操作都会频繁地遇到集合类。 

 4.2 核心接口和实现类解析

4.2.1 Collection 接口体系

4.2.1.1 Collection 接口核心定义

Collection是单列集合的根接口,定义了集合的通用行为:

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();// Java 8新增boolean removeIf(Predicate<? super E> filter);Spliterator<E> spliterator();Stream<E> stream();Stream<E> parallelStream();
}
4.2.1.2 List接口详解

1. 核心特性:

  • 有序集合:元素按插入顺序存储,可通过索引精确访问

  • 元素可重复:允许存储相同元素(包括null)

  • 位置访问:提供基于索引的增删改查方法

特有方法:

// 位置访问
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);// 搜索
int indexOf(Object o);
int lastIndexOf(Object o);// 范围操作
List<E> subList(int fromIndex, int toIndex);// Java 8新增
default void replaceAll(UnaryOperator<E> operator);
default void sort(Comparator<? super E> c);

2. 实现类对比

对比维度ArrayListLinkedListVector
底层数据结构动态数组双向链表动态数组
内存布局连续内存空间离散节点存储连续内存空间
初始容量10 (首次添加时初始化)无固定容量概念10
扩容机制1.5倍增长 (int newCapacity = oldCapacity + (oldCapacity >> 1))无需扩容,动态增加节点2倍增长 (capacityIncrement>0时按指定值增长)
随机访问性能O(1) - 直接数组索引访问O(n) - 需要遍历链表O(1)
头部插入性能O(n) - 需要移动所有元素O(1) - 修改头节点引用O(n)
尾部插入性能O(1)摊销 (考虑扩容)O(1) - 修改尾节点引用O(1)
中间插入性能O(n) - 平均需要移动一半元素O(n) - 需要先找到位置O(n)
删除操作性能O(n) - 类似插入O(1) - 找到节点后只需修改引用O(n)
内存占用较少 (仅需存储元素和数组引用)较高 (每个元素需要额外前后节点引用)与ArrayList类似
缓存友好性好 (空间局部性原理)
线程安全性非线程安全非线程安全线程安全 (方法级synchronized)
迭代器安全性快速失败 (fail-fast)快速失败线程安全但迭代时仍需外部同步
序列化支持自定义序列化 (transient数组+size)自定义序列化同ArrayList
最佳适用场景读多写少,随机访问频繁写多读少,频繁在头尾操作需要线程安全的场景 (已过时)

 3. ArrayList 示例

// 创建ArrayList
List<String> arrayList = new ArrayList<>();// 添加元素
arrayList.add("Java");
arrayList.add("Python");
arrayList.add(1, "C++"); // 在指定位置插入// 访问元素
String lang = arrayList.get(0); // "Java"// 遍历方式1:for循环
for (int i = 0; i < arrayList.size(); i++) {System.out.println(arrayList.get(i));
}// 遍历方式2:增强for循环
for (String language : arrayList) {System.out.println(language);
}// 遍历方式3:迭代器
Iterator<String> it = arrayList.iterator();
while (it.hasNext()) {System.out.println(it.next());
}// 删除元素
arrayList.remove("Python"); // 按对象删除
arrayList.remove(0);       // 按索引删除// 转换为数组
String[] array = arrayList.toArray(new String[0]);// Java 8操作
arrayList.removeIf(s -> s.length() < 3); // 删除长度小于3的元素
arrayList.replaceAll(String::toUpperCase); // 全部转为大写

ArrayList常用的方法都在这里了。我们可以把ArrayList就看成一个动态数组,实际上ArrayList比较适合查询数组内地各个元素,但在增删改上地性能较差。

4. LinkedList 示例

// 创建LinkedList
LinkedList<String> linkedList = new LinkedList<>();// 添加元素
linkedList.add("Apple");
linkedList.addFirst("Banana"); // 添加到头部
linkedList.addLast("Orange"); // 添加到尾部
linkedList.add(1, "Grape");   // 在指定位置插入// 队列操作
linkedList.offer("Pear");     // 添加到队尾
String head = linkedList.poll(); // 移除并返回队头// 栈操作
linkedList.push("Cherry");    // 压栈
String top = linkedList.pop(); // 弹栈// 获取元素
String first = linkedList.getFirst();
String last = linkedList.getLast();// 遍历方式:降序迭代器
Iterator<String> descIt = linkedList.descendingIterator();
while (descIt.hasNext()) {System.out.println(descIt.next());
}

这里刻意强调一下栈操作。LinkedList 实现了 Deque(双端队列)接口,因此可以作为栈(Stack)使用。栈是一种后进先出(LIFO)的数据结构,实际上就是数据接口的知识。

// 将元素推入栈顶(实际添加到链表头部)入栈
LinkedList<String> stack = new LinkedList<>();
stack.push("A");  // 栈底 ← "A" → 栈顶
stack.push("B");  // 栈底 ← "A" ← "B" → 栈顶
stack.push("C");  // 栈底 ← "A" ← "B" ← "C" → 栈顶String top = stack.pop();  // 移除并返回栈顶元素 "C" 出栈
// 现在栈状态:栈底 ← "A" ← "B" → 栈顶String peek = stack.peek(); // 返回 "B"(栈顶元素)
// 栈保持不变:栈底 ← "A" ← "B" → 栈顶
4.2.1.3 Set 接口详解

1. 核心特性:

  • 元素唯一性:不包含重复元素(依据equals()判断)

  • 无序性:不保证维护插入顺序(TreeSet/LinkedHashSet除外)

  • 数学集合:支持并集、交集、差集等操作

2. 实现类对比

对比维度HashSetLinkedHashSetTreeSet
底层实现基于HashMap继承HashSet,使用LinkedHashMap基于TreeMap
数据结构哈希表+链表/红黑树哈希表+链表+双向链表红黑树
元素顺序无序插入顺序自然顺序/Comparator定义顺序
null值支持允许一个null元素允许一个null元素不允许null元素
基本操作复杂度平均O(1)平均O(1)O(log n)
内存开销较低较高 (额外维护双向链表)较高 (树结构开销)
构造方法可指定初始容量和负载因子同HashSet可提供Comparator
迭代顺序不稳定插入顺序稳定排序顺序稳定
性能特点插入删除极快插入删除稍慢于HashSet插入删除较慢但有序
额外方法提供first(), last(), subSet()等导航方法
线程安全性非线程安全非线程安全非线程安全
哈希冲突解决链地址法,JDK8后链表转红黑树同HashSet不适用
扩容机制默认16→32→64... 负载因子0.75同HashSet无需扩容
比较方式equals()和hashCode()同HashSetComparable或Comparator
典型应用场景需要快速判断元素是否存在需要保持插入顺序的集合需要有序集合或范围查询

3.  HashSet 示例

// 创建HashSet
Set<String> hashSet = new HashSet<>();// 添加元素
hashSet.add("Java");
hashSet.add("Python");
hashSet.add("Java"); // 重复元素不会被添加// 判断包含
boolean hasJava = hashSet.contains("Java"); // true// 删除元素
hashSet.remove("Python");// 遍历
for (String language : hashSet) {System.out.println(language);
}// 集合运算
Set<String> otherSet = new HashSet<>(Arrays.asList("C++", "Java", "JavaScript"));hashSet.retainAll(otherSet); // 交集
hashSet.addAll(otherSet);    // 并集
hashSet.removeAll(otherSet); // 差集

4. LinkedHashSet示例

// 创建LinkedHashSet(保持插入顺序)
Set<String> linkedHashSet = new LinkedHashSet<>();linkedHashSet.add("First");
linkedHashSet.add("Second");
linkedHashSet.add("Third");// 遍历顺序与插入顺序一致
for (String item : linkedHashSet) {System.out.println(item); // 输出顺序:First, Second, Third
}// 移除并添加,顺序会变
linkedHashSet.remove("Second");
linkedHashSet.add("Second");// 现在顺序:First, Third, Second

LinkedHashSet能够保持插入顺序,即删除时后面元素会自动补位,增添元素时会自动退位;但HashSet不会,不管组内元素如何变化,其他元素均不变。

5. TreeSet示例

// 创建TreeSet(自然排序)
Set<String> treeSet = new TreeSet<>();treeSet.add("Orange");
treeSet.add("Apple");
treeSet.add("Banana");// 自动排序输出
for (String fruit : treeSet) {System.out.println(fruit); // Apple, Banana, Orange
}// 定制排序
Set<Integer> customSort = new TreeSet<>((a, b) -> b - a); // 降序
customSort.addAll(Arrays.asList(5, 3, 9, 1));// 输出:9, 5, 3, 1// 导航方法
TreeSet<Integer> nums = new TreeSet<>(Arrays.asList(1, 3, 5, 7, 9));Integer lower = nums.lower(5);  // 3 (小于5的最大元素)
Integer higher = nums.higher(5); // 7 (大于5的最小元素)
Integer floor = nums.floor(4);   // 3 (小于等于4的最大元素)
Integer ceiling = nums.ceiling(6); // 7 (大于等于6的最小元素)// 范围视图
Set<Integer> subSet = nums.subSet(3, true, 7, false); // [3, 5]
4.2.1.4 Queue/Deque接口详解

1. Queue核心方法:

操作类型抛出异常的方法返回特殊值的方法
插入add(e)offer(e)
移除remove()poll()
检查element()peek()

 2. 实现类对比

对比维度PriorityQueueArrayDequeLinkedList
底层结构二叉堆(数组实现)循环数组双向链表
排序特性自然顺序/Comparator
容量限制无界(自动扩容)可选有界(默认16)无界
null值允许不允许不允许允许
基本操作复杂度插入O(log n),获取O(1)两端操作O(1)两端操作O(1),中间操作O(n)
线程安全性非线程安全非线程安全非线程安全
内存使用紧凑(数组)非常紧凑较高(节点开销)
扩容策略小规模+50%,大规模+25%双倍增长动态增加节点
迭代顺序按优先级顺序FIFO/LIFO顺序插入顺序
特殊方法comparator()大量列表操作方法
最佳适用场景任务调度,需要自动排序高性能栈/队列实现需要同时作为队列和列表使用
实现接口QueueDequeList, Deque

 3. PriorityQueue示例

// 创建优先级队列(自然排序)
PriorityQueue<Integer> pq = new PriorityQueue<>();pq.add(30);
pq.add(10);
pq.add(20);// 取出时会按顺序
while (!pq.isEmpty()) {System.out.println(pq.poll()); // 10, 20, 30
}// 定制排序
PriorityQueue<String> customPq = new PriorityQueue<>((s1, s2) -> s2.length() - s1.length()); // 按长度降序customPq.add("Apple");
customPq.add("Banana");
customPq.add("Pear");// 输出:Banana, Apple, Pear

2. ArrayDeque示例

// 创建ArrayDeque
Deque<String> deque = new ArrayDeque<>();// 作为栈使用
deque.push("First");
deque.push("Second");
String top = deque.pop(); // "Second"// 作为队列使用
deque.offer("Third");
deque.offer("Fourth");
String head = deque.poll(); // "First"// 双端操作
deque.addFirst("Front");
deque.addLast("End");
String first = deque.getFirst(); // "Front"
String last = deque.getLast();   // "End"

4.2.2 Map 接口体系详解

1. 核心定义

public interface Map<K,V> {// 基本操作int size();boolean isEmpty();boolean containsKey(Object key);boolean containsValue(Object value);V get(Object key);V put(K key, V value);V remove(Object key);// 批量操作void putAll(Map<? extends K, ? extends V> m);void clear();// 集合视图Set<K> keySet();Collection<V> values();Set<Map.Entry<K, V>> entrySet();// 内部Entry接口interface Entry<K,V> {K getKey();V getValue();V setValue(V value);// Java 8新增boolean equals(Object o);int hashCode();public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey()// ...}// Java 8新增方法default V getOrDefault(Object key, V defaultValue)default void forEach(BiConsumer<? super K, ? super V> action)default V putIfAbsent(K key, V value)default boolean remove(Object key, Object value)default boolean replace(K key, V oldValue, V newValue)default V replace(K key, V value)default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)// ...
}

这里是Java的源码,可以看到Map实际上放的是一对K-V键值对。

2. 实现类对比

对比维度HashMapLinkedHashMapTreeMap
继承体系AbstractMap继承HashMapAbstractMap
底层结构数组+链表/红黑树数组+链表/红黑树+双向链表红黑树
键值顺序无序插入顺序/访问顺序键的自然顺序/Comparator顺序
null键值支持允许null键和null值同HashMap不允许null键
初始容量16同HashMap无容量概念
扩容机制2^n增长,负载因子0.75同HashMap无需扩容
基本操作复杂度平均O(1)平均O(1)O(log n)
线程安全性非线程安全非线程安全非线程安全
迭代器类型fail-fastfail-fastfail-fast
额外功能可设置访问顺序(LRU实现)导航方法(如ceilingKey)
哈希算法(h = key.hashCode()) ^ (h >>> 16)同HashMap不适用
树化阈值链表长度≥8且桶数量≥64同HashMap不适用
序列化方式自定义同HashMap同HashMap
推荐场景大多数键值对存储场景需要保持插入/访问顺序需要有序映射或范围查询

3. HashMap示例

// 创建HashMap
Map<String, Integer> hashMap = new HashMap<>();// 添加键值对
hashMap.put("Apple", 10);
hashMap.put("Banana", 20);
hashMap.put("Orange", 15);// 获取值
int apples = hashMap.get("Apple"); // 10
int defaultValue = hashMap.getOrDefault("Pear", 0); // 0// 遍历方式1:entrySet
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());
}// 遍历方式2:keySet
for (String key : hashMap.keySet()) {System.out.println(key);
}// 遍历方式3:values
for (int value : hashMap.values()) {System.out.println(value);
}// Java 8操作
hashMap.forEach((k, v) -> System.out.println(k + " => " + v));
hashMap.computeIfAbsent("Pear", k -> 5); // 如果不存在则添加
hashMap.merge("Apple", 5, Integer::sum); // Apple数量增加5

4. LinkedHashMap示例

// 创建LinkedHashMap(保持插入顺序)
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();linkedHashMap.put("First", 1);
linkedHashMap.put("Second", 2);
linkedHashMap.put("Third", 3);// 遍历顺序与插入顺序一致
linkedHashMap.forEach((k, v) -> System.out.println(k)); // First, Second, Third// 按访问顺序排序的LinkedHashMap(可用于LRU缓存)
Map<String, Integer> accessOrderMap = new LinkedHashMap<>(16, 0.75f, true);accessOrderMap.put("One", 1);
accessOrderMap.put("Two", 2);
accessOrderMap.put("Three", 3);accessOrderMap.get("Two"); // 访问Two会使它移动到末尾// 现在顺序:One, Three, Two

5. TreeMap示例

// 创建TreeMap(按键自然排序)
Map<String, Integer> treeMap = new TreeMap<>();treeMap.put("Orange", 5);
treeMap.put("Apple", 10);
treeMap.put("Banana", 8);// 按键排序输出
treeMap.forEach((k, v) -> System.out.println(k)); // Apple, Banana, Orange// 定制排序
Map<String, Integer> reverseMap = new TreeMap<>(Comparator.reverseOrder());
reverseMap.putAll(treeMap);// 输出顺序:Orange, Banana, Apple// 导航方法
TreeMap<Integer, String> employeeMap = new TreeMap<>();
employeeMap.put(1001, "Alice");
employeeMap.put(1002, "Bob");
employeeMap.put(1003, "Charlie");Map.Entry<Integer, String> entry = employeeMap.floorEntry(1002); // 1002=Bob
Integer higherKey = employeeMap.higherKey(1001); // 1002// 范围视图
Map<Integer, String> subMap = employeeMap.subMap(1001, true, 1003, false); // 1001-1002

红黑树特性:

  1. 每个节点是红色或黑色

  2. 根节点是黑色

  3. 所有叶子节点(NIL)是黑色

  4. 红色节点的子节点必须是黑色

  5. 从任一节点到其每个叶子的路径包含相同数目的黑色节点

主要是TreeMap的底层结构就是红黑树,这里建议恶补一下数据结构的知识——红黑树、链表、二叉堆和二叉树等,方便理解。这里放两个链接:

二叉树和堆详解(通俗易懂)_堆和二叉树的区别-CSDN博客

【数据结构】红黑树超详解 ---一篇通关红黑树原理(含源码解析+动态构建红黑树)_红黑树的原理-CSDN博客

 

 4.3 集合类选择

4.3.1 集合类选择指南

  • 需要存储键值对时:

    • 不需要排序:HashMap

    • 需要保持插入/访问顺序:LinkedHashMap

    • 需要按键排序:TreeMap

    • 需要线程安全:ConcurrentHashMap

  • 只需要存储元素时:

    • 允许重复、需要索引:ArrayList/LinkedList

    • 不允许重复、不关心顺序:HashSet

    • 不允许重复、需要保持插入顺序:LinkedHashSet

    • 不允许重复、需要排序:TreeSet

  • 需要队列功能时:

    • 普通队列:ArrayDeque

    • 优先级队列:PriorityQueue

    • 线程安全队列:LinkedBlockingQueue

  • 需要线程安全时:

    • List:CopyOnWriteArrayList

    • Set:CopyOnWriteArraySet

    • Map:ConcurrentHashMap

    • Queue:LinkedBlockingQueue

4.3.2 集合类选择决策树

字有点小,建议点开了以后放大看 !!

决策树文字说明:

  • 第一层决策:存储类型

    • 键值对 → 进入Map分支

    • 单元素 → 进入Collection分支

  • Map分支选择逻辑:

    • 需要排序?→ TreeMap(自然排序)或ConcurrentSkipListMap(线程安全排序)

    • 不需要排序但需要顺序?→ LinkedHashMap(可配置插入顺序或访问顺序)

    • 都不需要 → HashMap(最高性能)或ConcurrentHashMap(线程安全)

  • Collection分支选择逻辑:

    • 允许重复(List/Queue):

      • 需要索引 → ArrayList(随机访问快)或LinkedList(插入删除快)

      • 需要队列 → ArrayDeque(标准队列)或PriorityQueue(优先级队列)

      • 线程安全 → CopyOnWriteArrayListBlockingQueue实现类

    • 不允许重复(Set):

      • 需要排序 → TreeSetConcurrentSkipListSet

      • 需要插入顺序 → LinkedHashSet

      • 只需要去重 → HashSet

4.4 性能优化建议

  1. 合理设置初始容量:对于ArrayList、HashMap等基于数组的集合,预先设置合理的初始容量可以减少扩容带来的性能损耗。

  2. 选择合适的负载因子:HashMap的负载因子(默认0.75)决定了哈希表在多少满时扩容。更高的值节省内存但增加哈希冲突。

  3. 实现高质量的hashCode():对于作为HashMap键或HashSet元素的类,要确保hashCode()方法能产生均匀分布的哈希值。

  4. 考虑使用视图:keySet()、values()等方法返回的是视图而非新集合,可以节省内存。

  5. 注意自动装箱开销:对于大量基本类型数据,考虑使用专门的集合库如Trove,避免自动装箱带来的性能损耗。

  6. 谨慎使用同步集合:只有在确实需要线程安全时才使用同步包装器,否则会带来不必要的性能损失。

  7. 利用不可变集合:对于不会修改的集合,使用Collections.unmodifiableXXX()创建不可变视图,既安全又明确表达设计意图。

4.5 总结

我在第一次接触集合类的时候其实有点被搞得眼花缭乱的,因为实现类太多了我也不是特别能分得清各个核心类之间的区别;后来代码量逐渐上来以后才能分辨请他们之间的差异。比较核心底层的东西还是得看源码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/92943.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/92943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GaussDB 数据库架构师(八) 等待事件(1)-概述

1、等待事件概述 等待事件&#xff1a;指当数据库会话(session)因资源竞争或依赖无法继续执行时&#xff0c;进入"等待"状态&#xff0c;此时产生的性能事件即等待事件。 2、等待事件本质 性能瓶颈的信号灯&#xff0c;反映CPU,I/O、锁、网络等关键资源的阻塞情况。…

五分钟系列-文本搜索工具grep

目录 1️⃣核心功能​​ ​​2️⃣基本语法​​ 3️⃣​​常用选项 & 功能详解​​ ​​4️⃣经典应用场景 & 示例​​ 5️⃣​​重要的提示 & 技巧​​ ​​6️⃣总结​​ grep 是 Linux/Unix 系统中功能强大的​​文本搜索工具​​&#xff0c;其名称源自 …

Java面试题及详细答案120道之(041-060)

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

【尝试】本地部署openai-whisper,通过 http请求识别

安装whisper的教程&#xff0c;已在 https://blog.csdn.net/qq_23938507/article/details/149394418 和 https://blog.csdn.net/qq_23938507/article/details/149326290 中说明。 1、创建whisperDemo1.py from fastapi import FastAPI, UploadFile, File import whisper i…

Visual Studio 的常用快捷键

Visual Studio 作为主流的开发工具&#xff0c;提供了大量快捷键提升编码效率。以下按功能分类整理常用快捷键&#xff0c;涵盖基础操作、代码编辑、调试等场景&#xff08;以 Visual Studio 2022 为例&#xff0c;部分快捷键可在「工具 > 选项 > 环境 > 键盘」中自定…

Triton Server部署Embedding模型

在32核CPU、无GPU的服务器上&#xff0c;使用Python后端和ONNX后端部署嵌入模型&#xff0c;并实现并行调用和性能优化策略。方案一&#xff1a;使用Python后端部署Embedding模型 Python后端提供了极大的灵活性&#xff0c;可以直接在Triton中运行您熟悉的sentence-transformer…

Java动态调试技术原理

本文转载自 美团技术团队胡健的Java 动态调试技术原理及实践, 通过学习java agent方式进行动态调试了解目前很多大厂开源的一些基于此的调试工具。 简介 断点调试是我们最常使用的调试手段&#xff0c;它可以获取到方法执行过程中的变量信息&#xff0c;并可以观察到方法的执…

人工智能-python-OpenCV 图像基础认知与运用

文章目录OpenCV 图像基础认知与运用1. OpenCV 简介与安装OpenCV 的优势安装 OpenCV2. 图像的基本概念2.1. 图像的存储格式2.2. 图像的表示3. 图像的基本操作3.1. 创建图像窗口3.2. 读取与显示图像3.3. 保存图像3.4. 图像切片与区域提取3.5. 图像大小调整4. 图像绘制与注释4.1. …

Windows电脑添加、修改打印机的IP地址端口的方法

本文介绍在Windows电脑中&#xff0c;为打印机添加、修改IP地址&#xff0c;从而解决电脑能找到打印机、但是无法打印问题的方法。最近&#xff0c;办公室的打印机出现问题——虽然在电脑的打印机列表能找到这个打印机&#xff0c;但是选择打印时&#xff0c;就会显示文档被挂起…

告别复杂配置!Spring Boot优雅集成百度OCR的终极方案

1. 准备工作 1.1 注册百度AI开放平台 访问百度AI开放平台 注册账号并登录 进入控制台 → 文字识别 → 创建应用 记录下API Key和Secret Key 2. 项目配置 2.1 添加依赖 (pom.xml) <dependencies><!-- Spring Boot Web --><dependency><groupId>o…

「iOS」——内存五大分区

UI学习iOS-底层原理 24&#xff1a;内存五大区总览一、栈区&#xff08;Stack&#xff09;1.1 核心特性1.2 优缺点1.3函数栈与栈帧1.3 堆栈溢出风险二、堆区&#xff08;Heap&#xff09;;2.1 核心特性2.2 与栈区对比三、全局 / 静态区&#xff08;Global/Static&#xff09;3.…

每日一题【删除有序数组中的重复项 II】

删除有序数组中的重复项 II思路class Solution { public:int removeDuplicates(vector<int>& nums) {if(nums.size()<2){return nums.size();}int index 2;for (int i 2; i < nums.size();i ) {if(nums[i] ! nums[index-2]) {nums[index]nums[i];}}return ind…

兼容性问题记录

1、dialog设置高度MATCH_PARENT全屏后&#xff0c;三星机型和好像是一加&#xff0c;会带出顶部状态栏&#xff0c;设置隐藏状态栏属性无效。解决方法&#xff1a;高度不设置为MATCH_PARENT&#xff0c;通过windowmanager.getdefaultdisplay来获取并设置高度&#xff0c;再设置…

6.数组和字符串

在C语言中&#xff0c;数组和字符串是基础且重要的概念。它们用于存储和操作一系列相同类型的元素或字符序列。数组1. 数组定义与初始化数组是一系列相同类型的数据项的集合&#xff0c;这些数据项可以通过一个共同的名字来引用。数组中的每个元素都有一个索引&#xff08;也称…

odoo代码分析(一)

Odoo 是一套基于网络的开放式源代码商业应用套件,既可以作为独立应用运行,也可以作为集成的全功能 ERP 系统使用。Odoo 平台采用模块化架构,允许组织根据自身需求起步,并在需求增长时扩展功能。 什么是 Odoo? Odoo 提供了一个完整的商业应用生态系统,包括: 客户关系管…

从“人工眼”到‘智能眼’:EZ-Vision视觉系统如何重构生产线视觉检测精度?

制造业是我国实体经济的基础&#xff0c;是国内经济增长的重要引擎。制造业智能化建设是当下的必然趋势&#xff0c;然而目前依旧有很多中小型企业因为成本原因&#xff0c;无法加快智能化制造的步伐。在智能检测领域更是如此&#xff0c;很多企业依旧在采用人工检测&#xff0…

Etcd原理基础学习

etcd 是一个开源的分布式键值存储系统&#xff0c;专注于提供高可用性、强一致性的数据存储与访问&#xff0c;广泛应用于分布式系统的服务发现、配置管理和协调任务。以下是其核心特性和应用场景的详细介绍。接下来就看看Etcd如何实现服务注册&#xff0c;以及如何通过Raft算法…

【硬件-笔试面试题】硬件/电子工程师,笔试面试题-32,(知识点:模数转换器,信噪比,计算公式,)

目录 1、题目 2、解答 步骤一&#xff1a;明确理想 ADC 的信噪比公式 步骤二&#xff1a;推导公式的来源 步骤三&#xff1a;得出答案 3、相关知识点 一、信噪比&#xff08;SNR&#xff09;的定义 二、理想 ADC 的量化噪声 三、满量程正弦波信号的功率 四、信噪比公…

Redis过期数据的删除策略是什么?有哪些?

定时删除&#xff1a;- 每个设置了TTL的key中都会创建一个计时器&#xff0c;等到过期时间就会立即删除- 对内存友好&#xff0c;但是会占用大量的CPU资源去处理过期数据&#xff0c;从而影响缓存的吞吐量和响应时间惰性删除&#xff1a;- 设置了key的过期后&#xff0c;不会立…

linux dd命令详解

dd 是一个功能强大的 Unix/Linux 命令行工具&#xff0c;用于低级别的字节流操作&#xff0c;常用于创建、复制、转换和处理文件或设备数据。它在 macOS 和 Linux 系统上都可用&#xff0c;但在 macOS 上有一些细微差异。本文将详细讲解 dd 命令的用法&#xff0c;包括参数、常…