c入门第二十三篇: 学生成绩管理系统优化(支持远程操作)

前言

师弟高兴的说道:“师兄,你猜我今天上课看见谁了?”
我:“谁呢?”
师弟:“程夏,没想到,她竟然来旁听我们计算机系的课程了。虽然我从前门进去的,但是我还是一眼就看见了坐在后面的她。”
我:“有意思,你没过去打个招呼?”
师弟:“我正要挨过去坐着,被占位的室友拉住了,就不好意思了。还好第一节课间休息的时候,我果断溜了过去。”
师弟开始回想当时的场景,嘴角先是上扬,接着又下扬。当时她在忙着看书,等我在她旁边坐下,稍微撇过头看她看什么书的时候,她才发现的我。她说:‘上课都不积极,踩着点来上课。’我先是惊讶了,然后不好意思地说:‘程老师批评的对。’接下来竟是一段沉默。打破沉默的还是她,她说道:‘你现在的学生成绩管理系统只支持运行时候,在运行的程序终端进行输入。你能够支持一下,我在我的电脑上,也能连上你的系统设置么?’我听得有点懵,我从来没想到还能这样实现。我原以为我的系统已经可以了。她见我茫然,就说:‘可以好好想想。期待你更新的版本。’说完她就自顾看书去了。我则一整节课都在思考这个问题。
师弟:“师兄,她说要实现在她电脑上,也能连上我的系统,这个有经验可以分享一下么?”
我:“这个倒是不复杂,就是c/s架构,客户端和服务端分离。可以通过c语言中的网络套接字实现。”

背景

在C语言中,可以使用网络套接字(Socket)来实现基于网络的进程间通信。可以先看下面TCP通信的服务端和客户端代码。主要实现的功能是客户端发送一个“Hello message sent”,服务端回复一个“Hello from server”。
互相发送hello问候

服务端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 8080int main() {int server_fd, conn_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[1024] = {0};char *hello = "Hello from server";// Creating socket file descriptorif ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// Forcefully attaching socket to the port 8080if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// Bind the socket to the addressif (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// Listen for connectionsif (listen(server_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}// Accept a connectionif ((conn_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}// Read data from the socketread(conn_socket, buffer, 1024);printf("Message from client: %s\n", buffer);// Send data to the clientsend(conn_socket, hello, strlen(hello), 0);printf("Hello message sent\n");close(conn_socket);close(server_fd);return 0;
}

客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>#define PORT 8080int main() {int sock = 0;struct sockaddr_in serv_addr;char *hello = "Hello from client";char buffer[1024] = {0};// Create a socketif ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {printf("\n Socket creation error \n");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// Convert IPv4 and IPv6 addresses from text to binary formif(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {printf("\nInvalid address/ Address not supported \n");return -1;}// Connect to the serverif (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {printf("\nConnection Failed \n");return -1;}// Send data to the serversend(sock, hello, strlen(hello), 0);printf("Hello message sent\n");// Read data from the serverread(sock, buffer, 1024);printf("Message from server: %s\n", buffer);close(sock);return 0;
}

整个编程实现的过程可以总结如下:
客户端服务端TCP通信流程

学生成绩管理系统的实现

这里主要是考虑将上文中的客户端和服务端代码如何在学生系统中实现。其中的关键就是socket_server_init,实现了服务端的监听,以及数据的处理。

int socket_server_init()
{int ret;int server_fd, conn_fd;int opt = 1;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[BUF_SIZE] = {0};// 创建 TCP socketif ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed!");exit(EXIT_FAILURE);}if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt!");exit(EXIT_FAILURE);}#define PORT 8080address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// Bind the socket to the addressif (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed!");exit(EXIT_FAILURE);}// Listen for connectionsif (listen(server_fd, 3) < 0) {perror("listen!");exit(EXIT_FAILURE);}while (1) {// Accept a connectionif ((conn_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}while (1) {// Send data to the clientret = send(conn_fd, welcome_info, strlen(welcome_info), 0);if (ret == -1) {perror("sent failed!\n");break;}// Read data from the socketret = read(conn_fd, buffer, BUF_SIZE);if (ret == -1) {perror("read failed!\n");break;}printf("recv: %s\n", buffer);ret = server_process_to_client(conn_fd, buffer);if (ret == 1) {break;}}close(conn_fd);}close(server_fd);return 0;
}

完整服务端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for access() function
#include <sys/socket.h>
#include <netinet/in.h>#define MAX_STUDENTS 100
#define MAX_NAME_LEN 50
#define STUDENT_SYSTEM "student_system"
#define TRUE 1
#define FALSE 0
#define BUF_SIZE 1024char *welcome_info = "\nWelcome to Student Score Management System\n"\"0. Exit\n"\"1. Add Student\n"\"2. Display All Students\n"\"3. Find Student by ID\n"\"4. Find Student by Name\n"\"5. Add Score\n"\"6. Display Average Score\n"\"7. Display by Score sort\n"\"Enter your choice: ";typedef struct {int id; // 学号char name[MAX_NAME_LEN]; // 姓名float score; // 成绩
} Student;int student_count = 0; // 学生数量Student *students; // 学生数组指针
int g_max_student = MAX_STUDENTS;Student *stu_sys_init(int num)
{Student *stu_sys;stu_sys = malloc(num * sizeof(Student));if (stu_sys == NULL) {printf("student system malloc failed!\n");}return stu_sys;
}int write_student_info(Student *s)
{FILE *fp = fopen(STUDENT_SYSTEM, "a");if (fp == NULL) {printf("fopen student_system failed!\n");return 1;}fprintf(fp, "%-4d %-10s %-.2f\n", s->id, s->name, s->score);fclose(fp);return 0;
}int check_if_student_exsit(int id)
{int i;for(i = 0; i < student_count; i++) {if(students[i].id == id) {return 1;}}return 0;
}void update_student_info(Student s, int need_write)
{Student *stu_reinit;int old_max_student;if(student_count >= g_max_student) {old_max_student = g_max_student;g_max_student = g_max_student << 1;stu_reinit = stu_sys_init(g_max_student);if (stu_reinit == NULL) {printf("Database is full!\n");return;}memcpy(stu_reinit, students, old_max_student * sizeof(Student));free(students);students = stu_reinit;}if (!check_if_student_exsit(s.id)) {students[student_count++] = s;if (need_write) {printf("Student added successfully, all student: %d!\n", student_count);write_student_info(&s);}} else {printf("student has in db, do nothing!\n");}
}void add_student()
{Student s;printf("Enter student ID: ");scanf("%d", &s.id);printf("Enter student name: ");scanf("%s", s.name);s.score = 0.0; // 初始成绩设置为0update_student_info(s, TRUE);
}void print_title()
{printf("%-4s %-10s %-5s\n", "ID", "Name", "Score");
}void display_all_students()
{int i;printf("-------- All students info --------\n");if (student_count == 0) {printf("No students!\n");} else {print_title();for(i = 0; i < student_count; i++) {printf("%-4d %-10s %-.2f\n", students[i].id, students[i].name, students[i].score);}}printf("--------      End       -----------\n");
}/*** @arr: 有序数组* @l: 待查找区间左端点* @r: 待查找区间右端点* @target: 需要查找的元素*/
int binary_search(Student *s, int l, int r, int target)
{int m;while (l <= r) {// 计算中间位置m = l + (r - l) / 2; // 防止(l+r)直接相加导致的溢出// 检查x是否存在于中间位置if (s[m].id == target)return m;// 若x大,则忽略左半部分if (s[m].id < target) {l = m + 1;} else {// 若x小,则忽略右半部分r = m - 1;}}// 若未找到元素,返回-1return -1;
}void find_student_by_id()
{int id, ret;printf("Enter student ID to search: ");scanf("%d", &id);ret = binary_search(students, 0, student_count, id);if (ret != -1) {print_title();printf("%-4d %-10s %-.2f\n", students[ret].id, students[ret].name, students[ret].score);return;}printf("Student with ID %d not found!\n", id);
}void find_student_by_name()
{int i, is_find = 0;char name[MAX_NAME_LEN];printf("Enter student name to search: ");scanf("%s", name);for(i = 0; i < student_count; i++) {if(strcmp(students[i].name, name) == 0) {print_title();printf("%-4d %-10s %-.2f\n", students[i].id, students[i].name, students[i].score);is_find = 1;}}if (is_find == 0) {printf("Student with name %s not found!\n", name);}
}void add_score()
{int id, i;float score;printf("Enter student ID: ");scanf("%d", &id);printf("Enter student score: ");scanf("%f", &score);for(i = 0; i < student_count; i++) {if(students[i].id == id) {students[i].score = score;printf("Score added successfully!\n");return;}}printf("Student with ID %d not found!\n", id);
}void display_average_score()
{float total = 0.0;int i;for(i = 0; i < student_count; i++) {total += students[i].score;}printf("Average score of all students: %.2f\n", total / student_count);
}int init_student_info()
{if(access(STUDENT_SYSTEM, F_OK) != 0) { // 文件不存在return 0;}FILE *fp = fopen(STUDENT_SYSTEM, "r");if (fp == NULL) {printf("fopen student_system failed!\n");return 1;}#define BUF_SIZE 1024char buf[BUF_SIZE];Student s;while(fgets(buf, BUF_SIZE - 1, fp) != NULL) {sscanf(buf, "%d %s %f\n", &s.id, s.name, &s.score);update_student_info(s, FALSE);}fclose(fp);return 0;}void swap(Student *a, Student *b)
{Student tmp = *a;*a = *b;*b = tmp;
}void bubble_sort_by_score(Student *s, int n)
{int i, j;for (i = 0; i < n-1; i++) {for (j = 0; j < n-i-1; j++) { // 最后 i 个已经排序好了, 遍历未排序的部分if (s[j].score < s[j+1].score) {// 如果当前元素大于后面的元素,交换它们swap(&s[j], &s[j+1]);}}}
}int do_process(int choice)
{switch(choice) {case 0:printf("Exiting...\n");break;case 1:add_student();break;case 2:display_all_students();break;case 3:find_student_by_id();break;case 4:find_student_by_name();break;case 5:add_score();break;case 6:display_average_score();break;case 7:bubble_sort_by_score(students, student_count);display_all_students();break;default:printf("Invalid choice!\n");}return 0;
}int do_exit(int fd)
{int ret;char *exit_instruct = "Exit";ret = send(fd, exit_instruct, strlen(exit_instruct), 0);if (ret == -1) {perror("sent failed!\n");return -1;}printf("send: %s\n", exit_instruct);return 0;
}int do_add_student(int fd)
{int ret;char *enter_id_helps = "Enter student ID:";char *name_helps = "Enter student name:";Student s;char buf[BUF_SIZE];ret = send(fd, enter_id_helps, strlen(enter_id_helps), 0);if (ret == -1) {perror("sent failed!\n");return -1;}printf("send: %s\n", enter_id_helps);// Read data from the socketret = read(fd, buf, BUF_SIZE);if (ret == -1) {perror("read failed!\n");return -1;}s.id = atoi(buf);ret = send(fd, name_helps, strlen(name_helps), 0);if (ret == -1) {perror("sent failed!\n");return -1;}// Read data from the socketmemset(buf, 0, BUF_SIZE);ret = read(fd, buf, BUF_SIZE);if (ret == -1) {perror("read failed!\n");return -1;}strcpy(s.name, buf);s.score = 0.0; // 初始成绩设置为0update_student_info(s, TRUE);return 0;
}int server_process_to_client(int fd, char *buffer)
{int choice = atoi(buffer);switch(choice) {case 0:do_exit(fd);return 1;case 1:do_add_student(fd);break;default:printf("Invalid choice!\n");}return 0;
}int socket_server_init()
{int ret;int server_fd, conn_fd;int opt = 1;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[BUF_SIZE] = {0};// 创建 TCP socketif ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed!");exit(EXIT_FAILURE);}if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt!");exit(EXIT_FAILURE);}#define PORT 8080address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// Bind the socket to the addressif (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed!");exit(EXIT_FAILURE);}// Listen for connectionsif (listen(server_fd, 3) < 0) {perror("listen!");exit(EXIT_FAILURE);}while (1) {// Accept a connectionif ((conn_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}while (1) {// Send data to the clientret = send(conn_fd, welcome_info, strlen(welcome_info), 0);if (ret == -1) {perror("sent failed!\n");break;}// Read data from the socketret = read(conn_fd, buffer, BUF_SIZE);if (ret == -1) {perror("read failed!\n");break;}printf("recv: %s\n", buffer);ret = server_process_to_client(conn_fd, buffer);if (ret == 1) {break;}}close(conn_fd);}close(server_fd);return 0;
}void welcome_sys_menu()
{printf("%s", welcome_info);
}int main()
{int choice;int ret;students = stu_sys_init(MAX_STUDENTS);if (students == NULL) {printf("student system init failed, exit!\n");return -1;}ret = init_student_info();if (ret) {printf("init_student_info failed!\n");return 1;}display_all_students();socket_server_init();#if 0 //通过if 0注释代码do {welcome_sys_menu();scanf("%d", &choice);do_process(choice);} while(choice != 0);
#endifreturn 0;
}

客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>#define PORT 8080
#define BUF_SIZE 1024int main() {int sock = 0;struct sockaddr_in serv_addr;char buffer[BUF_SIZE] = {0};// Create a socketif ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {printf("Socket creation error!\n");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// Convert IPv4 and IPv6 addresses from text to binary formif(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { //127.0.0.1需要换成服务器所在地址printf("Invalid address/ Address not supported!\n");return -1;}// Connect to the serverif (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {printf("Connection Failed!\n");return -1;}while (1) {memset(buffer, 0, BUF_SIZE);// Read data from the serverread(sock, buffer, BUF_SIZE);printf("%s", buffer);if (strcmp(buffer, "Exit") == 0) {printf("\nNormal Exit, bye!\n");break;}// Send data to the serverscanf("%s", buffer);send(sock, buffer, strlen(buffer), 0);}close(sock);return 0;
}

在实际应用中127.0.0.1需要换成服务器所在地址。

结尾

在这里只是实现了学生成绩管理系统的添加功能和退出功能,其他功能如显示、查询功能有待进一步实现。你以为这就构造好了一个学生成绩管理系统?其实还可以有很多的工作可以做。

我:“你都被提问了这么久,你怎么没给人家出个编程题试试呢?”
师弟:“也对哦,我的思想似乎总是转的比较慢。我先去问问,她最近是不是也在鼓捣什么系统。”

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

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

相关文章

swing jdk版本导致的显示尺寸不一致问题

Java Swing JFrame size different after upgrade to JRE11 from JRE 7 or 8. How can I make the frame size consistent? - Stack Overflow 从 JRE 7 或 8 升级到 JRE11 后&#xff0c;Java Swing JFrame 大小不同。如何使帧大小一致&#xff1f; - IT工具网 设置虚拟机选项…

01背包问题:组合问题

01背包问题&#xff1a;组合问题 题目 思路 将nums数组分成left和right两组&#xff0c;分别表示相加和相减的两部分&#xff0c;则&#xff1a; left - right targetleft right sum 进而得到left为确定数如下&#xff0c;且left必须为整数&#xff0c;小数表示组合不存在&…

28. 找出字符串中第一个匹配项的下标(力扣LeetCode)

文章目录 28. 找出字符串中第一个匹配项的下标题目描述暴力KMP算法 28. 找出字符串中第一个匹配项的下标 题目描述 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。…

mapbox高德地图与相机

mapbox高德地图与相机 本案例使用Mapbox GL JavaScript库创建高德地图。 演示效果引入 CDN 链接地图显示 创建地图实例定义地图数据源配置地图图层 设置地图样式实现代码 1. 演示效果 2. 引入 CDN 链接 <script src"https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapb…

项目实战:Qt监测操作系统cpu温度v1.1.0(支持windows、linux、国产麒麟系统)

若该文为原创文章&#xff0c;转载请注明出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/136277231 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

全面升级!Apache HugeGraph 1.2.0版本发布

图数据库以独特的数据管理和分析能力&#xff0c;在企业数智化转型的过程中正在成为数据治理的核心&#xff0c;根据IDC调研显示&#xff0c;95%的企业认为图数据库是重要的数据管理工具&#xff0c;超过65%的厂商认为在业务上图数据库优于其他选择&#xff0c;尤其是在金融风控…

Unity零基础到进阶 | Unity中的 RectTransformUtility 方法整理汇总

Unity零基础到进阶 ☀️| RectTransformUtility 方法整理汇总一、RectTransformUtility 官方文档1.1 RectTransformUtility.CalculateRelativeRectTransformBounds&#xff08;重&#xff09;1.2 RectTransformUtility.FlipLayoutAxes1.3 RectTransformUtility.FlipLayoutOnAxi…

观察者模式与发布订阅模式

观察者模式 定义&#xff1a; 观察者模式是一种行为型设计模式&#xff0c;定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。 结构图&#xff1a; ES6简易代码实现&#xff1a; //ts环境下…

Nginx——安装和反向代理

Nginx安装与应用 1.1 Nginx介绍 Nginx 是一个高性能的HTTP和反向代理服务器,特点是占有内存少&#xff0c;并发能力强 Nginx可以作为静态页面的web服务器&#xff0c;同时还支持CGI协议的动态语言&#xff0c;比如perl、php等。但是不支持java。Java程序只能通过与tomcat配合…

谷歌AI发展史:从阿尔法围棋到Gemini与Gemma的开源创新

谷歌一直是人工智能领域的重要推动者。本文将回顾谷歌AI的发展历程&#xff0c;从阿尔法围棋到现如今的Gemini和Gemma&#xff0c;探讨谷歌在人工智能领域的重大突破和创新。 1. 引言 在计算机科学领域&#xff0c;谷歌一直是人工智能&#xff08;AI&#xff0…

MasterAlign全景视觉点胶应用软件说明书

MasterAlign视觉软件通过高精度的图像处理和机器学习算法&#xff0c;实现了对点胶过程的全面控制和管理。以下是关于MasterAlign在全景视觉点胶应用场景中如何使用的详细说明。看完全文相信一定能让您快速上手使用。

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型 目录 多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基本介绍…

基于R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习技术应用

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;最早出现于“循证医学”&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面。…

设计模式(六)代理模式

相关文章设计模式系列 1.代理模式简介 代理模式介绍 代理模式也叫委托模式&#xff0c;是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场景有很多&#xff0c;比如代购、代理上网、打官司等。 定义 为其他对象提供一种代理以控制这个对象的访问。 代理模式…

Layer1 明星项目 Partisia Blockchain 何以打造互操作、可创新的数字经济网络

我们的目标是创建一个以用户为中心的全新数字经济网络&#xff1a;在去信任化和公平透明的环境下&#xff0c;所有的隐私数据都能够得到天然保障&#xff0c;企业、用户等各角色的协作与共享将会更顺利地进行。 —— Partisia Blockchain 团队 作为一个以 Web3 安全为技术方向的…

Linux学习之vi/vim详细介绍

目录 ​编辑 1. 什么是 vim&#xff1f; 2. vi/vim 的使用 2.1 命令模式 2.2 输入模式 2.3 底线命令模式 3. vi/vim 使用实例 3.1 使用 vi/vim 进入一般模式 3.2 按下 i 进入输入模式(也称为编辑模式)&#xff0c;开始编辑文字 3.3 按下 ESC 按钮回到一般模式…

jenkins+kubernetes+git+dockerhub构建devops云平台

Devops简介 k8s助力Devops在企业落地实践 传统方式部署项目为什么发布慢&#xff0c;效率低&#xff1f; 上线一个功能&#xff0c;有多少时间被浪费了&#xff1f; 如何解决发布慢&#xff0c;效率低的问题呢&#xff1f; 什么是Devops&#xff1f; 敏捷开发 提高开发效率&…

CKA认证,开启您的云原生之旅!

在当今数字化时代&#xff0c;云计算已经成为企业和个人发展的关键技术。而获得CKA&#xff08;Certified Kubernetes Administrator&#xff09;认证&#xff0c;将是您在云原生领域迈出的重要一步。 CKA认证是由Kubernetes官方推出的权威认证&#xff0c;它旨在验证您在Kuber…

vue:实现顶部消息横向滚动通知

前言 系统顶部展示一个横向滚动的消息通知&#xff0c;就是消息内容从右往左一直滚动。 效果如下&#xff1a; 代码 使用 <template><div class"notic-bar"><img :src"notic" class"notice-img" /><div class"noti…

C++之类和对象(2)

目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 2. 赋值运算符只能重载成类的成员函数不能重载成全局函数 3. 用户没有显式实现时&…