基于消息队列+多进程编写的银行模拟系统

银行模拟系统

  • 概述
  • 客户端 client.c
  • 服务端 serve.c
  • 开户 enroll.c
  • 存款 save.c
  • 转账 transfer.c
  • 取款 take.c
  • makefile文件

概述

  该案例大体过程为,服务器先启动,初始化消息队列和信号,用多线程技术启动开户、存钱、转账、取钱模块,并且可以控制结束。客户端启动后会自动链接服务器,会将用户的请求发送到请求队列,从响应消息队列读取处理结果,并提示给用户。其他模块轮询检测请求消息队列中是否有自己应该去做事情的消息,如果读取到就开始任务,并且将任务结果发送到响应消息队列。
  目前用户信息存取是通过txt文件实现的,每个用户单独一个文件。
  并且提供了makefile文件生成可执行文件,文件布局如下:

在这里插入图片描述

客户端 client.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int reqid;//请求队列id
int resid;//响应队列id

typedef struct msgbuff
{
   long mtype;
   char name[20];
   char password[20];
   float money;
}user;

typedef struct resbuff
{
   long type;
   char name[20];
   char msg[256];
   float money;
}res;

void menu(void);				//菜单
void enroll(void);				//开户
void save_money(void);			//存钱
void transfer_money(void);		//转账
void take_money(void);			//取钱

int main(int argc,char *argv[])
{
   while(1)
   {
   	menu();
   }
}


void menu(void)
{
   system("clear");
   printf("\n\t欢迎使用wwz银行ATM机\n");
   printf("\t\t1:开户\n");
   printf("\t\t2:存钱\n");
   printf("\t\t3:转账\n");
   printf("\t\t4:取钱\n");
   printf("\t请输入1-4进行选择:\n");
   int key;
   scanf("%d",&key);
   switch(key)
   {
   	case 1 :	enroll();			break;
   	case 2 :	save_money();		break;
   	case 3 :	transfer_money();	break;
   	case 4 :	take_money();		break;
   default:printf("输入有误请重新输入\n");sleep(1);break;
   }
}
void enroll(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、存钱金额\n");
   user u;
   scanf("%s %s %f",u.name,u.password,&u.money);
   //发送到请求队列
   u.mtype = 1;
   msgsnd(reqid,&u,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r;
   msgrcv(resid,&r,sizeof(res),1,0);  //1对应上面的1
   printf("%s",r.msg);
   return;
}
void save_money(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、存钱金额\n");
   user u;
   scanf("%s %s %f",u.name,u.password,&u.money);
   //发送到请求队列
   u.mtype = 2;
   msgsnd(reqid,&u,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r;
   msgrcv(resid,&r,sizeof(res),2,0);  //1对应上面的1
   printf("%s",r.msg);
   return;
}
void transfer_money(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、转账金额、转账账户\n");
   user u1,u2;
   scanf("%s %s %f %s",u1.name,u1.password,&u1.money,u2.name);
   //发送到请求队列
   u1.mtype = 4;
   u2.mtype = 5;
   msgsnd(reqid,&u1,sizeof(user)-sizeof(long),0);
   msgsnd(reqid,&u2,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r1,r2;
   msgrcv(resid,&r1,sizeof(res),4,0);
   msgrcv(resid,&r2,sizeof(res),5,0);
   printf("%s\t",r1.msg);
   printf("%s",r2.msg);
   return;
}
void take_money(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、取钱金额\n");
   user u;
   scanf("%s %s %f",u.name,u.password,&u.money);
   //发送到请求队列
   u.mtype = 3;
   msgsnd(reqid,&u,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r;
   msgrcv(resid,&r,sizeof(res),3,0);  //1对应上面的1
   printf("%s",r.msg);
   return;
}

服务端 serve.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>

static int reqid = -1; //作为请求的消息队列的返回id
static int resid = -1;  //作为响应的消息队列的返回id

typedef struct Service{
    char path[256];
    pid_t pid;
}Srv;
static Srv srv[]={ 
    {"./out/enroll",-1},      	//开户
    {"./out/save",-1},      	//存款
    {"./out/take",-1},  		//取款
    {"./out/trans",-1},     	//转账
};

int Init_msg();				//初始化消息队列
void deInit_msg();			//销毁消息队列
void sigint(int signum);	//初始化信号
int start();				//启动服务器
int stop();					//关闭服务器

int main(int argc,char *argv[])
{
	atexit(deInit_msg);
	signal(SIGINT,sigint);
	if(Init_msg() == -1){return -1;}
    if(start() == -1){return -1;}
    sleep(1);
    //阻塞等待退出
    printf("按<回车>键退出......\n");
    getchar();
    if(stop() == -1){return -1;}
    return 0;
}
int Init_msg()
{
    printf("服务器初始化.....\n");
    
    //键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
	//创建
    reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
    printf("创建请求消息队列成功!\n");
    resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
    printf("创建应答消息队列成功!\n");
    return 0;
}
void deInit_msg()
{
    printf("服务器关闭.....\n");
    if(msgctl(reqid,IPC_RMID,NULL) == -1){perror("msgctl");}
    else	printf("销毁请求消息队列成功!\n");
    if(msgctl(resid,IPC_RMID,NULL) == -1)perror("msgctl");
    else	printf("销毁应答消息队列成功!\n");
}
void sigint(int signum)
{
    printf("%d\n",signum);
    stop();
    exit(0);
}

int start()
{
    printf("启动服务器\\n");
    size_t i;
    for(i=0; i<sizeof(srv)/sizeof(srv[0]); i++)
    {
        if((srv[i].pid = vfork()) == -1)
        {perror("vfork");return -1;}
        if(srv[i].pid == 0)
        {
            if(execl(srv[i].path,srv[i].path,NULL)==-1)
            {
                perror("execl");
                return -1;
            }
            return 0;
        }
    }
    return 0;
}
int stop()
{
    printf("关闭服务器\n");
    size_t i;
    for(i=0; i<sizeof(srv)/sizeof(srv[0]); i++)
    {
        if(kill(srv[i].pid,SIGINT) == -1)
        {
            perror("kill");
            return -1;
        }
    }
    for(;;)if(wait(NULL) == -1){perror("wait");break;}
    return 0;
}

开户 enroll.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;
//停止服务函数
void stop_fun(void)
{
	printf("开户服务停止\n");
	exit(0);
}
//保存信息函数
int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	printf("开户服务启动\n");
	while(1)
	{
		//轮循等待从队列中读出数据
		user req;
		if(msgrcv(reqid,&req,sizeof(req)-sizeof(long),1,0)==-1)
		{perror ("msgrcv");continue;}
		
		printf("开户帐号:");
        printf("%s\n",req.name);
		
		res r;
		strcpy(r.name,req.name);
		//打开文件并且确认是否有该用户
		char temp[128]={0};
		sprintf(temp,"/home/wwz/xyd/bank/data/%s.txt",req.name);
		//只写,如果打不开就证明没有,能打开就是有了
		int fp = open(temp,O_WRONLY);
		
		if(fp>0)
		{
			r.type = 1;
			sprintf(r.msg,"已有该用户,开户失败!");
			msgsnd(resid,&r,sizeof(res)-sizeof(long),0);
		}
		else
		{
			save(&req);
			sprintf(r.msg,"开户成功!");
			msgsnd(resid,&r,sizeof(res)-sizeof(long),0);
		}
		close(fp);
	}
	return 0;
}

存款 save.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;

void * stop_fun(void)
{
	printf("存款服务停止\n");
	exit(0);
}

int get(char name[20],user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",name);
	FILE * fp = fopen(pathname,"r");
	if(fp == NULL){perror("get:fopen");return -1;}
	fscanf(fp,"%s\t%s\t%f\n",u->name,u->password,&u->money);
	fclose(fp);
	return 1;
}

int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	printf("存款服务启动\n");
	while(1)
	{
		//轮循等待从队列中读出数据
		user req;
		if(msgrcv(reqid,&req,sizeof(req)-sizeof(long),2,0)==-1)
		{perror ("msgrcv");continue;}
        printf("存款帐号:%s\n",req.name);
		res r;
		user u;
		if(get(req.name,&u)==-1)
		{sprintf(r.msg,"无效账户");goto send;}
		
		if(strcmp(req.password,u.password)!=0)
		{sprintf(r.msg,"密码错误");goto send;}
		
		u.money += req.money;
		if(save(&u) == -1)
		{sprintf(r.msg,"存款失败");goto send;}
		r.money = u.money;
		sprintf(r.msg,"存款成功");
send:		
		r.type = 2;
		if(msgsnd(resid,&r,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
	}
	return 0;
}

转账 transfer.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;

void  stop_fun(void)
{
	printf("转账服务停止\n");
	exit(0);
}

int get(char name[20],user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",name);
	FILE * fp = fopen(pathname,"r");
	if(fp == NULL){perror("get:fopen");return -1;}
	fscanf(fp,"%s\t%s\t%f\n",u->name,u->password,&u->money);
	fclose(fp);
	return 1;
}

int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out/",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out/",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	while(1)
	{
		//轮循等待从队列中读出数据
		user req1,req2;
		if(msgrcv(reqid,&req1,sizeof(user)-sizeof(long),4,0)==-1)
		{perror ("req1:msgrcv");continue;}
		if(msgrcv(reqid,&req2,sizeof(user)-sizeof(long),5,0)==-1)
		{perror ("req2:msgrcv");continue;}
		
		res r1,r2;
		user u1,u2;
		
		memset(r1.msg,0,sizeof(r1.msg));
		memset(r2.msg,0,sizeof(r2.msg));
		
		printf("转账帐号:%s  收款帐号:%s\n",req1.name,req2.name);
		
		if(get(req1.name,&u1)==-1)
		{strcpy(r1.msg,"转账账户为无效账户");goto send;}
		if(get(req2.name,&u2)==-1)
		{strcpy(r2.msg,"收款账户为无效账户");goto send;}
		if(strcmp(req1.password,u1.password))
		{strcpy(r1.msg,"密码错误");goto send;}
		if(req1.money>u1.money)
		{sprintf(r1.msg,"抱歉,余额不足,您的余额为:%f",u1.money);goto send;}
		u1.money -= req1.money;
		u2.money += req1.money;
		if(save(&u1) == -1)
		{strcpy(r1.msg,"转账失败");goto send;}
		if(save(&u2) == -1)
		{strcpy(r2.msg,"收款失败");goto send;}
		
		r1.money = u1.money;
		r2.money = u2.money;
		
		sprintf(r1.msg,"转账成功,您的余额为:%f",u1.money);
		strcpy(r2.msg,"收款成功");
send:		
		r1.type = 4;
		if(msgsnd(resid,&r1,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
send2:
		r2.type = 5;
		if(msgsnd(resid,&r2,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
	}
	return 0;
}

取款 take.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;

void  stop_fun(void)
{
	printf("取款服务停止\n");
	exit(0);
}

int get(char name[20],user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",name);
	FILE * fp = fopen(pathname,"r");
	if(fp == NULL){perror("get:fopen");return -1;}
	fscanf(fp,"%s\t%s\t%f\n",u->name,u->password,&u->money);
	fclose(fp);
	return 1;
}

int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out/",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out/",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	printf("取款服务启动\n");
	while(1)
	{
		//轮循等待从队列中读出数据
		user req;
		if(msgrcv(reqid,&req,sizeof(req)-sizeof(long),3,0)==-1)
		{perror ("msgrcv");continue;}
		printf("取款帐号:%s\n",req.name);
		res r;
		user u;
		if(get(req.name,&u)==-1)
		{strcpy(r.msg,"无效账户");goto send;}
		if(strcmp(req.password,u.password))
		{strcpy(r.msg,"密码错误");goto send;}
		if(req.money>u.money)
		{sprintf(r.msg,"抱歉,余额不足,您的余额为:%f",u.money);goto send;}
		u.money -= req.money;
		if(save(&u) == -1)
		{strcpy(r.msg,"取款失败");goto send;}
		r.money = u.money;
		sprintf(r.msg,"取款成功,您的余额为:%f",u.money);
send:		
		r.type = 3;
		if(msgsnd(resid,&r,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
	}
	return 0;
}

makefile文件

all:serve client ./out/enroll ./out/save ./out/take ./out/trans
obj = $(wildcard ./src/*.c)

serve:$(obj)
	gcc  ./src/serve.c -o $@
client:$(obj)
	gcc  ./src/client.c -o $@
./out/enroll:$(obj)
	gcc  ./src/enroll.c -o $@
./out/save:$(obj)
	gcc ./src/save.c -o $@
./out/take:$(obj)
	gcc  ./src/take.c -o $@
./out/trans:$(obj)
	gcc  ./src/transfer.c -o $@

clean:
	rm serve client ./out/enroll ./out/save ./out/take ./out/trans
.PHONY:clean

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人力项目框架解析新增修改方法

在迁移项目但是遇到了一些问题&#xff0c;迁移项目的时候发现项目的整体框架很有趣&#xff0c;但是苦于项目框架太大了&#xff0c;竟然只能完整迁移&#xff0c;做不到部分迁移&#xff0c;于是我也只能从一半的角度来进行解释整个项目。 雇员 我们雇员这个为对象讲解一下…

软件测试项目案例哪里找?【银行/教育/商城/金融/等等....】

项目一&#xff1a;ShopNC商城 项目概况&#xff1a; ShopNC商城是一个电子商务B2C电商平台系统&#xff0c;功能强大&#xff0c;安全便捷。适合企业及个人快速构建个性化网上商城。 包含PCIOS客户端Adroid客户端微商城&#xff0c;系统PC后台是基于ThinkPHP MVC构架开发的跨…

一个用于操作Excel文件的.NET开源库

推荐一个高性能、跨平台的操作Excel文件的.NET开源库。 01 项目简介 ClosedXML是一个.NET第三方开源库&#xff0c;支持读取、操作和写入Excel 2007 (.xlsx&#xff0c; .xlsm)文件&#xff0c;是基于OpenXML封装的&#xff0c;让开发人员无需了解OpenXML API底层API&#xf…

阿里云今年服务器是真便宜,看看哪些云服务器值得买!

2023年双十一&#xff0c;阿里云推出了一项令人惊喜的独家优惠活动&#xff01;在这次活动中&#xff0c;阿里云开放了老用户购买权限&#xff0c;以超低的价格购买云服务器ECS经济型e实例。这款服务器配置了2核2G内存、3M固定带宽和40G ESSD entry系统盘。而且&#xff0c;更棒…

Playwright测试自动化工具

作者观点&#xff1a;很长时间以来&#xff0c;Selenium是QA工程师寻求测试自动化解决方案的首选测试框架。它能够测试任何浏览器&#xff08;这在IE浏览器的统治时期尤其重要&#xff09;和任何平台。然而&#xff0c;现在看来&#xff0c;那个时代已经过去了。 今天&#xf…

flutter实用笔记

前言 写下这一篇文章是为了记录这段时间使用flutter 制作项目中一些比较常用的组件&#xff0c;以及具体怎么使用&#xff0c;获得怎样的效果。我使用的貌似是flutter4。由于官方更新迭代的差别比较明显&#xff0c;可能之后许多内容对应最新的flutter不适用&#xff0c;在此只…

IDEA导入jar包

通过maven导入本地包 mvn install:install-file -DfileD:\WebProject\ERP\zhixing-heyue-erp-server\zxhy-service-api\src\main\java\com\zxhy\service\api\invoice\baiwang\lib\com_baiwang_bop_sdk_outer_3_4_393.jar -DgroupIdcom.baiwang -DartifactIdbaiwang.open -Dver…

比较器应用之一_窗口比较器/极限比较器

窗口比较器&#xff1a;用处能在一个&#xff0c;电压落在规定的范围之内&#xff0c;报警或者不报警 当输入电压u1 > URa时&#xff0c;必然大于UaL&#xff0c;所以集成运放A1的输出uo1Uow&#xff0c;A2的输出u02-Uow。使得二极管D1导通&#xff0c;D2截止&#xff0c;电…

接口自动化测试用例编写规范

一、接口自动化测试用例设计方法 1.1接口参数覆盖 接口测试通过输入使用参数组合&#xff0c;获得服务器返回值&#xff0c;并根据预先设定的规则判断是否符合预期值。在接口测试中&#xff0c;根据接口的功能不同&#xff0c;需要侧重检测的方面也不同。主要从以下几个方面考…

(Matalb时序预测)GWO-BP灰狼算法优化BP神经网络的多维时序回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分代码展示&#xff1a; 四、完整代码数据说明手册下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于M…

年薪百万的人怎么做好工作复盘和总结

我们在为谁工作&#xff1f; 在大山宏泰《我们为什么工作》一书中有提到过&#xff1a; 70%左右的人认为工作只是维持生计的存在&#xff1b; 20%左右的人认为工作是个人价值的体现&#xff1b; 不到10%的人才会认为工作是幸福的。 人类的终极幸福有四重&#xff1a;被爱&…

PDF自动打印

​ 最近接到用户提过来的需求&#xff0c;需要一个能够自动打印图纸的功能&#xff0c;经过几天的研究整出来个初版了的&#xff0c;分享出来给大家&#xff0c;希望能有帮助。 需求描述: ​ 生产车间现场每天都有大量的图纸需要打印&#xff0c;一个一个打印太慢了&#xff0…

响应系统的作用与实现

首先讨论什么是响应式数据和副作用函数&#xff0c;然后尝试实现一个相对完善的响应系统。在这个过程中&#xff0c;我们会遇到各种各样的问题&#xff0c;例如如何避免无限递归&#xff1f;为什么需要嵌套的副作用函数&#xff1f;两个副作用函数之间会产生哪些影响&#xff1…

Leetcode——岛屿的最大面积

1. 题目链接&#xff1a;695. 岛屿的最大面积 2. 题目描述&#xff1a; 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都…

23000 个恶意流量代理的 IPStorm 僵尸网络被拆除

美国司法部今天宣布&#xff0c;联邦调查局取缔了名为 IPStorm 的僵尸网络代理服务的网络和基础设施。 IPStorm 使网络犯罪分子能够通过世界各地的 Windows、Linux、Mac 和 Android 设备匿名运行恶意流量。 与此案相关的俄罗斯裔摩尔多瓦籍公民谢尔盖马基宁 (Sergei Makinin)…

VUE基础的一些总结

首先推荐观看VUE官方文档 目录 创建一个 Vue 应用 要创建一个 Vue 应用&#xff0c;你需要按照以下步骤操作&#xff1a; 步骤 1&#xff1a;安装 Node.js 和 npm 确保你的计算机上已经安装了 Node.js。你可以在 Node.js 官网 上下载并安装它。安装完成后&#xff0c;npm&…

Spring中的BeanFactory和ApplicationContext的区别

我用一个例子去测试BeanFactory和ApplicationContext的区别 首先建立一个bean public class User { //声明无参构造&#xff0c;打印一句话&#xff0c;监测对象创建时机public User(){System.out.println("User对象初始化");} } 然后再建立测试类 ublic class User…

接口测试 —— Jmeter 之测试片段的应用

一、什么是测试片段&#xff1f; 控制器上一种特殊的线程组&#xff0c;它与线程组处于一个层级。与线程组不同的就是&#xff1a;测试片段不会执行。它是一个模块控制器或者被控制器应用时才会被执行。通常与Include Controller或模块控制器一起使用。 1.1 那它有啥作用&…

数据库进阶教学——索引

目录 一、索引概述 1、介绍 2、演示 3、优缺点 二、索引结构 1、B树 2、Hash 三、索引分类 四、索引语法 1、语法 2、示例 五、SQL性能分析 1、SQL执行频率 2、慢查询日志 3、profile详情 4、explain执行计划 六、索引使用 七、索引设计原则 一、索引概述 …

【文件包含】metinfo 5.0.4 文件包含漏洞复现

1.1漏洞描述 漏洞编号————漏洞类型文件包含漏洞等级⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐漏洞环境windows攻击方式 MetInfo 是一套使用PHP 和MySQL 开发的内容管理系统。MetInfo 5.0.4 版本中的 /metinfo_5.0.4/about/index.php?fmodule文件存在任意文件包含漏洞。攻击者可利用漏洞读取网…