【DBC专题】-10-CAN DBC转换C语言代码Demo_接收Rx报文篇

news2024/11/17 23:55:03

案例背景(共15页精讲):
该篇博文将告诉您,CAN DBC转换C语言代码Demo只需传递对应CAN信号关联参数,无需每个信号"左移"和"右移",并举例介绍:在CANoe/Canalyzer中CAPL中的应用:对接收报文,进行解包。其它场景的应用,也可参考该篇。

目录

1 背景:CAN信号在CAN 报文/Frame中位置的决定因素

2 讲解:CAN DBC转换C语言代码Demo

2.1 定义一些宏定义

2.2 定义一些结构体

2.3 API接口函数原型

2.4 对CANFD DBC的支持

2.5 如何使用该API接口

3 举例:在CANoe/Canalyzer中CAPL中的应用:对接收报文,进行解包

3.1 信号的字节顺序Byte Order: Intel小端模式

3.1.1 CAPL文件can的完整代码

3.1.2 系统变量定义

3.1.3 测试结果

3.2信号的字节顺序Byte Order: Motorola大端模式

3.2.1 CAPL文件can的完整代码

3.2.2 系统变量定义

3.2.3 测试结果

结尾


优质博文推荐阅读(单击下方链接,即可跳转):

Vector工具链

CAN Matrix DBC

CAN Matrix Arxml

1 背景:CAN信号在CAN 报文/Frame中位置的决定因素

一个CAN信号在CAN 报文/Frame中的位置,由3个条件决定,见图1-1:

  • 信号的起始位Startbit默认为信号的Lsb
  • 信号的长度Length
  • 信号的字节顺序Byte Order: Intel小端模式Motorola大端模式

详见博文“【DBC专题】-4-DBC文件中的Signal信号字节顺序Motorola和Intel介绍icon-default.png?t=N176https://blog.csdn.net/qfmzhu/article/details/111561710”,这里不再重复讲解。

下面我们根据这个背景,来设计一个通用算法,封装成一个函数,只需输入几个参数,即可得到对应的信号值。

图1-1

 

2 讲解:CAN DBC转换C语言代码Demo

2.1 定义一些宏定义

#define FRAME_TJW_ZERO_DLC  0   // unit:Byte
#define FRAME_TJW_MAX_DLC  8    // unit:Byte
#define SIGNAL_TJW_ZERO_LENGTH  0    // unit:Bit
#define SIGNAL_TJW_MAX_LENGTH  64    // unit:Bit
#define SIGNAL_TJW_INIT_VALUE  0
#define SIGNAL_TJW_INIT_MASK  0

#define SIGNAL_TJW_BYTE_ORDER_INTEL  0
#define SIGNAL_TJW_BYTE_ORDER_MOTOROLA  1

#define CAN_SIGNAL_TJW_NORMAL  0
#define CAN_SIGNAL_TJW_NO_VALUE  1
#define CAN_FRAME_TJW_DLC_OUT_OF_RANGE  2
#define INVALID_INPUT_PARAMETERS_TJW  3

/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/

2.2 定义一些结构体

typedef struct
{
   uint8 Signal_State;      // Describes the state of a signal
   uint64 Signal_Value;     // Describes the value of a signal
} Unpack_CAN_Signal;
/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/

2.3 API接口函数原型

/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/

Unpack_CAN_Signal Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex_Fun(
uint8* data_buff,          /**Byte array of CAN data field**/
uint8 signal_start_bit,    /**Rang:0~(FRAME_TJW_MAX_DLC * 8 - 1)**/
uint8 signal_length,       /**Rang:1~SIGNAL_TJW_MAX_LENGTH**/
boolean signal_byte_order, /**0:Intel;1:Motorola**/
uint8 frame_length)        /**Rang:1~FRAME_TJW_MAX_DLC**/
{
	Unpack_CAN_Signal can_signal;
	uint8 i = 0;
	uint8 byte_num = 0;
	uint8 low_data_byte = 0;
	uint8 high_data_byte = 0;
	uint8 low_data_byte_position = 0;
	uint8 high_data_byte_position = 0;
	uint8 remaining_bit_number = 0;
	uint8 remaining_byte_number = 0;	
	uint64 can_signal_mask = SIGNAL_TJW_INIT_MASK;
	
	can_signal.Signal_State = CAN_SIGNAL_TJW_NORMAL;
	can_signal.Signal_Value = SIGNAL_TJW_INIT_VALUE;
	
	if(frame_length == FRAME_TJW_ZERO_DLC)            /**DLC of CAN frame is 0**/
	{
		can_signal.Signal_State = CAN_SIGNAL_TJW_NO_VALUE;
	}
	else if(frame_length > FRAME_TJW_MAX_DLC)         /**DLC of CAN frame is out of range**/
	{
		can_signal.Signal_State = CAN_FRAME_TJW_DLC_OUT_OF_RANGE;
	}
	else if(
	        (signal_length > (frame_length * 8))         /**Invalid signal_length: The length of the signal is not in the range of DLC**/
	        || (signal_length > SIGNAL_TJW_MAX_LENGTH)          /**Invalid signal_length: The length of the signal exceeds the maximum Unsigned of C language**/
	        || (signal_length == SIGNAL_TJW_ZERO_LENGTH)        /**Invalid signal_length: The length of the signal is not equal to 0**/				
			)
	{
		can_signal.Signal_State = INVALID_INPUT_PARAMETERS_TJW;
	}
	else
	{		
		/**Byte Order: Intel**/
		if(signal_byte_order == SIGNAL_TJW_BYTE_ORDER_INTEL)  
		{
			/**Bytes used by CAN signal,Byte[0] is low byte,Byte[frame_length] is high byte**/
			low_data_byte = signal_start_bit / 8;
			high_data_byte = (signal_start_bit + signal_length - 1) / 8;  // 2 + 6 - 1 /8 = 0;  2 + 7 - 1 /8 = 1 ;  2 + 14 - 1 /8 = 1 ;  2 + 15 - 1 /8 = 2
			
			if((high_data_byte + 1) > frame_length)  /** CAN signal is not in the range of DLC**/
			{
				can_signal.Signal_State = CAN_FRAME_TJW_DLC_OUT_OF_RANGE;
			}
			else
			{
				for(i = 0;i < signal_length;i++)  /**Generate signal mask according to signal length**/
				{
					can_signal_mask |= 0x0000000000000001 << i;
				}
					
				low_data_byte_position = signal_start_bit % 8;  /**Distance from the lowest bit of each byte**/
				
				/**CAN Signal is in a bytes**/
				if(low_data_byte == high_data_byte) 
				{					
					can_signal.Signal_Value = (((uint64)data_buff[low_data_byte]) >> low_data_byte_position) & can_signal_mask;				
				}
				/**CAN Signal in multiple bytes**/
				else
				{					
					for(byte_num = low_data_byte;byte_num <= high_data_byte;byte_num++)
					{
						if(byte_num == low_data_byte)
						{
							can_signal.Signal_Value |= ((uint64)data_buff[low_data_byte]) >> low_data_byte_position;
						}
						else
						{
							can_signal.Signal_Value |= ((uint64)data_buff[byte_num]) << ((byte_num - low_data_byte - 1) * 8 + (8 - low_data_byte_position));
						}						
					}
					
					can_signal.Signal_Value = can_signal.Signal_Value & can_signal_mask;					
				}				
			}
		}
		/**Byte Order: Motorola**/
		else  /**signal_byte_order == SIGNAL_TJW_BYTE_ORDER_MOTOROLA**/
		{
			/**Bytes used by CAN signal,Byte[0] is low byte,Byte[frame_length] is high byte**/
			high_data_byte = signal_start_bit / 8;	
			
			if((high_data_byte + 1) > frame_length)        /** CAN signal is not in the range of DLC**/
			{
		    	can_signal.Signal_State = CAN_FRAME_TJW_DLC_OUT_OF_RANGE;
			}
			else
			{
				for(i = 0;i < signal_length;i++)  /**Generate signal mask according to signal length**/
				{
					can_signal_mask |= 0x0000000000000001 << i;
				}
				
				high_data_byte_position = signal_start_bit % 8;  /**Distance from the lowest bit of each byte**/
				
				/**CAN Signal is in a bytes**/
				if(signal_length <= (8 - high_data_byte_position))
				{				
					can_signal.Signal_Value = (((uint64)data_buff[high_data_byte]) >> high_data_byte_position) & can_signal_mask;					
				}
				/**CAN Signal in multiple bytes**/
				else
				{			
					remaining_bit_number = signal_length - (8 - high_data_byte_position); // 剩余bit = 12 - (8 - 2) = 6
					
					if((remaining_bit_number % 8) != 0)     
					{
						remaining_byte_number = remaining_bit_number / 8 + 1;          // remaining_byte_number = 1
					}
					else
					{
						remaining_byte_number = remaining_bit_number / 8;
					}

					for(byte_num = high_data_byte;byte_num >= (high_data_byte - remaining_byte_number);byte_num--)  // high_data_byte = 2  remaining_byte_number = 1
					{						
						if(byte_num == high_data_byte)
						{
							can_signal.Signal_Value |= ((uint64)data_buff[high_data_byte]) >> high_data_byte_position;
						}
						else
						{
							can_signal.Signal_Value |= ((uint64)data_buff[byte_num]) << ((high_data_byte - byte_num - 1) * 8 + (8 - high_data_byte_position));
						}		
						
						if(byte_num == 0)	
						{
							break;
						}						
					}
					can_signal.Signal_Value = can_signal.Signal_Value & can_signal_mask;									
				}			
			}				
		}
	}

	return can_signal;
}
/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/

2.4 对CANFD DBC的支持

只需将宏定义FRAME_TJW_MAX_DLC的值由8调整为64,即可适配CANFD DBC。

2.5 如何使用该API接口

1、提供的demo,使用了uint8,uint64,boolean类型,在将该代码集成至开发环境中,需要注意这些类型的替换:

  • typedef unsigned char               uint8
  • typedef unsigned long long           uint64

2、调用函数Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex_Fun时,需要确认传参data_buff,signal_start_bit,signal_length,signal_byte_order,frame_length的准确性,需与DBC保持一致,这样您可以得到对应信号的状态与值;

3 举例:在CANoe/Canalyzer中CAPL中的应用:对接收报文,进行解包

CAPL语法和C语言有一些差异,我们将第2.3章节中的demo稍作修改,以满足测需要。其它场景的应用与其类似。

3.1 信号的字节顺序Byte Order: Intel小端模式

3.1.1 CAPL文件can的完整代码

/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/
/*@!Encoding:936*/
includes
{
  
}

variables
{
	byte CAN_Data_Byte[8];

	byte Signal_State;
	word Signal_Value;
}

on message 0x100
{
	CAN_Data_Byte[0] = this.byte(0);
	CAN_Data_Byte[1] = this.byte(1);
	CAN_Data_Byte[2] = this.byte(2);
	CAN_Data_Byte[3] = this.byte(3);
	CAN_Data_Byte[4] = this.byte(4); 
	CAN_Data_Byte[5] = this.byte(5);  
	CAN_Data_Byte[6] = this.byte(6);
	CAN_Data_Byte[7] = this.byte(7);

	@sysvar::CAN_Frame::sysvar_Test_Signal_1 = Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(0,2,8);
	@sysvar::CAN_Frame::sysvar_Test_Signal_2 = Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(50,12,8);
	@sysvar::CAN_Frame::sysvar_Test_Signal_3 = Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(62,2,8);
}

word Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(
byte signal_start_bit,    /**Rang:0~(8 * 8 - 1)**/
byte signal_length,       /**Rang:1~64**/
byte frame_length)        /**Rang:1~8**/
{
	byte i = 0;
	byte byte_num = 0;
	byte low_data_byte = 0;
	byte high_data_byte = 0;
	byte low_data_byte_position = 0;
	byte high_data_byte_position = 0;
	byte remaining_bit_number = 0;
	byte remaining_byte_number = 0;	
	word can_signal_mask = 0;
	
	Signal_State = 0;
	Signal_Value = 0;
	
	if(frame_length == 0)            /**DLC of CAN frame is 0**/
	{
		Signal_State = 1;
	}
	else if(frame_length > 8)         /**DLC of CAN frame is out of range**/
	{
		Signal_State = 2;
	}
	else if(
	        (signal_length > (frame_length * 8))         /**Invalid signal_length: The length of the signal is not in the range of DLC**/
	        || (signal_length > 16)          /**Invalid signal_length: The length of the signal exceeds the maximum Unsigned of C language**/
	        || (signal_length == 0)        /**Invalid signal_length: The length of the signal is not equal to 0**/				
			)
	{
		Signal_State = 3;
	}
	else
	{
		/**Byte Order: Intel**/

		{
			/**Bytes used by CAN signal,Byte[0] is low byte,Byte[frame_length] is high byte**/
			low_data_byte = signal_start_bit / 8;
			high_data_byte = (signal_start_bit + signal_length - 1) / 8;  // 2 + 6 - 1 /8 = 0;  2 + 7 - 1 /8 = 1 ;  2 + 14 - 1 /8 = 1 ;  2 + 15 - 1 /8 = 2
			
			if((high_data_byte + 1) > frame_length)  /** CAN signal is not in the range of DLC**/
			{
				Signal_State = 2;
			}
			else
			{		
				for(i = 0;i < signal_length;i++)  /**Generate signal mask according to signal length**/
				{
					can_signal_mask |= 0x0000000000000001 << i;
				}
					
				low_data_byte_position = signal_start_bit % 8;  /**Distance from the lowest bit of each byte**/
				
				/**CAN Signal is in a bytes**/
				if(low_data_byte == high_data_byte) 
				{			
					Signal_Value = (((word)CAN_Data_Byte[low_data_byte]) >> low_data_byte_position) & can_signal_mask;				
				}
				/**CAN Signal in multiple bytes**/
				else
				{			
					for(byte_num = low_data_byte;byte_num <= high_data_byte;byte_num++)
					{				
						if(byte_num == low_data_byte)
						{		
							Signal_Value |= ((word)CAN_Data_Byte[low_data_byte]) >> low_data_byte_position;
						}
						else
						{			
							Signal_Value |= ((word)CAN_Data_Byte[byte_num]) << ((byte_num - low_data_byte - 1) * 8 + (8 - low_data_byte_position));
						}				
					}
					
					Signal_Value = Signal_Value & can_signal_mask;					
				}				
			}
		}

	}

	return Signal_Value;
}
/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/

3.1.2 系统变量定义

3.1.3 测试结果

使用的DBC:

CAN DBC中信号与系统变量的解析结果一致:

3.2信号的字节顺序Byte Order: Motorola大端模式

3.2.1 CAPL文件can的完整代码

/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/
/*@!Encoding:936*/
includes
{
  
}

variables
{
	byte CAN_Data_Byte[8];

	byte Signal_State;
	word Signal_Value;
}

on message 0x100
{
	CAN_Data_Byte[0] = this.byte(0);
	CAN_Data_Byte[1] = this.byte(1);
	CAN_Data_Byte[2] = this.byte(2);
	CAN_Data_Byte[3] = this.byte(3);
	CAN_Data_Byte[4] = this.byte(4); 
	CAN_Data_Byte[5] = this.byte(5);  
	CAN_Data_Byte[6] = this.byte(6);
	CAN_Data_Byte[7] = this.byte(7);  

	@sysvar::CAN_Frame::sysvar_Test_Signal_4 = Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(6,2,8);
	@sysvar::CAN_Frame::sysvar_Test_Signal_5 = Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(10,12,8);
	@sysvar::CAN_Frame::sysvar_Test_Signal_6 = Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(56,2,8);
}

word Rx_CAN_Frame_Data_Buff_to_CAN_Signal_Hex(
byte signal_start_bit,    /**Rang:0~(8 * 8 - 1)**/
byte signal_length,       /**Rang:1~64**/
byte frame_length)        /**Rang:1~8**/
{
	byte i = 0;
	byte byte_num = 0;
	byte low_data_byte = 0;
	byte high_data_byte = 0;
	byte low_data_byte_position = 0;
	byte high_data_byte_position = 0;
	byte remaining_bit_number = 0;
	byte remaining_byte_number = 0;	
	word can_signal_mask = 0;
	
	Signal_State = 0;
	Signal_Value = 0;
	
	if(frame_length == 0)            /**DLC of CAN frame is 0**/
	{
		Signal_State = 1;
	}
	else if(frame_length > 8)         /**DLC of CAN frame is out of range**/
	{
		Signal_State = 2;
	}
	else if(
	        (signal_length > (frame_length * 8))         /**Invalid signal_length: The length of the signal is not in the range of DLC**/
	        || (signal_length > 16)          /**Invalid signal_length: The length of the signal exceeds the maximum Unsigned of C language**/
	        || (signal_length == 0)        /**Invalid signal_length: The length of the signal is not equal to 0**/				
			)
	{
		Signal_State = 3;
	}
	else
	{

		/**Byte Order: Motorola**/

		{
			/**Bytes used by CAN signal,Byte[0] is low byte,Byte[frame_length] is high byte**/
			high_data_byte = signal_start_bit / 8;	
			
			if((high_data_byte + 1) > frame_length)        /** CAN signal is not in the range of DLC**/
			{
		    	Signal_State = 2;
			}
			else
			{
				for(i = 0;i < signal_length;i++)  /**Generate signal mask according to signal length**/
				{
					can_signal_mask |= 0x0000000000000001 << i;
				}
				
				high_data_byte_position = signal_start_bit % 8;  /**Distance from the lowest bit of each byte**/
				
				/**CAN Signal is in a bytes**/
				if(signal_length <= (8 - high_data_byte_position))
				{				
					Signal_Value = (((word)CAN_Data_Byte[high_data_byte]) >> high_data_byte_position) & can_signal_mask;					
				}
				/**CAN Signal in multiple bytes**/
				else
				{			
					remaining_bit_number = signal_length - (8 - high_data_byte_position); // 剩余bit = 12 - (8 - 2) = 6
					
					if((remaining_bit_number % 8) != 0)     
					{
						remaining_byte_number = remaining_bit_number / 8 + 1;          // remaining_byte_number = 1
					}
					else
					{
						remaining_byte_number = remaining_bit_number / 8;
					}

					for(byte_num = high_data_byte;byte_num >= (high_data_byte - remaining_byte_number);byte_num--)  // high_data_byte = 2  remaining_byte_number = 1
					{						
						if(byte_num == high_data_byte)
						{
							Signal_Value |= ((word)CAN_Data_Byte[high_data_byte]) >> high_data_byte_position;
						}
						else
						{
							Signal_Value |= ((word)CAN_Data_Byte[byte_num]) << ((high_data_byte - byte_num - 1) * 8 + (8 - high_data_byte_position));
						}		
						
						if(byte_num == 0)	
						{
							break;
						}						
					}
					Signal_Value = Signal_Value & can_signal_mask;									
				}			
			}				
		}
	}

	return Signal_Value;
}
/** 使用该Demo需注明出处,以表对作者的尊重 **/
/** 版权归CSDN博客“汽车电子助手”所有,https://blog.csdn.net/qfmzhu **/

3.2.2 系统变量定义

3.2.3 测试结果

使用的DBC

CAN DBC中信号与系统变量的解析结果一致:

结尾

获取更多“汽车电子资讯”和“工具链使用”,

请关注CSDN博客“汽车电子助手”,做您的好助手。

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

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

相关文章

【MIT 6.S081】Lab1: Xv6 and Unix utilities

Util概述sleeppingpongprimesfindxargs本Lab包括五个应用程序的实现&#xff0c;初步熟悉系统调用接口。用时约8h&#xff08;我太菜辣&#xff09;本Lab包括五个简单程序的实现&#xff0c;初步熟悉系统调用接口。 笔者用时约6h&#xff08;我太菜辣&#xff09; 概述 根据文…

mysql数据库之全局锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资源&#xff08;CPU、RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题&#x…

【Day2】Numpy简单入门基础

NumPy 简单入门基础 我的另一篇文章 &#xff1a; Numpy介绍-深度学习&#xff1a;Numpy介绍-深度学习&#xff08;Numpy介绍深度学习使用看这些足够了&#xff09; import numpy as npmy_array np.array([1, 2, 3, 4, 5]) print(my_array)[1 2 3 4 5]print(my_array.shape)…

Kafka 多线程消费者

Kafka 多线程消费者多线程方案Kafka 0.10.1.0 后&#xff0c;Kafka Consumer 变为双线程的设计 : 用户主线程 : 启动 Consumer 的 main心跳线程 (Heartbeat Thread) : 定期对 Broker 发送心跳请求&#xff0c;探测消费者的存活性 (liveness&#xff09;将心跳频率与主线程处理…

MQTT协议-取消订阅和取消订阅确认

MQTT协议-取消订阅和取消订阅确认 客户端向服务器取消订阅 取消订阅的前提是客户端已经通过CONNECT报文连接上服务器&#xff0c;并且订阅了一个主题 UNSUBSCRIBE—取消订阅 取消订阅的报文同样是由固定报头可变报头有效载荷组成 固定报头由两个字节组成&#xff0c;第一个…

2023年,当我们谈论架构时,我们要聊什么

架构是一个非常宽泛的话题&#xff0c;从组织结构上来说&#xff0c;涉及到前端、后端、运维&#xff1b;从软件设计上来说&#xff0c;涉及到需求分析、设计、编码、测试&#xff1b;从物理结构上来说&#xff0c;涉及到CDN、负载均衡、网关、服务器、数据库。当前一些架构方面…

奇淫技巧:阅读源码时基于一组快捷键,让我们知道身在何方!

一个十分蛋疼的问题 在我们阅读框架底层源码的时候&#xff0c;我们往往会一个方法一个方法的往下翻&#xff0c;翻了很久很快就会有这样的灵魂拷问&#xff1a;我从那个类&#xff08;方法&#xff09;来&#xff0c;我要到哪个&#xff08;类&#xff09;方法中去。这个时候…

RK3568平台开发系列讲解(显示篇) DRM显示系统组成分析

🚀返回专栏总目录 文章目录 一、DRM Framebuffer二、CRTC三、Planes四、Encoder五、Connector沉淀、分享、成长,让自己和他人都能有所收获!😄 📢让我们分析一下绿框中的五个部件,以及他们的联动。 一、DRM Framebuffer 与 framebuffer一样,是一片存放图像的内存区域,…

敏捷开发还需要PRD吗

一、PRD有什么用 prd提升与RD或者未来接手人的沟通效率 二、为什么会有PRD 首先来说说为什么会有PRD文档。 1、稍微大一点的团队产品经理未必能向每个人传达产品需求&#xff0c;这就需要有一个文档的形式来向项目的所有成员来传达需求&#xff0c;这就是文档的来源。 2、由…

Python读写mdb文件的实战代码

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…

MySQL的分库分表?通俗易懂

1- 为什么要分库分表 如果一个网站业务快速发展&#xff0c;那这个网站流量也会增加&#xff0c;数据的压力也会随之而来&#xff0c;比如电商系统来说双十一大促对订单数据压力很大&#xff0c;Tps十几万并发量&#xff0c;如果传统的架构&#xff08;一主多从&#xff09;&a…

【数据结构】解决顺序表题的基本方法

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;> 初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0…

java 4 (面向对象上)

java——面向对象&#xff08;上&#xff09; 目录java——面向对象&#xff08;上&#xff09;面向对象的思想概述类的成员&#xff08;1-2&#xff09;&#xff1a;属性和方法对象的内存解析类中属性的使用类中方法的使用1.举例&#xff1a;2.声明方法&#xff1a;3.说明4.re…

计算机网络基础知识点【1】

文章目录计算机网络第一章 计算机网络参考模型1.计算机网络为什么需要分层&#xff1f;1.1 分层思想1.2 分层好处2.OSI七层模型2.1 OSI七层模型总结2.2 OSI七层工作原理2.3 数据封装与解封装2.4 计算机网络常用协议3.TCP/IP参考模型3.1 什么是TCP/IP协议3.2 TCP/IP协议族的组成…

扬帆优配|引活水 增活力 促转型 创业板助力实体经济高质量发展

立异就是生产力&#xff0c;企业赖之以强&#xff0c;国家赖之以盛。全面注册制变革持续开释立异生机。日前&#xff0c;创业板公司已开端连续公布2022年度年度报告和2023年第一季度成绩预告&#xff0c;从频频传来的“喜报”中可窥见立异驱动开展战略下新兴工业的强劲开展态势…

jvm之堆上的GC和分代思想解读

堆上的GC JVM在进行GC时&#xff0c;并非每次都对上面三个内存区域一起回收的&#xff0c;大部分时候回收的都是指新生代。 性能调优主要就是减少GC&#xff0c;GC线程执行引发STW会让用户线程停止&#xff0c;阻碍了用户线程的执行&#xff0c;并且majorGC和fullGC阻碍的时间…

内卷把同事逼成了“扫地僧”,把Git上所有面试题整理成足足24W字Java八股文

互联网大厂更多的是看重学历还是技术&#xff1f;毫无疑问&#xff0c;是技术&#xff0c;技术水平相近的情况下&#xff0c;肯定学历高/好的会优先一点&#xff0c;这点大家肯定都理解。说实话&#xff0c;学弟学妹们找工作难&#xff0c;作为面试官招人也难呀&#xff01;&am…

TypeScript深度剖析:Vue项目中应用TypeScript?

一、前言 与link类似 在VUE项目中应用typescript&#xff0c;我们需要引入一个库vue-property-decorator&#xff0c; 其是基于vue-class-component库而来&#xff0c;这个库vue官方推出的一个支持使用class方式来开发vue单文件组件的库 主要的功能如下&#xff1a; metho…

【刷题笔记】之滑动窗口(长度最小的子数组、水果成篮、最小的覆盖子串)

滑动窗口模板//滑动窗口模板&#xff1a;注意使用滑动窗口方法&#xff0c;使用一个 for(while) 循环中的变量是用来控制终止位置的//最小滑窗&#xff1a;给定数组 nums&#xff0c;定义滑动窗口的左右边界 i、j&#xff0c;求满足某个条件的滑窗的最小长度 for(j 0; j < …

华为OD机试题,用 Java 解【寻找身高相近的小朋友】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…