嵌入式安防监控项目——exynos4412主框架搭建

news2025/7/17 4:42:59

目录

一、模块化编程思维

二、安防监控项目主框架搭建


一、模块化编程思维

其实我们以前学习32使用keil的时候就是再用模块化的思维。每个硬件都单独有一个实现功能的C文件和声明函数,进行宏定义以及引用需要使用头文件的h文件。

比如简单的加减乘除取余操作我们把他们每个都封装一个文件

但是他们每个文件里功能很少所以可以共用一个h文件common 

二、安防监控项目主框架搭建

这是我们的整个架构的代码

 buzzer和led都是板子上的外设,

transfer:是进行数据转换的

sqlite就是数据库之前学过的

refresh是刷新,我们上传的数据需要刷新到网页上

client request是客户端请求,从上往下发来的命令都由我们主机上的服务器处理

sms就是GPRS线程的程序可以打电话和发短信

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include "data_global.h"


void release_pthread_resource(int signo);

extern pthread_mutex_t mutex_client_request,
        		mutex_refresh,
        		mutex_sqlite,
	        	mutex_transfer,
	        	mutex_sms,
	        	mutex_buzzer,
	         	mutex_led;

extern pthread_cond_t  cond_client_request,
        		cond_refresh,
        		cond_sqlite,
	        	cond_transfer,
	        	cond_transfer,
	        	cond_sms,
	        	cond_buzzer,
	         	cond_led;

extern int msgid;
extern int shmid;
extern int semid;

pthread_t  id_client_request,
		  id_refresh,
		  id_sqlite,
		  id_transfer,
		  id_sms,
		  id_buzzer,
		  id_led;		


int main(int argc, const char *argv[])
{
	//
	pthread_mutex_init(&mutex_client_request,NULL);
	pthread_mutex_init(&mutex_refresh,NULL);
	pthread_mutex_init(&mutex_sqlite,NULL);
	pthread_mutex_init(&mutex_transfer,NULL);
	pthread_mutex_init(&mutex_sms,NULL);
	pthread_mutex_init(&mutex_buzzer,NULL);
	pthread_mutex_init(&mutex_led,NULL);

	signal (SIGINT, release_pthread_resource);

	pthread_cond_init(&cond_client_request,NULL);
	pthread_cond_init(&cond_refresh,NULL);
	pthread_cond_init(&cond_sqlite,NULL);
	pthread_cond_init(&cond_transfer,NULL);
	pthread_cond_init(&cond_sms,NULL);
	pthread_cond_init(&cond_buzzer,NULL);
	pthread_cond_init(&cond_led,NULL);


	pthread_create(&id_client_request,  NULL,pthread_client_request,NULL);   
	pthread_create(&id_refresh,		NULL,pthread_refresh,NULL);  			
	pthread_create(&id_sqlite,		NULL,pthread_sqlite,NULL);  			
	pthread_create(&id_transfer,	NULL,pthread_transfer,NULL); 
	pthread_create(&id_sms,			NULL,pthread_sms,NULL);  	
	pthread_create(&id_buzzer,		NULL,pthread_buzzer,NULL);	 
	pthread_create(&id_led,			NULL,pthread_led,NULL);  	

	//
	pthread_join(id_client_request,NULL);   printf ("pthread1\n");
	pthread_join(id_refresh,NULL);          printf ("pthread2\n");
	pthread_join(id_sqlite,NULL);			printf ("pthread3\n");
	pthread_join(id_transfer,NULL);			printf ("pthread4\n");
	pthread_join(id_sms,NULL);				printf ("pthread5\n");
	pthread_join(id_buzzer,NULL);			printf ("pthread6\n");
	pthread_join(id_led,NULL);				printf ("pthread7\n");

	return 0;
}


void release_pthread_resource(int signo)
{

	pthread_mutex_destroy (&mutex_client_request);   
	pthread_mutex_destroy (&mutex_refresh);   
	pthread_mutex_destroy (&mutex_sqlite);    
	pthread_mutex_destroy (&mutex_transfer);   
	pthread_mutex_destroy (&mutex_sms);   
	pthread_mutex_destroy (&mutex_buzzer);   
	pthread_mutex_destroy (&mutex_led);   

 	pthread_cond_destroy (&cond_client_request);
 	pthread_cond_destroy (&cond_refresh);
 	pthread_cond_destroy (&cond_sqlite);
 	pthread_cond_destroy (&cond_transfer);
 	pthread_cond_destroy (&cond_sms);
 	pthread_cond_destroy (&cond_buzzer);
 	pthread_cond_destroy (&cond_led);

	 pthread_detach(id_client_request);
	 pthread_detach(id_refresh);
	 pthread_detach(id_sqlite);
	 pthread_detach(id_transfer);
	 pthread_detach(id_sms);
	 pthread_detach(id_buzzer);
	 pthread_detach(id_led);

	 printf("all pthread is detached\n");
	 
	 msgctl (msgid, IPC_RMID, NULL);
	 shmctl (shmid, IPC_RMID, NULL);
	 semctl (semid, 1, IPC_RMID, NULL);

	 exit(0);
}

这是主函数,主函数其实就是一个进程,它创建了一堆线程来实现这些功能。

#include "data_global.h"


//½ԊԚigBeeµŊ񻍲ɼ¯µÁ9ƽ̨µĴ«¸ц뽾

void *pthread_transfer(void *arg)
{

	printf("pthread_analysis\n");

	
	
}

 transfer里面就是打印了一句话具体的功能还都没有实现。

#include "data_global.h"


//:A9LED模块线程.
void *pthread_led(void *arg)
{
	printf("pthread_led\n");
#if 0
	5.	open(dev_led,  )
	6.	pthread_cond_wait (cond_led,  );
	7.	获取dev_led_mask(控制标志)
	8.	通过ioctl()控制led
#endif 
}

 

#include "data_global.h"


//:A9·儹Ƿ¿ٖǏ߳ʮ
void *pthread_buzzer(void *arg)
{
	printf("pthread_buzzer\n");

#if 0	
	1.	open(dev_buzzer,  )
	2.	pthread_cond_wait (cond_buzzer,  );
	3.	»򈠤ev_buzzer_mask(¿ٖƱ떾)
	4.	ͨ¹򢳬£¨£©¿ٖŢuzzer
#endif 
}
#include "data_global.h"

extern int msgid;
extern key_t key;

extern pthread_mutex_t mutex_client_request,
        		mutex_refresh,
        		mutex_sqlite,
	        	mutex_transfer,
	        	mutex_analysis,
	        	mutex_sms,
	        	mutex_buzzer,
	         	mutex_led,
	         	mutex_camera;

extern pthread_cond_t  cond_client_request,
        		cond_refresh,
        		cond_sqlite,
	        	cond_transfer,
	        	cond_analysis,
	        	cond_sms,
	        	cond_buzzer,
	         	cond_led,
	         	cond_camera;

extern char recive_phone[12] ;
extern char center_phone[12] ;


struct msg msgbuf;




//:处理消息队列里请求的线程.
void *pthread_client_request(void *arg)
{
	if((key = ftok("/tmp",'g')) < 0){
		perror("ftok failed .\n");
		exit(-1);
	}

	msgid = msgget(key,IPC_CREAT|IPC_EXCL|0666);
	if(msgid == -1)	{
		if(errno == EEXIST){
			msgid = msgget(key,0777);
		}else{
			perror("fail to msgget");
			exit(1);
		}
	}
	printf("pthread_client_request\n");
	
	while(1){
		bzero(&msgbuf,sizeof(msgbuf));
			printf("wait form client request...\n");
		msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
		printf ("Get %ldL msg\n", msgbuf.msgtype);
		printf ("text[0] = %#x\n", msgbuf.text[0]);

		switch(msgbuf.msgtype){
			case 1L:
					printf("hello led\n");
				break;
			case 2L:
					printf("hello beep\n");
				break;
			case 3L:
					printf("hello seg\n");
				break;
			case 4L:
					printf("hello fan\n");
				break;
			
			case 5L:
					printf("set env data\n");
					printf("temMAX: %d\n",*((int *)&msgbuf.text[1]));
					printf("temMIN: %d\n",*((int *)&msgbuf.text[5]));
					printf("humMAX: %d\n",*((int *)&msgbuf.text[9]));
					printf("humMAX: %d\n",*((int *)&msgbuf.text[13]));
					printf("illMAX: %d\n",*((int *)&msgbuf.text[17]));
					printf("illMAX: %d\n",*((int *)&msgbuf.text[21]));

				break;
			case 6L:
			case 7L:
			case 8L:
			case 9L:
					printf("ţ¿ʒԽ«֢ЩطΪ)չ4ѧϰ£¬¼ԓˮ\n");
				break;
			case 10L:
				{
					int i = 0 , j = 0 ;
					for(i = 0 ; i < 11; i++){
						recive_phone[i] = msgbuf.text[i]; 	
					}
					recive_phone[i] = '\0';
					printf("recive:%s\n",recive_phone);
					for(j = 0 ;msgbuf.text[i] != '\0' && j < 12; i++, j++)
					{
						center_phone[j] =  msgbuf.text[i];
					}
					center_phone[j] = '\0';
					printf("center:%s\n",center_phone);
					#if 0
						pthread_mutex_lock (&mutex_slinklist);
						sqlite_InsertLinknode (ENV_UPDATE, all_info_RT, sto_no, 0);//0,0分别是仓库号和货物种类号
						pthread_mutex_unlock (&mutex_slinklist);
						pthread_cond_signal (&cond_sqlite);
					#endif 
				 }
				break;
			default:
				break;
				
		}
	}

}


#if 0

		long msgtype;//¾ࠌ嶄лϢ`э
		лϢ`эµķׅ䣺
			1L: 		LED¿ٖ 
			2L:			·儹Ƿ¿ٖ 
			3L:			̄·LEDµDŽ£ŢµŊ
			4L:			·芈
			5L:			ςʪ¶ɗʨ׃
			6L-7L-8L-9L,ԃԚ¸󉋵ŀ©չ
			10L: 		3Gͨхģ¿笇PRS 
		switch(msgbuf.msgtype){
			case 1L: ...  break;
			....
			default ....  break;
		}
#endif 

这些线程都还没有具体实现功能这就是一个框架


两种意识:
	1、分层意识
	2、数据流

*****************************************************
分层分析: 
##################
web网页端显示部分: 
		环境信息 === 实时刷新环境数据
		摄像头采集图像  ===  采集监控信息
		硬件控制 === 下发要去控制的命令
A9数据处理部分
		创建进程、线程
		每条线程做自己的事情
		涉及到进程间通信
		数据处理===>分发(上行数据 or 下行数据)		
A9-ZigBee数据采集部分
		A9采集部分
		ZigBee采集部分
		(STM32平台(可以自己扩展))
*****************************************************
数据流分析:
##################
		数据上传:
		数据下发:
					
	制定通信的协议(结构体):
	数据要怎么上传,上传的目的是为了什么?
	数据要怎么下发,下发的目的又是为了什么?
	
		数据的上传: ====> 共享内存上传数据 ====> 显示并交给用户查看环境信息
		数据的下发用于控制硬件:====> 消息队列下发数据 ===> 控制硬件改变环境
	
**************************************************************************

分层分析: 
web网页端显示部分: 
		环境信息:  		adc电压数据
							mpu6050的六轴数据
							温度
							湿度
		摄像头采集图像:
							
		硬件控制:			风扇
							LED灯
							蜂鸣器
							GPRS ==== 发短信或打电话

A9数据处理部分
	数据流向分析:
		1、ZigBee(采集终端)-->A9(处理平台)
		2、A9(处理平台)-->网页(显示平台)
		3、网页(显示平台)-->A9(处理平台)
		4、A9(处理平台)--->ZigBee(采集终端)
	
A9-ZigBee采集部分
			外设驱动 --------在应用层去获取外设的状态或数据
A9--------- 蜂鸣器  ------------------蜂鸣器报警
			LED灯   ------------------卧室-厕所-楼道-公共照明 --------LED2-LED3-LED4-LED5
			按键    ------------------按键触发中断---控制卧室和厕所灯-----LED2-LED3 
			ADC      -----------------获取ADC的采样数据
			mpu6050 ------------------获取MPU6050的六轴数据

zigbee------adc     ------主---协调器
			风扇    ------从---终端节点   下发命令控制风扇
			温湿度	------从---终端节点   上传温湿度数据
			(光敏)
			
小结: 					 
		|	        |             |             |
		|	ZigBee  |   A9 		  |      web    |
		|	        |             |             |
        |   adc     |   蜂鸣器    |  环境信息:-----------------adc电压数据
        |   风扇    |   LED灯     |  摄像头采集:-----usb摄像头  mpu6050的六轴数据
        |   温湿度	|   按键      |  硬件控制:	|------风扇     温度
        | (光敏)	|   ADC       |   			|      LED灯    湿度
                        mpu6050                        蜂鸣器
                        四路led灯模拟数码管			   GPRS
													   四路led灯模拟数码管	
						
数据流分析:
	数据上传: 
		ZigBee                 | 
			温湿度数据         |
		A9                     |
			ADC采集            |-----------上传这些数据
			加速计数据         |
			陀螺仪数据         |
		摄像头                 |
			视频流图像         |
			
	数据下发:                    
		ZigBee:                      |
			风扇                      |
		A9:                          |
			蜂鸣器                    |-----打开设备节点控制硬件
			LED灯                     |
			四路LED灯模拟的数码管     |
		GPRS:                        |
			3G通信模块                |
					
		    #define		GPRS_DEV   		 "/dev/ttyUSB0"
		    #define		ZIGBEE_DEV 		 "/dev/ttyUSB1"
		    #define		BEEPER_DEV 		 "/dev/fsbeeper0"
		    #define		LED_DEV    		 "/dev/fsled0"
		
制定通信的结构体:

	数据的上传: 
	数据类型定义: 	
		typedef uint8_t  unsigned char;       =======参考:
		typedef uint16_t unsigned short;
		typedef uint32_t unsigned int;

		//考虑到内存对齐的问题
		struct makeru_zigbee_info{
				uint8_t head[3]; //标识位: 'm' 's' 'm'  makeru-security-monitor  
				uint8_t type;	 //数据类型  'z'---zigbee  'a'---a9
				------------->crc ...加密算法 <--------------
				float temperature; //温度
				float humidity;  //湿度
				float tempMIN;//温度下限
				float tempMAX;//温度上限 
				float humidityMIN;   //湿度下限
				float humidityMAX;   //湿度上限
				uint32_t reserved[2]; //保留扩展位,默认填充0
				//void *data;  内核预留的扩展接口  参考版
		};

		struct makeru_a9_info{
			uint8_t head[3]; //标识位: 'm' 's' 'm'  makeru-security-monitor  
			uint8_t type;	 //数据类型  'z'---zigbee  'a'---a9
			uint32_t adc;
			short gyrox;   //陀螺仪数据
			short gyroy;
			short gyroz;
			short  aacx;  //加速计数据
			short  aacy;
			short  aacz;
			uint32_t reserved[2]; //保留扩展位,默认填充0
			//void *data;  内核预留的扩展接口  参考版
		};
		
		struct makeru_env_data{
			struct makeru_a9_info       a9_info;    
			struct makeru_zigbee_info   zigbee_info;
		};
		
		//所有监控区域的信息结构体
		struct env_info_client_addr
		{
			struct makeru_env_data  monitor_no[MONITOR_NUM];	//数组  老家---新家
		};
		
		
		
	数据的下发:(采用消息队列的方式下发数据到下位机上) 
		数据的下发用于控制硬件: 
		
		man msgsnd 
	   #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
       ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
                      int msgflg);
		消息队列用于通信的结构体: 包括数据类型和数据
		
		将消息队列封装成函数,直接通过参数传递的方式来发送信息: 
		int send_msg_queue(long type,unsigned char text)
		{
			struct msg msgbuf;
			msgbuf.type = 1L;
			msgbuf.msgtype = type;   //具体的消息类型
			msgbuf.text[0] = text;   //控制命令字 
			if(msgsnd(msgid,&msgbuf,sizeof(msgbuf) - sizeof(long),0) == -1){
				perror("fail to msgsnd type2");
				exit(1);
			}
			return 0;
		}
		
		struct msgbuf {
           long mtype;       /* message type, must be > 0 */
           char mtext[1];    /* message data */
        };

		//消息队列结构体
		#define QUEUE_MSG_LEN 32                 
		struct msg
		{
		    long type;   //从消息队列接收消息时用于判断的消息类型  ==== 暂时不用 1L===home1  2L===home2 ... 
		    
			long msgtype;//具体的消息类型 === 指代控制的设备,是什么类型的设备
		    unsigned char text[QUEUE_MSG_LEN];//消息正文  ====> CMD 控制指定的设备
		};
		
		long msgtype;//具体的消息类型
		消息类型的分配:
			1L: 		LED控制
			2L:			蜂鸣器控制
			3L:			四路LED灯模拟的数码管
			4L:			风扇
			5L:			温湿度最值设置
			6L-7L-8L-9L,用于个人的扩展
			10L: 		3G通信模块-GPRS 
		switch(msgbuf.msgtype){
			case 1L: ...  break;
			....
			default ....  break;
		}
		
		
		控制命令的制定:
		
		消息队列接收消息:
			msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
		解析buf中的数据:
			printf ("Get %ldL msg\n", msgbuf.msgtype);
			printf ("text[0] = %#x\n", msgbuf.text[0]);
		
		
		A9-ZIGBEE通用指令
		命令格式:一个字节,unsigned char 对应消息队列中正文的类型: 
							unsigned int 
		8位
		----------------------------------------
		7	6	|  5	4	|	3	2	1	0
		平台编号|  设备编号 |	操作设备
		----------------------------------------
		
		 0   0
		 0   1 
		 1   0
		 1   1
		 
		平台编号	
		0x00		0号-ZigBee平台 
		0x40		1号-A9/A53平台
		0x80		2号-STM32平台(可以自己扩展)
		0xc0		3号-avr arduino....保留(如果平台继续增多的话可以采用2个字节或多个字节来对设备进行
								唯一的编号,比如A9类下的1号平台,2号平台,先分类,然后再具体标识设备)
		
		----------------------------------------		
		设备编号		操作掩码	
		0x00	LED		0x00	全部关闭
						0x01	全部打开
						0x02	打开LED2
						0x03	打开LED3
						0X04	打开LED4
						0x05	打开LED5
						0X10	打开流水灯
		----------------------------------------
		0x10	蜂鸣器	0x00	关闭
						0x01	打开
						0x02	自动报警关闭
						0x03	自动报警打开
		----------------------------------------
		0x20	风扇	0x00	关闭风扇
						0x01	打开风扇
		----------------------------------------			
		0x30	数码管	0x0~0xF	    显示0~F数字(四盏灯,对应0000-表示0,0001-表示1....1110-表示14)
						0x0f		关闭数码管				led2-3-4-5
		----------------------------------------
		
		控制命令:		
			平台编号 + 设备编号 + 操作掩码 = 命令 (命令的封装)
			例如:
					0x00 + 0x20 + 0x01 = 0x21   风扇打开
 
					0x40 + 0x10 + 0x01 = 0x51   蜂鸣器打开
					0x40 + 0x30 + 0x08 = 0x78   数码管显示8
					0x40 + 0x30 + 0x0f = 0x7f   关闭数码管
					
					a 高位数据,b代表低位数据
					short  c
					unsigned char a ,b;
					c = a | b;
					c = a + b;
				
	上行:封装的结构体====共享内存和信号量 ===>交给CGI(C语言和HTML语言之间的转化接口)===>交给HTML
	下行:封装的命令字====消息队列 ====>msgbuf msgsnd===>控制命令字封装在msgsnd的msgbuf中 ===>A9端解析==>向下控制硬件







这是之前定义好的结构体,id和key值,一定要严格按照定好的来,不然就会造成无法通信的后果,再团队合作中有想法要在做前提,这样可以提前修改。

 

现在线程都启动成功了

 

CROSS_COMPILE=arm-linux-
CC=$(CROSS_COMPILE)gcc
CFLAGS= -c -g
#LDFLAGS= -lpthread -L ./lib -lsqlite3
LDFLAGS= -lpthread

OBJS=main.o data_global.o pthread_transfer.o \
     pthread_client_request.o pthread_buzzer.o pthread_led.o\
     pthread_sqlite.o \
     pthread_refresh.o pthread_sms.o

monitor_obj :$(OBJS)
    $(CC) -o $@ $^ $(LDFLAGS)
    mv *o ./obj
$(OBJS):%.o:%.c
    $(CC) $(CFLAGS) $< -o $@

install:
    sudo cp monitor_obj ~/nfs_rootfs/ 

.PHONY:clean
clean:
    rm *.o monitor_obj -rf 

上面是makefile的内容 

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

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

相关文章

Spark Standalone 部署

Spark Standalone 部署解压缩文件修改配置文件启动集群Web UI 界面提交应用提交参数说明配置历史服务配置日志存储路径添加日志配置重启重新执行任务查看历史服务配置高可用&#xff08;HA&#xff09;集群规划停止集群启动 Zookeeper启动集群关闭集群关闭历史服务解压缩文件 …

Go语言使用Playwright自动化测试、录屏、执行js

Go版本的Playwright支持Chromium、Firefox和WebKit的Web自动化测试&#xff0c;兼容Windows、Linux和MacOS&#xff0c;默认支持headless无头模式&#xff0c;安装方便、绿色高效、兼容性强、运行速度快。 支持的主要功能有&#xff1a; 跨多个页面、域名和iframe的场景&#x…

什么led灯性价比高?家用led灯选哪种最好

人造灯具经过多年的发展&#xff0c;现在最为成熟的工艺就是led灯了&#xff0c;不仅有荧光灯高效节能、省电高亮的特点&#xff0c;而且光线可控性非常高&#xff0c;对于调光、提高光线柔和度等方面非常方便&#xff0c;保护眼睛更有效。 那么什么led灯性价比高呢&#xff0c…

JavaScript 高级5 :ES6

JavaScript 高级5 &#xff1a;ES6 Date: January 19, 2023 Sum&#xff1a;ES6新增语法、ES6内置对象扩展&#xff08;Array、String扩展方法、set数据结构&#xff09; 目标 能够说出使用let关键字声明变量的特点 能够使用解构赋值从数组中提取值 能够说出箭头函数拥有的…

基于SpringBoot的学生会管理系统 源码

StudentUnionManagementSystem 基于SpringBoot的学生会管理系统 源码 链接 目录StudentUnionManagementSystem介绍软件架构使用说明1.页面登录2.首页3.成员信息管理4.角色信息管理5.权限管理6.活动管理7.文件管理8.活动展示介绍 学生会管理系统 SpringBoot Mybatis-plus shir…

CentOS 7 怎样设置自动连接网络

作为 Linux 中的重要一员&#xff0c;CentOS 7 始终把安全放在第一位&#xff0c;开机以后并不会自动启动网络。而且&#xff0c;相比 Windows 下只需点击几下鼠标便能搞定配置&#xff0c;在 CentOS 7 中要想设置开机自动连接网络&#xff0c;简直可以说是需要具有“专业级水准…

手动实现 数组和链表

数组和链表示意图 目的 不用java标准库 自己时间 一个 arraylist 和 linked list 区别 数组 数组 支持 随机访问 可以立即访问 根据 第一个元素的位置&#xff0c; 推算出 第三个地方的位置 如下图所示&#xff0c;假设我们知道 头的位置是X 数组是 int类型 每个位置就是 …

Qt音视频开发21-mpv内核万能属性机制

一、前言 搞过vlc内核后又顺带搞了搞mpv内核&#xff0c;mpv相比vlc&#xff0c;在文件数量、sdk开发便捷性方面绝对占优势的&#xff0c;单文件&#xff08;可能是静态编译&#xff09;&#xff0c;不像vlc带了一堆插件&#xff0c;通过各种属性来set和get值&#xff0c;后面…

第十四届蓝桥杯三月真题刷题训练——第 5 天

目录 题目1&#xff1a;数的分解 题目描述 运行限制 代码&#xff1a; 题目2&#xff1a;猜生日 题目描述 运行限制 代码&#xff1a; 题目3&#xff1a;成绩分析 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码&#xff1a; 题目4&#xff1a;最大和…

Vue3做出B站【bilibili】 Vue3+TypeScript【快速入门一篇文章精通系列(一)前端项目案例】

本项目分为二部分 1、后台管理系统&#xff08;用户管理&#xff0c;角色管理&#xff0c;视频管理等&#xff09; 2、客户端&#xff08;登录注册、发布视频&#xff09; Vue3做出B站【bilibili】 Vue3TypeScript【快速入门一篇文章精通系列&#xff08;一&#xff09;前端项目…

vue3 拖拽 穿梭框

文章目录期望结果当前技术栈实现方法安装 sortablejs导入 sortablejs视图 通过 id 绑定 sortablejs 数据通过 data-xxx 自定义属性 挂载ts中 通过id获取dom 实现拖拽 getNewArr函数通过自定义属性对数据做处理以下是全部代码官网链接下面是文档UsageOptionsgroup optionsort op…

代码随想录之哈希表(力扣题号)

242. 有效的字母异位词 直接用数组模拟哈希表 只有小写字母&#xff0c;开26的数组就可以了 class Solution {public boolean isAnagram(String s, String t) {//24-28int[] hash new int[26];Arrays.fill(hash,0);for(int i0;i<s.length();i){hash[s.charAt(i)-a];}for(i…

2023年3月全国数据治理工程师认证DAMA-CDGA/CDGP火热报名中...

弘博创新是DAMA中国授权的数据治理人才培养基地&#xff0c;贴合市场需求定制教学体系&#xff0c;采用行业资深名师授课&#xff0c;理论与实践案例相结合&#xff0c;快速全面提升个人/企业数据治理专业知识与实践经验&#xff0c;通过考试还能获得数据专业领域证书。 DAMA认…

【致敬女神】HTMLReport应用之Unittest+Python+Selenium+HTMLReport项目自动化测试实战

HTMLReport应用之UnittestPythonSeleniumHTMLReport项目自动化测试实战1 测试框架结构2 技术栈3 实现思路3.1 使用HtmlTestRunner3.2 使用HTMLReport4 TestRunner参数说明4.1 源码4.2 参数说明5 框架代码5.1 common/reportOut.py5.2 common/sendMain.py5.3 report5.3.1 xxx.htm…

ARM架构下使用Docker安装Nacos

大家好&#xff0c;我是中国码农摘星人。 欢迎分享/收藏/赞/在看&#xff01; 注意&#xff1a;以下内容仅适用于 ARM 架构&#xff0c;X86 及 AMD 架构理论类似&#xff0c;只需要修改配置即可。 构建 MySQL 8.x 镜像 MySQL 5.x 版本没有 ARM 架构的镜像 FROM mysql:8.0.32 A…

Java 8 排序

今天分享 Java 8 进行排序的 10 个姿势&#xff0c;其实就是把 Java 8 中的 Lambda、Stream、方法引用等知识点串起来 传统排序 现在有一个 List 集合&#xff1a; public static List<User> LIST new ArrayList() {{add(new User("Lisa", 23));add(new Us…

三维人脸实践:基于Face3D的渲染、生成与重构

face3d: Python tools for processing 3D face git code: https://github.com/yfeng95/face3d paper list: PaperWithCode 该方法广泛用于基于三维人脸关键点的人脸生成、属性检测&#xff08;如位姿、深度、PNCC等&#xff09;&#xff0c;能够快速实现人脸建模与渲染。推荐…

如何判断多账号是同一个人?用图技术搞定 ID Mapping

原文出处&#xff1a;https://discuss.nebula-graph.com.cn/t/topic/11873 本文是一个基于图数据库 NebulaGraph 上的图算法、图数据库、图神经网络的 ID-Mapping 方法综述&#xff0c;除了基本方法思想的介绍之外&#xff0c;我还给大家弄了可以跑的 Playground。 基于图数据…

浏览器:浏览器指纹

一、引子 场景一、绑定用户与浏览器&#xff08;设备&#xff09;&#xff0c;比如某一个网站的账号给到用户&#xff0c;用户只能在自己的电脑的某浏览器使用。 场景二、精准推送广告。 场景三、公司做营销活动&#xff0c;防止活动奖品被程序薅羊毛。 等等场景我们有什么…

Qt配置VS的编译环境(以MSVC2015 64bit为例)

目录 一、原因 二、VS2015安装 三、配置套件&#xff08;Kits&#xff09; 一、原因 很多时候&#xff0c;由于VS版本切换&#xff0c;需要从高版本切换到低版本&#xff0c;或者从低版本升级到高版本&#xff0c;例如VS2019到VS2015&#xff0c;或者VS2010到VS2015。 以VS2…