锂电池寿命预测实战:基于LSTM与RNN的时间序列建模与PyTorch实现
简介一套基于RNN与LSTM的锂电池寿命预测项目源码主要面向机器学习学习者、电池管理系统开发者及能源领域研究人员可用于电池健康状态评估与剩余使用寿命RUL预测研究。项目使用CALCE数据集包含电流、电压、温度等关键特征的清洗、缺失值处理、归一化与序列建模流程模型部分同时提供RNN和LSTM实现LSTM通过门控机制缓解长期依赖问题便于对比两种网络对电池退化趋势的拟合效果。压缩包共234个文件以212个xlsx格式的CALCE数据文件为主体辅以8个Jupyter Notebook示例程序、3个Python工具脚本、3份Markdown说明文档和结果可视化PNG图整体大小约461.28MB。已有395人学习下载。项目说明与建模过程完整覆盖从数据预处理、特征提取、模型训练与验证到预测结果可视化的各环节代码带注释目录按数据、脚本和说明组织适合希望快速复现实验并将其迁移到其他时间序列预测任务的读者。1. 锂电池寿命预测这条开发路径为什么值得把 RNN 和 LSTM 放进你的工具箱锂电池寿命预测在实际项目中不是一个炫技需求而是实打实的运营问题储能电站要决定什么时候把电池从并网状态切下来电动车售后要判断电池是否该进入梯次利用BMS 算法岗则希望提前知道 SOH 降到 80% 的剩余循环数。这个标题里出现的 RNN、LSTM、CALCE 数据集、python 源码和预测结果可视化拼起来恰好是一条能落地的开发链路——先拿公开数据把时间序列模型跑通再迁移到自己的电池数据上做剩余寿命RUL预测。适合做这件事的人很具体刚接手电池数据分析的维护工程师、做 BMS 算法的同行以及拿这个题目当课程设计或毕业设计的同学。你不用先把电化学机理吃透只需要把 CALCE 数据集里的充放电循环处理成规整序列喂给 LSTM 模型最后输出一条容量衰减曲线和 RUL 估计。这篇文章就把这条链路拆开讲数据怎么切、网络怎么搭、预测结果怎么看、哪些坑会让你白跑一星期。2. 为什么是 RNN 与 LSTM 而不是普通回归锂电池退化数据藏着的时序特性2.1 老化曲线的三个特征决定了不能只做特征工程把锂电池容量衰减画出来前一两百个循环是一段带波动的平台之后在某个“膝盖点”突然加速下跌。这种形状对基于单点特征的回归模型很不友好同一个容量值在早期和晚期对应的剩余寿命完全不同线性外推几乎必然翻车。传统做法是构造特征比如循环数、平均温度、内阻变化率再用 SVM 或随机森林拟合但特征和寿命之间的映射高度非线性更何况温度、放电倍率带来的噪声会让曲线出现台阶和毛刺。RNN循环神经网络的价值在于把“一段历史”作为输入而不是只看当前值。给模型喂最近 30 个循环的容量和温度序列它去学习下一步容量等于隐式建模了局部退化斜率。对电池这种非平稳过程序列上下文比单点特征信息量大得多。问题在于普通 RNN 学长序列时梯度消失很严重所以工程上通常直接上 LSTM这也是这个项目标题把 RNN 和 LSTM 并列的原因——RNN 是基础LSTM 是稳定能用的版本。2.2 LSTM 门控机制在寿命预测里的实际价值LSTM 的 cell state细胞状态是一条贯穿时间步的“传送带”遗忘门、输入门、输出门各自决定丢弃什么历史信息、写入什么新信息、输出什么内容。放到电池退化场景里理解前 100 个循环记录的容量平台特征其实很关键普通 RNN 早把它冲掉了LSTM 还能记住“这块电池早期平台期的容量水平”等预测接近阈值时再结合当前加速度输出。用 PyTorch 构造一个 LSTM 层参数语义如下import torch.nn as nn model nn.LSTM( input_sizefeat_dim, # 每个时间步的特征数比如 [容量, 温度, 内阻] 就是 3 hidden_size32, # 隐状态维度电池数据量小32 足够了别一上来就 128 num_layers2, # 两层 LSTM层数越多越容易过拟合 batch_firstTrue, # 输入形状 (batch, seq_len, features)更符合直觉 dropout0.2 # 两层之间才生效单层 LSTM 会忽略这个参数 )hidden_size是最值得调的一个值。电池循环数据通常只有几百到一千多条窗口滑出来的样本量也就在几千这个量级隐状态设 64 就已经偏大再往上就进入“训练损失下降但验证损失飘”的过拟合区间。num_layers2是起步值3 层以上对数据量要求很高我一般不推荐在寿命预测里做深网络。把常见序列模型放到电池场景里对比选型结论很直接模型参数量长序列记忆能力电池寿命预测建议普通 RNN小弱梯度消失明显序列短于 50 步时可尝试LSTM较大强主力选择稳定GRU适中较强边缘部署或轻量场景BiLSTM大强但引入未来信息离线预测可用在线滚动预测慎用BiLSTM 要特别说明寿命预测的滚动推理是对未来一步步外推双向结构在训练时看到了未来信息部署时又没有未来数据可用这种错位会让 RUL 结果虚高。除非做离线批量诊断否则优先单向 LSTM。3. 处理 CALCE 数据集从原始循环数据到 LSTM 训练样本的切分逻辑3.1 CALCE 数据集的常见字段和读取方式CALCE 是美国马里兰大学先进寿命周期工程中心公开的锂电池测试数据项目标题里的“CALCE 数据集”就是干这个用的。下载解压后每个文件对应一块电池的循环测试记录不同电池型号的列名不完全一致但核心信息基本是这几类循环序号、放电容量、平均温度、内阻、充电时间、放电时间。先把数据读进来看一眼比凭空猜字段靠谱import pandas as pd df pd.read_csv(calce_battery.csv, encodingutf-8) print(df.columns.tolist()) print(df.head())真实文件的表头往往带着厂商命名习惯比如capacity_ah、cycle_index、avg_temp_c你需要把它们映射到统一的内部字段。我一般直接在读取后做一次重命名df df.rename(columns{ cycle: cycle_index, Capacity: capacity, Temp: temp, IR: internal_resistance })映射后的核心字段用途如下表字段含义在训练中的作用cycle_index循环序号时间轴决定序列顺序capacity放电容量目标变量预测容量衰减temp循环平均温度特征温度加速老化internal_resistance内阻特征老化后期明显抬升discharge_time放电时长可选的倍率特征数据处理这一步在项目里通常比模型训练更耗时因为测试台偶尔会中断、某个循环没有完整记录、容量曲线里混着噪声毛刺这些都会直接影响 LSTM 能不能学到真实退化趋势。3.2 清洗三步去重、毛刺、缺失值一个完整充放电循环包含充电、静置、放电三个阶段放电容量在日志里可能重复出现第一步是按循环序号聚合并取有效观测。常见做法是每个循环保留放电容量的最大值因为放电初段的电压跳动会产生异常小值# 每个循环只保留一条容量记录用最大值对抗初段电压噪声 df_clean df.groupby(cycle_index).agg({ capacity: max, temp: mean, internal_resistance: mean, discharge_time: max }).reset_index()第二步是处理毛刺。测试台重启或温度传感器抖动会产生瞬间下跌的容量值这种点会让 LSTM 误以为是老化加速。用滚动中位数把突变拉回正常带# 窗口 5把单点毛刺拉回局部中位数水平 df_clean[capacity] df_clean[capacity].rolling(5, centerTrue, min_periods1).median()滚动窗口大小不要设太大电池容量本来就是缓变信号窗口太大反而把真实的膝盖拐点磨平了。第三步看缺失循环有些电池文件会跳过若干循环号直接重排成 0..N-1 连续索引避免 LSTM 把间隔误解为时间步长df_clean df_clean.reset_index(dropTrue) df_clean df_clean.dropna(subset[capacity])缺失值处理上我倾向直接丢弃而不是前向填充因为连续缺失超过 5 个循环时填充出来的线段是假的模型学到的是“这条曲线会平着走”很危险。3.3 滑窗、归一化与按电池划分LSTM 吃的是“过去 seq_len 步预测下一步”的样本对。假设 seq_len30那么第 31 个循环的容量由前 30 个循环的特征序列来预测。生成训练样本的代码如下import numpy as np def make_windows(data, seq_len30): xs, ys [], [] for i in range(len(data) - seq_len): x data[i : i seq_len] # 前 seq_len 步特征 y data[i seq_len, 0] # 下一步容量第 0 列是容量 xs.append(x) ys.append(y) return np.array(xs, dtypenp.float32), np.array(ys, dtypenp.float32) feat_cols [capacity, temp, internal_resistance] # 假设 train_df 是训练电池的数据先归一化再滑窗 from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler() train_scaled scaler.fit_transform(train_df[feat_cols].values) X_train, y_train make_windows(train_scaled, seq_len30)归一化这里有一个容易忽略的细节scaler只允许在训练电池上fit测试电池的数据必须用同一个scaler.transform不能重新 fit。如果测试电池也参与 fit相当于模型在训练阶段提前知道了测试集的数值分布这在小数据集上会让指标好看 30% 以上但真实部署时会原形毕露。这个坑后面专门展开说。窗口长度 30 不是拍脑袋。对按天循环的电池30 个循环大概相当于一个月的老化过程足以覆盖一个温度扰动周期。窗口太短模型只能看到局部抖动窗口太长则样本量急剧减少。数据量小时可以设置 20~30 之间数据充足再尝试 50。另外注意点测试数据切分不要随机打乱必须按电池隔离。常见的错误是全部电池混在一起随机分训练验证然后验证集里出现了训练集同一块电池的相邻窗口这种“邻居样本”会让验证损失虚低跨电池部署时立刻露馅。正确的做法是拿 A、B 两块电池完整数据做训练留 C 电池做测试。4. 用 PyTorch 实现锂电池寿命预测源码的 LSTM 模型训练、保存与滚动推理4.1 定义 LSTM 回归模型网络结构并不复杂一层或两层LSTM 负责提取序列特征全连接层把最后一个时间步的隐状态映射成容量值。输出层只有一个神经元因为我们要回归的是一个连续容量数值。一个可以直接跑的模型定义如下import torch import torch.nn as nn class LSTMRegressor(nn.Module): def __init__(self, feat_dim, hidden_size32, num_layers2, dropout0.2): super().__init__() self.lstm nn.LSTM( input_sizefeat_dim, hidden_sizehidden_size, num_layersnum_layers, batch_firstTrue, dropoutdropout ) self.fc nn.Sequential( nn.Linear(hidden_size, 16), nn.ReLU(), nn.Linear(16, 1) ) def forward(self, x): out, _ self.lstm(x) # out.shape (batch, seq_len, hidden_size) last out[:, -1, :] # 取最后一个循环的输出 return self.fc(last) # 输出预测容量shape (batch, 1)这里为什么取out[:, -1, :]而不是把所有时间步输出都用到因为我们的任务是对“下一个循环”做单点预测最后一个隐状态已经融合了整个窗口的信息。如果做的是容量曲线整段重建才需要每个时间步都输出。全连接层中间加了一层 16 维的 ReLU不要直接一步nn.Linear(hidden_size, 1)非线性映射对拟合容量衰减曲线末段的拐点有帮助。4.2 训练循环与早停策略小数据上训练曲线很不稳定我习惯用早停而不是固定训多少个 epoch。验证损失连续 15 个 epoch 不下降就停并保存验证损失最小的那次权重防止训练后期过拟合导致 RUL 偏移import torch.optim as optim device cuda if torch.cuda.is_available() else cpu model LSTMRegressor(feat_dim3).to(device) optimizer optim.Adam(model.parameters(), lr1e-3) criterion nn.MSELoss() best_val float(inf) patience 0 for epoch in range(200): model.train() train_loss 0.0 # train_loader 是 DataLoaderbatch_size 设为 64 for xb, yb in train_loader: xb, yb xb.to(device), yb.to(device) optimizer.zero_grad() pred model(xb).squeeze(1) loss criterion(pred, yb) loss.backward() optimizer.step() train_loss loss.item() # 验证 model.eval() val_loss 0.0 with torch.no_grad(): for xb, yb in val_loader: xb, yb xb.to(device), yb.to(device) pred model(xb).squeeze(1) val_loss criterion(pred, yb).item() if val_loss best_val: best_val val_loss torch.save(model.state_dict(), best_lstm.pth) patience 0 else: patience 1 if patience 15: print(fearly stop at epoch {epoch}) break两个参数值得细说lr1e-3是 Adam 的常用起点但验证损失如果震荡得厉害降到3e-4往往能救回来。batch_size64在小数据集上比 32 更平滑但样本总数很小时不足两千条也可以直接全 batch 训练省去 shuffle 带来的随机性。训练过程里最重要的一点验证集不能乱切要保持电池身份隔离这个问题第五章重点说。4.3 从容量预测到 RUL滚动外推模型训练完下一步是预测剩余寿命。锂电池的寿命终点通常定义为容量衰减到额定容量的 80%这个 80% 就是 SOH 阈值。预测时从最后一个已知循环开始把模型输出的容量填回序列尾部再作为输入预测下下个循环一直滚到预测容量低于阈值为止滚动的步数就是 RULdef extimate_rul(model, scaler, recent_data, threshold0.8, max_steps600): recent_data 是最后 seq_len 个循环的原始特征数组 seq scaler.transform(recent_data) # 归一化scaler必须用训练时的对象 seq np.array(seq, dtypenp.float32) pred_curve [] for _ in range(max_steps): x torch.FloatTensor(seq[-30:]).unsqueeze(0).to(device) with torch.no_grad(): pred model(x).item() pred_curve.append(pred) # 达到寿命阈值停止滚动 if pred threshold: break # 构造下一步输入温度/内阻用最后窗口均值近似 next_step np.array([pred, seq[-1, 1], seq[-1, 2]], dtypenp.float32) seq np.vstack([seq, next_step]) pred_curve scaler.inverse_transform( np.array([[c, seq[0,1], seq[0,2]] for c in pred_curve]) )[:, 0] return len(pred_curve), pred_curve这段滚动代码是整个项目最容易踩坑的地方。容量预测值无脑填回序列尾部没问题但温度和内阻怎么办真实场景你要么用当前电池最近几圈的平均温度去近似要么干脆假设温控系统让温度恒定。如果测试数据里温度波动大这种近似会给 RUL 带来误差。另一个隐患是误差累积模型预测偏一点填回去后又影响下一步预测几十步下来会系统性偏向乐观或悲观。所以工业上很少一步外推几百个循环而是每实时多跑一个循环就把真实容量追加进序列再重新预测这样只外推未来 10~20 步误差可控得多。5. 锂电池寿命预测里的 5 个避坑点数据泄漏、时序乱序和过拟合5.1 测试电池的数据提前进了训练缩放器装错了位置现象模型在测试集上的 RMSE 小得离谱画出来的预测曲线几乎贴着真实容量线走但换一块新电池实际预测时误差翻倍。原因最典型的是把全部电池数据合在一起做scaler.fit_transform()测试电池的容量数值分布已经混进了训练阶段。对神经网络来说这等于提前知道了测试标签的取值范围本质上是数据泄漏。另一种情况是用全量数据的统计量均值、最大最小值归一化后再切分结果一样。解决任何归一化统计量都只从训练电池计算。测试电池的数值用训练时的scaler.transform()直接映射哪怕测试电池的最大值超过了训练范围也保持 scaler 不变。严格的做法是把“读取数据 → 归一化 → 滑窗 → 划分”这条流水线封装成函数先切电池列表再统一 transform。5.2 随机划分训练验证集跨电池泛化能力失真现象验证损失一路上上下下但整体很低测试电池 RUL 误差却忽高忽低同一模型在不同随机种子下评估结果差 40%。原因随机shuffle会把同一块电池相邻窗口拆进训练和验证。相邻窗口的输入有 29 个循环重叠目标容量只差一圈模型“背”着答案进验证集泛化能力被严重高估。解决按电池 ID 分组做留一验证。比如数据集里有三块电池就“两块训练、一块验证”轮转三次取三次误差平均。具体到代码用sklearn.model_selection.GroupShuffleSplit或者最简单粗暴的按电池名切片都行。这个原则同样适用于超参数搜索网格搜索时每一次 fold 都要保持电池隔离。5.3 归一化参数没有保存模型上线变成黑匣子现象训练时 RUL 预测偏差 15 个循环部署到新电池上预测容量直接输出负数或大于 1 的值。原因推理脚本里把scaler又对当前电池重新fit了一遍。模型学习的是 0~1 归一化空间的曲线形态推理时却喂给它一套新的数值范围输出自然对不上。解决训练结束后把 scaler 的min_和scale_保存成 json 或 joblib 文件推理脚本单独加载不允许重新 fitimport joblib joblib.dump(scaler, scaler.joblib) # 推理端 scaler joblib.load(scaler.joblib) seq scaler.transform(recent_data)这条是典型的“留后悔药”问题我见过不止一个项目因为漏存 scaler 导致线上预测全部错位最后只能重新训练。5.4 容量毛刺触发早停验证损失像弹簧现象训练几百个 epoch 里验证损失始终不收敛早停很快触发保存下来的模型用测试电池一预测容量曲线完全是一条水平线。原因清洗阶段没有把毛刺处理干净导致验证集里某项损失突然升高模型权重震荡。更隐蔽的是早停只盯原始 loss不关心 loss 是否被单点异常值拉高于是模型停在了一个局部糟糕的位置。解决清洗时增加滚动中位数并检查验证集中的容量序列是否有偏离超过 3 倍 MAD绝对中位差的点有就删除该窗口。训练期间记录平滑后的验证损失窗口内均值不要用单轮最低值判断早停。另一种有效做法是验证损失计算时先用预测容量做 3 点滑动平均再和真实曲线比抗毛刺能力立竿见影。5.5 自回归预测的“滞后感”RMSE 很低但 RUL 总是差一段现象预测容量曲线和真实曲线几乎平行RMSE 非常好看但 RUL 预测值系统性偏大或偏小十几到几十循环。原因滚动预测是拿上一步输出当下一步输入模型学到的是“容量基本延续上一圈”所以预测序列总是比真实退化慢半拍。这是自回归推理的通病不是模型没学好而是评估方式不对。解决画图时把预测曲线向右平移一个循环量做对照看斜率是否一致。更实用的做法是训练时增加多步损失不只让模型预测下一步还让它预测未来第 5 步、第 10 步的容量三个损失加起来反向传播。这样模型被迫学真实衰减趋势而不是学“延续上一步”。RUL 评估也要分起点分别从寿命中段和末段开始外推计算 MAE别只看最后一两个点。6. 预测结果可视化与跨电池验证图上先看到问题再谈指标优化6.1 一张图上放三样东西真实容量、预测容量、寿命阈值项目标题里“支持预测结果可视化”实际落地时最有用的就是一张退化曲线叠加图。把测试电池的真实容量画成灰线滚动外推的预测容量画成红虚线再画一条 80% 的寿命阈值横线一眼就能看出滞后和趋势是否合理import matplotlib.pyplot as plt plt.figure(figsize(10, 5)) plt.plot(real_cycles, real_capacity, colorgray, linewidth1.5, labelreal capacity) plt.plot(pred_cycles, pred_capacity, colorcrimson, linestyle--, labelextrapolated) plt.axhline(y0.8, colornavy, linestyle:, labelSOH80% threshold) plt.xlabel(cycle) plt.ylabel(SOH) plt.legend() plt.title(LSTM rolling prediction on test battery) plt.savefig(rul_result.png, dpi150)如果红线和灰线之间的横向距离稳定说明 RUL 偏差有系统性如果某一段突然发散多半是温度或内阻特征在外推时用了不合理占位值。可视化不是用来写报告的是自己判断模型健康度的第一步。6.2 用三类指标交叉验证别只看 RMSE单点 RMSE 只能描述容量拟合误差RUL 是循环数性质不同。我日常记录一套三维指标指标计算方式关注点RMSE预测容量与真实容量逐循环差的均方根曲线拟合精度MAPE预测 RUL 与真实 RUL 的绝对百分比误差寿命估计是否可用阈值穿越偏差预测容量到达 80% 的循环数与真实值的差最终交付数值是否可靠如果 RMSE 很低但 MAPE 很高说明模型拟合住了大部分曲线但错过了膝盖拐点。此时优先级不是加复杂网络而是把训练目标从单步损失改成多步损失或者干脆缩短外推步长减少滚动误差。数据量只有两三块电池时别追求绝对精度把留一验证的误差波动区间算出来比一个看似漂亮的数字有价值得多。6.3 模型迁移到新电池的两个习惯我踩过来觉得真管用第一用小数据微调而不是直接部署。新电池的前 30 个循环跑完后拿真实容量把模型再训几十个 epoch学习率调低到 1e-4让模型快速适配新材料体系的衰减速率这比直接拿旧模型硬预测稳很多。第二永远保留滚动更新的入口——每获得一个真实循环就把新观测追加进序列重新预测只外推 10 到 20 步寿命预测的误差能降下近一半。这些细节都不是玄学是从一次次的“预测偏乐观、阈值早穿”里试出来的。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

树莓派Pico硬件控制实战:从GPIO/PWM到舵机与OLED

树莓派Pico硬件控制实战:从GPIO/PWM到舵机与OLED

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 1:10:48 阅读更多 →
ESP32芯片与模组本质区别:SoC选型、模组料号与射频合规全解析

ESP32芯片与模组本质区别:SoC选型、模组料号与射频合规全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 1:10:48 阅读更多 →
基于YOLO的电缆破损检测实战:1318张数据集训练与避坑指南

基于YOLO的电缆破损检测实战:1318张数据集训练与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 1:10:48 阅读更多 →

最新新闻

OKL4微内核源码深度拆解:从IPC到用户态驱动设计

OKL4微内核源码深度拆解:从IPC到用户态驱动设计

简介:OKL4 1.4.1.1 是微内核领域早期颇具代表性的发行版,适合操作系统课程学习者、嵌入式系统开发者以及想深入理解内核机理的工程师。资源以 tar.gz 压缩格式打包,整体约 58.71MB,解开后即可按目录查看完整源码结构。目前已有 94…

2026/10/9 6:01:59 阅读更多 →
Fabric超级账本构建企业级资产可信链:登记、流转、防伪、溯源一体化

Fabric超级账本构建企业级资产可信链:登记、流转、防伪、溯源一体化

简介:这是一套面向区块链开发工程师与企业级应用实践者的开源解决方案,基于Hyperledger Fabric 1.0构建,聚焦企业资产管理、交易、防伪与溯源四大核心场景,提供从底层链码到前后端一体化的完整落地参考。资源共2000个文件&#xf…

2026/10/9 6:01:59 阅读更多 →
SSM博物馆售票系统开发实战:从数据库设计到并发防超卖全解析

SSM博物馆售票系统开发实战:从数据库设计到并发防超卖全解析

做毕业设计那会儿,我抽到的题目是一个JavaWeb方向的经典项目——博物馆售票管理系统。拿到题目的第一反应是“这有什么难的”,真正动手才发现,光是一个在线选票和库存扣减的逻辑,就能让新手纠结一整天。如果你也正在做类似的SSM项…

2026/10/9 6:01:59 阅读更多 →
Claude Code接入GLM 5完整指南:环境配置与10个实战技巧

Claude Code接入GLM 5完整指南:环境配置与10个实战技巧

最近我把 GLM 5 接进了 Claude Code,直接在终端里用 Claude Code 的交互界面跑 GLM 5 的代码生成和推理。这套组合让我日常改 bug、读工程、写测试脚本的效率明显上了一个台阶,最关键的是 API 成本比默认方案可控不少。所以这篇就把整个安装配置过程从头…

2026/10/9 6:01:59 阅读更多 →
Flutter游戏迁移OpenHarmony:碰撞检测与游戏结束处理实战

Flutter游戏迁移OpenHarmony:碰撞检测与游戏结束处理实战

把一个小游戏从 Flutter 迁到 OpenHarmony 上跑通,最大的感受就是:Dart 层的逻辑基本不用动,但“碰撞检测”和“游戏结束处理”这两块,却需要重新从算法选型到工程落地都过一遍脑子。你可能会觉得,碰撞检测不就是算两个…

2026/10/9 6:01:59 阅读更多 →
从JDK到IDEA:Java与JavaScript开发环境搭建避坑指南

从JDK到IDEA:Java与JavaScript开发环境搭建避坑指南

刚带完一个新人,他抱着笔记本跑过来说环境装了三天还没跑起来。我一看,问题非常典型:JDK装了两个版本,Maven依赖一直在下载失败,npm在PowerShell底下直接报“禁止运行脚本”,IntelliJ IDEA里项目一片飘红。…

2026/10/9 6:00:58 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →