RNN(循环神经网络)原理与结构
1 RNN(循环神经网络)原理与结构
循环神经网络(Recurrent Neural Network, RNN)是一类专门用于处理序列数据(如时间序列、文本、语音等)的深度学习模型。与传统的前馈神经网络不同,RNN在每个时间步都会将前一时刻的隐藏状态(hidden state)作为输入之一,从而能够保留和传递历史信息,捕捉序列内部的时间依赖关系。
1.1 基本计算流程
设输入序列长度为 T T T,每个时间步输入为 x t x_t xt,隐藏状态为 h t h_t ht,输出为 y t y_t yt。RNN 的核心更新公式为:
h t = f h ( W i h x t + W h h h t − 1 + b h ) , y t = f o ( W h o h t + b o ) , \begin{aligned} h_t &= f_h(W_{ih} x_t + W_{hh} h_{t-1} + b_h),\\ y_t &= f_o(W_{ho} h_t + b_o), \end{aligned} htyt=fh(Wihxt+Whhht−1+bh),=fo(Whoht+bo),
其中:
- W i h W_{ih} Wih 为输入到隐藏层的权重矩阵,维度为 H × I H \times I H×I;
- W h h W_{hh} Whh 为隐藏到隐藏的权重矩阵,维度为 H × H H \times H H×H;
- W h o W_{ho} Who 为隐藏到输出的权重矩阵,维度为 O × H O \times H O×H;
- b h b_h bh 与 b o b_o bo 分别为隐藏层和输出层的偏置项;
- f h f_h fh 与 f o f_o fo 分别为隐藏层与输出层的激活函数,常见选择包括 tanh、ReLU、softmax 等。
整个序列的前向计算可视为一个展开的多层网络:
- 初始化:通常将 h 0 h_0 h0 初始化为零向量。
- 时间步循环:从 t = 1 t=1 t=1 到 t = T t=T t=T,依次计算 h t h_t ht 与 y t y_t yt。
- 输出收集:根据任务需求,输出可以取最后一个时间步的 y T y_T yT(如分类、回归),也可以取全序列的 ( y 1 , y 2 , … , y T ) (y_1, y_2, \dots, y_T) (y1,y2,…,yT)(如序列标注)。
1.2 训练与反向传播
RNN 的训练基于梯度下降,需要通过“反向传播通过时间”(Backpropagation Through Time,BPTT)算法计算梯度:
- 损失函数:对全序列或部分时间步的输出计算损失,如均方误差(MSE)或交叉熵(Cross-Entropy)。
- 反向展开:将时间维度展开为深度网络,并在展开后的网络上进行反向传播,累积来自每个时间步的梯度。
- 梯度更新:按常规方式(SGD、Adam、RMSProp 等)更新参数。由于展开后的网络深度较大,可能出现梯度弥散或梯度爆炸问题。
1.3 长期依赖问题及改进
基础 RNN 在处理长序列时容易出现梯度消失或爆炸,导致模型难以捕捉远距离的依赖。为此,研究者提出了多种改进结构:
- LSTM(Long Short-Term Memory):引入了输入门、忘记门和输出门,通过门控机制控制信息流动,有效缓解长期依赖问题。
- GRU(Gated Recurrent Unit):将 LSTM 的输入门和遗忘门合并为重置门和更新门,结构更简洁,性能相当。
- 带门控的 RNN:在基础 RNN 上添加层归一化、残差连接或门控线性单元(GLU)等技巧,提升稳定性和收敛速度。
下面以 LSTM 单元为例,展示其核心计算:
f t = σ ( W f [ h t − 1 , x t ] + b f ) (遗忘门) i t = σ ( W i [ h t − 1 , x t ] + b i ) (输入门) o t = σ ( W o [ h t − 1 , x t ] + b o ) (输出门) c ~ t = tanh ( W c [ h t − 1 , x t ] + b c ) (候选细胞状态) c t = f t ⊙ c t − 1 + i t ⊙ c ~ t (更新细胞状态) h t = o t ⊙ tanh ( c t ) (输出隐藏状态) \begin{aligned} f_t &= \sigma(W_f [h_{t-1}, x_t] + b_f) \quad &\text{(遗忘门)}\\ i_t &= \sigma(W_i [h_{t-1}, x_t] + b_i) \quad &\text{(输入门)}\\ o_t &= \sigma(W_o [h_{t-1}, x_t] + b_o) \quad &\text{(输出门)}\\ \tilde{c}_t &= \tanh(W_c [h_{t-1}, x_t] + b_c) \quad &\text{(候选细胞状态)}\\ c_t &= f_t \odot c_{t-1} + i_t \odot \tilde{c}_t \quad &\text{(更新细胞状态)}\\ h_t &= o_t \odot \tanh(c_t) \quad &\text{(输出隐藏状态)} \end{aligned} ftitotc~tctht=σ(Wf[ht−1,xt]+bf)=σ(Wi[ht−1,xt]+bi)=σ(Wo[ht−1,xt]+bo)=tanh(Wc[ht−1,xt]+bc)=ft⊙ct−1+it⊙c~t=ot⊙tanh(ct)(遗忘门)(输入门)(输出门)(候选细胞状态)(更新细胞状态)(输出隐藏状态)
通过门控机制,LSTM 能够选择性地保留或忘记信息,使得模型在处理长序列时更加稳定。
2 序列到序列模型(Seq2Seq)
序列到序列(Sequence to Sequence, Seq2Seq)模型最早应用于机器翻译任务,其核心思想是:将一个可变长度的输入序列映射为另一个可变长度的输出序列。典型结构由编码器(Encoder)和解码器(Decoder)两部分组成:
- 编码器:逐步读取输入序列,将其压缩为一个固定长度的上下文向量(context vector)。
- 解码器:根据上下文向量,以自回归方式生成输出序列。
2.1 基本架构
- Encoder:一个多层 RNN(如 LSTM/GRU),从 t = 1 t=1 t=1 到 t = T i n t=T_{in} t=Tin 读取输入 x t x_t xt,并最终输出隐藏状态 h T i n h_{T_{in}} hTin(或多层的状态集合)。
- Context Vector:通常取编码器最后一个时间步的隐藏状态或其线性变换,作为定长向量 c c c。
- Decoder:另一个多层 RNN,初始状态由上下文向量 c c c(或映射后的初始隐藏状态)提供。解码器在每一时刻接收上一时刻生成的 y t − 1 y_{t-1} yt−1(训练时可使用真实标签,称为 Teacher Forcing),并输出当前时刻 y t y_t yt。
2.2 注意力机制(Attention)
固定长度的上下文向量在长序列或信息密集场景中可能成为瓶颈。注意力机制为解码器在每一步动态计算与编码器所有隐藏状态的加权和,从而获得更加丰富的上下文信息。核心计算:
e t , s = score ( h t − 1 d e c , h s e n c ) a l p h a t , s = exp ( e t , s ) ∑ s ′ = 1 T i n exp ( e t , s ′ ) c t = ∑ s = 1 T i n α t , s ⋅ h s e n c \begin{aligned} e_{t,s} &= \text{score}(h^{dec}_{t-1}, h^{enc}_s) \\ alpha_{t,s} &= \frac{\exp(e_{t,s})}{\sum_{s'=1}^{T_{in}} \exp(e_{t,s'})} \\ c_t &= \sum_{s=1}^{T_{in}} \alpha_{t,s} \cdot h^{enc}_s \end{aligned} et,salphat,sct=score(ht−1dec,hsenc)=∑s′=1Tinexp(et,s′)exp(et,s)=s=1∑Tinαt,s⋅hsenc
其中,score 函数可以是点积、可学习的前馈网络或双线性形式。最终,解码器将上下文向量 c t c_t ct 与自身隐藏状态拼接或融合后进行生成。注意力机制在机器翻译、文本摘要、图像描述等任务中大幅提升了性能。
3 实际案例:基于 Seq2Seq 的多步时间序列预测
下面通过一个端到端示例,演示如何使用 TensorFlow/Keras 构建并训练一个 Seq2Seq 模型,进行多步时间序列预测。示例目标:根据过去 48 小时传感器采集的温度数据,预测未来 24 小时的温度变化。
3.1 数据集与预处理
-
数据来源:假设 CSV 文件
sensor_temperature.csv
包含两列:timestamp
与temperature
。 -
时间索引:将
timestamp
转为 pandas 的 DatetimeIndex,按小时对齐。缺失值使用线性插值。 -
归一化:为了加快收敛并稳定训练,对温度序列做标准化:
x ′ = x − μ σ x' = \frac{x - \mu}{\sigma} x′=σx−μ
其中 μ , σ \mu, \sigma μ,σ 分别为训练集上的均值和标准差。 -
滑动窗口构建:定义输入长度 L i n = 48 L_{in}=48 Lin=48,输出长度 L o u t = 24 L_{out}=24 Lout=24。遍历序列,构造样本对:
X i = [ x i , x i + 1 , … , x i + L i n − 1 ] , Y i = [ x i + L i n , x i + L i n + 1 , … , x i + L i n + L o u t − 1 ] . X_i = [x_i, x_{i+1}, \dots, x_{i+L_{in}-1}],\\ Y_i = [x_{i+L_{in}}, x_{i+L_{in}+1}, \dots, x_{i+L_{in}+L_{out}-1}]. Xi=[xi,xi+1,…,xi+Lin−1],Yi=[xi+Lin,xi+Lin+1,…,xi+Lin+Lout−1].
-
数据拆分:按时间顺序将前 80% 样本作为训练集,后 20% 作为验证集。
import pandas as pd
import numpy as np# 读取与插值
df = pd.read_csv('sensor_temperature.csv', parse_dates=['timestamp'], index_col='timestamp')
df = df.resample('1H').mean().interpolate()# 提取序列并标准化
series = df['temperature'].values
mu, sigma = series.mean(), series.std()
series_norm = (series - mu) / sigma# 滑动窗口函数
def create_sequences(data, L_in, L_out):X, Y = [], []for i in range(len(data) - L_in - L_out + 1):X.append(data[i:i+L_in])Y.append(data[i+L_in:i+L_in+L_out])return np.array(X), np.array(Y)L_in, L_out = 48, 24
X, Y = create_sequences(series_norm, L_in, L_out)# 拆分训练/验证集
split = int(0.8 * len(X))
X_train, Y_train = X[:split], Y[:split]
X_val, Y_val = X[split:], Y[split:]
3.2 模型搭建
采用经典的编码器-解码器结构:
- 编码器:单层 LSTM,隐藏单元数 64。
- 解码器:RepeatVector 将上下文向量复制为输出序列长度,后接单层 LSTM(64 单元)与 TimeDistributed(Dense(1))。
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, LSTM, RepeatVector, TimeDistributed, Dense# 输入层
encoder_inputs = Input(shape=(L_in, 1), name='encoder_inputs')
# 编码器 LSTM
encoder_lstm, state_h, state_c = LSTM(64, return_state=True, name='encoder_lstm')(encoder_inputs)
encoder_states = [state_h, state_c]# 解码器输入:重复编码器输出
decoder_inputs = RepeatVector(L_out, name='repeat_vector')(state_h)
# 解码器 LSTM
decoder_lstm = LSTM(64, return_sequences=True, name='decoder_lstm')
decoder_outputs = decoder_lstm(decoder_inputs, initial_state=encoder_states)
# 时间分布的全连接层
decoder_dense = TimeDistributed(Dense(1), name='time_distributed')
decoder_outputs = decoder_dense(decoder_outputs)# 定义模型
model = Model(encoder_inputs, decoder_outputs)
model.compile(optimizer='adam', loss='mse')
model.summary()
3.2.1 超参数与训练策略
- 学习率:Adam 默认
lr=0.001
; - 批次大小:32;
- 训练轮次:50 次;
- EarlyStopping:监控验证集损失,
patience=5
,以防过拟合。
from tensorflow.keras.callbacks import EarlyStoppingcallbacks = [EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)]
history = model.fit(X_train[..., np.newaxis], Y_train[..., np.newaxis],validation_data=(X_val[..., np.newaxis], Y_val[..., np.newaxis]),epochs=50,batch_size=32,callbacks=callbacks
)
3.3 训练结果与评估
-
收敛曲线:绘制训练与验证损失随轮次变化曲线,以判断过拟合或欠拟合。
-
定量指标:采用均方根误差(RMSE)、平均绝对百分比误差(MAPE)评估预测性能:
RMSE = 1 N ∑ i = 1 N ( y ^ i − y i ) 2 , MAPE = 100 % N ∑ i = 1 N ∣ y ^ i − y i y i ∣ . \text{RMSE} = \sqrt{\frac{1}{N} \sum_{i=1}^N (\hat{y}_i - y_i)^2},\\ \text{MAPE} = \frac{100\%}{N} \sum_{i=1}^N \left|\frac{\hat{y}_i - y_i}{y_i}\right|. RMSE=N1i=1∑N(y^i−yi)2,MAPE=N100%i=1∑N yiy^i−yi .
-
可视化对比:随机选取若干样本,绘制真实值与预测值对比曲线。
import matplotlib.pyplot as plt# 收敛曲线
plt.figure(); plt.plot(history.history['loss'], label='train'); plt.plot(history.history['val_loss'], label='val'); plt.legend(); plt.title('Loss Curve')# 随机样本可视化
def plot_sample(idx):true = Y_val[idx]pred = model.predict(X_val[idx:idx+1])[0,...,0]plt.figure(); plt.plot(true, label='True'); plt.plot(pred, label='Pred'); plt.legend(); plt.title(f'Sample {idx} Prediction')plot_sample(0)
plot_sample(5)
3.4 性能优化与拓展
- 加入注意力机制:在解码器每一步对编码器隐藏状态加权。
- 双向编码器:使用双向 LSTM 捕捉过去和未来上下文。
- 多层堆叠:增加 LSTM 层数以提升表达能力。
- 混合模型:结合卷积神经网络(CNN)进行特征提取。
- 超参数搜索:使用网格搜索(Grid Search)或贝叶斯优化(Bayesian Optimization)寻找最佳超参数。
致谢
感谢阅读!如有疑问或建议,欢迎讨论。
相关文章:
RNN(循环神经网络)原理与结构
1 RNN(循环神经网络)原理与结构 循环神经网络(Recurrent Neural Network, RNN)是一类专门用于处理序列数据(如时间序列、文本、语音等)的深度学习模型。与传统的前馈神经网络不同,RNN在每个时间…...
Claude深度解析:从技术原理到实战应用的全栈指南
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言:AI编程新纪元中的Claude 在生成式AI技术爆发的2024年,Anthropic的Claude系列模型以卓越的长文本处理能力和精确的代码生成质量,正在重塑程序员的开发范式。当开发者…...
9.渐入佳境 -- 套接字的多种可选项
前言 套接字具有多种特性,这些特性可通过可选项更改。本章将介绍更改套接字可选项的方法,并以此为基础进一步观察套接字内部。 一、套接字可选项和I/O缓冲大小 我们进行套接字编程时往往只关注数据通信,而忽略了套接字具有的不同特性。但是…...
AI日报 - 2024年05月13日
🌟 今日概览 (60秒速览) ▎🚀 技术突破 | Flow-GRPO将在线RL引入流匹配模型,提升性能并降低训练成本;「层内循环」(ILR)技术无需增加参数即可提升Transformer性能。▎💬 行业热议 | ICML强制作者参会政策引发广泛争议…...
开发工具分享: Web前端编码常用的在线编译器
1.OneCompiler 工具网址:https://onecompiler.com/ OneCompiler支持60多种编程语言,在全球有超过1280万用户,让开发者可以轻易实现代码的编写、运行和共享。 OneCompiler的线上调试功能完全免费,对编程语言的覆盖也很全&#x…...
Android学习总结之线程池篇
一、线程池参数调优实战真题 真题 1:直播 APP 弹幕加载线程池设计 题目描述:直播 APP 需要实时加载弹幕数据(网络请求,IO 密集型),同时渲染弹幕视图(UI 操作需切主线程)࿰…...
03.Golang 切片(slice)源码分析(二、append实现)
Golang 切片(slice)源码分析(二、append实现) 前言: Golang 切片(slice)源码分析(一、定义与基础操作实现) 在前面的文章我们介绍了,切片的结构体与创建\扩容…...
Python实例题:pygame开发打飞机游戏
目录 Python实例题 题目 pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本 代码解释 初始化部分: 游戏主循环: 退出部分: 运行思路 注意事项 Python实例题 题目 pygame开发打飞机游戏 pygame-aircraft-game使用 Pygame 开发…...
MySQL创建了一个索引表,如何来验证这个索引表是否使用了呢?
MySQL创建了一个索引表,如何来验证这个索引表是否使用了呢? 1. 使用 EXPLAIN 分析查询执行计划 在 SQL 查询前添加 EXPLAIN 关键字,查看 MySQL 优化器是否选择了你的索引。 示例: EXPLAIN SELECT * FROM db关键输出字段: typ…...
Go语言多线程爬虫与代理IP反爬
有个朋友想用Go语言编写一个多线程爬虫,并且使用代理IP来应对反爬措施。多线程在Go中通常是通过goroutine实现的,所以应该使用goroutine来并发处理多个网页的抓取。然后,代理IP的话,可能需要一个代理池,从中随机选择代…...
Linux文件编程:操作流程与内核机制
在 Linux 操作系统中,一切皆文件,这意味着从硬盘上的数据文件、设备驱动、到管道、套接字等都以文件的形式存在。Linux 的文件系统将这些不同类型的文件统一抽象成文件对象,允许程序通过文件描述符来访问它们。 一、核心概念解析 文件描述符…...
用短说社区搭建的沉浸式生活方式分享平台
你是否想打造一个融合小红书式种草基因与论坛深度互动的全新社区?本文依托短说社区论坛系统的社区功能规划,一起来规划,如何搭建一个集内容分享、社交互动、消费决策于一体的沉浸式生活社区。 短说社区的界面样式支持普通资讯列表或瀑布流列…...
【ASR学习笔记】:语音识别领域基本术语
一、基础术语 ASR (Automatic Speech Recognition) 自动语音识别,把语音信号转换成文本的技术。 VAD (Voice Activity Detection) 语音活动检测,判断一段音频里哪里是说话,哪里是静音或噪音。 Acoustic Model(声学模型࿰…...
2025年best好用的3dsmax插件和脚本
copitor 可以从一个3dsmax场景里将物体直接复制到另一个场景中 Move to surface 这个插件可以将一些物体放到一个平面上 instancer 实体器,举例:场景中有若干独立的光源,不是实体对象,我们可以使用instancer将他变成实体。 paste …...
电厂除灰系统优化:时序数据库如何降低粉尘排放
在环保要求日益严苛的当下,电厂作为能源生产的重要主体,其除灰系统的运行效率与粉尘排放控制效果紧密相关。传统除灰系统在数据处理和排放控制方面存在一定局限性,而时序数据库凭借对时间序列数据的高效存储、处理和分析能力,为电…...
upload-labs通关笔记-第2关 文件上传之MIME绕过
目录 一、MIME字段 1. MIME 类型的作用 2. 常见的 MIME 类型 二、实验准备 1.构造脚本 2.打开靶场 3.源码分析 三、修改MIME字段渗透法 1.选择shell脚本 2.bp开启拦截 3.上传脚本bp拦包 4.bp改包 5.获取脚本地址 6.获取木马URL 7.hackbar渗透 8.蚁剑渗透 本文通…...
未来技术展望:光子量子计算集成与连续变量可视化
光子量子计算作为量子计算的重要分支,凭借其独特的光子传输优势和连续变量编码方式,正在量子计算领域掀起新的技术革命。以Xanadu公司的Borealis光量子处理器为代表,连续变量量子计算的可视化技术将面临全新的挑战与机遇。以下从技术适配、可视化方法及工具开发三个维度展开…...
vite项目使用i18n-ally未读取到文件
前言 在使用 Vue CLI 创建的Vue 3项目中,语言文件(src/lang/zh.js和en.js)正常加载。 .vscode/settings.json如下:i18n-ally.enabledParsers中增加了js {"i18n-ally.localesPaths": ["src/i18n","src/…...
yarn workspace使用指南
作用 Yarn workspace 是 Yarn 包管理工具中的一个功能,主要用于管理多包项目(monorepo)。它的主要作用如下: 支持多包结构:允许在一个仓库中管理多个独立的包或项目。项目间依赖管理:方便地在不同包之间添…...
Spring Boot 参数验证
一、依赖配置 首先确保在 pom.xml 中添加了以下依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency> 这个依赖包含了 Hibernate Valida…...
Electron学习大纲
Electron 实际工作学习大纲路线,结合技术原理、实战开发与工程化最佳实践,分为 5 大核心阶段,每个阶段包含关键知识点和实践目标,帮助快速掌握桌面应用开发能力: 阶段一:Electron 基础与环境搭建(1-2周) 核心概念与架构Electron 组成: 主进程(Main Process):控制应…...
Linux 系统中设置开机启动脚本
Linux 系统中设置开机启动脚本有多种方法,适用于不同的场景和需求。以下是几种最常用且详细的方法: 核心理念: 无论哪种方法,核心都是让系统在启动过程中的某个阶段执行你的脚本。 1. 使用 systemd (推荐,现代 Linux 发行版的标准) systemd 是目前大多数主流 Linux 发行…...
如何解决Deepseek服务器繁忙的问题?
在现如今互联网技术飞速发展的时代,AI技术也逐渐开始兴起,Deepseek作为一款强大的AI工具,可以帮助各个行业的用户高效的处理复杂任务,但是,用户在使用这一工具的过程中,可能会遇到服务器繁忙的问题…...
四、STM32 HAL库API完全指南:从功能分类到实战示例
STM32 HAL库API完全指南:从功能分类到实战示例 一、HAL库API的总体架构 STM32 HAL库(Hardware Abstraction Layer)作为STMicroelectronics推出的统一驱动框架,提供了覆盖所有STM32外设的标准化API。HAL库的API设计遵循严格的分层…...
集成学习——Bagging,Boosting
一.什么是集成学习 集成学习的基本思想是通过结合多个基学习器的预测结果,来提高模型的泛化能力和稳定性。这些基学习器可以是相同类型的算法,也可以是不同类型的算法。 当基学习器之间具有一定的差异性时,它们在面对不同的样本子集或特征子…...
如何有效追踪需求的实现情况
有效追踪需求实现情况,需要清晰的需求定义、高效的需求跟踪工具、持续的沟通反馈机制,其中高效的需求跟踪工具尤为关键。 使用需求跟踪工具能确保需求实现进度可视化、提高团队协作效率,并帮助识别和管理潜在风险。例如,使用专业的…...
网页Web端无人机直播RTSP视频流,无需服务器转码,延迟300毫秒
随着无人机技术的飞速发展,全球无人机直播应用市场也快速扩张,从农业植保巡检到应急救援指挥,从大型活动直播到智慧城市安防,实时视频传输已成为刚需。预计到2025年,全球将有超过1000万架商用无人机搭载直播功能&#…...
基于SpringBoot的蜗牛兼职网设计与实现|源码+数据库+开发说明文档
一、项目简介 蜗牛兼职网是一个集职位信息发布、用户申请、企业管理、后台运维于一体的校园类兼职招聘平台,使用 SpringBoot 作为后端核心框架,搭配 Layui Bootstrap 实现前端页面开发,前后端结合,功能齐全。 系统共分为 三种角…...
kafka消费组
Kafka【二】关于消费者组(Consumer Group)、分区(partition)和副本(replica)的理解_consumergroup-CSDN博客 定义: 消费者组是一组可以协同工作的消费者实例的集合。 每个消费者都属于一个特定…...
每日一题洛谷P8662 [蓝桥杯 2018 省 AB] 全球变暖c++
P8662 [蓝桥杯 2018 省 AB] 全球变暖 - 洛谷 (luogu.com.cn) DFS #include<iostream> using namespace std; char a[1001][1001]; bool s[1001][1001]; int res 0; int n; bool flag true; int dx[4] { -1,0,1,0 }; int dy[4] { 0,-1,0,1 }; void dfs(int x, int y)…...
2025年Energy SCI1区TOP,改进雪消融优化算法ISAO+电池健康状态估计,深度解析+性能实测
目录 1.摘要2.雪消融优化算SAO原理3.改进策略4.结果展示5.参考文献6.代码获取7.读者交流 1.摘要 锂离子电池(LIBs)的健康状态(SOH)估计对于电池健康管理系统至关重要,为了准确估计LIBs的健康状态,本文提出…...
docker使用过程中遇到概念问题
容器和虚拟机的区别 容器共享主机内核;虚拟机占用主机内核硬件容器的启动速度是秒级别;虚拟机的启动速度是分钟级别容器资源占用低,性能接近原生;虚拟机资源占用高,性能有一定的损耗容器是进程级别的隔离;…...
leetcode-hot-100(双指针)
1. 移动零 题目链接:移动 0 题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 解答 类似于签到题&#x…...
力扣HOT100之二叉树:101. 对称二叉树
这道题我本来想着挑战一下自己,尝试着用迭代的方法来做,然后就是用层序遍历,将每一层的元素收集到一个临时的一维向量中,然后再逐层判断每一层是否都是轴对称的,一旦发现某一层不是轴对称的,就直接return f…...
深入解读tcpdump:原理、数据结构与操作手册
一、tcpdump 核心原理 tcpdump 是基于 libpcap 库实现的网络数据包捕获与分析工具,其工作原理可分解为以下层次: 数据包捕获机制 底层依赖:通过操作系统的 数据链路层接口(如 Linux 的 PF_PACKET 套接字或 AF_PACKET 类型&#x…...
HTML5 中实现盒子水平垂直居中的方法
在 HTML5 中,有几种方法可以让一个定位的盒子在父容器中水平垂直居中。以下是几种常用的方法: 使用 Flexbox 布局 <div class"parent"><div class"child">居中内容</div> </div><style>.parent {di…...
个人博客系统测试报告
目录 1 项目背景 2 项目功能 3 项目测试 3.1 测试用例 3.2 登录页面测试 3.3 博客列表页面测试 3.4 博客详情页面测试 3.5 自动化测试 3.5.1 Utils类 3.5.2 登录测试页面类 3.5.3 博客列表页测试类 3.5.4 博客详情页测试类 3.5.5 博客修改页测试类 3.5.6 未登录…...
适配WIN7的最高版本Chrome谷歌浏览器109版本下载
本仓库提供了一个适用于Windows 操作系统的谷歌浏览器109版本的离线安装包。 点击下面链接下载 WIN7的最高版本Chrome谷歌浏览器109版本下载...
从规划到完善,原型标注图全流程设计
一、原型标注图:设计到开发的精准翻译器 1. 设计意图的精准传递 消除模糊性:将设计师的视觉、交互逻辑转化为可量化的数据(尺寸、颜色、动效参数),避免开发“凭感觉还原”。 统一理解标准:通过标注建立团…...
极狐GitLab 通用软件包存储库功能介绍
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 极狐GitLab 通用软件包存储库 (BASIC ALL) 在项目的软件包库中发布通用文件,如发布二进制文件。然后,…...
系统架构-嵌入式系统架构
原理与特征 嵌入式系统的典型架构可概括为两种模式,即层次化模式架构和递归模式架构 层次化模式架构,位于高层的抽象概念与低层的更加具体的概念之间存在着依赖关系,封闭型层次架构指的是,高层的对象只能调用同一层或下一层对象…...
hive两个表不同数据类型字段关联引发的数据倾斜
不同数据类型引发的Hive数据倾斜解决方案 #### 一、原因分析 当两个表的关联字段存在数据类型不一致时(如int vs string、bigint vs decimal),Hive会触发隐式类型转换引发以下问题: Key值的精度损失:若关联字…...
制作一款打飞机游戏45:简单攻击
粒子系统修复 首先,我们要加载cow(可能是某个项目或资源),然后直接处理粒子系统。你们看到在粒子系统中,我们仍然有X滚动。这现在已经没什么意义了,因为我们正在使用一个奇怪的新系统。所以我们实际上不再…...
《Vuejs设计与实现》第 5 章(非原始值响应式方案) 中
目录 5.4 合理触发响应 5.5 浅响应与深响应 5.6 只读和浅只读 5.4 合理触发响应 为了合理触发响应,我们需要处理一些问题。 首先,当值没有变化时,我们不应该触发响应: const obj = { foo: 1 } const p = new Proxy(obj, { /* ... */ })effect(() => {console.log(p…...
深入理解 Webpack 核心机制与编译流程
🤖 作者简介:水煮白菜王,一位前端劝退师 👻 👀 文章专栏: 前端专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧和知识归纳总结✍。 感谢支持💕💕&#…...
okhttp3.Interceptor简介-笔记
1. Interceptor 简介 okhttp3.Interceptor 是 OkHttp 提供的一个核心接口,用于拦截 HTTP 请求和响应,允许开发者在请求发送前和响应接收后插入自定义逻辑。它在构建灵活、可扩展的网络请求逻辑中扮演着重要角色。常见的用途包括: 添加请求头…...
交易流水表的分库分表设计
交易流水表的分库分表设计需要结合业务特点、数据增长趋势和查询模式,以下是常见的分库分表策略及实施建议: 一、分库分表核心目标 解决性能瓶颈:应对高并发写入和查询压力。数据均衡分布:避免单库/单表数据倾斜。简化运维&#…...
《AI大模型应知应会100篇》第59篇:Flowise:无代码搭建大模型应用
第59篇:Flowise:无代码搭建大模型应用 摘要:本文将详细探讨 Flowise 无代码平台的核心特性、使用方法和最佳实践,提供从安装到部署的全流程指南,帮助开发者和非技术用户快速构建复杂的大模型应用。文章结合实战案例与配…...
开发环境(Development Environment)
在软件开发与部署过程中,通常会划分 开发环境(Development)、测试环境(Testing)、生产环境(Production) 这三个核心环境,以确保代码在不同阶段的质量和稳定性。以下是它们的详细介绍…...
MySQL的sql_mode详解:从优雅草分发平台故障谈数据库模式配置-优雅草卓伊凡
MySQL的sql_mode详解:从优雅草分发平台故障谈数据库模式配置-优雅草卓伊凡 引言:优雅草分发平台的故障与解决 近日,优雅草分发平台(youyacaocn)在运行过程中遭遇了一次数据库访问故障。在排查过程中,技术…...