顺序表功能实现(入手版详解)
🍉博客主页:阿博历练记
📖文章专栏:数据结构与算法
🚚代码仓库:阿博编程日记
🌹欢迎关注:欢迎友友们点赞收藏+关注哦
文章目录
- 🍓前言
- ✨顺序表
- 🔍1.顺序表的整体框架
- 🔍2.打印顺序表的菜单
- 🔍3.主函数的创建
- ⭐第一个case后面加中括号
- ⭐枚举变量和函数名同名
- 🔍4.顺序表的定义
- 🔍5.顺序表的初始化
- ⭐传结构体本身还是它的地址
- 🔍6.顺序表的尾插
- 🔍7.顺序表的打印
- 🔍8.顺序表的头插
- ⭐挪动数据(从后往前)
- 🔍9.顺序表的尾删
- ⭐assert的声明
- ⭐数组越界不一定报错
- 🔍10.顺序表的头删
- ⭐挪动数据(从前往后)
- 🔍11.顺序表任意位置的插入
- 🔍12.顺序表任意位置的删除
- ⭐assert声明的改变&&函数的附用
- 🔍13.顺序表数据的查找
- 🔍13.顺序表数据的修改
- 🔍14.顺序表的销毁
- 👻Seqlist.h代码
- 👻Seqlist.c代码
- 👻test.c代码
🍓前言
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
1.静态顺序表:使用定长数组
存储元素.
2.动态顺序表:使用动态开辟的数组
存储.
友友们,这里虽然顺序表删除需要挪动大量的元素很不方便,但是顺序表有个绝对的优势就是下标的随机访问,比如:二分查找、还有一些排序都需要作用到数组之上.
✨顺序表
🔍1.顺序表的整体框架
1.创建一个test.c文件:测试顺序表的相关功能
2.创建一个SeqList.c文件:实现顺序表功能的定义
3.创建一个SeqList.h文件:实现顺序表功能的声明
🔍2.打印顺序表的菜单
void menu()
{printf("***************************\n");printf("****1.尾插数据 2.尾删数据****\n");printf("****3.头插数据 4.头删数据****\n");printf("****5.打印数据 0.退出 ****\n");printf("***************************\n");
}
🔍3.主函数的创建
enum option
{ Destory,PushBack,PopBack,PushFront,PopFront,Print,
};
int main()
{SL s;SLInit(&s);int option = 0;do{menu();printf("请输入你的选择:\n");scanf("%d", &option);switch (option){case PushBack:{printf("请输入要尾插数据的个数,再依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushBack(&s, x);n--;}break;}case PopBack:printf("尾删成功\n");SLPopBack(&s);break;case PushFront:printf("请输入要头插数据的个数,在依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushFront(&s, x);n--;}break;case PopFront:printf("头删成功\n");SLPopFront(&s);break;case Print:SLPrint(&s);break;case Destory:SLDestory(&s);break;default:printf("选择错误,请重新选择:\n");break;}} while (option);return 0;
}
⭐第一个case后面加中括号
友友们,这里我们加中括号是因为我们需要把它里面的n和x变成
局部变量
,防止和下面的x和n出现变量的重定义
⭐枚举变量和函数名同名
函数名代表函数的地址,可以认为是函数指针类型,如果我们用它当作枚举变量的话,这里我们就会改变它的类型,当再次调用函数的时候,程序就会报错.
🔍4.顺序表的定义
//typedef int SLDatatype;
//
//struct Seqlist
//{
// SLDatatype a[N]; //静态的顺序表 给小了不够用,给大了浪费,这里我们考虑动态顺序表
// int size;
//};typedef int SLDatatype;typedef struct Seqlist
{SLDatatype * a; //动态的顺序表int size; //存储的有效数据个数int capcity; //容量空间
}SL;
🔍5.顺序表的初始化
void SLInit(SL* ps1)
{assert(ps1);ps1->a =(SLDatatype*)malloc(sizeof(SLDatatype)*4);if (ps1->a == NULL){perror("malloc");return;}ps1->capcity = 4;ps1->size = 0;
}
⭐传结构体本身还是它的地址
1.传结构体本身
2.传结构体的地址
友友们,这里传结构体本身,形参相当于实参的一份
临时拷贝
,形参的改变不会影响实参,所以如果如果我们要改变它,就要传它的地址,这样我们解引用就可以改变它了.
🔍6.顺序表的尾插
void SLCheckcapcity(SL*ps1)
{assert(ps1);if (ps1->size == ps1->capcity){SLDatatype* temp =(SLDatatype*) realloc(ps1->a, sizeof(SLDatatype) * ps1->capcity * 2); if (temp == NULL){perror("realloc");return;}ps1->a = temp;ps1->capcity *= 2;}
}
void SLPushBack(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);ps1->a[ps1->size++] = x;
}
🔍7.顺序表的打印
void SLPrint(SL* ps1)
{assert(ps1);for (int i = 0; i < ps1->size; i++){printf("%d ", ps1->a[i]);}printf("\n");
}
🔍8.顺序表的头插
1.方法一:
void SLPushFront(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);//挪动数据int end = ps1->size - 1;while (end >= 0){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[0] = x;ps1->size++;
}
⭐挪动数据(从后往前)
2.方法二:
void SLPushFront(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);//挪动数据int end = ps1->size;while (end > 0){ps1->a[end] = ps1->a[end-1];end--;}ps1->a[0] = x;ps1->size++;
}
🔍9.顺序表的尾删
void SLPopBack(SL* ps1)
{assert(ps1->size > 0&&ps1); //暴力检查ps1->size--;
}
⭐assert的声明
友友们注意,如果我们顺序表里面有5个数据,而我们尾删6次,这时候ps1->size就变成-1了,就会出现数组越界,就是第一个数据放到下标为-1的位置上了,导致结果出错. 所以这里我们就需要assert来声明一下:如果顺序表为空,就不需要再尾删了.
⭐数组越界不一定报错
友友们一定要清楚越界本身就是一个抽查,并不是一定会报错的,如果数组下标越界了,那么它会自动接着那块内存往后写,如果界外的空间暂时没有被利用,那么我们就可以占用那块内存,但是如果界外的内存已经存放了数据,我们越界过去就会覆盖那块内存,则就有可能导致错误的产生.
🔍10.顺序表的头删
1.方法一:start为1
void SLPopFront(SL* ps1)
{assert(ps1);assert(ps1->size > 0);int start = 1;while (start < ps1->size){ps1->a[start - 1] = ps1->a[start];start++;}ps1->size--;
}
2.方法二:start为0
void SLPopFront(SL* ps1)
{assert(ps1);assert(ps1->size > 0);int start = 0;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
⭐挪动数据(从前往后)
🔍11.顺序表任意位置的插入
void SLInsert(SL* ps1, int pos,SLDatatype x)
{assert(pos >= 0 && pos <= ps1->size&&ps1); //防止越界访问SLCheckcapcity(ps1);int end = ps1->size - 1;while (end >= pos){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[pos] = x;ps1->size++;
}
友友们,这里我们的
头插
和尾插
其实就是两种特殊位置的任意插入,这时候我们就可以附用这个函数,比如头插:SLInsert(ps1,0,x),尾插:SLInsert(ps1,ps1->size,x).
🔍12.顺序表任意位置的删除
1.方法一:start为pos+1
void SLErase(SL* ps1, int pos)
{assert(pos >= 0 && pos < ps1->size&&ps1); //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素int start = pos + 1;while (start < ps1->size){ps1->a[start - 1] = ps1->a[start];start++;}ps1->size--;
}
2.方法二:start为pos
void SLErase(SL* ps1, int pos)
{assert(pos >= 0 && pos < ps1->size&&ps1); //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素int start = pos;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
⭐assert声明的改变&&函数的附用
友友们注意,这里pos就不能等于ps1->size了,因为我们要删除顺序表中的数据,它最多下标为ps1->size-1.这里我们的
头删
和尾删
就可以附用这个函数,头删就是:SLErase(ps1,0),尾删就是:(ps1,ps1->size-1).
🔍13.顺序表数据的查找
int SLFind(SL* ps1, SLDatatype x)
{assert(ps1);for (int i = 0; i < ps1->size; i++){if (ps1->a[i] == x){return i;}}return -1;
}
友友们注意,因为下标不可能是负数,所以我们没有找到就可以返回负数,一般我们都使用-1.
🔍13.顺序表数据的修改
void Modify(SL* ps1, int pos, SLDatatype x)
{assert(pos >= 0 && pos < ps1->size&&ps1);ps1->a[pos] = x;
}
🔍14.顺序表的销毁
1.free之后需要置空
void SLDestory(SL*ps1)
{assert(ps1);free(ps1->a);ps1->a = NULL;ps1->size = 0;ps1->capcity = 0;
}
友友们,这里我们把ps1->a释放之后,因为它不是在函数内部创建的指针变量,它存放的是顺序表的地址,所以释放之后,函数外部可能会调用到它,所以我们这里需要及时置空.
2.free之后不需要置空
void rate(int* nums, int numsSize, int k)
{if (k > numsSize){k %= numsSize;}int* temp = (int*)malloc(sizeof(int) * numsSize);memcpy(temp + k, nums, sizeof(int) * numsSize - k);memcpy(temp, nums + numsSize - k, sizeof(int) * k);memcpy(nums, temp, sizeof(int) * numsSize);free(temp);temp = NULL;
}
友友们注意了,这里的temp是我们在这个函数内部创建的指针变量,它是一个局部变量,它出完函数作用域就销毁了,所以我们free释放之后,就还给操作系统了,以后它也不会被调用了,所以这里我们不置空也是可以的.
👻Seqlist.h代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//typedef int SLDatatype;
//
//struct Seqlist
//{
// SLDatatype a[N]; //静态的顺序表 给小了不够用,给大了浪费,这里我们考虑动态顺序表
// int size;
//};typedef int SLDatatype;typedef struct Seqlist
{SLDatatype * a; //动态的顺序表int size; //存储的有效数据个数int capcity; //容量空间
}SL;
void SLInit(SL* ps1);
void SLDestory(SL *ps1);
void SLPushBack(SL* ps1, SLDatatype x);
void SLPushFront(SL* ps1, SLDatatype x);
void SLPopBack(SL* ps1);
void SLPopFront(SL* ps1);
void SLPrint(SL* ps1);
void SLInsert(SL* ps1, int pos,SLDatatype x);
void SLErase(SL* ps1, int pos);
//找到了返回下标,找不到返回-1
int SLFind(SL* ps1, SLDatatype x);
void Modify(SL* ps1, int pos, SLDatatype x);
👻Seqlist.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void SLInit(SL* ps1)
{assert(ps1);ps1->a =(SLDatatype*)malloc(sizeof(SLDatatype)*4);if (ps1->a == NULL){perror("malloc");return;}ps1->capcity = 4;ps1->size = 0;
}
void SLDestory(SL*ps1)
{assert(ps1);free(ps1->a);ps1->a = NULL;ps1->size = 0;ps1->capcity = 0;
}
void SLPrint(SL* ps1)
{assert(ps1);for (int i = 0; i < ps1->size; i++){printf("%d ", ps1->a[i]);}printf("\n");
}
void SLCheckcapcity(SL*ps1)
{assert(ps1);if (ps1->size == ps1->capcity){SLDatatype* temp =(SLDatatype*) realloc(ps1->a, sizeof(SLDatatype) * ps1->capcity * 2); if (temp == NULL){perror("realloc");return;}ps1->a = temp;ps1->capcity *= 2;}
}
void SLPushBack(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);ps1->a[ps1->size++] = x;
}
void SLPushFront(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);//挪动数据int end = ps1->size;while (end >0){ps1->a[end] = ps1->a[end-1];end--;}ps1->a[0] = x;ps1->size++;/*assert(ps1);SLInsert(ps1, 0, x);*/
}
void SLPopBack(SL* ps1)
{assert(ps1->size > 0&&ps1); //暴力检查/*ps1->a[ps1->size - 1] = 0;*/ //有可能最后一个数据就是0/*if (ps1->size == 0) {return;}*/ps1->size--;/*assert(ps1);SLErase(ps1, ps1->size - 1);*/
}
void SLPopFront(SL* ps1)
{assert(ps1);assert(ps1->size > 0);int start = 0;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
void SLInsert(SL* ps1, int pos,SLDatatype x)
{assert(pos >= 0 && pos <= ps1->size&&ps1); //防止越界访问SLCheckcapcity(ps1);int end = ps1->size - 1;while (end >= pos){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[pos] = x;ps1->size++;
}
void SLErase(SL* ps1, int pos)
{assert(pos >= 0 && pos < ps1->size&&ps1); //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素int start = pos;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
int SLFind(SL* ps1, SLDatatype x)
{assert(ps1);for (int i = 0; i < ps1->size; i++){if (ps1->a[i] == x){return i;}}return -1;
}
void Modify(SL* ps1, int pos, SLDatatype x)
{assert(pos >= 0 && pos < ps1->size&&ps1);ps1->a[pos] = x;
}
👻test.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void menu()
{printf("***************************\n");printf("****1.尾插数据 2.尾删数据****\n");printf("****3.头插数据 4.头删数据****\n");printf("****5.打印数据 0.退出 ****\n");printf("***************************\n");
}
enum option
{ Destory,PushBack,PopBack,PushFront,PopFront,Print,
};
int main()
{SL s;SLInit(&s);int option = 0;do{menu();printf("请输入你的选择:\n");scanf("%d", &option);switch (option){case PushBack:{printf("请输入要尾插数据的个数,再依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushBack(&s, x);n--;}break;}case PopBack:printf("尾删成功\n");SLPopBack(&s);break;case PushFront:printf("请输入要头插数据的个数,在依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushFront(&s, x);n--;}break;case PopFront:printf("头删成功\n");SLPopFront(&s);break;case Print:SLPrint(&s);break;case Destory:SLDestory(&s);break;default:printf("选择错误,请重新选择:\n");break;}} while (option);return 0;
}
相关文章:

顺序表功能实现(入手版详解)
🍉博客主页:阿博历练记 📖文章专栏:数据结构与算法 🚚代码仓库:阿博编程日记 🌹欢迎关注:欢迎友友们点赞收藏关注哦 文章目录 🍓前言✨顺序表🔍1.顺序表的整体…...
Java 中的线程是什么,如何创建和管理线程-下(十三)
书接上文 CompletableFuture CompletableFuture 是 Java 8 中新增的类,提供了更为强大的异步编程支持。它可以将多个异步任务组合成一个整体,并且可以处理异常情况。 例如,可以使用 CompletableFuture 来实现异步任务的串行执行࿱…...
为什么我的Windows 10 便签不支持更改字体?
Windows便签是一款常用的记录工具,可以帮助我们快速记录一些重要的信息。在使用Windows便签时,如果你想要更好地呈现你的信息,可以通过设置字体来达到这个效果。本文将介绍Windows便签字体设置的相关知识,希望对你有所帮助。 1、打…...

野火STM32电机系列(六)Cubemx配置ADC规则和注入通道
前文已经配置了GPIO、编码器 本节讲解CubeMXADC规则和注入通道 本文adc注入通道采用定时器触发,因此在上文定时器配置的基础上进行 常规信号(温度等)使用带DMA的常规通道连续采样 注入采样由定时器触发,采集电机三相电流&…...
预制菜,巨头们的新赛场
俗话说“民以食为天”,饮食对于大众的重要性自然是无需赘述。然而,随着生活节奏的加快,越来越多年轻人没有时间和精力去烹制菜肴,这也是外卖行业持续火热的重要原因之一。尽管如此,随着消费者健康意识的持续提升&#…...

英语语法第一章之英语语法综述
英语的任何句型基本都可以翻译成 什么怎么样 ,在这里什么就是我们常说的主语,而怎么样就是我们常说的谓语; 可能有些小伙伴会反问,不是主谓宾吗?别急等我慢慢讲解 在这里谓语也有很有多的不同的动作 可以独立完成的动作 句型&am…...

ChatGPT被淘汰了?Auto-GPT到底有多强
大家好,我是可夫小子,关注AIGC、读书和自媒体。解锁更多ChatGPT、AI绘画玩法。 说Auto-GPT淘汰了ChatGPT了,显然是营销文案里面的标题党。毕竟它还是基于ChatGPT的API,某种意义只是基于ChatGPT能力的应用。但最近,Auto…...

unity NGUI使用方法
基本用法 很多基本模块比如按钮、slider等都能从Prefab中直接拖拽到场景中实现,但都需要有一个Collider(Prefab已经自带) 因为不仅是UI,所有带有Collider的游戏物体都能接收到OnClick, OnPress这样的事件——前提是需…...

软件测试技术(五)软件测试流程
软件测试流程 软件测试流程如下: 测试计划测试设计测试执行 单元测试集成测试确认测试系统测试验收测试回归测试验证活动 测试计划 测试计划由测试负责人来编写,用于确定各个测试阶段的目标和策略。这个过程将输出测试计划,明确要完成的测…...

Redis缓存穿透和雪崩
Redis缓存穿透和雪崩 Redis缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题…...

【C++】set和map的使用
对于STL容器来说,有很多相似的功能,所以这里主要将与之前不同的功能说清楚 文章目录 1.对于set与map的简单理解2. setinsert迭代器遍历countmultisetinsertfindcount 3. mapinsert与迭代器的使用统计水果次数 operator []operator[]的实现理解对整体的拆…...
大学生学java编程的就业前景怎么样?我来聊聊自己的见解
今天兴哥想跟大家分享一个话题,就是学java到底好不好找工作。因为我发现很多粉丝朋友,之前可能并不是从事IT行业的,然后想转行来做这一行,或者是有些大四即将面临毕业的老哥,可能大学没有好好学习吧,然后专…...

JavaScript全解析——canvas 入门(上)
●canvas 是 HTML5 新增的一个标签, 表示画布 ●canvas 也是 h5 的画布技术, 我们通过代码的方式在画布上描绘一个图像 canvas 标签 ●向进行 canvas 绘图, 首先我们先要了解到 canvas 标签 ●是 html5 推出的一个标签 <html> <head>... </head> <body&…...
vue 插槽的用法
Vue的插槽(Slot)是一种可以让父组件向子组件传递内容的机制。插槽可以让开发者将组件的结构和内容分离开来,从而实现更好的可维护性和复用性。 在Vue中,插槽通过 标签实现。具体用法如下: 单个插槽 在子组件中使用一…...

【C++复习2】C++编译器的工作原理
如果你是一名newbird的话,建议观看如下视频加深你的理解,再看如下内容: https://www.bilibili.com/video/BV1N24y1B7nQ?p7 The cherno会额外告诉你如何将目标文件转换成汇编代码,CPU执行指令的过程以及编译器如何通过删除冗余变…...
回调函数_回顾
函数指针和回调函数 函数指针是指向函数的指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。 函数指针可以像一般函数一样,用于调用函数、传递参数。 直接用指针表示函数,而不是*指针ÿ…...

今天面了个字节跳动拿35K出来的,真是砂纸擦屁股,给我露了一手啊
今年的金三银四已经结束,很多小伙伴收获不错,拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文,为此咱这里也统一做一次大整理和大归类,这也算是划重点了。 俗话说得好,他山之…...
8. 数据结构与算法
8. 数据结构与算法 常见面试题 说说一个算法有哪些时间复杂度?归并算法时间复杂度是多少?⭐⭐⭐ O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) 归并算法时间复杂度是O(nlogn) 说说数组时间复杂度,什么场景下使用?⭐⭐⭐⭐⭐ 从渐进趋势…...

Springboot +Flowable,任务认领和回退(一)
一.简介 有的时候,一个任务节点会存在多个候选人,例如:张三提交一个任务,这个任务即可以由李四处理,又可以由王五处理,那么针对这种多个任务候选人的情况,该如何处理? 二.绘制流程…...
机器学习 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络模型答疑
机器学习 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络模型答疑 目录 机器学习 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络模型答疑问题汇总问题一答疑问题二答疑问题三答疑问题四答疑问题五答疑参考资料问题汇总 有几个问题咨询一下: 1.数据集划分时出现了问题如何解决? 2…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...