C++积累06_简单的学生成绩管理系统_1.题目要求 学生成绩管理系统 (1)增加记录:要求可以连续增加多条记录。 (2)查找:-程序员宅基地

技术标签: c++  

这个学生成绩管理系统是我一个高中哥们他们的假期作业,记得假期的时候我刚看到了这个的最终效果,大一上刚结束的我震惊了:原来控制台还能这么玩儿!

题目描述

(1) 增加记录:要求可以连续增加多条记录。
(2) 查找:可以根据姓名(或学号)查找某个学生的课程成绩,查找某门课程成绩 处于指定分数段内的学生名单等等。可以实现模糊查询,即输入名字的一部 分,可以列出满足条件的所有记录。再从这个记录中进行二次选择。
(3) 删除一个学生的记录:要求可以先查找,再删除。删除前,要求用户确认。
(4) 成绩修改:若输入错误可进行修改;要求可以先查找,再修改。
(5) 统计分析:对某个班级学生的单科成绩进行统计,求出平均成绩;求平均成绩 既能求单科的平均成绩,又能求三科总分的平均成绩。 求出一门课程标准差和合格率;
(6) 排序功能:要求按总分进行排序(从高到低),若总分相同,则按数学排序; 若总分和数学相同,则按物理排序;若总分和各科成绩都相同,则按学号排 序;
(7) 文件操作:可以打开文件,显示班级的所有学生信息;可以将增加或修改后的 成绩重新写入文件;可以将排序好的信息写入新的文件。

这个就是积累一下,就不写我的心路历程了,直接把源代码贴上来,后续查找也方便。
代码里也有我当时的一些心路历程。
由于是大一,好多东西现在看还能修改的更好,当时也是做了好多尝试。

代码

其他的“散装”函数,先一起贴在这里,看下面看不懂的这里就有。

template<typename T>
void swapT(T & a, T & b)//用来交换两个东西的函数,虽然swap()这个有了,但是还是自己写一个
{
    
	T temp = a;
	a = b;
	b = temp;
}

template<typename T>
T inputT()//用来输入的函数
{
    
	T a;
	cin >> a;
	return a;
}

void outputT(const char* prev_param, ...)//用来输出的函数
{
    
	//定义保存函数参数的结构
	va_list pArgs;
	const char* para;    //获取参数用的临时变量    

	//对pArgs进行初始化,让它指向可变参数表里面的第一个参数
	//prev_param 是在变参表前面紧挨着的一个变量,即"..."之前的那个参数
	va_start(pArgs, prev_param);
	cout << prev_param;
	while (1)
	{
    
		//获取参数
		para = va_arg(pArgs, const char*);
		if ( NULL == para )	//判断最后一个参数是NULL则退出处理
			break;
		cout<< para;
	}

	//获取所有的参数之后,将pArgs指针关掉
	va_end(pArgs);
}

//输出学生成绩数据
void outputStudent(student&studentObj,int methodOfOutput = -1)//aka数组下标,-1就不输出下标
{
    
	if (methodOfOutput == -1)
	{
    
	/*	cout <<'\t'<< studentObj.Id << '\t' << '\t' << studentObj.Name << '\t' << studentObj.Math << '\t' << studentObj.Physics << '\t'
			<< studentObj.English << '\t' << endl;*/

		outputT ( "\t" ,studentObj.Id.c_str() , "\t" ,"\t", studentObj.Name.c_str(),  "\t" , std::to_string((int)studentObj.Math).c_str(), "\t", std::to_string((int)studentObj.Physics).c_str(),  "\t"
			, std::to_string((int)studentObj.English).c_str(),  "\t" , "\n",NULL);
	}
	else
	{
    
		cout <<'\t'<< methodOfOutput + 1 << '\t' << studentObj.Id << '\t' << '\t' << studentObj.Name << '\t' << studentObj.Math << '\t' << studentObj.Physics << '\t'
			<< studentObj.English << '\t' << endl;
	}
}

//用来在控制台输出表头行
void outputTitle( int methodOfOutput = -1)//仅作为输出方式选择,默认为不输出序号,其他为输出序号
{
    
	if (methodOfOutput == -1)
	{
    
		cout << "\t学号" << '\t' << '\t' << "姓名" << '\t' << "数学" << '\t' << "物理" << '\t' << "英语" << '\t' << endl;
	}
	else
	{
    
		cout << "\t序号" << '\t' << "学号" << '\t' << '\t' << "姓名"
			<< '\t' << "数学" << '\t' << "物理"
			<< '\t' << "英语" << '\t' << endl;
	}
}

(一)创建一个储存每个学生信息的结构体和学生类

//储存学生信息的结构体
struct student {
    	
	string Id;
	string Name;
	float Math = 0;
	float Physics = 0;
	float English = 0;
	float TotalScore = 0;
};

//学生类,Cstudent
class Cstudent {
    
private:
	int nStudentsCount = 0;	//记录学生的人数
	student stu[50];		//学生容量是50

public:
	void InputFile();//学生信息输入
	void Show();//显示成绩
	void Add();//添加成绩
	void Search();//查找成绩
	void Delete();//删除成绩
	void Revise();//修改成绩
	void Analysis();//统计分析
	void Sort();//排序功能
	void Save();//保存成绩
	void allSearch(int nStudentsCount);
};
  1. 为结构分配内存时,速度非常快,因为它们被保存在栈中。 在结构超出了作用域被删除时,速度也很快。
  2. 只要把结构作为参数来传递或者把一个结构赋给另一个结构(例如A=B,其中A和B是结构),结构的所有内容就被复制,而对于类,则只复制引用(所以就又有深拷贝、浅拷贝)。
  3. 结构主要用于小的数据结构。

(二)学生信息输入
学生信息输入要按照一定的格式。本例是要从一个记事本文件中读入数据。所以使用了ifstream。

void Cstudent::InputFile()
{
    
	string Id,stringFirst;
	nStudentsCount = 0;//学生总数初始化为0					
	
	ifstream input;
	input.open("D:\\学生成绩数据.txt");
	if (!input)//如果没有打开
	{
    
		cout << "此文件不存在!" << endl;
	}
	else
	{
    
		getline(input,stringFirst);	//读取表头行,然后什么也不要管
		//表头是一串字符串,如果直接用下面的读取的话会出现问题。
		while (1)//读入成绩数据
		{
    
			input >> stu[nStudentsCount].Id >>stu[nStudentsCount].Name >>
			 stu[nStudentsCount].Math >> stu[nStudentsCount].Physics >> stu[nStudentsCount].English;
			if (input.eof() != 0){
    //下面还有数据的话就继续读取
				break;
			}
			nStudentsCount++;
		}
	}
	input.close();
}

(三)显示成绩数据

void Cstudent::Show()
{
    
	/*//如果说上一个函数用while(1)还情有可换,这个是真的没必要int i = 0;*/
	outputTitle();//这个函数是在控制台中输出最上面一行的汉字表头的。
	
	for (int i = 0; i < nStudentsCount; i++)
	{
    
		outputStudent(stu[i]);//输出学生的成绩数据的函数。
	}
}

(四)增加学生信息

void Cstudent::Add()//可以设置一个自动保存机制,或者每次写完之后必须记得使用save函数
{
    
	while (1)
	{
    
		cout << "请输入学生的学号:";
		stu[nStudentsCount].Id = inputT<string>();

		cout << "请输入学生的姓名:";
		stu[nStudentsCount].Name = inputT<string>();

		cout << "请分别输入学生的数学、物理、英语成绩:";
		stu[nStudentsCount].Math = inputT<float>();
		stu[nStudentsCount].Physics = inputT<float>();
		stu[nStudentsCount].English = inputT<float>();

		cout << stu[nStudentsCount].Id << '\t'  << stu[nStudentsCount].Name << '\t' << stu[nStudentsCount].Math << '\t' << stu[nStudentsCount].Physics << '\t'
			<< stu[nStudentsCount].English << '\t' << endl;
		nStudentsCount++;//一定要注意这里的n值对上方数组的个数的影响

		cout << "是否继续添加?" << endl;
		//cout << "【1】添加\n" << "【2】返回" << endl;
		outputT("【1】添加\n", "【2】返回", '\n', NULL);

		int a = inputT<int>();
		
		if (a == 2){
    
			break;
		}
	}
}

(五)学生信息查找
这个是最多的了。查找有两种方式,一种是模糊查找,一种是精确查找。下面两个函数搭配,实现了两个功能。
把专门用来进行查找动作的函数抽了出来,方便复用。

void Cstudent::allSearch(int nStudentsCount)
//这个是专门实现查找过程的函数。
//因为这个系统里其他的功能也需要查找,所以专门写出来一个,方便复用。
{
    
	cout << "请选择查找方式:\n【1】模糊查找\n【2】精确查找\n";
	int choiceofsearchmethod;
	cin >> choiceofsearchmethod;
	
	if (choiceofsearchmethod == 1)
	{
    
		cout << "请选择要查询的内容:\n【1】姓名\n【2】学号\n";

		string fuzzyname;
		string fuzzyid;

		int fuzzychoice;
		cin >> fuzzychoice;

		if (fuzzychoice == 1)
		{
    
			cin >> fuzzyname;

			outputTitle(0);


			for (int i = 0; i < nStudentsCount; i++)
			{
    
				if (stu[i].Name.find(fuzzyname) != string::npos)
				{
    
					outputStudent(stu[i], i);

				}
			}
		}
		else
		{
    
			cin >> fuzzyid;

			outputTitle(0);

			for (int i = 0; i < nStudentsCount; i++)
			{
    
				if (stu[i].Id.find(fuzzyid) != string::npos)
				{
    
					outputStudent(stu[i], i);

				}
			}
		}
	}
	else
	{
    
		cout << "请选择:\n【1】查找学生个人信息\n【2】查找某分数段的学生,然后删除" << endl;
		int a;
		int rangtafanhui = 0;
		cin >> a;
		if (a == 1)//查找个人信息已实现
		{
    
			cout << "根据学生的____查找信息:\n【1】姓名\n【2】学号" << endl;
			int b;
			cin >> b;

			if (b == 1)//根据姓名查找
			{
    
				cout << "请输入学生姓名:" << endl;
				string c;
				cin >> c;
				outputTitle(0);
				for (int i = 0; i < nStudentsCount; i++)
				{
    
					if (stu[i].Name == c)
					{
    
						outputStudent(stu[i], i);
					}
				}
			}
			else//根据学号查找
			{
    
				cout << "请输入待查找的学号:" << endl;
				string inputId;
				cin >> inputId;
				outputTitle(0);
				for (int i = 0; i < nStudentsCount; i++)
				{
    
					if (stu[i].Id == inputId)
					{
    
						outputStudent(stu[i], i);
					}
				}
			}
		}
		else//查找某分数段
		{
    
			cout << "请输入科目:\n【1】数学\n【2】物理\n【3】英语\n";
			int courseNumber;
			int periodMax, periodMin;
			cin >> courseNumber;
			if (courseNumber == 1)//数学分数段
			{
    
				cout << "请输入数学分数段:\n";
				cout << "分数段左端点为:";
				cin >> periodMin;
				cout << "\n分数段右端点为:";
				cin >> periodMax;
				cout << "为您显示位于该分数段的学生:\n";
				outputTitle(0);
				for (int i = 0; i < nStudentsCount; i++)
				{
    
					if (stu[i].Math >= periodMin && stu[i].Math <= periodMax)
					{
    
						outputStudent(stu[i], i);
					}
				}
			}
			else if (courseNumber == 2)//物理分数段
			{
    
				cout << "请输入物理分数段:\n";

				cout << "分数段左端点为:";
				cin >> periodMin;
				cout << "\n分数段右端点为:";
				cin >> periodMax;
				cout << "为您显示位于该分数段的学生:\n";

				outputTitle(0);

				for (int i = 0; i < nStudentsCount; i++)
				{
    
					if (stu[i].Physics >= periodMin && stu[i].Physics <= periodMax)
					{
    
						outputStudent(stu[i], i);
					}
				}
			}
			else//英语分数段
			{
    
				cout << "请输入英语分数段:\n";

				cout << "分数段左端点为:";
				cin >> periodMin;
				cout << "\n分数段右端点为:";
				cin >> periodMax;
				cout << "为您显示位于该分数段的学生:\n";
				outputTitle(0);
				for (int i = 0; i < nStudentsCount; i++)
				{
    
					if (stu[i].English >= periodMin && stu[i].English <= periodMax)
					{
    
						outputStudent(stu[i], i);
					}
				}
			}
		}
	}
}

void Cstudent::Search()
{
    
	while (1)
	{
    
		allSearch(nStudentsCount);
		cout << "是否需要继续查找?" << endl;
		cout << "【1】继续\n【2】返回" << endl;
		int z = inputT<int>();
		if (z == 2){
    
			break;
		}
	}
}

(六)删除学生成绩
删除成绩前需要先查找要删除的同学,所以还得先使用查找函数。

void Cstudent::Delete()
{
    
	while (1)
	{
    
		allSearch(nStudentsCount);

		cout << "请输入所要操作的学生的序号:" << endl;
		int deletenumber = inputT<int>();		
		cout << "确定删除?\n【1】确定\n【2】取消\n";
		int choiceofdelete = inputT<int>();
			
		if (choiceofdelete == 2){
    
			break;
		}
		else
		{
    
			for (int i = deletenumber - 1; i < nStudentsCount - 1; i++)
			{
    		
				stu[i].Id = stu[i + 1].Id;
				stu[i].Name = stu[i + 1].Name;
				stu[i].Math = stu[i + 1].Math;
				stu[i].Physics = stu[i + 1].Physics;
				stu[i].English = stu[i + 1].English;
			}
			
			stu[nStudentsCount - 1].Id = '0';
			stu[nStudentsCount - 1].Name = '0';
			stu[nStudentsCount - 1].Math = -1;
			stu[nStudentsCount - 1].Physics = -1;
			stu[nStudentsCount - 1].English = -1;

			nStudentsCount--;

			cout << "是否继续删除?\n【1】是\n【2】否\n";
			int choiceofwanttocontinue = inputT<int>();		
			if (choiceofwanttocontinue == 2)
			{
    
				break;
			}
		}	
	}
}

对于删除某个数据,其实思路也还是比较多的。这里也总结一下在删除这里可以用到的一些想法。

  1. 要求了顺序的话,就把一个一个往前移,不要求顺序的话就最后一个赋值给要删除的那个,最后一个再重置。
  2. 可以设置一个对应的数组B[],然后某条删除掉之后对应的那个数组的那个项赋成-1,然后遍历的时候见到对应项是-1的时候就跳过。也就是说,遍历B[]的每一个元素,如果B[]中有一个元素是-1的话,那么这个索引对应的A中的元素就不输出。这是“假删除”。
  3. 这个是要往记事本文件里存的,所以说其实存储的时候遍历,如果是B[x]为-1的话,那么x索引对应的这项就不要存储,也是可以的。

(七)修改学生成绩

void Cstudent::Revise()
{
    
	while (1)
	{
    
		allSearch(nStudentsCount);
		
		//修改
		cout << "是否对某学生进行操作?\n【1】是\n【2】否" << endl;
		int choiceofwhetherrevise = inputT<int>();
		
		if (choiceofwhetherrevise == 2){
    
			break;
		}
		else
		{
    
			cout << "请输入要修改的同学的序号;" << endl;
			int numberofrevise = inputT<int>();
			
			cout << "请选择修改:\n【1】学号\n【2】姓名\n【3】数学成绩\n【4】物理成绩\n【5】英语成绩" << endl;
			
			string newid, newname; float newmath, newphysics, newenglish;
			cout << "请输入修改后的值:\n";
		
			int choicethings = inputT<int>();
			switch (choicethings)
			{
    
			case 1: stu[numberofrevise - 1].Id = inputT<string>(); break;
			case 2: stu[numberofrevise - 1].Name = inputT<string>(); break;
			case 3: stu[numberofrevise - 1].Math = inputT<float>(); break;
			case 4: stu[numberofrevise - 1].Physics = inputT<float>(); break;
			case 5: stu[numberofrevise - 1].English = inputT<float>(); break;
			}
		}

		cout << "是否继续修改?\n【1】是\n【2】否" << endl;
		int choicecontinuerevise = inputT<int>();
		if (choicecontinuerevise == 2){
    
			break;
		}
	}
}

(八)统计分析成绩
这个需要输出平均数,合格率,标准差。
这个有点小麻烦,大致思路是这样…

void Cstudent::Analysis()
{
    
	cout << "您选择的功能是:6" << endl;

	while (1)
	{
    
		double aveMath, avePhysics, aveEnglish, aveTotal, MathstdDeviation = 0, PhysicsstdDeviation = 0, EnglishstdDeviation = 0;
		double mathPassRate, physicsPassRate, englishPassRate;
		int MathpassPerson = 0, PhysicspassPerson = 0, EnglishpassPerson = 0;
		double sumMath = 0, sumPhysics = 0, sumEnglish = 0, sumTotal = 0;
		
		for (int i = 0; i < nStudentsCount; i++)
		{
    
			sumMath += stu[i].Math;
			sumPhysics += stu[i].Physics;
			sumEnglish += stu[i].English;
			sumTotal = sumTotal + stu[i].Math + stu[i].Physics+ stu[i].English;
			if (stu[i].Math >= 60)
			{
    
				MathpassPerson++;
			}
			if (stu[i].Physics >= 60)
			{
    
				PhysicspassPerson++;
			}
			if (stu[i].English >= 60)
			{
    
				EnglishpassPerson++;
			}
		}

		aveMath = (double)sumMath / nStudentsCount;
		avePhysics = (double)sumPhysics / nStudentsCount;
		aveEnglish = (double)sumEnglish / nStudentsCount;
		aveTotal = (aveMath + avePhysics + aveEnglish) / 3;
		mathPassRate = (double)MathpassPerson / nStudentsCount;
		physicsPassRate = (double)PhysicspassPerson / nStudentsCount;
		englishPassRate = (double)EnglishpassPerson / nStudentsCount;

		//标准差
		for (int i = 0; i < nStudentsCount; i++)//数学标准差
		{
    
			MathstdDeviation += ((stu[i].Math - aveMath) * (stu[i].Math - aveMath)) / nStudentsCount;
		}
		for (int i = 0; i < nStudentsCount; i++)//物理标准差
		{
    
			PhysicsstdDeviation += ((stu[i].Physics - avePhysics) * (stu[i].Physics - avePhysics)) / nStudentsCount;
		}
		for (int i = 0; i < nStudentsCount; i++)//英语标准差
		{
    
			EnglishstdDeviation += ((stu[i].English - aveEnglish) * (stu[i].English - aveEnglish)) / nStudentsCount;
		}

		cout << "请选择:\n【1】平均成绩\n【2】标准差\n【3】合格率" << endl;
		int x = inputT<int>();

		if (x == 1)//平均成绩
		{
    
			cout << "请选择:\n【1】数学平均成绩\n【2】物理平均成绩\n【3】英语平均成绩\n【4】三科平均成绩" << endl;
			int v = inputT<int>();
			
			if (v == 1)//数学平均成绩
			{
    
				cout << "数学的平均成绩是:" << aveMath << endl;
			}
			else if (v == 2)//物理平均成绩
			{
    
				cout << "物理的平均成绩是:" << avePhysics << endl;
			}
			else if (v == 3)//英语平均成绩
			{
    
				cout << "英语的平均成绩是:" << aveEnglish << endl;
			}
			else//三科平均成绩
			{
    
				cout << "三科的平均成绩是:" << aveTotal << endl;
			}
		}
		else if (x == 2)//标准差
		{
    
			cout << "请选择:\n【1】数学\n【2】物理\n【3】英语" << endl;
			int s = inputT<int>();

			if (s == 1)//数学标准差
			{
    
				cout << "数学的标准差是:" << sqrt(MathstdDeviation) << endl;
			}
			else if (s == 2)//物理标准差
			{
    
				cout << "物理的标准差是:" << sqrt(PhysicsstdDeviation) << endl;
			}
			else//英语标准差
			{
    
				cout << "英语的标准差是:" << sqrt(EnglishstdDeviation) << endl;
			}
		}
		else//合格率
		{
    
			cout << "请选择:\n【1】数学\n【2】物理\n【3】英语" << endl;
			int q = inputT<int>();
			
			if (q == 1)//数学合格率
			{
    
				cout << "数学的合格率是:" << mathPassRate << endl;
			}
			else if (q == 2)//物理合格率
			{
    
				cout << "物理的合格率是:" << physicsPassRate << endl;
			}
			else//英语合格率
			{
    
				cout << "英语的合格率是:" << englishPassRate << endl;
			}
		}
		cout << "请选择接下来的操作:\n【1】继续分析\n【2】返回" << endl;
		int choice_of_analysis = inputT<int>();
		if (choice_of_analysis == 2){
    
			break;
		}
	}
}

(九)排序成绩
有广大的排序算法,用哪一种都行…这里就用最基本的了!

void Cstudent::Sort()
{
    
	float totalScore[50] = {
     0 };
	for (int i = 0; i < nStudentsCount; i++)
	{
    
		totalScore[i] = stu[i].Math + stu[i].Physics + stu[i].English;
	}//然后进行排序
	for (int j = 0; j < nStudentsCount-1; j++)
	{
    
		for (int i = 0; i < nStudentsCount-j - 1; i++)
		{
    
			if (totalScore[i] > totalScore[i + 1])
			{
    
				string tempid, tempname;
				float tempmath, tempphysics, tempenglish;
				int tempTotalScore;

				swapT(totalScore[i], totalScore[i + 1]);

				//交换id
				swapT(stu[i].Id, stu[i + 1].Id);

				//交换name
				swapT(stu[i].Name, stu[i + 1].Name);

				//交换math
				swapT(stu[i].Math, stu[i + 1].Math);

				//交换physics
				swapT(stu[i].Physics, stu[i + 1].Physics);

				//交换english
				swapT(stu[i].English, stu[i + 1].English);
			}
		}
	}
}

(十)把成绩存储入记事本

void Cstudent::Save()
{
    
	ofstream output;
	output.open("D:\\学生成绩数据.txt");
	
	output << "学号" << '\t' << '\t' << "姓名" << '\t' << "数学" << '\t' << "物理" << '\t' << "英语" << '\t' << endl;

	for(int i = 0; i < nStudentsCount; i++)
	{
    
		output<<stu[i].Id << '\t' << '\t' << stu[i].Name << '\t' << stu[i].Math << '\t' << stu[i].Physics<< '\t' << stu[i].English << '\t' << endl;
	}
	output.close();
	cout << "保存成功!" << endl;
}

(十一)其余的函数

int main()
{
    
	cout << "请确定存储学生信息的文件存放在D:\\学生成绩数据.txt" << endl;
		
	int Choice = 0;
	Cstudent s;
	s.InputFile();//打开文件
	do
	{
    
		Choice = Menu();//由此可见,menu是要输入一个东西的,menu还要显示菜单
		switch (Choice)
		{
    
		case 0:					break;
		case 1: s.Show();		break;
		case 2: s.Add();		break;
		case 3: s.Search();		break;
		case 4: s.Delete();		break;
		case 5: s.Revise();		break;
		case 6: s.Analysis();	break;
		case 7: s.Sort();		break;
		case 8: s.Save();		break;
		case 9: s.InputFile();	break;
		}

	} while (Choice != 0);

	return 1;
}

int Menu()//用来进行选择操作
{
    
	cout << "学生成绩管理系统-by57" << endl << endl;
	cout << "==============================================" <<  endl;
	cout << "系统功能:\n【1】显示成绩\n【2】增加记录\n【3】查找记录\n【4】删除记录\n【5】修改记录\n【6】统计分析\n【7】成绩排序\n【8】保存成绩\n【9】刷新文件\n【0】退出系统" << endl;
	cout << "==============================================" << endl;
	cout << "您选择的功能是:" << endl;
	
	return inputT<int>();
}

写在后面

当时寒假的时候写这个程序,花了我好多好多天……
当时也是各种不会,各种查书查资料,可是大补了!
不过也就是写了一遍这个,让我对OOP以及整个程序的流程都了解的很清楚了。
之后也碰到好多程序,也不发怵了。
也碰到类似的,思路也就了解了。

加油!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46192722/article/details/105439195

智能推荐

下班的时候在电梯里碰见个妹子,问这层楼是哪个部门的。我答技术部吧。她惊异:技术部也这么晚下班?妹子,你听说过科比和程序员的故事么?-程序员宅基地

文章浏览阅读1.4k次。下班的时候在电梯里碰见个妹子,问这层楼是哪个部门的。我答技术部吧。她惊异:技术部也这么晚下班?妹子,你听说过科比和程序员的故事么?转自:程序猿才懂得笑话 http://cxmonkey.duapp.com/?p=222

【0day】复现用友 NC NCFindWeb大型企业数字化平台log4j远程代码执行漏洞-程序员宅基地

文章浏览阅读220次。NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。用友 NC NCFindWeb大型企业数字化平台存在log4j远程代码执行漏洞,攻击者可以在恶意环境变量中插入特定的代码,使得Log4j执行该代码。_用友 nc ncfindweb大型企业数字化平台log4j远程代码执行漏洞

MySQL数据库分卷备份还原类_sql数据库分卷备份和还原-程序员宅基地

文章浏览阅读101次。执行数据库恢复是DBA的日常生活的一部分。一个DBA可能需要执行恢复由于种种原因,如恢复,刷新数据库用于测试目的等许多倍,它可能很难执行恢复由于损坏的媒体,在服务器上的磁盘空间不足等。在这篇文章中,我将概述的方法之一,我用来恢复的备份生产数据库的方案夫妇的日子,我的支持团队的成员来找我,说他们是无法刷新农行从生产服务器相同的的备份副本名为OLTP开发环境数据库。从生产服务器的备份副本大约75 GB...

Hi3516A开发--编译内核、uboot_hi3516a_sdk_v1.0.5.0.tgz-程序员宅基地

文章浏览阅读1.5w次,点赞4次,收藏20次。有两种编译方式一、整个编译(1)编译整个osdrv目录:make OSDRV_CROSS=arm-hisiv300-linux all或者make OSDRV_CROSS=arm-hisiv400-linux all/* 如果单板使用spi接口nand flash作为存储介质,请在编译整个目录时传入如下FLASH_TYPE参数 */make OSDRV_CROSS=_hi3516a_sdk_v1.0.5.0.tgz

国内首个基于 Rust 语言的 RPC 框架 — Volo 正式开源!_rust开源项目-程序员宅基地

文章浏览阅读3k次。Volo 是字节跳动服务框架团队研发的轻量级、高性能、可扩展性强、易用性好的 Rust RPC 框架,使用了 Rust 最新的 GAT 和 TAIT 特性。在字节内部,Volo 已经落地多个业务和基础组件,并且取得了超预期的性能收益。..._rust开源项目

3.安装PHP环境(Ubuntu)_ubuntu离线安装php-程序员宅基地

文章浏览阅读516次。php环境 Ubuntu_ubuntu离线安装php

随便推点

TreeViewer应用实例(ITreeContentProvider与LabelProvider的使用)-程序员宅基地

文章浏览阅读1.2k次。TreeViewer应用实例。ITreeContentProvider与LabelProvider的使用_treeviewer

如何将别人Google云端硬盘中的数据进行保存_谷歌网盘怎么保存别人的资源-程序员宅基地

文章浏览阅读5.9k次。查了好久终于知道!如何将别人Google云端硬盘中的数据进行copy,而不是右键发现只有添加快捷方式只要shift+z就可以保存了!之后等我弄清楚怎么将别人家的云盘中的数据集导到colab再来详细更新!..._谷歌网盘怎么保存别人的资源

java中查看数据类型_java查看数据类型-程序员宅基地

文章浏览阅读2.5k次。/** * 1. 通过反射获取传来参数的JavaClass对象 * 2. 获取到JavaClass对象的类型名称 * 3. 将参数的类型名称返回 */public class GetType { public static String getType(Object obj) { return obj.getClass().getTypeName(); }}..._java查看数据类型

Scrapy-redis分布式+Scrapy-redis实战-程序员宅基地

文章浏览阅读185次。【学习目标】Scrapy-redis分布式的运行流程Scheduler与Scrapy自带的Scheduler有什么区别Duplication Filter作用源码自带三种spider的使用6. Scrapy-redis分布式组件Scrapy 和 scrapy-redis的区别Scrapy 是一个通用的爬虫框架,但是不支持分布式,Scrapy-redis是为了更方..._本模块定义了 redismixin 类用于从 redis 服务器读取url 构造为 request,同时

web播放H.264/H.265,海康,大华监控摄像头RTSP流方案_海康api hls怎么取265的流-程序员宅基地

文章浏览阅读211次。况且很多技术方案,需要在后端持续运行高负荷运转的视频转码转流服务,如果摄像头路数多或需要在线播放的终端比较多,服务器的压力就会很大,播放卡顿、花屏、黑屏、断播等现象就会时常出现,很难让客户满意,为了解决这些问题,相关硬件、软件的投入和持续不断的带宽占用往往也让客户难以接受。2. 设备兼容性强,同时支持海康、大华、宇视、华为等厂家的硬件设备,只要能输出RTSP、RTMP、HLS、HTTP、TCP、UDP等流媒体协议,就可以直接播放;3. 录像功能,支持直接录像保存到本地MP4文件。5. 语音对讲及云台控制。_海康api hls怎么取265的流

HTML详解连载(7)-程序员宅基地

文章浏览阅读2k次,点赞57次,收藏59次。对伪元素和盒子模型进行了详细分析