Java集合篇

news2024/11/18 11:51:00

前言:笔者参考了JavaGuide、三分恶等博主的八股文,结合Chat老师和自己的理解,整理了一篇关于Java集合的八股文。希望对各位读者有所帮助~~

引言

常见集合有哪些?

Java集合相关类和接口都在java.util包中,按照其存储结构集合可以分为两大类:单列集合 Collection 和双列集合 Map。Collection派生出了三个子接口:List、Set、Queue,因此Java集合大致也可分成List、Set、Queue、Map四种接口体系。

单列集合Collection

在这里插入图片描述

  • List:元素有序、可重复,这里所谓的有序意思是:元素的存入顺序和取出顺序一致。例如,存储元素的顺序是 11、22、33,那么我们从 List 中取出这些元素的时候也会按照 11、22、33 这个顺序。List 接口的常用实现类有:
    • ArrayList:底层数据结构是数组,线程不安全;
    • LinkedList:底层数据结构是链表,线程不安全;
  • Set:元素不可重复,不能通过整数索引来访问,并且元素无序。所谓无序也就是元素的存入顺序和取出顺序不一致。其常用实现类有:
    • HashSet:底层基于 HashMap 实现,采用 HashMap 来保存元素;
    • LinkedHashSetLinkedHashSetHashSet 的子类,并且其底层是通过 LinkedHashMap 来实现的;
  • Queue:先进先出的队列。其常用实现类有:PriorityQueue

双列集合Map

Map:元素是成对存在的。每个元素由键(key)与值(value)两部分组成,通过键可以找对所对应的值。显然这个双列集合解决了数组无法存储映射关系的痛点。另外,需要注意的是,Map 不能包含重复的键,值可以重复;并且每个键只能对应一个值。

在这里插入图片描述

需要注意的是,这些容器都只能存储对象引用类型,也就是说当我们需要装载的数据是诸如 intfloat 等基本数据类型的时候,必须把它们转换成对应的包装类。

线程安全的集合有哪些?线程不安全的呢?

线程安全的:

  • Hashtable:比HashMap多了个线程安全。
  • ConcurrentHashMap:是一种高效但是线程安全的集合。
  • Vector:比Arraylist多了个同步化机制。
  • Stack:栈,也是线程安全的,继承于Vector。

线程不安全的:

  • HashMap
  • ArrayList
  • LinkedList
  • HashSet
  • TreeSet
  • TreeMap

List

ArrayList和LinkedList有什么区别?

  • ArrayList和LinkedList都是线程不安全的;
  • ArrayList 的实现是基于数组,LinkedList 的实现是基于双向链表;
  • ArrayList 采用数组存储,所以插入和删除元素受元素位置的影响;LinkedList采用链表存储,所以插入和删除元素不受元素位置的影响;
  • ArrayList 支持随机访问,而 LinkedList 不支持。ArrayList 可以根据下标以 O ( 1 ) O(1) O(1)时间复杂度对元素进行随机访问,而 LinkedList 的每一个元素都依靠地址指针和它后一个元素连接在一起,查找某个元素的时间复杂度是 O ( n ) O(n) O(n)
  • LinkedList 比 ArrayList 更占内存。因为 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素;

讲讲ArrayList的扩容机制?

ArrayList是基于数组的集合,数组的容量是在定义的时候确定的,如果数组满了再插入,就会数组溢出。所以在插入时候,会先检查是否需要扩容,如果当前容量+1超过数组长度,就会进行扩容。

扩容发生在啥时候?那肯定是我们往数组中新加入一个元素但是发现数组满了的时候。没错,我们去 add 方法中看看 ArrayList 是怎么做扩容的:

在这里插入图片描述

ensureExplicitCapacity 判断是否需要进行扩容,很显然,grow 方法是扩容的关键:
在这里插入图片描述

别的都不用看了,看上面图中的黄色框框就知道 ArrayList 是怎么扩容的了:扩容后的数组长度 = 当前数组长度 + 当前数组长度 / 2(也就是【1.5 倍】)。最后使用 Arrays.copyOf 方法直接把原数组中的数组 copy 过来,需要注意的是,Arrays.copyOf 方法会创建一个新数组然后再进行拷贝。

扩容操作需要调用 Arrays.copyOf()(底层 System.arraycopy())需要把原数组整个复制到新数组中,这个操作代价很高,因此最好在创建 ArrayList 对象时就指定大概的容量大小,减少扩容操作的次数。

举个栗子:
在这里插入图片描述

Arraylist 扩容的数组长度为什么是原数组长度的 1.5 倍?

这种扩容方式能够有效地平衡内存空间的使用和程序性能之间的关系。如果每次扩容时都将数组长度翻倍,可能会导致数组长度过大,浪费内存空间,而如果每次扩容时只增加一个固定的长度,可能会导致频繁扩容,影响程序性能。因此,1.5倍左右的扩容因子是一个比较理想的选择。

ArrayList怎么序列化的知道吗? 为什么用transient修饰数组?

ArrayList的序列化不太一样,它使用 transient 修饰存储元素的 elementData 的数组, transient 关键字的作用是让被修饰的成员属性不被序列化。

为什么最ArrayList不直接序列化元素数组呢?

出于效率的考虑,数组可能长度100,但实际只用了50,剩下的50不用其实不用序列化,这样可以提高序列化和反序列化的效率,还可以节省内存空间。

那ArrayList怎么序列化呢?

ArrayList通过两个方法readObjectwriteObject自定义序列化和反序列化策略,实际直接使用两个流ObjectOutputStreamObjectInputStream来进行序列化和反序列化。
在这里插入图片描述

什么是CopyOnWriteArrayList?

CopyOnWriteArrayList就是线程安全版本的ArrayList。它的名字叫 CopyOnWrite ——写时复制,已经明示了它的原理。

CopyOnWriteArrayList采用了一种读写分离的并发策略。CopyOnWriteArrayList容器允许并发读,读操作是无锁的,性能较高。至于写操作,比如向容器中添加一个元素,则首先将当前容器复制一份,然后在新副本上执行写操作,结束之后再将原容器的引用指向新容器。

在这里插入图片描述

ArrayList 与Vector区别?

  • 实现:都实现了List接口,底层都使用 Object[]数组存储。
  • 线程安全: Vector使用了Synchronized 来实现线程同步,是线程安全的,而 ArrayList是非线程安全的。
  • 扩容: Vector 每次扩容请求其大小的 2 倍(也可以通过构造函数设置增长的容量),而 ArrayList 是 1.5 倍。
  • 性能: ArrayList在性能方面要优于Vector。

Map

HashMap 有什么特点?

HashMap 基于哈希表的 Map 接口实现,是以 key-value 存储形式存在,主要用来存放键值对。

  • HashMap 的实现不是同步的,这意味着它不是线程安全的;
  • key 是唯一不重复的,底层的哈希表结构,依赖 hashCode 方法和 equals 方法保证键的唯一;
  • key、value 都可以为null,但是 key 位置只能是一个null;
  • HashMap 中的映射不是有序的,即存取是无序的;
  • key 要存储的是自定义对象,需要重写 hashCode 和 equals 方法,防止出现地址不同内容相同的 key;
  • JDK1.8 之前 HashMap 由 数组+链表 组成
    • 数组是 HashMap 的主体;
    • 链表则是为了解决哈希冲突而存在的(拉链法解决冲突),拉链法就是头插法,两个对象调用的 hashCode 方法计算的哈希码值(键的哈希)一致导致计算的数组索引值相同;
  • JDK1.8 以后 HashMap 由 数组+链表 +红黑树数据结构组成
    • 解决哈希冲突时有了较大的变化;
    • 当链表长度超过阈值(或者红黑树的边界值,默认为 8)并且当前数组的长度大于等于 64 时,此索引位置上的所有数据改为红黑树存储;
    • 即使哈希函数取得再好,也很难达到元素百分百均匀分布。当 HashMap 中有大量的元素都存放到同一个桶中时,就相当于一个长的单链表,假如单链表有 n 个元素,遍历的时间复杂度是 O ( n ) O(n) O(n),所以 JDK1.8 中引入了 红黑树(查找时间复杂度为 O ( l o g n ) O(logn) O(logn))来优化这个问题,使得查找效率更高

HashMap的底层数据结构是什么?

在JDK1.7 中,由“数组+链表”组成:数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的。
在JDK1.8 中,由“数组+链表+红黑树”组成:当链表过长,则会严重影响 HashMap 的性能,红黑树搜索时间复杂度是 O ( l o g n ) O(logn) O(logn),而链表是糟糕的 O ( n ) O(n) O(n)。因此,JDK1.8 对数据结构做了进一步的优化,引入了红黑树。链表和红黑树在达到一定条件会进行转换。

数据结构示意图如下:
在这里插入图片描述

其中,桶数组是用来存储数据元素,链表是用来解决冲突,红黑树是为了提高查询的效率。

  • 数据元素通过映射关系,也就是散列函数,映射到桶数组对应索引的位置;
  • 如果发生冲突,从冲突的位置拉一个链表,插入冲突的元素;
  • 如果链表长度>8&数组大小>=64,链表转为红黑树;
  • 如果红黑树节点个数<6 ,转为链表;

了解红黑树嘛?

红黑树本质上是一种二叉查找树,为了保持平衡,它又在二叉查找树的基础上增加了一些规则:

  1. 每个节点要么是红色,要么是黑色;
  2. 根节点永远是黑色的;
  3. 所有的叶子节点都是黑色的(注意这里说叶子节点其实是图中的 NULL 节 点);
  4. 每个红色节点的两个子节点一定都是黑色;
  5. 从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点;

在这里插入图片描述

为什么HashMap不使用二叉树/平衡树/B树、B+树呢?

之所以不用二叉树:

红黑树是一种不严格的平衡二叉树,插入、删除、查找的最坏时间复杂度都为 O(logn),避免了二叉树最坏情况下的O(n)时间复杂度。

之所以不用平衡二叉树:

平衡二叉树是比红黑树更严格的平衡树,是一种高度平衡的二叉树,查询效率高。但是为了维持这种高度的平衡,需要旋转的次数更多,每次插入、删除都要做调整,就比较复杂、耗时,也就是说平衡二叉树保持平衡的效率更低。因此,红黑树的查询性能略微逊色于二叉平衡树, 但是红黑树在插入和删除上优于二叉平衡树。总体来说,红黑树的插入、删除、查找各种操作性能都比较稳定。

之所以不用B树、B+树:

  • B+树在数据库中被应用的原因就是B+树比B树更加“矮胖”,B+树的非叶子结点不存储数据,所以每个结点能存储的关键字更多。所以B+树更能应对大量数据的情况。如果用B+树的话,在数据量不是很多的情况下,数据都会“挤在”一个结点里面。这个时候遍历效率就退化成了链表;
  • B和B+树主要用于数据存储在磁盘上的场景,比如数据库索引就是用B+树实现的。这两种数据结构的特点就是树比较矮胖,每个结点存放一个磁盘大小的数据,这样一次可以把一个磁盘的数据读入内存,减少磁盘转动的耗时,提高效率。而红黑树多用于内存中排序,也就是内部排序。

红黑树怎么保持平衡的知道吗?

红黑树有两种方式保持平衡:旋转(左旋和右旋)和染色。
在这里插入图片描述

HashMap的put流程知道吗?

流程图如下:
在这里插入图片描述

  1. 首先判断数组是否为空,为空则调用 resize 进行初始化;
  2. 根据 key 的值计算 hash 值,找到该元素在数组中存储的下标;
  3. 如果没有哈希冲突直接放在对应的数组下标里;
  4. 如果冲突了,且 key 已经存在,就覆盖掉 value;
  5. 如果冲突后,发现该节点是红黑树,就将这个节点挂在树上;
  6. 如果冲突后是链表,判断该链表是否大于 8 ,如果大于 8 并且数组长度小于 64,就进行扩容;如果链表节点大于 8 并且数组长度大于 64,则将这个结构转换为红黑树;否则,链表插入键值对,若 key 存在,就覆盖掉 value。

HashMap怎么查找元素的呢?

先看流程图:
在这里插入图片描述

HashMap的查找流程:

  1. 使用扰动函数,获取新的哈希值;
  2. 计算数组下标,获取节点;
  3. 当前节点和key匹配,直接返回;
  4. 否则,当前节点是否为树节点,查找红黑树;
  5. 否则,遍历链表查找。

HashMap的哈希/扰动函数是怎么设计的?

HashMap的哈希函数是先拿到 key 的hashcode,是一个32位的int类型的数值,然后让hashcode的高16位和低16位进行异或操作。

static final int hash(Object key) {
    int h;
    // key的hashCode和key的hashCode右移16位做异或运算
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

这么设计是为了降低哈希碰撞的概率。

你还知道哪些哈希函数的构造方法呢?

HashMap里哈希构造函数的方法叫除留取余法 :H(key) = key%p(p<=N),关键字除以一个不大于哈希表长度的正整数p,所得余数为地址,当然HashMap里进行了优化改造,效率更高,散列也更均衡。

除此之外,还有这几种常见的哈希函数构造方法:

  • 直接定址法:直接根据 key 来映射到对应的数组位置,例如1232放到下标1232的位置。
  • 数字分析法:取 key 的某些数字(例如十位和百位)作为映射的位置。
  • 平方取中法:取 key 平方的中间几位作为映射的位置。
  • 折叠法:将 key 分割成位数相同的几段,然后把它们的叠加和作为映射的位置。

在这里插入图片描述

解决哈希冲突有哪些方法呢?

解决Hash冲突方法有:开放寻址法、再哈希法、链地址法(拉链法)、建立公共溢出区。HashMap中采用的是链地址法 。

  • 开放寻址法:开放寻址法也称为再散列法,基本思想就是如果p = H(key)出现冲突时,则以p为基础,再次hash,p1 = H(p),直到找到一个不冲突的哈希地址。 因此开放定址法所需要的hash表的长度要大于等于所需要存放的元素,而且因为存在再次hash,所以只能在删除的节点上做标记,而不能真正删除节点。
  • 再哈希法:再哈希法(双重散列,多重散列),提供多个不同的hash函数,当R1 = H1(key1)发生冲突时,再计算R2 =H2(key1),直到没有冲突为止。 这样做虽然不易产生堆集,但增加了计算的时间。
  • 链地址法(拉链法):在冲突的位置拉一个链表,把冲突的元素放进去。链地址法适用于经常进行插入和删除的情况。
  • 建立公共溢出区:再建一个数组,把冲突的元素放进去。

为什么HashMap链表转红黑树的阈值为8呢?

源码的注释也给出了答案:
在这里插入图片描述

这和统计学有关。理想情况下,使用随机哈希码,链表里的节点符合泊松分布,出现节点个数的概率是递减的,节点个数为8的情况,发生概率仅为0.00000006 。至于红黑树转回链表的阈值为什么是6,而不是8呢?这是因为如果这个阈值也设置成8,那么假如发生碰撞,节点增减刚好在8附近,则会发生链表和红黑树的不断转换,导致资源浪费。

**扩容在什么时候呢 **

为了减少哈希冲突发生的概率,当当前HashMap的元素个数达到一个临界值的时候,就会触发扩容,把所有元素rehash之后再放在扩容后的容器中,这是一个相当耗时的操作。

临界值threshold就是由加载因子和当前容器的容量大小来确定的,假如采用默认的构造方法:

临界值(threshold )= 默认容量(DEFAULT_INITIAL_CAPACITY) * 默认扩 容因子(DEFAULT_LOAD_FACTOR)
在这里插入图片描述

那就是大于 16 × 0.75 = 12 16\times 0.75=12 16×0.75=12时,就会触发扩容操作。

为什么选择了0.75作为HashMap的默认加载因子呢?

简单来说,这是对空间成本和时间成本平衡的考虑。

在HashMap中有这样一段注释:
在这里插入图片描述

我们都知道,HashMap的散列构造方式是Hash取余,负载因子决定元素个数达到多少时候扩容。

假如我们设的比较大,元素比较多,空位比较少的时候才扩容,那么发生哈希冲突的概率就增加了,查找的时间成本就增加了。

假设我们设的比较小的话,元素比较少,空位比较多的时候就扩容了,发生哈希碰撞的 概率就降低了,查找时间成本降低,但是就需要更多的空间去存储元素,空间成本就增加了。

总结,主要是在时间成本和空间成本上做的折衷:

  • 如果负载因子太高,确实可以减少空间开销,但会增加查找复杂度(哈希冲突的概率增加,链表上的元素也就越多,查询的效率也就越低);
  • 如果负载因子太低,就会频繁触发 resize 导致 rehash 操作;

具体到底为什么精确到 0.75 这个数值,可以看这篇文章的解释:博客 。

HashMap和Hashtable的区别?

  1. 线程安全:Hashtable方法sychonized修饰,线程安全;
  2. 效率方面:由于Hashtable方法被sychonized修饰,效率比HashMap低;
  3. 底层数据结构:HashMap jdk8当链表长度>8并且数组长度>=64链表会转红黑树,Hashtable没有这样机制;
  4. 初始容量: 默认初始量:Hashtable为11,HashMap为16;若指定初始量: Hashtable用指定的值,HashMap会扩充为2的幂次方大小;
  5. 扩容:Hashtable容量变为原来2n+1倍,HashMap变为2倍;
  6. 对Null key与Null value支持: HashMap支持一个Null key多个Null value,Hashtable不支持Null key 和 Null value,否则报错空指针异常;

HashMap jdk8与jdk7区别?

  • 数据结构:1.7中是数组+链表,1.8中是数组+链表 或 数组 + 链表 + 红黑树。原因:发生哈希冲突,元素会存入链表,链表过长转为红黑树,将时间复杂度由 O(n) 降为 O(logn)。
  • 链表插入方式:1.7是头插法,1.8是尾插法。原因:因为1.7头插法扩容时,头插法会使链表发生反转,多线程环境下会产生环。
  • 扩容rehash:1.7 需要对原数组中的元素进行重新 hash 定位在新数 组的位置,1.8不需要重新通过哈希函数计算位置,新的位置不变或索引 + 旧的数组容量大小。原因:提高扩容的效率,更快地扩容。
  • 扩容时机:1.7是先判断是否需要扩容然后再插入,1.8是先进行插入,插入完成再判断是否需要扩容;
  • 散列函数:1.7 做了四次移位和四次异或,jdk1.8只做一次。原因:做四次的话,边际效用也不大,改为一次,提升效率。

HashMap 是线程安全的吗? 多线程下会有什么问题?

HashMap不是线程安全的,可能会发生这些问题:

  1. 多线程下扩容死循环。JDK1.7 中的 HashMap 使用头插法插入元素,在多线程的环境下,扩容的时候有可能导致环形链表的出现,形成死循环。因此,JDK1.8 使用尾插法插入元素,在扩容时会保持链表元素原本的顺序,不会出现环形链表的问题。
  2. 多线程的 put 可能导致元素的丢失。多线程同时执行 put 操作,如果计算出来的索引位置是相同的,那会造成前一个 key 被后一个 key 覆盖,从而导致元素的丢失。此问题在 JDK 1.7 和 JDK 1.8 中都存在。
  3. put 和 get 并发时,可能导致 get 为 null。线程 1 执行 put 时,因为元素个数超出 threshold 而导致 rehash,线程 2 此时执行 get,有可能导致这个问题。这个问题在 JDK 1.7 和 JDK 1.8 中都存在。

有什么办法能解决HashMap线程不安全的问题呢?

Java 中有 HashTable、Collections.synchronizedMap、以及 ConcurrentHashMap 可以实现线程安全的 Map。

  • HashTable 是直接在操作方法上加 synchronized 关键字,锁住整个table数组,粒度比较大;
  • Collections.synchronizedMap 是使用 Collections 集合工具的内部类,通过传入 Map 封装出一个 SynchronizedMap 对象,内部定义了一个对象锁,方法内通过对象锁实现;
  • ConcurrentHashMap 在jdk1.7中使用分段锁,在jdk1.8中使用CAS+synchronized。

HashMap 内部节点是有序的吗?

HashMap是无序的,根据 hash 值随机插入。如果想使用有序的Map,可以使用 LinkedHashMap 或者 TreeMap。

LinkedHashMap 怎么实现有序的?

LinkedHashMap维护了一个双向链表,有头尾节点,同时 LinkedHashMap 节点 Entry 内部除了继承 HashMap 的 Node 属性,还有 before 和 after 用于标识前置节点和后置节点。可以实现按插入的顺序或访问顺序排序。
在这里插入图片描述

TreeMap 怎么实现有序的?

TreeMap 是按照 Key 的自然顺序或者 Comprator 的顺序进行排序,内部是通过红黑树来实现。所以要么 key 所属的类实现 Comparable 接口,或者自定义一个实现了Comparator 接口的比较器,传给 TreeMap 用于 key 的比较。
在这里插入图片描述

Set

讲讲HashSet的底层实现?

HashSet 底层就是基于 HashMap 实现的。(HashSet的源码非常少,因为除了clone()、writeObject()、readObject()是HashSet自己不得不实现之外,其他方法都是直接调用HashMap中的方法。)

HashSet的add方法,直接调用HashMap的put方法,将添加的元素作为key,new一个 Object作为value,直接调用HashMap的put方法,它会根据返回值是否为空来判断是否插入元素成功。

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

在这里插入图片描述

而在HashMap的putVal方法中,进行了一系列判断,最后的结果是,只有在key在table数组中不存在的时候,才会返回插入的值。

if (e != null) {	// existing mapping for key
    V oldValue = e.value;
    if (!onlyIfAbsent || oldValue == null) {
        e.value = value;
    }
    afterNodeAccess(e);
    return oldValue;
}

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

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

相关文章

JVM基础篇-虚拟机栈

JVM基础篇-虚拟机栈 定义 Java Virtual Machine Stacks &#xff08;Java 虚拟机栈&#xff09; 每个线程运行时所需要的内存&#xff0c;称为虚拟机栈每个栈由多个栈帧&#xff08;Frame&#xff09;组成&#xff0c;对应着每次方法调用时所占用的内存每个线程只能有一个活动…

Spring的创建及使用

文章目录 什么是SpringSpring项目的创建存储Bean对象读取Bean对象getBean()方法 更简单的读取和存储对象的方式路径配置使用类注解存储Bean对象关于五大类注解使用方法注解Bean存储对象Bean重命名 Bean对象的读取 使用Resource注入对象Resource VS Autowired同一类型多个bean对…

QT服务器练习

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间server new QTcpServer(this); }Widget::~Widget() {delete ui; }//启动服务器按钮对…

第1篇:了解Matter物模型翻译器

第1篇&#xff1a;了解Matter物模型翻译器 1. Matter物模型简介2. 物模型翻译成编程语言3. 思考题 1. Matter物模型简介 Matter物模型的介绍可以参考: Matter Core Specification的第7章 Matter物模型直观展示&#xff0c;可以看下图1-1&#xff0c; Matter Dimmable Light的…

【Linux】7、D-Bus 消息总线系统

文章目录 d-bus 官网 d-bus详解 D-Bus 是一种消息总线系统&#xff0c;是应用程序相互通信的一种简单方法。除了进程间通信之外&#xff0c;D-Bus 还有助于协调进程生命周期; 它使得编写“单实例”应用程序或守护进程以及在需要应用程序和守护进程的服务时按需启动它们变得简…

【学习笔记】关于RAW图片的概念学习

这里是尼德兰的喵芯片设计相关文章&#xff0c;欢迎您的访问&#xff01; 如果文章对您有所帮助&#xff0c;期待您的点赞收藏&#xff01; 让我们一起为成为芯片前端全栈工程师而努力&#xff01; 前言 能为我介绍一下raw图片吗&#xff1f; 当谈论"Raw图片"时&am…

c++ ,vs2019, cpp20规范之 forward_list 源码分析

通过阅读源码可知&#xff0c;该单向链表不像list双向链表那样有专门的前导节点。即list._Mypair._Myval2._head._next才指向第一个有效数据节点。而 forward_list ._Mypair._Myval2._head 已经指向了有效数据节点。原因就在于复杂巧妙的类型转换。如下图的构造函数里&#xff…

C语言实现定时器,定时触发函数

最近想到使用C语言实现一个简单的定时器。使用操作系统windows.h提供的多线程API就能实现 首先定义一个定时器结构体&#xff0c;包含定时时间和触发的函数指针 typedef struct Stimer{int valid;//定时器有效long timingMS;//定时时间TriggerFunc tf;//触发函数 }Stimer;创建…

python下的control库使用

文章目录 control的官方网站函数示例强迫响应forced_response control的官方网站 函数示例 强迫响应forced_response import numpy as np import os import sys import control as ctrl import matplotlib.pyplot as pltdef lim_x(x, lim0):res 0if x > lim:res 1else:…

qt代码练习

计时器练习 namespace Ui { class third; }class third : public QWidget {Q_OBJECTpublic:explicit third(QWidget *parent nullptr);~third();QLabel *labth1 new QLabel(this);QTextEdit *txtth1 new QTextEdit("闹钟",this);QLineEdit *leth1 new QLineEdit(t…

Stable Diffusion:网页版 体验 / AI 绘图

一、官网地址 Stable Diffusion Online 二、Stable Diffusion AI 能做什么 Stable Diffusion AI绘图是一种基于Stable Diffusion模型的生成式AI技术&#xff0c;能够生成各种类型的图像&#xff0c;包括数字艺术、照片增强和图像修复等。以下是一些可能的应用&#xff1a; …

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(13)-Fiddler请求和响应断点调试

1.简介 Fiddler有个强大的功能&#xff0c;可以修改发送到服务器的数据包&#xff0c;但是修改前需要拦截&#xff0c;即设置断点。设置断点后&#xff0c;开始拦截接下来所有网页&#xff0c;直到取消断点。这个功能可以在数据包发送之前&#xff0c;修改请求参数&#xff1b…

【wsl-windows子系统】安装、启用、禁用以及同时支持docker-desktop和vmware方案

如果你要用docker桌面版&#xff0c;很可能会用到wsl&#xff0c;如果没配置好&#xff0c;很可能wsl镜像会占用C盘很多空间。 前提用管理员身份执行 wsl-windows子系统安装和启用 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper…

什么是DOTS?

(图片为实机测试) DOTS全称&#xff1a;&#xff08;Burst Job SystemEntity Component System&#xff09; 新型高性能、多线程面向数据的技术堆栈 是由&#xff1a;BrustJob System ECS组合而成&#xff0c;是一种面向数据对象的编程体系&#xff0c;在unity中您也可以对…

机器学习-Gradient Descent

机器学习(Gradient Descent) videopptblog 梯度下降(Gradient Descent) optimization problem: 损失函数最小化 假设本模型有两个参数&#x1d703;1和&#x1d703;2&#xff0c;随机取得初始值 求解偏微分&#xff0c;梯度下降对参数进行更新 Visualize: 确定梯度方向&…

学习使用axios,绑定动态数据

目录 axios特性 案例一&#xff1a;通过axios获取笑话 案例二&#xff1a;调用城市天气api接口数据实现天气查询案例 axios特性 支持 Promise API 拦截请求和响应&#xff08;可以在请求前及响应前做某些操作&#xff0c;例如&#xff0c;在请求前想要在这个请求头中加一些…

leetcode 1372. 二叉树中的最长交错路径

给你一棵以 root 为根的二叉树&#xff0c;二叉树中的交错路径定义如下&#xff1a; 选择二叉树中 任意 节点和一个方向&#xff08;左或者右&#xff09;。 如果前进方向为右&#xff0c;那么移动到当前节点的的右子节点&#xff0c;否则移动到它的左子节点。 改变前进方向&a…

IIS创建网站报错 \\?\C:\Windows\inetsrv\config\applicationHost.config

现象&#xff1a; IIS创建不了网站&#xff0c;IIS配置没有发生改变 原因&#xff1a; 服务器C盘无空间&#xff0c;释放空间后问题解决。

Java-day03(程序流程控制)

程序流程控制 1.顺序结构 程序从上至下逐行执行&#xff0c;无判断与跳转 public class Test1{ public static void main(String[] args){int i 1;int j i 1; System.out.println(j);} }2.分支结构 依据条件&#xff0c;选择性执行某段语句 主要有以下两种 2.1 i…

计算机毕设 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长…