四大集合之Set

news2024/12/23 23:18:39

一、Set基础知识

1. Set集合

1.1 HashSet

Set集合区别于其他三大集合的重要特性就是元素具有唯一性,南友们记不住这个特性的话,有个易记的方法。Set集合为什么要叫Set呢?因为Set集合的命名取自于我们小学数学里的集合论(Set Theory),数学集合一个很重要的概念就是每个元素的值都互不相同。

Set集合常见的有实例有:HashSet、LinkedHashSet、TreeSet,南哥先缕一缕HashSet。

// HashSet类源码
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {...}

HashSet底层实现其实是基于HashMap,HashMap的特点就是Key具有唯一性,这一点被HashSet利用了起来,每一个HashMap的Key对应的就是HashSet的元素值。来看看官方源码的解释。

此类实现Set接口,由哈希表(实际上是HashMap实例)支持。它不保证集合的迭代顺序;特别是,它不保证顺序随时间保持不变。此类允许null元素。

我们创建一个HashSet对象,实际上底层创建了一个HashMap对象。

    // HashSet构造方法源码
    public HashSet() {
        map = new HashMap<>();
    }

HashSet一共提供了以下常用方法,不得不说HahSet在业务开发中还是用的没那么多的,南哥在框架源码上看HashSet用的就比较多,比如由Java语言实现的zookeeper框架源码。

(1)添加元素

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

我们看上面add方法的源码,是不是调用了HashMap的put方法呢?而put方法添加的Key是HashSet的值,Val则是一个空的Object对象。PRESENT是这么定义的。

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

(2)判断元素是否存在

    public boolean contains(Object o) {
        return map.containsKey(o);
    }

HashSet的contains方法同样是调用HashMap判断Key是否存在的方法:containsKey

(3)移除元素

    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

1.2 LinkedHashSet

接着轮到LinkedHashSet,同为Set集合之一,它和上文的HashSet有什么区别?南哥卖个关子。

源码对LinkedHashSet的解释。

Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order).

源码的大概意思就是:Set接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与HashSet的不同之处在于,它维护一个贯穿其所有条目的双向链表。此链表定义迭代顺序,即**元素插入集合的顺序 (**插入顺序)。

底层数据结构是一条双向链表,每个元素通过指针进行相连,也就有了按插入顺序排序的功能。

知道了LinkedHashSet的特性,看看他的构造方法。

    /**
     * 构造一个新的、空的链接哈希集,具有默认初始容量(16)和负载因子(0.75)。
     */
    public LinkedHashSet() {
        super(16, .75f, true);
    }

这个super方法向上调用了底层C语言源码实现的LinedHashMap的构造方法。LinkedHashMap的特点就是元素的排序是根据插入的顺序进行排序,那LinkedHashSet也就继承了这个特性。

    // C语言源码
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

LinkedHashSet的常见方法和HashSet一样,同样是add()、contains()、remove(),这里我写个简单的Demo。

    public static void main(String[] args) throws IOException {
        LinkedHashSet<Integer> set = new LinkedHashSet<>();
        set.add(1);
        System.out.println(set.contains(1));
        set.remove(1);
        System.out.println(set.contains(1));
    }
# 运行结果
true
false

1.3 TreeSet

轮到你了,TreeSet。我们南友们很好奇为什么他叫TreeSet?

因为他是基于TreeMap实现的。。。

但根本原因不是,TreeMap的底层是通过红-黑树数据结构来实现自然排序,那TreeSet也就继承了这个特性。

官方源码对TreeSet的解释:

基于TreeMap的NavigableSet实现。元素使用其自然顺序进行排序,或者根据使用的构造函数,使用创建集合时提供的Comparator进行排序。

源码解释告诉我们,TreeSet和HashSet、LinkedHashSet不同的特性在于,元素既不像HashSet一样无序,也不是像LinkedHashSet一样是以插入顺序来排序,它是根据元素的自然顺序来进行排序。

b、c、a这三个元素插入到TreeSet中,自然顺序就和字母表顺序一样是:a、b、c

    public static void main(String[] args) throws IOException {
        TreeSet<String> treeSet = new TreeSet<>();
        treeSet.add("b");
        treeSet.add("c");
        treeSet.add("a");
        System.out.println(treeSet);
    }
# 运行结果
[a, b, c]

TreeSet除了拥有以下的add()、contains()、remove()方法。

    // 如果指定元素尚不存在,则将其添加到此集合中。
    public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }
    // 如果此集合包含指定元素,则返回true 
    public boolean contains(Object o) {
        return m.containsKey(o);
    }
    // 如果存在指定元素,则从此集合中移除该元素。
    public boolean remove(Object o) {
        return m.remove(o)==PRESENT;
    }

值得提出来的是,TreeSet还拥有first()、last(),可以方便我们提取出第一个、最后一个元素。

    // 返回集合中的第一个元素。
    public E first() {
        return m.firstKey();
    }
    // 返回集合中的最后一个元素。
    public E last() {
        return m.lastKey();
    }

1.4 TreeSet自定义排序

TreeSet的自定义排序我们要利用Comparator接口,通过向TreeSet传入自定义排序规则的Comparator来实现。

官方源码是这么解释的,南友们看一看。

    // 构造一个新的空树集,根据指定的比较器进行排序。
    // 插入到集合中的所有元素都必须能够通过指定的比较器相互比较: comparator. compare(e1, e2)不得对集合中的任何元素e1和e2抛出ClassCastException 。
    // 如果用户尝试向集合中添加违反此约束的元素,则add调用将抛出ClassCastException 
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

传入Comparator接口时,我们还需要定义compare方法的游戏规则:如果compare方法比较两个元素的大小,返回正整数代表第一个元素 > 第二个元素、返回负整数代表第一个元素 < 第二个元素、返回0代表第一个元素 = 第二个元素。

下面我写了一个Demo,Comparator接口的规则是这样:人的岁数越小,那么他排名越靠前。

public class JavaProGuideTest {
    public static void main(String[] args) {
        TreeSet set = new TreeSet(new Comparator() {
            public int compare(Object o1, Object o2) {
                Person p1 = (Person)o1;
                Person p2 = (Person)o2;
                return (p1.age > p2.age) ? 1 : (p1.age < p2.age) ? -1 : 0;
            }
        });

        set.add(new Person(5));
        set.add(new Person(3));
        set.add(new Person(6));
        System.out.println(set);
    }

    @Data
    @AllArgsConstructor
    private static class Person {
        int age;
    }
}
# 执行结果
[JavaProGuideTest.Person(age=3), JavaProGuideTest.Person(age=5), JavaProGuideTest.Person(age=6)]

二、Set常见面试题

1. 你能解释一下 Set 和 List 的区别吗?特别是它们在使用场景上的差异?

回答: SetList 是 Java 集合框架中的两个核心接口,它们的主要区别在于是否允许重复元素。List 允许存储重复的元素,并且元素是有序的,可以通过索引访问。Set 则不允许存储重复元素,元素的顺序不固定(具体取决于实现类)。在实际应用中,当你需要保证集合中的元素唯一时,使用 Set,例如处理用户权限、存储唯一标识符等场景;而 List 适用于需要频繁访问元素或保持插入顺序的场景,如订单列表、待办事项等。

2. 你如何选择使用 HashSet、LinkedHashSet 和 TreeSet?分别在什么情况下使用它们?

回答: HashSet 是最常用的 Set 实现,适用于对顺序没有要求且需要高效查询的场景。LinkedHashSet 保留了插入顺序,适用于需要保留元素插入顺序且对性能要求不太高的场景。TreeSet 则保证元素的排序顺序,适用于需要对集合中的元素进行排序的场景,如存储按字母顺序排列的单词、按照优先级排序的任务等。

3. 假如我们有一个包含大量元素的 List,现在需要去重并保持顺序,你会选择什么集合实现?为什么?

回答: 我会选择 LinkedHashSet。因为 LinkedHashSet 不仅能去重,还能保持元素的插入顺序。通过将 List 转换为 LinkedHashSet,可以轻松地去除重复元素,同时保留原始顺序。

4. 在 HashSet 中插入一个元素时,底层具体做了哪些操作?

回答: 当在 HashSet 中插入一个元素时,底层首先通过 hashCode() 方法计算该元素的哈希值,然后将这个哈希值用于定位元素在哈希表中的存储位置。如果该位置已经有元素,则会调用 equals() 方法来比较新元素和现有元素是否相等。如果相等,则不插入新元素;如果不相等,则使用链表或红黑树结构解决哈希冲突,最后将新元素插入到适当位置。

5. 能详细解释一下 TreeSet 是如何进行排序的吗?如果我们有自定义对象呢?

回答: TreeSet 是基于红黑树实现的,默认情况下使用元素的自然顺序(通过 Comparable 接口的 compareTo() 方法)进行排序。如果是自定义对象,可以实现 Comparable 接口并重写 compareTo() 方法,或者在创建 TreeSet 时传入一个 Comparator 来定义排序逻辑。例如,假设我们有一个 Person 类,按照年龄排序,可以在 compareTo() 方法中定义比较逻辑,或者通过 Comparator 传入 TreeSet

6. 在实际项目中,是否遇到过 HashSet 无法去重的情况?是什么原因造成的?

回答: 是的,可能会遇到这种情况。这通常是由于自定义对象没有正确实现 equals()hashCode() 方法造成的。HashSet 依赖这两个方法来判断元素的唯一性,如果它们没有正确实现,即使两个对象内容相同,HashSet 也会认为它们是不同的元素,导致无法去重。解决方法是确保 equals()hashCode() 方法按照相同的逻辑比较对象的所有关键属性。

7. 你如何在 Set 中存储自定义对象,同时确保没有重复对象?

回答: 要在 Set 中存储自定义对象并确保没有重复对象,必须重写对象类的 equals()hashCode() 方法。equals() 方法用于判断两个对象是否相等,而 hashCode() 方法则用于计算对象的哈希值。在重写这些方法时,通常需要确保 equals() 方法判断的关键字段都参与 hashCode() 的计算,以确保哈希值和相等性逻辑一致。

8. 什么情况下你会选择使用 EnumSet?它和普通的 Set 有什么不同?

回答: EnumSet 是一个专门用于存储枚举类型的高效 Set 实现。它的实现基于位向量,因而非常高效,特别是当你需要存储一组枚举常量时。相比普通的 SetEnumSet 占用更少的内存,性能也更好。例如,在权限管理系统中,如果有一组固定的权限(枚举),可以使用 EnumSet 来高效管理这些权限。

9. 为什么 TreeSet 不允许插入 null 元素?

回答: TreeSet 基于红黑树实现,它需要对插入的元素进行排序,而 null 元素无法进行比较(因为 compareTo()Comparator 都无法处理 null),因此在插入 null 时会抛出 NullPointerException。这与 HashSet 可以插入 null 元素形成了对比,因为 HashSet 不需要对元素进行排序。

10. 假如我们需要创建一个线程安全的 Set,你会怎么做?

回答: 有几种方法可以创建线程安全的 Set。一种方法是使用 Collections.synchronizedSet(new HashSet<>()),这会返回一个同步的 Set,所有对它的访问都会自动加锁。另一种更现代的方法是使用 ConcurrentHashMap.newKeySet(),它基于 ConcurrentHashMap 实现,允许并发访问,并且性能更好。

11. HashSet 的默认加载因子是 0.75,你能解释一下这个值的含义吗?它对性能有什么影响?

回答: 加载因子表示 HashSet 在需要扩容前能填满的比例。默认值 0.75 表示当 HashSet 中的元素数量达到容量的 75% 时,它会自动扩容以保持性能。较高的加载因子可以减少内存的使用,但会增加冲突率,从而降低查找和插入的性能。较低的加载因子会增加内存使用,但减少冲突率,提升性能。一般情况下,0.75 是在性能和内存使用之间的一个折中选择。

12. 你能描述一下 Set 和 Map 之间的关系吗?为什么我们说 HashSet 实际上是基于 HashMap 实现的?

回答Set 和 Map 是 Java 集合框架的两种不同接口。Set 用于存储不重复的元素,而 Map 用于存储键值对。HashSet 是基于 HashMap 实现的,实际上,HashSet 通过 HashMap 来存储元素,每个元素作为 HashMap 的键(key),而值(value)则是一个固定的常量对象。因此,HashSet 在内部通过 HashMap 的 put() 方法来确保元素唯一。

13. 在并发环境中,使用 ConcurrentSkipListSet 有什么优势?

回答ConcurrentSkipListSet 是一个线程安全的 Set 实现,它基于跳表数据结构。这种结构不仅支持并发访问,而且在执行插入、删除和查找操作时具有较高的性能。与传统的锁机制不同,跳表允许多个线程并发地操作不同的部分,从而减少了锁争用,提升了并发性能。ConcurrentSkipListSet 特别适用于需要自然排序且需要支持高并发的场景。

14. 你是否遇到过 HashSet 中的元素顺序不一致的情况?为什么会这样?

回答: 是的,HashSet 的元素顺序是不固定的。这是因为 HashSet 的底层实现是基于哈希表的,元素的位置取决于其哈希值。而哈希值的分布可能随着元素的增加、删除或哈希表的扩容而发生变化,从而导致元素顺序的变化。因此,HashSet 不适合用在需要保持元素顺序的场景中,如果需要顺序,可以使用 LinkedHashSet

15. 如何在一个 Set 中查找最大或最小元素?

回答: 如果使用的是 TreeSet,可以直接使用 first() 和 last() 方法来获取最小和最大元素,因为 TreeSet 是有序的。对于无序的 Set(如 HashSet 或 LinkedHashSet),你需要手动遍历集合并使用比较器来找到最大或最小元素

16. 如何判断两个 Set 是否相等?

回答: 两个 Set 被认为是相等的,当且仅当它们包含的元素相同,且元素的数量也相同。可以使用 Set 的 equals() 方法来判断两个 Set 是否相等。这个方法会检查两个集合是否具有相同的元素(无论顺序),如果是,则返回 true。

17. 你能解释一下 WeakHashSet 是什么吗?它在什么场景下使用?

回答: 实际上,Java 标准库中并没有 WeakHashSet,但可以通过 Collections.newSetFromMap(new WeakHashMap<>()) 来创建一个 WeakHashSet。这种 Set 使用 WeakHashMap 来存储元素的引用,当元素不再被其他强引用所引用时,GC 会自动回收这些元素。这种 Set 适用于缓存等场景,可以防止内存泄漏

18. 如果需要对一个非常大的 Set 进行操作,比如合并、交集或差集,如何处理会更高效?

回答: 对于非常大的 Set,可以使用并行流(parallelStream())来提高操作效率。并行流可以利用多核处理器同时处理多个元素,从而加快合并、交集和差集的计算。另外,如果这些操作频繁且数据量非常大,使用高效的并发集合如 ConcurrentSkipListSet 也可以帮助提升性能

19. 在 Java 8 中,如何使用流(Stream)操作 Set?

回答: 在 Java 8 中,可以使用 Set.stream() 方法将 Set 转换为流,然后使用流的各种操作如 filtermapcollect 等进行操作。例如,如果你想对 Set 中的每个元素进行处理并收集结果,可以这样做: java Set<String> set = new HashSet<>(Arrays.asList("a", "b", "c")); Set<String>result=set.stream().map(String::toUpperCase).collect(Collectors.toSet()); 这样你就可以很方便地使用流来操作 Set

20. 在面试中经常问到如何优化 Set 操作,你会给出哪些建议?

回答: 优化 Set 操作的建议包括: - 根据需求选择合适的 Set 实现,如 HashSetLinkedHashSetTreeSet 等。 - 合理设置 HashSet 的初始容量和加载因子,以减少扩容次数。 - 对于频繁的集合操作如并集、交集等,可以使用并行流来提升性能。 - 使用 EnumSet 来处理枚举类型的集合,能大幅度减少内存消耗和提高性能。 - 在多线程环境下使用线程安全的集合如 ConcurrentSkipListSet 或通过 Collections.synchronizedSet() 来保证安全性。

让我们一起学习,一起进步!期待在评论区与你们见面。

祝学习愉快!

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

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

相关文章

SPI(硬件协议)

1 SPI硬件外设协议 2 SPI框图 3 硬件SPI数据收发流程 1 发送数据&#xff0c;同时接收数据&#xff0c;相互配合&#xff0c;可以实现数据流不间断 2 全双工SPI&#xff0c;发送和接收数据寄存器分开&#xff0c;可以同时进行 4 spi传输框图 1 速度快 2 速度慢&#xff0c;容…

软考中项拿证利器:系统集成项目管理工程师(第3版)一站通关

指尖疯编著的《系统集成项目管理工程师&#xff08;适用第3版大纲&#xff09;一站通关》目前现货已经上线各大电商平台&#xff0c;您可以在任一电商搜索《系统集成项目管理工程师&#xff08;适用第3版大纲&#xff09;一站通关》即刻找到。 出版中项一站通关完全是机缘巧合&…

Nginx: 性能优化之提升CPU效率以及TCP的三次握手和四次挥手

提升利用CPU的效率 1 &#xff09;CPU的调度机制 现在来看下 linux中 CPU的一个调度机制 假设现在系统上有只有一颗CPU&#xff0c;而linux系统是一个多任务的一个操作系统 它允许我们各个不同的用户允许在同一个操作系统上执行很多个进程 单核CPU肯定不可能同时去执行这样一…

5.图论.题目2

5.图论.题目2 题目8.字符串接龙9.有向图的完全可达性10.岛屿的周长11.寻找存在的路径12.冗余连接113.冗余连接214.寻宝 题目 8.字符串接龙 题目链接 本题的直观思路如下图所示&#xff1b;但该题有两个问题&#xff1a;1.图中的线是如何连接起来的 2.如何确定起点到终点的最…

《JavaEE进阶》----4.<SpringMVC①简介、基本操作(各种postman请求)>

本篇博客讲解 MVC思想、及Spring MVC&#xff08;是对MVC思想的一种实现&#xff09;。 Spring MVC的基本操作、学习了六个注解 RestController注解 RequestMappering注解 RequestParam注解 RequestBody注解 PathVariable注解 RequestPart注解 MVC View(视图) 指在应⽤程序中…

数据同步的艺术:探索PostgreSQL和Redis的一致性策略

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 1. 前言 在当今高度数字化的世界中,应用程…

ACL学习笔记

1.ACL快速配置 需求&#xff1a;拒绝PC 1访问PC 3 &#xff08;1&#xff09;配置PC PC 1: PC 2: PC 3: &#xff08;2&#xff09;配置R1的接口IP信息 sys sysname R1 undo info-center enable interface GigabitEthernet0/0/0 ip address 192.168.1.1 255.255.255.0 qui…

超声波智能水表多少钱一个?

超声波智能水表的价格因品牌、功能、规格等因素而异&#xff0c;就拿深圳合众致达科技有限公司智能水电表厂家的超声波智能水表DN15口径产品举例&#xff0c;价格为399元起。具体价格需根据实际需求来确定。 一、影响价格的主要因素 -技术含量&#xff1a;具备远程数据传输、…

DSOJ-id12

1.保留几位小数 #include <iostream>#include <iomanip> //必须包含这个头文件using namespace std;void main( ){ double a 3.141596;cout<<fixed<<setprecision(3)<<a<<endl; //输出小数点后3位 2. 使用了未初始化的局部变量 Point* …

如何使用小乌龟清除认证缓存、还原版本、定位及常用开发工具集成

&#x1f600;前言 本篇博文是关于如何使用小乌龟清除认证缓存、还原版本、定位及常用开发工具集成&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大…

openGuass之CTE Reuse

一. 前言 ​ CTE 是指with的公共表达式&#xff0c;如下所示是个CTE样例&#xff1a; ​ CTE表达式往往在同一条sql中多次被重复引用&#xff0c;如上图所示的cte被引用了两次&#xff08;c1 和 c2&#xff09;&#xff0c;我们称为2个CTE实例。 ​ 本文只要…

Windows系统Nginx下载安装配置 运行错误处理

Nginx是一款轻量级的web 服务器/反向代理 服务器。本篇文章主要是nginx的下载安装&#xff0c;处理运行中遇到的问题&#xff0c;配置反向代理。主要分为两部分&#xff1a;下载安装和配置。 目录 1.下载安装 2.nginx配置反向代理 1.下载安装 nginx官网&#xff1a;nginx: …

新160个crackme -044-tsrh-crackme

运行分析 提示去除NAG 不去除NAG也能进入主窗口&#xff0c;需要破解Name和Serial PE分析 ASM程序&#xff0c;32位&#xff0c;壳未知 去除NAG ida搜索字符串&#xff0c;发现NAG弹窗标题字符串&#xff0c;双击进入函数 找到了messagebox&#xff0c;即NAG位置00401079 打开x…

网络压缩之动态计算(dynamic computation)

动态计算希望网络可以自由 地调整它需要的计算量。为什么期待网络可以自由地调整它需要的计算量呢? 因为有时候我 们可能同样的模型会想要跑在不同的设备上面&#xff0c;而不同的设备上面的计算资源是不太一样的。所以期待训练好一个网络以后&#xff0c;放到新的设备上面&am…

Python编程基础知识,让编程基础更加扎实(输出个人简介)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

考研--数学(相关公式)

解析几何 知识点1 A(x1,y1) B(x2,y2) 则AB长度 |AB| A、B中点的坐标 &#xff08;&#xff0c;) 知识点2 方程求解 ①点斜式&#xff1a; y-y0k(x0-x) ②斜率式&#xff1a; ykxb ③两点式&#xff1a; …

【笔记篇】Davinci Configurator CanNm模块

目录 1 简介1.1 架构概览2 功能描述2.1 特性2.2 初始化2.3 状态机2.3.1 网络模式2.3.1.1 重复报文状态2.3.1.2 正常状态2.3.1.3 准备休眠状态2.3.2 预休眠模式2.3.3 总线休眠模式2.4 被动模式(对于被动节点)2.5 NM报文格式2.6 NM报文发送2.6.1 重试第一次报文请求2.7 降低总线…

集成电路学习:什么是I2C内部集成电路总线

I2C&#xff1a;内部集成电路总线 I2C&#xff0c;全称Inter-Integrated Circuit&#xff0c;即内部集成电路总线&#xff0c;是由飞利浦公司&#xff08;现为恩智浦半导体&#xff09;在上世纪八十年代初开发的一种同步的串行通信总线。它以其接线简单、硬件实现容易、可扩展性…

Mysql8利用binlog实现数据恢复

文章目录 1binlog基本概念2 binlog相关常用命令3 binlog工具mysqlbinlog4 测试数据准备&导入数据5 模拟误删表6 数据恢复方式说明7 数据恢复分析(偏移量方式恢复)8 数据恢复9 验证10 数据恢复的局限性11 总结 1binlog基本概念 binlog即binary log&#xff0c;二进制日志文件…

【React原理 - 任务调度之中断恢复】

概览 本文紧接上文介绍React调度的时间分片中任务中断和恢复&#xff0c;由于篇幅过长&#xff0c;所以拆成了两篇。上文主要介绍了调度器中的优先级和调度任务的触发、注册和调度循环。本文主要从任务调度入手介绍调度任务之后发送了什么&#xff0c;即在协调器中如何进行到f…