操作系统课程实验1-进程调度模拟实验

操作系统课程实验1-进程调度模拟实验

一、实验介绍

1.1 实验目的

本实验模拟在单处理机环境下的处理机调度,帮助理解进程调度的概念,深入了解进程控制块的功能,以及进程的创建、撤销和进程各个状态间的转换过程。

1.2 实验内容
  1. 进程调度算法:采用最高优先数优先的调度算法、先来先服务算法、SJF和多级反馈调度算法。
  2. 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。进程的优先数及需要的运行时间可以事先人为输入(也可以由随机数产生)。进程的到达时间为进程输入的时间。 进程的运行时间以时间片为单位进行计算。
1.3 实验要求
  1. 每进行一次调度程序都显示输出一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
  2. 对同一组进程的各种调度算法分别计算平均周转时间和平均带权周转时间。
1.4 参考测试数据

系统有5个进程,其就绪时刻、服务时间和优先级(优先级数值越大优先级越高)如下图所示:
在这里插入图片描述

多级反馈队列调度算法:设3个就绪队列,时间片分别为1、2、3。

二、实现代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>using namespace std;typedef struct ProcessControlBlock { // 定义进程控制块结构体int name;                   // 进程名称unsigned int Arrive_Time;   // 到达时间unsigned int Wait_Time;     // 等待时间unsigned int Start_Time;    // 开始时间unsigned int Serve_Time;    // 服务时间unsigned int Finish_Time;   // 完成时间int Priority;               // 优先级unsigned int cycle_time;    // 周转时间double Weighted_cycle_time; // 带权周转时间unsigned int Original_Serve_Time;bool FinishFlag;            // 完成标志
} PCB;                          // 进程控制块的别名typedef struct Multilevel_Feedback_Queue { // 定义多级反馈队列int L1_Length, L1[5];       // 第一级别反馈队列int L2_Length, L2[5];       // 第二级别反馈队列int L3_Length, L3[5];       // 第三级别反馈队列unsigned int Time_Slice[3]; // 三级反馈队列分配的时间片
} MFQ;void PCB_Info_Input(PCB Process_HPF[5], PCB Process_FCFS[5], PCB Process_SJF[5], PCB Process_MFQ[5]); 					 	// 函数声明:输入进程控制块信息void Highest_Prioriy_First(PCB  Process[5]); 	// 函数声明:最高优先级优先算法
void First_Come_First_Serve(PCB Process[5]); 	// 函数声明:先来先服务算法
void Shortest_Job_First(PCB Process[5]);	 	// 函数声明:短作业优先算法
void Multilevel_Feedback_Queue_Algorithm(PCB Process[5]);	// 函数声明:多级反馈队列算法
void Multilevel_Feedback_Queue_Algorithm_Input(MFQ * mfq);	// 函数声明:多级反馈队列的输入bool SortBy_Priority(PCB* a, PCB* b);		 	// 函数声明:按优先级排序
bool SortBy_ServeTime(PCB* a, PCB* b);		 	// 函数声明:按服务时间排序
bool SortBy_ArriveTime(PCB a, PCB b);		 	// 函数声明:按到达时间排序int main(void) {PCB Process_HPF[5]; 								// 定义5个进程控制块数组PCB Process_FCFS[5]; 								// 定义5个进程控制块数组PCB Process_SJF[5]; 								// 定义5个进程控制块数组PCB Process_MFQ[5]; 								// 定义5个进程控制块数组PCB_Info_Input(Process_HPF, Process_FCFS, Process_SJF, Process_MFQ); 								// 调用输入进程控制块信息函数Highest_Prioriy_First(Process_HPF); 				// 调用优先级最高优先算法函数First_Come_First_Serve(Process_FCFS); 				// 调用先来先服务算法函数Shortest_Job_First(Process_SJF);	 				// 调用短作业优先算法函数Multilevel_Feedback_Queue_Algorithm(Process_MFQ); 	// 调用多级反馈队列调度算法return 0;
}//	3比较函数,用于sort函数的参数
bool SortBy_ArriveTime(PCB a, PCB b) {return a.Arrive_Time < b.Arrive_Time;
}
bool SortBy_Priority(PCB* a, PCB* b) {return a->Priority < b->Priority;
}
bool SortBy_ServeTime(PCB* a, PCB* b) {return a->Serve_Time < b->Serve_Time;
}void PCB_Info_Input(PCB Process_HPF[5], PCB Process_FCFS[5], PCB Process_SJF[5], PCB Process_MFQ[5]) {cout << "\nPlease input the Process Control Block information\n" << endl;for (int i = 0; i < 5; i++) {printf("PCB%d:", i);scanf("%u%u%d", &Process_HPF[i].Arrive_Time, &Process_HPF[i].Serve_Time, &Process_HPF[i].Priority);// 完成输入的深拷贝Process_FCFS[i].Arrive_Time = Process_SJF[i].Arrive_Time = Process_MFQ[i].Arrive_Time = Process_HPF[i].Arrive_Time;Process_FCFS[i].Serve_Time = Process_SJF[i].Serve_Time = Process_MFQ[i].Serve_Time = Process_HPF[i].Serve_Time;Process_FCFS[i].Priority = Process_SJF[i].Priority = Process_MFQ[i].Priority = Process_HPF[i].Priority;Process_HPF[i].name = Process_FCFS[i].name = Process_SJF[i].name = Process_MFQ[i].name = i + 1; 							// 设置进程名称Process_HPF[i].FinishFlag = Process_FCFS[i].FinishFlag = Process_SJF[i].FinishFlag = Process_MFQ[i].FinishFlag = false; 	// 初始化完成标志为false}
}// 优先级最高优先调度算法函数
void Highest_Prioriy_First(PCB Process[5]) {cout << "\n优先级最高优先调度算法:" << endl;PCB* Available_Processes[5]; 	// 定义指向进程控制块的指针数组int FinishCout = 0; 			// 完成进程计数器初始化为0unsigned Time = 0; 				// 时间初始化为0cout << endl;sort(Process, Process + 5, SortBy_ArriveTime);  // 按到达时间对进程数组进行排序while (FinishCout < 5) { 						// 当完成进程数量小于5时循环执行调度算法,因为进程还有进程未得到处理机时间int j = 0; 									// 已到达且未完成进程计数器初始化为0for (int i = 0; i < 5; i++) { 				// 循环遍历所有进程if (Process[i].Arrive_Time <= Time and Process[i].FinishFlag == false) { // 如果进程已到达且未完成Available_Processes[j++] = Process + i; 							 // 将该进程加入到可用进程数组中}}// 如果j为0,表示当前时间没有到达的进程,此时应该让时间继续推进if (j == 0) {Time += 1; 	// 时间加1continue; 	// 继续下一次循环}// 将当前时间已经到达的所有进程按优先级进行排序sort(Available_Processes, Available_Processes + j, SortBy_Priority);// 选取优先级最大的进程执行任务Available_Processes[0]->Start_Time = Time; 	// 设置进程开始时间Available_Processes[0]->Wait_Time = Available_Processes[0]->Arrive_Time; // 设置进程等待时间Time += Available_Processes[0]->Serve_Time; // 更新时间Available_Processes[0]->Finish_Time = Time; // 设置进程完成时间Available_Processes[0]->cycle_time = Available_Processes[0]->Finish_Time - Available_Processes[0]->Arrive_Time; 	// 计算进程周转时间Available_Processes[0]->Weighted_cycle_time = Available_Processes[0]->cycle_time * 1.0 / Available_Processes[0]->Serve_Time;Available_Processes[0]->FinishFlag = true; 	// 设置进程完成标志为truecout << "PCB:" << Available_Processes[0]->name << "\tArriveTime:" << Available_Processes[0]->Arrive_Time<< "\tPriority:" << Available_Processes[0]->Priority<< "\tWaitTime:" << Available_Processes[0]->Wait_Time<< "\tStartTime:" << Available_Processes[0]->Start_Time<< "\tServeTime:" << Available_Processes[0]->Serve_Time<< "\tFinishTime:" << Available_Processes[0]->Finish_Time<< "\tCircleTime:" << Available_Processes[0]->cycle_time<< endl; // 输出进程完成信息FinishCout += 1; 							// 完成进程计数器加1}double avg = 0, weighted_avg = 0;for (int i = 0; i < 5; i++) {      // 遍历进程数组avg += Process[i].cycle_time;     // 计算总周转时间weighted_avg += Process[i].Weighted_cycle_time; // 计算总带权周转时间}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转时间
}// 先来先服务调度算法(FCFS)
void First_Come_First_Serve(PCB  Process[5]) {cout << "\n先来先服务调度算法:" << endl;int FinishCout = 0; 	// 完成进程计数器初始化为0unsigned Time = 0; 		// 时间初始化为0cout << endl;sort(Process, Process + 5, SortBy_ArriveTime); // 按到达时间对进程数组进行排序while (FinishCout < 5) { // 当完成进程数量小于5时循环执行调度算法,因为进程还有进程未得到处理机时间int j = -1; 		 // 已到达且未完成进程计数器初始化为0for (int i = 0; i < 5; i++) { // 循环遍历所有进程if (Process[i].Arrive_Time <= Time and Process[i].FinishFlag == false) {j = i;break;}}// 如果j为-1,表示当前时间没有到达的进程,此时应该让时间继续推进if (j == -1) {Time += 1; 	// 时间加1continue; 	// 继续下一次循环}// 选取当前满足条件且到达时间最早的进程进行执行Process[j].Start_Time = Time; 	// 设置进程开始时间Process[j].Wait_Time = Process[j].Start_Time - Process[j].Arrive_Time; // 设置进程等待时间Time += Process[j].Serve_Time; 	// 更新时间Process[j].Finish_Time = Time; 	// 设置进程完成时间Process[j].cycle_time = Process[j].Finish_Time - Process[j].Arrive_Time; 				// 计算进程周转时间Process[j].Weighted_cycle_time = Process[j].cycle_time * 1.0 / Process[j].Serve_Time;Process[j].FinishFlag = true; 	// 设置进程完成标志为truecout << "PCB:" << Process[j].name << "\tArriveTime:" << Process[j].Arrive_Time<< "\tWaitTime:" << Process[j].Wait_Time<< "\tStartTime:" << Process[j].Start_Time<< "\tServeTime:" << Process[j].Serve_Time<< "\tFinishTime:" << Process[j].Finish_Time<< "\tCircleTime:" << Process[j].cycle_time<< endl; // 输出进程完成信息FinishCout += 1; // 完成进程计数器加1}double avg = 0, weighted_avg = 0;for (int i = 0; i < 5; i++) {      // 遍历进程数组avg += Process[i].cycle_time;     // 计算总周转时间weighted_avg += Process[i].Weighted_cycle_time; // 计算总带权周转时间}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转时间
}// 短作业优先算法 (SJF)
void Shortest_Job_First(PCB Process[5]) {cout << "\n短作业优先算法:" << endl;PCB* Available_Processes[5]; 	// 定义指向进程控制块的指针数组int FinishCout = 0; 			// 完成进程计数器初始化为0unsigned Time = 0; 				// 时间初始化为0cout << endl;sort(Process, Process + 5, SortBy_ArriveTime); // 按到达时间对进程数组进行排序while (FinishCout < 5) { 	// 当完成进程数量小于5时循环执行调度算法,因为进程还有进程未得到处理机时间int j = 0; 				// 已到达且未完成进程计数器初始化为0for (int i = 0; i < 5; i++) { // 循环遍历所有进程if (Process[i].Arrive_Time <= Time and Process[i].FinishFlag == false) { 	// 如果进程已到达且未完成Available_Processes[j++] = Process + i; 								// 将该进程加入到可用进程数组中}}// 如果j为0,表示当前时间没有到达的进程,此时应该让时间继续推进if (j == 0) {Time += 1; 	// 时间加1continue; 	// 继续下一次循环}// 将当前时间已经到达的所有进程按服务时间进行排序sort(Available_Processes, Available_Processes + j, SortBy_ServeTime);// 选取当前满足条件且服务时间最短的进程执行任务Available_Processes[0]->Start_Time = Time; 	// 设置进程开始时间Available_Processes[0]->Wait_Time = Available_Processes[0]->Arrive_Time; // 设置进程等待时间Time += Available_Processes[0]->Serve_Time; // 更新时间Available_Processes[0]->Finish_Time = Time; // 设置进程完成时间Available_Processes[0]->cycle_time = Available_Processes[0]->Finish_Time - Available_Processes[0]->Arrive_Time; 	// 计算进程周转时间Available_Processes[0]->Weighted_cycle_time = Available_Processes[0]->cycle_time * 1.0 / Available_Processes[0]->Serve_Time;Available_Processes[0]->FinishFlag = true; 	// 设置进程完成标志为truecout << "PCB:" << Available_Processes[0]->name << "\tArriveTime:" << Available_Processes[0]->Arrive_Time<< "\tWaitTime:" << Available_Processes[0]->Wait_Time<< "\tStartTime:" << Available_Processes[0]->Start_Time<< "\tServeTime:" << Available_Processes[0]->Serve_Time<< "\tFinishTime:" << Available_Processes[0]->Finish_Time<< "\tCircleTime:" << Available_Processes[0]->cycle_time<< endl; // 输出进程完成信息FinishCout += 1; 							// 完成进程计数器加1}double avg = 0, weighted_avg = 0;for (int i = 0; i < 5; i++) {      // 遍历进程数组avg += Process[i].cycle_time;     // 计算总周转时间weighted_avg += Process[i].Weighted_cycle_time; // 计算总带权周转时间}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转时间}void Multilevel_Feedback_Queue_Algorithm(PCB Process[5]) {cout << "\n多级反馈队列调度算法:" << endl;MFQ MFQSet;Multilevel_Feedback_Queue_Algorithm_Input(&MFQSet); // 调用输入多级反馈队列的函数queue<PCB> L1, L2, L3; // 定义三个队列sort(Process, Process + 5, SortBy_ArriveTime); // 按到达时间对进程数组进行排序unsigned int Time = 0; // 时间初始化为0double avg = 0, weighted_avg = 0; // 初始化平均周转时间和带权平均周转时间for (int i = 0; i < 5; i++) { // 将进程按照到达时间加入到第一级别队列Process[i].Original_Serve_Time = Process[i].Serve_Time;L1.push(Process[i]);}while (!L1.empty() || !L2.empty() || !L3.empty()) { // 当三个队列有不为空的时循环cout << "Time:" << Time << " \t\t"; // 输出当前时间if (!L1.empty()) { // 如果第一级别队列不为空PCB temp = L1.front(); // 获取队首进程L1.pop();              // 弹出队首进程cout << "P" << temp.name << " is processing:"; // 输出当前处理的进程名称Time += min(temp.Serve_Time, MFQSet.Time_Slice[0]); // 时间增加当前进程的服务时间或者时间片长度中较小的那个temp.Serve_Time = max(0, (int)(temp.Serve_Time - MFQSet.Time_Slice[0])); // 更新当前进程的服务时间if (temp.Serve_Time == 0) { // 如果当前进程的服务时间为0temp.Finish_Time = Time; // 设置当前进程的完成时间temp.cycle_time = temp.Finish_Time - temp.Arrive_Time;   // 计算当前进程的周转时间temp.Weighted_cycle_time = (double)temp.cycle_time / temp.Original_Serve_Time; // 计算当前进程的带权周转时间avg += temp.cycle_time;     // 计算总周转时间weighted_avg += temp.Weighted_cycle_time; // 计算总带权周转时间cout << "Finish Time:" << Time << endl; // 输出当前进程的完成时间} else {cout << 'P' << temp.name << "转移到队列2的末尾\n";L2.push(temp); // 否则将当前进程加入到第二级别队列}} else if (!L2.empty()) { // 如果第一级别队列为空但第二级别队列不为空PCB temp = L2.front(); // 获取队首进程L2.pop();              // 弹出队首进程cout << "P" << temp.name << " is processing:"; // 输出当前处理的进程名称Time += min(temp.Serve_Time, MFQSet.Time_Slice[1]); // 时间增加当前进程的服务时间或者时间片长度中较小的那个temp.Serve_Time = max(0, (int)(temp.Serve_Time - MFQSet.Time_Slice[1])); // 更新当前进程的服务时间if (temp.Serve_Time == 0) { // 如果当前进程的服务时间为0temp.Finish_Time = Time; // 设置当前进程的完成时间temp.cycle_time = temp.Finish_Time - temp.Arrive_Time;   // 计算当前进程的周转时间temp.Weighted_cycle_time = (double)temp.cycle_time / temp.Original_Serve_Time; // 计算当前进程的带权周转时间avg += temp.cycle_time;     // 计算总周转时间weighted_avg += temp.Weighted_cycle_time; // 计算总带权周转时间cout << "Finish Time:" << Time << endl; // 输出当前进程的完成时间} else {cout << 'P' << temp.name << "转移到队列3的末尾\n";L3.push(temp); // 否则将当前进程加入到第三级别队列}} else { // 如果第一级别和第二级别队列均为空while (!L3.empty()) {PCB temp = L3.front(); // 获取队首进程L3.pop();              // 弹出队首进程cout << "P" << temp.name << " is processing:"; // 输出当前处理的进程名称Time += min(temp.Serve_Time, MFQSet.Time_Slice[2]); // 时间增加当前进程的服务时间或者时间片长度中较小的那个temp.Serve_Time = max(0, (int)(temp.Serve_Time - MFQSet.Time_Slice[2])); // 更新当前进程的服务时间if (temp.Serve_Time == 0) { // 如果当前进程的服务时间为0temp.Finish_Time = Time; // 设置当前进程的完成时间temp.cycle_time = temp.Finish_Time - temp.Arrive_Time;   // 计算当前进程的周转时间temp.Weighted_cycle_time = (double)temp.cycle_time / temp.Original_Serve_Time; // 计算当前进程的带权周转时间avg += temp.cycle_time;     // 计算总周转时间weighted_avg += temp.Weighted_cycle_time; // 计算总带权周转时间cout << "Finish Time:" << Time << endl; // 输出当前进程的完成时间} else {cout << 'P' << temp.name << "继续执行\n";L3.push(temp); // 将当前进程加入到第三级别队列末尾}}}}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转
}// 输入多级反馈队列的函数
void Multilevel_Feedback_Queue_Algorithm_Input(MFQ *mfq) {cout << "Please input the Time Slice(Three Numbers) for Multilevel Feedback Queue" << endl;cin >> mfq->Time_Slice[0] >> mfq->Time_Slice[1] >> mfq->Time_Slice[2];
}

三、心灵的救赎

  1. “爱”就是科学与逻辑永远无法解释的程序
    在这里插入图片描述

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

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

相关文章

NDIS小端口驱动开发(一)

在四种NDIS相关的驱动中&#xff0c;微型端口驱动(也经常翻译为为小端口驱动)位于驱动栈的底部&#xff0c;一般将它理解为NIC设备的驱动程序&#xff1a; 有几种类型的微型端口驱动程序类型&#xff1a; 无连接微型端口驱动程序用于控制无连接网络媒体 &#xff0c;如以太网的…

redis基本数据结构与应用

文章目录 概要String结构Hash结构List结构Set结构Zset结构bitmap位图类型geo地理位置类型其他常用命令 概要 redis常用的5种不同数据结构类型之间的映射如下&#xff1a; 结构类型结构存储的值结构的读写能力STRING可以是字符串、整数或者浮点数key-value形式&#xff1b;对整…

JMH304-剑侠情缘2网络版+2017纹饰端+翅膀+单机+外网整理+各种副本

资源介绍&#xff1a; 藏剑-太虚-梁山-杀手堂种树地宫师门纹饰装备长流云阳套等等———– 做登录器联系站长 资源截图&#xff1a; 下载地址

.NET周刊【5月第4期 2024-05-26】

国内文章 开源低代码框架 ReZero API 正式版本发布 &#xff0c;界面操作直接生成API https://www.cnblogs.com/sunkaixuan/p/18201175 ReZero是一款.NET6的中间件&#xff0c;采用MIT许可证开源&#xff0c;目的是降低.NET Core开发的门槛。它提供界面操作生成API的功能&am…

《Ai学习笔记》自然语言处理 (Natural Language Processing):常见机器阅读理解模型(上)02

Glove 词向量&#xff1a; 在机器理解中的词的表示&#xff1a; 词袋&#xff08;bow,bag of words&#xff09; one-hot 词向量 word2vec glove 目的&#xff1a;将一个词转换成一个向量 Word2vec 是一种用于生成词向量的工具包&#xff0c;由Google在2013年开源推出…

大规模语言模型的书籍分享

在当今人工智能领域&#xff0c;大规模语言模型成为了研究和应用的热点之一。它们以其大规模的参数和强大的性能表现&#xff0c;推动着机器学习和深度学习技术的发展。对于GPT 系列大规模语言模型的发展历程&#xff0c;有两点令人印象深刻。 第一点是可拓展的训练架构与学习范…

《TCP/IP网络编程》(第十二章)I/O复用(1)

本章将讨论实现并发服务器的第二种办法&#xff0c;基于I/O复用的服务器端构建。 I/O复用它允许单个进程或线程同时处理多个输入/输出&#xff08;I/O&#xff09;操作&#xff0c;而无需为每个I/O操作创建一个独立的线程或进程。这种技术可以显著提高应用程序的效率和性能&…

前端学习--React部分

文章目录 前端学习--React部分前言1.React简介1.1React的特点1.2引入文件1.3JSX&#x1f349;JSX简介与使用&#x1f349;JSX语法规则 1.4模块与组件&#x1f349;模块&#x1f349;组件 1.5安装开发者工具 2.React面向组件编程2.1创建组件&#x1f349;函数式组件&#x1f349…

Elasticsearch 认证模拟题 - 1

1、题目 定义一个数据流&#xff0c;满足 data-stream_*_*&#xff0c;数据首先分布在 data_hot&#xff0c;5分钟后移动到 data_warm&#xff0c;3分钟后到 data_cold&#xff0c;再过 8 分钟删除。 1.1 考点 生命周期索引模板数据流 1.2 答案 # 修改生命周期策略修改时间…

【算法】位运算算法——只出现一次的数字Ⅱ

题解&#xff1a;只出现一次的数字Ⅱ(位运算算法) 目录 1.题目2.题解&#xff1a;3.代码示例4.总结 1.题目 题目链接&#xff1a;LINK 要求&#xff1a;时间复杂度&#xff1a;O(N)&#xff0c;空间复杂度&#xff1a;O(1) 2.题解&#xff1a; 3.代码示例 class Solution {…

Java设计模式 _行为型模式_中介者模式

一、中介者模式 1、中介者模式 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型模式。主要通过一个中介类&#xff0c;该类通常处理不同类之间的通信&#xff0c;并支持松耦合&#xff0c;使代码易于维护。 2、实现思路 &#xff08;1&#xff09;、定义实体…

【Linux】-Kafka集群安装部署[18]

简介 Apache Kafka是一款分布式的、去中心化的、高吞吐低延迟、订阅模式的消息队列系统。 同RabbitMQ一样&#xff0c;Kafka也是消息队列。不过RabbitMQ多用于后端系统&#xff0c;因其更加专注于消息的延迟和容错。 Kafka多用于大数据体系&#xff0c;因其更加专注于数据的…

K210 数字识别 笔记

一、烧写固件 连接k210开发板&#xff0c;点开烧录固件工具&#xff0c;选中固件&#xff0c;并下载 二、模型训练 网站&#xff1a;MaixHub 1、上传文件 2、开始标记数据 添加9个标签&#xff0c;命名为1~9&#xff0c;按键盘w开始标记&#xff0c;键盘D可以下一张图片&…

解密Prompt系列15. LLM Agent之数据库应用设计:DIN C3 SQL-Palm BIRD

上一章我们主要讲搜索引擎和LLM的应用设计&#xff0c;这一章我们来唠唠大模型和DB数据库之间的交互方案。有很多数据平台已经接入&#xff0c;可以先去玩玩再来看下面的实现方案&#xff0c;推荐 [sql translate]&#xff1a;简单&#xff0c;文本到SQL&#xff0c;SQL到文本…

后端企业级开发之yaml数据序列化格式文件详解2024

yaml格式 数据格式 yaml 是一种数据序列化的格式 容易阅读 容易与脚本语言交互 以数据为核心 重数据轻格式 我们要知道他怎么书写 大小写敏感 属性层级关系使用多行描述 每行结尾使用冒号结束 使用缩进表示层级关系 同层级左侧对其 只运行使用空格 属性前面添加空格 #表…

面试二十六、c++语言级别的多线程编程

一、 多线程编程 ​​​​​ 这里的c语言级别的多线程和linux的有一定的区别&#xff0c;c语言级别提供的多线程比较严格&#xff0c;如果主线程结束了&#xff0c;但是子线程没有结束&#xff0c;进程就会异常终止&#xff0c;而linux不会&#xff0c;会继续执行。 二、模拟卖…

Window VScode配置Conda教程(成功版)

VScode配置Conda 参考博文&#xff1a;https://blog.csdn.net/qq_51831335/article/details/126757014Anaconda安装&#xff08;注意勾选自动配置环境变量&#xff01;&#xff09; 官网&#xff1a;https://www.anaconda.com/download/success VScode配置 python插件安装安装 …

关于Java程序入口args参数

关于Java程序入口args参数 我们都知道一个java工程会有一个主程序入口&#xff0c;即我们常见到的如下代码 public static void main(String[] args) {// 中间程序 }但是很多人可能都不知道主程序入口中的String[] args后面的args会有怎么样一个使用场景呢&#xff1f; 其实在…

爬虫逆向实例小记——某数据知识管理网站-DES-ECB模式

aHR0cHM6Ly9rZC5uc2ZjLmNuL2ZpbmFsUHJvamVjdEluaXQ 注意&#xff1a;本文是逆向部分比较少&#xff0c;主要为了流程走通&#xff0c;限于代码搬运工。 第一步:分析页面 此网站经过请求响应&#xff0c;可以看出响应内容为加密内容。 第二步&#xff1a;判断加密类型 在XHR …

java.lang.NumberFormatException: For input string:

创建SpringBoot&#xff0c;Mybatis的项目时候&#xff0c;Service层调用Mapper层时候爆出了一个错误 发现报错是一个类型转换错误&#xff0c;经过排查后发现是因为mapper接收的实体类中没有写空参构造