JavaSE 集合从入门到面试:全面解析与实战指南

JavaSE 集合从入门到面试:全面解析与实战指南

在 Java 编程中,集合是处理数据的核心工具,几乎所有 Java 应用都会用到集合框架。从简单的列表存储到复杂的数据分析,集合框架提供了丰富的数据结构和操作方法。本文将从基础概念到面试考点,全方位剖析 JavaSE 集合框架,帮助你构建完整的知识体系。

一、集合框架概述:为什么需要集合?

在 Java 中,数组是最基本的数据存储结构,但数组存在明显局限性:长度固定、只能存储同类型元素、缺乏常用操作方法(如添加、删除、查找)。集合框架的出现正是为了弥补这些不足,它提供了一系列灵活的数据结构,能够动态存储不同类型的元素,并内置了丰富的操作方法。

Java 集合框架(Java Collections Framework)位于 java.util 包下,主要包含三大块:接口(如 CollectionMap)、实现类(如 ArrayListHashMap)、工具类(如 Collections)。其核心思想是面向接口编程,通过接口定义规范,不同的实现类提供不同的功能,满足多样化的业务需求。

二、集合框架整体结构:一张图看懂核心体系

集合框架的核心接口可以分为两大分支:CollectionMap,它们分别代表不同的数据结构:

java.util
├─ Collection(单值集合,存储单个元素)
│  ├─ List(有序、可重复)
│  │  ├─ ArrayList(动态数组实现)
│  │  ├─ LinkedList(双向链表实现)
│  │  └─ Vector(线程安全的动态数组,古老类)
│  │     └─ Stack(栈,继承自Vector)
│  │
│  ├─ Set(无序、不可重复)
│  │  ├─ HashSet(哈希表实现)
│  │  │  └─ LinkedHashSet(有序的HashSet,维护插入顺序)
│  │  └─ TreeSet(红黑树实现,元素可排序)
│  │
│  └─ Queue(队列,先进先出)
│     ├─ LinkedList(双向链表实现,可作队列/双端队列)
│     └─ PriorityQueue(优先级队列,基于堆实现)
│
└─ Map(键值对集合,存储键值映射)├─ HashMap(哈希表实现)│  └─ LinkedHashMap(有序的HashMap,维护插入顺序)├─ TreeMap(红黑树实现,键可排序)└─ Hashtable(线程安全的哈希表,古老类)

核心接口的区别与联系

  • Collection:存储单个元素的集合,元素可以重复(List)或不可重复(Set),元素可以有序(List、LinkedHashSet)或无序(HashSet)。
  • Map:存储键值对(key-value)的集合,键(key)不可重复,值(value)可以重复。Map 与 Collection 的主要区别是存储方式不同,Map 通过键快速查找值,而 Collection 直接存储元素。

三、List 接口:有序可重复的动态数组

List 接口继承自 Collection,是最常用的集合类型之一,其核心特点是元素有序(插入顺序与存储顺序一致)、可重复,并允许通过索引访问元素。

1. ArrayList:数组的动态实现

ArrayList 是 List 接口的主要实现类,底层基于动态数组实现,能够根据元素数量自动扩容。

核心特点
  • 查询快:通过索引直接访问元素,时间复杂度为 O(1)。
  • 增删慢:在中间位置添加或删除元素时,需要移动后续元素,时间复杂度为 O(n)。
  • 线程不安全:多线程环境下可能出现并发问题,如需线程安全可使用 Collections.synchronizedList()CopyOnWriteArrayList
底层原理:动态扩容机制

ArrayList 的初始容量为 10(JDK 8 及以上),当元素数量超过当前容量时,会触发扩容:

  1. 计算新容量:新容量 = 旧容量 + 旧容量 / 2(即扩容 1.5 倍)。
  2. 创建新数组,将旧数组元素复制到新数组。
  3. 替换引用,旧数组被垃圾回收。

注意:频繁扩容会影响性能,因此在已知元素数量的情况下,建议初始化时指定容量(如 new ArrayList<>(100))。

常用操作示例
List<String> list = new ArrayList<>();
// 添加元素
list.add("Java");
list.add("Python");
// 插入元素到指定位置
list.add(1, "C++");
// 获取元素
String element = list.get(0);
// 修改元素
list.set(2, "JavaScript");
// 删除元素
list.remove(1);
// 遍历元素
for (String s : list) {System.out.println(s);
}

2. LinkedList:双向链表的灵活实现

LinkedList 底层基于双向链表实现,每个节点包含前驱指针(prev)、数据(data)和后继指针(next)。

核心特点
  • 增删快:在链表头部或尾部添加/删除元素时,时间复杂度为 O(1);在中间位置操作时,需先查找位置,时间复杂度为 O(n)。
  • 查询慢:访问指定索引的元素时,需要从头或尾遍历,时间复杂度为 O(n)。
  • 功能丰富:实现了 Deque 接口,可作为队列(Queue)、双端队列(Deque)或栈(Stack)使用。
作为队列和栈的使用示例
// 作为队列(先进先出)
Queue<String> queue = new LinkedList<>();
queue.offer("A"); // 添加元素到队尾
queue.offer("B");
String head = queue.poll(); // 移除并返回队头元素// 作为栈(后进先出)
Deque<String> stack = new LinkedList<>();
stack.push("X"); // 添加元素到栈顶
stack.push("Y");
String top = stack.pop(); // 移除并返回栈顶元素

3. ArrayList 与 LinkedList 的选择

  • 频繁查询、少增删:选 ArrayList
  • 频繁增删(尤其是头部/尾部)、少查询:选 LinkedList
  • 大多数业务场景中,ArrayList 的性能更优,是首选。

四、Set 接口:无序不可重复的集合

Set 接口继承自 Collection,其核心特点是元素不可重复(通过 equals()hashCode() 判断)、无序(存储顺序与插入顺序无关,LinkedHashSet 除外)。

1. HashSet:哈希表的高效实现

HashSet 是 Set 接口的主要实现类,底层基于哈希表(HashMap)实现,通过哈希值快速定位元素。

核心特点
  • 无序性:元素存储顺序与插入顺序无关。
  • 唯一性:通过 hashCode()equals() 保证元素不重复。
  • 高效性:添加、删除、查找元素的平均时间复杂度为 O(1)。
  • 线程不安全:多线程环境下需额外处理线程安全问题。
去重原理:hashCode() 与 equals() 的协作

HashSet 判断元素是否重复的规则:

  1. 先比较两个元素的 hashCode() 值,若不同,则认为是不同元素。
  2. hashCode() 值相同,再调用 equals() 方法,若返回 true,则认为是相同元素(不添加);若返回 false,则认为是不同元素(发生哈希冲突,通过链表或红黑树存储)。

重写规范

  • 若两个对象 equals() 返回 true,则 hashCode() 必须相等。
  • 若两个对象 hashCode() 不等,则 equals() 一定返回 false
示例:自定义对象去重
class Student {private String id;private String name;// 构造方法、getter、setter省略@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return Objects.equals(id, student.id); // 按id去重}@Overridepublic int hashCode() {return Objects.hash(id); // 基于id计算哈希值}
}// 使用HashSet存储Student
Set<Student> students = new HashSet<>();
students.add(new Student("1", "张三"));
students.add(new Student("1", "张三")); // 重复,不会被添加

2. LinkedHashSet:有序的 HashSet

LinkedHashSet 继承自 HashSet,底层通过哈希表 + 双向链表实现,既保证了元素的唯一性,又维护了元素的插入顺序。

其性能略低于 HashSet(因需维护链表),但在需要有序性的场景下非常实用。

3. TreeSet:可排序的 Set

TreeSet 底层基于红黑树(一种自平衡二叉查找树)实现,能够对元素进行自然排序或自定义排序。

排序方式
  • 自然排序:元素类实现 Comparable 接口,重写 compareTo() 方法。
  • 自定义排序:创建 TreeSet 时传入 Comparator 对象,定义排序规则。
示例:自定义排序
// 自然排序:Student实现Comparable
class Student implements Comparable<Student> {private String id;private int age;@Overridepublic int compareTo(Student o) {return this.age - o.age; // 按年龄升序排序}
}// 自定义排序:按id长度降序
Set<Student> treeSet = new TreeSet<>((s1, s2) -> s2.getId().length() - s1.getId().length()
);

五、Map 接口:键值对的映射关系

Map 接口用于存储键值对(key-value),其中键(key)不可重复,值(value)可以重复,键和值都可以为 null(HashMap 允许,Hashtable 不允许)。

1. HashMap:哈希表的键值实现

HashMap 是 Map 接口的主要实现类,底层基于哈希表(数组 + 链表 / 红黑树)实现,通过键的哈希值快速定位值。

JDK 8 中 HashMap 的结构
  • 底层是数组(称为 “桶”),每个桶中存储链表或红黑树。
  • 当链表长度超过 8 且数组容量≥64 时,链表会转换为红黑树(提高查询效率)。
  • 当红黑树节点数少于 6 时,会转回链表。
核心特点
  • 无序性:键值对的存储顺序与插入顺序无关。
  • 高效性:添加、删除、查找的平均时间复杂度为 O(1)。
  • 线程不安全:多线程环境下可能出现 ConcurrentModificationException,需使用 ConcurrentHashMap
扩容机制

HashMap 的初始容量为 16,负载因子为 0.75(当元素数量超过容量 × 负载因子时触发扩容)。扩容时,新容量为旧容量的 2 倍,并重新计算所有键的哈希值,将元素转移到新数组中。

常用操作示例
Map<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("Java", 100);
map.put("Python", 90);
// 获取值
int javaScore = map.get("Java");
// 判断键是否存在
boolean hasPython = map.containsKey("Python");
// 遍历键值对
for (Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 遍历键
for (String key : map.keySet()) {System.out.println(key);
}
// 遍历值
for (int value : map.values()) {System.out.println(value);
}

2. LinkedHashMap:有序的 HashMap

LinkedHashMap 继承自 HashMap,底层通过哈希表 + 双向链表实现,在 HashMap 的基础上维护了键值对的插入顺序或访问顺序。

  • 插入顺序:默认模式,按键值对的插入顺序排序。
  • 访问顺序:调用 get() 方法访问元素后,该元素会被移到链表尾部,适用于实现 LRU(最近最少使用)缓存。
示例:LRU 缓存实现
// 最大容量为3,按访问顺序排序
Map<String, String> lruCache = new LinkedHashMap<>(3, 0.75f, true) {@Overrideprotected boolean removeEldestEntry(Map.Entry<String, String> eldest) {// 当元素数量超过3时,移除最久未访问的元素return size() > 3;}
};

3. TreeMap:可排序的 Map

TreeMap 底层基于红黑树实现,能够根据键对键值对进行自然排序或自定义排序,与 TreeSet 类似。

其键必须实现 Comparable 接口或通过 Comparator 指定排序规则,适合需要对键进行排序的场景。

4. HashMap 与 Hashtable 的区别

特性HashMapHashtable
线程安全不安全安全(方法加 synchronized)
效率
允许 null 键/值允许(键只能有一个 null)不允许
初始容量16,扩容为 2 倍11,扩容为 2n+1
父类AbstractMapDictionary(古老类)

六、集合工具类:Collections 与 Arrays

1. Collections:集合操作工具类

Collections 提供了大量静态方法,用于操作 Collection 和 Map,常用方法包括:

  • 排序sort(list)sort(list, comparator)
  • 查找binarySearch(list, key)(二分查找,需先排序)
  • 同步化synchronizedList(list)synchronizedMap(map)(将非线程安全集合转为线程安全)
  • 不可变集合unmodifiableList(list)unmodifiableMap(map)(返回只读视图)
  • 其他reverse(list)(反转)、shuffle(list)(随机打乱)
示例:创建不可变集合
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
// 返回不可变视图,修改会抛出UnsupportedOperationException
List<String> unmodifiableList = Collections.unmodifiableList(list);

2. Arrays:数组操作工具类

Arrays 提供了数组操作的静态方法,常用方法包括:

  • 排序sort(array)
  • 转换为集合asList(array)(返回固定大小的 List,不能添加/删除元素)
  • 填充fill(array, value)
  • 比较equals(array1, array2)
  • 二分查找binarySearch(array, key)
示例:数组与集合的转换
String[] array = {"a", "b", "c"};
// 数组转集合(返回的是Arrays.ArrayList,不是java.util.ArrayList)
List<String> list = Arrays.asList(array);
// 如需操作集合,需转为ArrayList
List<String> arrayList = new ArrayList<>(Arrays.asList(array));

七、面试高频考点解析

1. 集合框架常见面试题

Q1:ArrayList 与 Vector 的区别?

A:两者都基于动态数组实现,主要区别在于:

  • Vector 是线程安全的(方法加 synchronized),ArrayList 线程不安全。
  • Vector 初始容量为 10,扩容时默认翻倍;ArrayList 初始容量为 10,扩容为 1.5 倍。
  • Vector 是古老类(JDK 1.0),ArrayList(JDK 1.2)是其替代者,性能更优。

Q2:HashMap 的底层实现原理(JDK 7 vs JDK 8)?

A:JDK 7 中 HashMap 由数组 + 链表实现;JDK 8 中引入红黑树优化,当链表长度超过 8 且数组容量≥64 时,链表转为红黑树,提高查询效率(从 O(n) 优化为 O(log n))。

Q3:ConcurrentHashMap 与 Hashtable 的线程安全实现方式有何不同?

A:Hashtable 通过在方法上添加 synchronized 关键字实现线程安全,每次操作都锁定整个对象,并发效率低;ConcurrentHashMap 在 JDK 7 中通过分段锁(Segment) 实现,将哈希表分为多个段,每个段独立加锁,支持多线程同时操作不同段;JDK 8 中摒弃分段锁,采用 CAS + synchronized 实现,对链表头部或红黑树的根节点加锁,并发效率更高。

Q4:Iterator 的 fail-fast 机制是什么?

A:fail-fast(快速失败)是 Iterator 的一种错误检测机制,当集合在迭代过程中被修改(如添加、删除元素),会抛出 ConcurrentModificationException。其原理是集合内部维护一个 modCount 变量,记录修改次数,迭代器初始化时复制该值到 expectedModCount,每次迭代都检查两者是否相等,不等则抛出异常。

注意:通过迭代器的 remove() 方法修改集合不会触发 fail-fast。

Q5:List 的 subList() 方法返回的是什么?

AsubList() 返回原集合的视图(不是新集合),对 subList 的修改会影响原集合,反之亦然。subList 依赖原集合存在,若原集合被修改(如 add、clear),subList 的操作会抛出 ConcurrentModificationException

2. 集合设计思想与源码分析

为什么 Collection 和 Map 是顶层接口而非类?

Java 集合框架采用接口 + 实现的设计模式,接口定义规范,实现类提供具体实现。不同数据结构(如数组、链表、哈希表)的操作方式不同,用接口可以统一 API,方便开发者切换实现类(如从 ArrayList 改为 LinkedList 只需修改初始化代码)。

HashMap 的哈希函数如何设计?

JDK 8 中 HashMap 的哈希函数为:(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)。通过将哈希值的高 16 位与低 16 位异或,混合哈希值的高位和低位,减少哈希冲突(尤其在数组容量较小时)。

八、集合性能优化策略

1. 初始化时指定容量

对于 ArrayList、HashMap 等集合,初始化时根据预期元素数量指定容量,减少扩容次数。例如:

// 已知需要存储1000个元素
List<String> list = new ArrayList<>(1000);
Map<String, Integer> map = new HashMap<>(2000); // HashMap容量需为2的幂,2000接近2048

2. 选择合适的集合类型

  • 频繁包含/排除操作:用 HashSet(contains 方法 O(1)),避免用 ArrayList(contains 方法 O(n))。
  • 存储键值对且需要排序:用 TreeMap,无需排序用 HashMap。
  • 多线程读多写少:用 CopyOnWriteArrayList(读不加锁,写时复制)。

3. 避免自动装箱拆箱

优先使用基本类型数组或泛型指定基本类型包装类,避免频繁自动装箱拆箱(如 ArrayList<Integer>add(int) 会自动装箱为 Integer)。

4. 合理使用不可变集合

对于不需要修改的集合,使用 Collections.unmodifiableXXX() 或 JDK 9 的 List.of()Map.of() 创建不可变集合,提高安全性和性能(不可变集合无需考虑并发修改)。

九、总结:集合框架的学习路径

掌握 Java 集合框架需要经历三个阶段:

  1. 入门阶段:熟悉常用集合(ArrayList、HashMap、HashSet)的基本用法,能根据场景选择合适的集合。
  2. 进阶阶段:理解底层数据结构(数组、链表、哈希表、红黑树),掌握扩容机制、哈希冲突解决等原理。
  3. 深入阶段:阅读源码(如 HashMap 的 put 方法、ArrayList 的 grow 方法),理解设计思想(如接口隔离、开闭原则),能分析性能瓶颈并优化。

集合框架是 Java 开发的基石,无论是日常开发还是面试,都占据重要地位。学习时应结合理论与实践,通过源码分析加深理解,通过性能测试验证选择,让集合成为提升代码效率的利器而非瓶颈。

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

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

相关文章

自建云音乐服务器:Navidrome+cpolar让无损音乐随身听

文章目录前言1. 安装Docker2. 创建并启动Navidrome容器3. 公网远程访问本地Navidrome3.1 内网穿透工具安装3.2 创建远程连接公网地址3.3 使用固定公网地址远程访问前言 “想听自己的无损音乐还要开会员&#xff1f;”——音乐发烧友小王的烦恼。商业音乐平台音质压缩&#xff…

C3P0连接池适配HGDB

文章目录文档用途详细信息文档用途 讲解常用的并且需要与数据库进行交互的开源框架C3P0&#xff0c;以及C3P0框架是如何适配HGDB的。 详细信息 1.C3P0概述 C3P0是一个开源的JDBC连接池&#xff0c;它实现了数据源和JNDI绑定&#xff0c;支持JDBC3规范和JDBC2的标准扩展。目…

ZeroGPU Spaces 加速实践:PyTorch 提前编译全解析

ZeroGPU 让任何人都能在 Hugging Face Spaces 中使用强大的 Nvidia H200 硬件&#xff0c;而不需要因为空闲流量而长期占用 GPU。 它高效、灵活&#xff0c;非常适合演示&#xff0c;不过需要注意的是&#xff0c;ZeroGPU 并不能在所有场景下完全发挥 GPU 与 CUDA 栈的全部潜能…

8.ImGui-输入框

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;7.ImGui-单选框和复选框 单行输入框使用 ImGui::InputText()&#xff0c;下图中…

2025年- H120-Lc28. 找出字符串中第一个匹配项的下标(数组)--Java版

1.题目2.思路 短的子串相对不变 所以我们用长的字符串去截取in个长度的子串做遍历 如果两者相等 返回字符串第一个匹配项的索引的下标 3.代码实现 class Solution {public int strStr(String haystack, String needle) {int s1haystack.length();int s2needle.length();//遍历最…

uport1100系列转接头,SZ系列光电编码器RS485通信

安装uport1100系列转接头驱动 &#xff1a;选择对应自己系统内核版本的驱动。否则爆出系统内核过高过低等问题。 查看系统内核版本指令&#xff1a; uname -r #简要 uname -a #详细驱动下载官网&#xff1a; https://www.moxa.com.cn/support/product-support/software-and-…

Java全栈开发面试实战:从基础到微服务架构

Java全栈开发面试实战&#xff1a;从基础到微服务架构 在一次互联网大厂的Java全栈开发岗位面试中&#xff0c;一位名叫李明的28岁程序员&#xff0c;拥有计算机科学与技术本科学历&#xff0c;工作年限为5年。他的主要职责包括设计和实现前后端分离的Web应用、参与微服务架构的…

win10(三)视频剪裁

上传一刻相册&#xff0c;有30M大小限制。这个软件能免费剪裁视频而且支持手机的H.265格式&#xff0c;这个格式目前连potplayer都支持不好。但是配合FFmpeg可以检测并且能按大小&#xff08;或时间&#xff09;剪裁&#xff0c;并上传到一刻相册上播放。 下载FFmpeg的方法&am…

Linux--线程

Linux线程概念 1 什么是线程 • 在⼀个程序⾥的⼀个执⾏路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“⼀个进程内部 的控制序列” • ⼀切进程⾄少都有⼀个执⾏线程 • 线程在进程内部运⾏&#xff0c;本质是在进程地址空间内运⾏ • 在L…

【C++】C++11的包装器:function与bind简介

各位大佬好&#xff0c;我是落羽&#xff01;一个坚持不断学习进步的学生。 如果您觉得我的文章还不错&#xff0c;欢迎多多互三分享交流&#xff0c;一起学习进步&#xff01; 也欢迎关注我的blog主页: 落羽的落羽 文章目录一、function1. 概念2. 用法二、bind1. 概念2. 用法…

MySQL高级特性详解

MySQL高级特性详解 一、自关联查询 概念 自关联查询是指一个表与它自己进行连接的查询。通常用于处理具有层级关系或递归结构的数据。 应用场景 员工与上级关系分类的父子关系地区的层级关系 示例 -- 创建员工表 CREATE TABLE employees (emp_id INT PRIMARY KEY,emp_name VARC…

深度学习——调整学习率

学习率调整方法详解在深度学习训练过程中&#xff0c;学习率&#xff08;Learning Rate, LR&#xff09; 是影响模型收敛速度和效果的关键超参数。学习率过大可能导致训练不稳定、震荡甚至无法收敛&#xff1b;学习率过小又会导致收敛过慢甚至陷入局部最优。因此&#xff0c;如…

Java分页 Element—UI

前端代码 <div class"block"><span class"demonstration">页数较少时的效果</span><el-paginationlayout"prev, pager, next":total"50"></el-pagination> </div>参考Element-UI total:0, form: …

html中列表和表格的使用

列表一般来说只有一列一列的进行使用&#xff0c;是一维的列表分为三种列表形式<!-- 列表标签ul-li:无序列表&#xff0c;必须用 <ul> 当 “容器”&#xff08;代表 “无序列表”&#xff09;&#xff0c;每个条目用 <li> 包起来&#xff08;代表 “列表项”&am…

大学信息查询平台:一个现代化的React教育项目

一 项目简介大学信息查询平台是一个基于React Vite Tailwind CSS构建的现代化Web应用&#xff0c;专门用于查询中国各大高校的详细信息。该项目不仅功能实用&#xff0c;更在用户体验和界面设计上做到了极致。二 核心功能2.1. 智能大学搜索// 搜索功能核心代码 const searchU…

代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和

代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和454.四数相加II解题思路383.赎金信自己解答&#xff1a;代码随想录讲解暴力做法哈希表15.三数之和双指针优化改进18.四数之和自己的解答系统讲解454.四数相加II 文档讲解&…

FPGA实现流水式排序算法

该算法采用双调排序算法&#xff0c;是一种可流水的递推算法&#xff0c;且算法的消耗时长可算&#xff0c;具体细节参考视频&#xff1a; https://www.bilibili.com/video/BV1S3thzWEnh/?spm_id_from333.1387.homepage.video_card.click&vd_source69fb997b62efa60ae1add…

平衡车 -- MPU6050

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 传感器原理 此外&#xff0c;用陀螺仪获取x,y,z轴的加速度。 初始化 我们现在对MPU6050进行初始化&#xff0c;MPU6050通过I2C总线与单片机进行通信&#xff0c;通过的是PB8和PB…

在电路浪涌测试中,TVS(瞬态电压抑制二极管)的防护效果确实会受到陪测设备中去耦网络(Decoupling Network,DN)的显著影响

在电路浪涌测试中&#xff0c;TVS&#xff08;瞬态电压抑制二极管&#xff09;的防护效果确实会受到陪测设备中去耦网络&#xff08;Decoupling Network&#xff0c;DN&#xff09;的显著影响&#xff0c;这一现象与浪涌能量的传递路径、阻抗匹配及信号完整性密切相关。结合 AD…

Redis之分布式锁与缓存设计

1、分布式锁 1.1、超卖问题/*** 存在库存超卖的不安全问题*/private void deductStock() {int stockTotal Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));if (stockTotal > 0) { // 这里存在多个线程、进程同时判断通过&#xff0c;然后超买…