跳转到内容
GitHub

主题 / 工程基础

02 通用编码规范

不分语言都适用的编码约定:命名、注释、错误处理与传播、日志字段与级别、配置、复杂度,时间、金额、编码、并发这些容易出错的地方,以及格式化和 lint 的通用原则。

草稿复核于 2026-11-14 · 下次复核 2027-05-1440 条规则 · 硬约束 21 条在 GitHub 上修改

一页结论

  1. 跨语言只统一语义,不统一表层风格。 命名要清楚、一致;大小写和后缀按各语言惯例,空白和导入顺序交给格式器。
  2. 注释写为什么。 原因、约束、边界、风险;公共接口写清输入输出、错误和副作用。
  3. 错误不吞、不丢原因。 传播时保留原错误并补上下文;只在能处理或要转换的地方捕获;在边界转成稳定的错误码,不把栈和 SQL 交给调用方。
  4. 日志是结构化数据。 固定的基本字段、统一的级别含义;不记密钥、令牌和不必要的个人信息;同一错误只完整记一次。
  5. 配置集中加载、启动即校验。 缺了或错了就启动失败,报键名不报值。
  6. 复杂度看趋势,不设跨语言行数红线。 阈值继承各语言工具默认值,只卡新增代码;不为凑行数机械拆分。
  7. 容易错的地方按标准来。 时间点用 RFC 3339,本地时间另存 IANA 时区;金额不用二进制浮点,带 ISO 4217 币种;文本默认 UTF-8;超过 2^53 的整数在 JSON 里用字符串。
  8. 外部调用都有超时,重试有上限和退避。 非幂等写操作没有幂等设计就不自动重试;每个后台任务都有停止方式。
  9. 格式器只有一个,lint 例外要说理由。 抑制精确到规则、写明原因;长期例外登记负责人和到期日。

规则

级别
检查方式
显示 40 条
COD-001软指导检查:人工

同一个概念全项目用同一个名称,不同概念不共用名称;领域术语记进术语表

怎么检查:评审时对照术语表检查新出现的名称;术语表本身随代码一起评审
为什么、来源
为什么:一个概念几个叫法、一个叫法几个意思,是读错代码和接错字段的常见原因。
  • 类型用名词,函数用动词短语,布尔值读起来像判断(is_active、has_children)。
  • 集合用复数或明确的集合名,和单个对象区分开。
COD-002硬约束检查:自动

标识符的大小写、前后缀遵循所用语言的惯例,不跨语言强行统一一种写法

怎么检查:用各语言的命名 lint 规则检查(工具见 10–15)
为什么、来源
为什么:每种语言的工具链、标准库和社区代码都按自己的惯例写,强行统一会和生态打架。

对外字段(JSON、数据库、事件)是契约,大小写在 16、17 里定,不随后端语言变化。

COD-003软指导检查:人工

新的公共名称用通用英文词和业内公认的缩写,不用随意的拼音、中英混拼和自造缩写

怎么检查:评审新增的公共接口、字段和模块名;专有名词(如地名、法规名)登记在术语表里作为例外
为什么、来源
为什么:拼音和自造缩写换个人就看不懂,也没法可靠地自动识别,只能靠评审。
  • 已经公开的旧名称,不为改风格而直接改名,按 16、17 的兼容规则处理。
  • 公认缩写如 id、url、config 可以用;不认识的缩写在第一次出现处解释或换全称。
COD-004软指导检查:半自动

带单位的数量把单位写进名称或类型里,如 timeout_ms、size_bytes,或用语言自带的时长类型

怎么检查:评审时检查新增的时长、大小、比例类字段和参数;能用强类型(如时长类型)的优先用类型
为什么、来源
为什么:没写单位的 1000,有人当毫秒有人当秒,这类错误测试很难发现。
COD-005软指导检查:半自动

有业务含义的数字和字符串定义成具名常量,写清含义、单位和来源

怎么检查:开启各语言的魔法数字规则提示候选(如 ESLint no-magic-numbers、Ruff PLR2004),评审确认
为什么、来源
为什么:散落在代码里的 86400、0.06、"VIP2" 看不出含义,改的时候也找不全。
  • 不需要处理:0、1、-1、数组下标、测试里的样例数据、一看就懂的数学常量。
  • 来自外部规定的值(费率、上限、协议常量),在常量旁注明出处。
  • 可能随部署变化的值做成配置(见 COD-022),不要做成常量。
COD-006软指导检查:人工

注释写原因、取舍、约束和风险,不逐行复述代码;改行为时同步改注释

怎么检查:评审时检查注释是否解释了「为什么」,以及改动处的注释是否还和代码一致
为什么、来源
为什么:复述代码的注释没有信息量;过期的注释比没有注释更误导人。
COD-007硬约束检查:半自动供别人引用的库或 SDK

供别人调用的库,公开接口必须有文档注释,写清用途、参数和返回值、可能的错误、前置条件和副作用

怎么检查:用各语言的文档缺失检查找出没写的公开接口(工具见 10–15),内容是否完整靠评审
为什么、来源
为什么:调用方看不到实现,文档注释就是接口说明的一部分。

文档注释的格式(Go Doc、TSDoc、docstring、rustdoc、Javadoc/KDoc)按各语言规范。

COD-008软指导检查:自动

TODO、FIXME 要写原因并关联任务编号或负责人;不留占位实现冒充完成

怎么检查:lint 或脚本检查 TODO 是否带任务编号(如 Ruff 的 TD 规则、ESLint no-warning-comments);评审时检查空实现和写死的返回值
为什么、来源
为什么:没人认领的 TODO 永远不会被处理;占位实现上线后就是缺陷。
COD-009软指导检查:自动

生成的代码在文件头标明由什么工具生成、不要手改;手写代码不放在生成目录里

怎么检查:检查生成文件头部的标记(如 Go 约定的 // Code generated ... DO NOT EDIT.),格式器和 lint 跳过这些文件
为什么、来源
为什么:手改生成代码,下次重新生成时改动就丢了。
COD-010硬约束检查:半自动

不吞错:禁止空的 catch、捕获后什么都不做,或只打印一下就当成功继续

怎么检查:开启各语言的相关 lint(如空 catch、裸 except、未检查的返回错误),评审有意忽略的地方是否写了原因
为什么、来源
为什么:被吞掉的错误会以数据错乱、状态不一致的形式在别处出现,很难追到源头。

确实要忽略的错误(如关闭只读文件失败),在代码里写明为什么可以忽略。

另见:10-15
COD-011硬约束检查:半自动

向上传递错误时保留原始错误,并补上操作、对象标识、所处阶段等上下文;不用新错误覆盖掉原错误

怎么检查:用语言自带的错误链(Go %w 和 errors.Is/As、Python raise ... from、JS new Error(msg, { cause })、Java/Kotlin 构造异常时传入 cause、Rust source()),评审检查是否丢了原错误
为什么、来源
为什么:只剩一句「保存失败」而丢了底层原因,排查时只能靠猜。

上下文里只放安全的标识(订单号、阶段名),不放密码、令牌、完整请求体。

COD-012软指导检查:人工

只在能处理或恢复、要转换错误类型、要补有用上下文的地方捕获错误;其余情况向上传

怎么检查:评审时检查每个捕获点属于哪一种情况
为什么、来源
为什么:到处捕获会让错误被重复处理、重复记录,或在半路被改得面目全非。
COD-013软指导检查:人工

区分三类错误:调用方能纠正的(输入非法、无权限、冲突)、临时故障(超时、限流、下游不可用)、程序缺陷;是否可重试单独标记

怎么检查:评审错误类型的定义和映射表
为什么、来源
为什么:分清类别才知道该提示用户、该重试还是该报警;「可预期」不等于「可以忽略」。
COD-014软指导检查:半自动

调用方按错误类型或错误码判断,不靠匹配错误消息文本

怎么检查:搜索代码里对错误消息做字符串比较或正则匹配的地方,评审确认
为什么、来源
为什么:错误消息是给人看的,随时会改措辞或翻译,按文本判断一改就坏。
COD-015硬约束检查:半自动对外提供服务的后端供别人引用的库或 SDK命令行工具

在服务或进程的边界把内部错误转成稳定的错误码和安全的说明,不把栈、SQL、内部路径、密钥返回给调用方

怎么检查:评审边界处的错误映射;用安全扫描找出直接返回异常信息的地方;对错误响应做样例测试
为什么、来源
为什么:栈和 SQL 会暴露内部结构,给攻击者提供线索;调用方也没法依赖这些内容做判断。

对外错误响应的具体格式(如 RFC 9457)见 16。

COD-016硬约束检查:自动对外提供服务的后端命令行工具

生产环境的应用日志用结构化格式(如每行一个 JSON 对象),不拼接成只有人能读的句子

怎么检查:在测试或预发环境采样日志,检查每行都能被解析成字段
为什么、来源
为什么:结构化日志才能可靠地检索、聚合和告警,也更难被注入伪造。
COD-017硬约束检查:自动对外提供服务的后端

每条日志都有时间戳、级别、服务名、事件名和消息;处理请求时带上追踪编号和请求编号,出错时带错误码

怎么检查:定义日志字段清单,用日志样本校验必备字段
为什么、来源
为什么:缺了这几个字段,日志就没法按时间、服务、请求串起来看。
  • 时间戳用 UTC 的 RFC 3339 格式(见 COD-026)。
  • 事件名用稳定的标识(如 order.payment_failed),消息可以是给人读的句子。
  • 字段名全项目统一一套;没有追踪编号时不要编造。
  • 示例:{"timestamp":"2026-11-13T09:00:00Z","level":"ERROR","service":"order-api","event":"order.persistence_failed","trace_id":"…","request_id":"req_123","error_code":"STORAGE_UNAVAILABLE","duration_ms":42}
COD-018软指导检查:人工

全项目统一日志级别的含义:DEBUG 诊断细节,INFO 正常的重要事件,WARN 异常但已恢复或已降级,ERROR 本次操作失败,FATAL 进程无法继续

怎么检查:评审新增日志的级别;抽查生产日志里 ERROR 是否都对应真实失败
为什么、来源
为什么:级别乱用会让告警失灵:到处是 ERROR 就没人看 ERROR。

这套含义是行业通行的惯例,不是某个标准规定的。syslog(RFC 5424)只定义了级别名称和数值,OpenTelemetry 日志数据模型只定义了级别的数值区间,用于不同日志库之间对齐。 不要用 ERROR 记录调用方的输入错误(那是正常业务结果,用 INFO 或 WARN)。

COD-019硬约束检查:半自动

日志里不记录密码、令牌、密钥、Cookie、完整连接串、银行卡号和没有正当用途的个人信息;按字段白名单记录,不整个打印请求体

怎么检查:用密钥和个人信息检测扫描日志样本(工具见 25);评审新增日志的字段
为什么、来源
为什么:日志的访问范围通常比业务数据宽,保存时间也长,泄露在日志里等于泄露给所有能看日志的人。

用户编号这类标识也可能算个人信息,记录前确认有用途且访问受控。

COD-020硬约束检查:半自动

写入日志的外部输入要经过编码,去掉或转义换行等控制字符,并限制长度

怎么检查:优先用结构化日志库自动编码字段;安全扫描找出把外部输入直接拼进日志消息的地方
为什么、来源
为什么:不处理换行就能伪造日志行,不限长度就能撑爆存储。
COD-021软指导检查:人工

同一个错误只在处理它的那一层完整记录一次,中间层只传递不重复打印

怎么检查:评审时检查一条错误路径上有几处记录日志;对照日志样本看是否同一错误出现多条
为什么、来源
为什么:层层记录会让一次失败变成五条 ERROR,告警和统计都会失真。
COD-022硬约束检查:半自动对外提供服务的后端命令行工具

随部署变化的配置不写死在代码里;在一处集中加载并按类型校验,缺失或非法时启动失败,报键名和原因,不输出值

怎么检查:配置加载代码有单元测试覆盖缺失和非法值的情况;评审时搜索业务代码里散落的读取环境变量的地方
为什么、来源
为什么:带着错误配置启动,往往在半夜才以奇怪的方式失败;集中校验能把问题挡在启动时。
  • 密钥和普通配置分开处理,密钥不写进代码、示例、日志和命令行参数,具体做法见 25。
  • 「配置与代码分离」来自 Twelve-Factor App,是业界方法论,不是标准。
COD-023软指导检查:半自动对外提供服务的后端命令行工具

每个配置项写明类型、单位、取值范围、默认值、是否必填、是否敏感;写清多个来源的覆盖顺序和是否支持热更新

怎么检查:用配置结构定义(schema)生成说明文档和校验代码;评审新增配置项
为什么、来源
为什么:不写清楚,同一个配置在不同环境里被理解成不同的意思。

覆盖顺序常见做法是「命令行 > 环境变量 > 配置文件 > 默认值」,这是惯例不是标准;项目选定后写进文档。

COD-024软指导检查:自动

复杂度阈值沿用各语言工具的默认值,只对新增和改动的代码执行;存量代码用基线记录,不一次性全仓阻断

怎么检查:在 CI 里只对改动部分运行复杂度检查,超出时要求说明或简化(工具见 10–15)
参考值:参考值:Sonar 认知复杂度默认 15(C、C++、Objective-C 为 25),其维护者说明这是调出来的经验值;Google Python 风格指南建议函数超过约 40 行时考虑能否拆分,并明确不设硬上限。
为什么、来源
为什么:阈值是经验值,不是科学定律;对存量一刀切只会催生大量无意义的例外。
COD-025软指导检查:人工

不设跨语言统一的函数或文件行数上限;不为凑行数机械拆出没有意义的小函数

怎么检查:评审时看函数是否只做一件事,而不是只看行数
为什么、来源
为什么:同样的行数,在状态机、声明式配置、生成代码里阅读成本完全不同;机械拆分反而增加跳转。
  • 用提前返回减少嵌套;嵌套深度可由 lint 提示。
  • 不写为省几行而难懂的表达式、隐式副作用和晦涩的元编程。
COD-026硬约束检查:自动

跨系统传递的时间点用 RFC 3339 格式并带时区偏移;存储和比较用 UTC

怎么检查:接口结构定义里时间字段声明为 date-time 格式并做校验;评审时检查不带偏移的时间字符串
为什么、来源
为什么:不带偏移的「2026-11-13 10:00」在不同机器上代表不同的时刻。
  • 2026-11-13 是日历日期,不是时间点,用单独的日期类型。
  • RFC 9557 更新了 RFC 3339:Z 现在只表示「UTC 时间已知、当地偏移未知」。需要表达当地偏移时写实际偏移(如 +08:00)。
COD-027硬约束检查:半自动

有本地时间含义的数据(排班、每天当地 9 点、未来某天的预约)另存 IANA 时区名,不只存一个偏移量

怎么检查:评审这类字段是否同时保存了时区名;时区计算用标准库或成熟时间库,不自己算夏令时
为什么、来源
为什么:偏移量会随夏令时和政策变化,只存偏移,未来的本地时间会算错一小时甚至更多。
  • 时区名用 IANA 时区数据库的名称,如 Asia/Shanghai、Europe/Paris;需要和时间写在一起时,可用 RFC 9557 的后缀写法 2026-01-01T09:00+01:00[Europe/Paris]。
  • 时区数据库会更新,运行环境要能随之更新。
COD-028硬约束检查:半自动

时长和超时写明单位;计算耗时用单调时钟,不用系统墙上时间相减

怎么检查:评审耗时计算用的时钟接口;部分语言有 lint 可提示(工具见 10–15)
为什么、来源
为什么:系统时间会被校时、手动修改而跳变,用它算耗时可能得到负数或巨大的值。

单调时钟对应 POSIX 的 CLOCK_MONOTONIC,各语言都有对应接口(如 Go 的 time.Since、Python 的 time.monotonic、JS 的 performance.now)。

COD-029硬约束检查:半自动

金额不用二进制浮点数计算和存储;用十进制类型或最小货币单位的整数,同时带 ISO 4217 币种代码和明确的舍入规则

怎么检查:评审金额字段和计算代码的类型;接口结构定义里金额字段不用 number/float
为什么、来源
为什么:二进制浮点无法精确表示 0.1 这类十进制小数,累加和舍入后会差一分钱,对账时就对不上。
  • 各币种的小数位数不同(如日元 0 位、人民币 2 位、科威特第纳尔 3 位),按 ISO 4217 的「minor unit」取,不要写死 2 位。
  • 只有数字没有币种的 amount=19.99 不能用于结算。
COD-030软指导检查:半自动

浮点数比较按业务的误差要求判断,不用 == 直接比较,也不套一个全局通用的误差值

怎么检查:开启各语言的浮点相等比较提示(如 Rust Clippy float_cmp),评审确认误差来源
为什么、来源
为什么:浮点运算有舍入误差,直接比较结果不稳定;合理的误差范围取决于数据的量级和用途。
COD-031硬约束检查:自动

源文件和交换的文本数据默认用 UTF-8;截断、计长度、比较时按字符处理,不按字节

怎么检查:在 .editorconfig 里设置 charset = utf-8,CI 检查文件编码;评审字符串截断和长度校验的实现
为什么、来源
为什么:混用编码会产生乱码;按字节截断会把一个汉字切成两半。
  • 在系统之间交换的 JSON 必须用 UTF-8(RFC 8259 的要求)。
  • 比较用户输入的文本(如用户名)前先做 Unicode 规范化(通常用 NFC 或 NFKC),否则看起来一样的字符串可能不相等。
COD-032硬约束检查:半自动

在 JSON 里传递可能超过 2^53 的整数(如长整型编号)时用字符串;接口里写清整数范围,以及「字段为空」和「字段不存在」是否有区别

怎么检查:评审接口结构定义里的整数字段类型和范围;用超大值做契约测试
为什么、来源
为什么:很多 JSON 解析器(包括浏览器里的 JavaScript)把数字当双精度浮点处理,超过 2^53 就会悄悄丢精度。

接口契约的其他细则见 16。

COD-033硬约束检查:半自动

每个网络调用和外部调用都设置超时或截止时间,并把剩余时间传给下游

怎么检查:评审外部调用的客户端配置;搜索没有设置超时的客户端构造(部分语言有 lint 可提示)
为什么、来源
为什么:没有超时的调用遇到下游卡死时会无限期占着连接和线程,一个慢依赖就能拖垮整个服务。
COD-034硬约束检查:半自动

重试只针对临时故障,必须有次数上限和带随机抖动的指数退避;非幂等的写操作没有幂等设计时不自动重试

怎么检查:评审重试配置(上限、退避、可重试的错误类型);用现成的重试库或客户端自带的重试,不手写循环
为什么、来源
为什么:无限重试会把短暂故障放大成雪崩;重试非幂等的写操作会造成重复扣款、重复下单。
  • HTTP 标准(RFC 9110)规定:除非确知请求实际是幂等的,或能确认原请求没有生效,否则客户端不应自动重试非幂等方法的请求。
  • 幂等键等接口层的幂等设计见 16;限流见 18。
COD-035软指导检查:半自动

启动的每个后台任务、线程或协程都有明确的负责方和停止方式(取消或截止时间),退出时回收资源

怎么检查:评审任务的启动和停止路径;测试里检查泄漏(如 Go 的 goleak)
为什么、来源
为什么:没人负责停止的任务会在进程里越积越多,造成内存和连接泄漏,关闭时还会丢数据。
COD-036硬约束检查:半自动

多个执行单元共享的可变数据必须有明确的同步方式;支持竞态检测的语言在测试中开启它

怎么检查:测试时开启竞态检测(如 Go 的 -race、C/C++/Rust 的 ThreadSanitizer);评审共享状态的访问方式
为什么、来源
为什么:数据竞争的结果不确定,平时测不出来,线上偶发且难以复现。

能用不可变数据或消息传递的,就不共享可变状态。

COD-037软指导检查:人工

时间、金额、JSON、UUID、加密、重试这类有大量边角情况的功能,用标准库或成熟的库,不自己写;新增依赖写明理由

怎么检查:评审依赖清单的变化和新增的工具函数
为什么、来源
为什么:这些领域的坑早有人踩过,自己写往往在时区、精度、安全上出问题。

两段代码相似不一定要抽成共享;只有复制的是同一条业务规则时才提取,避免把不同流程硬凑成一个抽象(见 01)。

COD-038硬约束检查:自动

每种语言只用一个格式器,配置文件入库,CI 用检查模式验证;评审不再讨论空白和导入顺序

怎么检查:CI 运行格式器的检查模式(如 --check),有差异即失败(工具见 10–15)
为什么、来源
为什么:格式交给工具后,评审精力才能放在设计、正确性和安全上;两个格式器并存会互相改来改去。

仓库根目录放 .editorconfig,统一编码、换行符、缩进和文件末尾换行,让各编辑器行为一致。

COD-039硬约束检查:自动

在代码里关闭 lint 时必须指明具体规则并写理由,不允许整文件或不指明规则地关闭

怎么检查:用 lint 自带的检查强制执行(如 ESLint 的未使用禁用指令报告和禁用注释说明、Ruff PGH004、golangci-lint 的 nolintlint 要求写说明)
为什么、来源
为什么:不指明规则的关闭会把以后出现的新问题一起盖住;不写理由,后人不知道能不能删。
COD-040软指导检查:半自动

长期的 lint 例外(基线文件、整条规则关闭)登记理由、负责人和到期日,到期复查

怎么检查:脚本检查例外清单里每项都有负责人和到期日,到期时提醒
为什么、来源
为什么:没有到期日的例外会永久存在,规则名义上开着,实际上已经失效。

选型

类别默认备选(何时用)不推荐
格式化每种语言一个官方或主流格式器 + 仓库根目录 .editorconfig
沿用项目已有的格式器(存量项目已经统一使用某个格式器)
靠人工评审统一空格和引号:浪费评审精力且不一致
同一语言并用两个格式器:互相改写,产生无意义的改动
lint 例外行内关闭精确到规则并写理由;存量问题用工具自带的基线文件—
整文件或不指明规则地关闭:会盖住以后的新问题
在 CI 里调低阈值让检查通过:规则名义上开着,实际上失效
错误传播语言自带的错误链(cause)+ 边界处的错误码映射—
把原错误转成字符串再拼进新错误:丢失原错误类型,调用方无法判断
靠匹配错误消息文本判断错误类型:措辞一改就坏
应用日志语言主流的结构化日志库,输出 JSON 行
键值对格式的文本日志(只在本地开发查看时)
随手 print 或拼接字符串:无法检索,容易被注入
时间标准库或成熟时间库,时区用 IANA 时区数据库;传输用 RFC 3339—
自己解析时间字符串或计算夏令时:边角情况太多
用不带偏移的本地时间字符串跨系统传递:在不同机器上代表不同时刻
金额十进制类型(如各语言的 Decimal/BigDecimal)或最小货币单位的整数,配 ISO 4217 币种代码—
float/double:无法精确表示十进制小数
重试现成的重试库或客户端自带的重试机制,配上限、指数退避和随机抖动—
手写 while 循环重试:容易漏掉上限、退避和可重试判断
格式化
每种语言一个官方或主流格式器 + 仓库根目录 .editorconfig
备选:沿用项目已有的格式器(存量项目已经统一使用某个格式器)
不推荐:靠人工评审统一空格和引号;同一语言并用两个格式器
lint 例外
行内关闭精确到规则并写理由;存量问题用工具自带的基线文件
不推荐:整文件或不指明规则地关闭;在 CI 里调低阈值让检查通过
错误传播
语言自带的错误链(cause)+ 边界处的错误码映射
不推荐:把原错误转成字符串再拼进新错误;靠匹配错误消息文本判断错误类型
应用日志
语言主流的结构化日志库,输出 JSON 行
备选:键值对格式的文本日志(只在本地开发查看时)
不推荐:随手 print 或拼接字符串
时间
标准库或成熟时间库,时区用 IANA 时区数据库;传输用 RFC 3339
不推荐:自己解析时间字符串或计算夏令时;用不带偏移的本地时间字符串跨系统传递
金额
十进制类型(如各语言的 Decimal/BigDecimal)或最小货币单位的整数,配 ISO 4217 币种代码
不推荐:float/double
重试
现成的重试库或客户端自带的重试机制,配上限、指数退避和随机抖动
不推荐:手写 while 循环重试
  • 格式化:具体工具见 10–15。
  • 应用日志:日志采集和链路追踪见 26。

常见错误

错误做法:所有语言统一用 camelCase 或 snake_case
应该:统一语义,大小写按各语言惯例;对外字段按 16 定
错误做法:用拼音或无意义的名字(yonghuId、tmp2)
应该:用术语表里的英文词(userId、user_id)
错误做法:代码里散落 86400、0.06 这样的数字
应该:定义成具名常量并写清单位和来源
错误做法:catch {} 或 except: pass
应该:处理、转换或向上传递,确需忽略时写明原因
错误做法:每一层都捕获并打印同一个错误
应该:中间层带上下文传递,在处理边界记录一次
错误做法:把异常栈、SQL 错误直接返回给调用方
应该:返回稳定错误码和安全说明,细节记在内部日志
错误做法:把整个请求体交给日志
应该:按白名单记录需要的字段
错误做法:业务代码里到处读取环境变量并自己解析
应该:集中加载、按类型校验配置
错误做法:「函数超过 30 行必须拆」「文件超过 300 行必须拆」
应该:行数只作提醒,评审看职责是否单一
错误做法:两段相似的代码就抽成公共库
应该:只有同一条业务规则被复制时才提取
错误做法:用 double 存金额
应该:用十进制类型或最小单位整数,带币种和舍入规则
错误做法:用系统时间相减计算耗时
应该:用单调时钟
错误做法:无上限、无退避地重试,或自动重试下单、扣款请求
应该:设上限和带抖动的退避,非幂等写操作先有幂等设计
错误做法:用 // eslint-disable 或 # noqa 整片关闭检查
应该:精确到规则并写理由,长期例外登记到期日

待确认

下面的内容还没核实或待补调研,不要当成规则执行。

  • 待补调研:魔法数字的业界做法(哪些值可以豁免、各语言 lint 规则的误报率);COD-005 目前按通用做法写成软指导
  • 待补调研:文件和目录命名、导入分组的跨语言约定
  • 待补调研:复杂度和重复代码检测有没有值得推荐的跨语言工具;目前只沿用各语言工具
  • 待补调研:日志字段名用 OpenTelemetry 语义约定的名称,还是项目自定的 snake_case 名称
  • 跨语言自定义规则引擎(如 Semgrep)是否推荐、许可证口径,交 25 和 27 统一定
  • 内部注释能否用中文、公开 SDK 文档是否必须英文,交 05 定
  • RFC 9557 把 Z 的含义改成「当地偏移未知」后,各语言时间库的输出是否需要调整,未逐一核实
  • golangci-lint nolintlint 的配置项名称未核实

来源

  1. S01 Google Engineering Practices: What to look for in a code review · Google · 官方文档 · 核实于 2026-11-13
  2. S02 Google Python Style Guide · Google · 官方文档 · 核实于 2026-11-14
  3. S03 AIP-140: Field names · Google · 官方文档 · 核实于 2026-11-14
  4. S04 AIP-141: Quantities · Google · 官方文档 · 核实于 2026-11-14
  5. S05 AIP-142: Time and duration · Google · 官方文档 · 核实于 2026-11-14
  6. S06 ESLint: no-magic-numbers · ESLint · 官方文档 · 核实于 2026-11-14
  7. S07 Ruff: magic-value-comparison (PLR2004) · Astral · 官方文档 · 核实于 2026-11-14
  8. S08 go command: Generate Go files by processing source · Go · 官方文档 · 核实于 2026-11-14
  9. S09 Working with Errors in Go 1.13 · Go · 官方文档 · 2019-10-17 · 核实于 2026-11-14
  10. S10 Python Tutorial: Exception Chaining · Python Software Foundation · 官方文档 · 核实于 2026-11-14
  11. S11 MDN: Error.prototype.cause · MDN · 官方文档 · 核实于 2026-11-14
  12. S12 OWASP Error Handling Cheat Sheet · OWASP · 标准 · 核实于 2026-11-14
  13. S13 OWASP Logging Cheat Sheet · OWASP · 标准 · 核实于 2026-11-13
  14. S14 OpenTelemetry: Logs Data Model · OpenTelemetry · 标准 · 核实于 2026-11-13
  15. S15 RFC 5424: The Syslog Protocol · IETF · 标准 · 2009-03 · 核实于 2026-11-14
  16. S16 The Twelve-Factor App: Config · Heroku · 社区 · 核实于 2026-11-13
  17. S17 S3676: Reason for the current default value of 15 · Sonar Community · 社区 · 2024 · 核实于 2026-11-14
  18. S18 RFC 3339: Date and Time on the Internet: Timestamps · IETF · 标准 · 2002-07 · 核实于 2026-11-14
  19. S19 RFC 9557: Date and Time on the Internet: Timestamps with Additional Information · IETF · 标准 · 2024-04 · 核实于 2026-11-14
  20. S20 IANA Time Zone Database · IANA · 标准 · 核实于 2026-11-14
  21. S21 POSIX: clock_getres, clock_gettime, clock_settime · The Open Group · 标准 · 核实于 2026-11-14
  22. S22 ISO 4217: Currency codes · ISO · 标准 · 核实于 2026-11-14
  23. S23 SIX: ISO 4217 currency code lists (maintenance agency) · SIX · 官方文档 · 核实于 2026-11-14
  24. S24 IEEE 754-2019: Standard for Floating-Point Arithmetic · IEEE · 标准 · 2019-07 · 核实于 2026-11-14
  25. S25 Python Tutorial: Floating-Point Arithmetic: Issues and Limitations · Python Software Foundation · 官方文档 · 核实于 2026-11-14
  26. S26 RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format · IETF · 标准 · 2017-12 · 核实于 2026-11-14
  27. S27 RFC 3629: UTF-8, a transformation format of ISO 10646 · IETF · 标准 · 2003-11 · 核实于 2026-11-14
  28. S28 Unicode Standard Annex #15: Unicode Normalization Forms · Unicode Consortium · 标准 · 核实于 2026-11-14
  29. S29 EditorConfig Specification · EditorConfig · 标准 · 核实于 2026-11-13
  30. S30 RFC 7493: The I-JSON Message Format · IETF · 标准 · 2015-03 · 核实于 2026-11-14
  31. S31 gRPC: Deadlines · gRPC · 官方文档 · 核实于 2026-11-14
  32. S32 Timeouts, retries, and backoff with jitter · Amazon Web Services · 案例 · 核实于 2026-11-14
  33. S33 RFC 9110: HTTP Semantics · IETF · 标准 · 2022-06 · 核实于 2026-11-14
  34. S34 Go: Data Race Detector · Go · 官方文档 · 核实于 2026-11-14
  35. S35 Clang: ThreadSanitizer · LLVM · 官方文档 · 核实于 2026-11-14
  36. S36 ESLint: Configure Rules (disable comments and descriptions) · ESLint · 官方文档 · 核实于 2026-11-14
  37. S37 Ruff: blanket-noqa (PGH004) · Astral · 官方文档 · 核实于 2026-11-14