0X JavaSE-- 集合框架【Collection(List、Set、Queue)、Map】

news2024/11/16 1:18:01
  • 每一个集合类底层采用的数据结构不同,例如ArrayList集合底层采用了数组,LinkedList集合底层采用了双向链表,HashMap集合底层采用了哈希表,TreeMap集合底层采用了红黑树。
  • **集合中存储的是引用。**即。集合中存放的是对象的地址,而不是把堆中的实例对象存储。
  • 默认情况下,如果不使用泛型的话,集合中可以存储任何类型的引用,只要是 Object 的子类都可以存储。
  • Java集合框架相关的类都在 java.util 包下。
  • Java 集合框架有两大支线:
    • Collection,可进一步细分为
      • List:可重复的集合。具体实现有: ArrayList(动态数组)LinkedList(双向链表)
      • Set:不可重复的集合,典型代表就是 HashSet(哈希表)TreeSet(红黑树)
      • Queue:队列。具体实现有:双端队列 ArrayDeque,以及优先级队列 PriorityQueue
    • Map:键值对的集合。具体实现有: HashMapLinkedHashMap(双向链表 + 哈希表)
  • 这些具体实现中,只有 TreeSet、LinkedHashMap 是有序的(键有序

Collection

1、List

List 的特点是存取有序,可以存放重复的元素,可以用下标对元素进行操作。

1.1 ArrayList

  • ArrayList 是由数组实现的,支持随机存取,也就是可以通过下标直接存取元素;
  • 从尾部插入和删除元素会比较快捷,从中间插入和删除元素会比较低效,这是由数组的特点决定的;
  • 如果内部数组的容量不足时会自动扩容,因此当元素非常庞大的时候,效率会比较低。

1.2 LinkedList

  • LinkedList 是由双向链表实现的,不支持随机存取,只能从一端开始遍历,直到找到需要的元素后返回;
  • 任意位置插入和删除元素都很方便,因为只需要改变前一个节点和后一个节点的引用即可,不像 ArrayList 那样需要复制和移动数组元素,这是由链表的特点决定的;
  • 因为每个元素都存储了前一个和后一个节点的引用,所以相对来说,占用的内存空间会比 ArrayList 多一些。
// CRUD 实例
// 创建一个集合
LinkedList<String> list = new LinkedList<String>();
// 添加元素
list.add("apple");
list.add("avocado");

// 遍历集合 for 循环
for (int i = 0; i < list.size(); i++) {
    String s = list.get(i);
    System.out.println(s);
}
// 遍历集合 for each
for (String s : list) {
    System.out.println(s);
}

// 删除元素
list.remove(1);
// 遍历集合
for (String s : list) {
    System.out.println(s);
}

// 修改元素
list.set(1, "apricot");

1.3 ArrayList 和 LinkedList

通常,我们总是优先使用 ArrayList。
在这里插入图片描述

1.4 Vector 和 Stack

List 的实现类还有一个 Vector,是一个元老级的类,比 ArrayList 出现得更早。

ArrayList 和 Vector 非常相似,只不过 Vector 是线程安全的,像 get、set、add 这些方法都加了 synchronized 关键字,就导致执行效率会比较低,所以现在已经很少用了。
这种加了同步方法的类,注定会被淘汰掉,就像StringBuilder 取代 StringBuffer那样。

Stack 是 Vector 的一个子类,本质上也是由动态数组实现的,只不过还实现了先进后出的功能(在 get、set、add 方法的基础上追加了 pop「返回并移除栈顶的元素」、peek「只返回栈顶元素」等方法),所以叫栈。
由于 Stack 执行效率比较低(方法上同样加了 synchronized 关键字),就被双端队列 ArrayDeque 取代了(下面会介绍)。

1.5 List 接口 的 API

List 接口继承自 Collection。自然,Collection 定义的 API,List 也有。

以下给出 List 特有的 API:

void add​(int index, E element) 在指定索引处插入元素

E set​(int index, E element); 修改索引处的元素

E get​(int index); 根据索引获取元素(通过这个方法List集合具有自己特殊的遍历方式:根据下标遍历)

E remove​(int index); 删除索引处的元素

int indexOf​(Object o); 获取对象o在当前集合中第一次出现时的索引。

int lastIndexOf​(Object o); 获取对象o在当前集合中最后一次出现时的索引。

List<E> subList​(int fromIndex, int toIndex); 截取子List集合生成一个新集合(对原集合无影响)。[fromIndex, toIndex)

static List<E> of​(E... elements); 静态方法,返回包含任意数量元素的不可修改列表。(获取的集合是只读的,不可修改的。)

2、Set

3、Queue

3.1 ArrayDeque

ArrayDeque 是一个基于数组实现的双端队列,为了满足可以同时在数组两端插入或删除元素的需求,数组必须是循环的,也就是说数组的任何一点都可以被看作是起点或者终点。

3.2 LinkedList

LinkedList 一般应该归在 List 下,只不过,它也实现了 Deque 接口,可以作为队列来使用。

实际上,LinkedList 同时实现了 Stack、Queue、PriorityQueue 的所有功能。

// 演示 LinkedList 的队列特性
LinkedList<String> queue = new LinkedList<>();

// 区别于 add, offer元素用于向队尾添加元素
queue.offer("apple");
queue.offer("avocado");
System.out.println(queue); // 输出 [apple, avocado]

// 删除元素
queue.poll();
System.out.println(queue); // 输出 [avocado]

// 修改元素:LinkedList 中的元素不支持直接修改,需要先删除再添加
String first = queue.poll();
queue.offer("apple");
System.out.println(queue); // 输出 [apple]

// 查找元素:既可以查找下标,也可以查找内容
System.out.println(queue.get(0)); // 输出 apple
System.out.println(queue.contains("apricot")); // 输出 false

// 查找元素:使用迭代器的方式查找陈清扬
// 使用迭代器依次遍历元素并查找
Iterator<String> iterator = queue.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    if (element.equals("apple")) {
        System.out.println("找到了:" + element);
        break;
    }
}
3.2.1 add–remove / offer–poll

LinkedList 同时实现了 List 和 Deque(双端队列)接口,因此,其同时拥有两组插入/删除的方法:

  • add–remove:List 接口中定义的方法
    • 在 LinkedList 实例的尾部进行插入和删除
  • offer–poll:Deque 接口中定义的方法
    • 在 LinkedList 实例的尾部进行插入,头部进行删除(即队列的特征)

3.3 ArrayDeque 和 LinkedList

LinkedList 和 ArrayDeque 都是 Java 集合框架中的双向队列(deque),它们都支持在队列的两端进行元素的插入和删除操作。

不过,LinkedList 和 ArrayDeque 在实现上有一些不同:

  • 底层实现方式不同:LinkedList 是基于链表实现的,而 ArrayDeque 是基于数组实现的。
  • 随机访问的效率不同:由于底层实现方式的不同,LinkedList 对于随机访问的效率较低,时间复杂度为 O(n),而 ArrayDeque 可以通过下标随机访问元素,时间复杂度为 O(1)。
  • 迭代器的效率不同:LinkedList 对于迭代器的效率比较低,因为需要通过链表进行遍历,时间复杂度为 O(n),而 ArrayDeque 的迭代器效率比较高,因为可以直接访问数组中的元素,时间复杂度为 O(1)。
  • 内存占用不同:由于 LinkedList 是基于链表实现的,它在存储元素时需要额外的空间来存储链表节点,因此内存占用相对较高,而 ArrayDeque 是基于数组实现的,内存占用相对较低。
  • 如何选择?
    • 如果需要在双向队列的两端进行频繁的插入和删除操作,并且需要随机访问元素,可以考虑使用 ArrayDeque;
    • 如果需要在队列中间进行频繁的插入和删除操作,可以考虑使用 LinkedList。‘

3.4 PriorityQueue

PriorityQueue 是一种优先级队列,它的出队顺序与元素的优先级有关,执行 remove 或者 poll 方法,返回的总是优先级最高的元素。

4、Collection 接口的 API

Collection 接口中定义了如下 API。自然,所有实现了 Collection 接口的类(List、Set、Queue)都能使用这些方法。

boolean add(E e);			向集合中添加元素
int size();					获取集合中元素个数
boolean addAll(Collection c);	将参数集合中所有元素全部加入当前集合
boolean contains(Object o);	判断集合中是否包含对象o
boolean remove(Object o);		从集合中删除对象o
void clear();				清空集合
boolean isEmpty();			判断集合中元素个数是否为0
Object[] toArray();			将集合转换成一维数组

SequencedCollection 接口

  • 所有的有序集合都实现了 SequencedCollection 接口。
  • SequencedCollection 接口是 JDK21 版本新增的。
SequencedCollection接口中的方法:
void addFirst(Object o):向头部添加
void addLast(Object o):向末尾添加
Object removeFirst():删除头部
Object removeLast():删除末尾
Object getFirst():获取头部节点
Object getLast():获取末尾节点
SequencedCollection reversed(); 反转集合中的元素
ArrayListLinkedListVectorLinkedHashSetTreeSet,Stack 都可以调用这个接口中的方法。

5、遍历 Collection

  • 获取当前集合依赖的迭代器对象
Iterator it = collection.iterator();
  • 编写循环,循环条件是:当前光标指向的位置是否存在元素。
while(it.hasNext()){}
  • 如果有,将光标指向的当前元素返回,并且将光标向下移动一位。
Object obj = it.next();

6、删除 Collection 元素

使用 remove 方法删除 Collection 元素时:

  • 不得使用集合对象.remove(元素)。因为可能导致 ConcurrentModificationException 异常。
  • 应使用迭代器对象.remove(元素)

本质是潜在的线程冲突。

fail-fast 机制

假设有两个线程:A 和 B。A 线程负责迭代遍历集合,B 线程使用集合对象.remove(元素)删除集合中的某个元素。
当这两个线程同时执行时,我们无法预知 A 线程遍历的结果。

  • 因此,集合框架使用 fail-fast 快速失败机制,避免这种情况发生。

    • 只要程序发现了程序对集合进行了并发修改。就会立即让其失败,以防出现错误。
    • 该机制在数据量少的时候,可能并不会触发。
  • fail-fast 机制的实现原理,以上述代码为例

    • 集合中设置了一个 modCount 属性,用来记录修改次数。
    • 迭代器中设置了一个 expectedModCount 属性,用来记录预期的修改次数。当获取一个迭代器对象时,构造器会将迭代器对象中的 expectedModCount 属性初始化为 modCount 的值,即:int expectedModCount = modCount 。
    • 使用集合对象执行增\删\改任意一个操作时,modCount 自动加 1。;使用迭代器执行增\删\改任意一个操作时,modCount 和 expectedModCount 同时加1。
    • 当任意时刻检测到 modCount != expectedModCount 时,抛出 ConcurrentModificationException 异常。

实例

// 以下程序会抛出 ConcurrentModificationException 异常
     ArrayList<String> namesList = new ArrayList<>();

        namesList.add("zhangsan");
        namesList.add("lisi");
        namesList.add("wangwu");
        namesList.add("zhaoliu");

        Iterator<String> it = namesList.iterator();
        while (it.hasNext()) {
            String name = it.next();
            if ("lisi".equals(name)) {
                namesList.remove(name);
            }
            System.out.println(name);
        }

对于以上代码执行的描述:

  1. 当使用集合对象删除lisi时:modCount 加1,但是迭代器 expectedModCount 不会加 1。
  2. 进入下一轮循环,当迭代器对象的 next() 方法执行时,会检测 expectedModCount 和 modCount 是否相等,如果不相等,则抛出:ConcurrentModificationException 异常,程序终止
			  // 将删除元素的方式改成用迭代器删除,程序正常运行.	
               it.remove(); // 使用迭代器的 remove 方法

对于以上代码执行的描述:

  1. 当使用迭代器删除元素的时候:modCount 和 expectedModCount 同时加1。
  2. 下一次循环时,当迭代器对象的 next() 方法执行时,检测到 expectedModCount = modCount,则不会出现 ConcurrentModificationException 异常。

注意:虽然我们当前写的程序是单线程的程序,并没有使用多线程,但是通过迭代器去遍历的同时使用集合去删除元素,这个行为将被认定为并发修改。


Map

  • Map 保存的是键值对,键要求保持唯一性,值可以重复。
  • Map 接口的常见实现类有两个:
    • HashMap
    • TreeMap

1. HashMap

  • HashMap 可以根据快速地查找对应的值——通过哈希函数将键映射到哈希表中的一个索引位置,从而实现快速访问。
  • HashMap 中的键和值都可以为 null。如果键为 null,则将该键映射到哈希表的第一个位置。
  • 可以使用迭代器或者 forEach 方法遍历 HashMap 中的键值对。
  • HashMap 有一个初始容量和一个负载因子。初始容量是指哈希表的初始大小,负载因子是指哈希表在扩容之前可以存储的键值对数量与哈希表大小的比率。默认的初始容量是 16,负载因子是 0.75。
// HashMap 实例
HashMap<String, String> hashMap = new HashMap<>();

// 添加键值对
hashMap.put("苹果", "apple");
hashMap.put("牛油果", "avocado");
hashMap.put("香蕉","Banana");

// 遍历 HashMap
for (String key : hashMap.keySet()) {
    String value = hashMap.get(key);
    System.out.println(key + " 对应的值为:" + value);
}
// HashMap 中,键的顺序是根据键的哈希码计算结果来决定的,因此,不保证有序
// 输出为 苹果-- 香蕉--牛油果

// 获取指定键的值
String value1 = hashMap.get("苹果");
System.out.println("苹果对应的值为:" + value1);

// 修改键对应的值
hashMap.put("苹果", "apple1");
String value2 = hashMap.get("苹果");
System.out.println("修改后苹果对应的值为:" + value2);

// 删除指定键的键值对
hashMap.remove("牛油果");

2. LinkedHashMap

  • LinkedHashMap 是 HashMap 的子类,。也就是说,只要是 LinkedHashMap ,那么必然也是一个 HashMap。
  • LinkedHashMap 可以看作是 HashMap + LinkedList 的合体。它使用哈希表来存储数据;使用双向链表来记录插入/访问元素的顺序,维持顺序。
  • 这里的顺序,指的是维持插入的顺序。
// LinkedHashMap 实例
LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("苹果", "apple");
linkedHashMap.put("牛油果", "avocado");
linkedHashMap.put("香蕉","Banana");

// 遍历 LinkedHashMap
for (String key : linkedHashMap.keySet()) {
    String value = linkedHashMap.get(key);
    System.out.println(key + " 对应的值为:" + value);
}
// linkedHashMap 保证顺序,输出为 苹果--牛油果--香蕉,可对比 HashMap 的无序

3. TreeMap

  • TreeMap 实现了 SortedMap 接口,可以自动将键按照自然顺序或指定的比较器顺序排序,并保证其元素的顺序。
  • 内部使用红黑树来实现键的排序和查找。
  • 这里的顺序,指的是以键值为依据,按照某种规则排序。
// TreeMap 实例
Map<String, String> treeMap = new TreeMap<>();

// 向 TreeMap 中添加键值对
treeMap.put("c", "cat");
treeMap.put("a", "apple");
treeMap.put("b", "banana");

// 遍历 TreeMap
for (Map.Entry<String, String> entry : treeMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 按照默认顺序对键进行了排序,输出是 a--b--c

// 查找键值对
String name = "c";
if (treeMap.containsKey(name)) {
    System.out.println("找到了 " + name + ": " + treeMap.get(name));// 输出 c:cat
} 

// 修改键值对
name = "a";
if (treeMap.containsKey(name)) {
    System.out.println("修改前的 " + name + ": " + treeMap.get(name));// 输出 a:apple
    treeMap.put(name, "aovcado");
    System.out.println("修改后的 " + name + ": " + treeMap.get(name));// 输出 a:aovcado
} 

// 删除键值对
name = "b";
if (treeMap.containsKey(name)) {
    System.out.println("删除前的 " + name + ": " + treeMap.get(name));
    treeMap.remove(name);
    System.out.println("删除后的 " + name + ": " + treeMap.get(name));// 输出 b:null
} 

ArrayList

  • ArrayList 和 HashMap,算是最常用的两个集合框架实现。
  • ArrayList 基于数组实现了 List 接口。
  • Java 原生数组的大小是固定的,但 ArrayList 提供了自动扩容,它可以看作“可变长度”的数组,因此用起来比数组更方便。
  • 实际上 ArrayList 内部就是一个 Object[] 数组,配合一个变量记录当前分配空间,就可以充当“可变数组”
  • 需要频繁的检索元素,并且很少的进行随机增删元素时使用 ArrayList。

Constructor

// 使用无参数构造器创建 ArrayList,并提前指定泛型为 String
ArrayList<String> list = new ArrayList<>();

// 使用无参数构造器创建 ArrayList,将泛型留给调用者确认类型
ArrayList<E> list = new ArrayList<>();

// 尽管会自动扩容,但仍可以使用带有固定容量参数创建 ArrayList
ArrayList<String> list1 = new ArrayList<>(int capacity);

// 使用带有集合参数的构造器创建 ArrayList
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));

// 运用多态。由于 ArrayList 实现了 List 接口,所以 list 变量的类型可以是 List 类型
List<String> list = new ArrayList<>();

API

// E,即泛型,即可以传入任何引用类型。
boolean add(E e);// 添加元素到列表末尾

void add(int index, E element);// 在指定位置插入元素

E get(int index);// 获取指定位置的元素

E set(int index, E element);// 修改指定位置的元素

E remove(int index);// 移除指定位置的元素

boolean remove(Object o);// 移除首次出现的指定元素

void clear();// 清空列表

int size();// 获取列表的大小

boolean isEmpty();// 检查列表是否为空

boolean contains(Object o);// 检查列表是否包含某个元素

int indexOf(Object o);// 获取某个元素第一次出现的索引

int lastIndexOf(Object o);// 获取某个元素最后一次出现的索引

boolean addAll(Collection<? extends E> c);// 添加一个集合中的所有元素到列表末尾

boolean addAll(int index, Collection<? extends E> c);// 在指定位置插入一个集合中的所有元素

boolean removeAll(Collection<?> c);// 从列表中移除指定集合中包含的所有元素

boolean retainAll(Collection<?> c);// 仅保留列表中包含在指定集合中的元素

Object[] toArray();// 将列表转换为数组

<T> T[] toArray(T[] a);// 将列表转换为指定类型的数组

Iterator<E> iterator();// 获取列表的迭代器

ListIterator<E> listIterator();// 获取列表的列表迭代器(从开始处)

ListIterator<E> listIterator(int index);// 获取列表的列表迭代器(从指定位置开始)

void sort(Comparator<? super E> c);// 使用自然顺序对列表进行排序

void replaceAll(UnaryOperator<E> operator);// 用新值替换列表中所有旧值

源码解读

add

// 堆栈过程示意:
add(element)
└── if (size == elementData.length) // 判断是否需要扩容。elementData 是实际存储元素的数组。
    ├── grow(minCapacity) // 扩容
    │   └── newCapacity = oldCapacity + (oldCapacity >> 1) // 新数组容量 = 老数组容量 + 老数组容量的一半
    │   └── Arrays.copyOf(elementData, newCapacity) // 将老数组
    ├── elementData[size++] = element; // 添加新元素
    └── return true; // 添加成功

add 方法源码如下:

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // 确保 ArrayList 能够容纳新的元素
    // 在 ArrayList 的末尾添加指定元素。ArrayList 底层就是一个叫 elementData 的数组
    elementData[size++] = e;return true;
}

add 方法非常简洁,主要代码被封装于静态方法 ensureCapacityInternal 中。

/**
 * 确保 ArrayList 能够容纳指定容量的元素
 * @param minCapacity 指定容量的最小值
 */
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // 如果 elementData 还是默认的空数组
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 使用 DEFAULT_CAPACITY 和指定容量的最小值中的较大值
    }
    ensureExplicitCapacity(minCapacity); // 确保容量能够容纳指定容量的元素
}

ensureExplicitCapacity 方法的作用是:确保 ArrayList 内部数组有足够的容量来存储新添加的元素。如果容量不足,它会增加内部数组的大小。

调用的顺序是:add --> ensureCapacityInternal --> ensureExplicitCapacity,以下分析二者的不同:

  • ensureCapacityInternal 用于计算初始容量。在指定容量和默认容量 10 之间取更大者,作为初始容量,然后将这个初始容量参数传入 ensureExplicitCapacity。
  • ensureExplicitCapacity 来实际执行容量检查和扩容。当容量不足时,调用 grow 方法进行扩容。

LinkedList

Map

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

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

相关文章

【学习】DCMM认证提升企业竞争优势的表现

DCMM认证是企业提升数据管理能力的重要途径。它不仅可以帮助企业评估自身的数据管理水平&#xff0c;还可以为企业提供改进的方向和目标。在数字化时代&#xff0c;拥有强大的数据管理能力是企业成功的关键。因此&#xff0c;通过DCMM认证&#xff0c;企业可以更好地适应数字化…

【iOS】UI——关于UIAlertController类

目录 前言关于UIAlertController具体操作及代码实现总结 前言 在UI学习中&#xff0c;我们发现UIAlertView在iOS 9中已经被废弃&#xff0c;我们找到UIAlertController来代替UIAlertView实现弹出框的功能&#xff0c;从而有了这篇关于UIAlertController的学习笔记。 关于UIAle…

基于websocket与node搭建简易聊天室

一、前言 上一篇文章介绍了websocket的详细用法与工具类的封装&#xff0c;本篇就基于websocket搭建一个简易实时的聊天室。 在本篇开始之前也可以去回顾一下websocket详细用法&#xff1a;WebSocket详解与封装工具类 二、基于node搭建后台websocket服务 首先确认本机电脑中…

手机录屏怎么没有声音?一键排查,轻松解决!

“手机录屏怎么没有声音&#xff1f;今天录制了一个线上的音乐会&#xff0c;结束的时候发现完全没有声音&#xff0c;我检查了手机的设置&#xff0c;录屏功能看起来是正常的&#xff0c;但为什么就是录不到声音呢&#xff1f;希望大家能帮我解答这个疑惑。” 随着智能手机的…

linux上VirtualBox使用

前言 最近想把唯一的windows系统装成linux&#xff0c; 但是确实存在一些特殊软件无法舍弃&#xff0c;所有装完linux需要用虚拟机装个windows 上来使用特定的一些软件&#xff08;不想用wine了&#xff09;。 还有对一些特定usb设备的透传&#xff0c;这样才能保证在虚拟机中…

数据库开发-Mysql03

目录 1. 多表查询 1.1 概述 1.1.1 数据准备 1.1.2 介绍 1.1.3 分类 1.2 内连接 1.3 外连接 1.4 子查询 1.4.1 介绍 1.4.2 标量子查询 1.4.3 列子查询 1.4.4 行子查询 1.4.5 表子查询 1.5 案例 2. 事务 2.1 介绍 2.2 操作 2.3 四大特性 3. 索引 3.1 介绍 3…

雷士大路灯有必要买吗?雷士、书客、孩视宝护眼落地灯实测PK!

面对市面上众多的护眼大路灯品牌&#xff0c;其中雷士、书客和孩视宝这几款大路灯受到了广泛的青睐&#xff0c;也是热度比较高的几款产品&#xff0c;正是因为这么多款大路灯&#xff0c;很多伙伴在看到文章推荐后很纠结&#xff0c;不知道如何选择&#xff0c;也有一部分伙伴…

【猫狗识别系统】图像识别Python+TensorFlow+卷积神经网络算法+人工智能深度学习

猫狗识别系统。通过TensorFlow搭建MobileNetV2轻量级卷积神经算法网络模型&#xff0c;通过对猫狗的图片数据集进行训练&#xff0c;得到一个进度较高的H5格式的模型文件。然后使用Django框架搭建了一个Web网页端可视化操作界面。实现用户上传一张图片识别其名称。 一、前言 …

RK3568技术笔记之一 RK3568总体介绍

RK3568是瑞芯微开发出一款很好用的芯片。我先把ROCKCHIP的原厂信息搬过来看看。 首先声明一下&#xff0c;这篇文章里的资讯版权归瑞芯微电子股份有限公司。毕竟是我转过来的嘛。 我自己的心得&#xff0c;版权就归我啦。 搬砖地址Rockchip-瑞芯微电子股份有限公司瑞芯微专注…

day34--Spring(三)

一、AOP 1 AOP简介 问题导入 问题1&#xff1a;AOP的作用是什么&#xff1f; 问题2&#xff1a;连接点和切入点有什么区别&#xff0c;二者谁的范围大&#xff1f; 问题3&#xff1a;请描述什么是切面&#xff1f; 1.1 AOP简介和作用【理解】 AOP(Aspect Oriented Progr…

TSINGSEE青犀视频汇聚机房动环智能监控方案,提升机房安全稳定性

一、背景需求 在当今信息化时代&#xff0c;机房作为数据中心的核心设施&#xff0c;承载着重要的网络设备和数据存储设备&#xff0c;其正常运行对于企业的数据安全和业务连续性至关重要。机房内部设备众多&#xff0c;且运行过程中涉及大量的数据交换和传输。一旦发生安全事…

合并多个h5文件

如图&#xff0c;bbt_frames下有多个视频文件夹&#xff0c;每个文件夹包括多个h5文件&#xff0c;将每个文件夹的h5文件合并成一个h5文件&#xff0c;并以该文件夹命名&#xff0c;存储至video_feature文件夹。 import os import h5py import numpy as npdef merge_h5_files(…

《深入浅出存储引擎》不同数据库背后的数据存储方案

在大数据和AI时代&#xff0c;数据库成为各类应用不可或缺的重要组成部分。而数据库中的数据依赖存储引擎进行管理&#xff0c;包括数据的存储、查询、更新和删除等。因此&#xff0c;在设计系统时&#xff0c;选择正确的数据库存储引擎方案变得尤为重要。这篇文章将以关系型、…

4.5-24V48V60V72V80V降压12V 0.5A 电动车车充USB充电方案芯片IC-H6601

H6601 降压开关转换器是一款为电动车USB充电设计的芯片。这款芯片内置功率MOSFET&#xff0c;具备宽输入工作电压范围&#xff08;4.5V 至 60V&#xff09;&#xff0c;能够持续输出电流0.5A&#xff0c;并且具有良好的负载和线性调整率。 电流控制模式使环路易稳定&#xff0c…

测试工具fio

一、安装部署 fio是一款优秀的磁盘IO测试工具&#xff0c;在Linux中比较常用于测试磁盘IO 其下载地址&#xff1a;https://brick.kernel.dk/snaps/fio-2.1.10.tar.gz 或者登录其官网&#xff1a;http://freshmeat.sourceforge.net/projects/fio/ 进行下载。 tar -zxvf fio-…

SpringBoot整合Skywalking

下载Java Agent 官网&#xff1a;https://skywalking.apache.org/downloads/ 提示&#xff1a;Agent最好到网上找一找之前的版本&#xff0c;新版本可能有bug&#xff0c;如果出现了并且网上也几乎没有这个版本的解决方法那么就切换之前的版本 本地启动时 -javaagent:d:\opt\…

ABB码垛机器人IRB260通讯板维修

ABB码垛机器人在现代制造业中发挥着重要作用&#xff0c;而机器人通讯板维修对于确保机器人的正常运行至关重要。 通讯板是ABB码垛机器人与控制系统之间进行数据传输的桥梁。它负责接收控制系统的指令&#xff0c;并将机器人的运行数据反馈给控制系统。如果通讯板出现故障&…

郑州永兴牌饲料机械设备厂家

作为专注生产饲料机械设备厂家&#xff0c;郑州永兴不仅拥有完善的生产线和制造工艺&#xff0c;更在技术创新和产品研发方面走在了行业前列。 郑州永兴深知饲料机械设备对于饲料生产的重要性&#xff0c;因此始终坚持以市场需求为导向&#xff0c;不断推陈出新。其生产的饲…

黄金票据~

一. 黄金票据原理 黄金票据一般是伪造的TGT,生成这个TGT&#xff0c;不需要和KDC进行校验&#xff0c;金票可以在本地直接生成&#xff0c;生成的的金票在非域机器和域内机器都可以使用 黄金票据的作用&#xff1a; 可以用来权限维持 可以用来横向移动二. 利用条件 1. 必须…

Docker-compose 编排lnmp(dockerfile) 完成Wordpress

一、部署 Nginx 镜像 1. 建立工作目录 mkdir /opt/lnmp/nginx -pcd /opt/lnmp/nginx#上传 nginx 安装包 nginx-1.12.0.tar.gz#上传 wordpress 服务包 wordpress-4.9.4-zh_CN.tar.gz mkdir /opt/lnmp/nginx/htmltar zxvf wordpress-4.9.4-zh_CN.tar.gz -C /opt/lnmp/nginx/html…