学生信息管理系统(通讯录)----------通俗易懂、附源码、C语言实现
绪论:
本篇文章使结构体章节后的习题,如果你对C语言有问题,或者结构体有什么问题不妨看看我之前所写的文章(章回体),对于文件管理和内存分配问题我将在后面补上,对于这个学生信息管理系统我用了多种方法和分源管理的形式来写可能内容偏多,但都有着重大意义,可以自行对我的源码进行copy和删减一些用了多种方法的地方,当然直接用也是没什么问题的。
附:红色,部分为重点部分;蓝颜色为需要记忆的部分(不是死记硬背哈,多敲);黑色加粗或者其余颜色为次重点;黑色为描述需要
思维导图
要XMind思维导图的话可以私信哈
逐步实现的目录
1.界面的创建、和功能的选择
1.1分源管理
1.1.1在主函数内
1.1.3在contact.h
1.1.2在contact.c
2.功能的实现
2.1分源管理
2.1.1在主函数内
2.1.2在contact.h
2.1.3在contact.c
3.文件的保存、和文件的调用
3.1分源管理
3.1.1在主函数内
3.1.2在contact.c
3.1.3在contact.h
补充:
对于分源管理:这样做的原因是可以将这个程序的实现,分开来实现,主函数放在了test.c中这里就像一个枢纽(主干)来选择功能,而contact.c 中放着的是这些主干后的分支(他代表着所要实现的功能的具体代码),而contact.h(头文件)这里存放着一些在test.c 和 contact.c 同时需要用到的东西,如头文件的应用、#define 定义的常量 、以及函数的声明 、这样只需在.c(源文件)中引用#include"contact" 即可包含该文件中的内容
下面先上源码:
test.c:
#define _CRT_SECURE_NO_WARNINGS 1#include"contact.h"enum function
{Exit = 0,Add,Del,Search,Modeify,Show,Sort,Refresh
};void menu()
{printf("********************************\n");printf("********************************\n");printf("***** 1. Add 2.Del *****\n");printf("********************************\n");printf("***** 3.Search 4.Modeify *****\n");printf("********************************\n");printf("***** 5.Show 6.Sort *****\n");printf("********************************\n");printf("***** 7.refresh 0.exit *****\n");printf("********************************\n");printf("********************************\n");//1)添加学生信息//2)删除学生信息//3)查询学生信息//4)修改学生信息//5)展示所有学生信息//6)重新排序学生信息//7)刷新学生信息
}int main()
{int input = 0;Info_System con ;
//初始化InitCon(&con);//初始化方法二:Info_System con = {0};直接将全部置成0do{menu();printf("请选择>:");scanf("%d", &input);switch(input){case Add:Add_Stu_message(&con);break;case Del:Del_Stu_message(&con);break;case Search:Search_Stu_message(&con);break;case Modeify:Modeifyh_Stu_message(&con);break;case Show:Show_Stu_message(&con);break;case Sort:Sort_Stu_message(&con);break;case Refresh:Refresh_Stu_message(&con);break;case Exit:printf("退出\n");break;default:printf("选择错误,重新选择:\n");break;}} while (input);return 0;
}
contact.h:
#pragma once#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>#define Name_Max 20
#define Sex_Max 5
#define Class_Max 20
#define Room_Max 20#define PeoMax 100typedef struct PeoInfo
{int ID;// 学号char Name[Name_Max];// 姓名char Sex[Sex_Max];// 性别char Class[Class_Max];// 班级char Room[Room_Max];// 宿舍号int Score;// 成绩}PeoInfo;typedef struct management_System
{PeoInfo Contact[PeoMax];//存放人的信息int sz;//已近存放了多少个人}Info_System;void InitCon(Info_System *con);void Add_Stu_message(Info_System* con);void Show_Stu_message(const Info_System* con);void Del_Stu_message (Info_System* con);void Search_Stu_message(const Info_System* con);void Modeifyh_Stu_message(Info_System* con);void Sort_Stu_message(Info_System* con);void Refresh_Stu_message(Info_System* con);
contact.c:
#define _CRT_SECURE_NO_WARNINGS 1#include"contact.h"//初始化
void InitCon(Info_System* con)
{assert(con);con->sz = 0;memset(con->Contact, 0, sizeof(Info_System));//利用memset将一块连续的空间初始化成0最后要初始化多少个字节
}int FindById(int Id, const Info_System* con)
{int t = con->sz;//不要改变sz,用t来代替需要查找的人while (t--){if (Id == con->Contact[t].ID){return t;}}printf("找不到此人\n");return -1 ;//返回-1是因为区别于返回0(返回0表示查找的人的下标为0)
}
int FindByName(char * name,const Info_System* con)
{int t = con->sz;//不要改变sz,用t来代替需要查找的人while (t--){if (strcmp(name, con->Contact[t].Name) == 0)//--ret 是因为ret表示的是总人数,而总人数-1才能找到最后一个人{return t;}}printf("找不到此人\n");return -1;//返回-1是因为区别于返回0(返回0表示查找的人的下标为0)
}//增加
void Add_Stu_message(Info_System* con)
{assert(con);if (con->sz == PeoMax){printf("信息已满,请删除或刷新后再试\n");return;}printf("依次输入学号 名字 班级 性别 宿舍 计算机成绩\n并且以空格/回车分隔\n");scanf("%d %s %s %s %s %d", &con->Contact[con->sz].ID,con->Contact[con->sz].Name,con->Contact[con->sz].Class,con->Contact[con->sz].Sex,con->Contact[con->sz].Room,&con->Contact[con->sz].Score);con->sz += 1;//con->sz++;printf("添加完成\n");
}void Show_Stu_message(const Info_System* con)
{assert(con);printf("%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");for (int i = 0; i < con->sz;i++)//解引用操作符的优先级都很(最)高{printf("%-10d %-20s %-20s %-5s %-20s %-10d\n", con->Contact[i].ID,con->Contact[i].Name,con->Contact[i].Class,con->Contact[i].Sex,con->Contact[i].Room,con->Contact[i].Score);}}void Del_Stu_message(Info_System* con)
{assert(con);if (con->sz == 0){printf("没有学生信息\n");return;}int input = 0;printf("输入学号进行删除;>");scanf("%d", &input);int ret = FindById(input,con);if (ret != -1){for (ret; ret < con-> sz - 1; ret++) //sz -1 也要转化成下标{con->Contact[ret] = con->Contact[ret+1]; //注意返回的就是所对应的下标}con->sz--;printf("删除成功\n");}//if (ret!=-1)//{// memmove(con->Contact + ret, con->Contact + ret + 1, (con->sz)*sizeof(PeoInfo) - (ret) * sizeof(PeoInfo));// con->sz--;// printf("删除成功\n");//}}void Search_Stu_message(const Info_System* con)
{assert(con);int i = 0;printf("1.Id\n2.Name\n选择查找方法:>");scanf("%d", &i);if (i == 1){int input = 0;printf("输入学号进行查找:>");scanf("%d", &input);int ret = FindById(input, con);if (ret != -1){printf("%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");printf("%-10d %-20s %-20s %-5s %-20s %-10d\n", con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,con->Contact[ret].Score);}}else if (i == 2){char name[20] = { 0 };printf("输入姓名进行查找:>");scanf("%s",name);int ret = FindByName(name, con);if (ret != -1){printf("%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");printf("%-10d %-20s %-20s %-5s %-20s %-10d\n", con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,con->Contact[ret].Score);}}else{printf("选择错误\n");}}void Modeifyh_Stu_message(Info_System* con)
{assert(con);int i = 0;printf("1.Id\n2.Name\n选择查找方法:>");scanf("%d", &i);if (i == 1){int input = 0;printf("输入要修改的学生信息的学号:>");scanf("%d", &input);int ret = FindById(input, con);if (ret != -1){printf("修改:>\n");printf("依次输入学号 名字 班级 性别 宿舍 计算机成绩\n并且以空格/回车分隔\n");scanf("%d %s %s %s %s %d", &con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,&con->Contact[ret].Score);printf("修改完成\n");}}else if (i == 2){char name[20] = { 0 };printf("输入要修改的学生信息的姓名:>");scanf("%s", name);int ret = FindByName(name, con);if (ret != -1){printf("修改:>\n");printf("依次输入学号 名字 班级 性别 宿舍 计算机成绩\n并且以空格/回车分隔\n");scanf("%d %s %s %s %s %d", &con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,&con->Contact[ret].Score);printf("修改完成\n");}}else{printf("选择错误\n");}
}int Sort_Name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->Name, ((PeoInfo*)e2)->Name);}int Sort_age(const void* e1, const void* e2)
{return ((PeoInfo*)e1)->ID - ((PeoInfo*)e2)->ID;
}
void Sort_Stu_message(Info_System* con)
{assert(con);int input = 0;printf("1.以名字排序\n2.以学号排序\n");scanf("%d", &input);switch (input){case 1:qsort(con->Contact, con->sz, sizeof(con->Contact[0]), Sort_Name);printf("排序成功\n");break;case 2:qsort(con->Contact, con->sz, sizeof(con->Contact[0]), Sort_age);printf("排序成功\n");break;default:printf("输入错误\n");break;}
}void Refresh_Stu_message(Info_System* con)
{InitCon(con);printf("刷新成功\n");
}
1.界面的创建、和功能的选择
1.1分源管理
1.1.1在主函数内
- 创建目录(界面)
在main函数内创建一个目录函数
int main() {menu();retrn 0; }
直接通过打印的方法,打印出自己所想要的目录(界面)
void menu() {printf("********************************\n");printf("********************************\n");printf("***** 1. Add 2.Del *****\n");printf("********************************\n");printf("***** 3.Search 4.Modeify *****\n");printf("********************************\n");printf("***** 5.Show 6.Sort *****\n");printf("********************************\n");printf("***** 7.refresh 0.exit *****\n");printf("********************************\n");printf("********************************\n");//1)添加学生信息//2)删除学生信息//3)查询学生信息//4)修改学生信息//5)展示所有学生信息//6)重新排序学生信息//7)刷新学生信息 }
- 创建选择功能,
通过dowhile循环来不断的进行选择并且通过switch语句来控制所选择功能
int main() {int input = 0;do{printf("请选择>:");scanf("%d", &input);switch(input){case Add:Add_Stu_message(&con);break;case Del:Del_Stu_message(&con);break;case Search:Search_Stu_message(&con);break;case Modeify:Modeifyh_Stu_message(&con);break;case Show:Show_Stu_message(&con);break;case Sort:Sort_Stu_message(&con);break;case Refresh:Refresh_Stu_message(&con);break;case Exit:printf("退出\n");break;default:printf("选择错误,重新选择:\n");break;}} while (input);return 0; }
1.1.3在contact.h
- 创建一个结构体存放学生的信息
一个学生的信息可能有 学号、姓名、性别、班级、宿舍、成绩
所以我们可以用一个结构体来存,并且用typedef来将复杂的名字简化
typedef struct PeoInfo {int ID;// 学号char Name[Name_Max];// 姓名char Sex[Sex_Max];// 性别char Class[Class_Max];// 班级char Room[Room_Max];// 宿舍号int Score;// 成绩}PeoInfo;
- 再创建一个结构体来存放每个学生(用数组)以及再通过计数器来计存了几个学生了
同样用到typedef来简化
typedef struct management_System {PeoInfo Contact[PeoMax];//存放人的信息int sz;//已近存放了多少个人}Info_System;
1.1.2在contact.c
- 初始化学生信息
对于已经创建好的结构体,他们此时还是一些随机值需要初始化
所以写一个初始化函数来进行初始化
void InitCon(Info_System* con) {assert(con);con->sz = 0;memset(con->Contact, 0, sizeof(Info_System));//利用memset将一块连续的空间初始化成0最后要初始化多少个字节 }
其中有到了memset来直接对其初始化,
第一个元素放目标地址,第二个元素表示要放东西的整形形式(如0 -> 0 ;而 'a' -> 97),第三个元素表示这个目标的大小(byte),具体用法可以看这篇博客:进阶C语言第三章-------《字符函数和内存函数》 完整思维导图+基本练习题+深入细节+通俗易懂+知识点+建议收藏_溟洵的博客-CSDN博客
附:首先,对于这些进行解释:他是通过枚举的办法实现
的具体可以看看我写的一篇关于自定义类型的blog;其次,是对这个的解释
这是引用contact.h头文件,包含其里面的内容(函数的头文件,和函数声明)
2.功能的实现
2.1分源管理
2.1.1在主函数内
通过目录的选择后进入功能内部
2.1.2在contact.h

2.1.3在contact.c
添加学生信息
对于下面的scanf操作我们需要引用并且存进结构体中 对于数组来说不需要加上&
因为其数组名表示其地址 而对于整形就需要&了
先从con这是Info_System结构体的变量所以通过->访问其里面的成员Contact而其又是PeoInfo结构体的数组变量所以就可以通过访问数组空间再用.操作符来找到学生的信息,
这里不用-> 是因为前面con->Contact[con->sz] 已经表示成Contact[PeoMax]结构体变量了不需要在*解引用了void Add_Stu_message(Info_System* con) { assert(con); if (con->sz == PeoMax) {printf("信息已满,请删除或刷新后再试\n");return; } printf("依次输入%s %s %s %s %s %s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩"); scanf("%d %s %s %s %s %d", &con->Contact[con->sz].ID, con->Contact[con->sz].Name, con->Contact[con->sz].Class, con->Contact[con->sz].Sex, con->Contact[con->sz].Room, &con->Contact[con->sz].Score ); printf("添加完成\n"); }
展示学生信息
void Show_Stu_message(Info_System* con) {assert(con);printf("%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");for (int i = 0; i < con->sz;i++){printf("%-10d %-20s %-20s %-5s %-20s %-10d\n",con->Contact[i].ID,con->Contact[i].Name,con->Contact[i].Class,con->Contact[i].Sex,con->Contact[i].Room,con->Contact[i].Score);} }
对于printf打印只需要满足所给条件(%d)和所写条件(con->Contact[i].ID)对应的类型一致即可。
删除学生信息
void Del_Stu_message(Info_System* con) {assert(con);if (con->sz == 0){printf("没有学生信息\n");return;}int input = 0;printf("输入学号进行删除;>");scanf("%d", &input);int ret = FindById(input,con);if (ret != -1){for (ret; ret < con-> sz - 1; ret++) //sz -1 也要转化成下标{con->Contact[ret] = con->Contact[ret+1]; //注意返回的就是所对应的下标}con->sz--;printf("删除成功\n");}//if (ret!=-1)//{// memmove(con->Contact + ret, con->Contact + ret + 1, (con->sz)*sizeof(PeoInfo) - (ret) * sizeof(PeoInfo));// con->sz--;// printf("删除成功\n");//}}
查找函数:
int FindByName(char * name,const Info_System* con)
{int t = con->sz;//不要改变sz,用t来代替需要查找的人while (t--){if (strcmp(name, con->Contact[t].Name) == 0)//--ret 是因为ret表示的是总人数,而总人数-1才能找到最后一个人{return t;}}printf("找不到此人\n");return -1;//返回-1是因为区别于返回0(返回0表示查找的人的下标为0)
}
int FindById(int Id, const Info_System* con)
{int t = con->sz;//不要改变sz,用t来代替需要查找的人while (t--){if (Id == con->Contact[t].ID){return t;}}printf("找不到此人\n");return -1 ;//返回-1是因为区别于返回0(返回0表示查找的人的下标为0)
}
查找学生信息
void Search_Stu_message(const Info_System* con) {assert(con);int i = 0;printf("1.Id\n2.Name\n选择查找方法:>");scanf("%d", &i);if (i == 1){int input = 0;printf("输入学号进行查找:>");scanf("%d", &input);int ret = FindById(input, con);if (ret != -1){printf("%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");printf("%-10d %-20s %-20s %-5s %-20s %-10d\n", con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,con->Contact[ret].Score);}}else if (i == 2){char name[20] = { 0 };printf("输入姓名进行查找:>");scanf("%s",name);int ret = FindByName(name, con);if (ret != -1){printf("%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");printf("%-10d %-20s %-20s %-5s %-20s %-10d\n", con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,con->Contact[ret].Score);}}else{printf("选择错误\n");}}
修改学生信息
void Modeifyh_Stu_message(Info_System* con) {int i = 0;printf("1.Id\n2.Name\n选择查找方法:>");scanf("%d", &i);if (i == 1){int input = 0;printf("输入要修改的学生信息的学号:>");scanf("%d", &input);int ret = FindById(input, con);if (ret != -1){printf("原信息:\n%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");printf("%-10d %-20s %-20s %-5s %-20s %-10d\n", con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,con->Contact[ret].Score);printf("修改:>\n");printf("依次输入学号 名字 班级 性别 宿舍 计算机成绩\n并且以空格/回车分隔\n");scanf("%d %s %s %s %s %d", &con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,&con->Contact[ret].Score);}}else if (i == 2){char name[20] = { 0 };printf("输入要修改的学生信息的姓名:>");scanf("%s", name);int ret = FindByName(name, con);if (ret != -1){printf("原信息:\n%-10s %-20s %-20s %-5s %-20s %-10s\n", "学号", "名字", "班级", "性别", "宿舍", "计算机成绩");printf("%-10d %-20s %-20s %-5s %-20s %-10d\n", con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,con->Contact[ret].Score);printf("修改:>\n");printf("依次输入学号 名字 班级 性别 宿舍 计算机成绩\n并且以空格/回车分隔\n");scanf("%d %s %s %s %s %d", &con->Contact[ret].ID,con->Contact[ret].Name,con->Contact[ret].Class,con->Contact[ret].Sex,con->Contact[ret].Room,&con->Contact[ret].Score);}}else{printf("选择错误\n");} }
排序学生信息
int Sort_Name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->Name, ((PeoInfo*)e2)->Name);//注意强转要写成 PeoInfo* 结构体类型//返回大于0的数才交换,即是升序形式
}int Sort_age(const void* e1, const void* e2)
{return ((PeoInfo*)e1)->ID - ((PeoInfo*)e2)->ID;
}
void Sort_Stu_message(Info_System* con)
{assert(con);int input = 0;printf("1.以名字排序\n2.以学号排序\n");scanf("%d", &input);switch (input){case 1://ASCII升序qsort(con->Contact, con->sz, sizeof(con->Contact[0]), Sort_Name);//头文件stdlib,比较函数int compare(const void *elem1, const void *elem2)//此处con->Contact 直接找到了数组名传进去,所以qsort内所接受到的结构体时PeoInfo类型的printf("排序成功\n");break;case 2://升序qsort(con->Contact, con->sz, sizeof(con->Contact[0]), Sort_age);printf("排序成功\n");break;default:printf("输入错误\n");break;}
}
刷新学生信息
void Refresh_Stu_message(Info_System* con)
{InitCon(con);//直接再次调用初始化函数printf("刷新成功\n");
}
3.文件的保存、和文件的调用
3.1分源管理
3.1.1在主函数内
3.1.2在contact.c
3.1.3在contact.h
敬请期待!持续更新,关注喔老铁
相关文章:

学生信息管理系统(通讯录)----------通俗易懂、附源码、C语言实现
绪论: 本篇文章使结构体章节后的习题,如果你对C语言有问题,或者结构体有什么问题不妨看看我之前所写的文章(章回体),对于文件管理和内存分配问题我将在后面补上,对于这个学生信息管理系统我用了多种方法和…...

Python抽奖系统
#免费源码见文末公众号# 抽奖系统① def choujiang1():def write():with open(d:\\抽奖系统\\抽奖1.1.pickle,rb) as file:lst1pickle.load(file)namevar1.get()if name not in lst1 and name!录入成功! and name!录入失败! and name!:lst1.append(name)…...

真实景观渲染技巧【Three.js】
受到一些很棒的 three.js 演示、与 covid 相关的旅行禁令以及可能在 pinterest 上花太多时间看美丽的旅行照片的启发——我开始看看我是否可以使用 three.js 和r3f在浏览器中渲染一个令人信服的风景场景。 推荐:将 NSDT场景编辑器 加入你的3D开发工具链。 在过去一个…...

MySQL知识汇总:MySQL函数CASE WHEN用法详解
Case When的两种简单用法 用法一: CASE seasonWHEN Spring THEN 春天 WHEN Summer THEN 夏天 WHEN autumn THEN 秋天 else 冬天 end 用法二: CASE WHEN season Spring THEN 春天WHEN season Summer THEN 夏天WHEN season autumn THEN 秋天 els…...

Python学习-----模块1.0(模块的简介、定义与使用)
目录 前言: 1.什么是模块 2.模块的分类 (1)内置模块 (2)第三方模块 (3)自定义模块 3.模块的使用 4.自定义模块 5.模块和执行文件的判断 前言: 今天就开始讲Python中的模块篇…...

Linux进程学习【二】
✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Perseverance is not a long race; it is many short races one after another…...
我问chatGPT,在JavaScript中构造函数和类的区别
问:构造器函数和面向中的类是同样的东西吗|? 答:构造器函数和面向对象中的类并不是同样的东西,它们之间有些许不同。 在面向对象编程中,类是一种抽象的概念,它描述了一类具有相同属性和行为的对象。类可以…...

软考高级-信息系统管理师之沟通管理(最新版)
项目沟通管理 1、项目沟通管理基础项目沟通管理的重要性项目沟通管理相关理论2、规划沟通管理3、管理沟通4、控制沟通项目沟通管理的技术和工具1、项目沟通管理基础 项目沟通管理的重要性 1、与1T项目成功有关的最重要的四个因素是:主管层的支持、用户参与、有经验的项目经理…...

PyQt5 自定义富文本编辑器
介绍 一款使用PyQt5和网页端框架wangEditor集成的富文本编辑器 代码片段 PyQt5客户端 与网页端建立连接def create_connect(self):self.web_view QWebEngineView()self.bridge JSBridge(self.web_view.page())self.web_view.load(QUrl.fromLocalFile(self.editor_path))w…...

【高可用系统架构设计】SLA服务可用性4个9是什么意思?如何保证服务的高可用性 HA(High Availability)?...
如何保证服务的高可用性 HA(High Availability)?高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。方法论上,高可用是通…...
微服务架构设计模式-(14)面向生产环境
生产环境要求 应用安全 数据权限 服务可配置性 不同环境的配置不一样,不能写死代码,所以要配置 可观测性 需要日志系统 应用安全 四个方面 身份验证 验证主体的身份解决方案 单体 cookie 微服务中 API Gateway 访问令牌 不透明令牌透明令牌ÿ…...
HTML5新增用法
新增语义化标签 并无特殊含义,是语义!语义!语义! <header> 头部区域 <nav> 导航区域 <main> 主体区域 <article> 内部标签 <section> 块级标签 <aside> 侧边栏标签 <footer> 尾部…...

富足金字塔:人的努力是为了扩大选择的范围
人的努力是为了扩大选择的范围,这是熵减的另一种表述。富足金字塔代表着人生的三重境界。第一层是温饱。人需要食物、水、住所。第二层是品质。能源、ICT、教育带来更有品质的生活,如智能门锁、智能马桶、扫地机、洗碗机、洗衣烘衣机。第三层是梦想。包括…...

C++类基础(十七)
类的继承——补充知识 ● public 与 private 继承(C Public, Protected and Private Inheritance) 改变了类所继承的成员的访问权限 //公有继承 struct Base { public:int x; private:int y; protected:int z; }; struct Derive : public Base //公有继承…...

LeetCode刷题复盘笔记—一文搞懂贪心算法之56. 合并区间(贪心算法系列第十四篇)
今日主要总结一下可以使用贪心算法解决的一道题目,56. 合并区间 题目:56. 合并区间 Leetcode题目地址 题目描述: 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间…...

Andriod入门级开发
这学期有个课设,我们组我负责一个手机APP的开发,虽然刚开始说要实现什么智能导航,类似高德地图那种,但最后阉割的只剩一个Socket通信了,因为之前没有接触过(可能之后也不会再接触),记…...

DCL 数据控制语言
1、简介 DCL英文全称是Data Control Language(数据控制语言),用来管理数据库用户、控制数据库的访问权限。 2、管理用户 2.1 查询用户 select * from mysql.user;查询的结果如下: 其中 Host代表当前用户访问的主机, 如果为localhost, 仅代表只能够在当前本机访问…...

全网超详细的下载与安装VMware虚拟机以及为什么要安装VMware虚拟机
文章目录1. 文章引言2. 下载VMware3. 安装VMware1. 文章引言 我们使用最多的系统是windows系统,因为,国内电脑厂商的操作系统(os)基本是windows系统,比如华为、联想、华硕等电脑。 但线上的服务器大多是Linux系统,而我们经常使用…...

Python获取zabbix问题触发器
背景:阿里云的ECS服务器因为阿里云升级插件,导致安全防护程序重启,产生不同的端口。导致低自动发现注册的端口 大量报警。 解决:杀掉关于因为非业务 变更的端口检测的触发器。 相关文档: Zabbix监控之主机端口监控自…...

原型链污染
目录 前置知识 原型对象 prototype和__proto__的区别 原型链概念 原型链的继承 原型 链污染 原型链污染原理 javascript中可能会存在原型链污染的危险函数 原型链污染的实际应用 JavaScript中可以触发弹窗的函数 前置知识 原型对象 在JavaScript中,每个函…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
[特殊字符] Spring Boot底层原理深度解析与高级面试题精析
一、Spring Boot底层原理详解 Spring Boot的核心设计哲学是约定优于配置和自动装配,通过简化传统Spring应用的初始化和配置流程,显著提升开发效率。其底层原理可拆解为以下核心机制: 自动装配(Auto-Configuration) 核…...