JAVA|后端编码规范
目录
零、引言
一、基础
二、集合
三、并发
四、日志
五、安全
零、引言
规范等级:
|
一、基础
序号 | 等级 | 规范 | 示例 | 说明 | |||
---|---|---|---|---|---|---|---|
1 | 强制 | 在POJO类中定义布尔类型成员变量时,禁止用is作变量名前缀。 | 反例:
| is作变量名前缀的布尔型成员变量,在一些IDE(如:IDEA)中,默认生成的getter方法与变量名相同,导致部分框架(如:Jackson、Fastjson)在反向解析时会引发“找不到指定成员变量名”的错误。 | |||
2 | 强制 | 在对象之间做相等比较时,应当使用Objects工具类(java.util.Objects)的equals方法。 | 正例:
反例:
| 当对象为null时,直接调用equals会出现空指针异常。 注意:Objects的equals方法内部会利用参数对象的equals方法进行比较,对数组、集合之类的对象并不会做内部元素的一一比较。 | |||
3 | 强制 | 在BigDecimal之间做等值比较时,禁止使用equals方法。 | 正例:
反例:
| BigDecimal的equals方法会比较精度,如1.0与1.00比较的结果为false,推荐使用其 compareTo方法做比较。 | |||
4 | 强制 | 在浮点数之间做等值比较时,基本类型禁止使用==,包装类型禁止使用equals。 | 正例:
反例:
反例:
| 浮点数先转成BigDecimal,再用compareTo方法做比较,以避免精度问题影响结果。 浮点数采用“尾数+阶码”的编码方式,类似于科学计数法的“有效数字+指数”的表示方式。二进制无法精确表示大部分的十进制小数。 | |||
5 | 强制 | 将浮点数转换为BigDecimal 时,禁止直接使用构造方法。 | 正例:
反例:
| BigDecimal的浮点数构造方法存在精度损失风险,在精确计算或值比较的场景中会导致业务逻辑异常。 注意:和上一条的正例不同的是,前者在经过浮点计算后已经形成了误差,在转换时用toScaledBigDecimal方法限定了精度。在此处,是为了避免因直接利用浮点数构造而导致的误差。 | |||
6 | 强制 | 在空指针异常易发的场景中,应当对对象做null判断。 | 正例:
反例:
| 在对象未判断null的情况下直接引用,容易发生空指针异常,推荐用Optional类更优雅的处理null对象。 一些空指针异常(NPE)易发的场景:
| |||
7 | 强制 | 在日期格式化时,应当使用DateUtils工具类 | 正例
反例
| DateUtils包装了常用的日期格式,避免了手动格式化时的误用风险,如:年份格式化误书写成YYYY,如本周存在跨年的情况,返回的就是下一年。 | |||
8 | 强制 | POJO类属性,禁止使用基本数据类型。 | 正例
反例:
| POJO类属性使用包装数据类型有如下优点:
|
二、集合
序号 | 等级 | 规范 | 示例 | 说明 | ||
---|---|---|---|---|---|---|
1 | 强制 | 在需要对List的subList方法返回结果进行遍历、增加、删除元素时,禁止直接变更原List中的元素。 | 反例:
| List的subList方法返回的是一个List的内部类对象,它是List的一个视图,对原List所有的操作都会反映到这个对象上。 同时,对原List进行元素的增加或删除,会被计数(modCount,结构变更次数),此数值和原subList时记录的数值(expectedModCount)不一致,会引发ConcurrentModification Exception异常。 | ||
2 | 强制 | 对集合进行for循环时,禁止在循环体内用remove/add方法。 | 正例:
反例:
| 若在for循环体内对集合元素进行remove/add操作,可能导致异常,建议使用iterator方式处理。 |
三、并发
序号 | 等级 | 规范 | 示例 | 说明 | ||
---|---|---|---|---|---|---|
1 | 强制 | 动态线程池只允许使用通义管理平台定义的(比如Poseidon),禁止自行创建。 | 正例:
反例:
| 通过Poseidon创建的线程池将能较好的进行管理和监控:
| ||
2 | 强制 | 在使用线程池时,禁止将拒绝策略设置为DiscardPolicy。 | 反例:
| 若配置了DiscardPolicy,当线程池队列排满且已达到了最大线程数后,新增任务会被直接丢弃,无任何提示,并且在结合future.get()运行时,存在阻塞的风险。 | ||
3 | 强制 | 父子任务禁止使用同一个线程池。 | 反例:
| 父子任务使用同一个线程池容易相互影响,线程数达上限时,子任务等待线程资源,而同时,父任务因子任务未完成,其资源得不到释放,最终可能导致相互等待或死锁。 | ||
4 | 强制 | 在多线程环境下,禁止直接使用HashMap。 | 正例:
反例:
| HashMap是线程不安全的,在容量不够进行resize时,可能因并发出现死链,导致CPU飙升。 |
四、日志
序号 | 等级 | 规范 | 示例 | 说明 | ||
---|---|---|---|---|---|---|
1 | 强制 | 日志级别只允许使用ERROR、WARN、INFO、DEBUG。 | 正例:
|
| ||
2 | 强制 | 业务受损或预期外的异常场景,应当打印ERROR日志。 | 正例:
反例:
| ERROR日志用于描述异常不可控的场景,当该类异常发生的时候会给业务和系统带来伤害,需要第一时间告警并介入排查修复。 | ||
3 | 强制 | 业务不受损且预期内的异常场景,应当打印WARN日志。 | 正例:
| WARN日志用于描述异常可控的场景,当该类异常发生的时候不会给业务和系统带来伤害,用于记录和观测,指导进一步处理。 | ||
4 | 推荐 | 打印日志时,建议使用占位符的方式拼装内容。 | 正例:
反例:
| ”+“ 拼接会多次调用StringBuilder的append()方式,每一次append的时候会计算字符串的长度以及重新分配一次内存,对性能有一定的损耗。 此外,“+”拼接方式无论本条日志是否打印都会计算长度和分配内存,而占位符的方式仅在打印的时候才进行内存分配。 | ||
5 | 推荐 | 打印日志时,不建议使用JSON工具将对象转换成String。 | 正例
反例:
| 如果对象里某些get方法被覆写,存在抛出异常的风险,进而影响正常业务流程。 | ||
6 | 推荐 | 异常日志内容中应当包含三要素:异常场景、异常数据、异常堆栈。 | 正例:
反例:
| 异常日志内容应记录关键的信息(异常场景、异常数据、异常堆栈),为问题排查提供有效帮助,能更高效的处理线上故障。 三要素包含: 异常场景:出现异常的业务场景说明。 异常数据:出现异常的数据(比如下单场景,需要记录商品ID、用户ID等信息)。 异常堆栈:异常堆栈信息。 |
五、安全
序号 | 等级 | 规范 | 示例 | 说明 | ||
---|---|---|---|---|---|---|
1 | 强制 | 用户敏感数据禁止直接展示、禁止用Get方式提交。 | 反例:
| 手机号、银行卡卡号、身份证、车牌、车架号等都属于用户敏感信息,不能直接展示。 脱敏方式:
禁止用Get方式提交,这种方式在URL上带有敏感数据,将会在wan/lan日志中出现这些元数据。 | ||
2 | 强制 | 用户输入的参数,禁止直接拼接到SQL访问数据库。 | 反例:
| 用户输入的参数可能带有SQL片段,存在SQL注入的风险,需要使用参数绑定的技术来防范。 | ||
3 | 强制 | 未经许可,禁止外发公司任何程序代码。 | 反例:
| 程序代码属于公司资产,在未经许可的情况下不得以任何方式(邮件、IM软件、纸质打印等)向外传输或公开,包括但不仅限于:
|
相关文章:
JAVA|后端编码规范
目录 零、引言 一、基础 二、集合 三、并发 四、日志 五、安全 零、引言 规范等级: 【强制】:强制遵守,来源于线上历史故障,将通过工具进行检查。【推荐】:推荐遵守,来源于日常代码审查、开发人员反馈…...

重写B站(网页、后端、小程序)
1. 网页端 1.1 框架 Vue ElementUI axios 1.2 框架搭建步骤 搭建Vue 1.3 配置文件 main.js import {createApp} from vue import ElementUi from element-plus import element-plus/dist/index.css; import axios from "axios"; import router from…...

文档债务拖累交付速度?5大优化策略文档自动化
开发者在追求开发速度的过程中,往往会忽视文档的编写,如省略设计文档、代码注释或API文档等。这种做法往往导致在后期调试阶段需要花费三倍以上的时间来理解代码逻辑,进而形成所谓的文档债务,严重拖累交付速度并造成资源浪费。而积…...

【数据结构与算法】LeetCode 每日三题
如果你已经对数据结构与算法略知一二,现在正在复习数据结构与算法的一些重点知识 ------------------------------------------------------------------------------------------------------------------------- 关注我🌈,每天更新总结文章…...

基于深度学习的电力负荷预测研究
一、深度学习模型框架 在当今数字化时代,基于深度学习的电力负荷预测研究正成为保障电力系统稳定、高效运行的关键领域。其模型构建是一个复杂而精妙的过程,涉及多学科知识与前沿技术的融合应用。首先,要明确电力负荷预测的目标,…...

篇章十 消息持久化(二)
目录 1.消息持久化-创建MessageFileManger类 1.1 创建一个类 1.2 创建关于路径的方法 1.3 定义内部类 1.4 实现消息统计文件读写 1.5 实现创建消息目录和文件 1.6 实现删除消息目录和文件 1.7 实现消息序列化 1. 消息序列化的一些概念: 2. 方案选择…...

【IDEA】删除/替换文件中所有包含某个字符串的行
目录 前言 正则表达式 示例 使用方法 前言 在日常开发中,频繁地删除无用代码或清理空行是不可避免的操作。许多开发者希望找到一种高效的方式,避免手动选中代码再删除的繁琐过程。 使用正则表达式是处理字符串的一个非常有效的方法。 正则表达式 …...

基于深度学习的不良驾驶行为为识别检测
一.研究目的 随着全球汽车保有量持续增长,交通安全问题日益严峻,由不良驾驶行为(如疲劳驾驶、接打电话、急加速/急刹车等)引发的交通事故频发,不仅威胁生命财产安全,还加剧交通拥堵与环境污染。传统识别方…...
FD+Mysql的Insert时的字段赋值乱码问题
方法一 FDQuery4.SQL.Text : INSERT INTO 信息表 (中心, 分组) values(:中心,:分组); FDQuery4.Params[0].DataType : ftWideString; //必须加这个数据类型的定义,否则会有乱码 FDQuery4.Params[1].DataType : ftWideString; //ftstring就不行,必须是…...

第十周作业
一、CSRF 1、DVWA-High等级 2、使用Burp生成CSRF利用POC并实现攻击 二、SSRF:file_get_content实验,要求获取ssrf.php的源码 三、RCE 1、 ThinkPHP 2、 Weblogic 3、Shiro...

Python操作PDF书签详解 - 添加、修改、提取和删除
目录 简介 使用工具 Python 向 PDF 添加书签 添加书签 添加嵌套书签 Python 修改 PDF 书签 Python 展开或折叠 PDF 书签 Python 提取 PDF 书签 Python 删除 PDF 书签 简介 PDF 书签是 PDF 文件中的导航工具,通常包含一个标题和一个跳转位置(如…...
One-shot和Zero-shot的区别以及使用场景
Zero-shot是模型在没有任务相关训练数据的情况下进行预测,依赖预训练知识。 One-shot则是提供一个示例,帮助模型理解任务。两者的核心区别在于是否提供示例,以及模型如何利用这些信息。 在机器学习和自然语言处理中,Zero-Shot 和…...
微软 Build 2025:开启 AI 智能体时代的产业革命
在 2025 年 5 月 19 日的微软 Build 开发者大会上,萨提亚・纳德拉以 "我们已进入 AI 智能体时代" 的宣言,正式拉开了人工智能发展的新纪元。这场汇聚了奥特曼、黄仁勋、马斯克三位科技领袖的盛会,不仅发布了 50 余项创新产品&#…...

集星獭 | 重塑集成体验:新版编排重构仿真电商订单数据入库
概要介绍 新版服务编排以可视化模式驱动电商订单入库流程升级,实现订单、客户、库存、发票、发货等环节的自动化处理。流程中通过循环节点、判断逻辑与数据查询的编排,完成了低代码构建业务逻辑,极大提升订单处理效率与业务响应速度。 背景…...

多模态大语言模型arxiv论文略读(八十八)
MammothModa: Multi-Modal Large Language Model ➡️ 论文标题:MammothModa: Multi-Modal Large Language Model ➡️ 论文作者:Qi She, Junwen Pan, Xin Wan, Rui Zhang, Dawei Lu, Kai Huang ➡️ 研究机构: ByteDance, Beijing, China ➡️ 问题背景…...
创建Workforce
创建你的Workforce 3.3.1 简单实践 1. 创建 Workforce 实例 想要使用 Workforce,首先需要创建一个 Workforce 实例。下面是最简单的示例: from camel.agents import ChatAgent from camel.models import ModelFactory from camel.types import Model…...
Cribl 中 Parser 扮演着重要的角色 + 例子
先看文档: Parser | Cribl Docs Parser The Parser Function can be used to extract fields out of events or reserialize (rewrite) events with a subset of fields. Reserialization will preserve the format of the events. For example, if an event contains comma…...

WebSocket 从入门到进阶实战
好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受. 聊天系统是WebSocket的最佳实践,以下是使用WebSocket技术实现的一个聊天系统的关键代码,可以通过这些关键代码ÿ…...

CSS:vertical-align用法以及布局小案例(较难)
文章目录 一、vertical-align说明二、布局案例 一、vertical-align说明 上面的文字介绍,估计大家也看不懂 二、布局案例...
Linux 正则表达式 扩展正则表达式 gawk
什么是正则表达式 正则表达式是我们所定义的模式模板(pattern template),Linux工具用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时,使用正则表达式对数据进行模式匹配。如果数据匹配…...

Java转Go日记(五十四):gin路由
1. 基本路由 gin 框架中采用的路由库是基于httprouter做的 地址为:https://github.com/julienschmidt/httprouter package mainimport ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/", func(c …...

【解决】自己的域名任何端口都访问不到,公网地址正常访问,服务器报错500。
一、问题描述 后端项目部署在服务器上,通过域名访问接口服务器报错500,通过浏览器访问域名的任何端口都是无法访问此网站。 但是通过公网地址访问是可以正常访问到的,感觉是域名出现了问题 二、解决过程 先说结论:问题原因是…...
探秘鸿蒙 HarmonyOS NEXT:Navigation 组件的全面解析
鸿蒙 ArkTS 语言中 Navigation 组件的全面解析 一、引言 本文章基于HarmonyOS NEXT操作系统,API12以上的版本。 在鸿蒙应用开发中,ArkTS 作为一种简洁、高效的开发语言,为开发者提供了丰富的组件库。其中,Navigation 组件在构建…...
订单导入(常见问题和sql)
1.印章取行,有几行取几行 union select PARAM07 name, case when regexp_count(PO_PARAM_20, chr(10)) > 0 then substr(PO_PARAM_20, 0, instr(PO_PARAM_20, chr(10)) - 1) else PO_PARAM_20 end value,PO_ID …...
PyTorch中diag_embed和transpose函数使用详解
torch.diag_embed 是 PyTorch 中用于将一个向量(或批量向量)**嵌入为对角矩阵(或批量对角矩阵)**的函数。它常用于图神经网络(GNN)或线性代数中生成对角矩阵。 函数原型 torch.diag_embed(input, offset0,…...
算法分析与设计实验:找零钱问题的贪心算法与动态规划解决方案
在计算机科学中,贪心算法和动态规划是两种常用的算法设计策略。本文将通过一个经典的找零钱问题,详细讲解这两种算法的实现和应用。我们将会提供完整的C代码,并对代码进行详细解释,帮助读者更好地理解和掌握这两种算法。 问题描述…...

制作 MacOS系统 の Heic动态壁纸
了解动态桌面壁纸 当macOS 10.14发布后,会发现系统带有动态桌面壁纸,设置后,我们的桌面背景将随着一天从早上、到下午、再到晚上的推移而发生微妙的变化。 虽然有些软件也有类似的动态变化效果,但是在新系统中默认的HEIC格式的动…...

大数据 笔记
kafka kafka作为消息队列为什么发送和消费消息这么快? 消息分区:不受单台服务器的限制,可以不受限的处理更多的数据顺序读写:磁盘顺序读写,提升读写效率页缓存:把磁盘中的数据缓存到内存中,把…...
js中encodeURIComponent函数使用场景
encodeURIComponent 是 JavaScript 中的一个内置函数,它的作用是: 将字符串编码为可以安全放入 URL 的形式。 ✅ 为什么需要它? URL 中有一些字符是有特殊意义的,比如: ? 用来开始查询参数 & 分隔多个参数 连接…...
iOS工厂模式
iOS工厂模式 文章目录 iOS工厂模式简单工厂模式(Simple Factory)工厂方法模式(Factory Method)抽象工厂模式(Abstract Factory)三种模式对比 简单工厂模式(Simple Factory) 定义&am…...