为新的数据库编写 Quartz.NET Driver Delegate:方言驱动委托完整指南
任务调度后端【免费下载链接】quartznetQuartz Enterprise Scheduler .NET项目地址https://gitcode.com/gh_mirrors/qu/quartznet点击查看免费下载本文以 Quartz.NET 官方 4.x 文档《A Driver Delegate for a New Database》为骨架完整讲解如何为 Quartz 内置六种数据库方言之外的新数据库编写驱动委托Driver Delegate。读完本文你将掌握何时应该继承StdAdoDelegate而非实现IDriverDelegate、十个方言契约成员的覆写时机与写法、行限制/分页/布尔映射/参数绑定四类 SQL 方言差异的处理方式以及如何把委托、DbMetadata提供程序注册和建表 DDL 三件套接入AddQuartz配置并让ProvisionSchema()自动建表。为什么需要一个新数据库的 Driver DelegateQuartz 的 ADO 持久化存储AdoJobStore通过一个驱动委托把调度语义翻译成具体数据库的 SQL。官方现成实现覆盖六种数据库方言分别位于仓库 src/Quartz/Impl/AdoJobStoreSQL ServerSqlServerDelegatePostgreSQLPostgreSQLDelegateMySQLMySQLDelegateOracleOracleDelegateSQLiteSQLiteDelegateFirebirdFirebirdDelegate当接入一种全新的数据库或者某种已在列表中的数据库但由行为不同的 Provider 提供时就需要一个自己的委托。起点不要实现 IDriverDelegate继承 StdAdoDelegate官方文档给出了明确的起点建议不要实现IDriverDelegate整个产品中没有任何东西实现它其约一百一十个成员中绝大多数在任何数据库上都是同一份 SQL。请继承StdAdoDelegate只覆写有差异的部分。六个内置方言合起来也只覆写了十个不同的成员其中 Firebird 和 PostgreSQL 各只需覆写两个。这个建议有源码支撑在 StdAdoDelegate.cs 中StdAdoDelegate声明为public partial class StdAdoDelegate : IDriverDelegate, IDbAccessor——公开、未密封且带有公共无参构造函数正是为作为可继承的方言基类而设计的。public sealed class MyDatabaseDelegate : StdAdoDelegate { // override only what differs }这段示例与下文所有 snippet 均可在仓库的 DialectDelegateSamples.cs 中直接找到该文件位于Quartz.Documentation.Samples项目它不是 Quartz 的友元程序集因此编译通过本身就证明这套公共 API 对任何外部开发者是完整可用的。接缝十个方言契约成员StdAdoDelegate的其他protected virtual成员应被视为私有实现步骤真正值得覆写的是下面这张契约表。这是方言委托的完整契约逐行继承自官方文档成员何时覆写protected virtual string? SchemaResourceName你希望ProvisionSchema()创建你的表——见下文还需要DbMetadata 与 schemaprotected virtual SqlRowLimit GetRowLimit(int count)你的数据库可以限制语句返回的行数protected virtual string GetSelectNextTriggerToAcquireSql(TriggerAcquisitionSqlShape shape)获取语句需要的不仅是行限制MySQL 的索引提示是唯一的内置案例protected virtual string GetSelectMisfiredTriggersToRecoverSql(int count)同上用于 misfire 扫描count -1表示不限制protected virtual string GetCountMisfiredTriggersInStateSql()计数形式的语句需要不同形态protected virtual string ApplyPaging(string sql, bool takeLimited)数据库不理解OFFSET … FETCH NEXT …protected virtual void AddPagingParameters(DbCommand cmd, int skip, int take, bool takeLimited)你的分页子句以不同顺序命名两个参数public virtual void AddCommandParameter(DbCommand cmd, string paramName, object? paramValue, Enum? dataType null, int? size null)Provider 需要显式设置类型或大小public virtual object GetDbBooleanValue(bool value)没有布尔列类型public virtual bool GetBooleanFromDbValue(object columnValue)同上读回时反向转换行限制Row limitingSQL 没有 ANSI 标准的行限制子句所以基类StdAdoDelegate默认不施加任何限制。触发器获取trigger acquisition和 misfire 扫描两条语句都会调用GetRowLimit。内置方言的覆写形态恰好覆盖了三种放置位置全部可以在仓库源码中逐一对证// … LIMIT n (PostgreSQL, MySQL, SQLite) — 或 Firebird 的 ROWS protected override SqlRowLimit GetRowLimit(int count) SqlRowLimit.AtStatementEnd(LIMIT, count); // SELECT TOP n … SqlRowLimit.InProjection(TOP, count) // SELECT * FROM ( … ) WHERE rownum n SqlRowLimit.InEnclosingSelect(rownum, count)逐条对应内置实现PostgreSQL / MySQL / SQLiteSqlRowLimit.AtStatementEnd(LIMIT, count)见 PostgreSQLDelegate.cs、MySQLDelegate.cs、SQLiteDelegate.csFirebirdSqlRowLimit.AtStatementEnd(ROWS, count)见 FirebirdDelegate.csSQL ServerSqlRowLimit.InProjection(TOP, count)见 SqlServerDelegate.csOracleSqlRowLimit.InEnclosingSelect(rownum, count)见 OracleDelegate.cs。SqlRowLimit本身是公开的readonly record struct定义在 SqlRowLimit.cs。它命名了行限制可以去的三个位置语句是带着它被构建出来的而不是事后对成品 SQL 做字符串拼接——在引入它之前SQL Server 方言曾经要靠裁掉前六个字符再贴回自己的SELECT这种脆弱方式实现TOP。使用要点count始终至少为 1表示取全部行的-1会在到达你的覆写之前被拦截并替换为SqlRowLimit.Unlimited见 StdAdoDelegate.Triggers.cs 与NoRowLimit -1哨兵值。TriggerAcquisitionSqlShape携带的是会改变语句文本的东西行限制以及NOT IN需要多少个 job 类型排除项。它同时是语句的缓存键因此它保存的是分桶后的排除项数量而不是精确值——缓存里只会沉淀少量条目见 StdAdoDelegate.cs 的acquisitionSqlByShape。只有当行限制表达不了的东西才需要覆写GetSelectNextTriggerToAcquireSql(shape)就像 MySQL 处理FORCE INDEX那样——仍然调用base并在其返回文本上做替换不要动行限制部分protected override string GetSelectNextTriggerToAcquireSql(TriggerAcquisitionSqlShape shape) base.GetSelectNextTriggerToAcquireSql(shape) .Replace({0}TRIGGERS t, {0}TRIGGERS t FORCE INDEX (IDX_{1}T_NFT_ST));MySQL 对 misfire 扫描的两条相关语句也做了同样的FORCE INDEX处理GetSelectMisfiredTriggersToRecoverSql与GetCountMisfiredTriggersInStateSql见 MySQLDelegate.cs让优化器强制走获取索引IDX_*_T_NFT_ST而非结构不匹配的 misfire 索引。分页Paging基类默认使用 ANSI 标准分页子句SQL Server 2012、Oracle 12c、PostgreSQL 和 Firebird 3 都能理解OFFSET pageSkip ROWS FETCH NEXT pageTake ROWS ONLYMySQL 和 SQLite 需要覆写ApplyPaging与AddPagingParameters它们的子句以相反的顺序命名两个参数而按位置绑定参数的 Provider 会按语句中的出现顺序绑定。参数名应使用AdoConstants.ParameterPageSkip与AdoConstants.ParameterPageTake在 SQL 文本中带前缀绑定时不带protected override string ApplyPaging(string sql, bool takeLimited) takeLimited ? sql LIMIT AdoConstants.ParameterPageTake OFFSET AdoConstants.ParameterPageSkip : sql LIMIT -1 OFFSET AdoConstants.ParameterPageSkip; protected override void AddPagingParameters(DbCommand cmd, int skip, int take, bool takeLimited) { if (takeLimited) { AddCommandParameter(cmd, AdoConstants.ParameterPageTake, take); } AddCommandParameter(cmd, AdoConstants.ParameterPageSkip, skip); }细节要点takeLimited为false表示无界分页Take int.MaxValue。因为没有仅 OFFSET的写法MySQL 使用最大的BIGINT UNSIGNED源码中是字面量LIMIT 18446744073709551615 OFFSET …见 MySQLDelegate.csSQLite 使用LIMIT -1。基类传入的take是页面大小加一多取的那一行让PagedResultT.HasMore判断精确成立。布尔值BooleansOracle 没有布尔列类型所以它的委托双向映射1/0见 OracleDelegate.cspublic override object GetDbBooleanValue(bool booleanValue) booleanValue ? 1 : 0; public override bool GetBooleanFromDbValue(object columnValue) Convert.ToInt32(columnValue) 1;IS_DURABLE、REQUESTS_RECOVERY等列都通过GetDbBooleanValue绑定参数因此写入与读回两个方向的映射必须互相一致。基类默认实现直接把bool原样交给 Provider并在读回时用Convert.ToBoolean转换见 StdAdoDelegate.cs。参数ParametersAddCommandParameter是最后的兜底手段。以 SQL Server 为例见 SqlServerDelegate.cs它做了三件事把bool参数转换为1/0照顾 SQL Server CE对二进制参数dataType匹配DbProvider.Metadata.BinaryParameterType设置size -1即 varbinary(MAX)对字符串参数在没有显式size时固定为size 4000——避免 SQL Server 为每种字符串长度各建一份查询计划。覆写后务必调用base.AddCommandParameter(...)完成实际的参数添加。委托无法触及的部分::: warningStdAdoConstantsSQL 文本是internal的。Schema 才是契约它公开在AdoConstants中。 :::你不能写StdAdoConstants.SqlSelectNextTriggerToAcquire。要么转换base.GetSelectNextTriggerToAcquireSql(shape)的返回值像 MySQL 的.Replace({0}TRIGGERS t, …)那样要么完整地自己写出整条语句。你可以直接引用公开的表名、列名、状态常量AdoConstants.TableTriggers、AdoConstants.ColumnTriggerName、AdoConstants.StateWaiting等。{0}是表前缀占位符protected string ReplaceTablePrefix(string query)负责替换它。基类返回的语句文本中仍包含{0}由调用方在真正执行时完成替换。另一条重要限制官方文档明确提示只定制某一条语句是不被支持的。六个 SQL 钩子覆盖了数据库之间的差异其余约 76 条语句都是内联的ReplaceTablePrefix(StdAdoConstants.X)调用。请改为覆写发出该语句的方法StdAdoDelegate上的每一个IDriverDelegate成员都是virtual的包括无锁获取路径用来认领触发器的UpdateTriggerStateFromOtherStateWithNextFireTime。未来也可以兼容地增加更多GetXxxSql()钩子如果确实需要可以向项目提出。值得留意的是这些整体重写成员的写法在文档示例中也有体现——DialectDelegateSamples.cs中展示了一个完整的SelectTriggerState覆写它用ReplaceTablePrefix组合公开常量拼出 SQL、用PrepareCommand准备命令、用AddCommandParameter绑定参数、用SchedulerName限定作用域再通过StoredTriggerStates.FromStoredValue把字符串映射回状态。这说明只要钩子不够用整个成员写出来是受支持且所有原材料都可达的。值转换并不全是接缝GetDbBooleanValue/GetBooleanFromDbValue是virtual的但下面这四个不是GetDbDateTimeValue、GetDateTimeFromDbValueGetDbTimeSpanValue、GetTimeSpanFromDbValue原因源码有明确注释见 StdAdoDelegate.csUTC 时钟周期ticks和整毫秒是 schema 契约的一部分。首选节点preferred-node的存活探测 SQL 直接对LAST_CHECKIN_TIME和CHECKIN_INTERVAL做 tick 算术如果某个委托改了这两种值的存储格式会让固定触发器pinned trigger的故障转移在无任何报错的情况下静默失效。因此官方文档给出结论必须原生存储DATETIME的数据库应当直接实现IDriverDelegate并完全拥有自己的 SQL。初始化DriverDelegateContextStdAdoDelegate.Initialize(DriverDelegateContext context)是public virtual六个内置方言都没有覆写它。默认实现从上下文拷贝tablePrefix、schedulerName、instanceId、DbProvider、TypeLoader、useProperties、ObjectSerializer、TimeProvider创建AdoUtil注册五个内置触发器族Simple、Cron、CalendarInterval、DailyTimeInterval、Recurrence的持久化委托再追加容器传入的自定义持久化委托见 StdAdoDelegate.cs。只在需要注册额外的触发器持久化委托或从上下文中捕获某些值时才覆写它并且必须先调用base.Initialize(context)。DriverDelegateContext成员一览成员说明TablePrefix、SchedulerName、InstanceId必填DbProvider、TypeLoader必填ObjectSerializer可空TriggerPersistenceDelegates为本调度器注册的那些TimeProvider调度器的时钟CommandTimeout来自AdoJobStoreOptions.CommandTimeout为什么上下文在构造之后才送达因为当容器构建委托时自动生成的InstanceId还不存在。基类暴露了protected string SchedulerName { get; }几乎每条语句都按它做作用域限定和protected IDbProvider DbProvider { get; }见 StdAdoDelegate.cs所以你的子类不需要自己再保存一份副本。注册委托builder.Services.AddQuartz(q { q.UsePersistentStore(s { s.UseDriverDelegateMyDatabaseDelegate(); s.UseGenericDatabase(MyProvider, connectionString); }); });::: warning 顺序很重要 注册是先到先得TryAdd语义。UseSqlServer、UsePostgres等在内部都会调用UseDriverDelegate…()所以UseDriverDelegateMyDatabaseDelegate()必须放在数据库方法之前否则会被静默忽略。 :::这与 PersistentStoreBuilder.cs 的实现一致UseDriverDelegateT()与UseDriverDelegate(FuncIServiceProvider, IDriverDelegate)最终都走TryAdd系的注册逻辑。其他要点委托由ActivatorUtilities构建所以构造函数依赖注入可用例如ILoggerMyDatabaseDelegate或容器中的任何东西。UseDriverDelegate(factory)接受一个由你构建委托的工厂。工厂的 Provider 解析的是该调度器自己的部件注册在全局Services上的IDriverDelegate对命名调度器不可见——命名调度器在它自己的键key下解析。UseSerializer、UseLockHandler、UseConnectionProvider、UseTriggerPersistenceDelegate都以同样的方式接受工厂。旧式配置键quartz.jobStore.driverDelegateType仍然按类型名选择委托即使存储本身是代码配置的也依然生效。还需要DbMetadata 与 schema官方文档明确新数据库三件套委托——本文主题Provider 注册。UseGenericDatabase(provider, connectionString, describeMetadata)接受一个FuncDbMetadata来描述 ADO.NET Provider连接、命令和参数类型、参数前缀、DbType拼写。Provider 与委托相互独立Use…快捷方法是一次性把两者都设置好。DDL。复制最接近的database/tables/tables_ .sql并调整列类型。仓库的 database/tables 目录下有六种方言的建表脚本tables_sqlServer.sql、tables_postgres.sql、tables_mysql_innodb.sql、tables_oracle.sql、tables_sqlite.sql、tables_firebird.sql。手工执行 DDL 即可满足默认的SchemaProvisioning.Validate。若要让ProvisionSchema()自动建表需要三步嵌入脚本EmbeddedResource IncludeMyDatabase.sql /从SchemaResourceName返回其清单资源名RootNamespace.文件夹路径.文件名语句之间用内容为--;;的行分隔因为存储过程体内可能含分号并在脚本中写{0}作为表前缀占位符。// 该委托据以建表的 schema 脚本与它并排嵌入 // EmbeddedResource IncludeMyDatabase.sql /名称与编译器命名方式一致 // RootNamespace.文件夹路径.文件名。语句之间以 --;; 行分隔。 protected override string? SchemaResourceName MyCompany.Quartz.MyDatabase.sql;这个名字会先在委托类型所在的程序集中查找再沿基类链向上查找——因此内置方言的子类会直接继承该方言的脚本内置方言的SchemaResourceName如Quartz.Impl.AdoJobStore.Schema.create_mysql_innodb.sql见 MySQLDelegate.cs。若未设置ProvisionSchema()会以一条点名该成员的错误信息失败。小结一份新方言的落地清单把上面的内容收敛成实操顺序继承StdAdoDelegate对照十成员契约表只覆写你的数据库真正有差异的部分多数情况下行限制 分页即可提供FuncDbMetadata描述你的 ADO.NET Provider并用UseDriverDelegateMyDelegate()先于数据库方法UseGenericDatabase注册基于 database/tables 中最接近的脚本编写 DDL可选地嵌入资源并实现SchemaResourceName以启用自动建表别忘了为布尔、日期时间等值转换确认双向一致且不要触碰 UTC ticks/整毫秒这两条 schema 契约。参见Job Stores —— ADO 存储是如何组装起来的A Job Store of Your Own —— 比本页高一层Persisting a Custom Trigger Type —— 另一个委托接缝赞分享任务调度后端【免费下载链接】quartznetQuartz Enterprise Scheduler .NET项目地址https://gitcode.com/gh_mirrors/qu/quartznet点击查看免费下载相关推荐面向 Antigravity 的委托任务简报Brief写作实战基于 agentic-awesome-skills 的 agy-delegate 完整指南面向 Antigravity 的委托任务简报Brief写作实战基于 agentic awesome skills 的 agy delegate 完整指南AI 技能AI 插件dataset测试驱动开发为SQL数据库应用编写单元测试的完整指南dataset测试驱动开发为SQL数据库应用编写单元测试的完整指南 在Python数据开发领域dataset库以其简洁的API和强大的功能赢得了众多开发者的数据库后端开发工具Lombok Delegate注解委托模式的终极自动化实现指南Lombok Delegate注解委托模式的终极自动化实现指南 Lombok的Delegate注解是Java开发中实现委托模式的终极自动化解决方案。作为L开发工具代码生成上一篇dotnet-bluetooth-le 项目使用教程下一篇如何快速构建美观Electron应用Photon开源项目完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Czkawka 磁盘清理完整指南:14 项本地任务如何挑出重复文件与相似图片

Czkawka 磁盘清理完整指南:14 项本地任务如何挑出重复文件与相似图片

Czkawka 磁盘清理完整指南:14 项本地任务如何挑出重复文件与相似图片 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 磁盘容量红线逼近…

2026/10/7 9:22:15 阅读更多 →
防抖装饰器(Debounce Decorator):在 JavaScript 中合并高频函数调用的实现与原理

防抖装饰器(Debounce Decorator):在 JavaScript 中合并高频函数调用的实现与原理

文档教程前端 【免费下载链接】zh.javascript.info 现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。…

2026/10/7 9:22:15 阅读更多 →
Superpowers:开发者认知增强工作流的原理与落地实践

Superpowers:开发者认知增强工作流的原理与落地实践

1. 项目概述:Superpowers 不是超能力,而是开发者工作流的“认知增强套件” 你最近在技术社区、GitHub Trending 或 Discord 开发者频道里,大概率已经反复刷到 superpowers 这个词——它不是漫威电影里的变种人设定,也不是某款新…

2026/10/7 9:22:15 阅读更多 →

最新新闻

云端任务输出增长后:本地扩容数据盘与项目网盘的关机计费边界

云端任务输出增长后:本地扩容数据盘与项目网盘的关机计费边界

云端 GPU 任务跑了一段时间以后,存储判断通常会比创建实例时复杂。 原因很简单:模型输出、日志、检查点或成果文件已经产生,此时即使计算实例已经关机,文件占用并不会因为“计算停止”自动消失。 因此,遇到“实例已经关…

2026/10/7 9:58:40 阅读更多 →
Language Server Protocol TextDocumentItem 详解:客户端向服务器传输文档的四大字段与语言标识符规范

Language Server Protocol TextDocumentItem 详解:客户端向服务器传输文档的四大字段与语言标识符规范

开发工具 【免费下载链接】language-server-protocol Defines a common protocol for language servers. 项目地址: https://gitcode.com/gh_mirrors/la/language-server-protocol 点击查看 免费下载 TextDocumentItem 是 Language Server Protocol(LSP…

2026/10/7 9:58:40 阅读更多 →
Schema.org 汽车本体与 Automotive Ontology Working Group:auto.schema.org 扩展及协作贡献机制解析

Schema.org 汽车本体与 Automotive Ontology Working Group:auto.schema.org 扩展及协作贡献机制解析

知识图谱数据 【免费下载链接】schemaorg Schema.org - schemas and supporting software 项目地址: https://gitcode.com/gh_mirrors/sc/schemaorg 点击查看 免费下载 本篇技术指南围绕 Automotive_Ontology_Working_Group.md 这份协作方(collaborator…

2026/10/7 9:58:40 阅读更多 →
【Linux系统】【从菜鸟驿站到操作系统:一节课打通Linux重定向与缓冲区真相】流食般投喂

【Linux系统】【从菜鸟驿站到操作系统:一节课打通Linux重定向与缓冲区真相】流食般投喂

从菜鸟驿站到操作系统:一节课彻底打通 Linux 重定向、VFS 与缓冲区少年们,如果你曾疑惑过:为什么 ./a.out > log.txt 时错误信息依然赖在屏幕上?为什么 fork() 之后文件里突然冒出 7 行输出?为什么 printf 明明返回…

2026/10/7 9:58:40 阅读更多 →
常用芯片介绍 各种常用芯片目录总览介绍

常用芯片介绍 各种常用芯片目录总览介绍

列表模式列出各种芯片目录,点击连接可进入每种芯片查看详细介绍 芯片 说明 厂家 封装 LM2575T (Buck)开关稳压器 德州仪器 TO-220-5 TO-263-5 AMS1117 (LDO)低压差线性稳压器

2026/10/7 9:58:40 阅读更多 →
LokiJS 快速上手:JavaScript 嵌入式内存数据库的创建、查询、链式操作与动态视图实战

LokiJS 快速上手:JavaScript 嵌入式内存数据库的创建、查询、链式操作与动态视图实战

数据库后端 【免费下载链接】LokiJS javascript embeddable / in-memory database 项目地址: https://gitcode.com/gh_mirrors/lo/LokiJS 点击查看 免费下载 本文是一份基于 LokiJS 官方文档(OVERVIEW.md)与仓库源码的实战入门指南&#xff…

2026/10/7 9:57:39 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

/* 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 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

/* 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 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

/* 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 1:02:00 阅读更多 →

周新闻

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/6 7:15:40 阅读更多 →
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/6 5:29:09 阅读更多 →
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/7 9:29:10 阅读更多 →

月新闻

我发现了一个新思路:用 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/6 8:21:32 阅读更多 →
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/6 4:21:51 阅读更多 →
黑夜航拍船只数据集训练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/6 1:18:13 阅读更多 →