- 博客(523)
- 资源 (4)
- 收藏
- 关注
原创 上层应用如何为其所依赖的基础SDK里的静态属性赋值?
我们的系统对商户暴露了RestAPI,供合作商户以API的形式接入。为了提高合作商户侧API接入的开发效率,我编写了一个SDK。下面是这个SDK一个工具类,封装了API数据加解密、API数字签名的工具方法。这些工具方法都是静态方法。在这个中,有两个静态field,和,分别是我们系统的数字签名RSA公私钥。和这两个field的值,需要被依赖的上层应用来赋值。那么,要实现 SDK 中的工具类能够从上层应用获取和。
2025-06-05 09:45:00
410
原创 一个Mybatisplus组件扫描不当引起的bug:弄巧成拙,认真的锅,自我怀疑
问题就在于 datamig 的这个自动配置class,它扫描了 MybatisPlusMapperScanConfig, 这就导致 sby-biz-component 中所有的 Mapper接口类都作为spring容器的bean生效了。例如,刷完碗,为了控水,我会把一个碗倒扣在另外两个碗上,然后,自己在忙活中,不小心把碗碰到了地上,结果就碎碎平安了~在我们系统基建层的业务组件包 sby-biz-component 中,最初,我写了两个业务组件,一个是 通道错误码组件,一个是 审核流水组件。
2025-05-27 09:04:00
929
原创 代码易读性实践
查询数据涉及到读缓存时,可以在方法名中加入缓存相关的词汇,比如Cache、Cached、WithCache等,可以明确表达方法使用了缓存。同时,需要避免使用可能引起歧义的词汇,比如本案例中的“No”,本意是表示“序号”(Number),但与“Cache”结合一起,NoCache,容易让人产生负面联想为“不走缓存”/“没有缓存”。下面6行代码,是在给一个转账对象进行赋值操作,其中包括3个转出账户的属性,和3个转入账户的属性。如果没有,自己手撸一下,在你的IDE里写出来这6行。我在DAO里定义了一个方法,
2025-05-20 11:26:00
253
原创 开窍了!如何为缓存工具类(CacheUtil中的static方法)定义interface(2)
那么,我没有办法了!我曾经在遥远的2017年听过一个架构师讲过类似场景的解决方案,可惜的是,忘却了,脑子里只留下“讲解过”这三个字了。直到最近,我才想到方案。
2025-04-28 09:12:00
397
原创 开窍了!如何为缓存工具类(CacheUtil中的static方法)定义interface(下)
那么,我没有办法了!我曾经在遥远的2017年听过一个架构师讲过类似场景的解决方案,可惜的是,忘却了,脑子里只留下“讲解过”这三个字了。直到最近,我才想到方案。
2025-04-28 09:12:00
328
原创 开窍了!如何为缓存工具类(CacheUtil中的static方法)定义interface
那么,我没有办法了!我曾经在遥远的2017年听过一个架构师讲过类似场景的解决方案,可惜的是,忘却了,脑子里只留下“讲解过”这三个字了。直到最近,我才想到方案。(>>
2025-04-28 09:11:00
394
原创 开窍了!如何为缓存工具类(CacheUtil中的static方法)定义interface(上)
那么,我没有办法了!我曾经在遥远的2017年听过一个架构师讲过类似场景的解决方案,可惜的是,忘却了,脑子里只留下“讲解过”这三个字了。直到最近,我才想到方案。(>>
2025-04-28 09:11:00
191
原创 小重构,大收益!技术重构实践:如何优雅升级老旧接口
小重构,大收益!本次小重构通过版本化路径设计和响应格式分层兼容,在不破坏现有调用的前提下实现了接口的标准化升级,显著提升了接口的可维护性、调用方体验和错误处理能力。
2025-04-22 21:19:00
760
原创 lexer(词法分析器)与 parser(语法分析器)
Lexer是编译器的初始处理模块,主要任务是将输入的原始字符流(如源代码)拆解为具有特定意义的词法单元(token)。例如,对于代码片段int x = 5;,Lexer会识别出关键字int、标识符x、运算符、数字5和分隔符;,每个元素被标记为独立的Token并附带类型信息。这种转换使得后续的语法分析器能更高效地处理代码结构。FastJSON中的具体实现词法分析器(JSONLexer)源码类核心方法public int token() { ... } // 当前Token类型。
2025-04-21 16:05:00
726
原创 FastJSON 对 `Integer` 类型的编解码(序列化和反序列化)
/ 处理十六进制字符串 "0xFF" → 255FastJSON 通过实现了Integer直接操作原始类型(int等基础类型,primitive type)避免性能损耗。支持多种输入格式(整数、字符串、其他数字类型)。严格校验非法输入,保证数据安全。这种设计模式可以完全复用到自定义类型(如Money)的编解码实现中。
2025-04-21 15:24:00
700
原创 AI都深度思考了,人却不思考了...
AI 虽强大,但它的 “思考” 是基于数据训练,无法替代程序员对业务的理解、对技术的创新探索。【结语】如今,AI 代码生成工具如 Copilot、Cursor 等,能基于简单提示快速输出代码片段,甚至完成复杂功能模块,其 “思考” 速度与覆盖范围令人惊叹。但不少程序员却因此过度依赖,遇到问题便直接让 AI 生成代码,不再主动分析需求、构思算法逻辑,也不深入理解代码背后的原理与设计模式。当人放弃思考,就如同失去灵魂的躯壳,难以形成独特见解,创造力也会被逐渐磨灭。小三、小四的师傅工匠李得知后,一眼发现了问题。
2025-04-20 12:03:00
432
原创 代码 “歪楼”:Money 类在程序里的离奇 “旅程”
这段代码是一个简单的金额赋值操作,本可以非常简洁地实现,但实际采用了较为复杂的方式。这背后反映出了编码意识的浅薄。且不说这个绕路导致的代码执行效率方面的性能损耗和资源浪费。单说代码质量方面,也违背 KISS 原则(Keep It Simple, Stupid)。KISS原则强调代码应该尽可能简单。此代码没有遵循该原则,增加了不必要的复杂度,不符合简洁高效的编码理念。如果不及时纠正这种现象,类似的问题可能会在项目中不断出现,导致代码质量逐渐下降,增加项目的维护成本和风险。
2025-04-05 19:15:00
836
原创 恕我直言,你不懂开发
我发现,多数同学,即使有几年的开发经验,但在应用开发中,思考的比较少。开发一个功能其实是比较容易的,大家都能完成,不过,如果缺乏必要的思考,上来就是干,那么,往往编写的代码要么不易读,要么耦合度高,要么代码结构混乱,要么扩展性不足。这样的代码一多,系统就成了所谓的烂系统了。带来的恶果就是可维护性差,维护成本高,这无疑会大大降低团队的开发效率。我看过许多这样的缺乏思考、缺乏设计的代码,阅读这样的代码有时会感到啼笑皆非。
2025-03-30 22:45:00
590
原创 如你所期,DataIdNameVO 来了!
小改动,大收益!我们通过分析我们复杂的企业系统,抽象出来这个 DataIdNameVO,很大程序上可以降低程序的复杂度,增强代码的可读性,并能提高开发效率。站在宏观的角度,利用OOP设计思想,来不断重构、调优系统,使之可持续发展。当然,这首先需要我们具备这样的能力 和 意识!
2025-03-30 10:39:00
755
原创 如何精准做到合同到期后不再发生业务?还是邻家系统做得真好!
本文以“合同”为例,来探讨特定应用场景的程序设计方案。合同数据包含生效日 和 到期日。到了合同的到期日,合同涉及的业务就不能再做了。这是企业应用系统中常见的应用场景。即:业务发生时,要判断对应的合同是否有效合同到期时,要标记为“已到期”我们先定义合同的数据结构:名称类型说明contactIdint合同ideffectiveTimedate生效...
2025-02-27 22:59:00
428
原创 缓存过期的惰性删除(Lazy Deletion)策略
缓存过期 - 惰性删除(Lazy Deletion)是一种用于处理缓存过期的策略,它在读取缓存数据时才去判断缓存项是否过期,如果过期则将其删除并返回空值,而不是在缓存项过期的瞬间就立即进行删除操作。以下从原理、优缺点、适用场景、实现示例几个方面为你详细介绍:原理在采用惰性删除策略的缓存系统中,为每个缓存项设置了过期时间,但系统不会主动去监控这些缓存项是否过期。当客户端发起对某个缓存项的读取请...
2025-02-27 22:33:00
646
原创 一则修复数据的case,来看什么是*解决问题要彻底*
我司年久不修的商旅系统,今天突然遇到一个问题,程序执行的一个sql时出现数据类型转换异常。经排查,这是一个多表join的sql。select ... from t_enterprise ent join t_passenger psg on ent.ent_id = psg.ent_idwhere ...上面sql涉及的企业表t_enterprise里,ent_id是bigint。企...
2025-02-27 21:59:00
151
原创 Oops! 更改field的数据类型,影响到rabbitmq消费了...(有关于Java序列化)
程序中有如下entity类-LevyPaymentFlow@Data@TableName(value = "levy_payment_flow", autoResultMap = true)public class LevyPaymentFlow implements Serializable { private static final long serialVersionUID...
2025-02-20 15:20:00
520
原创 【研发笔记250214】do what you do
do what you do.开发团队里曾经一个中级开发水平的小伙因为KPI不达标而被优化。离职前小伙跟我说:“战哥,我觉得咱们这儿的氛围特别好!”,他接着解释:“你看昨天你觉得我把’联调时间‘命名成’joint_debug_time‘不合适,我立即就按你说的改了。你觉得我那个model定义不符合编码规范,我也立即就改了”。我只是点了点头。我其实想告诉他:我们需要的是更优秀的伙伴,能够开发...
2025-02-14 10:16:00
154
原创 【注意】sql语句where条件中的数据类型不一致,不仅存在性能问题,还会有数据准确性方面的bug......
隐式类型转换规则MySQL 在进行比较操作时,如果比较双方的数据类型不一致,通常会尝试将其中一个数据类型转换为另一个数据类型,以便进行比较。对于 select * from t_order where order_no = 1538808276987285507 ,当 order_no 为 varchar字符串类型的情况下,MySQL 会把 varchar 类型的 order_no 列的值转...
2025-02-10 22:32:00
478
原创 状态机幂等
何为状态幂等?先了解何为幂等。幂等大家应该都知道。在针对数据更新操作的幂等中,有一个实现方案是基于版本号的数据库乐观锁。在账户记账业务中,我们通常会使用这种方式。具体的姿势是下面2步(前提是表里有version):查询数据,然后执行业务逻辑处理执行完业务逻辑,在更新数据时,将数据中的version作为update语句的where条件有了这些知识,我们再来理解状态幂等,就比...
2025-01-16 21:36:00
235
原创 【研发笔记20251114】技术自信 & 不因纠结于细节而放弃本该做的事情
技术自信我们要拥有技术自信!我们许多同学,是缺乏技术自信的。我们习惯了代码有改动,就提测给测试组的同学来进行测试验证。虽说有测试组,但有些开发改动,我们开发者,凭借我们的专业能力(技术能力),可以自己确信没有问题,可以不用一律提测。例如:重命名一个底层工具类的public static方法,这会涉及到上层的项目跟着发生变更。对于这种重构来说,只要IDE可以compile通过,就没有必要...
2025-01-14 22:44:00
446
原创 来了,资金类交易业务(如电商交易、支付)中,经常提到的Money类!
资金类交易业务中 经常提到的Money类,大家了解一下。 了解了Money类,就会对资金类业务如电商交易、支付更了解。资金类业务中,金额如果处理得不好,带来的直接后果就是资金损失(资损风险)。对于研发经验不足的团队而言,经常会犯以下几种错误:不统一,存在各系统使用BigDecimal、double、long等数据类型来定义金额。手动对金额进行加、减、乘、除运算,单位(元与分)换算。...
2025-01-07 15:24:00
232
原创 浅谈分布式锁的常用实现
序言在单机时代,虽然不存在分布式锁,但也会面临资源互斥的情况,只不过在单机的情况下,如果有多个线程要同时访问某个共享资源的时候,我们可以采用线程间加锁的机制,即当某个线程获取到这个资源后,就需要对这个资源进行加锁,当使用完资源之后,再解锁,其它线程就可以接着使用了。例如,在 Java 中 synchronize/Lock 等。但是到了分布式系统的时代,这种线程之间的锁机制,就没作用了,系统可能...
2024-12-27 18:09:00
369
原创 【开发笔记041211】论“俯瞰”的重要性
2024.12初我司零工平台,为合作企业客户提供向税地服务商充值的功能,我们内部叫在线分账。我们的在线分账功能,包括充值、分账、提现、通知上账这几个步骤。具体来讲,①充值:充值指的是客户将资金转入到我们为客户开通的银行虚户里。一般有两种途径,一种是客户线下自行转入,一种是通过我司平台提供的B2B网银充值页面来操作。我们系统中这个的充值步骤,指的是后者。对于前者,我们系统会忽略此步骤。②分...
2024-12-18 10:57:00
341
原创 系统网站登录,如何合规传输用户登录密码?
对于系统登录页面来说,我们作为开发人员,应该没有陌生的吧。就像下面这样子。点击登录,调用/login 接口。来看下面截图中的 载荷(payload)数据,其中,密码 password 的值是明文。这里要说的是,用户登录密码属于用户隐私数据。首先,隐私数据属于敏感数据,不能明文传输;其次,系统server端不能直接触碰用户密码。也就是说,server端程序不能知道用户真实的登录密码。...
2024-12-17 21:42:00
454
原创 知识就是力量?
我司零工结算平台的系统架构模式是:前端的bosskg业务线-----→中台的RPC服务-----→后端的税地服务商系统。其中,bosskg提供了商户结算的HTTP接口,zhongtai-trans为bosskg等业务线提供付款交易服务。bosskg为每个商户提供一个商户id,商户侧系统通过HTTP调用bosskg提供的商户结算查询API,进行结算结果的查询。显然,bosskg的商户结算查询A...
2024-12-09 21:38:00
291
原创 开发一份API接口,需要注意这些,看你做到了几项
在实际工作中,我们需要经常跟外部三方系统打交道,可能会提供API接口给外部三方系统调用。API接口通常通过WebController来实现。如果设计一个优雅的API接口,能够满足安全性、稳定性、易维护等多方面需求呢?下面几项,看你做到了哪些。1. 数字签名为了防止API接口中的数据被篡改,我们需要对接口做签名。接口请求方将请求参数 + 时间戳 + 密钥拼接成一个字符串,然后通过md5...
2024-11-20 10:15:00
1384
原创 API接口的请求参数要更名,如何保持代码可读性?
接口参数名与程序里定义的model属性名,是完全一致的吗?本文通过案例,来讲述他们之间的联系与区别。1我们会补贴系统对外暴露的获取收银台地址的API,响应参数是一个url地址,这个url地址包含一个参数,就是我们的订单号。形如:http://***.com/#/pages/orderPay/index?orderNo=4d2b8e3f9a6c4e278b5e对应到程序里的spring...
2024-11-18 21:26:00
291
原创 发现一肉鸡接口,快来围攻啦~
系统登录页面,为防止明文传输用户密码,开发者做了安全加固。服务端暴露一个 loginEncryptKey 的API,用来根据登录名 username 获取 加密秘钥 encryptKey。 前端页面 获取到 encryptKey 后,在请求login登录接口时,会对 用户密码 进行加密传输。这个 loginEncryptKey 接口的服务端怎么写的呢?下面是完整代码,其中SysLoginMo...
2024-11-11 12:46:00
294
原创 【聚合系统业务场景设计】异步回调先于同步响应,怎么办?
以请求三方付款为例,通常是先发起付款请求,然后等待三方异步通知付款结果,或者我方主动调三方查询付款结果。见下方时序示意图。#我方聚合系统三方支付系统#1发起付款请求→接收付款请求,处理付款#2.1接收请求,变更付款状态←←付款完成,主动回调#2.2主动查单→接收查单请求,返回付款状态本文我们谈回调,所以让我们细化其中的#1、#2.1,下面时序示意...
2024-11-04 20:29:00
360
原创 【开发笔记241025】她趣介意时效超5分钟的付款交易。简单一招,应对!
她趣介意时效超5分钟的付款交易。简单一招,应对!我们平台近期入网一个新客户是她趣。她趣这个企业比较关注下发时效,他们那边系统做了告警,当存在超5分钟时效的交易,就会发告警。然后,那边的人就来质问。并声称,现在只是放了3%的量,就总出现下发慢的交易,如果10月份剩下的这5天里依然存在,就不打算用我们这个通道了。销售经理询问有什么办法,连销售老大老董都亲自来找我们技术老大了。近期系统交易量大,而...
2024-10-31 20:56:00
254
原创 Mybatisplus TableInfoHelper:获取entity对应的数据表字段列表
如题,调用 TableInfoHelper#getTableInfo(clazz) 这个工具方法可以得到entity类所对应的数据表的字段列表。import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;i...
2024-10-23 19:45:00
884
原创 发现问题就解决,往往是低效的方式。关于对象参数的赋值取值问题
走查我们zhongtai-task(中台的task服务,注意,这个task不是Spring/Java里的task,而是我司业务中的企业用工任务)代码时发现一个问题。先看下面的方法调用关系①TaskJobProxy#updateTaskStatus②TaskLevyReviewServiceImpl#levyAudit↘↙③TaskApplyS...
2024-10-22 09:28:00
496
原创 spring mybatis upgrade to mybatisplus 实战小记
我司压箱底儿的灵工服务商系统,系统框架是spring,持久层是mybatis。最近,将Mybatisplus集成到系统中,以提高开发效率。升级版本:mybatis版本3.2.2,升级到3.5.16Mybatisplus版本:3.5.3mybatis-spring版本1.2.0,升级到3.0.0pagehelper版本:5.3.1【注】mybatis官方提供了My...
2024-10-22 09:27:00
488
原创 定义明确的参数名/变量名--许多时候,授人以渔还真不如直接授人以鱼
定义明确的参数名/变量名,是软件开发中的一个重要准则。但是,总这么强调,起的作用似乎并不大。许多时候,授人以渔还真不如直接授人以鱼。所以,我们具象化,看一个栗子。下面是一个业务服务类UserTagService中的一个私有方法。这个方法控制业务逻辑并调用仓储类UserTagManager实现向user_tag表批量新增数据。 user_tag表是用户技能标签表,字段包括 用户id、用户名(u...
2024-10-22 09:27:00
334
原创 程序埋点(Event Tracking)
程序埋点(Event Tracking)是指在软件程序中嵌入记录用户行为或系统运行状态的代码,以便收集数据用于分析和监控。程序埋点通常用于分析用户行为、性能监控、问题排查、产品优化等目的。何时使用程序埋点:用户行为分析:了解用户在应用中的行为,例如点击量、页面访问次数等。性能监控:监控应用性能指标,如响应时间、资源利用率等。问题排查:记录应用中的异常情况,帮助定位和解决问题。产品优化...
2024-09-27 09:00:00
535
原创 系统里这个同时查冷热表的sql,动动手指,从12s降到3s
系统将交易数据按交易时间分为热表(最近3个月)和冷表(3个月前)。为保证用户体验,当企业门户端查询跨越冷热表时,尤其针对大客户,查询性能优化至关重要。以下是程序的SQL查询语句及其优化版本。系统里的交易数据按交易时间做了冷热表分离(热表仅存储最近3个月的交易数据,3个月前的交易数据自动结转至冷表),我们内部运营系统的交易查询功能进行了冷热数据分开查询。然后企业客户端呢,为了不影响用户体...
2024-09-26 21:18:00
473
原创 redis序列化数据时,如何包含clsss类型信息?
通过配置 `com.fasterxml.jackson.databind.ObjectMapper` 的 `enableDefaultTyping` 方法,可以使序列化后的 JSON 包含类信息。大家可能留意过,在redis里缓存的数据经常有下面两种形式。不难发现,这两者的区别就是后者包含了JavaObject类型信息。{"levyName":"test","levyCode"...
2024-09-24 20:11:00
536
使用sql server Profiler监听应用程序执行的sql
2013-11-08
tomcat-redis-session-manager-1.2.jar
2021-07-23
jsonclassgenerator源码
2016-04-29
TA创建的收藏夹 TA关注的收藏夹
TA关注的人