当前位置: 首页 > news >正文

数据结构(栈Stack)

1.前言:

在计算机科学中,栈(Stack)是一种基础而存在的数据结构,它的核心特性是后进先出(LIFO,Last In, First Out)。想象一下,在现实生活中我们如何处理一堆托盘——我们总是将新托盘放在最上面,而取托盘时则从最上面开始,这正好与托盘的操作方式相吻合。

栈的简单结构和高效的操作,使得在许多计算机程序和算法中扮演关键的角色。从方法调用、递归过程到表达求值、短语匹配,栈几乎暗示在。只允许在前置插入和删除元素的数据结构,不仅能简化问题的高效初始化过程,还能提供的性能,尤其是在处理需要回溯和深度优先搜索的问题时,堆栈外形更架构。

无论是Smashing初学者还是丰富的开发者,理解Stack的工作原理及其应用,都是构建健壮软件系统的基础。本文将深入探讨Stack的概念、操作以及应用场景,并通过实例经验演示如何在Java中中实现和使用栈。让我们一起来走进这个简单但强大的数据结构,了解它在实际编程中的巨大价值。

2.讲解栈:

2.1概念:

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈。出数据在栈顶

2.2栈的使用:

import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        
        stack.push(10);  // 入栈
        stack.push(20);  // 入栈
        stack.push(30);  // 入栈
        
        System.out.println("Top of the stack: " + stack.peek());  // 查看栈顶元素 (30)
        
        System.out.println("Popped element: " + stack.pop());  // 弹出栈顶元素 (30)
        
        System.out.println("Is stack empty? " + stack.isEmpty());  // 判断栈是否为空 (false)
        
        System.out.println("Size of stack: " + stack.size());  // 查看栈大小 (2)
    }
}

2.3 栈的模拟实现:

1.实现栈前的模拟:

1.private int[] elem;

这行代码声明了一个容器的整型仓库elem,它用于存储栈中的元素。在栈中,我们需要一个容器来保存被压入栈的值,因此这里选择了一个仓库。

  • 类型int[]表示这是一个队列,用于存储栈中的数据。
  • 访问控制private关键字表示该队列只能在MyStack类内部访问,外部无法直接访问。

2.private int usedSize;

这行代码声明了一个原始的整型变量usedSize,它用来记录栈中当前存储的元素个数。

  • 类型int,用于表示栈中当前的元素个数。
  • 访问控制private关键字使得usedSize只能在MyStack类内部访问,外部无法直接修改或读取。

3.private static final int DEFAULT_SIZE = 10;

这行代码定义了一个常量DEFAULT_SIZE,它表示栈的最终容量,默认为 10。

  • 类型int,表示栈的容量大小。
  • 访问控制private关键字表示常量只能在MyStack类内部使用。
  • 修饰符
    • static:意味着该常量是类级别的,而不是实例级别的。那么,所有MyStack类的实例共享这个常量。
    • final:表示这个常量的值一旦被赋值后就不能修改。
  • 作用:为栈的初始大小提供一个默认值。如果没有指定栈的大小,栈的容量将默认为10。

4.public MyStack() {

这是MyStack类的构造方法。构造方法是类的实例化时调用的特殊方法,用于初始化对象的状态。

  • 访问控制public关键字表示构造方法可以被外部类访问,否则允许通过构造方法创建MyStack的实例。
  • 方法名:构造方法的名称是MyStack,与类名相同。

5.elem = new int[DEFAULT_SIZE];

在构造方法的主体中,这行代码用于初始化elem内存。

  • 队列初始化new int[DEFAULT_SIZE]创建了一个大小为DEFAULT_SIZE(即10)的内存队列,并赋予其赋值elem。这表示堆栈一开始的容量为10。
  • :栈的最终容量设为10,当栈中的元素数量小于10时,栈能够承载更多元素。当元素数量超过10时,通常会触发动态扩容。

这需要构造方法的结束。构造方法结束后,MyStack类的实例会完成初始化,可以开始使用栈。

 

2.push添加元素:

public void push(int val) {

  • 访问控制public 关键字表示这个方法可以被外部类调用,允许用户向栈中添加元素。
  • 方法名push 是栈数据结构中的常见操作,用于向栈中添加元素。
  • 参数int val 是栈要添加的元素,它表示一个整数,用户希望将其压入栈中。
  • 返回类型void 表示这个方法没有返回值。

2. if (isFull()) {

  • 这行代码检查栈是否已满。isFull() 是一个方法,通常用来判断栈是否达到了最大容量。

  • isFull():我们可以推测它的作用是判断栈的当前容量是否已满。可能的实现方式是检查 usedSize 是否等于栈的当前容量 elem.length。如果栈已满,则 isFull() 返回 true,否则返回 false

3.grow();

  • 这是一个调用 grow() 方法的语句,意味着当栈满时,栈将扩容。grow() 是扩展栈容量的操作。
  • 扩容操作:在栈满时,我们需要增加栈的容量,通常是通过创建一个更大的数组,并将原数组的元素复制到新的数组中。扩容后,栈可以容纳更多的元素。

4. elem[usedSize] = val;

  • 这行代码将 val 插入到栈顶。具体来说,它将 val 赋值给 elem[usedSize],即将 val 存储到当前栈的下一个可用位置。
  • usedSize:在栈未满时,usedSize 表示栈中已经存储的元素个数,它也可以用作 elem 数组的下标。当插入一个新元素时,usedSize 会指向栈的顶部元素的位置。
  • 栈的压栈操作是通过把元素存储在 elem[usedSize] 来实现的,然后 usedSize 自增,表示栈中元素个数增加了。

5. usedSize++;

  • 这行代码执行后,usedSize 增加 1,表示栈中元素个数增加了一个。
  • usedSize:这个变量用于追踪栈中实际存储的元素数量。每当我们向栈中压入一个元素时,usedSize 就会递增,以保证在后续操作中可以准确地知道栈的大小。

3.pop删除元素:

1.public int pop():

  • 访问控制public 表示这个方法对外可见,可以被其他类调用。
  • 返回类型int,表示该方法返回一个整数,即栈顶的元素值。
  • 方法名pop 是栈的基本操作之一,表示从栈顶移除元素并返回被移除的元素。

2. if (isEmpty()) {

  • 在执行 pop 操作之前,方法会首先检查栈是否为空,防止对空栈执行弹栈操作。
  • isEmpty() 方法:这个方法通常用于判断栈是否为空。可能的实现逻辑是检查 usedSize 是否为 0

3. throw new RuntimeException();

  • 如果栈为空,直接抛出一个 RuntimeException
  • 异常的目的:防止非法操作(即对空栈执行弹栈操作)。这种设计能够提醒用户修复程序中潜在的问题。
  • 替代方案:注释中的代码显示了一种替代方式,即返回一个特殊值(如 -1)来表示操作失败。然而,抛出异常更加严谨,因为返回特殊值可能导致逻辑混淆(-1 可能与有效数据冲突)。

4. usedSize--;

  • 这行代码将 usedSize 减 1,表示栈中元素的数量减少了一个。
  • 减少后的作用
    • usedSize 减少后,指向的索引位置就是被弹出的元素的索引。
    • elem[usedSize] 表示当前栈顶的元素。

5. return elem[usedSize];

  • 返回当前栈顶元素,即 elem[usedSize]
  • 逻辑
    • 由于前面已经执行了 usedSize--,此时 usedSize 的值指向的是刚刚被移除的栈顶元素所在的索引。
    • 直接返回 elem[usedSize],实现弹栈并返回被移除的元素。

4.获取栈顶元素 但是不删除当前元素peek

1.public int peek()

  • 访问控制public 表示该方法对外可见,允许外部代码调用。
  • 返回类型int,表示该方法返回一个整数,即栈顶的元素值。
  • 方法名peek,这是栈数据结构中的常见操作,用于查看栈顶元素而不改变栈的状态。

2. if (isEmpty()) {

  • 在执行 peek 操作之前,方法首先检查栈是否为空,以防止在空栈上进行不合法的操作。
  • isEmpty() 方法:判断栈是否为空。通常的实现方式是检查 usedSize 是否为 0

3. throw new RuntimeException();

  • 如果栈为空,抛出一个 RuntimeException

  • 异常处理:抛出异常意味着对空栈执行 peek 操作是非法的,并且程序会抛出一个运行时异常来提醒用户。这样可以防止程序在不正确的状态下继续运行。

    这种方式相较于返回特殊值(如 -1)更为严谨,因为返回 -1 可能会与有效的数据冲突,导致逻辑错误。

4. return elem[usedSize - 1];

  • 这行代码返回栈顶元素的值,但并不移除该元素。
  • usedSize - 1:栈的大小 usedSize 表示栈中当前有效元素的个数。由于数组索引从 0 开始,因此栈顶的元素位于 usedSize - 1 的索引位置。例如:
    • 如果栈有 3 个元素,usedSize = 3,栈顶元素的位置是 elem[2],即 usedSize - 1
  • 通过返回 elem[usedSize - 1],我们能够获取栈顶的元素值,而不影响栈的内容。

5.返回栈大小:

  • 返回 usedSizeusedSize 是一个成员变量,用于记录栈中当前元素的数量。当我们创建栈时,usedSize0 开始,随着元素的压栈操作(push)而增加,随着弹栈操作(pop)而减少。
  • 因此,size 方法返回的就是栈当前的有效元素个数,也就是 usedSize 的值。

2.4  完整代码展示:

import java.util.Arrays;public class MyStack {private int[] elem;private int usedSize;private static final int DEFAULT_SIZE = 10;public MyStack() {elem = new int[DEFAULT_SIZE];}//存储数据public void push(int val) {if(isFull()) {//扩容grow();}elem[usedSize] = val;usedSize++;}private void grow() {elem = Arrays.copyOf(elem,elem.length);}public boolean isFull() {return usedSize == elem.length;}//删除数据public int pop() {if(isEmpty()) {//return -1;throw new RuntimeException();}usedSize--;return elem[usedSize];}public boolean isEmpty() {return usedSize == 0;}//获取栈顶元素 但是不删除当前元素public int peek() {if(isEmpty()) {//return -1;throw new RuntimeException();}//usedSize--;return elem[usedSize-1];}public int size() {return usedSize;}}

2.5栈的使用场景

  • 方法调用栈(堆栈) Java中的方法调用栈是由虚拟机(JVM)管理的栈空间。当一个方法被调用时,JVM 会在栈中为该方法分配一个栈帧,用于存储方法的局部变量、操作数栈、返回地址等信息。方法执行完毕后,栈帧会被销毁。

  • 表达式求值 栈在算术表达式求值中非常重要。例如,在中缀表达式转后缀表达式时,栈用来保存运算符,并且根据运算符的优先级来控制栈中的内容。

  • 回溯算法 在深度优先搜索(DFS)算法和回溯算法中,栈用于存储递归过程中的状态信息。

  • 括号匹配 在编程中,检查一段代码中的括号是否匹配也可以通过栈来实现。遇到左括号时入栈,遇到右括号时出栈。如果栈为空或括号不匹配,则说明括号不合法。

2.6栈的优缺点

优点:

  • 高效性:栈的插入和删除操作是常数时间操作(O(1)),不需要查找、排序等复杂操作。
  • 简洁性:栈的操作非常简单,只有栈顶访问,避免了复杂的数据结构管理。
  • 适用性强:栈可以用来解决许多常见的算法问题,如括号匹配、回溯算法、递归、深度优先搜索等。

缺点:

  • 访问受限:栈只能访问栈顶的元素,无法直接访问栈中的其他元素。对于需要随机访问的场景,栈就不太合适。
  • 空间限制:栈的大小通常是有限的,如果栈的空间耗尽(比如在递归调用时),会导致栈溢出(StackOverflowError)。

3.栈的拓展方法:

1.toArray()将栈转换为一个数组,方便进行其他操作或输出栈的内容。

public int[] toArray() {
    return Arrays.copyOf(elem, usedSize);  // 返回栈中有效部分的数组
}

  • 返回值:返回一个数组,包含栈中的所有元素。
  • 功能:将栈的内容转换为数组。
  • 复杂度:时间复杂度 O(n),需要遍历栈中的元素并将其复制到数组中。

比较重要所以详细讲解:

  • Arrays.copyOf(elem, usedSize)
    • Arrays.copyOf() 是 Java 提供的一个静态方法,它可以复制一个数组的前几个元素到新的数组中。这里它将 elem 数组中从索引 0usedSize - 1 的所有元素复制到一个新的数组。
    • elem 是栈的存储数组,它的长度可能大于当前栈的实际元素个数(usedSize)。
    • usedSize 表示栈中当前存储的元素个数,因此我们只需要复制前 usedSize 个元素。
    • copyOf 方法返回一个新的数组,包含栈中当前的所有有效元素。
为什么使用 Arrays.copyOf
  • Arrays.copyOf() 方法能够处理数组的拷贝,并自动管理目标数组的大小。它会创建一个新的数组,并将原数组的元素复制到新数组中。
  • 使用 copyOf 的好处是可以确保不会出现数组越界问题,而且代码简洁。

4. 方法返回值

toArray() 方法返回的是一个新的数组,其中包含栈中当前所有的元素。返回值的类型是 int[],也就是一个整型数组。

例如,假设栈中有以下元素:

  • elem = [10, 20, 30, 0, 0]
  • usedSize = 3

调用 toArray() 后,会返回一个包含栈中前 3 个元素的新数组:

  • 返回的数组:[10, 20, 30]

5. 使用场景

toArray() 方法主要用于以下几种场景:

  • 输出栈内容:有时需要输出栈的内容,toArray() 可以将栈元素转换成数组,然后方便地打印或者操作。
  • 与其他API交互:有些算法或库可能需要将栈转换为数组进行处理。toArray() 可以方便地将栈的元素传递给这些函数。
  • 复制栈内容:如果需要保持栈的副本,或者用于历史数据的存储时,toArray() 会返回一个包含栈元素的数组副本。

6. 时间复杂度分析

  • 时间复杂度Arrays.copyOf(elem, usedSize) 会复制 usedSize 个元素,因此时间复杂度为 O(n),其中 n 是栈中当前元素的个数。
  • 空间复杂度toArray() 会创建一个新的数组,因此空间复杂度是 O(n),其中 n 是栈中元素的个数。

7. 与其他集合类的对比

toArray() 是将栈中的元素转换为数组的常见方法。与其他集合类(如 ArrayListLinkedList 等)中的 toArray() 方法类似,栈的 toArray() 方法返回一个包含当前栈元素的数组。不过,栈通常是一个基于数组或动态数组的实现,因此 toArray() 返回的数组通常是连续存储的,和数组的顺序一致。

8. 示例使用

假设我们使用 MyStack 类来测试 toArray() 方法:

import java.util.Stack;
import java.util.Arrays;

public class StackToArrayExample {
    public static void main(String[] args) {
        // 创建一个栈对象
        Stack<Integer> stack = new Stack<>();

        // 使用 push() 方法压入元素
        stack.push(10);
        stack.push(20);
        stack.push(30);
        stack.push(40);
        stack.push(50);

        // 打印栈内容
        System.out.println("栈的内容(通过 printStack() 方法查看):");
        for (Integer item : stack) {
            System.out.print(item + " ");
        }
        System.out.println();

        // 使用 toArray() 方法将栈转换为数组
        Integer[] array = stack.toArray(new Integer[0]);

        // 打印转换后的数组
        System.out.println("栈转换成的数组:");
        System.out.println(Arrays.toString(array));  // 输出:[10, 20, 30, 40, 50]
        
        // 弹出栈顶元素
        stack.pop();
        
        // 再次打印栈转换成的数组
        array = stack.toArray(new Integer[0]);
        System.out.println("栈弹出一个元素后的数组:");
        System.out.println(Arrays.toString(array));  // 输出:[10, 20, 30, 40]
    }
}

2.contains()判断栈中是否包含指定的元素。

public boolean contains(int value) {
    for (int i = 0; i < usedSize; i++) {
        if (elem[i] == value) {
            return true;
        }
    }
    return false;
}

  • 功能:检查栈中是否包含某个元素。通常需要遍历栈中的元素。
  • 复杂度:时间复杂度 O(n),因为需要遍历栈中的所有元素。
  • 使用场景:当你需要判断栈中是否存在特定元素时使用。

3. peekAt(int index)返回栈中指定位置的元素,不修改栈的状态。

public int peekAt(int index) {
    if (index < 0 || index >= usedSize) {
        throw new IndexOutOfBoundsException("Index out of bounds");
    }
    return elem[index];
}

  • 功能:返回栈中指定索引位置的元素。这里的索引是栈内的相对位置,不是从栈顶开始的。
  • 复杂度:时间复杂度 O(1)。
  • 使用场景:可以用来查看栈中某个特定位置的元素。需要注意的是,它不保证返回栈顶元素,而是指定索引位置的元素。

4. reverse()将栈中的元素反转。这个操作通常修改栈的顺序。

public void reverse() {
    int[] reversed = new int[usedSize];
    int j = 0;
    for (int i = usedSize - 1; i >= 0; i--) {
        reversed[j++] = elem[i];
    }
    System.arraycopy(reversed, 0, elem, 0, usedSize);
}

  • 功能:反转栈中的所有元素,栈顶元素变为栈底,栈底元素变为栈顶。
  • 复杂度:时间复杂度 O(n),因为需要遍历栈的所有元素并进行重新排序。
  • 使用场景:如果需要将栈中的元素顺序反转,可以使用此方法。

5. toString()将栈转换为字符串形式,方便查看栈的内容。

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("[");
    for (int i = 0; i < usedSize; i++) {
        sb.append(elem[i]);
        if (i < usedSize - 1) {
            sb.append(", ");
        }
    }
    sb.append("]");
    return sb.toString();
}

  • 功能:返回栈中元素的字符串表示。
  • 复杂度:时间复杂度 O(n),需要遍历栈中的所有元素并构建字符串。
  • 使用场景:当需要打印栈的内容时,可以使用 toString() 方法。对于调试和日志记录非常有用。

6. clone()(深拷贝栈)克隆栈,创建栈的副本。确保副本与原栈是两个独立的对象。

@Override
public MyStack clone() {
    MyStack newStack = new MyStack();
    newStack.elem = Arrays.copyOf(this.elem, this.elem.length);
    newStack.usedSize = this.usedSize;
    return newStack;
}

  • 功能:创建栈的一个副本,确保副本的元素与原栈相同,但两个栈是独立的对象,互不影响。
  • 复杂度:时间复杂度 O(n),因为需要将栈中的元素复制到新的栈中。
  • 使用场景:需要操作栈的副本,而不改变原栈的内容时使用。

7. shrink()(可选)如果栈的容量比元素数量大很多,进行收缩,减少不必要的内存占用。

private void shrink() {
    if (usedSize < elem.length / 4) {
        int newCapacity = elem.length / 2;
        elem = Arrays.copyOf(elem, newCapacity);
    }
}

  • 功能:如果栈的元素数量小于数组容量的四分之一,则将栈的容量缩小为原来的一半。
  • 复杂度:时间复杂度 O(n),因为需要复制栈中的元素到新数组中。
  • 使用场景:用于栈的动态缩容,当栈的元素数目小于某个比例时,减少内存浪费。

8.clearAll()(可选)清空栈,并且将栈容量调整到默认大小。

public void clearAll() {
    usedSize = 0;
    elem = new int[DEFAULT_SIZE];  // 将栈的容量恢复为默认大小
}

  • 功能:除了清空栈中的元素,还将栈的容量恢复为默认大小。
  • 复杂度:时间复杂度 O(n)(如果实现了 clear 操作)+ O(n)(重新分配数组)。
  • 使用场景:当你想要重置栈,包括清空栈内容和恢复容量时使用。

9.peekBottom()(可选)返回栈底元素,但不删除它。

public int peekBottom() {
    if (isEmpty()) {
        throw new RuntimeException("Stack is empty");
    }
    return elem[0];  // 栈底元素是数组的第一个元素
}

  • 功能:查看栈底的元素,而不删除它。
  • 复杂度:时间复杂度 O(1),直接返回栈底元素。
  • 使用场景:有时需要查看栈底的元素,或者从栈底进行操作。

4.结语:

在本文中,我们详细探讨了如何实现一个简单的栈数据结构,并对栈的常见操作如 pushpoppeeksize 进行了深入的分析。通过这些方法,我们不仅了解了栈的基本功能,还能看到如何通过调整 usedSize 来有效管理栈的状态,保证其操作的高效性和安全性。

栈作为一种基本的数据结构,具有广泛的应用场景,尤其在算法、数据解析、函数调用栈等方面扮演着重要角色。通过本文的学习,我们可以更好地理解栈的内在机制,并能够在实际编程中灵活运用栈。

在实现栈的过程中,我们还探讨了几个常见的优化点,例如动态扩容、异常处理、以及线程安全等,确保栈能够在不同的环境和需求下稳定高效地运行。这些设计细节不仅提升了代码的健壮性,还增强了栈的可扩展性。

希望通过本文的介绍,读者能够对栈这一数据结构有更清晰的理解,并能够在实际项目中更加熟练地使用和扩展它。栈是很多算法和应用的基础,掌握它的设计和使用,将为解决更多复杂问题打下坚实的基础。

感谢您的阅读,期待您在实践中不断深入,探索更多有趣且实用的数据结构和算法。

相关文章:

数据结构(栈Stack)

1.前言&#xff1a; 在计算机科学中&#xff0c;栈&#xff08;Stack&#xff09;是一种基础而存在的数据结构&#xff0c;它的核心特性是后进先出&#xff08;LIFO&#xff0c;Last In, First Out&#xff09;。想象一下&#xff0c;在现实生活中我们如何处理一堆托盘——我们…...

Maven 中scope 的provided、compile、runtime、test、system 含义

在 Maven 中&#xff0c;<scope> 定义了依赖的可见性和生命周期。不同的 scope 值指示 Maven 在编译、测试和运行时如何处理这些依赖。以下是 Maven 中的几种常用依赖范围及其详细说明&#xff1a; 1. <scope>provided</scope> 含义&#xff1a;provided 范…...

Nginx 负载均衡和反向代理

Nginx 是一个高性能的 HTTP 服务器和反向代理服务器&#xff0c;广泛应用于负载均衡中。它的负载均衡功能支持多种策略&#xff0c;可以有效分配流量到后端服务器&#xff0c;提升系统的可靠性和可用性。 负载均衡 首先&#xff0c;Nginx 负载均衡配置是通过在 Nginx 配置文件…...

【网络安全】数据集合集!

本文将为您介绍经典、热门的数据集&#xff0c;希望对您在选择适合的数据集时有所帮助。 1 SecGPT 更新时间&#xff1a;2024-05-08 访问地址: GitHub 描述&#xff1a; SecGPT的愿景是将人工智能技术引入网络安全领域&#xff0c;以提高网络防御的效率和效果。其使命是推动…...

大数据(一)MaxCompute

一、引言 作者后面会使用MaxCompute&#xff0c;所以在进行学习研究&#xff0c;总会有一些疑问产生&#xff0c;这里讲讲作者的疑问和思路 二、介绍 MaxCompute&#xff08;原名 ODPS - Open Data Processing Service&#xff09;是阿里云提供的大数据处理平台&#xff0c;专…...

数据科学与大数据之间的区别

什么是数据科学&#xff1f; 数据科学是一个跨学科领域&#xff0c;它将统计学和计算方法相结合&#xff0c;旨在从数据中提取见解和知识。它涉及收集、处理、分析以及解读数据&#xff0c;以揭示可用于为决策过程提供依据并推动创新的模式、趋势和关系。 数据科学涵盖了广泛…...

IP 地理位置定位技术原理概述

本文深入探讨 IP 地理位置定位技术的原理。介绍了 IP 地址的基本概念及其在网络中的作用&#xff0c;随后阐述了基于数据库查询、基于网络拓扑分析以及基于机器学习算法的三种主要 IP 地理位置定位技术原理中的基于IP数据库查询。 IP 地址基础 IP 地址是互联网协议&#xff0…...

多进程multiprocessing通信multiprocessing.Queue

multiprocessing.Queue 通常只能在主模块&#xff08;即 if __name__ "__main__": 块&#xff09;中创建和使用。这是因为 multiprocessing 模块在 Windows 系统上需要通过 if __name__ "__main__": 块来避免递归导入问题。 from multiprocessing import…...

工业—使用Flink处理Kafka中的数据_ChangeRecord2

使用 Flink 消费 Kafka 中 ChangeRecord 主题的数据,每隔 1 分钟输出最近 3 分钟的预警次数最多的 设备,将结果存入Redis 中, key 值为...

微信小程序4-内容溢出滚动条

感谢阅读&#xff0c;初学小白&#xff0c;有错指正。 一、功能描述 在前一篇文章的隐藏框页面的功能里&#xff08;《微信小程序3-显标记信息和弹框》&#xff09;&#xff0c;我想添加一个内容溢出的时候&#xff0c;可通过滑动滚动条&#xff0c;实现查看溢出部分的内容&a…...

python源码实例游戏开发小程序办公自动化网络爬虫项目开发源码(250+个项目、26.6GB)

文章目录 源代码下载地址项目介绍预览 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 python源码实例游戏开发小程序办公自动化网络爬虫项目开发源码(250个项目、26.6GB) 预览 项目备注 1、该资源内项目代码都经过测试运行成功&#xff0c;功能ok的情…...

ProjectSend 身份认证绕过漏洞复现(CVE-2024-11680)

0x01 产品描述: ProjectSend 是一个开源文件共享网络应用程序,旨在促进服务器管理员和客户端之间的安全、私密文件传输。它是一款相当流行的应用程序,被更喜欢自托管解决方案而不是 Google Drive 和 Dropbox 等第三方服务的组织使用。0x02 漏洞描述: ProjectSend r1720 之前…...

算法训练-搜索

搜索 leetcode102. 二叉树的层序遍历 法一&#xff1a;广度优先遍历 leetcode103. 二叉树的锯齿形层序遍历 法一&#xff1a;双端队列 法二&#xff1a;倒序 法三&#xff1a;奇偶逻辑分离 leetcode236. 二叉树的最近公共祖先 法一&#xff1a;递归 leetcode230. 二叉…...

【C++】map和set

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 关联式容器2. 键值对3. set3.1 set的模板参数列表3.2 set的构造3.3 set的迭代器3.4 set的容量3.5 set修改操作3.6 multiset 4. map4.1 map的模板参数说明4.2 map的构造4.3 map的迭代器4.4 map的容量与元素访问4.5 …...

MongoDB安装|注意事项

《疯狂Spring Boot讲义》是2021年电子工业出版社出版的图书&#xff0c;作者是李刚 《疯狂Spring Boot终极讲义》不是一本介绍类似于PathVariable、MatrixVariable、RequestBody、ResponseBody这些基础注解的图书&#xff0c;它是真正讲解Spring Boot的图书。Spring Boot的核心…...

使用playwright自动化测试时,npx playwright test --ui打开图形化界面时报错

使用playwright自动化测试时&#xff0c;npx playwright test --ui打开图形化界面时报错 1、错误描述&#xff1a;2、解决办法3、注意符号的转义 1、错误描述&#xff1a; 在运行playwright的自动化测试项目时&#xff0c;使用npm run test无头模式运行正常&#xff0c;但使用…...

Linux ufw 命令详解

简介 UFW(Uncomplicated Firewall) 简单防火墙是一款基于 iptables 构建的、用于管理防火墙规则的用户友好型工具。它简化了在 Linux 系统上配置防火墙的过程。 安装 在 Ubuntu/Debian 上安装 sudo apt update sudo apt install ufw在 CentOS/Red Hat 上安装 sudo yum ins…...

3248. 矩阵中的蛇

3248. 矩阵中的蛇 题目链接&#xff1a;3248. 矩阵中的蛇 代码如下&#xff1a; class Solution { public:int finalPositionOfSnake(int n, vector<string>& commands){int i 0, j 0;for (string& command : commands){if (command "LEFT") { j…...

图片的懒加载

目录 懒加载的来源 事件监听 IntersectionObserver 懒加载的来源 图片的来加载其实就是延迟加载&#xff0c;我们知道浏览器的可视范围是有限的&#xff0c;现在网页的内容越来越丰富&#xff0c;一般网页的内容都是需要滚动才能完成浏览 如果网页有很多图片&#xff0c;然…...

网络脚本生成器

网络官网地址 网络配置生成工具 终端-接入-汇聚-核心-防火墙-互联网路由器 一 开局配置 华为设备配置命令 system-viewsysname SW-JR-Switchvlan 10 vlan 20 vlan 30 vlan 40 quitinterface Vlan-interface 40 ip address 192.168.40.1 255.255.255.0 quitip route-static 1…...

Kibana server is not ready yet

遇到“Kibana server is not ready yet”错误通常表示Kibana无法连接到Elasticsearch。以下是一些常见原因及其解决方案&#xff1a; 1.常见原因 1.1.Elasticsearch未运行&#xff1a; 确保Elasticsearch服务已启动并正常运行。您可以通过访问 http://localhost:9200 来检查…...

Git 高频命令及其功能、作用与使用场景

在软件开发的世界里&#xff0c;Git 已经成为了版本控制的代名词。无论你是开发小型项目还是参与大型团队协作&#xff0c;Git 都是你不可或缺的得力助手。今天我们来聊聊 Git 中的一些高频命令&#xff0c;了解它们的功能、作用以及常见的使用场景&#xff0c;帮助你在日常开发…...

将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式

文章目录 将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式MathType安装问题MathType30天试用延期MathPage.wll文件找不到问题 将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式 word自带公式编辑器编辑的公式格式&#xff1a; MathType编辑的格式&a…...

【HarmonyOS】Component组件引入报错 does not meet UI component syntax.

【HarmonyOS】Component组件引入报错 一、问题背景 有时会碰到引入组件时&#xff0c;无法import引入组件&#xff0c;导致引入的组件报错。 或者提示does not meet UI component syntax. &#xff08;不符合UI组件语法。&#xff09; 如下图所示&#xff0c;在引入组件时&a…...

力扣-图论-1【算法学习day.51】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…...

使用lumerical脚本语言创建定向耦合器并进行数据分析(纯代码实现)

本文使用lumerical脚本语言创建定向耦合器波导、计算定向耦合器的偶数和奇数模式、分析定向耦合器的波长依赖性、分析定向耦合器的间隙依赖性(代码均有注释详解)。 一、绘制定向耦合器波导 1.1 代码实现 # 这段代码主要实现了绘制定向耦合器波导几何结构的功能。通过定义各种…...

Java面试要点50 - List的线程安全实现:CopyOnWriteArrayList

文章目录 一、引入二、实现原理解析2.1 写时复制机制2.2 读写分离策略 三、性能测试分析四、应用场景分析4.1 事件监听器管理4.2 缓存实现 五、最佳实践建议5.1 性能优化技巧5.2 常见陷阱规避 总结 一、引入 在并发编程中,线程安全的集合类扮演着重要角色。CopyOnWriteArrayLi…...

python脚本实现csv中百度经纬度转84经纬度

数据准备 csv文件,带百度经纬度字段:bd09_x,bd09_y 目的 将百度经纬度转换为84经纬度,并在csv文件中添加两个字段:84_x,84_y python脚本 from ChangeCoordinate import ChangeCoordimport pandas as pd import numpy as npcoord = ChangeCoord()def bd09_to_wgs84...

Vue2和Vue3的区别

响应式系统 Vue 2 技术基础&#xff1a;使用 Object.defineProperty 实现响应式。局限性&#xff1a; 无法监听新增属性&#xff1a;如果在创建实例后添加新属性&#xff0c;这些属性不会自动成为响应式的。数组变更检测问题&#xff1a;直接通过索引设置值或长度不会触发更新…...

JavaEE-经典多线程样例

文章目录 单例模式设计模式初步引入为何存在单例模式饿汉式单例模式饿汉式缺陷以及是否线程安全懒汉式单例模式基础懒汉式缺陷以及是否线程安全懒汉式单例模式的改进完整代码(变量volatile) 阻塞队列生产者消费者模型生产者消费者模型的案例以及优点请求与响应案例解耦合削峰填…...

Android显示系统(04)- OpenGL ES - Shader绘制三角形

一、前言&#xff1a; OpenGL 1.0采用固定管线&#xff0c;OpenGL 2.0以上版本重要的改变就是采用了可编程管线&#xff0c;Shader 编程是指使用着色器&#xff08;Shader&#xff09;编写代码来控制图形渲染管线中特定阶段的处理过程。在图形渲染中&#xff0c;着色器是在 GP…...

PMP–一、二、三模、冲刺–分类–10.沟通管理

文章目录 技巧十、沟通管理 一模10.沟通管理--1.规划沟通管理--文化意识--军事背景和非军事背景人员有文化差异5、 [单选] 项目团队由前军事和非军事小组成员组成。没有军事背景的团队成员认为前军事团队成员在他们的项目方法中过于结构化和僵化。前军事成员认为其他团队成员更…...

flutter windows 使用c++、dll等实践记录

在flutter的windows平台引入dll文件 https://juejin.cn/post/7223676609794015287 google官方说法&#xff08;感觉不太实用&#xff09; https://groups.google.com/a/dartlang.org/g/misc/c/fyh2W38AEVo Using a C DLL in Flutter Windows desktop app&#xff08;未尝试&…...

JUnit介绍:单元测试

1、什么是单元测试 单元测试是针对最小的功能单元编写测试代码&#xff08;Java 程序最小的功能单元是方法&#xff09;单元测试就是针对单个Java方法的测试。 2、为什么要使用单元测试 确保单个方法运行正常&#xff1b; 如果修改了代码&#xff0c;只需要确保其对应的单元…...

电脑插入耳机和音响,只显示一个播放设备

1. 控制面板-硬件和声音-Realtek高清音频-扬声器-设备高级设置-播放设备里选择使用前部和后部输出设备同时播放两种不同的音频流 在声音设置中就可以看到耳机播放选项...

【每日刷题】Day162

【每日刷题】Day162 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 3302. 字典序最小的合法序列 - 力扣&#xff08;LeetCode&#xff09; 2. 44. 通配符匹配 - 力扣&…...

使用 EasyExcel 实现高效的 Excel 读写操作

在日常开发中&#xff0c;Excel 文件的读写操作是一个常见的需求。EasyExcel 是阿里巴巴开源的一个高性能、易用的 Excel 读写库&#xff0c;可以大幅提高处理 Excel 文件的效率。它通过事件驱动模型优化了大数据量 Excel 的读写性能&#xff0c;非常适合处理大文件或高并发场景…...

千益畅行,旅游卡有些什么优势?

千益畅行共享旅游卡是一种创新的旅游服务模式&#xff0c;旨在通过整合各类旅游资源&#xff0c;为用户提供一站式的旅游解决方案。这张旅游卡支持2至6人同行&#xff0c;涵盖了接机、酒店、用餐、大巴、导游、景区门票等服务&#xff0c;用户只需自行承担往返交通费用即可享受…...

Hive分区裁剪(Partition Pruning)详解

Hive分区裁剪是一种优化技术&#xff0c;旨在查询时只读取与条件匹配的分区&#xff0c;从而减少不必要的数据扫描。这种机制依赖于分区表的设计和查询优化器的工作&#xff0c;特别是在处理大规模数据时&#xff0c;分区裁剪可以显著提高查询性能。 1. 什么是分区裁剪&#xf…...

云原生数据库 PolarDB

PolarDB 是阿里云推出的一款云原生数据库&#xff0c;旨在为企业提供高性能、高可靠性的数据库解决方案。它基于云计算环境设计&#xff0c;特别适用于云上的大规模数据处理和存储需求。PolarDB 是一种兼具关系型数据库&#xff08;RDS&#xff09;和分布式数据库特性的新型数据…...

数据库原理-期末基础知识

1、数据库管理系统有哪些功能&#xff1f; 数据定义功能、数据操作功能、数据库的运行管理、数据库的建立与维护。 2、数据库设计分哪几个阶段&#xff1f; 需求分析->概念设计->逻辑设计->物理设计->数据库实施->数据的运营与维护 3、简述三级封锁协议的内…...

Java版-速通数据结构-树基础知识

现在面试问mysql,红黑树好像都是必备问题了。动不动就让手写红黑树或者简单介绍下红黑树。然而&#xff0c;我们如果直接去看红黑树&#xff0c;可能会一下子蒙了。在看红黑树之前&#xff0c;需要先了解下树的基础知识&#xff0c;从简单到复杂&#xff0c;看看红黑树是在什么…...

量化交易系统开发-实时行情自动化交易-8.4.MT4/MT5平台

19年创业做过一年的量化交易但没有成功&#xff0c;作为交易系统的开发人员积累了一些经验&#xff0c;最近想重新研究交易系统&#xff0c;一边整理一边写出来一些思考供大家参考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下来会对于MT4/MT5平台介绍。 MetaT…...

Git 的基本概念和使用方式

Git是一个分布式版本控制系统&#xff0c;用于跟踪文件内容的变化和协作开发。 Git的主要概念包括&#xff1a; 仓库&#xff08;Repository&#xff09;&#xff1a;存储代码和历史记录的地方。可以是本地仓库&#xff08;Local Repository&#xff09;或远程仓库&#xff08…...

Conda-Pack打包:高效管理Python环境

在Python开发中&#xff0c;环境管理是一个不可忽视的重要环节。Conda是一个流行的包管理器和环境管理器&#xff0c;它允许用户创建隔离的环境&#xff0c;以避免不同项目之间的依赖冲突。Conda-pack是一个工具&#xff0c;可以帮助我们将一个conda环境打包成一个可移植文件&a…...

Python语法基础---正则表达式

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 我们这个文章所讲述的&#xff0c;也是数据分析的基础文章&#xff0c;正则表达式 首先&#xff0c;我们在开始之前&#xff0c;引出一个问题。也是我们接下来想要解决的问题。…...

深入理解ROS中的参数服务器及其应用

深入理解ROS中的参数服务器及其应用 在Robot Operating System (ROS) 中&#xff0c;参数服务器&#xff08;Parameter Server&#xff09;是一个中心化服务&#xff0c;它允许节点在运行时存储和检索配置信息。这种机制是为了支持数据的共享和灵活的参数管理而设计的&#xf…...

Kafka 常见面试题深度解析

一、基础概念 1. 请简要介绍 Kafka 的基本架构。 Kafka 主要由生产者&#xff08;Producer&#xff09;、消费者&#xff08;Consumer&#xff09;、代理&#xff08;Broker&#xff09;、主题&#xff08;Topic&#xff09;和分区&#xff08;Partition&#xff09;等组成。…...

数学建模之熵权法

熵权法 概述 **熵权法(Entropy Weight Method,EWM)**是一种客观赋权的方法&#xff0c;原理&#xff1a;指标的变异程度越小&#xff0c;所包含的信息量也越小&#xff0c;其对应的权值应该越低&#xff08;例如&#xff0c;如果对于所有样本而言&#xff0c;某项指标的值都相…...

交易所 Level-2 历史行情数据自动化导入攻略

用户部署完 DolphinDB 后&#xff0c;需要将历史股票数据批量导入数据库&#xff0c;再进行数据查询、计算和分析等操作。DolphinDB 开发了 ExchData 模块&#xff0c;主要用于沪深交易所 Level-2 行情原始数据的自动化导入&#xff0c;目前已支持的数据源包括&#xff1a; 沪…...