用c语言实现——一个带头节点的链队列,支持用户输入交互界面、初始化、入队、出队、查找、判空判满、显示队列、遍历计算长度等功能
一、知识介绍
带头节点的链队列是一种基于链表实现的队列结构,它在链表的头部添加了一个特殊的节点,称为头节点。头节点不存储实际的数据元素,主要作用是作为链表的起点,简化队列的操作和边界条件处理。
1.节点结构
链队列的每个节点由两部分组成:
-
数据域(data):用于存储队列中的元素。
-
指针域(next):用于指向下一个节点。
头节点是链队列的第一个节点,它不存储实际数据,但它的指针域指向队列的第一个实际数据节点。
2.队列结构
链队列通常包含两个指针:
-
队头指针(front):指向头节点。
-
队尾指针(rear):指向队列的最后一个节点。
3.初始化
在初始化链队列时,会创建一个头节点,并将队头指针和队尾指针都指向这个头节点。此时,队列为空。
4.入队操作
入队操作在队列的尾部添加一个新元素:
-
创建一个新节点。
-
将队尾节点的指针域指向新节点。
-
更新队尾指针指向新节点。
5.出队操作
出队操作从队列的头部移除一个元素:
-
检查队列是否为空。
-
如果队列不为空,获取队头节点的下一个节点的数据。
-
更新队头节点的指针域,使其指向下一个节点的下一个节点。
-
如果队列中只有一个元素,出队后需要将队尾指针也指向头节点。
6.判空
检查队头指针和队尾指针是否都指向头节点:
-
如果是,则队列为空。
-
否则,队列不为空。
7.判满
在动态内存分配的链队列中,队列通常不会满,除非系统内存耗尽。可以通过尝试分配新节点来间接判断队列是否已满。
8.显示队列和计算长度
通过遍历链表,从头节点的下一个节点开始,直到队尾节点,可以显示队列中的所有元素并计算队列的长度。
9.优势
-
简化操作:头节点的存在使得队列的操作(如入队、出队)更加统一,避免了对空队列或单节点队列的特殊处理。
-
边界条件处理方便:头节点作为固定的起点,使得处理队列为空或只有一个节点的情况更加简单。
-
增强可读性:代码逻辑更加清晰,易于理解和维护。
带头节点的链队列是链表的一种变体,通过引入头节点,提高了队列操作的效率和代码的健壮性。
二、思路大致
①定义结构体:有两种结构体👇
一个是节点结构体👉👉包含数据和指向下一个节点的指针;
一个是队列结构体👉👉包含front和rear。
②用户交互界面:
设计一个菜单,让用户选择不同的操作。用循环显示选项,输入数字选择操作。这可以用printf和scanf实现。
❗❗但要注意处理输入错误,比如用户输入的不是数字,或者选项不在范围内。这时候可能需要清空输入缓冲区,防止后续操作出错。
③初始化函数:
需要创建头节点,并让front和rear都指向它。
❗❗如果用户未初始化就进行入队或出队操作,程序应该提示错误。所以每个操作前都要检查队列是否已经初始化。
在程序中定义一个全局的LinkQueue变量,初始时front和rear都为NULL。初始化函数会创建头节点,并让front和rear指向它。之后的其他操作首先检查front是否为NULL,如果是,说明未初始化。这可能更简单。所以,假设有一个全局的LinkQueue queue变量,初始化的时候创建头节点,front和rear指向它。否则,front和rear都是NULL。那么,在入队或出队之前,检查front是否为NULL,如果是,提示用户先初始化队列。
④用户输入数据:
将数据添加到队尾。
❗❗这里要注意用户输入的数据是否有效,比如是否是整数。比如用scanf读取整数时,如果用户输入了字符,会导致错误。这时候需要处理输入错误的情况,可能需要清空输入缓冲区,并提示重新输入。
⑤出队操作:
需要判断队列是否为空,如果为空则提示不能出队,否则删除队头元素,并释放内存。
❗❗如果出队后队列为空,需要将rear指向front(即头节点),否则rear可能成为野指针。
⑥查找功能:
需要用户输入一个元素,然后遍历队列查找是否存在该元素。这里需要遍历头节点的下一个节点开始,直到rear指向的节点。
⑦判空判满,链队列理论上不会满,除非内存不足,所以判满可以返回false或者不处理。判空就是判断front == rear。
⑧显示队列需要从头节点的下一个节点开始,依次输出每个节点的数据,直到队尾。
⑨计算长度则是遍历队列,统计节点数量。
⑩代码的健壮性。
❗❗在初始化时:如果内存分配失败,要处理错误。
❗❗在入队时:如果新节点分配失败,也要提示错误。
❗❗每个操作前:都要检查队列是否已经初始化。
❗❗对于用户输入的选项:需要处理非法输入,比如输入字符而不是数字,这时候需要清空输入缓冲区,并提示重新输入。
代码的大致流程可能是:
1. 初始化队列变量为未初始化状态(front和rear为NULL)。
2. 显示菜单,用户选择操作。
3. 根据用户选择调用对应的函数,每个函数首先检查队列是否已经初始化(比如,除了初始化操作外,其他操作需要队列已初始化)。
❗❗ 初始化队列时,如果用户多次调用初始化,是否会导致内存泄漏?
比如,如果队列已经初始化过,再次调用InitQueue会创建新的头节点,而原来的头节点没有被释放。
因此,在InitQueue函数中,应该先检查队列是否已经初始化,如果是,则先销毁原来的队列,或者提示用户先销毁。或者,在初始化函数中,如果队列已经初始化,就提示错误。或者,在InitQueue函数中,先释放之前的头节点,如果存在的话。这可能比较复杂。所以,在用户选择初始化队列时,如果队列已经初始化,应该提示用户需要先销毁队列。或者,在初始化函数内部处理这种情况
三、分段解释
1.节点结构体定义
QNode 定义
typedef struct QNode
:定义了一个名为 QNode
的结构体类型,用于表示队列中的节点。
int data;
:每个节点包含一个 int
类型的成员变量 data
,用于存储队列中的数据元素。
struct QNode *next;
:每个节点还包含一个指向 QNode
类型的指针 next
,用于指向下一个节点,从而形成链表结构。
} QNode;
:结束结构体定义,并将其命名为 QNode
。
2.队列结构体定义
LinkQueue 定义
typedef struct
:定义了一个匿名结构体类型,并立即使用 typedef
为其创建一个别名 LinkQueue
。
QNode* front;
:LinkQueue
结构体包含一个指向 QNode
的指针 front
,用于指向队列的头部节点(头节点)。
QNode* rear;
:LinkQueue
结构体还包含一个指向 QNode
的指针 rear
,用于指向队列的尾部节点。
} LinkQueue;
:结束结构体定义,并将其别名为 LinkQueue
。
3.判空逻辑
return q->front == q->rear;
:这是函数的实现部分,它比较链队列的队头指针 front
和队尾指针 rear
是否相等。
在带头节点的链队列中,初始化时 front
和 rear
都指向头节点。当队列为空时,front
和 rear
仍然指向同一个节点(头节点),因此它们相等。
当队列不为空时,rear
指向最后一个实际数据节点,因此 front
和 rear
不相等。
4. 初始化链队列
a.检查队列是否已经初始化
检查 q->front
是否不为 NULL
。如果不为 NULL
,说明队列可能已经初始化过,或者包含一些未清理的节点。
b.清理现有节点
如果队列已经初始化过(即 q->front
不为 NULL
),则需要清理现有的所有节点以防止内存泄漏。
使用一个临时指针 p
遍历链表,逐一释放每个节点的内存。
最后,将 q->front
和 q->rear
都设置为 NULL
,表示队列现在为空。
c.创建头节点
使用 malloc
分配一个新节点的内存空间,这个节点将作为头节点。
d.检查内存分配是否成功
如果内存分配失败,输出错误信息并返回,不继续执行后续操作。
e.初始化头节点
将头节点的 next
指针设置为 NULL
,表示初始时队列为空。
将 q->front
和 q->rear
都指向这个头节点。
最后输出成功信息
5. 入队操作
a.创建新节点
使用 malloc
分配一个新节点的内存空间。
b.检查内存分配是否成功
如果内存分配失败,输出错误信息并返回 false
。
c.初始化新节点
将新节点的数据域设置为传入的 data 值。
将新节点的指针域设置为 NULL
d.将新节点添加到队列尾部
更新当前队尾节点的指针域,使其指向新节点。
更新队列的队尾指针 rear
,使其指向新节点。
最后返回成功状态。
6. 出队操作
a.函数定义
bool Dequeue(LinkQueue* q, int *data)
:定义了一个返回类型为 bool
的函数 Dequeue
,它接受一个指向 LinkQueue
类型的指针 q
和一个指向整型的指针 data
。这个函数用于从链队列 q
的头部移除一个元素,并将该元素的值存储到 data
所指向的内存位置。
b.检查队列是否为空
调用 IsEmpty
函数检查队列是否为空。如果队列为空,输出错误信息并返回 false
。
c.获取队头元素
队头元素是头节点的下一个节点,将这个节点存储在临时指针 temp
中。
头节点不是首元素!!!
d.保存数据
将队头元素的数据保存到 data
指针所指向的内存位置。
e.更新队头指针
更新头节点的指针域,使其指向队头元素的下一个节点,从而移除原来的队头元素。
比如旧有队列为 head 、1、2、3、4。经过出队操作后,此步骤即把2设为1出列后的队头元素。
f.处理队尾指针
如果队列中只有一个元素(即队尾指针指向当前要移除的队头元素),移除该元素后,需要将队尾指针重新指向头节点。
然后释放内存,并且返回成功状态。
7.销毁操作
a.检查队列是否为空
检查队列的队头指针 q->front
是否为 NULL
。如果为 NULL
,说明队列已经为空或未初始化,直接返回,无需执行后续操作。
b.遍历并释放节点内存
使用指针 p
从队头节点开始遍历链表。
在每次迭代中,将当前节点 p
存储到临时指针 temp
中。
将 p
移动到下一个节点 p->next
。
释放 temp
指针所指向的当前节点的内存。
c.将队列指针置为空
将队列的队头指针 front
和队尾指针 rear
都设置为 NULL
,表示队列已经销毁。
最后输出销毁信息
8. 遍历操作
a.检查队列是否为空
调用 IsEmpty
函数检查队列是否为空。如果队列为空,输出提示信息并返回。
b.初始化遍历指针
将指针 p
初始化为头节点的下一个节点,即队列的第一个实际数据节点。
c.打印队列元素
输出队列元素的提示信息。
使用 while
循环遍历队列中的每个节点,直到 p
为 NULL
(即队列末尾)。
在每次迭代中,打印当前节点的数据,并将 p
移动到下一个节点。
9.查找操作
a.函数定义
int FindElement(LinkQueue* q, int value)
:定义了一个返回类型为 int
的函数 FindElement
,它接受一个指向 LinkQueue
类型的指针 q
和一个整型参数 value
。这个函数用于在链队列 q
中查找值为 value
的元素的位置。
b.检查队列为空是否
调用 IsEmpty
函数检查队列是否为空。如果队列为空,返回 -1
表示找不到元素。
c.初始化遍历指针和位置计数器
将指针 p
初始化为头节点的下一个节点,即队列的第一个实际数据节点。
初始化位置计数器 pos
为 1
,表示从第一个位置开始计数。
d.遍历队列查找元素
使用 while
循环遍历队列中的每个节点,直到 p
为 NULL
(即队列末尾)。
在每次迭代中,检查当前节点的数据是否等于要查找的 value
。
如果找到匹配的值,返回当前的位置计数器 pos
。
如果未找到,将 p
移动到下一个节点,并递增位置计数器 pos
。
10. 长度计算
a.初始化计数器和指针
初始化计数器 len
为 0
,用于记录队列中元素的数量。
将指针 p
初始化为头节点的下一个节点,即队列的第一个实际数据节点。
b.遍历队列并计数
使用 while
循环遍历队列中的每个节点,直到 p
为 NULL
(即队列末尾)。
在每次迭代中,递增计数器 len
,并将 p
移动到下一个节点。
最后返回len,即队列中元素的数量。
11.主函数main()逻辑
主循环
-
while (1)
:创建一个无限循环,使程序持续运行直到用户选择退出。 -
menu();
:调用menu
函数显示操作菜单(假设menu
函数已定义)。 -
输入处理:
-
使用
scanf_s
读取用户输入的选择。 -
如果输入失败(即输入的不是有效整数),输出错误信息,并使用
while (getchar() != '\n');
清空输入缓冲区,然后跳过本次循环重新显示菜单。
-
操作分支
根据用户的选择,执行不同的操作
0.退出程序
1.初始化程序
2.入队操作
3.出队操作
4.判断队列是否为空
5.显示队列元素
6.查找元素
7.获取队列长度
8.销毁队列
default:默认情况
12. 健壮性代码的方式
-
scanf_s
函数的返回值:-
scanf_s
函数的返回值是指成功读取和转换的输入项的数量。 -
在尝试读取一个整数时,如果成功读取一个整数,返回值是
1
。 -
如果输入失败(比如用户输入了非数字字符),返回值会是
0
或EOF
(表示输入失败或遇到文件结束)。
-
-
为什么要检查返回值:
-
如果用户输入的不是一个有效的整数(例如输入了字母 "abc"),
scanf_s
会失败,并返回一个非1
的值。 -
如果不检查返回值,程序会继续执行,但此时变量
data
中的值可能是未定义的,导致后续操作出现意外行为,比如:-
使用未定义的值进行计算或操作。
-
引发逻辑错误或程序崩溃。
-
-
-
防止程序异常:
-
通过检查
scanf_s
的返回值,可以及时发现输入错误。 -
如果输入无效,程序可以提示用户重新输入,而不是继续使用无效的数据进行操作。
-
这种做法增强了程序的健壮性和用户体验,避免因输入错误导致程序异常终止。
-
-
输入缓冲区:
-
当用户通过键盘输入数据时,数据会先进入输入缓冲区。
-
按下回车键后,输入的数据(包括回车键对应的换行符
\n
)会被存入缓冲区。
-
-
清空缓冲区的必要性:
-
如果用户输入了错误的数据类型或格式,缓冲区中可能会残留未处理的字符。
-
这些残留的字符可能会影响后续的输入操作,导致程序行为异常。
-
-
代码作用:
-
getchar()
逐个读取输入缓冲区中的字符。 -
while (getchar() != '\n');
会不断读取并丢弃字符,直到遇到换行符\n
为止。 -
这样可以确保输入缓冲区被清空,避免残留字符干扰后续输入。
-
以及使用入队、出队、查找等操作之前,都有相应的检查是否初始化的逻辑代码,已经在上述代码解析中给出。
四、完整代码
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>typedef struct QNode
{int data;struct QNode* next;
}QNode;typedef struct
{QNode* front;QNode* rear;
}LinkQueue;bool IsEmpty(LinkQueue* q)
{return q->front == q->rear;
}void InitQueue(LinkQueue* q)
{if (q->front != NULL){QNode* p = q->front;while (p){QNode* temp = p;p = p->next;free(temp);}q->front = q->rear = NULL;}QNode* head = (QNode*)malloc(sizeof(QNode));if (!head){printf("初始化失败,内存不足!\n");return;}head->next = NULL;q->front = head;q->rear = head;printf("队列初始化成功!\n");
}bool EnQueue(LinkQueue* q, int data)
{QNode* newNode = (QNode*)malloc(sizeof(QNode));if (!newNode){printf("内存分配失败,无法入队!\n");return false;}newNode->data = data;newNode->next = NULL;q->rear->next = newNode;q->rear = newNode;return true;
}bool Dequeue(LinkQueue* q, int *data)
{if (IsEmpty(q)){printf("队列为空,无法出队!\n");return false;}QNode* temp = q->front->next;*data = temp->data;q->front->next = temp->next;if (q->rear == temp){q->rear = q->front;}free(temp);return true;
}void DestroyQueue(LinkQueue* q)
{if (q->front == NULL){return;}QNode* p = q->front;while (p){QNode* temp = p;p = p->next;free(temp);}q->front = q->rear = NULL;printf("队列已销毁!\n");}void DisplayQueue(LinkQueue* q)
{if (IsEmpty(q)){printf("队列为空!\n");return;}QNode* p = q->front->next;printf("队列元素:>");while (p){printf("%d ", p->data);p = p->next;}printf("\n");}// 查找元素位置(返回1-based位置,找不到返回-1)
int FindElement(LinkQueue* q, int value)
{if (IsEmpty(q)){return -1;}QNode* p = q->front->next;int pos = 1;while (p){if (p->data == value){return pos;}p = p->next;pos++;}return -1;
}int QueueLength(LinkQueue* q)
{int len = 0;QNode* p = q->front->next;while (p){len++;p = p->next;}return len;
}void menu()
{printf("===================\n");printf("链队列操作菜单:>\n");printf("1. 初始化队列\n");printf("2. 入队\n");printf("3. 出队\n");printf("4. 判空\n");printf("5. 显示队列\n");printf("6. 查找元素\n");printf("7. 计算队列长度\n");printf("8. 销毁队列\n");printf("0. 退出\n");printf("请输入选项:>");
}int main()
{LinkQueue queue = { NULL,NULL };int choice = 0;int data = 0;while (1){menu();if (scanf_s("%d", &choice) != 1){printf("输入错误,请重新输入!\n");while (getchar() != '\n');continue;}switch (choice){case 0:DestroyQueue(&queue);printf("程序已退出!\n");return 0;case 1:InitQueue(&queue);break;case 2:{if (queue.front == NULL){printf("队列未初始化,请先初始化!\n");break;}printf("请输入要入队的整数:");if (scanf_s("%d", &data) != 1){printf("输入错误,请重新输入!\n");while (getchar() != '\n');break;}if (EnQueue(&queue, data)){printf("元素 %d 入队成功!\n", data);}break;}case 3:{if (queue.front == NULL){printf("队列未初始化,请先初始化!\n");break;}int dequeuedData = 0;if (Dequeue(&queue, &dequeuedData)){printf("出队元素:%d\n", dequeuedData);}break;}case 4:{if (queue.front == NULL){printf("队列未初始化!\n");}else{printf("队列%s空\n", IsEmpty(&queue) ? "为" : "不");}break;}case 5:{if (queue.front == NULL){printf("队列未初始化!\n");}else{DisplayQueue(&queue);}break;}case 6:{if (queue.front == NULL){printf("队列未初始化!\n");break;}printf("请输入要查找的整数:");int value = 0;if (scanf_s("%d", &value) != 1){printf("输入错误,请重新输入!\n");while (getchar() != '\n');break;}int pos = FindElement(&queue, value);if (pos != -1){printf("元素 %d 存在于队列中,位置为第%d个!\n", value, pos);}else{printf("元素 %d 不存在于队列中!\n", value);}break;}case 7:{if (queue.front == NULL){printf("队列未初始化!\n");}else{printf("队列长度:%d\n", QueueLength(&queue));}break;}case 8:{if (queue.front == NULL){printf("队列未初始化!\n");}else {DestroyQueue(&queue);}break;}default:printf("无效选项,请重新输入!\n");break;}}return 0;
}
以上是基于VS2022编译器,用C语言编写的——用c语言实现——一个带头节点的链队列,支持用户输入交互界面、初始化、入队、出队、查找、判空判满、显示队列、遍历计算长度等功能,注意代码的健壮性,包括边界、是否为空指针、以及防止用户输入错误数据,未初始化就进行出列、入队操作等
❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀
参考课程:哔哩哔哩——王道考研数据结构相关视频。
相关文章:
用c语言实现——一个带头节点的链队列,支持用户输入交互界面、初始化、入队、出队、查找、判空判满、显示队列、遍历计算长度等功能
一、知识介绍 带头节点的链队列是一种基于链表实现的队列结构,它在链表的头部添加了一个特殊的节点,称为头节点。头节点不存储实际的数据元素,主要作用是作为链表的起点,简化队列的操作和边界条件处理。 1.节点结构 链队列的每…...
webpack基础使用了解(入口、出口、插件、加载器、优化、别名、打包模式、环境变量、代码分割等)
目录 1、webpack简介2、简单示例3、入口(entry)和输出(output)4、自动生成html文件5、打包css代码6、优化(单独提取css代码)7、优化(压缩过程)8、打包less代码9、打包图片10、搭建开发环境(webpack-dev-server…...
【项目】基于MCP+Tabelstore架构实现知识库答疑系统
基于MCPTabelstore架构实现知识库答疑系统 整体流程设计(一)Agent 架构(二)知识库存储(1)向量数据库Tablestore(2)MCP Server (三)知识库构建(1&a…...
C语言高频面试题——malloc 和 calloc区别
在 C 语言中,malloc 和 calloc 都是用于动态内存分配的函数,但它们在 内存初始化、参数形式 和 使用场景 上有显著区别。以下是详细的对比分析: 1. 函数原型 malloc void* malloc(size_t size);功能:分配 未初始化 的连续内存块…...
深入探讨JavaScript性能瓶颈与优化实战指南
JavaScript作为现代Web开发的核心语言,其性能直接影响用户体验与业务指标。随着2025年前端应用的复杂性持续增加,性能优化已成为开发者必须掌握的核心技能。本文将从性能瓶颈分析、优化策略、工具使用三个维度,结合实战案例,系统梳理JavaScript性能优化的关键路径。 一、Ja…...
[创业之路-376]:企业法务 - 创业,不同的企业形态,个人承担的风险、收益、税费、成本不同
在企业法务领域,创业时选择不同的企业形态,个人在风险承担、收益分配、税费负担及运营成本方面存在显著差异。以下从个人独资企业、合伙企业、有限责任公司、股份有限公司四种常见形态展开分析: 一、个人承担的风险 个人独资企业 风险类型&…...
【Lua】Lua 入门知识点总结
Lua 入门学习笔记 本教程旨在帮助有编程基础的学习者快速入门Lua编程语言。包括Lua中变量的声明与使用,包括全局变量和局部变量的区别,以及nil类型的概念、数值型、字符串和函数的基本操作,包括16进制表示、科学计数法、字符串连接、函数声明…...
低空经济 WebGIS 无人机配送 | 图扑数字孪生
2024 年,”低空经济” 首次写入政府工作报告,在政策驱动下各地纷纷把握政策机遇,从基建网络、场景创新、产业生态、政策激励等方面,构建 “规划-建设-应用-赋能” 的系统性布局,作为新质生产力的重要体现,推…...
【程序员 NLP 入门】词嵌入 - 如何基于计数的方法表示文本? (★小白必会版★)
🌟 嗨,你好,我是 青松 ! 🌈 希望用我的经验,让“程序猿”的AI学习之路走的更容易些,若我的经验能为你前行的道路增添一丝轻松,我将倍感荣幸!共勉~ 【程序员 NLP 入门】词…...
基于机器学习的多光谱遥感图像分类方法研究与定量评估
多光谱遥感技术通过获取可见光至红外波段的光谱信息,为地质勘探、农业监测、环境调查等领域提供了重要支持。与普通数码相机相比,多光谱成像能记录更丰富的波段数据(如近红外、短波红外等),从而更精准地识别地物特征。…...
BEVDepth: Acquisition of Reliable Depth for Multi-View 3D Object Detection
背景 基于多视角图片的3D感知被LSS证明是可行的,它使用估计的深度将图像特征转化为3D视椎,再将其压缩到BEV平面上。对于这个得到的BEV特征图,它支持端到端训练以及各种下游任务。但是对于深度估计这一块学习的深度质量如何,到目前为止没有相关工作研究。 贡献 本文的贡献…...
【Linux】静态库 动态库
🌻个人主页:路飞雪吖~ 🌠专栏:Linux 目录 一、👑静态库和动态库 静态库: 动态库: 🌠手动制作静态库 && 手动调用一下我们自己写的静态库 1> 安装到系统里面 ✨生成静…...
Java转Go日记(六):TCP黏包
服务端代码如下: // socket_stick/server/main.gofunc process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)var buf [1024]bytefor {n, err : reader.Read(buf[:])if err io.EOF {break}if err ! nil {fmt.Println("read from client…...
(51单片机)LCD显示温度(DS18B20教程)(LCD1602教程)(延时函数教程)(单总线教程)
演示视频: LCD显示温度 源代码 如上图将9个文放在Keli5 中即可,然后烧录在单片机中就行了 烧录软件用的是STC-ISP,不知道怎么安装的可以去看江科大的视频: 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.…...
【通过Docker快速部署Tomcat9.0】
文章目录 前言一、部署docker二、部署Tomcat2.1 创建存储卷2.2 运行tomcat容器2.3 查看tomcat容器2.4 查看端口是否监听2.5 防火墙开放端口 三、访问Tomcat 前言 Tomcat介绍 Tomcat 是由 Apache 软件基金会(Apache Software Foundation)开发的一个开源 …...
云原生--基础篇-3--云原生概述(云、原生、云计算、核心组成、核心特点)
1、什么是云和原生 (1)、什么是云? “云”指的是云计算环境,代表应用运行的基础设施和资源。依赖并充分利用云计算的弹性、分布式和资源池化能力。 核心含义: 1、云计算基础设施 云原生应用的设计和运行完全基于云…...
Spark-Streaming
Spark-Streaming概述 DStream实操 案例一:WordCount案例 需求:使用 netcat 工具向 9999 端口不断的发送数据,通过 SparkStreaming 读取端口数据并统计不同单词出现的次数 实验步骤: 添加依赖 <dependency> <gro…...
乐视系列玩机------乐视2 x620红灯 黑砖刷写教程以及新版刷写工具的详细释义
乐视x620在上期解析了普通黑砖情况下的救砖刷机过程。但在一些例外的情况下。使用上面的步骤会一直刷写报错 。此种情况就需要另外一种强制刷写方法来救砖 通过博文了解💝💝💝 1💝💝💝-----详细解析乐视2 x620系列 红灯 黑砖线刷救砖的步骤 2💝💝💝----图…...
若依SpringCloud项目-定制微服务模块
若依SpringCloud项目-定制微服务模块 关于微服务先不过多介绍,刚开始熟悉并不能讲的很彻底,成熟的微服务项目-若依SpringCloud就是一个典型的微服务架构工程(网上有很多教程了,不明白的可以学习一下)。 我正在看的视…...
【扫描件批量改名】批量识别扫描件PDF指定区域内容,用识别的内容修改PDF文件名,基于C++和腾讯OCR的实现方案,超详细
批量识别扫描件PDF指定区域内容并重命名文件方案 应用场景 本方案适用于以下场景: 企业档案数字化管理:批量处理扫描的合同、发票等文件,按内容自动分类命名财务票据处理:自动识别票据上的关键信息(如发票号码、日期)用于归档医疗记录管理:从扫描的检查报告中提取患者I…...
学习Docker遇到的问题
目录 1、拉取hello-world镜像报错 1. 检查网络连接 排查: 2. 配置 Docker 镜像加速器(推荐) 具体解决步骤: 1.在服务器上创建并修改配置文件,添加Docker镜像加速器地址: 2. 重启Docker 3. 拉取hello-world镜像 2、删除镜像出现异常 3、 容器内部不能运行ping命令 …...
Docker 数据卷
目录 一、数据卷(Data Volume) 二、使用 1、单独建立数据卷 2、挂载主机数据卷 3、数据卷容器挂载 基本语法: 工作原理: 主要用途: 使用事例: 一、数据卷(Data Volume) 数据卷的使用,类似于 Linux 下对目录或文件进行 mount 数据卷(Data Volume)是一个可供一个或多…...
【数据结构】励志大厂版·初级(二刷复习)双链表
前引:今天学习的双链表属于链表结构中最复杂的一种(带头双向循环链表),按照安排,我们会先进行复习,如何实现双链表,如基本的头插、头删、尾删、尾插,掌握每个细节,随后进…...
通过dogssl申请ssl免费证书
SSL证书作为实现HTTPS加密的核心工具,能够确保用户与网站之间的数据传输安全。尤其是在小程序之类的开发时,要求必须通过https发起请求的情况下。学会如何免费申请一个ssl证书就很有必要了。这里我分享一下,我通过dogssl如何申请ssl的。 一&…...
路由与路由器
路由的概念 路由是指在网络通讯中,从源设备到目标设备路径的选择过程。路由器是实现这一过程的关键设备,它通过转发数据包来实现网络的互联。路由工作在OSI参考模型的第三层,‘网络层’。 路由器的基本原理 路由器通过维护一张路由表来决定…...
Docker底层原理浅析 | namespace+cgroups+文件系统
本文目录 1. Linux NamespaceLinux系统里是否只能有一个pid为1的进程?namespace机制查看namespacenamespace机制测试使用Docker验证namespace机制 2. Dcoerk网络模式3.Control groups4.文件系统(联合文件系统)5. 容器格式 1. Linux Namespace…...
【无人机】使用扩展卡尔曼滤波 (EKF) 算法来处理传感器测量,各传感器的参数设置,高度数据融合、不同传感器融合模式
目录 #1、IMU #2、磁力计 #3、高度 #典型配置 #4、气压计 #静压位置误差修正 #气压计偏置补偿 #5、全球导航系统/全球定位系统--GNSS/GPS #位置和速度测量 #偏航测量 #GPS 速度的偏航 #双接收器 #GNSS 性能要求 #6、测距 #条件范围辅助-Conditional range aidin…...
常见的raid有哪些,使用场景是什么?
RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)是一种将多个物理硬盘组合成一个逻辑硬盘的技术,目的是通过数据冗余和/或并行访问提高性能、容错能力和存储容量。不同的 RAID 级别有不同的实现方式和应用场景。以下…...
《 C++ 点滴漫谈: 三十四 》从重复到泛型,C++ 函数模板的诞生之路
一、引言 在 C 编程的世界里,类型是一切的基础。我们为 int 写一个求最大值的函数,为 double 写一个相似的函数,为 std::string 又写一个……看似合理的行为,逐渐堆积成了难以维护的 “函数墙”。这些函数逻辑几乎一致࿰…...
EasyRTC打造无人机低延迟高清实时通信监控全场景解决方案
一、方案背景 随着无人机技术的飞速发展,其在航拍、物流配送、农业监测、应急救援等多个领域的应用日益广泛。然而,无人机在实际作业过程中面临着诸多挑战,如通信延迟、数据传输不稳定、监控范围有限等。EasyRTC作为一种高效、低延迟的实时通…...
【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出)
【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出) 引言 本文使用状态空间模型实现失业率递归预测,状态空间模型(State Space Model, SSM)是一种用于描述动态系统行为的…...
关于大数据的基础知识(三)——数据安全与合规
成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于大数据的基础知识(三&a…...
从信息泄露到内网控制
0x01 背景 之前常见用rce、文件上传等漏洞获取webshell,偶然遇到一次敏感信息泄露获取权限的渗透,简单记录一下过程。 0x02 信息泄露 发现系统某端口部署了minio服务,经过探测发现存在minio存储桶遍历 使用利用工具把泄露的文件全部整理一…...
【Qt】QDialog类
🌈 个人主页:Zfox_ 🔥 系列专栏:Qt 目录 一:🔥 对话框 - QDialog 🦋 基本介绍🦋 对话框分类🦋 Qt 内置对话框🎀 QMessageBox -消息对话框🎀 QColo…...
【Spring Boot基础】MyBatis的基础操作:增删查改、列名和属性名匹配 -- XML实现
MyBatis的基础操作 1. MyBatis XML配置文件1.1 简单介绍1.2 配置连接字符串和MyBatis1.3 XMl文件实现--分层1.4 XMl文件实现--举例 2.增删改查操作2.1 增(insert)2.1.1 不使用Param2.1.2 用Param2.1.3 返回自增键 2.2 删(delete)2…...
谷歌推出探索型推荐新范式:双LLM架构重塑用户兴趣挖掘
文章目录 1. 背景1.1 闭环困境1.2 谷歌的两次失败尝试1.2.1 尝试一:轻量微调1.2.2 尝试二:RLHF 强化学习微调 1.3 双LLM范式的提出1.3.1 模型1:Novelty LLM — 负责生成“探索方向”1.3.2 模型2:Alignment LLM — 负责评估“相关性…...
Linux kernel signal原理(下)- aarch64架构sigreturn流程
一、前言 在上篇中写到了linux中signal的处理流程,在do_signal信号处理的流程最后,会通过sigreturn再次回到线程现场,上篇文章中介绍了在X86_64架构下的实现,本篇中介绍下在aarch64架构下的实现原理。 二、sigaction系统调用 #i…...
使用 LangChain + Higress + Elasticsearch 构建 RAG 应用
RAG(Retrieval Augmented Generation,检索增强生成) 是一种结合了信息检索与生成式大语言模型(LLM)的技术。它的核心思想是:在生成模型输出内容之前,先从外部知识库或数据源中检索相关信息&…...
【Linux】46.网络基础(3.3)
文章目录 5. 其他重要协议或技术5.1 DNS(Domain Name System)5.1.1 DNS背景5.1.2 域名简介 5.2 ICMP协议5.2.1 ICMP功能5.2.2 ICMP的报文格式5.2.3 ping命令5.2.4 一个值得注意的坑5.2.5 traceroute命令 5.3 NAT技术5.3.1 NAT技术背景5.3.2 NAT IP转换过程5.3.3 NAPT5.3.4 NAT技…...
【Unity笔记】Unity + OpenXR项目无法启动SteamVR的排查与解决全指南
图片为AI生成 一、前言 随着Unity在XR领域全面转向OpenXR标准,越来越多的开发者选择使用OpenXR来构建跨平台的VR应用。但在项目实际部署中发现:打包成的EXE程序无法正常启动SteamVR,或者SteamVR未能识别到该应用。本文将以“Unity OpenXR …...
【sylar-webserver】重构 增加内存池
文章目录 内存池设定结构ThreadCacheCentralCachePageCache allocatedeallocate测试 参考 https://github.com/youngyangyang04/memory-pool 我的代码实现见 https://github.com/star-cs/webserver 内存池 ThreadCache(线程本地缓存) 每个线程独立的内存…...
云账号安全事件分析:黑客利用RAM子账户发起ECS命令执行攻击
事件背景 某企业云监控系统触发高危告警,提示API请求中包含黑客工具特征(cf_framework),攻击者试图通过泄露的RAM子账户凭据调用ECS高危API。以下是攻击关键信息整理: 字段详情告警原因API请求包含黑客工具特征(cf_framework)攻击实体RAM子账户 mq泄露凭证AccessKey ID…...
Node.js 模块导入的基本流程
Node.js 模块导入的基本流程,主要是 CommonJS 模块加载机制(即使用 require())的内部执行步骤。下面我用清晰的结构给你梳理一下这个过程: ✅ Node.js 模块导入的基本流程(使用 require()) const someModu…...
Unitest和pytest使用方法
unittest 是 Python 自带的单元测试框架,用于编写和运行可重复的测试用例。它的核心思想是通过断言(assertions)验证代码的行为是否符合预期。以下是 unittest 的基本使用方法: 1. 基本结构 1.1 创建测试类 继承 unittest.TestC…...
wps批量修改字体
选择这个小箭头 找到需要修改的字体如正文,右击修改选择合适的字体确定即可...
【Linux网络】各版本TCP服务器构建 - 从理解到实现
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
航电系统多模态融合技术要点
一、技术要点 1. 多模态数据特性分析 异构数据对齐:需处理不同传感器(如雷达、摄像头、IMU、ADS-B等)在时间、空间、精度和采样率上的差异,需设计同步机制(如硬件时钟同步、软件插值对齐)。 数据预处…...
【Git】branch合并分支
在 Git 中,将分支合并到 main 分支是一个常见的操作。以下是详细的步骤和说明,帮助你完成这个过程。 1. 确保你在正确的分支上 首先,你需要确保当前所在的分支是 main 分支(或者你要合并到的目标分支)。 检查当前分支…...
uniapp-商城-33-shop 布局搜索页面以及u-search
shop页面上有一个搜索,可以进行商品搜索,这里我们先做一个页面布局,后面再来进行数据i联动。 1、shop页面的搜索 2、搜索的页面代码 <navigator class"searchView" url"/pagesub/pageshop/search/search"> …...
蓝桥杯常考的找规律题
目录 灵感来源: B站视频链接: 找规律题具有什么样的特点: 报数游戏(Java组): 题目描述: 题目链接: 思路详解: 代码详解: 阶乘求和(Java组…...