Java常见数据结构---八大结构

  前言:

数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 

常见的八大数据结构:

 栈:

思想:

栈是一种数据结构,它遵循后进先出 (LIFO) 原则。这意味着最后添加的元素(称为栈顶元素)将首先被移除。

特点:

  • **简单性和效率:**栈的操作(push、pop、peek)可以在常数时间内完成。
  • **后进先出:**栈的 LIFO 特性使其非常适合需要按添加顺序处理元素的应用。
  • 可以理解为子弹夹一样,先进后出,后出先进

 

 数据进入栈模型的过程称为:压/进栈

  数据出栈模型的过程称为:弹/出栈

代码: 

public class Stack {

    private int[] arr;
    private int top;
    private int capacity;

    public Stack(int capacity) {
        this.arr = new int[capacity];
        this.top = -1;
        this.capacity = capacity;
    }

    public void push(int element) {
        if (isFull()) {
            System.out.println("Stack overflow");
            return;
        }

        arr[++top] = element;
    }

    public int pop() {
        if (isEmpty()) {
            System.out.println("Stack underflow");
            return -1;
        }

        return arr[top--];
    }

    public int peek() {
        if (isEmpty()) {
            System.out.println("Stack is empty");
            return -1;
        }

        return arr[top];
    }

    public boolean isEmpty() {
        return top == -1;
    }

    public boolean isFull() {
        return top == capacity - 1;
    }

    public static void main(String[] args) {
        Stack stack = new Stack(5);

        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);

        System.out.println("Top element: " + stack.peek());

        stack.pop();
        stack.pop();

        System.out.println("Top element: " + stack.peek());
    }
}

过程:

过程解释:

  1. 创建栈:我们创建一个容量为 5 的栈对象。栈是用数组实现的,其中 top 变量跟踪栈顶元素的索引。
  2. 压入元素:push 方法将元素压入栈中。如果栈已满,它会打印一条错误消息。
  3. 弹出元素:pop 方法从栈中移除并返回栈顶元素。如果栈为空,它会打印一条错误消息。
  4. 查看栈顶元素:peek 方法返回栈顶元素,但不将其移除。如果栈为空,它会打印一条错误消息。
  5. 检查栈是否为空:isEmpty 方法检查栈是否为空。
  6. 检查栈是否已满:isFull 方法检查栈是否已满。
  7. 主方法:**在主方法中,我们创建了一个栈对象,压入一些元素,弹出一些元素,并打印栈顶元素。

 最后输出:

Top element: 4

Top element: 2

 

队列:

思想:

队列是一种遵循先进先出 (FIFO) 原则的数据结构。这意味着队列中的第一个添加的元素将首先被移除。与栈恰恰相反,队列两端全开,遵循先进先出,后进后出的原则

特点:

  • 先进先出 (FIFO):队列遵循先进先出原则,这意味着第一个添加的元素将首先被移除。
  • 线性数据结构:队列是一种线性数据结构,这意味着元素按顺序排列。
  • 插入在末尾:新元素总是添加到队列的末尾(也称为尾部)。
  • 删除在头部:元素从队列的头部(也称为前端)移除。
  • 限制访问:队列只允许在头部和尾部进行插入和删除操作。中间元素无法直接访问。
  • 队列大小:队列可以是固定大小的(使用数组实现)或动态大小的(使用链表实现)。
  • 广泛的应用:队列在计算机科学中有广泛的应用,例如消息传递、任务调度、缓冲和广度优先搜索

  

代码: 

import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {

    public static void main(String[] args) {
        // 创建一个队列
        Queue<Integer> queue = new LinkedList<>();

        // 向队列中添加元素
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.add(4);

        // 从队列中移除元素
        int removedElement = queue.remove(); // 移除并返回第一个元素

        // 查看队列中的第一个元素
        int headElement = queue.peek(); // 返回第一个元素,但不将其移除

        // 检查队列是否为空
        boolean isEmpty = queue.isEmpty();

        // 打印队列中的元素
        System.out.println("Queue elements: " + queue);

        // 打印移除的元素
        System.out.println("Removed element: " + removedElement);

        // 打印队列头部的元素
        System.out.println("Head element: " + headElement);

        // 打印队列是否为空
        System.out.println("Queue is empty: " + isEmpty);
    }
}

输出:

Queue elements: [2, 3, 4]
Removed element: 1
Head element: 2
Queue is empty: false

过程: 

  1. 创建队列:我们使用 Java 的 LinkedList 类创建一个队列。LinkedList 实现了 Queue 接口,它提供了队列的基本操作。
  2. 添加元素:add 方法将元素添加到队列的末尾。
  3. 移除元素:remove 方法从队列中移除并返回第一个元素。
  4. 查看队列头部的元素:peek 方法返回队列中的第一个元素,但不将其移除。
  5. 检查队列是否为空:isEmpty 方法检查队列是否为空。

数组:

思想:

数组是一种数据结构,它存储固定数量的相同类型元素的集合。数组中的元素使用索引进行访问,索引从 0 开始。

数组相对其他数据结构相对来说比较简单理解,可以理解为是一组元素,起始值下标从0开始

  1. 查询速度快:查询数据通过地址值和索引定位,查询任意数据耗时相同。 
  2. 删除效率低:要将原始数据删除,同时后面每个数据前移。 

代码: 

public class Array {

    public static void main(String[] args) {
        // 声明一个长度为 7 的整型数组
        int[] arr = {1, 2, 3, 4, 5, 6, 7};

        // 遍历数组并打印每个元素
        for (int element : arr) {
            System.out.println(element);
        }
    }
}

 过程:

  1. 声明数组:我们声明一个长度为 7 的整型数组,并使用花括号初始化其元素。
  2. 遍历数组:使用增强 for 循环遍历数组并打印每个元素。

链表:

思想:

链表是一种数据结构,它由一组称为节点的对象组成。每个节点包含一个数据项和指向下一个节点的引用。

在 Java 中,链表使用以下类实现:

  • LinkedList:一个双向链表,允许在列表的任何位置添加和删除元素。
  • ArrayList:一个基于数组的列表,在列表末尾添加和删除元素非常高 

链表中的元素是游离存储的,每个元素节点包含数据值和下一个元素的地址。 

链表是一种增删快、查询慢的模型(对比数组)

 

 代码:



public class LinkedList {

    public static void main(String[] args) {
        // 创建一个链表
        LinkedList<String> list = new LinkedList<>();

        // 向链表中添加元素
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");

        // 遍历链表并打印每个元素
        for (String fruit : list) {
            System.out.println(fruit);
        }

        // 从链表中删除元素
        list.remove("Banana");

        // 打印修改后的链表
        System.out.println("Modified list:");
        for (String fruit : list) {
            System.out.println(fruit);
        }
    }
}

输出:

Modified list:Apple  Orange

Banana元素已经被链表删除

二叉树:

思想:

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分 [1]。

特点:

 只能有一个根节点,每个节点最多支持2个直接子节点。

节点的度: 节点拥有的子树的个数,二叉树的度不大于2 叶子节点 度为0的节点,也称之为终端结点。

高度:叶子结点的高度为1,叶子结点的父节点高度为2,以此类推,根节点的高度最高。

层:根节点在第一层,以此类推

兄弟节点 :拥有共同父节点的节点互称为兄弟节点

代码:

 

public class BinaryTree {

    private Node root;

    public void add(int data) {
        root = addRecursive(root, data);
    }

    private Node addRecursive(Node current, int data) {
        if (current == null) {
            return new Node(data);
        }

        if (data < current.data) {
            current.left = addRecursive(current.left, data);
        } else if (data > current.data) {
            current.right = addRecursive(current.right, data);
        }

        return current;
    }

    public boolean contains(int data) {
        return containsRecursive(root, data);
    }

    private boolean containsRecursive(Node current, int data) {
        if (current == null) {
            return false;
        }

        if (data == current.data) {
            return true;
        } else if (data < current.data) {
            return containsRecursive(current.left, data);
        } else {
            return containsRecursive(current.right, data);
        }
    }

    public static void main(String[] args) {
        BinaryTree tree = new BinaryTree();
        tree.add(10);
        tree.add(5);
        tree.add(15);

        System.out.println("Contains 5: " + tree.contains(5));
        System.out.println("Contains 12: " + tree.contains(12));
    }
}

class Node {
    int data;
    Node left;
    Node right;

    public Node(int data) {
        this.data = data;
    }
}

 过程:

  1. 添加元素:add() 方法使用递归将元素添加到二叉树中。它将新元素与当前节点进行比较,并将其添加到左子树或右子树中,具体取决于元素的值。
  2. 查找元素:contains() 方法使用递归在二叉树中查找元素。它将查找值与当前节点进行比较,并根据需要递归地遍历左子树或右子树。
  3. 主方法:main() 方法创建二叉树并向其中添加元素。然后,它调用 contains() 方法来查找树中是否存在特定值。
  4. 输出:Contains 5: true Contains 12: false

二叉查找树:

思想:

二叉搜索树又被称为排序树,它或者是一颗空树,或者是一棵具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

 特点:

1,每一个节点上最多有两个子节点

2,左子树上所有节点的值都小于根节点的值

3,右子树上所有节点的值都大于根节点的值 

目的:提高检索数据的性能。

不同点:

二叉树

  • 每个节点最多有两个子节点(左子节点和右子节点)。
  • 没有排序规则。
  • 可以用于表示各种数据结构,例如堆和哈夫曼树

二叉搜索树(BST)

  • 一个特殊的二叉树,其中每个节点的值都比其左子树的所有值大,并且比其右子树的所有值小。
  • 具有以下性质:
    • 左子树中的所有值都小于根节点的值。
    • 右子树中的所有值都大于根节点的值。
    • 左子树和右子树都是二叉搜索树

区别

二叉搜索树和二叉树之间的主要区别在于排序规则

  • 二叉树没有排序规则,而二叉搜索树中的节点根据其值进行排序

代码: 

public class BinarySearchTree {

    private Node root;

    public void add(int data) {
        root = addRecursive(root, data);
    }

    private Node addRecursive(Node current, int data) {
        if (current == null) {
            return new Node(data);
        }

        if (data < current.data) {
            current.left = addRecursive(current.left, data);
        } else if (data > current.data) {
            current.right = addRecursive(current.right, data);
        }

        return current;
    }

    public boolean contains(int data) {
        return containsRecursive(root, data);
    }

    private boolean containsRecursive(Node current, int data) {
        if (current == null) {
            return false;
        }

        if (data == current.data) {
            return true;
        } else if (data < current.data) {
            return containsRecursive(current.left, data);
        } else {
            return containsRecursive(current.right, data);
        }
    }

    public static void main(String[] args) {
        BinarySearchTree tree = new BinarySearchTree();
        tree.add(10);
        tree.add(5);
        tree.add(15);

        System.out.println("Contains 5: " + tree.contains(5));
        System.out.println("Contains 12: " + tree.contains(12));
    }
}

class Node {
    int data;
    Node left;
    Node right;

    public Node(int data) {
        this.data = data;
    }
}

 过程:

 

  1. 添加元素:add() 方法使用递归将元素添加到二叉查找树中。它将新元素与当前节点进行比较,并将其添加到左子树或右子树中,具体取决于元素的值。
  2. 查找元素:contains() 方法使用递归在二叉查找树中查找元素。它将查找值与当前节点进行比较,并根据需要递归地遍历左子树或右子树。
  3. 主方法:main() 方法创建二叉查找树并向其中添加元素。然后,它调用 contains() 方法来查找树中是否存在特定值

输出:

Contains 5: true
Contains 12: false

平衡二叉树:

思想:

平衡二叉树是一种特殊的二叉搜索树,其中每个节点的左子树和右子树的高度差至多为 1。这确保了树在很大程度上保持平衡,并且查找、插入和删除操作的时间复杂度为 O(log n),其中 n 是树中的节点数。

 平衡二叉树可以通过使用称为旋转的操作来实现。旋转是重新排列树中节点以维护平衡的一种方法。AVL 树和红黑树使用不同的旋转规则来保持平衡。

平衡二叉树是在满足查找二叉树的大小规则下,让树尽可能矮小,以此提高查数据的性能。  

代码: 

public class AVLTree {

    private Node root;

    public void add(int data) {
        root = addRecursive(root, data);
    }

    private Node addRecursive(Node current, int data) {
        if (current == null) {
            return new Node(data);
        }

        if (data < current.data) {
            current.left = addRecursive(current.left, data);
        } else if (data > current.data) {
            current.right = addRecursive(current.right, data);
        }

        updateHeight(current);
        return balance(current);
    }

    private Node balance(Node current) {
        int balanceFactor = getBalanceFactor(current);

        if (balanceFactor > 1) {
            if (getBalanceFactor(current.left) < 0) {
                current.left = leftRotate(current.left);
            }
            return rightRotate(current);
        } else if (balanceFactor < -1) {
            if (getBalanceFactor(current.right) > 0) {
                current.right = rightRotate(current.right);
            }
            return leftRotate(current);
        }

        return current;
    }

    private int getBalanceFactor(Node node) {
        if (node == null) {
            return 0;
        }
        return height(node.left) - height(node.right);
    }

    private int height(Node node) {
        if (node == null) {
            return 0;
        }
        return node.height;
    }

    private void updateHeight(Node node) {
        node.height = 1 + Math.max(height(node.left), height(node.right));
    }

    private Node leftRotate(Node node) {
        Node newRoot = node.right;
        node.right = newRoot.left;
        newRoot.left = node;

        updateHeight(node);
        updateHeight(newRoot);

        return newRoot;
    }

    private Node rightRotate(Node node) {
        Node newRoot = node.left;
        node.left = newRoot.right;
        newRoot.right = node;

        updateHeight(node);
        updateHeight(newRoot);

        return newRoot;
    }

    public static void main(String[] args) {
        AVLTree tree = new AVLTree();
        tree.add(10);
        tree.add(5);
        tree.add(15);

        System.out.println("Inorder traversal of the AVL tree:");
        inorderTraversal(tree.root);
    }

    private static void inorderTraversal(Node node) {
        if (node != null) {
            inorderTraversal(node.left);
            System.out.print(node.data + " ");
            inorderTraversal(node.right);
        }
    }
}

class Node {
    int data;
    Node left;
    Node right;
    int height;

    public Node(int data) {
        this.data = data;
        this.height = 1;
    }
}

过程: 

  1. 添加元素:add() 方法使用递归将元素添加到 AVL 树中。它将新元素与当前节点进行比较,并将其添加到左子树或右子树中,具体取决于元素的值。添加后,它更新节点的高度并平衡树以保持 AVL 性质。
  2. 平衡树:balance() 方法检查节点的平衡因子并执行必要的旋转以平衡树。
  3. 获取平衡因子:getBalanceFactor() 方法计算节点的平衡因子,它等于左子树的高度减去右子树的高度。
  4. 获取高度:height() 方法计算节点的高度,它等于其子树中最大高度加 1。
  5. 更新高度:updateHeight() 方法更新节点的高度,它等于其子树中最大高度加 1。
  6. 左旋转:leftRotate() 方法执行左旋转操作,它将当前节点的右子树作为新根,并将当前节点作为新根的左子树。
  7. 右旋转:rightRotate() 方法执行右旋转操作,它将当前节点的左子树作为新根,并将当前节点作为新根的右子树。
  8. 主方法:main() 方法创建 AVL 树并向其中添加元素。然后,它打印树的中序遍历以显示树的顺序。

结果: 

Inorder traversal of the AVL tree:
5 10 15
 

红黑树:

规则: 

 每一个节点或是红色的,或者是黑色的,根节点必须是黑色。

如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)。

对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。

 

当添加的节点为根节点时,直接变成黑色就可以了 

 

 代码:

import java.util.ArrayList;
import java.util.List;

public class RedBlackTree {

    private Node root;

    public void add(int data) {
        root = addRecursive(root, data);
        root.color = Color.BLACK;
    }

    private Node addRecursive(Node current, int data) {
        if (current == null) {
            return new Node(data);
        }

        if (data < current.data) {
            current.left = addRecursive(current.left, data);
        } else if (data > current.data) {
            current.right = addRecursive(current.right, data);
        }

        if (isRed(current.left) && isRed(current.right)) {
            flipColors(current);
        }

        if (isRed(current.left) && isRed(current.left.left)) {
            current = rightRotate(current);
        }

        if (isRed(current.right) && isRed(current.right.right)) {
            current = leftRotate(current);
        }

        return current;
    }

    private void flipColors(Node node) {
        node.color = Color.RED;
        node.left.color = Color.BLACK;
        node.right.color = Color.BLACK;
    }

    private Node rightRotate(Node node) {
        Node newRoot = node.left;
        node.left = newRoot.right;
        newRoot.right = node;

        newRoot.color = node.color;
        node.color = Color.RED;

        return newRoot;
    }

    private Node leftRotate(Node node) {
        Node newRoot = node.right;
        node.right = newRoot.left;
        newRoot.left = node;

        newRoot.color = node.color;
        node.color = Color.RED;

        return newRoot;
    }

    private boolean isRed(Node node) {
        return node != null && node.color == Color.RED;
    }

    public static void main(String[] args) {
        RedBlackTree tree = new RedBlackTree();
        int[] data = {20, 18, 23, 20, 16, 24, 19};
        for (int value : data) {
            tree.add(value);
        }

        List<Node> redNodes = new ArrayList<>();
        inorderTraversal(tree.root, redNodes);

        System.out.println("Red nodes in the Red-Black tree:");
        for (Node node : redNodes) {
            System.out.print(node.data + " ");
        }
    }

    private static void inorderTraversal(Node node, List<Node> redNodes) {
        if (node != null) {
            inorderTraversal(node.left, redNodes);
            if (node.color == Color.RED) {
                redNodes.add(node);
            }
            inorderTraversal(node.right, redNodes);
        }
    }

    private enum Color {
        RED,
        BLACK
    }

    private static class Node {
        int data;
        Node left;
        Node right;
        Color color;

        public Node(int data) {
            this.data = data;
            this.color = Color.RED;
        }
    }
}

步骤:

           20(B)
             /  \
           18(R) 23(R)
          /   /  \
        16(B) 20(R) 24(B)
               /
             19(R)

红色节点R表示,黑节点B表示

 总结:

红黑树不是高度平衡的,它的平衡是通过"红黑规则"进行实现的 

每一个节点或是红色的,或者是黑色的,根节点必须是黑色

如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的;

如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况) 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JL-杰理芯片-认识TA的SDK的第二天

耳机升级 测试盒的有线升级和无线升级&#xff08;要加key&#xff09; 烧录器的有线升级&#xff08;不要key&#xff09;&#xff08;强制升级&#xff09; 一拖八的强制升级 测试盒无线升级 要求&#xff1a;耳机的主控&#xff08;芯片&#xff09;至少是D4的 测试盒设…

WordPress中插入视频的两种方法详解

最近我在建设WordPress网站的时候需要上传视频&#xff0c;我使用的是Hostease的主机安装的WordPress&#xff0c;随后在咨询了他们的技术支持后获得了一些解决方法。下面将介绍WordPress中插入视频的两种方法&#xff1a;本地上传和外部引用。 本地上传视频 使用WordPress的古…

springmvc核心流程

核心流程及配置 核心流程 执行流程 用户发送请求到DispatcherServlet前端控制器&#xff0c;前端控制器收到请求后自己不进行处理&#xff0c;而是委托给其他的解析器进行处理&#xff0c;作为统一访问点&#xff0c;进行全局的流程控制 DispatcherServlet调用HandlerMapping映…

Postman基础功能-Collection和批量运行

一、Collection&#xff08;集合&#xff09;介绍 当我们对一个或多个系统中的很多接口用例进行维护时&#xff0c;首先想到的就是对接口用例进行分类管理&#xff0c;同时还希望对这批接口用例做回归测试。 在 Postman 中也提供了这样一个功能&#xff0c;就是 Collec…

基础ArkTS组件:帧动画,内置动画组件,跑马灯组件(HarmonyOS学习第三课【3.6】)

帧动画 帧动画也叫序列帧动画&#xff0c;其原理就是在时间轴的每帧上逐帧绘制不同的内容&#xff0c;使其连续播放而成动画。ArkUI开发框架提供了 ImageAnimator 组件实现帧动画能力&#xff0c;本节笔者介绍一下 ImageAnimator 组件的简单使用。 官方文献 说明 该组件从A…

亚马逊测评实操干货,跨境电商做测评,卖家店铺测评攻略!

亚马逊在全球有超过 2 亿付费 Prime 会员和数以亿计的活跃买家账户&#xff0c;卖家们可以通过亚马逊一流的国际物流扩展业务。这是一个知名度极高的老牌跨境电商平台&#xff0c;而且平台流量非常大&#xff0c;成功打造爆款Listing这是每位亚马逊卖家渴望的诉求&#xff0c;做…

拿走不谢,送你一份HCIA自学攻略

HCIE固然是许多网络工程师梦寐以求的认证&#xff0c;但攀登这座高峰之前&#xff0c;先要稳扎稳打地从华为认证HCIA开始。 对于零基础的学员来说&#xff0c;自学HCIA不仅是一个挑战&#xff0c;更是一次宝贵的学习机会&#xff0c;为以后学习IP、IE打基础。 以HCIA数通方向…

专家报告+现场实操!和鲸社区携手武汉大学举办地理空间智能学术研讨会及编程工作坊,限时开启报名!

AI技术被深度应用在地理科学领域后&#xff0c;给科学研究及行业落地应用带来了机遇&#xff0c;同样也带来了挑战。 5月25日武汉大学&#xff0c;和鲸社区联合武汉大学遥感信息工程学院、中国地质大学&#xff08;武汉&#xff09;地理与信息工程学院邀请了来自高校、研究机构…

huggingface:利用git克隆目标资源

前言 因为有很多模型资源都被放在了huggingface上&#xff0c;为了下载它们&#xff0c;着实让一个不懂git的人犯了难&#xff0c;绕了很多远路&#xff0c;甚至将不需要解决的问题也都拿上了台面&#xff0c;因此我将在本篇博客中记载一些关于【huggingface】中利用git克隆目标…

Unsupervised Image-to-Image Translation Networks

Unsupervised Image-to-Image Translation Networks 无监督图像到图像翻译网络 Ming-Yu Liu, Thomas Breuel, Jan Kautz 刘明玉&#xff0c;Thomas Breuel&#xff0c;Jan Kautz NVIDIA {mingyul,tbreuel,jkautz}nvidia.com NVIDIA {mingyul&#xff0c;tbreuel&#xff0c;j…

《系统管理学报》期刊投稿经验与流程分享(一轮退修,历时3月)

双非研二&#xff0c;三作&#xff08;导师一作&#xff0c;师哥二作&#xff09;&#xff0c;《系统管理学报》期刊录用 投稿网址&#xff1a;https://xtglxb.sjtu.edu.cn/journalx_jgxb/authorLogOn.action 投稿&收稿&#xff1a;2022年12月26日初审&#xff1a;2023年…

设计公司图纸防泄密|图纸加密软件推荐

随着信息技术的快速发展&#xff0c;设计行业面临着前所未有的挑战和机遇。然而&#xff0c;随着设计图纸的电子化存储和传输越来越普遍&#xff0c;如何确保图纸的安全性、防止泄密成为了一个亟待解决的问题。针对这一问题&#xff0c;设计行业专用图纸加密软件应运而生&#…

MyBatis——在WEB中使用MyBatis(MVC架构模式)

一、在 Web 应用中使用 MyBatis 项目目录结构 pojo package org.qiu.bank.pojo;/*** 账户类&#xff0c;封装账户数据* author 秋玄* version 1.0* package org.qiu.bank.pojo* date 2022-09-27-20:31* since 1.0*/ public class Account {private Long id;private String …

华为ensp中路由器IPSec VPN原理及配置命令(超详解)

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年5月13日2点11分 虚拟专用网络&#xff08;VPN&#xff09;是一种通过公用网络建立安全连接的技术。它可以使您的设备看起来像是连接到另一个网络&#xff0c;例如公司…

Skywalking 8.x部署

一、下载版本 Skywalking 官网下载地址 版本地址 大家各自选取对应的版本即可 解压后&#xff1a; 二、修改配置 找到config目录下的application.yml 1. 修改存储方式为mysql 修改数据库jdbc连接信息 下一步懂得都懂,那肯定就需要mysql-connector-java-8.0.16写入mysql的…

智能自助终端RK3288全国产化主板在自助收银项目的应用,支持鸿蒙

智能自助终端主板IoT-3288A推出了自助收银终端&#xff0c;主要面向商场、超市、餐厅、零售店等门店收银场景。顾客在条形码扫描框前扫描要选购的商品后&#xff0c;可以选择扫码支付、刷脸支付和会员卡/购物卡支付&#xff0c;大幅提升收银效率&#xff0c;极大程度的降低人力…

redis的跳表

typedef struct zskiplistNode {// 分值double score;// 成员对象robj *obj;// 后退指针struct zskiplistNode *backward;// 层struct zskiplistLevel {// 前进指针struct zskiplistNode *forward;// 跨度unsigned int span;} level[]; } zskiplistNode;跳表的节点查找算法可以…

NR SRB传输的RRC messages

有朋友对SRB会传输哪些消息有疑问&#xff0c;这里以R15 38.331 为例做简单总结。 SRB0 SRB0 就不说了&#xff0c;罗列如上。 SRB2 SRB2用于NAS消息的发送&#xff0c;全部使用DCCH逻辑信道。 SRB2的优先级低于SRB1&#xff0c;网络会在AS安全激活后配置。 具体到38.331中就是…

SAP-CentralFinance - 学习心得3 - 应付账款与物料管理之间的集成

业务示例 工厂 1010 需要轮胎和内胎。负责的采购组织将相应的采购订单交给了某知名供应商。数天之后&#xff0c;先收到了货物&#xff0c;然后收到了发票。 物料管理中的组织单位 物流的中央组织对象为工厂。工厂是公司的运营范围或分支。工厂可以是集中交货仓库、地区销售…

FastAPI:Python打造高效API的终极武器

在Python的世界里&#xff0c;如果你想要一个既快速又现代的方式来构建API&#xff0c;那么FastAPI可能是你的首选。这个库基于Starlette&#xff08;用于Web编程&#xff09;和Pydantic&#xff08;用于数据验证&#xff09;&#xff0c;专门为速度和易用性设计。 什么是FastA…