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

【数据结构】队列实现剖析:掌握队列的底层实现

在计算机科学中,**队列(Queue)**是一种常见的数据结构,它遵循先进先出(FIFO,First In First Out)的原则。队列的应用非常广泛,例如任务调度、资源管理、进程通信等。本篇文章旨在为计算机专业的初学者详细讲解队列的多种实现方式,并通过 C++ 的代码示例让读者更好地理解和掌握这些概念和底层原理及优缺点。

本篇文章需要读者具有队列的基本知识,文内会简略介绍,若不清楚什么是队列,可参考以下文章:

  • 【计算机科学】深入理解队列:有序的数据之道
  • 【数据结构】快慢指针探秘:理解链表与数组中的环结构

全文共计4020字,耗时5天缝缝补补完成,若能够让你学到新知识,你可以给我点个👍或者关注。

文章目录

    • 队列的作用
    • 队列的基本操作
    • 队列的多种手动实现方式
      • **1. 基于纯数组的简单实现**
        • **特点**
        • **手动实现时的注意事项**
      • **2. 基于数组的循环队列**
        • **特点**
        • **手动实现时的注意事项**
      • **3. 基于链表的队列**
        • **特点**
        • **手动实现时的注意事项**
      • **4. 基于带头节点的链表队列**
        • **特点**
        • **手动实现时的注意事项**
      • **5. 基于数组的循环队列(无额外标志位实现)**
        • **特点**
        • **手动实现时的注意事项**
        • **代码**
      • **6. 基于数组的循环队列(带标志位实现)**
        • **特点**
        • **手动实现时的注意事项**
        • **代码**
    • 总结

队列的作用

队列的主要作用是按照顺序存储和管理数据,其常见应用包括:

  1. 任务调度: 队列可用于管理任务执行的先后顺序,例如操作系统中的进程调度。
  2. 数据缓冲: 在流式数据处理中,队列用于暂存数据。
  3. 广度优先搜索(BFS): 在图或树的遍历中,队列是关键的数据结构。

我们会在后期的内容中带来队列应用的实战内容。

队列的基本操作

一个队列通常包含以下几个操作:

  • enqueue(入队): 将元素加入队列尾部。
  • dequeue(出队): 从队列头部移除并返回元素。
  • isEmpty(判空): 判断队列是否为空。
  • isFull(判满,可选): 判断队列是否已满(通常适用于基于数组的实现)。

若对队列的概念还是比较模糊,强烈再去复习一下队列的基本知识

  • 【计算机科学】深入理解队列:有序的数据之道

队列的多种手动实现方式


1. 基于纯数组的简单实现

这种实现方式是队列的最基础版本,直接用一个固定大小的数组来存储队列元素,按照先进先出的顺序操作。队列的frontrear指针分别指向队头和队尾,所有元素插入到队尾,从队头取出。

特点
  • 优点:

    1. 实现简单,逻辑清晰,适合入门学习队列概念。
    2. 内存分配静态化,不依赖额外数据结构,直接在数组上操作。
  • 缺点:

    1. 空间浪费问题: 由于数组不循环,当rear到达数组末尾时,即使front前面有空余空间,队列也会被认为已满。
    2. 大小固定: 必须在初始化时确定数组的大小,缺乏灵活性。
手动实现时的注意事项
  1. 边界判断: 要确保在插入时判断队列是否已满,在删除时判断队列是否为空,否则可能会导致数组越界或错误访问。
  2. 队列空判断: 通常通过front == rear判断队列为空。
  3. 队列满判断:rear == maxSize时,需要提示队列已满。
  4. 动态调整难度: 该实现不支持动态扩展数组大小,需要手动扩展时增加实现难度。
#include <iostream>
using namespace std;struct Queue {
private:int *arr;int front, rear, maxSize;
public:Queue(int size) {maxSize = size;arr = new int[size];front = rear = 0;}~Queue() {delete[] arr;}bool isEmpty() {return front == rear;}bool isFull() {return rear == maxSize; // 队列满的条件}void enqueue(int x) {if (isFull()) {cout << "Queue is full!" << endl;return;}arr[rear++] = x;}int dequeue() {if (isEmpty()) {cout << "Queue is empty!" << endl;return -1;}return arr[front++];}
};

2. 基于数组的循环队列

循环队列是对纯数组实现的改进,通过将数组逻辑上看作是环形结构,解决了纯数组实现中空间浪费的问题。

特点
  • 优点:

    1. 高效利用内存: 通过循环的方式重新利用之前已释放的空间,提高数组的空间利用率。
    2. 操作简单: 只需要在插入和删除操作中使用模运算即可实现循环。
  • 缺点:

    1. 逻辑复杂度增加: 需要通过模运算来控制数组的循环,需要仔细处理frontrear的关系。
    2. 固定大小: 和纯数组一样,循环队列的大小也是固定的,无法动态扩展。
手动实现时的注意事项
  1. 队列满和空的判断:
    • 无标志位实现: 通常通过(rear + 1) % maxSize == front判断队列已满,rear == front判断队列为空。需要注意,这种实现中,队列最多只能使用maxSize - 1个空间。
    • 带标志位实现: 引入tag标志位后,可以清楚区分队列满和空的状态(rear == front 时,配合tag判断队列状态)。
  2. 模运算的正确性: 循环队列依赖模运算控制指针,确保数组不会越界。
  3. 初始化边界条件: 在队列为空或刚初始化时,frontrear应该相等。
  4. 特殊情况的处理: 需要处理rear追上front的情况,以及空队列状态下访问的错误提示。
#include <iostream>
using namespace std;struct Queue {
private:int *arr;int front, rear, maxSize;
public:Queue(int size) {maxSize = size;arr = new int[size];front = rear = 0;}~Queue() {delete[] arr;}bool isEmpty() {return front == rear;}bool isFull() {return (rear + 1) % maxSize == front; // 循环条件}void enqueue(int x) {if (isFull()) {cout << "Queue is full!" << endl;return;}arr[rear] = x;rear = (rear + 1) % maxSize;}int dequeue() {if (isEmpty()) {cout << "Queue is empty!" << endl;return -1;}int res = arr[front];front = (front + 1) % maxSize;return res;}
};

3. 基于链表的队列

基于链表的队列是动态存储的实现方式,不依赖固定大小的数组,通过链表的动态特性解决了内存限制问题。

特点
  • 优点:

    1. 灵活性强: 队列大小不固定,可以根据需求动态分配和释放内存。
    2. 无队列满的情况: 只要系统内存允许,就可以插入任意多的元素。
  • 缺点:

    1. 复杂性增加: 需要维护链表的动态分配和释放逻辑,代码实现比数组队列复杂。
    2. 内存开销: 每个节点需要额外的指针存储,整体占用内存比数组略高。
手动实现时的注意事项
  1. 链表初始化: 确保frontrear指针正确初始化为空。
  2. 边界条件: 在插入第一个元素时,需要同时更新frontrear指针。
  3. 内存管理: 每次插入时动态分配内存,删除时释放内存,避免内存泄漏。
  4. 空队列判断:front == nullptr时,队列为空。
  5. 队列尾处理: 当删除最后一个元素后,需要将rear指针置为空。
#include <iostream>
using namespace std;struct Node {int value;Node *next;Node(int v) : value(v), next(nullptr) {}
};struct Queue {
private:Node *front, *rear;
public:Queue() {front = rear = nullptr;}~Queue() {while (front != nullptr) {Node *temp = front;front = front->next;delete temp;}}bool isEmpty() {return front == nullptr;}void enqueue(int x) {Node *newNode = new Node(x);if (isEmpty()) {front = rear = newNode;} else {rear->next = newNode;rear = newNode;}}int dequeue() {if (isEmpty()) {cout << "Queue is empty!" << endl;return -1;}int res = front->value;Node *temp = front;front = front->next;delete temp;if (!front) rear = nullptr; // 更新rearreturn res;}
};

4. 基于带头节点的链表队列

在链表实现的基础上,加入一个不存储数据的头节点,用来简化操作逻辑。

特点
  • 优点:

    1. 边界处理简化: 由于头节点始终存在,可以统一插入和删除操作的逻辑,不需要处理链表为空时的特殊情况。
    2. 灵活性: 与普通链表队列一样,支持动态扩展,内存利用高。
  • 缺点:

    1. 稍微增加内存占用: 需要额外的头节点,占用少量额外内存。
    2. 实现复杂度增加: 需要手动维护头节点和尾节点的指针。
手动实现时的注意事项
  1. 头节点初始化: 确保头节点的next指针初始化为空,头节点本身可以设置一个哨兵值。
  2. 插入操作: 在队列为空时,需要同时更新front->nextrear
  3. 删除操作:front->next开始删除节点,当删除最后一个节点后,需要将rear置为空。
  4. 内存管理: 同样需要确保每次操作后,正确释放删除节点的内存。
#include <iostream>
using namespace std;struct Node {int value;Node *next;Node(int v) : value(v), next(nullptr) {}
};struct Queue {
private:Node *front, *rear;
public:Queue() {front = new Node(-1); // 带头节点rear = nullptr;}~Queue() {while (front != nullptr) {Node *temp = front;front = front->next;delete temp;}}bool isEmpty() {return rear == nullptr;}void enqueue(int x) {Node *newNode = new Node(x);if (isEmpty()) {front->next = newNode;rear = newNode;} else {rear->next = newNode;rear = newNode;}}int dequeue() {if (isEmpty()) {cout << "Queue is empty!" << endl;return -1;}Node *temp = front->next;int res = temp->value;front->next = temp->next;if (!front->next) rear = nullptr; // 更新reardelete temp;return res;}
};

5. 基于数组的循环队列(无额外标志位实现)

循环数组队列(无标志位)的实现是一种改进版的队列,数组逻辑上被看作环形。它通过模运算实现“循环”效果,从而提高了数组的空间利用率。

特点
  • 优点:

    1. 空间利用率高: 不会像纯数组实现那样浪费数组前端的可用空间。
    2. 实现较为简单: 通过模运算控制指针即可实现循环,逻辑清晰。
  • 缺点:

    1. 浪费一个存储单元: 为了区分队列空和满的情况,最多只能使用maxSize - 1个存储单元。
    2. 固定大小: 和所有数组实现一样,大小固定,无法动态扩展。
手动实现时的注意事项
  1. 边界条件: 通过(rear + 1) % maxSize == front判断队列已满,通过rear == front判断队列为空。
  2. 模运算正确性: 插入和删除时需要使用模运算来实现循环效果,避免指针越界。
  3. 初始化: 队列初始化时,frontrear均指向数组的起始位置,队列为空。
  4. 大小限制: 实际可用空间为maxSize - 1,需要特别注意数组容量的计算和使用。
代码
#include <iostream>
using namespace std;struct Queue {
private:int *arr;int front, rear, maxSize;
public:Queue(int size) {maxSize = size;arr = new int[size];front = rear = 0;}    ~Queue() {delete[] arr;}bool isFull() {return (rear + 1) % maxSize == front; // 判断队列满}bool isEmpty() {return front == rear; // 判断队列空}void enqueue(int x) {if (isFull()) {cout << "Queue is full." << endl;return;}arr[rear] = x; // 在队尾插入rear = (rear + 1) % maxSize; // 更新 rear,模运算实现循环}int dequeue() {if (isEmpty()) {cout << "Queue is empty." << endl;return -1; }int res = arr[front]; // 取出队头元素front = (front + 1) % maxSize; // 更新 front,模运算实现循环return res;}
};

6. 基于数组的循环队列(带标志位实现)

循环数组队列(带标志位)的实现是在无标志位版本的基础上引入一个tag标志位,来明确区分队列空和满的情况。这种实现避免了浪费一个存储单元的问题。

特点
  • 优点:

    1. 空间利用率最高: 不会像无标志位版本那样浪费一个存储单元,可以使用整个数组存储数据。
    2. 状态区分清晰: 通过tag标志位清楚地表示当前队列是空还是满。
  • 缺点:

    1. 实现稍复杂: 相比无标志位版本,多了tag标志位的更新逻辑。
    2. 固定大小: 依然受数组大小限制,无法动态扩展。
手动实现时的注意事项
  1. 标志位的维护:
    • enqueue时,如果插入后rear == front,需要将tag置为1,表示队列满。
    • dequeue时,如果删除后rear == front,需要将tag置为0,表示队列空。
  2. 边界条件:
    • 队列空的判断条件:front == rear && tag == 0
    • 队列满的判断条件:front == rear && tag == 1
  3. 初始化: frontrear指针初始化为0,tag初始化为0,表示队列为空。
  4. 模运算: 和无标志位版本类似,通过模运算实现循环效果。
代码
#include <iostream>
using namespace std;struct Queue {
private:int *arr;int front, rear, maxSize, tag;
public:Queue(int size) {maxSize = size;arr = new int[size];front = rear = 0;tag = 0; // 初始状态为空}~Queue() {delete[] arr;}bool isEmpty() {return front == rear && tag == 0; // 队列空:front == rear 且 tag 为 0}bool isFull() {return front == rear && tag == 1; // 队列满:front == rear 且 tag 为 1}void enqueue(int x) {if (isFull()) {cout << "Queue is full." << endl;return;}arr[rear] = x; // 在队尾插入rear = (rear + 1) % maxSize; // 更新 rearif (rear == front) tag = 1; // 如果 rear 追上 front,则队列满,tag 置为 1}int dequeue() {if (isEmpty()) {cout << "Queue is empty." << endl;return -1;}int res = arr[front]; // 取出队头元素front = (front + 1) % maxSize; // 更新 frontif (rear == front) tag = 0; // 如果 front 追上 rear,则队列空,tag 置为 0return res;}
};

总结

实现方式优点缺点适用场景
纯数组队列1. 实现简单,适合入门学习。2. 适合小规模的简单场景。1. 空间利用率低,出队后前部空间不可复用。2. 数组固定大小,无法动态扩展。小型队列,数据量较少且操作较简单的场景。
循环数组队列(无标志位)1. 空间利用率高,支持循环操作。2. 实现逻辑相对清晰,易于理解。1. 浪费一个存储单元,最大可用容量为maxSize - 1。2. 边界条件复杂,容易出错。小型队列,数据量适中且对空间利用有一定要求。
循环数组队列(带标志位)1. 空间利用率最高,无存储浪费。2. 状态明确,通过标志位区分队列空与满的状态。1. 实现稍复杂,需要维护标志位的逻辑。2. 数组固定大小,仍无法动态扩展。数据量较大且对空间利用率有高要求的场景。
链表队列(无头节点)1. 动态分配空间,无需固定大小,支持数据量变化。2. 空间利用率高,无浪费。1. 实现稍复杂,需要手动管理内存。2. 操作链表时,可能存在额外的时间和内存开销。数据量不确定或需要动态调整大小的场景。
链表队列(带头节点)1. 动态分配空间,支持大小变化。2. 带头节点的设计简化了插入和删除操作逻辑。1. 实现复杂度高,需要维护链表和头节点。2. 内存利用率高,但链表操作较慢。数据动态变化且需要更高鲁棒性的场景。
链表队列(带尾指针)1. 通过尾指针优化入队操作,性能更高。2. 动态空间分配,适应数据量变化。1. 内存分配和释放较复杂,容易出现内存泄漏问题。2. 指针操作复杂度较高,需小心处理边界。数据量较大,需频繁插入删除的场景。

推荐选择依据:

  1. 如果你是初学者或实现简单队列,纯数组队列是一个不错的起点。
  2. 如果需要循环结构并注重空间利用率,选择循环数组队列(无标志位)**或**循环数组队列(带标志位),根据是否需要完整利用空间来决定。
  3. 如果需要动态扩展且操作数据频繁,链表队列是最佳选择,根据是否需要头节点或尾指针进一步优化。

理解每种实现的原理和优缺点是学习数据结构的重要步骤。希望本文能够帮助你掌握队列的基本概念及实现方式,同时,若本文帮助到了你,你可以给我点个赞和关注,以支持我继续创作。

相关文章:

【数据结构】队列实现剖析:掌握队列的底层实现

在计算机科学中&#xff0c;**队列&#xff08;Queue&#xff09;**是一种常见的数据结构&#xff0c;它遵循先进先出&#xff08;FIFO&#xff0c;First In First Out&#xff09;的原则。队列的应用非常广泛&#xff0c;例如任务调度、资源管理、进程通信等。本篇文章旨在为计…...

【C++】IO库(二):文件输入输出

8.2 文件输入输出 头文件 fstream 定义了三个类型来之支持文件IO&#xff0c;分别是&#xff1a; ifstream&#xff1a;从一个给定文件读取数据&#xff1b;ofstream&#xff1a;向一个给定文件写入数据&#xff1b;fstream&#xff1a;读写给定文件。 在 C 当中&#xff0c…...

105.【C语言】数据结构之二叉树求总节点和第K层节点的个数

目录 1.求二叉树总的节点的个数 1.容易想到的方法 代码 缺陷 思考:能否在TreeSize函数内定义静态变量解决size的问题呢? 其他写法 运行结果 2.最好的方法:分而治之 代码 运行结果 2.求二叉树第K层节点的个数 错误代码 运行结果 修正 运行结果 其他写法 1.求二…...

力扣637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 提示&#xff1a; 树中节点数量在 [1, 104] 范围内-231 < Node.val < 231 - 1 代码&#xff1a; /*** Definition for a binary tree node.* stru…...

【前端】Next.js 服务器端渲染(SSR)与客户端渲染(CSR)的最佳实践

关于Next.js 服务器端渲染&#xff08;SSR&#xff09;与客户端渲染&#xff08;CSR&#xff09;的实践内容方面&#xff0c;我们按下面几点进行阐述。 1. 原理 服务器端渲染 (SSR): 在服务器上生成完整的HTML页面&#xff0c;然后发送给客户端。这使得用户在首次访问时能够…...

路径规划之启发式算法之一:A-Star(A*)算法

A*算法是一种启发式搜索算法&#xff0c;常用于解决路径规划问题。 一、A*算法的定义与原理 A*算法是一种用于在图形或网格中查找最短路径的算法。它在搜索过程中综合考虑了每个节点的实际距离&#xff08;g值&#xff09;和预估距离&#xff08;h值&#xff09;&#xff0c;以…...

Android复习代码1-4章

public class RudioButton extends AppCompatActivity {Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_rudio_button);// 找到RadioGroup和TextView的实例RadioGroup radioGrou…...

【问题】webdriver.Chrome()设置参数executable_path报不存在

场景1: 标红报错unresolved reference executable_path 场景2: 执行报错TypeError: __init__() got an unexpected keyword argument executable_path 原因&#xff1a; 上述两种场景是因为selenium4开始不再支持某些初始化参数。比如executable_path 解决&#xff1a; 方案…...

win10系统安装docker-desktop

1、开启Hyper-v ———————————————— Hyper-V 是微软提供的一种虚拟化技术&#xff0c;它允许你在同一台物理计算机上运行多个独立的操作系统实例。这种技术主要用于开发、测试、以及服务器虚拟化等领域。 —————————————————————— &#…...

小程序-基于java+SpringBoot+Vue的乡村研学旅行平台设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…...

组件A底部栏(position: fixed )事件使用$emit更新内容失败bug解决

今天遇到一个很离奇的bug&#xff0c;记录一下 问题&#xff1a;在组件内底部栏使用$emit触发按钮事件但打印出来的值是初始化的值&#xff0c;更新的值被重置导致更新失败 原因&#xff1a;组件内底部使用了 position: fixed; 固定&#xff0c; 导致组件内插槽 this 与 保存按…...

数据结构——排序第三幕(深究快排(非递归实现)、快排的优化、内省排序,排序总结)超详细!!!!

文章目录 前言一、非递归实现快排二、快排的优化版本三、内省排序四、排序算法复杂度以及稳定性的分析总结 前言 继上一篇博客基于递归的方式学习了快速排序和归并排序 今天我们来深究快速排序&#xff0c;使用栈的数据结构非递归实现快排&#xff0c;优化快排&#xff08;三路…...

C++的类功能整合

1. 类的基本概念 类是面向对象编程的核心&#xff0c;它封装了数据和操作数据的函数。 #include <iostream> using namespace std;class MyClass { public:int publicData;void publicFunction() {cout << "Public function" << endl;}private:i…...

《String类》

目录 一、定义与概述 二、创建字符串对象 2.1 直接赋值 2.2 使用构造函数 三、字符串的不可变性 四、常用方法 4.1 String对象的比较 4.1.1 比较是否引用同一个对象 4.1.2 boolean equals(Object anObject)方法&#xff1a;按照字典序比较 4.1.3 int compareTo(Strin…...

【docker】docker的起源与容器的由来、docker容器的隔离机制

Docker 的起源与容器的由来 1. 虚拟机的局限&#xff1a;容器的需求萌芽 在 Docker 出现之前&#xff0c;开发和部署软件主要依赖虚拟机&#xff08;VMs&#xff09;&#xff1a; 虚拟机通过模拟硬件运行操作系统&#xff0c;每个应用程序可以运行在自己的独立环境中。虽然虚…...

Window 安装 Nginx

参考链接 Windows 环境nginx安装使用及目录结构详解_windows 安装nginx-CSDN博客 Nginx 安装及配置教程&#xff08;Windows&#xff09;【安装】_nginx下载安装-CSDN博客 安装 1&#xff09;下载 nginx: download 2&#xff09;解压 3&#xff09;启动 3.1&#xff09;方…...

replace (regexp|substr, newSubstr|function)替换字符串中的指定部分

replace 方法用于替换字符串中的指定部分。它可以接受一个子字符串或正则表达式作为第一个参数&#xff0c;第二个参数是替换的内容。 用法示例 基本替换 let str "Hello, world!"; let newStr str.replace("world", "everyone"); console.lo…...

【ROS2】Ubuntu22.04安装ROS humble

一. ROS简介 1.1 什么是ROS ROS 是一个适用于机器人的开源的元操作系统。它提供了操作系统应有的服务&#xff0c;包括硬件抽象&#xff0c;底层设备控制&#xff0c;常用函数的实现&#xff0c;进程间消息传递&#xff0c;以及包管理。ROS的核心思想就是将机器人的软件功能做…...

cesium 3Dtiles变量

原本有一个变亮的属性luminanceAtZenith&#xff0c;但是新版本的cesium没有这个属性了。于是 let lightColor 3.0result._customShader new this.ffCesium.Cesium.CustomShader({fragmentShaderText:void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial mate…...

配置泛微e9后端开发环境

配置泛微e9的后端开发环境 1.安装jdk1.8&#xff08;请自行安装并设置环境变量&#xff09; 2.将服务器上的WEARVER文件夹拷贝到开发环境下(其中要包含ecology和Resin目录) 3.通过idea创建一个基础Java项目,将jdk设置为1.8 4.添加依赖,需要将3个文件夹的所有jar包添加到项目中…...

【Stable Diffusion】安装教程

目录 一、python 安装教程 二、windows cuda安装教程 三、Stable Diffusion下载 四、Stable Diffusion部署&#xff08;重点&#xff09; 一、python 安装教程 &#xff08;1&#xff09;第一步下载 打开python下载页面&#xff0c;找到python3.10.9&#xff0c;点击右边…...

USB Type-C一线通扩展屏:多场景应用,重塑高效办公与极致娱乐体验

在追求高效与便捷的时代&#xff0c;启明智显USB Type-C一线通扩展屏方案正以其独特的优势&#xff0c;成为众多职场人士、娱乐爱好者和游戏玩家的首选。这款扩展屏不仅具备卓越的性能和广泛的兼容性&#xff0c;更能在多个应用场景中发挥出其独特的价值。 USB2.0显卡&#xff…...

【力扣】541.反转字符串2

问题描述 思路解析 每当字符达到2*k的时候&#xff0c;判断&#xff0c;同时若剩余字符>k,只对前k个进行判断&#xff08;这是重点&#xff09;因为字符串是不可变变量&#xff0c;所以将其转化为字符串数组&#xff0c;最后才将结果重新转变为字符串 字符串->字符数组 …...

什么是防抖与节流

防抖&#xff08;Debouncing&#xff09;与节流&#xff08;Throttling&#xff09; 在前端开发中&#xff0c;尤其是在处理用户输入、窗口调整大小、滚动事件等高频率触发的事件时&#xff0c;防抖和节流是两种常用的技术手段。它们可以帮助我们优化性能&#xff0c;减少不必…...

springboot vue 开源 会员收银系统 (12)购物车关联服务人员 订单计算提成

前言 完整版演示 http://120.26.95.195/ 开发版演示 http://120.26.95.195:8889/ 在之前的开发进程中&#xff0c;我们完成订单的挂单和取单功能&#xff0c;今天我们完成购物车关联服务人员&#xff0c;用户计算门店服务人员的提成。 1.商品关联服务人员 服务人员可以选择 一…...

FFmpeg 推流给 FreeSWITCH

FFmpeg 推流&#xff0c;貌似不难&#xff0c;网上有很多资料, 接到一个任务&#xff0c;推流给 FreeSWITCH&#xff0c;最开始以为很容易&#xff0c; 实则不然&#xff0c;FreeSWITCH uuid_debug_media <uuid>&#xff0c; 一直没人任何反应 仔细一查&#xff0c;Fr…...

.npmrc文件的用途

.npmrc 文件是 npm&#xff08;Node.js 的包管理工具&#xff09;用于配置项目或用户的设置文件。它可以存储与 npm 相关的配置信息&#xff0c;如注册表地址、认证信息、代理设置、安装路径等。.npmrc 文件可以出现在不同的地方&#xff0c;具有不同的作用范围&#xff0c;通常…...

C++游戏开发入门:如何从零开始实现自己的游戏项目?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C游戏开发的相关内容&#xff01; 关于【…...

Redis设计与实现第16章 -- Sentinel 总结1(初始化、主从服务器获取信息、发送信息、接收信息)

Sentinel是Redis的高可用解决方案&#xff1a;由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器&#xff0c;以及这些主服务器属下的所有从服务器&#xff0c;被监视的主服务器进入下线状态时&#xff0c;自动将下线主服务器属下的某个从服务器升级为新的主…...

Windows10+VirtualBox+Ubuntu:安装虚拟机VirtualBox,虚拟机中安装Ubuntu

一、需求 在Windows10系统中&#xff0c;安装虚拟机VirtualBox&#xff0c;VirtualBox中安装Ubuntu桌面版。 二、环境准备 系统环境 Windows10 内存&#xff1a;8G 虚拟化 虚拟机的运行&#xff0c;如果需要Windows系统开启虚拟化&#xff0c;可以通过BIOS设置。 “虚拟…...

上海做响应式网站的公司/seo具体seo怎么优化

sys_rman工具包含若干命令&#xff0c;每个命令完成独立的功能。每个命令支持若干的选项&#xff0c;参考手册详细描述所有的选项。 基本格式如下&#xff1a; sys_rman --option1aaa --option2bbb 命令行指定的选项在本次运行过程中覆盖配置文件中的设定值&#xff0c;但不…...

vip影视建设网站官网/爱站数据

Objective-C中有几种数据类型和C不太一样。特此记录。 - id 是一个指针类型&#xff0c;可以指向任何类型的对象 - BOOL和char是一样的&#xff0c;但是做为布尔值使用。 YES 表示1 NO 表示0 - IBOutlet 是个没有任何意义的宏&#xff0c;可以忽略。当Interface Builder从.h…...

美乐乐网站模板/网络软文广告

linux输入yum后提示&#xff1a; -bash: /usr/bin/yum: No such file or directory的解决方案今天在安装程序时&#xff0c;发现有一个插件未安装&#xff0c;我就随手敲了一个命令,看都没看yum remove yum然后就杯具了...[rootlocalhost ~]# yum-bash: /usr/bin/yum: No such …...

网站建设客服话术/网站优化价格

** 转换工具界面:**1.选择xmind所在路径2.输入用例操作人3.提交等待xls生成image.png** Xmind编写用例规范&#xff1a;**用例目录:填写测试项目名称用例名称:填写用例所属模块名称前置条件:填写用例前置条件用例步骤:填写用例步骤预期结果:填写预期结果用例类型:默认写死“功能…...

网站子域名 更换/网站优化招聘

转载自:http://blog.csdn.net/silent123go/article/details/53010781 1、七号信令的基本术语 1.1 信令网 N0.7信令网是独立于电信网的支撑网&#xff0c;是电信网中用于传输No.7信令消息的专用数据网。信令网的三要素&#xff1a;信令点、信令转接点、信令链路。 1.2 信令点和…...

网站开发有什么网站/app拉新推广平台

文章目录找到nki音源加载器右键打开 定位到音源文件夹即可&#xff0c;双击即可进入 如果提示文件缺失&#xff0c;找到音源所在文件夹会自动寻找 等待加载完毕&#xff0c;就可以调成琴键格式弹奏了...