第十五天

集合框架

1.什么是集合 Collections

集合Collection,也是一个数据容器,类似于数组,但是和数组是不一样的。集合是一个可变的容器,可以随时向集合中添加元素,也可以随时从集合中删除元素。另外,集合还提供了若干个用来操作集合中数据的方法。

集合里的数据,我们称之为元素(elements);集合只能用来存储引用类型的数据不能存储八大基本**数据类型的数据**。

Java SE 5.0以前,集合的元素只要是Object类型就行,那个时候任何对象都可以存放在集合内,但是从集合中获取对象后,需要进行正确的强制类型转换。但是,Java SE 5.0 以后,可以使用新特性”泛型”,用来指定要存放在集合中的对象类型。避免了强制转换的麻烦

2.集合与数组

  1. 数组是定长的容器,一旦实例化完成,长度不能改变。集合是变长的,可以随时的进行增删操作。

  2. 数组中可以存储基本数据类型和引用数据类型的元素,集合中只能存储引用数据类型的元素。

  3. 数组的操作比较单一,只能通过下标进行访问。集合中提供了若干个方便对元素进行操作的方法。

3.集合框架体系图

父接口Collection

Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义了他们三个子接口的共同方法。既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。作为父接口,其子类集合的对象,存储元素的特点,可能是无序的,也可能是有序的,因此在父接口中并没有定义通过下标获取元素的方法功能。

// 1、实例化一个  ArrayList 对象,并向上转型为  Collection 类型。 
//    向上转型后的对象,只能访问父类或者接口中的成员
//    在这里,collection 将只能够访问  Collection 接口中的成员。
Collection<String> collection = new ArrayList<>();
​
// 2、向集合中添加元素
collection.add("lily");
collection.add("lucy");
collection.add("Uncle wang");
collection.add("Polly");
​
// 3、向集合中批量的添加元素(将一个集合中的元素依次添加到这个集合中)
collection.addAll(collection);
// 4、删除从前往后第一个匹配的元素
collection.remove("lily");
​
// 5、准备另外一个集合
Collection<String> list = new ArrayList<>();
list.add("Han Meimei");
list.add("Li Lei");
list.add("Uncle wang");
list.add("Polly");
​
// 6、删除所有的在另外一个集合中存在的元素
//   删除逻辑:遍历集合,将每一个元素带入到参数集合中判断是否存在,如果存在,就删除这个元素。
//删除的是list中的集合元素
collection.removeAll(list);
​
// 7、删除所有的满足条件的元素
//   删除逻辑:遍历集合,将每一个元素带入到参数方法中,如果返回值是true,需要删除这个元素。
collection.removeIf(ele -> ele.startsWith("lu"));
​
// 8、清空所有
collection.clear();
​
// 9、保留在另外一个集合中存在的元素
//   逻辑:遍历集合,将每一个元素带入到参数集合中,判断是否存在,如果存在则保留这个元素,如果 不存在,删除
collection.retainAll(list);
​
// 10、判断集合中是否包含指定的元素
boolean ret = collection.contains("Uncle wang");
System.out.println(ret);
​
// 11、判断参数集合中的每一个元素是否都在当前集合中包含
boolean ret1 = collection.containsAll(list);
System.out.println(ret1);
​
// 12、判断两个集合是否相同(依次比较两个集合中的每一个元素,判断是否完全相同) 
//    只有当两个集合中的元素数量、元素一一对应
boolean ret2 = collection.equals(list);
System.out.println(ret2);
​
// 13、判断一个集合是否为空
boolean ret3 = collection.isEmpty();
System.out.println(ret3);
​
// 14、获取一个集合中元素的数量,类似于数组长度
int size = collection.size();
System.out.println(size);
​
// 15、转成  Object 数组
Object[] array = collection.toArray();
System.out.println(Arrays.toString(array));
​
// 16、转成指定类型的数组
String[] arr = collection.toArray(new String[0]);
System.out.println(Arrays.toString(arr));
​
System.out.println(collection);

1.集合的迭代

在进行集合的遍历的时候,方式其实很多。但是,基本上所有的遍历,都与 Iterable 接口有关。这个接 口提供了对集合进行迭代的方法。只有实现了这个接口,才可以使用增强for循环进行遍历。

1)增强for循环

for (String ele : collection) {System.out.println(ele);
}

注意事项:

  • 增强for循环中不允许对集合中的元素进行修改,修改是无效的

  • 增强for循环中不允许对集合的长度进行修改,否则会出现 ConcurrentModificationException

2)迭代器

迭代器Iterator,是一个接口, Collection集合中有一个方法 iterator() 可以获取这个接口的实现类 对象。在这个迭代器中,维护了一个引用,指向集合中的某一个元素。默认指向一个集合前不存在的元 素,可以认为是下标为-1的元素。

迭代器的工作原理:循环调用 next() 方法进行向后的元素指向,并返回新的指向的元素。同时,在向 后进行遍历的过程中,使用 hasNext() 判断是否还有下一个元素可以迭代。

在迭代器使用的过程中,需要注意:

  • 不应该对集合中的元素进行修改

  • 不应该对集合的长度进行修改

  • 如果非要修改,需要使用迭代器的方法,不能使用的集合的方法。

// 1、获取迭代器对象,这里的   iterator 是一个  Iterator 接口的实现类对象
Iterator<String> iterator = collection.iterator();
​
// 2、使用迭代器进行集合的遍历
while (iterator.hasNext()) {// 让迭代器向后指向一位,并返回这一位的元素String element = iterator.next();System.out.println(element);
}

子接口List

  1. List 是一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引,从0开始

  2. List 允许使用重复元素,可以通过索引来访问指定位置的集合元素。

  3. List 默认按元素的添加顺序设置元素的索引。

  4. List 集合里添加了一些根据索引来操作集合元素的方法

1.ArrayList和LinkedList的区别

  1. ArrayList是一个可变大小组,初始容量为10,当数组满时,容量扩大1.5倍。新建一个更大的数组,将老数组复制到新数组上。他在查找元素更高效,因为数组是由一块连续区域的内存实现,可以通过地址索引计算出值的位置。而当删除或新增一个元素时,其他元素都要移动。

  2. LinkedList是一个双向链表,不考虑内存大小,原则上是可以无限大的,链表由不连续内存实现,链表中的每个节点都包含了前一个和后一个节点的引用,所以他在新增上是高效的。当查找时,它需要通过一个以知元素向下遍历才能找到要找到的值,

2.ArrayList线程安全吗?想要线程安全怎么办?

  1. 非线程安全的

  2. 使用Collections.synchronizedList方法可以得到一个线程安全的List,但在ArrayList的所有公共方法上加锁

  3. 使用CopyOnWriteArrayList或手动加锁

3.CopyOnWriteArrayList怎么保证线程安全?它的优点和缺点呢?

  1. 读不加锁,写加锁

  2. 优点:

- 读高效

- 线程安全

- 高并发性

  1. 缺点:

- 写性能低

- 内存占用高

- 不适合实时性要求高的场景

4.数组和链表的区别

  1. 数组每个元素都是连续的,通过下标进行访问

  2. 链表中的元素不连续的,必须获得某个元素后,才能访问后续元素

  3. 数组可以由一块连续区域的内存实现,数组从申请之后就会固定

  4. 链表可以由不连续内存实现,内存足够时可以任意申请空间

  5. 数组:查询O(1),插入/删除O(n)

  6. 链表:查询O(n),插入/删除O(1)

5.常用方法

1)添加元素

  • boolean add(E e)

作用:向列表末尾添加指定的元素

  • void add(int index, E element)

作用:在列表的指定位置添加元素

  • boolean addAll(Collection c)

作用:将集合c中的所有元素添加到列表的结尾

  • boolean addAll(int index, Collection c)

作用::将集合c中的所有元素添加到列表的指定位置

2)获取元素

  • E get(int index)

作用:返回列表指定位置的元素

3)查找元素

  • int indexOf(Object obj)

作用:返回列表中指定元素第一次出现的位置,如果没有该元素,返回-1

  • int lastIndexOf(Object obj)

作用:返回列表中指定元素最后一次出现的位置,如果没有该元素,返回-1

4)移除元素

  • E remove(int index)

作用:移除集合中指定位置的元素,返回被移除掉的元素对象

5)修改元素

  • E set(int index, E element)

作用:用指定元素替换指定位置上的元素,返回被替换出来的元素对象

6)截取子集

  • List subList(int fromIndex, int toIndex)

作用:截取子集,返回集合中指定的fromIndex 到 toIndex之间部分视图,包前不包后

7)案例演示

// 1、实例化一个  List 接口的实现类对象,并向上转型为接口类型
List<Integer> list = new ArrayList<>();
// 2、增
list.add(10);
list.add(20);
// 3、在指定的位置插入元素
list.add(1, 15);
// 4、删除元素
list.remove(Integer.valueOf(15));
// 5、按照下标删除元素
list.remove(0);
// 6、通过下标设置元素
list.set(0, 200);
// 7、通过下标获取元素
Integer element = list.get(0);
// 8、获取某一个元素出现的下标
int index = list.indexOf(200);
// 9、获取某一个元素最后一次出现的下标
int index = list.lastIndexOf(200);
​
System.out.println(element);

6.ListIterator

ListIterator是Iterator接口的子接口,继承到了Iterator中所有的方法,同时自己也添加了若干个方法。 允许使用ListIterator在进行元素迭代的时候,对集合中的数据进行修改,或者对集合的长度进行修改。 同时,使用ListIterator还可以进行倒序的迭代。

// 3、在迭代的过程中,修改集合
while (iterator.hasNext()) {// 向后指向一位,并返回当前指向的元素String ele = iterator.next();if (ele.equals("Vertu")) {// 在迭代的过程中,删除这个元素iterator.remove();// 在迭代的过程中,添加一个元素(加在当前迭代的这个元素的后面)iterator.add("HTC");// 在迭代的过程中,对当前迭代的元素进行修改iterator.set("Nokia");}
}
​
//倒叙
ArrayList<String> objects2 = new ArrayList<>();objects2.add("lily");objects2.add("lucy");objects2.add("Uncle wang");objects2.add("Polly");ListIterator<String> iterator = objects2.listIterator();
//        ListIterator<String> iterator = objects2.listIterator(4); //不写值,不正序就不会找到while (iterator.hasNext()){Object next = iterator.next();System.out.println(next+" ");}while (iterator.hasPrevious()){Object previous = iterator.previous();System.out.println(previous+" ");System.out.println(1);}

子接口Set

  1. Set集合中的元素是无序的(取出或者打印的顺序与存入的顺序无关)

  2. Set集合中的元素不能重复

  3. 底层实现是hashmap

1.HashSet

HashSet 具有以下特点:

  1. 不能保证元素的排列顺序

  2. HashSet 不是线程安全的

  3. 集合元素可以是 null

2.LinkedHashSet

  • LinkedHashSet 是 HashSet 的子类

  • LinkedHashSet 集合根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

  • LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

  • LinkedHashSet 不允许集合元素重复。

3.TreeSet

  1. TreeSet 是 SortedSet 接口的实现类, TreeSet集合是用来对元素进行排序的,同样他也可以保证元素的唯一。TreeSet 可以确保集合元素处于排序状态。

  2. TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。

  3. 必须实现Comparable,否则会报Exception in thread "main" java.lang.ClassCastException: com.youcai.day10._01.teacher cannot be cast to java.lang.Comparable

4.set去重

子接口Queue

  • 队列Queue也是Collection的一个子接口,它也是常用的数据结构,可以将队列看成特殊的线性表,队列限制对线性表的访问方式:只能从一端添加(offer)元素,从另一端取出(poll)元素。

  • 队列遵循先进先出(FIFO first Input First Output)的原则

  • 实现类LinkedList也实现了该接口,选择此类实现Queue的原因在于Queue经常要进行添加和删除操作,而LinkedList在这方面效率比较高。

  • 其主要方法如下:

    • 方法解析
      boolean offer(E e)作用:将一个对象添加到队尾,如果添加成功返回true
      E poll()作用:从队首删除并返回这个元素
      E peek()作用:查看队首的元素
public void testQueue(){Queue<String> queue = new LinkedList<>();queue.offer("a");queue.offer("b");queue.offer("c");System.out.println(queue); // [a,b,c]String str = queue.peek();System.out.println(str); // awhile(queue.size() > 0){str = queue.poll();System.out.println(str+" "); // a b c}
}

子接口Deque

Deque是Queue的子接口,定义了所谓的”双端队列”,即从队列的两端分别可以入队(offer)和出队(poll)。同样,LinkedList实现了该接口

如果将Deque限制为只能一端入队和出队,则可以实现“栈”(Stack)的数据结构,对于栈而言,入栈被称为push,出栈被称为pop。遵循先进后(FILO)出原则

public void testDeque(){Deque<String> stack = new LinkedList<>();stack.push("a");stack.push("b");stack.push("c");System.out.println(push); // [c,b,a]String str = queue.peek();System.out.println(str); // cwhile(stack.size() > 0){str = stack.pop();System.out.println(str+" "); // c b a}
}

父接口Map

Map是集合框架中的另一个父接口,它用来保存具有映射(一对一)关系的数据,这样的数据称之为键值对(Key-Value-Pair)。key可以看成是value的索引。特点如下:

  • key和value必须是引用类型的数据

  • 作为key,在Map集合中不允许重复,Value可以重复

  • key可以为null

  • key和value之间存在单向一对一关系,通过指定的key总能找到唯一,确定的value

1.常用方法

/ 1、实例化一个  Map 接口的实现类的对象,并向上转型为  Map 接口类型
Map<String, String> map = new HashMap<>();
​
// 2、增,向集合中添加一个键值对
map.put("name", "xiaoming");
map.put("age", "12");
map.put("gender", "male");
​
// 3、增,如果增的这个键在Map中已经存在,此时会用新的值覆盖原来的值
map.put("age", "20");
​
// 4、增,当这个键不存在的时候,才会增 ; 如果存在,这个方法没有任何效果
map.putIfAbsent("age", "30");
​
// 5、增,从一个Map集合中添加键值对,如果两个Map中存在相同的键,则会用新值覆盖原来的值
Map<String, String> tmp = new HashMap<>();
tmp.put("name", "xiaobai");
tmp.put("java", "89");
tmp.put("mysql", "78");
map.putAll(tmp);
System.out.println(map);
​
// 6、删,按照键删除键值对
map.remove("age");
System.out.println(map);
​
// 7、删,删除指定的键值对,只有当键和值都能够匹配上的时候,才会删除
map.remove("name", "xiaobai");
​
// 8、删,清空所有的键值对
map.clear();
​
​
// 9、改,通过键,修改值
map.replace("gender", "female");
System.out.println(map);
​
// 10、改,只有当键和值都能够匹配上,才会修改值
map.replace("gender", "female", "Unknown");
System.out.println(map);
​
// 11、 /*
V apply(K key, V oldValue):
将Map集合中的每一个键值对都带入到这个方法中,用返回值替换原来的值 */
// 需求 : 将现在所有的成绩后面添加上"分 "
map.replaceAll((k, v) -> {
if (k.matches("java|scala|linux|mysql|hadoop")) { return v + "分 ";
}
return v;
});
System.out.println(map);
// 12、查询(通过键,查询值)(如果不存在这个键,则结果是  null)
String value =  map.get("java1");
System.out.println(value);
​
// 13、查询(通过键查询值,如果不存在这个键,会返回默认的值)
String value2 = map.getOrDefault("java1", "0");
System.out.println(value2);
​
// 1、判断集合中是否包含指定的键
map.containsKey("java");
​
// 2、判断集合中是否包含指定的值
map.containsValue(98);
​
// 3、获取集合中元素的数量(键值对的数量)
map.size();
​
// 4、判断集合是否是一个空集合
map.isEmpty();
​
// 5、获取所有的值
Collection<Integer> values = map.values();

2.Map遍历

Map提供了三种遍历方式

1)遍历所有的key

Set<K> keySet();

该方法会将当前Map中的所有key存入一个Set集合后返回

2)遍历所有的key-value

Set<Entry<K,V>>  entrySet()Map<Object, Object> objectObjectMap = new HashMap<>();
objectObjectMap.put("1", "1");
objectObjectMap.put("2", "2");
objectObjectMap.put("3", "3");
Set<Map.Entry<Object, Object>> entries = objectObjectMap.entrySet();
for (Map.Entry<Object, Object> s:  entries){System.out.println(s.getKey()+"--"+s.getValue());
}

该方法会将当前Map中的每一组key-value封装成Entry对象存入Set集合后返回

3)遍历所有的value(不常用)

Collection<V> values

3.hashMap实现原理

在1.8之前是用链表加数组实现的,并使用头插法插入元素,在1.8之后使用数组链表红黑树实现的,当数组大于64,链表大于8,链表会转成红黑树,为了解决头插法产生的死循环,改为尾插法。hashMap是通过hash方法找到对应的存储位置。如果hash值相同,key值相同覆盖,不同会将数组插入链表或红黑树,Hashmap的初始值是17加载因子是0.75,所以当已将使用12个空间时,会扩大2倍,并且已有的数据会根据新的长度计算出对应的位置。HashMap是线程不安全的,会发生数据覆盖,size不准确,数据不一致问题。线程安全替代类:ConcurrentHashMap。

4.红黑树介绍

一种自平衡的二叉搜索树:

- 节点红或黑

- 根节点黑色

- 每个叶子节点黑色

- 如果一个节点是红色,则它的子节点必须是黑色

- 从任一节点到其每个子节点的所有路径会有相同数目的黑色节点

- 通过变色和旋转保持平衡

5.HashMap与HashTable、ConcurrentHashMap

  1. Hashtable线程安全通过方法使用synchronized关键字进行同步,保证了多线程的并发安全性。由于方法的同步锁机制,性能低于HashMap。不允许null键和null值,插入null键值会抛出NullPointerException

  2. HashMap:非线程安全的,没有线程同步机制。单线程性能高于Hashtable,允许一个null键和多个null值

  3. ConcurrentHashMap底层由数组+链表+红黑树组成,是线程安全的,使用了分段锁技术,将哈希表分成很多段,每个段有独立的锁。多个线程同时访问,只需锁住操作的那个段而不是整个表,提高并发性能。在JDK1.8后采用CAS+synchronized保证线程安全,锁粒度更细,从段锁到桶锁,添加元素时判断某个桶是否为空,空使用CAS添加,不空使用synchronized。key和value都不允许null。

6.HashMap的hash方法是如何实现的?

  1. hash方法的功能是根据Key来定位这个K-V在链表数组中的位置的。也就是hash方法的输入应该是个Object类型的Key,输出应该是个int类型的数组下标。最简单的话,我们只要调用Object对象的hashCode()方法,该方法会返回一个整数,然后用这个数对HashMap或者HashTable的容量进行取模就行了。

  2. 在这里面,HashMap的hash方法为了提升效率,主要用到了以下技术手段:

    1. 使用位运算(&)来代替取模运算(%),因为位运算(&)效率要比代替取模运算(%)高很多,主要原因是位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快。

    2. 对hashcode进行扰动计算,防止不同hashCode的高位不同但低位相同导致的hash冲突。简单点说,就是为了把高位的特征和低位的特征组合起来,降低哈希冲突的概率,也就是说,尽量做到任何一位的变化都能对最终得到的结果产生影响。

7.hash冲突通常怎么解决?

1.开放定址法 开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。这种方法的缺点是可能导致“聚集”问题,降低哈希表的性能。 2.链地址法 最常用的解决哈希冲突的方法之一。每个哈希桶(bucket)指向一个链表。当发生冲突时,新的元素将被添加到这个链表的末尾。在Java中,HashMap就是通过这种方式来解决哈希冲突的。Java 8之前,HashMap使用链表来实现;从Java 8开始,当链表长度超过一定阈值时,链表会转换为红黑树,以提高搜索效率。 3.再哈希法 当哈希地址发生冲突用其他的函数计算另一个哈希函数地址,直到冲突不再产生为止。这种方法需要额外的计算,但可以有效降低冲突率。 4.建立公共溢出区 将哈希表分为基本表和溢出表两部分,发生冲突的元素都放入溢出表中。 5.一致性hash 主要用于分布式系统中,如分布式缓存。它通过将数据均匀分布到多个节点上来减少冲突。

8.LinkedHashMap

LinkedHashMap 是 HashMap 的子类

LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致

9.TreeMap

TreeMap 存储 Key-Value对时,需要根据 Key 对 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。

注意:TreeMap里的key,是使用comparaTo来确定是否唯一的,而不是调用HashCode和equals的

TreeMap 的 Key 的排序:

  • 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClassCastException

  • 定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口

10.Properties

Properties 类是 Hashtable 的子类,该对象用于处理属性文件

由于属性文件里的 key、value 都是字符串类型,所以 properties 里的 Key 和 Value 都是字符串类型的

Collections

Collections 是一个操作 Set、List 和 Map 等集合的工具类,提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法

1)排序操作

  • reverse(List):反转 List 中元素的顺序

  • shuffle(List):对 List 集合元素进行随机排序

  • sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序

  • sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序

  • swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换

2)查找、替换

  • Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素

  • Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素

  • Object min(Collection)

  • Object min(Collection,Comparator)

  • int frequency(Collection,Object):返回指定集合中指定元素的出现次数

  • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值

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

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

相关文章

深度学习核心:神经网络-激活函数 - 原理、实现及在医学影像领域的应用

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#,Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开发…

OneCode3.0 核心表达式技术深度剖析:从架构设计到动态扩展

一、引言&#xff1a;表达式技术在企业级框架中的核心价值 在当今快速变化的企业级应用开发中&#xff0c;动态性和灵活性已成为衡量框架优劣的关键指标。OneCode 3.0 框架作为企业级应用开发的重要工具&#xff0c;其核心表达式技术提供了一种强大的解决方案&#xff0c;使开发…

[css]旋转流光效果

实现一个矩形的旋转流光边框效果。 需要使用css属性梯度渐变&#xff1a;链接: conic-gradient&#xff0c;他指的是圆锥形变化的梯度。 // html<div class"demo"></div>// css body {width: 100%;height: 100%;background-color: black; }.demo {width…

NPM组件 @0xme5war/apicli 等窃取主机敏感信息

【高危】NPM组件 0xme5war/apicli 等窃取主机敏感信息 漏洞描述 当用户安装受影响版本的 0xme5war/apicli 等NPM组件包时会窃取用户的主机名、用户名、工作目录、IP地址等信息并发送到攻击者的电报地址(botToken “7699295118:AAF6pb7t718vjHWHwFQlZOastZQYHL8IVDE”&#x…

计算机网络:组播和多播有什么区别?

在网络通信中&#xff0c;“组播”和“多播”其实是同一概念的不同中文翻译&#xff0c;它们对应的英文都是 Multicast。二者本质上没有技术区别&#xff0c;只是因翻译习惯不同而产生的两种表述&#xff0c;在实际应用中可以通用。 不过&#xff0c;为了更清晰地理解这个概念&…

Amazon Q Developer:AI 增强编码生产力的未来

Amazon Q Developer&#xff1a;重塑编码体验的 AI 助手 在如今快节奏的软件开发世界中&#xff0c;开发者们始终在寻找能平衡生产力与探索欲的工具。而 Amazon 推出的 Amazon Q Developer&#xff0c;这款可嵌入 Visual Studio Code 等主流 IDE 的 AI 编码助手&#xff0c;无疑…

linux eval命令的使用方法介绍

在这篇文章中&#xff0c;让我们来详细地介绍一下 Linux 中另一个非常强大但也极其危险的命令&#xff1a;eval。 eval 是一个 shell 内置命令&#xff0c;它的名字是 “evaluate”&#xff08;评估&#xff09;的缩写。它的作用是将紧跟其后的参数&#xff08;一个或多个字符串…

JavaWeb笔记2-JavaScriptVueAjax

1. JavaScript 1.1 基础介绍 JavaScript(简称&#xff1a;JS)是一门跨平台、面向对象的脚本语言&#xff0c;是用来控制网页行为&#xff0c;实现页面的交互效果。JavaScript和Java是完全不同的语言&#xff0c;但基本语法类似组成 ECMAScript: 规定了JS基础语法核心知识&…

代码随想录刷题Day23

右旋字符串 这道题是比较常规的对字符串的复制操作&#xff0c;找到右旋部分的分界点是关键 代码直接贴出来&#xff1a; #include<stdio.h> #include<string.h> int main(){int k;char s[10000];scanf("%d %s",&k,s);int cnt 0;for(int i str…

机器学习sklearn:编码、哑变量、二值化和分段

就是转换为数值类型方便机器学习模型处理一、编码这里举例将Survived这一行的数据转换为编码&#xff0c;原本是字符串类型2、将标签编码并赋值回去from sklearn.preprocessing import LabelEncoder y data.iloc[:, -1] # 最后一列拿出来 print(y) le LabelEncoder() le …

嵌入式八股文总结(ARM篇)

嵌入式开发中使用的通常是ARM芯片&#xff0c;在此总结一些面试常问的问题&#xff0c;希望可以和大家一起进步。&#xff08;持续更新中……&#xff09; 目录 1. 介绍一下I2C的传输时序 2. I2C为什么加上拉电阻&#xff0c;为什么使用开漏输出 3. I2C能接多少个设备&…

TCL --- 列表_part2

0 回顾 列表part0和part1描述了列表的创建&#xff0c;修改&#xff0c;获取&#xff0c;搜索等相关命令。接下来这篇文章将介绍列表的排序和拼接。通过这三篇文章的描述&#xff0c;详细大家对列表具有一个详细并且系统的认识。 1 排序 排序是一个老生常谈的话题。最最最常见的…

Kafka 单机多 Broker 实例集群搭建 | 详情

全文目录&#xff1a;开篇语前言1. Kafka 集群架构2. 环境要求2.1 安装 Java2.2 安装 Zookeeper3. 安装 Kafka4. 创建 Topic4.1 查看创建的 Topic5. 测试 Kafka 集群5.1 生产者&#xff08;Producer&#xff09;测试5.2 消费者&#xff08;Consumer&#xff09;测试6. 小结文末…

Ajax——异步前后端交互提升OA系统性能体验

本文介绍了Ajax中的基础使用&#xff0c;包括XMLHttpRequest的状态变化、并使用BMI 场景的示例进行介绍&#xff0c;以及结合 DAO 和 Servlet 处理OA系统复杂业务逻辑和JSON数据的处理等等。 本文目录一、Ajax 基础html页面二、 XMLHttpRequestXMLHttpRequest的状态变化同步和异…

【最后一个单词的长度】

思路 逆向遍历&#xff1a; 从字符串末尾开始向前遍历&#xff0c;跳过末尾的空格&#xff0c;直到找到非空格字符。 遇到非空格字符时开始计数&#xff0c;直到再次遇到空格或字符串开头。 状态标记&#xff1a; 使用 state 标记是否已经进入最后一个单词的计数阶段&#xff1…

OpenCV学习 day3

一、灰度实验 将彩色图像转换为灰度图像的过程称为灰度化&#xff0c;这种做法在图像处理中和计算机视觉领域非常常见 1、灰度图 灰度图是一种 单通道图像&#xff0c;每个像素仅存储 亮度信息&#xff08;0纯黑&#xff0c;255纯白&#xff09;&#xff0c;没有颜色信息&#…

基于单片机一氧化碳CO检测/煤气防中毒检测报警系统

传送门 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目速选一览表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目功能速览 概述 基于单片机的CO检测系统通过传感器实时监测环境中的一氧化碳浓度&#xff0c;结合信号处理电路与…

前端-移动Web-day3

目录 1、视口 2、rem体验 3、rem基本使用 4、媒体查询 5、rem适配 6、rem布局 7、less-体验 8、less-注释 9、less-运算 10、less-嵌套 11、less-变量 12、less-导入 13、less-导出 14、less-禁止导出 15、案例-极速问诊 1、视口 <!DOCTYPE html> <htm…

【正点原子K210连载】第二十四章 按键输入实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第二十四章 按键输入实验 本章实验将介绍如何使用CanMV让Kendryte K210获取板载按键的状态。通过本章的学习&#xff0c;读者将学习到在CanMV下读取Kendryte K210的GPIO上的高低电平状态。 本章分为如下几个小节&#xff1a; 14.1 maix.GPIO模块介绍 14.2 硬件设计 14.3 程序设…

基于springboot/java/VUE的旅游管理系统/旅游网站的设计与实现

用户&#xff1a;注册&#xff0c;登录&#xff0c;旅游景点&#xff0c;酒店信息&#xff0c;旅游线路&#xff0c;公告信息&#xff0c;留言板&#xff0c;后台管理&#xff0c;个人中心&#xff0c;门票预订管理&#xff0c;酒店预订管理管理员&#xff1a;登录&#xff0c;…