首页/新闻资讯/正文详情

Substrate Glutton Pallet 深度解析:用 `on_idle` 精准消耗区块权重,把链压榨到极限

发布时间:2026/9/26 2:00:25 来源:云帆数科 栏目:资讯中心
Substrate Glutton Pallet 深度解析:用 `on_idle` 精准消耗区块权重,把链压榨到极限
区块链开发框架后端【免费下载链接】substrateSubstrate: The platform for blockchain innovators项目地址https://gitcode.com/gh_mirrors/su/substrate点击查看免费下载导读pallet-gluttonGlutton Pallet是 Substrate 生态中一个专为测试场景设计的有趣 FRAME 模块它的名字源于其贪婪吞噬资源的特性——可以在每个区块的on_idle阶段按比例消耗链上剩余的计算权重ref_time与存储证明权重proof_size从而在实战环境中把平行链parachain及其中继链relay chain推至理论极限。阅读本文后你将掌握 Glutton 的初始化、set_compute/set_storage两个核心控制接口、on_idle的权重吞噬原理、Genesis 配置方式以及如何结合源码与测试用例进行实操验证。注意该 Pallet 仅用于测试严禁部署在任何承载真实价值的链上。一、Glutton 是什么为什么需要资源吞金兽在区块链开发中有一个非常现实的问题如何在实际运行环境中验证一条链的理论吞吐上限普通单元测试往往无法模拟真实网络负载、区块生产节奏与资源争抢。Substrate 在 frame/glutton 中提供的pallet-glutton正是为此而生。从其 README 的第一行就能看到官方明确的警告DO NOT USE ON VALUE-BEARING CHAINS. THIS PALLET IS ONLY INTENDED FOR TESTING USAGE.也就是说这个 Pallet 唯一的目的就是把平行链与中继链压到极限用实践检验理论极限theoretical limits。它的实现思路非常精巧它本身不执行任何有业务意义的逻辑只负责浪费区块权重它通过 FRAME 的on_idlehook 工作在区块执行完正常交易后按设定的比例吞噬剩余可用权重消耗的对象有两个维度ref_time计算时间与proof_size存储证明大小对应 Substrate 2D 权重模型中的两个分量。从 源码模块文档 中可以确认其定位Pallet that consumes ref_time and proof_size of a block. Based on the Compute and Storage parameters the pallet consumes the adequate amount of weight.二、核心机制on_idle与权重吞噬原理2.1 FRAME 的on_idlehookon_idle是 FRAME 提供给每个 Pallet 的区块生命周期 hook 之一。在 frame/support/src/traits/hooks.rs 中定义如下pub trait OnIdleBlockNumber { /// See [Hooks::on_idle]. fn on_idle(_n: BlockNumber, _remaining_weight: Weight) - Weight { Weight::zero() } }它的语义是区块在执行完所有交易extrinsics之后、还有剩余权重remaining_weight时被调用返回值表示该 hook 实际消耗了多少权重。多个 Pallet 的on_idle会按照元组顺序被依次调用后一个 Pallet 只能看到前一个消耗后剩下的权重见 hooks.rs 中的元组实现。Glutton 正是利用了这一机制——它专门吃掉别人用不完的权重。2.2 Glutton 的on_idle实现Glutton 在 frame/glutton/src/lib.rs#L177-L210 中实现了on_idlefn on_idle(_: BlockNumberForT, remaining_weight: Weight) - Weight { let mut meter WeightMeter::from_limit(remaining_weight); if meter.try_consume(T::WeightInfo::empty_on_idle()).is_err() { return T::WeightInfo::empty_on_idle() } let proof_size_limit Storage::T::get().saturating_mul_int(meter.remaining().proof_size()); let computation_weight_limit Compute::T::get().saturating_mul_int(meter.remaining().ref_time()); let mut meter WeightMeter::from_limit(Weight::from_parts( computation_weight_limit, proof_size_limit, )); Self::waste_at_most_proof_size(mut meter); Self::waste_at_most_ref_time(mut meter); meter.consumed() }工作流程分为四步扣除基础开销先用WeightMeter包装剩余权重尝试消耗empty_on_idle()这一基础成本用于读取Compute/Storage两个存储项的权重。如果剩余权重连这一步都不够就直接返回empty_on_idle()保证on_idle本身的开销被如实上报。按比例计算消耗上限从存储中读取Compute与Storage两个比例值分别乘以meter.remaining()的ref_time与proof_size得到本次允许消耗的计算权重上限与证明大小上限。这意味着 Glutton 消耗的是基于当前剩余权重的一定比例而非固定值。先浪费 proof size再浪费 ref time分别调用waste_at_most_proof_size与waste_at_most_ref_time尽量逼近但不超过各自的上限。返回实际消耗最终返回meter.consumed()让区块生产者在结算时知道 Glutton 用掉了多少权重。2.3 两个浪费函数贴近上限的精细控制证明大小消耗waste_at_most_proof_size在 lib.rs#L283-L312pub(crate) fn waste_at_most_proof_size(meter: mut WeightMeter) { let Ok(n) Self::calculate_proof_size_iters(meter) else { return }; meter.consume(T::WeightInfo::waste_proof_size_some(n)); (0..n).for_each(|i| { TrashData::T::get(i); }); }它先通过权重曲线waste_proof_size_some(n)估算出执行多少次读取操作能填满剩余权重然后实际执行n次TrashData读取。每次读取会访问一个 1 KiB 的存储值从而产生真实的 PoVProof of Validity证明开销。计算时间消耗waste_at_most_ref_time在 lib.rs#L314-L364pub(crate) fn waste_at_most_ref_time(meter: mut WeightMeter) { let Ok(n) Self::calculate_ref_time_iters(meter) else { return }; meter.consume(T::WeightInfo::waste_ref_time_iter(n)); let clobber Self::waste_ref_time_iter(vec![0u8; 64], n); // By casting it into a vec we can hopefully prevent the compiler from optimizing it debug_assert!(clobber.len() 64); if clobber.len() 65 { TrashData::T::insert(0, [clobber[0] as u8; VALUE_SIZE]); } }实际的计算浪费由waste_ref_time_iter完成lib.rs#L332-L345用 Blake2b-512 哈希器对一段数据反复执行i次哈希更新最后finalize一次。注释中特别说明了两点设计意图Blake2 哈希速度非常快所以单次迭代会做多次hasher.update以便一次性消耗更多ref_time通过把哈希结果放入Vec并加一个不可能成立的len() 65判断分支尽可能阻止编译器把这段纯计算优化掉——否则就浪费不成权重了。从 benchmarking.rs#L52-L56 可看到waste_ref_time_iter的基准测试范围是i in 0..100_000每次迭代的ref_time开销在 1–10 ms 量级见 lib.rs#L332-L335 的注释。三、三个核心外部接口Glutton 对外只暴露三个可调用函数全部仅允许 Root 或AdminOrigin调用权限由 Config trait 中的AdminOrigin控制接口参数作用相关事件initialize_palletnew_count: u32,witness_count: Optionu32初始化/调整TrashData垃圾数据量PalletInitialized { reinit }set_computecompute: FixedU64设置on_idle消耗剩余ref_time的比例ComputationLimitSet { compute }set_storagestorage: FixedU64设置on_idle消耗剩余proof_size的比例StorageLimitSet { storage }3.1initialize_pallet先初始化才能开吃在 lib.rs#L212-L248 中initialize_pallet负责管理TrashData——一张用于浪费证明大小的存储 Map。关键点pub fn initialize_pallet( origin: OriginForT, new_count: u32, witness_count: Optionu32, ) - DispatchResult { T::AdminOrigin::ensure_origin_or_root(origin)?; let current_count TrashDataCount::T::get(); ensure!( current_count witness_count.unwrap_or_default(), Error::T::AlreadyInitialized ); // ... 按 new_count 与 current_count 的大小关系插入或删除条目 Self::deposit_event(Event::PalletInitialized { reinit: witness_count.is_some() }); TrashDataCount::T::set(new_count); Ok(()) }new_count目标条目数量。源码注释给出的推荐默认值是5_000一个合理的垃圾数据量。witness_count当前TrashData的实际条目数见证值。首次初始化时传None如果 Pallet 已经初始化过必须传Some(current_count)才能绕过AlreadyInitialized错误实现重新初始化扩容或收缩。new_count current_count时插入新条目否则删除多余条目。TrashData的每个值大小为VALUE_SIZE 1024字节1 KiBMap 的MaxValues被限制为MAX_TRASH_DATA_ENTRIES 65_000见 lib.rs#L49-L54。为什么是 65k源码注释解释得很清楚lib.rs#L120-L13565k 刚好比16^4 65536小一点避免触发证明大小的基准测试跳变overestimate实践中 65k × 1 KiB ≈ 65 MiB 的证明浪费上限已经足够。3.2set_compute与set_storage设定吞噬比例两个函数逻辑完全对称lib.rs#L250-L280pub fn set_compute(origin: OriginForT, compute: FixedU64) - DispatchResult { T::AdminOrigin::ensure_origin_or_root(origin)?; ensure!(compute RESOURCE_HARD_LIMIT, Error::T::InsaneLimit); Compute::T::set(compute); Self::deposit_event(Event::ComputationLimitSet { compute }); Ok(()) } pub fn set_storage(origin: OriginForT, storage: FixedU64) - DispatchResult { T::AdminOrigin::ensure_origin_or_root(origin)?; ensure!(storage RESOURCE_HARD_LIMIT, Error::T::InsaneLimit); Storage::T::set(storage); Self::deposit_event(Event::StorageLimitSet { storage }); Ok(()) }比例值的语义非常直白lib.rs#L106-L1181.0对应 100%即吞掉全部剩余ref_time或proof_size最大允许值为RESOURCE_HARD_LIMIT 101000%超过会返回InsaneLimit错误超过 1.0 可能导致链停滞stall the chain——因为你让on_idle去消耗超过区块剩余权重的资源。两个存储项Compute与Storage都是StorageValue_, FixedU64, ValueQuery默认值为 0即默认不消耗任何资源这也是测试在 tests.rs#L92 中断言Compute::T::get()初始为零的原因。四、Genesis 配置预置初始状态如果不希望在部署后手动调用initialize_pallet可以在 Genesis 中直接配置。Glutton 的 GenesisConfig 包含三个字段字段类型说明computeFixedU64初始计算消耗比例storageFixedU64初始存储消耗比例trash_data_countu32初始垃圾数据条目数用于浪费 proof sizegenesis_build中有三条硬性断言trash_data_count MAX_TRASH_DATA_ENTRIES超出直接 paniccompute RESOURCE_HARD_LIMIT否则报 Compute limit is insanestorage RESOURCE_HARD_LIMIT否则报 Storage limit is insane。示例配置以 JSON chain spec 形式{ glutton: { compute: 500000000, storage: 500000000, trash_data_count: 5000 } }注意FixedU64在 JSON 中通常以整数形式表示定点数1.0 对应其定点表示值实际数值需按运行时使用的FixedU64编码换算trash_data_count建议使用文档推荐的5_000作为初始值。五、Runtime 集成方式在 Substrate 节点运行时中Glutton 的集成方式与普通 FRAME Pallet 一致。以bin/node/runtime为例1. 依赖声明bin/node/runtime/Cargo.tomlpallet-glutton { version 4.0.0-dev, default-features false, path ../../../frame/glutton }并在std、runtime-benchmarks、try-runtime三个 feature 中分别引入对应开关见 Cargo.toml#L178、#L274、#L346。2. Config 实现bin/node/runtime/src/lib.rs#L443-L447impl pallet_glutton::Config for Runtime { type RuntimeEvent RuntimeEvent; type AdminOrigin EnsureRootAccountId; type WeightInfo pallet_glutton::weights::SubstrateWeightRuntime; }AdminOrigin使用EnsureRoot即只有 Root治理能调用三个外部接口WeightInfo使用仓库自动生成的 weights.rs 中的SubstrateWeight。3. 注册到 Runtimebin/node/runtime/src/lib.rs#L2050Glutton: pallet_glutton,并在 benchmarking 白名单中加入[pallet_glutton, Glutton]bin/node/runtime/src/lib.rs#L2200使其可以参与基准测试。六、基准测试与权重校准Glutton 的浪费行为高度依赖准确的权重曲线因此它的 benchmark 设计非常讲究。benchmarking.rs 顶部注释特别提醒Has to be compiled and run twice to calibrate on new hardware.也就是说在新硬件上必须把 benchmark 编译并运行两次来完成校准。它定义了以下基准Benchmark变量范围用途initialize_pallet_grown in 0..1_000初始化/扩容TrashData的权重initialize_pallet_shrinkn in 0..1_000收缩TrashData的权重waste_ref_time_iteri in 0..100_000单次哈希迭代消耗的ref_time曲线waste_proof_size_somei in 0..5_000单次TrashData读取消耗的 proof size 曲线on_idle_high_proof_waste/on_idle_low_proof_waste—手动验证on_idle在高低两种 proof 负载下的行为empty_on_idle—on_idle自身的基础开销set_compute/set_storage—两个设置函数的基础权重生成的权重文件 frame/glutton/src/weights.rs 是 2023-06-16 在 2.60 GHz Intel Xeon 上、以--steps50 --repeat20参数自动生成的其中记录了完整的 benchmark CLI 命令weights.rs#L26-L43可供复现./target/production/substrate benchmark pallet \ --chaindev --steps50 --repeat20 \ --palletpallet_glutton \ --no-storage-info --no-median-slopes --no-min-squares \ --extrinsic* --executionwasm --wasm-executioncompiled \ --heap-pages4096 \ --output./frame/glutton/src/weights.rs \ --header./HEADER-APACHE2integrity_test防死循环的最后防线Glutton 在 lib.rs#L179-L188 还实现了一个integrity_testfn integrity_test() { assert!( !T::WeightInfo::waste_ref_time_iter(1).ref_time().is_zero(), Weight zero; would get stuck in an infinite loop ); assert!( !T::WeightInfo::waste_proof_size_some(1).proof_size().is_zero(), Weight zero; would get stuck in an infinite loop ); }它的作用很关键如果某个平台上这两条权重曲线是零on_idle里的迭代计算就会陷入死循环永远填不满 meter。这个 hook 会在运行时完整性检查阶段如try-runtime或集成测试提前拦截此类错误配置。七、测试用例行为验证与精度保证frame/glutton/src/tests.rs 提供了完整的单元测试可以从四个角度验证 Pallet 行为7.1 初始化与扩容/收缩initialize_pallet_works验证只有 Root 能调用、首次初始化后重复调用不带见证值会返回AlreadyInitialized、事件正确发出且TrashData中确实写入了确定性生成的值tests.rs#L28-L60。expand_and_shrink_trash_data_works验证5000 → 8000 → 6000 → 0的扩容/收缩流程TrashDataCount与iter_keys().count()始终一致tests.rs#L62-L87。7.2 比例设置与硬上限setting_compute_respects_limit/setting_storage_respects_limit验证9.99、10.0合法10.01返回InsaneLimittests.rs#L111-L161。setting_compute_works/setting_storage_works验证非 Root 签名signed(1)和无签名none()调用都会返回BadOrigintests.rs#L89-L109。7.3on_idle的接近上限精度Glutton 的测试最核心的断言是实际消耗必须尽量接近目标且绝不能超支over-spend。以on_idle_weight_high_proof_is_close_enough_works为例tests.rs#L172-L194let should Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND, WEIGHT_PROOF_SIZE_PER_MB * 5); let got Glutton::on_idle(1, should); assert!(got.all_lte(should), Consumed too much weight); let ratio Perbill::from_rational(got.proof_size(), should.proof_size()); assert!(ratio Perbill::from_percent(99), Too few proof size consumed, ...); let ratio Perbill::from_rational(got.ref_time(), should.ref_time()); assert!(ratio Perbill::from_percent(99), Too few ref time consumed, ...);在compute storage 1.0100%的情况下on_idle消耗的权重必须同时满足all_lte(should)绝不允许超过剩余权重消耗比例 ≥ 99%也不能浪费太多保证压测效果接近真实上限。on_idle_weight_over_unity_is_close_enough_workstests.rs#L220-L249进一步验证了比例超过 1.0 的场景当设置compute 1.75, storage 1.5时on_idle会尝试消耗超过区块限制的权重consumed.all_gt(max_block)此时消耗量应介于区块上限与请求量之间——这正是测试链是否会被撑爆的极端场景。waste_at_most_ref_time_weight_close_enough与waste_at_most_proof_size_weight_close_enoughtests.rs#L251-L283则直接对两个内部浪费函数做精度校验在ref_time与proof_size分别接近无限的极端 meter 上要求consumed_ratio() 99%否则报错Weight calibration failed. Please re-run the benchmarks on the same hardware.——再次印证了权重曲线必须与硬件匹配这一前提。7.4 数据生成器的确定性gen_value_workstests.rs#L285-L294验证gen_value生成的 1 KiB 值长度正确、不同 seed 值互不相同、非全零、且对相同 seed 具有确定性。这是TrashData数据可复现、可基准化的基础。八、使用场景与实战建议8.1 典型压测流程结合 README 与源码一个完整的 Glutton 压测流程如下部署在测试平行链/中继链的 runtime 中注册pallet-glutton参考第五节并在 Genesis 中预置trash_data_count如 5000。初始化若未配置 Genesis先以 Root 调用initialize_pallet(5000, None)初始化垃圾数据。设置比例以 Root 调用set_compute/set_storage例如各设0.5消耗 50% 剩余权重逐步调大观察链的负载与出块表现。压测观察区块利用率、出块时间、PoV 大小等指标逐步逼近 100%1.0甚至超过 1.0找到链的真实瓶颈。8.2 注意事项红线严禁用于有价值链README 与源码文档首行都给出了WARNING这条红线没有例外比例不要轻易设超过 1.0源码与注释多次警告Setting this to over 1.0 could stall the chain只有在你确实想测试链何时会停滞时才使用换硬件必须重新校准权重benchmarking.rs明确要求在新硬件上编译运行两次 benchmark否则on_idle的实际消耗可能与预期偏差超过 1%TrashData上限 65k虽然源码注释说明该上限未强制实施超出也能工作但超过后基准权重可能被低估导致 PoV 相关权重不准确。九、源码结构速查文件内容frame/glutton/README.md官方警告与功能简介frame/glutton/src/lib.rsPallet 全部实现存储项、外部接口、on_idle与内部浪费逻辑frame/glutton/src/benchmarking.rs9 个 benchmark 与校准说明frame/glutton/src/weights.rs自动生成的权重曲线SubstrateWeightframe/glutton/src/tests.rs行为、权限、精度与确定性测试frame/glutton/src/mock.rs测试用 mock runtimeAdminOrigin EnsureRootframe/glutton/Cargo.toml依赖与 feature 声明std/runtime-benchmarks/try-runtimebin/node/runtime/src/lib.rs参考运行时中的集成示例Config、注册、benchmark 白名单结语Glutton Pallet 是 Substrate 测试工具箱中一个反常规却极其实用的组件它用最朴素的方式反复哈希、反复读存储把区块链的权重预算精确烧掉让开发者能在真实环境中验证链的理论极限。理解它的on_idle消耗模型、FixedU64比例语义与基准测试校准逻辑不仅能帮助你正确地用它做压测也能加深对 Substrate 权重系统ref_time/proof_size二维模型本身的理解。记住那句开篇警告它只属于测试环境永远不要让它出现在承载真实价值的链上。赞分享区块链开发框架后端【免费下载链接】substrateSubstrate: The platform for blockchain innovators项目地址https://gitcode.com/gh_mirrors/su/substrate点击查看免费下载相关推荐Substrate pallet-elections-phragmen 深度解析基于顺序 Phragmén 的链上选举模块Substrate pallet elections phragmen 深度解析基于顺序 Phragmén 的链上选举模块 本文围绕 Substrate FR区块链开发框架后端Substrate区块链框架深度解析下一代区块链开发利器Substrate区块链框架深度解析下一代区块链开发利器 什么是Substrate Substrate是一个革命性的区块链开发框架它代表了区块链技术的下一区块链开发框架后端WeKan 卡片清单怎么配置自动重置间隔WeKan 卡片清单怎么配置自动重置间隔 在 WeKan 里把卡片清单checklist当作日常例行事项使用时常见的麻烦是勾完一遍后还要手动把每一项取区块链开发框架后端上一篇【亲测免费】 xrdp: 远程桌面协议服务器下一篇zlib: 一个广泛使用的压缩库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

基于featexp特征提取方法使用xgboost进行数据分析
基于featexp特征提取方法使用xgboost进行数据分析

在现代金融领域,信贷风险评估是数据科学的一个重要应用场景。通过有效的特征工程和模型优化,可以极大地提高预测的准确性,从而帮助金融机构更好地做出决策。 本文将以特征工程和模型优化为核心,展示如何通过实际案例来解决信贷风险评估中的关键问题。整个过程涵盖了从数据… · 2026/9/26 2:00:25

ZYNQ课设实战:FFT与打地鼠的软硬协同设计指南
ZYNQ课设实战:FFT与打地鼠的软硬协同设计指南

简介:本资源为ZYNQ课设合集,面向电子信息、嵌入式及FPGA方向的学生与开发者,包含「基于ZYNQ的FFT设计与实现」和「基于ZYNQ打地鼠游戏设计」两个完整项目,帮助读者在Xilinx ZYNQ SoC平台上打通软硬件协同开发流程。压缩包为rar格式… · 2026/9/26 2:00:25

Baserow 无代码数据库 5 分钟上手指南:不写代码搭好你的第一张数据表
Baserow 无代码数据库 5 分钟上手指南:不写代码搭好你的第一张数据表

Baserow 无代码数据库 5 分钟上手指南:不写代码搭好你的第一张数据表 【免费下载链接】baserow Build databases, automations, apps & agents with AI — no code. Open source platform available on cloud and self-hosted. GDPR, HIPAA, SOC 2 compliant. B… · 2026/9/26 2:00:25

贷款违约预测实战案例 从 Kaggle 表格分类到金融风控建模
贷款违约预测实战案例 从 Kaggle 表格分类到金融风控建模

贷款违约预测看似是入门级二分类题,实际对应的是金融风控中极常见的风险识别任务。这个 Kaggle 案例的价值,不在于单次提交分数,而在于用一套可复现的表格建模流程,把借款人特征转化为违约风险排序结果,并用 AUC 验证模型是否具备稳定区分能力。 整篇内容围绕真实风控建模… · 2026/9/26 3:11:09

医学影像分类实战复盘 从 Kaggle 竞赛到可落地建模流程
医学影像分类实战复盘 从 Kaggle 竞赛到可落地建模流程

这场楼加深度学习实战项目挑战比赛,适合作为医学影像分类的入门级项目复盘材料。题目规模不大,评价方式直接,能够把数据检查、预处理、迁移学习、验证设计和提交生成串成一条完整链路,比单纯演示模型调用更接近真实项目原型开发。 更重要的价值在于,这类任务虽然以分类准… · 2026/9/26 3:11:09

城市峡谷定位回归实战 从 GNSS 原始观测到位置误差预测
城市峡谷定位回归实战 从 GNSS 原始观测到位置误差预测

这道 Kaggle 赛题聚焦城市环境中的 GNSS 定位修正,任务目标不是判断卫星状态本身,而是基于双频观测、信号强度、载波相位和伪距误差等原始信息,预测东西向与北向的位置误差。训练场景与测试场景分属不同城区,决定了建模重点必须落在抗遮挡、多路径干扰和跨区域泛化能力上。… · 2026/9/26 3:11:09

医学影像分类模型在辅助诊断中的落地思路
医学影像分类模型在辅助诊断中的落地思路

在机器学习与计算机视觉的学习路径中,医学影像分类是一个极具代表性的入门实战领域。它要求从业者不仅理解算法原理,更能系统性掌握从原始数据到可用模型的完整工程化流程。本次解析所依托的“楼+机器学习实战”项目,正是一个以此为目标的典型教育型赛题,其核心在于引导学习… · 2026/9/26 3:11:09

FAST-LIO IESKF推导
FAST-LIO IESKF推导

目录 1. 系统描述 2.普通ESKF流程 2.1 预测(量侧)更新阶段 2.2 观测更新阶段 2.3 ESKF的局限 3. IESKF流程 3.1 预测(量侧)更新阶段 3.1.1 雅可比推导前的准备 3.1.2 i1时刻误差状态对i时刻误差状态的雅可比计算 3.1.3 … · 2026/9/26 3:11:09

Claude Code Windows 安装教程:从环境配置到 VS Code 实战
Claude Code Windows 安装教程:从环境配置到 VS Code 实战

1. 安装之前:先把环境盘点清楚最近总有人问我:Claude Code 在 Windows 上到底能不能用?是不是只支持 Mac 和 Linux?我一开始也以为要装 Linux 子系统或者搞个虚拟机才能跑。但实际试下来,Claude Code 官方对 Windows 的… · 2026/9/26 3:11:03

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

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

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码