LSTM模型实现电力数据预测
关于深度实战社区
我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万+粉丝,拥有2篇国家级人工智能发明专利。
社区特色:深度实战算法创新
获取全部完整项目数据集、代码、视频教程,请进入官网:zzgcz.com。竞赛/论文/毕设项目辅导答疑,v:zzgcz_com
1. 项目简介
本项目 A020-LSTM电力预测 旨在通过使用深度学习模型来实现电力需求的预测。随着智能电网的发展和电力消耗的增加,预测电力需求对电力系统的优化管理和资源分配具有重要意义。本项目的核心任务是基于历史电力数据,应用 长短期记忆网络(LSTM) 来构建预测模型。LSTM 作为一种循环神经网络,擅长处理时间序列数据,并能够捕捉长期依赖关系,特别适合电力数据这种具有时序性的应用场景。
项目的数据预处理步骤包括:对数据进行标准化处理、填补缺失值,并生成用于训练的时间序列数据。模型的输入包括多个电力相关的特征,如 电压、全局有功功率、全局无功功率、全局电流强度,通过这些特征,模型可以对未来的电力消耗进行预测。此外,项目还包含故障检测模块,旨在通过预测值与实际值的偏差检测潜在的电缆故障。这不仅提升了模型的应用场景,也加强了其在电力系统中的实用性。



2.技术创新点摘要
数据预处理与特征工程:代码首先对原始电力数据进行了必要的预处理,包括填补缺失值和数值标准化。通过将数值列转化为浮点数并填充缺失数据,该模型能够更好地处理实际应用中不完整或不一致的数据集。使用了 MinMaxScaler 对数据进行归一化处理,这有助于提升深度学习模型的收敛速度和预测精度。
时间序列处理:模型使用了自定义的 create_sequences 函数来生成用于训练的时间序列数据。这个序列生成器不仅能够构建多步输入,还能通过从历史数据中提取固定长度的时间序列特征来提升模型捕捉长期依赖关系的能力。LSTM 模型特别擅长处理这种时序数据,能够从连续的时间片段中学习有用的模式,这一点对于电力负荷预测等具有时间依赖性的任务尤为关键。
LSTM 模型架构:在模型设计上,使用了多层 LSTM 网络(代码中设置了两层 LSTM),并引入了 50 维的隐藏层,这为模型提供了足够的表达能力来捕捉数据的复杂模式。多层 LSTM 结构有助于提取更高阶的特征,并提升模型对复杂时间序列数据的预测能力。通过对最后一个时间步的输出应用全连接层,该模型能够直接输出预测结果。
模型优化与训练:在训练过程中,模型采用了自适应学习率的 Adam 优化器,这种优化算法在梯度更新时表现出快速且稳定的收敛性能。损失函数选择了均方误差(MSE),适合回归问题,并且能够有效衡量模型的预测值与真实值之间的差异。此外,模型在每 10 个 epoch 中输出训练损失值,使得训练过程中的模型表现可见且易于监控。
3. 数据集与预处理
本项目所使用的数据集来源于历史电力消耗数据,数据集中的主要特征包括 全局有功功率(Global_active_power)、全局无功功率(Global_reactive_power)、电压(Voltage)、全局电流强度(Global_intensity) 以及子计量特征。该数据集涵盖了与电力负载预测相关的多个变量,反映了电力系统中的关键指标,特别适合用于时间序列预测模型。
在数据预处理阶段,首先对数据集进行了缺失值的处理。项目使用了均值填充的方法来替换缺失的数据,确保模型能够处理实际应用中常见的不完整数据问题。接着,对数据进行了类型转换,将数值列转化为浮点数格式,以便后续处理。此外,项目剔除了非数值型特征,专注于与电力预测相关的数值型特征。
在数据归一化方面,使用了 MinMaxScaler 对数据进行了标准化处理,将所有特征值缩放到 [0,1] 区间。这种归一化操作有助于消除特征值之间的量级差异,防止数值较大的特征对模型训练过程中的权重更新产生不均衡影响,从而提高模型的收敛速度和性能。
特征工程是数据预处理的重要环节。项目选择了 全局有功功率 作为预测目标变量,并基于其他特征生成了用于训练的时间序列数据。在序列构建时,项目通过自定义的 create_sequences 函数,将原始数据转换为固定长度的输入序列和对应的目标值。这一过程通过利用前 10 个时间步的数据预测下一个时间步的全局有功功率,体现了电力负荷的时序依赖特性。

4. 模型架构
1. 模型结构的逻辑
本项目采用 长短期记忆网络(LSTM,Long Short-Term Memory) 模型来进行电力预测,LSTM 模型擅长处理时间序列数据,能够捕捉长期和短期依赖关系。代码中实现了一个两层 LSTM 模型,具体的层次结构如下:
-
输入层:输入数据的形状为
(batch_size, seq_length, input_dim),其中input_dim = 4代表 4 个特征(全局有功功率、全局无功功率、电压和全局电流强度)。LSTM 接受输入序列并通过多个时间步处理每个特征值。 -
LSTM层: LSTM的核心是使用记忆细胞(Cell State)和门控机制(输入门、遗忘门、输出门)来控制信息的流动。每个时间步
t的 LSTM 计算可以用以下数学公式表示:- 遗忘门: f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f) ft=σ(Wf⋅[ht−1,xt]+bf)控制遗忘多少过去的信息。
- 输入门: i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i) it=σ(Wi⋅[ht−1,xt]+bi) C ~ t = tanh ( W C ⋅ [ h t − 1 , x t ] + b C ) \tilde{C}_t = \tanh(W_C \cdot [h_{t-1}, x_t] + b_C) C~t=tanh(WC⋅[ht−1,xt]+bC)决定更新多少新的信息。
- 记忆细胞更新: C t = f t ⋅ C t − 1 + i t ⋅ C ~ t C_t = f_t \cdot C_{t-1} + i_t \cdot \tilde{C}_t Ct=ft⋅Ct−1+it⋅C~t存储新的细胞状态。
- 输出门: o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o) ot=σ(Wo⋅[ht−1,xt]+bo)
- 最终输出: h t = o t ⋅ tanh ( C t ) h_t = o_t \cdot \tanh(C_t) ht=ot⋅tanh(Ct)
-
模型使用了 两层 LSTM,每一层 LSTM 都根据前一层的输出更新其隐状态。隐层维度
hidden_dim=50,LSTM 层的输出为(batch_size, seq_length, hidden_dim)。 -
全连接层(FC层) : LSTM 最后一层输出的隐状态
h_t经过一个全连接层,将维度从hidden_dim=50降到output_dim=1,得到模型的最终预测值(即全局有功功率的预测值)。数学公式为: y pred = W fc ⋅ h t + b fc y_{\text{pred}} = W_{\text{fc}} \cdot h_t + b_{\text{fc}} ypred=Wfc⋅ht+bfc
2. 模型的整体训练流程
-
数据准备:将历史电力数据分割为输入序列
X和目标输出y。这些数据通过DataLoader进行批次加载,以便进行小批量训练。 -
损失函数:使用 均方误差(MSE,Mean Squared Error) 作为损失函数,计算预测值和真实值之间的差异: MSE = 1 N ∑ i = 1 N ( y i − y i ^ ) 2 \text{MSE} = \frac{1}{N} \sum_{i=1}^{N} (y_i - \hat{y_i})^2 MSE=N1i=1∑N(yi−yi^)2 其中,yi是真实值,yi^是预测值,N 是样本数量。
-
优化器:使用 Adam 优化器 进行梯度更新。Adam 是一种基于动量的优化方法,它在每次更新时自适应地调整学习率,有助于更快地收敛。学习率设定为 0.001。
-
训练循环:模型在多个 epoch 上进行训练。在每个 epoch 中:
- 通过前向传播计算模型的预测值。
- 计算损失(MSE)。
- 反向传播更新模型的参数。
-
每 10 个 epoch,输出一次训练损失以监控模型的性能。
- 训练损失(MSE) :通过计算训练数据上的损失,来衡量模型在训练过程中表现出的误差。
- 故障检测评估:除了预测未来的电力需求外,模型还加入了简单的故障检测模块。通过设定一个阈值,比较预测的全局有功功率与实际值的差异。如果差异超出阈值,系统提示可能的电缆故障。这为模型提供了额外的实用性。
5. 核心代码详细讲解
1. create_sequence函数
函数 create_sequence 的作用是将时间序列数据转换成适合用于训练时间序列预测模型的数据格式,特别是用于循环神经网络(如 LSTM)的训练。
具体功能说明:
-
输入参数:
data:预处理并归一化后的特征数据,类型为 NumPy 数组,形状为(样本数, 特征数)。datetime_data:对应每个样本的时间戳,类型为 NumPy 数组。seq_length:序列长度,表示输入序列包含多少个连续的时间步。
-
处理过程:
-
初始化列表:
xs:用于存储输入序列的列表。yx:用于存储对应目标值的列表。datetimes:用于存储目标值对应时间戳的列表。
-
循环遍历数据:
-
循环索引
i从0到len(data) - seq_length,确保序列不越界。 -
构建输入序列
x:- 取从位置
i开始的长度为seq_length的数据片段,即data[i:i+seq_length]。 - 这个片段代表了模型的输入,包含了连续
seq_length个时间步的特征数据。
- 取从位置
-
提取目标值
y:- 目标值是位置
i+seq_length处的第一个特征,即data[i+seq_length][0]。 - 通常,这个值是我们希望模型预测的下一个时间步的目标变量。
- 目标值是位置
-
获取对应时间戳
dt:- 取位置
i+seq_length处的时间戳,即datetime_data[i+seq_length]。
- 取位置
-
添加到列表:
- 将输入序列
x添加到xs。 - 将目标值
y(作为列表[y])添加到yx。 - 将时间戳
dt添加到datetimes。
- 将输入序列
-
-
转换为 NumPy 数组并返回:
- 将
xs、yx、datetimes转换为 NumPy 数组,方便后续处理。
- 将
-
-
返回值:
xs:形状为(样本数, seq_length, 特征数)的输入序列数组。yx:形状为(样本数, 1)的目标值数组。datetimes:形状为(样本数,)的时间戳数组。
def create_sequence(data,datetime_data,seq_length):xs,yx,datetimes=[],[],[]for i in range(len(data)-seq_length):x=data[i:i+seq_length]y=data[i+seq_length][0]dt=datetime_data[i+seq_length]xs.append(x)yx.append([y])datetimes.append(dt)return np.array(xs),np.array(yx),np.array(datetimes)
让我们创建一个小的合成数据集,来说明函数的工作原理。
假设我们有以下时间序列数据:
- 特征(
data) :为了简单起见,我们使用一个特征。 - 日期时间(
datetime_data) :与每个数据点对应的日期时间值。
示例数据(为简单起见,使用单个特征)
data = np.array([[10], t=0[20], t=1[30], t=2[40], t=3[50], t=4[60], t=5[70], t=6
])对应的日期时间数据
datetime_data = np.array(['2020-01-01 00:00', t=0'2020-01-01 01:00', t=1'2020-01-01 02:00', t=2'2020-01-01 03:00', t=3'2020-01-01 04:00', t=4'2020-01-01 05:00', t=5'2020-01-01 06:00', t=6
])序列长度
seq_length = 3
让我们一步步执行该函数。
- 总数据点数:
len(data) = 7 - 序列长度:
seq_length = 3 - 生成的序列数量:
len(data) - seq_length = 4(索引从 0 到 3)
迭代 1( i = 0 ):
-
输入序列(
x) :data[0:3](索引 0 到 2)- 值:
[[10], [20], [30]]
-
目标值(
y) :data[0+3][0](索引 3,第一个特征)- 值:
40
-
日期时间(
dt) :datetime_data[0+3](索引 3)- 值:
'2020-01-01 03:00'
-
添加到列表:
xs.append([[10], [20], [30]])yx.append([40])datetimes.append('2020-01-01 03:00')
完成所有迭代后,我们得到:
- 输入序列(
xs) :
xs = np.array([[[10], [20], [30]], 序列 1[[20], [30], [40]], 序列 2[[30], [40], [50]], 序列 3[[40], [50], [60]], 序列 4
])
- 目标值(
yx) :
yx = np.array([[40], 序列 1 的目标[50], 序列 2 的目标[60], 序列 3 的目标[70], 序列 4 的目标
])
- 日期时间(
datetimes) :
datetimes = np.array(['2020-01-01 03:00', 目标 1 对应的时间'2020-01-01 04:00', 目标 2 对应的时间'2020-01-01 05:00', 目标 3 对应的时间'2020-01-01 06:00', 目标 4 对应的时间
])
xs:每个元素是长度为seq_length的时间步序列。例如,第一个序列是[[10], [20], [30]],代表时间步 t=0 到 t=2。yx:每个元素是对应输入序列的目标值。对于第一个序列,目标是[40],即时间步 t=3 的值。datetimes:每个元素是对应目标值的日期时间,对于第一个序列,是'2020-01-01 03:00',与目标值[40]对应。
6. 模型优缺点评价
6.1、模型优点:
传统的模型有:
自回归移动平均模型(ARMA) :
ARMA模型结合了自回归(AR)和移动平均(MA)成分,适用于平稳的时间序列数据。它通过分析过去的数据点来预测未来的电力需求。
自回归积分滑动平均模型(ARIMA) :
ARIMA模型扩展了ARMA,适用于非平稳时间序列。通过差分操作,使数据平稳后,再应用ARMA模型进行预测。这种方法在电力负荷预测中非常流行。
季节性自回归积分滑动平均模型(SARIMA) :
SARIMA是对ARIMA的扩展,适用于具有季节性特征的时间序列数据。电力需求通常具有明显的季节性,因此SARIMA常被用于电力预测。
指数平滑法(Exponential Smoothing) :
指数平滑法通过给最新的观察值更高的权重,对时间序列进行预测。常用的有简单指数平滑、霍尔特线性平滑和霍尔特-温特斯季节性平滑,适用于电力数据的趋势和季节性变化。
lstm的优势是:
- 处理长序列依赖性
优势:LSTM专门设计用于捕捉时间序列中的长短期依赖关系。传统模型在处理长序列时,通常面临梯度消失或爆炸的问题,导致模型无法有效学习到长期依赖。而LSTM通过其门控机制(输入门、遗忘门和输出门)有效管理信息流动,能够更好地记忆和遗忘重要的信息。
- 非线性建模能力
优势:LSTM可以通过其多层神经网络结构捕捉复杂的非线性关系。这使得LSTM在面对电力负荷预测等复杂问题时,能够比传统线性模型(如ARIMA)提供更好的拟合效果。
- 自动特征学习
优势:LSTM能够通过数据驱动的方法自动学习和提取特征,不需要手动进行特征工程。这意味着在处理数据时,可以减少人工干预,从而提高效率和适应性。
- 适应性强
优势:LSTM可以处理不同的输入数据类型和不同的时间间隔。例如,它可以处理缺失数据或不规则时间序列,而传统模型通常要求数据是均匀采样的。
6.2、模型缺点:
缺乏数据预处理和特征工程:
- 问题:简单地用平均值填充缺失值,可能会引入偏差,尤其是在时间序列数据中,缺失值的处理需要更加谨慎。
- 建议:对缺失值进行深入分析,考虑使用插值方法或基于时间的填充方法;同时,进行特征工程,提取更多有用的特征,如时间特征(小时、星期、季节)、滞后特征等。
未考虑时间序列的平稳性:
- 问题:未对时间序列进行平稳性检测和处理,LSTM可能难以学习非平稳序列的长期依赖。
- 建议:对数据进行差分、去趋势或去季节性处理,或考虑使用能够处理非平稳序列的模型。
缺少对非线性关系的处理:
- 问题:未探索特征与目标变量之间的非线性关系,可能影响模型性能。
- 建议:尝试添加非线性特征,或使用其他模型(如Transformer)捕捉复杂的非线性关系。
↓↓↓更多热门推荐:
SE-Net模型实现猴痘病识别
基于深度学习的手势控制模型
全部项目数据集、代码、教程进入官网zzgcz.com
相关文章:
LSTM模型实现电力数据预测
关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝,拥有2篇国家级人工智能发明专利。 社区特色&a…...
jmeter学习(7)beanshell
beanshell preprocessor 发送请求前执行 beanshell postprocessor 发送请求前执行 获取请求相关信息 String body sampler.getArguments().getArgument(0).getValue(); String url sampler.getPath(); 获取响应报文 String responseprev.getResponseDataAsString(); 获…...
TCP_SOCKET编程实现
文章目录 与UDP_SOCKET的区别第一代Tcp_ServerTcp_Client第二代Tcp_Server第三代Tcp_server多线程版本Tcp_Server线程池版的Tcp_Server使用inet_ntop来解决线程安全问题 业务逻辑编写总结补充说明&&业务代码完成ping的真实作用Translate编写Transform业务代码 整体总结…...
螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习07(基于docker容器的防火墙及NAT企业实战)
7.1 网络准备 7.2 网络规划 1)虚拟网络编辑器 点击右下方“更改设置”,点击“添加网络”假如vmnet3和vmnet4,然后分别选择vmnet3和vmnet4,设置为“仅主机模式”,按③处处理,去掉“使用DHCP”,…...
②EtherNet/IP转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关
EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 EtherNet/IP 转 Modbus TCP (接上一章) GW系列型号 配置使用 与 EtherNet/IP 主站进行组态说明 这里介…...
Java 集合(Collection)
1.什么是集合? 对象的容器,定义了对多个对象进行操作的常用方法,属于接口类型。 2.集合和数组的区别 (1)数组长度固定,集合长度不固定 (2)数组可以存储基本类型和引用类型&#…...
Windows系统编程(三)线程并发
进程与线程 进程:直观的说就是任务管理器中各种正在运行的程序。对于操作系统来说,进程仅仅是一个数据结构,并不会真实的执行代码 线程:通常被称作但并不真的是轻量级进程或实际工作中的进程,它会真实的执行代码。每…...
【Qt】控件概述(2)—— 按钮类控件
控件概述(2) 1. PushButton2. RadioButton——单选按钮2.1 使用2.2 区分信号 clicked,clicked(bool),pressed,released,toggled(bool)2.3 QButtonGroup分组 3. CheckBox——复选按钮 1. PushButton QPushB…...
Java访问器方法和更改器方法
一.访问器方法 1.访问器方法的定义和用途 访问器方法,通常也称为getter方法,是一种在面向对象编程中用于从类的外部访问私有字段值的特殊方法。这些方法的设计目的是为了提供对类内部状态的受限访问,同时保持类的封装性。通过使用访问器方法&…...
CAN协议帧结构
一、数据帧的整体结构 ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐ │ SOF │ ID[11]│ RTR │ IDE │ DLC │ Data …...
valgrind 单例模式的自动释放(多线程)
单例模式,其中对象是由_pInstance指针来保存的,而在使用单例设计模式的过程中,也难免会遇到内存泄漏的问题。那么是否有一个方法,可以让对象自动释放,而不需要程序员自己手动去释放呢? ——嵌套类 5.1、内…...
OpenFegin
文章目录 一、OpenFegin是什么?二、基本使用三、超时重试机制4.自定义超时重传机制五、底层实现 一、OpenFegin是什么? OpenFeign的全称为Spring Cloud OpenFeign(下文简称OpenFeign),是Spring Cloud团队开发的一款基于 Feign的框架,声明式W…...
LeetCode-2608. 图中的最短环【广度优先搜索 图,腾讯面试真题】
LeetCode-2608. 图中的最短环【广度优先搜索 图,腾讯面试真题】 题目描述:解题思路一:【一图秒懂】枚举起点跑 BFS解题思路二:背诵版解题思路三: 题目描述: 现有一个含 n 个顶点的 双向 图,每个…...
IDEA 编译报错 “java: 常量字符串过长” 的解决办法
目录 一、问题描述二、问题原因2.1 理论角度2.2 源码角度 三、解决方案解决方案①:StringBuilder 拼接解决方案②:读取文件内容 四、方案验证 在线文本换行工具: https://lzltool.cn/Toolkit/WrapWordsInText 一、问题描述 今天在开发过程中…...
RK3568平台开发系列讲解(I2C篇)I2C 总线实现 client 设备方法
🚀返回专栏总目录 文章目录 一、非设备树实现 i2c client1.1、i2c_new_device1.2、i2c client二、设备树实现 i2c2.1、i2c_client 结构体的生成2.2、i2c_driver 驱动2.2.1、module_i2c_driver2.2.2、fan53555_regulator_probe沉淀、分享、成长,让自己和他人都能有所收获!�…...
K8S安装和部署
环境部署说明 主机IPmaster172.25.254.100node10172.25.254.10node20172.25.254.20harbor172.25.254.233 所有节点禁用selinux和防火墙 所有节点同步时间和解析 所有节点安装docker-ce 所有节点禁用swap,注意注释掉/etc/fstab文件中的定义 解析配置(…...
Singleton(单例模式)
1. 意图 在开发中,若某些模块或功能只需要一个类实例,所有调用地方通过着一个类对象访问功能,单例模式符合这种类实例创建模式,并且通过提供统一类实例接口访问类对象。 2. 适用性 《Gof 设计模式-可复用面向对象软件的基础》中对…...
【Linux报错】“-bash: cd: too many arguments“
问题描述 今天使用 cd 想要调整某个文件目录时,发现以下报错 原因分析: arguments 是参数的意思,该报错提示参数过多,意味着系统识别到了多余参数 本质原因:你的命令中输入了多余的 ”空格“ ,检查一…...
C# WebService返回参数为DataTable报错“XML文档有错误”
该问题由于DataTable列存在自定义类型。 解决该报错需要以下几步: 1、自定义类型增加xml序列化 2、由于C#从 XML 反序列化 DataSet 或 DataTable 时的默认限制,所以需要先把调用方的项目开放限制,如果是.netframework项目,需要…...
[paddle]paddleseg快速开始
快速开始 为了让大家快速了解PaddleSeg,本文档使用一个简单示例进行演示。在实际业务中,建议大家根据实际情况进行调整适配。 在开始下面示例之前,请大家确保已经安装好PaddleSeg开发环境(安装说明)。 1 准备数据 …...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...
