【链 表】

news2025/2/26 9:23:24

【链表】

  • 一级目录
      • 1. 基本概念
      • 2. 算法分析
        • 2.1 时间复杂度
        • 2.2 空间复杂度
        • 2.3 时空复杂度互换
      • 线性表的概念
      • 线性表的举例
      • 顺序表的基本概念
      • 顺序表的基本操作
        • 1. 初始化
        • 2. 插入操作
        • 3. 删除操作
        • 4. 查找操作
        • 5. 遍历操作
      • 顺序表的优缺点总结
        • 优点
        • 缺点
      • 树形结构
      • 图形结构
      • 单链表基本概念
      • 链表的分类
      • 单链表节点设置
        • Python 实现
        • C++ 实现
      • 单链表初始化
        • Python 实现
        • C++ 实现
      • 单链表增加节点
        • 尾部插入
        • Python 实现
        • C++ 实现
      • 单链表的遍历
        • Python 实现
        • C++ 实现
      • 单链表的销毁
        • Python 实现
        • C++ 实现
      • 链表的优缺点
        • 优点
        • 缺点
      • 循环链表
        • 循环链表节点设置与单链表相同,以下是循环链表初始化和尾部插入的 Python 示例:
      • 双向链表的概念
      • 基本操作
      • 节点设计
        • Python 实现
        • C++ 实现
      • 初始化
        • Python 实现
        • C++ 实现
      • 插入节点
        • Python 实现
        • C++ 实现
      • 剔除节点
        • Python 实现
        • C++ 实现
      • 链表的遍历
        • Python 实现
        • C++ 实现
      • 销毁链表
        • Python 实现
        • C++ 实现
      • 适用场合
      • 1. Linux 内核链表概述
      • 2. 容器与通用性
        • 容器概念
        • 通用性体现
      • 3. 节点的设计
      • 4. 增删操作
        • 初始化链表
        • 添加节点
        • 删除节点
      • 5. 查找结点
      • 6. 遍历链表
        • `list_for_each`
        • `list_for_each_entry`

一级目录

1. 基本概念

在计算机科学里,算法是为解决特定问题而设计的一系列明确且有限的指令。算法分析的核心目标是评估算法的效率与性能,一般从时间和空间两个维度展开。

  • 输入:算法运行所需的初始数据。
  • 输出:算法处理输入数据后得到的结果。
  • 确定性:算法的每个步骤都有明确的定义,不存在歧义。
  • 有穷性:算法必须在有限的步骤内结束。
  • 有效性:算法的每个步骤都能在有限时间内完成,并且是可行的。

在这里插入图片描述

2. 算法分析

2.1 时间复杂度

时间复杂度用于衡量算法执行所花费的时间随输入规模增长而变化的趋势,它不关注具体的执行时间,而是关注算法执行时间与输入规模之间的函数关系通常用大 O O O 符号来表示。

  • 常见时间复杂度
    • 常数时间复杂度 O ( 1 ) O(1) O(1):算法的执行时间不随输入规模的变化而变化。例如,访问数组中的某个元素:
def access_element(arr, index):
    return arr[index]
- **线性时间复杂度 $O(n)$**:算法的执行时间与输入规模 $n$ 成正比。例如,遍历数组中的每个元素:
def traverse_array(arr):
    for element in arr:
        print(element)
- **对数时间复杂度 $O(log n)$**:算法的执行时间随输入规模的对数增长。常见于二分查找算法:
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1
- **平方时间复杂度 $O(n^2)$**:算法的执行时间与输入规模的平方成正比。例如,冒泡排序算法:
def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr
2.2 空间复杂度

空间复杂度用于衡量算法在执行过程中所占用的存储空间随输入规模增长而变化的趋势,同样用大 O O O 符号表示。

  • 常见空间复杂度
    • 常数空间复杂度 O ( 1 ) O(1) O(1):算法执行过程中所占用的存储空间不随输入规模的变化而变化。例如,交换两个变量的值:
def swap(a, b):
    temp = a
    a = b
    b = temp
    return a, b
- **线性空间复杂度 $O(n)$**:算法执行过程中所占用的存储空间与输入规模 $n$ 成正比。例如,创建一个长度为 $n$ 的数组:
def create_array(n):
    return [0] * n
2.3 时空复杂度互换

在算法设计中,时间复杂度和空间复杂度往往是相互制约的。有时候可以通过增加空间开销来降低时间复杂度,或者通过增加时间开销来减少空间复杂度,这就是时空复杂度互换。

  • 以空间换时间
    • 原理:利用额外的存储空间来存储中间结果或数据,从而减少重复计算,降低时间复杂度。
    • 示例:斐波那契数列的计算。传统的递归方法时间复杂度为 O ( 2 n ) O(2^n) O(2n),但可以使用动态规划的方法,通过一个数组来存储中间结果,将时间复杂度降低到 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)
def fibonacci(n):
    if n == 0 or n == 1:
        return n
    dp = [0] * (n + 1)
    dp[1] = 1
    for i in range(2, n + 1):
        dp[i] = dp[i - 1] + dp[i - 2]
    return dp[n]
  • 以时间换空间
    • 原理:减少存储空间的使用,通过重复计算或其他方式来弥补空间的不足,从而增加时间复杂度。
    • 示例:在某些情况下,如果不使用额外的数组来存储中间结果,而是在每次需要时重新计算,就可以减少空间开销,但会增加时间开销。例如,在计算斐波那契数列时,可以使用迭代方法,只使用常数级的额外空间,但时间复杂度仍然是 O ( n ) O(n) O(n)
def fibonacci_iterative(n):
    if n == 0 or n == 1:
        return n
    a, b = 0, 1
    for i in range(2, n + 1):
        a, b = b, a + b
    return b

综上所述,算法分析中的时间复杂度、空间复杂度以及时空复杂度互换是设计和评估算法的重要概念,需要根据具体的问题和场景来选择合适的算法和策略。

线性表的概念

线性表(Linear List)是一种最基本、最简单的数据结构,它是由 n n n n ≥ 0 n \geq 0 n0)个数据元素(节点)组成的有限序列。

其中,除第一个元素外,每个元素都有且仅有一个直接前驱;除最后一个元素外,每个元素都有且仅有一个直接后继。数据元素之间呈现出一对一的线性关系。
在这里插入图片描述

线性表的举例

  • 学生信息表:假设要管理一个班级学生的信息,每个学生信息包含学号、姓名、年龄等。可以将每个学生的信息看作一个数据元素,这些学生信息按一定顺序排列就构成了一个线性表。例如,按照学号从小到大的顺序排列所有学生信息。
  • 图书列表:在图书馆管理系统中,每本图书的信息(如书名、作者、ISBN 号等)是一个数据元素,所有图书信息组成的列表就是一个线性表。

顺序表的基本概念

顺序表(Sequential List)是线性表的一种顺序存储结构,它是用一组地址连续的存储单元依次存储线性表中的各个数据元素,使得逻辑上相邻的数据元素在物理位置上也相邻。在高级编程语言中,通常使用数组来实现顺序表。

顺序表的基本操作

1. 初始化

创建一个空的顺序表,通常需要分配一定的存储空间。以下是 Python 代码示例:

class SeqList:
    def __init__(self, max_size=100):
        self.max_size = max_size
        self.data = [None] * max_size
        self.length = 0
2. 插入操作

在顺序表的指定位置插入一个新的数据元素。插入操作可能需要移动元素以腾出插入位置。以下是插入操作的代码示例:

    def insert(self, index, value):
        if index < 0 or index > self.length:
            return False
        if self.length >= self.max_size:
            return False
        for i in range(self.length, index, -1):
            self.data[i] = self.data[i - 1]
        self.data[index] = value
        self.length += 1
        return True
3. 删除操作

删除顺序表中指定位置的数据元素。删除操作后,需要将后续元素前移以填补空缺。以下是删除操作的代码示例:

    def delete(self, index):
        if index < 0 or index >= self.length:
            return False
        for i in range(index, self.length - 1):
            self.data[i] = self.data[i + 1]
        self.length -= 1
        return True
4. 查找操作

根据给定的值或位置查找顺序表中的数据元素。以下是按值查找的代码示例:

    def search(self, value):
        for i in range(self.length):
            if self.data[i] == value:
                return i
        return -1
5. 遍历操作

依次访问顺序表中的每个数据元素。以下是遍历操作的代码示例:

    def traverse(self):
        for i in range(self.length):
            print(self.data[i], end=" ")
        print()

顺序表的优缺点总结

在这里插入图片描述

优点
  • 随机访问效率高:由于顺序表使用数组存储,通过数组下标可以直接访问任意位置的元素,时间复杂度为 O ( 1 ) O(1) O(1)。例如,要访问顺序表中第 i i i 个元素,直接通过数组下标 i i i 即可快速定位。
  • 存储密度大:顺序表中只存储数据元素本身,不需要额外的指针来表示元素之间的逻辑关系,因此存储密度为 1,空间利用率高。
缺点

**

  • 插入和删除操作效率低:在顺序表中进行插入和删除操作时,通常需要移动大量元素,平均时间复杂度为 O ( n ) O(n) O(n)。例如,在顺序表的开头插入一个元素,需要将后面的所有元素依次后移一位。
  • 空间分配不灵活:顺序表在初始化时需要预先分配一定的存储空间,如果预先分配的空间过大,会造成空间浪费;如果预先分配的空间过小,又可能导致数据溢出。并且,在运行过程中难以动态调整存储空间的大小。

**

树形结构

- **概念**:非线性数据结构,由节点和边组成,有根节点,除根外每个节点有一个父节点,可有多子节点,无环。
- **特点**:层次分明,呈一对多关系。
- **常见类型**:二叉树、二叉搜索树、AVL 树、红黑树、B 树和 B + 树等。
- **应用**:用于文件系统组织、数据库索引、编译原理中的语法分析等。

图形结构

- **概念**:比树形结构复杂的非线性结构,由顶点和边构成,边可有无方向、可带权重。
- **特点**:顶点关系多对多,可能存在环。
- **常见类型**:无向图、有向图、带权图。
- **应用**:适用于社交网络分析、交通网络路径规划、电路设计等。 

在这里插入图片描述

单链表基本概念

单链表是一种常见的线性数据结构,它由一系列节点组成。每个节点包含两部分:数据域和指针域。数据域用于存储实际的数据,指针域存储指向下一个节点的指针(地址)。链表的第一个节点称为头节点,最后一个节点的指针域通常指向空(NULLNone),以此表示链表的结束

在这里插入图片描述

链表的分类

  • 单链表:节点只有一个指向下一个节点的指针,只能单向遍历。
  • 双向链表:每个节点除了有指向下一个节点的指针外,还有一个指向前一个节点的指针,可双向遍历。
  • 循环链表:单链表或双向链表的最后一个节点的指针域指向头节点,形成一个环。
    在这里插入图片描述

单链表节点设置

在这里插入图片描述
在这里插入图片描述

以下是用 Python 和 C++ 实现单链表节点的示例:

Python 实现
class Node:
    def __init__(self, data):
        self.data = data  # 数据域
        self.next = None  # 指针域,初始化为 None
C++ 实现
#include <iostream>

struct Node {
    int data;  // 数据域
    Node* next;  // 指针域
    Node(int value) : data(value), next(nullptr) {}  // 构造函数
};

单链表初始化

初始化一个单链表通常是创建一个头节点,其数据域可以不存储实际数据,仅作为链表的起始标识。

Python 实现
class LinkedList:
    def __init__(self):
        self.head = None  # 初始化头节点为 None
C++ 实现
class LinkedList {
private:
    Node* head;
public:
    LinkedList() : head(nullptr) {}  // 构造函数,初始化头节点为 nullptr
};

单链表增加节点

尾部插入

在链表尾部添加新节点。

Python 实现
class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        last_node = self.head
        while last_node.next:
            last_node = last_node.next
        last_node.next = new_node
C++ 实现
class LinkedList {
private:
    Node* head;
public:
    LinkedList() : head(nullptr) {}

    void append(int data) {
        Node* new_node = new Node(data);
        if (!head) {
            head = new_node;
            return;
        }
        Node* last_node = head;
        while (last_node->next) {
            last_node = last_node->next;
        }
        last_node->next = new_node;
    }
};

单链表的遍历

依次访问链表中的每个节点并处理其数据。

Python 实现
class LinkedList:
    # ... 前面的代码 ...

    def traverse(self):
        current_node = self.head
        while current_node:
            print(current_node.data)
            current_node = current_node.next
C++ 实现
class LinkedList {
    // ... 前面的代码 ...

    void traverse() {
        Node* current_node = head;
        while (current_node) {
            std::cout << current_node->data << std::endl;
            current_node = current_node->next;
        }
    }
};

单链表的销毁

释放链表中所有节点占用的内存。

Python 实现
class LinkedList:
    # ... 前面的代码 ...

    def destroy(self):
        current_node = self.head
        while current_node:
            next_node = current_node.next
            del current_node
            current_node = next_node
        self.head = None
C++ 实现
class LinkedList {
    // ... 前面的代码 ...

    ~LinkedList() {
        Node* current_node = head;
        while (current_node) {
            Node* next_node = current_node->next;
            delete current_node;
            current_node = next_node;
        }
        head = nullptr;
    }
};

链表的优缺点

优点
  • 动态内存分配链表可以在运行时动态分配和释放内存,不需要预先分配固定大小的空间,适合存储数量不确定的数据
  • 插入和删除效率高:在链表中插入或删除节点,只需要修改指针,时间复杂度为 O ( 1 ) O(1) O(1)(前提是已知要操作的节点位置)。
缺点
  • 随机访问效率低链表不支持随机访问,要访问链表中的某个节点,必须从头节点开始依次遍历,时间复杂度为 O ( n ) O(n) O(n)
  • 额外的指针开销:每个节点需要额外的指针域来存储指向下一个节点的地址,增加了内存开销。

循环链表

循环链表是一种特殊的链表,它的最后一个节点的指针域指向头节点,形成一个环。与单链表相比,循环链表可以从任意节点开始遍历整个链表。
在这里插入图片描述

循环链表节点设置与单链表相同,以下是循环链表初始化和尾部插入的 Python 示例:
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class CircularLinkedList:
    def __init__(self):
        self.head = None

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            new_node.next = self.head
            return
        last_node = self.head
        while last_node.next != self.head:
            last_node = last_node.next
        last_node.next = new_node
        new_node.next = self.head

循环链表在某些场景下很有用,例如实现循环队列、约瑟夫环问题等。

双向链表的概念

双向链表(Doubly Linked List)是一种线性数据结构,它是在单链表的基础上进行扩展。

每个节点除了包含数据域和指向下一个节点的指针(后继指针)外, 还包含一个指向前一个节点的指针(前驱指针)。

这种结构使得双向链表可以从两个方向进行遍历,既可以从链表头开始向后遍历,也可以从链表尾开始向前遍历。
在这里插入图片描述

在这里插入图片描述

基本操作

双向链表的基本操作包括初始化、插入节点、剔除节点、遍历链表以及销毁链表等。

节点设计

以下是使用 Python 和 C++ 实现双向链表节点的示例:

Python 实现
class Node:
    def __init__(self, data):
        self.data = data  # 数据域
        self.prev = None  # 前驱指针,初始化为 None
        self.next = None  # 后继指针,初始化为 None
C++ 实现
#include <iostream>

struct Node {
    int data;  // 数据域
    Node* prev;  // 前驱指针
    Node* next;  // 后继指针
    Node(int value) : data(value), prev(nullptr), next(nullptr) {}  // 构造函数
};

初始化

初始化双向链表通常是创建一个头节点,该头节点的数据域可以不存储实际数据,仅作为链表的起始标识。

Python 实现
class DoublyLinkedList:
    def __init__(self):
        self.head = None  # 初始化头节点为 None
C++ 实现
class DoublyLinkedList {
private:
    Node* head;
public:
    DoublyLinkedList() : head(nullptr) {}  // 构造函数,初始化头节点为 nullptr
};

插入节点

插入节点可以分为在链表头部插入、在链表尾部插入和在指定位置插入等情况。以下以在链表尾部插入为例:

Python 实现
class DoublyLinkedList:
    def __init__(self):
        self.head = None

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        last_node = self.head
        while last_node.next:
            last_node = last_node.next
        last_node.next = new_node
        new_node.prev = last_node
C++ 实现
class DoublyLinkedList {
private:
    Node* head;
public:
    DoublyLinkedList() : head(nullptr) {}

    void append(int data) {
        Node* new_node = new Node(data);
        if (!head) {
            head = new_node;
            return;
        }
        Node* last_node = head;
        while (last_node->next) {
            last_node = last_node->next;
        }
        last_node->next = new_node;
        new_node->prev = last_node;
    }
};

剔除节点

剔除节点时需要处理好前驱和后继指针的关系,以保证链表的连贯性。以下是删除指定值节点的示例:

Python 实现
class DoublyLinkedList:
    # ... 前面的代码 ...

    def delete(self, key):
        current = self.head
        while current:
            if current.data == key:
                if current.prev:
                    current.prev.next = current.next
                else:
                    self.head = current.next
                if current.next:
                    current.next.prev = current.prev
                return
            current = current.next
C++ 实现
class DoublyLinkedList {
    // ... 前面的代码 ...

    void deleteNode(int key) {
        Node* current = head;
        while (current) {
            if (current->data == key) {
                if (current->prev) {
                    current->prev->next = current->next;
                } else {
                    head = current->next;
                }
                if (current->next) {
                    current->next->prev = current->prev;
                }
                delete current;
                return;
            }
            current = current->next;
        }
    }
};

链表的遍历

双向链表可以从前往后或从后往前遍历。以下是从前往后遍历的示例:

Python 实现
class DoublyLinkedList:
    # ... 前面的代码 ...

    def traverse_forward(self):
        current = self.head
        while current:
            print(current.data)
            current = current.next
C++ 实现
class DoublyLinkedList {
    // ... 前面的代码 ...

    void traverseForward() {
        Node* current = head;
        while (current) {
            std::cout << current->data << std::endl;
            current = current->next;
        }
    }
};

销毁链表

释放链表中所有节点占用的内存。

Python 实现
class DoublyLinkedList:
    # ... 前面的代码 ...

    def destroy(self):
        current = self.head
        while current:
            next_node = current.next
            del current
            current = next_node
        self.head = None
C++ 实现
class DoublyLinkedList {
    // ... 前面的代码 ...

    ~DoublyLinkedList() {
        Node* current = head;
        while (current) {
            Node* next_node = current->next;
            delete current;
            current = next_node;
        }
        head = nullptr;
    }
};

适用场合

  • 需要双向遍历的场景:当需要频繁地从两个方向访问数据时,双向链表非常合适。例如,在文本编辑器中实现撤销和重做功能,双向链表可以方便地记录操作历史,向前遍历可以实现撤销操作,向后遍历可以实现重做操作。
  • 需要高效删除节点的场景:在双向链表中删除一个节点时,由于可以直接访问其前驱节点,不需要像单链表那样从头节点开始遍历找到前驱节点,因此删除操作更加高效。例如,在实现
    LRU(Least Recently Used)缓存算法时,双向链表结合哈希表可以高效地实现缓存的淘汰机制。

1. Linux 内核链表概述

Linux 内核链表是一种非常经典且高效的数据结构实现,它采用了一种独特的设计方式,将链表节点嵌入到其他数据结构中,从而实现了链表的通用性和灵活性。这种设计使得链表可以方便地管理各种不同类型的数据,避免了为每种数据类型都单独实现一个链表的繁琐工作。

2. 容器与通用性

容器概念

在 Linux 内核链表中,“容器”指的是包含链表节点的数据结构。链表节点并不是直接存储数据,而是作为一个成员嵌入到其他结构体中。通过这种方式,链表可以将不同类型的数据组织起来,这些包含链表节点的结构体就像是一个个“容器”,链表节点则是连接这些容器的纽带

通用性体现

由于链表节点不依赖于具体的数据类型,只要在自定义的数据结构中包含 list_head 结构体,就可以将这些数据结构添加到链表中进行管理。这使得内核链表可以用于管理各种不同类型的数据,如进程描述符、文件描述符等,大大提高了代码的复用性和可维护性。

3. 节点的设计

Linux 内核链表的节点由 list_head 结构体表示,其定义位于 <linux/list.h> 头文件中,代码如下:

struct list_head {
    struct list_head *next, *prev;
};

这个结构体只包含两个指针,分别指向前一个节点和后一个节点,不包含任何数据域。当需要使用链表来管理数据时,只需要在自定义的数据结构中包含一个 list_head 成员即可。例如:

struct my_data {
    int value;
    struct list_head list;  // 嵌入链表节点
};

4. 增删操作

初始化链表

在使用链表之前,需要对链表进行初始化。可以使用 INIT_LIST_HEAD 宏来初始化一个链表头:

#include <linux/list.h>

struct list_head my_list;
INIT_LIST_HEAD(&my_list);
添加节点

Linux 内核提供了几个宏来实现节点的添加操作,常用的有 list_addlist_add_tail

  • list_add:将新节点添加到指定节点之后,通常用于在链表头部插入节点。
struct my_data *new_node = kmalloc(sizeof(struct my_data), GFP_KERNEL);
new_node->value = 10;
list_add(&new_node->list, &my_list);
  • list_add_tail:将新节点添加到指定节点之前,通常用于在链表尾部插入节点。
struct my_data *new_node = kmalloc(sizeof(struct my_data), GFP_KERNEL);
new_node->value = 20;
list_add_tail(&new_node->list, &my_list);
删除节点

使用 list_del 宏可以从链表中删除一个节点:

struct my_data *node_to_delete;
// 假设 node_to_delete 指向要删除的节点
list_del(&node_to_delete->list);
kfree(node_to_delete);

5. 查找结点

Linux 内核链表本身并没有提供专门的查找函数,因为链表节点不包含数据域,查找操作通常需要结合具体的数据结构来实现。可以通过遍历链表,比较每个节点所包含的数据来查找符合条件的节点。例如,查找 value 等于某个特定值的节点:

struct my_data *entry;
list_for_each_entry(entry, &my_list, list) {
    if (entry->value == target_value) {
        // 找到目标节点
        break;
    }
}

6. 遍历链表

Linux 内核提供了几个宏来方便地遍历链表,常用的有 list_for_eachlist_for_each_entry

list_for_each

用于遍历链表节点,它只操作 list_head 结构体:

struct list_head *pos;
list_for_each(pos, &my_list) {
    // 处理节点
}
list_for_each_entry

用于遍历包含链表节点的数据结构,它会根据链表节点的地址计算出包含该节点的数据结构的地址:

struct my_data *entry;
list_for_each_entry(entry, &my_list, list) {
    printk(KERN_INFO "Value: %d\n", entry->value);
}

综上所述,Linux 内核链表通过巧妙的设计实现了高度的通用性和灵活性,为内核中的数据管理提供了强大而高效的工具。

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

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

相关文章

一周学会Flask3 Python Web开发-Jinja2模板过滤器使用

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在Jinja2中&#xff0c;过滤器(filter)是一些可以用来修改和过滤变量值的特殊函数&#xff0c;过滤器和变量用一个竖线 | &a…

【STM32H743IIT6】STM32H7的ADC时钟频率设置问题 —— 网上大多文章未注意到的要点!

前言 我使用的是定时器触发ADC采样。最近在想达到ADC的最高采样率的时候&#xff0c;发现一直却卡在1Msps上不去&#xff0c;直到在硬汉嵌入式的论坛里才发现了答案&#xff1a;[ADC] STM32H743/H750的Y版和V版芯片ADC的主频区别 这篇文章就详细的讲一下这个问题&#xff0c;这…

JavaScript基础(函数及面向对象)

函数 定义函数 Java定义方法&#xff1a; public 返回值类型 方法名(){ return 返回值 } 定义函数方法一 eg&#xff1a;定义一个绝对值函数 function abs(x) {if (x>0){return x;}else {return -x;}} 调用函数&#xff1a; 注意&#xff1a;一旦执行到return代表函数…

2025面试Go真题第一场

前几天参加了一场面试&#xff0c;GoLang 后端工程师&#xff0c;他们直接给了我 10 道题&#xff0c;我留了一个截图。 在看答案之前&#xff0c;你可以先简单做一下&#xff0c;下面我会对每个题目做一个说明。 文章目录 1、golang map 是否并发安全?2、协程泄漏的原因可能是…

【有奖实践】轻量消息队列(原 MNS)订阅 OSS 事件实时处理文件变动

当你需要对对象存储 OSS&#xff08;Object Storage Service&#xff09;中的文件变动进行实时处理、同步、监听、业务触发、日志记录等操作时&#xff0c; 你可以通过设置 OSS 的事件通知规则&#xff0c;自定义关注的文件&#xff0c;并将 OSS 事件推送到轻量消息队列&#x…

关于Postman自动获取token

在使用postman测试联调接口时&#xff0c;可能每个接口都需要使用此接口生成的令牌做Authorization的Bearer Token验证&#xff0c;最直接的办法可能会是一步一步的点击&#xff0c;如下图&#xff1a; 在Authorization中去选择Bearer Token&#xff0c;然后将获取到的token粘贴…

Baklib知识中台构建企业智慧中枢

智能技术架构构建路径 Baklib知识中台的技术架构设计以模块化和可扩展性为核心&#xff0c;通过分层解耦的架构体系实现知识管理的全流程覆盖。底层依托智能语义分析引擎与多模态知识图谱&#xff0c;完成非结构化数据的自动清洗与语义关联&#xff1b;中间层构建统一的知识资…

解决安卓recyclerView滚到底部不彻底问题

问题分析&#xff1a; 传统recycleview滚到到底部方式scrollToPosition(lastpositon)&#xff0c;只能定位到最后一条数据的顶部。由于数据过长&#xff0c;无法滚动到最底部。 问了下deepseek&#xff0c;给了个方案&#xff1a; private void recyclerViewScrollToBottom()…

StepAudio:语音大模型

Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#xff0c;方言&#xff…

Kafka可视化工具EFAK(Kafka-eagle)安装部署

Kafka Eagle是什么&#xff1f; Kafka Eagle是一款用于监控和管理Apache Kafka的开源系统&#xff0c;它提供了完善的管理页面&#xff0c;例如Broker详情、性能指标趋势、Topic集合、消费者信息等。 源代码地址&#xff1a;https://github.com/smartloli/kafka-eagle 前置条件…

[Web 安全] PHP 反序列化漏洞 —— PHP 反序列化漏洞演示案例

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 PHP 反序列化漏洞产生原因 PHP 反序列化漏洞产生的原因就是因为在反序列化过程中&#xff0c;unserialize() 接收的值可控。 0x01&#xff1a;环境搭建 这里笔者是使用 PhpStudy 搭建的环…

2.部署kafka:9092

官方文档&#xff1a;http://kafka.apache.org/documentation.html (虽然kafka中集成了zookeeper,但还是建议使用独立的zk集群) Kafka3台集群搭建环境&#xff1a; 操作系统: centos7 防火墙&#xff1a;全关 3台zookeeper集群内的机器&#xff0c;1台logstash 软件版本: …

springboot博客系统详解与实现(后端实现)

目录 前言&#xff1a; 项目介绍 一、项目的准备工作 1.1 数据准备 1.2 项目创建 1.3 前端页面的准备 1.4 配置配置文件 二、公共模块 2.1 根据需求完成公共层代码的编写 2.1.1 定义业务状态枚举 2.1.2 统一返回结果 2.1.3 定义项目异常 2.1.4 统一异常处理 三、业…

seacmsv9注入管理员账号密码+orderby+limit

一、网上收集&#xff1a; 海洋影视管理系统&#xff08;seacms&#xff0c;海洋cms&#xff09;是一套专为不同需求的站长而设计的视频点播系统&#xff0c;采 用的是 php5.Xmysql 的架构&#xff0c;seacmsv9漏洞文件&#xff1a;./comment/api/index.php&#xff0c;漏洞参数…

企业级大模型应用的Java-Python异构融合架构实践

一、后端语言相关技术生态 Python语言 Python在AI计算领域拥有全面的生态支持&#xff1a; 底层工具库: Pandas、NumPy、SciPy、Matplotlib深度学习框架: PyTorch、TensorFlow领域专用框架: HuggingFace Transformers&#xff08;社区生态为主&#xff09; 常见Python框架 …

C#连接sql server

连接时&#xff0c;出现如下提示&#xff1a; ERROR [IM014] [Microsoft][ODBC 驱动程序管理器] 在指定的 DSN 中&#xff0c;驱动程序和应用程序之间的体系结构不匹配 原因是odbc的驱动和应用程序的架构不一致。我的odbc如下所示&#xff1a; 显示为64位&#xff0c;而c#程序显…

粉色和紫色渐变壁纸怎么设计?

粉色和紫色的渐变壁纸设计可以打造极为浪漫的氛围&#xff0c;这两种颜色的搭配极具梦幻感与浪漫气息&#xff0c;常被用于各种浪漫主题的设计之中。以下是关于粉色和紫色渐变壁纸的设计方法&#xff1a; 一、渐变方向设计 横向渐变&#xff1a;从画面左侧的粉色过渡到右侧的紫…

AOP基础-01.快速入门

一.AOP 对于统计每一个业务方法的耗时这一操作&#xff0c;如果再业务层的每一个方法前获取方法运行的开始时间&#xff0c;方法结束获取结束时间&#xff0c;然后计算执行耗时&#xff0c;那这样就太繁琐了。能不能定义一个模板方法&#xff0c;使得该方法能够在业务层的方法执…

Go小技巧易错点100例(二十三)

本期分享&#xff1a; 1.Go Module控制Go版本 2.int转string注意事项 3.Go项目查看mod依赖关系 Go Module控制Go版本 当我们开发Go项目涉及到两台及以上的机器&#xff0c;而且它们又刚好是不同操作系统的时候&#xff0c;可能就要把代码挪到另一台机器上重新编译&#xff…

使用Docker Desktop部署GitLab

1. 环境准备 确保Windows 10/11系统支持虚拟化技术&#xff08;需在BIOS中开启Intel VT-x/AMD-V&#xff09;内存建议≥8GB&#xff0c;存储空间≥100GB 2. 安装Docker Desktop 访问Docker官网下载安装包安装时勾选"Use WSL 2 instead of Hyper-V"&#xff08;推荐…