- 博客(596)
- 资源 (4)
- 收藏
- 关注
原创 公司季度会建议,记录一下。
暂不提这个拒绝,单说领导对这个建议的认可,其实,这个建议与我的初版建议相比,区别并不大。原因不光是针对这个建议本身,而是另有原因,首先是我们迟交被点名了,其次是他刚参加完另一个比较有压抑的会议。最后,我采用了其中一个伙伴的下面的建议,在领导默许下,提交给了季度会组织者。季度会前一晚,领导又叮嘱让我们改一下提交的建议,他显然也意识到我们3人提交的建议并不妥当。我首先想到的系统的用户体验(UX),整理并通过AI反复修改,有了下面的建议。anyway,作为一线管理者,我未重视公司工作,需要深刻反思。
2026-10-19 10:32:00
153
原创 邮件正文该不该写入log?----通过【lombok注解语法糖】实现从 整块屏蔽 到 安全预览
一次邮件 DTO 日志脱敏的取舍 —— 三条泄露路径、两种方案,以及为什么"少打印一点"比"完全不打印"更可取。
2026-09-18 22:48:00
234
原创 交易成功还要记 3 笔账?我们直接砍到 1 笔—— 网络红包记账的一次自顶向下业务层重构
随着 j'j'l 系统交易量的增多,并发交易量也跟着增多(每秒高达 80 多笔),系统优化、尤其是性能优化,成了首要任务。j'j'l 网络红包的交易涉及企业校验、风控&延迟风控、交易单&通道单落库、资金冻结记账、请求三方通道、结果落库、同步与异步查单等环节。这个时候,必须自顶向下,从宏观角度分析业务——因为业务层的优化,往往收益最大。自顶向下,业务先行。先从宏观业务找空间,而不是一头扎进技术细节。业务层的一个模式调整,收益远超底层几十处微调。质疑"约定俗成"。
2026-09-10 10:09:00
113
原创 分享一次针对hardcode的小重构:不要把 package 名写死在代码里
actually,真正麻烦的往往不是那些不能编译的代码,而是那些可以正常编译、正常启动,却在运行时悄悄改变行为的代码。所在的 package,并匹配这个 package及其所有子 package 下的 Controller。package 发生变化时,编译器仍然不会提醒我们,IDE 的 package 重构也仍然可能遗漏它。很多时候,它只是拒绝随手写下一个字符串,主动寻找一个类型更明确、意图更清楚、能够得到编译器帮助的实现。是的,没有必要为了“看起来更灵活”,再引入一套当前并不需要的规则。
2026-09-09 20:56:00
228
原创 聚合系统设计:如何为银行代付通道抽象出公共的代付接口能力
这次讨论源于代码评审中的一个小问题:四个泛型会不会增加程序的理解成本?从表面上看,它只是一个接口声明有点长的问题。但继续往下思考,就会涉及方法重写、方法重载、多态、泛型以及里氏替换原则。我们曾经尝试直接去掉泛型。后来,经编码验证,发现行不通。最终的解决办法也谈不上多么高深:保留准确的泛型设计,再用抽象类隐藏大多数实现不需要关心的复杂度。这个过程带给我的思考是:好的设计,不是简单地让代码变短,而是把必要的复杂度放到正确的位置。
2026-09-07 09:38:00
294
原创 如何自定义 MyBatis枚举处理器(EnumTypeHandler):分享从 “同包同名 shadow 覆盖” 到 “官方扩展点” 的重构经历
SIGNsign4MyBatis 默认的只支持按枚举名精确匹配,读到sign或4会直接抛,导致历史脏数据、跨系统数据无法正常读取。一个健壮的系统需要兼容这种“异常”数据的情况。这次重构没有增加任何新功能——兼容逻辑原封不动,只改了类的包路径和注册方式(从"顶替官方类"改为"通过官方扩展点注册")。但正是这两点改动,把一段"碰巧能跑"的代码,变成了"必然能跑"的代码。如果某个行为的正确性取决于"顺序"、"恰好"、"没人动它",那它就是脆弱的。
2026-08-25 20:54:00
383
原创 如何自定义 MyBatis/MyBatis-Plus枚举处理器(EnumTypeHandler):分享从 “同包同名 shadow 覆盖” 到 “官方扩展点” 的重构经历
SIGNsign4MyBatis 默认的只支持按枚举名精确匹配,读到sign或4会直接抛,导致历史脏数据、跨系统数据无法正常读取。一个健壮的系统需要兼容这种“异常”数据的情况。这次重构没有增加任何新功能——兼容逻辑原封不动,只改了类的包路径和注册方式(从"顶替官方类"改为"通过官方扩展点注册")。但正是这两点改动,把一段"碰巧能跑"的代码,变成了"必然能跑"的代码。如果某个行为的正确性取决于"顺序"、"恰好"、"没人动它",那它就是脆弱的。
2026-08-25 20:54:00
379
原创 这儿也改状态,那儿也改状态,连AI都理不清楚了… 不妨试试这个状态机good-practice
在我们的企业应用系统中,业务数据的状态流转是最常见的场景之一。每个枚举值代表一个状态机事件。从这个枚举类可以清晰看到下面的。
2026-08-04 21:56:00
341
原创 业务解耦的经典实践:从订单表解耦开票业务说起(以滴滴网约车开票为例)
维度改造前(需求直译模式)改造后(中间表模式)订单表写操作每次开票都要 UPDATE零写入订单表读操作每次查询待开票列表都要 SELECT零读取业务耦合开票逻辑侵入订单表完全解耦,通过中间表隔离性能影响随订单量增长线性恶化稳定,不受订单总量影响并发安全依赖订单表行锁Redis锁 + 状态乐观锁双重防护失败重试回滚状态字段,耦合订单表独立状态回滚,不影响订单表核心设计原则单向依赖:开票域依赖中间表,订单域不知道开票的存在,依赖方向清晰异步解耦。
2026-08-04 12:21:00
443
原创 从 `int` 到 `Duration`:一个缓存 API 的三次演进教会我的事
指明让调用者传“秒”。所有表示“时间段”的参数,一律使用,禁止使用int或long。回头看,从int到再到Duration,不仅仅是 API 签名变了,更是对代码质量理解的深化——高质量代码不是靠“约定”和“自觉”,而是靠类型系统和编译器来保障。我能让调用方犯错的可能性降到零吗?
2026-07-21 22:42:00
275
原创 最差实践(bad-practice):开发者在方法里直接实例化线程池对象,然后...(应用gg了)
错误做法正确做法每次方法调用都应用全局只创建一份线程池实例使用等快捷方法使用构造方法并显式指定有界队列不关心线程池参数根据业务类型合理配置核心线程数、最大线程数、队列容量不调用shutdown()注册 JVM ShutdownHook 或使用 Spring优雅关闭将线程池视为轻量对象视作重量级资源,全局复用在 Spring 中只写@Async,不配置线程池实现或显式定义Bean一句话记住是线程安全的重量级执行引擎,应当全局单例、合理配置、优雅关闭。在 Spring 中,@Async。
2026-07-09 22:38:00
328
原创 【HttpClient最差实践(bad-practice)】开发者在 http 工具方法中直接实例化 HttpClient,然后……
错误做法正确做法每次请求都整个应用只创建一个HttpClient实例不关心连接池参数根据并发量合理配置连接池不关闭HttpClient注册关闭钩子或使用容器管理生命周期将HttpClient当作轻量对象视作重量级资源,线程安全可复用误以为HttpPost也需要复用每次请求新建HttpPost,轻量且线程安全一句话记住HttpClient是线程安全的重量级执行引擎,应当全局单例、复用连接池、统一配置、妥善关闭;而HttpPost只是轻量的请求消息,每次请求新建即可。下次你在工具方法里看到。
2026-07-09 21:49:00
377
原创 Crypto、Cipher与Password:Java加密开发的三个核心概念
是Java加密扩展(JCE,Java Cryptography Extension)框架的核心类,提供加密和解密的密码功能。它不保存数据,而是执行具体的加解密运算。用官方文档的话说:“此类为加密和解密提供密码功能,构成了JCE框架的核心。Password(口令/密码)是用户用于身份验证的一组字符串。它是“你输入的那个东西”——比如登录系统时输入的。概念一句话定义在Java中的体现Crypto密码学的总称/领域包Cipher执行加解密的具体工具类Password用户身份认证的凭据String。
2026-07-07 21:46:00
376
原创 知识VS技能:如何优雅判空?
回到最初的那个问题。开发者问我的"优雅方案"到底是什么?其实不是Optional,而是在合适的场景下主动想起并运用Optional的思维习惯。技术工具永远在变,但"学以致用"的能力是贯穿始终的。知道很多道理,却依然写不好代码——原因往往不是知识不够,而是思考不够。知识就是力量,但运用知识的能力,才是真正的力量。
2026-06-21 18:45:00
293
原创 20260604SR超时问题排查
2026-06-04 09:40 ~ 2026-06-02 10:20 期间,运营后台系统的用户数据查询明显变慢,甚至超时。由大数据StarRocks集群压力过大引发。基于 SR的审计日志。
2026-06-05 18:55:00
401
原创 异常日志记录の优化实践:从 `try..catch` 看异常日志打印的正确姿势
ERROR:用于系统异常、不可恢复错误、第三方服务调用失败。WARN:用于可恢复异常、业务预期内但不希望发生的情况(如重试、降级)。INFO/DEBUG:用于业务流程记录、调试信息,一般不用于记录异常本身。一次看似简单的catch块日志记录,背后涉及了日志级别、格式规范、存储成本、排查效率、异常分类处理等多个工程权衡点。避免机械优化:理解每处修改的真实影响,而非机械执行某个最佳实践。坚持区分原则:业务异常与系统异常应采取不同的日志策略。建立全局成本观:日志存储成本远低于因信息缺失导致的。
2026-05-27 22:56:00
569
原创 推敲见文章:从 `try..catch` 看异常日志打印的正确姿势
ERROR:用于系统异常、不可恢复错误、第三方服务调用失败。WARN:用于可恢复异常、业务预期内但不希望发生的情况(如重试、降级)。INFO/DEBUG:用于业务流程记录、调试信息,一般不用于记录异常本身。一次看似简单的catch块日志记录,背后涉及了日志级别、格式规范、存储成本、排查效率、异常分类处理等多个工程权衡点。避免机械执行与简单回退:理解每处修改的真实影响和背后原因,建立自己的决策框架,而不是在几个选项间盲目摇摆。坚持分类处理原则。
2026-05-27 22:56:00
410
原创 #解决问题要彻底# 慢SQL治理完成后,如何防止同类问题“死灰复燃”?
解决一个线上慢SQL,是技术能力的体现;而思考如何防止它再次发生,则是工程素养的彰显。“解决问题要彻底”,不仅意味着修复眼前的Bug,更意味着通过代码注释、流程规范、知识传承、技术工具等多重手段,在系统中建立起防止同类错误复发的“免疫机制”。从给危险的代码块加上一个醒目的警告注释开始,我们就是在为团队积累资产,为系统的长期稳定运行铺设基石。这一个小小的举动,体现的正是对工程质量负责、对后来者负责的工匠精神。当然,注释警告是有效的临时“路标”。知识沉淀。
2026-05-14 21:30:00
601
原创 从合同甲方是荒谬的“JD”谈起:软件开发不应遗忘的“常识”
经排查,问题根源在于:系统数据库中存有合作企业的“企业自定义名称”(运营或内部人员设定的别名),也存有合作企业的“企业营业执照上的法定名称”。劳动合同、采购合同、任何具有法律约束力的书面文件,其主体名称都应是经官方登记、具有法律效力的完整名称——对企业而言,是营业执照上的名称;最近,系统在调用外部服务商API接口生成合同时,出现了令人啼笑皆非的一幕:合同中甲方的企业名称,竟然显示为“JD”。要避免这类问题,不能仅依赖开发者个人的“悟性”或“细心”,而应通过流程和方法,将“常识”的运用固化为团队的基础能力。
2026-05-14 10:08:00
527
原创 别留小尾巴/尽快剪掉小尾巴:从一次“ABA”字段重命名,谈谈“解决问题要彻底”
在软件开发中,每一个被遗忘的“小尾巴”,都是未来某个时刻的“技术债”。它们可能默默占用资源,可能引发数据歧义,也可能在某个深夜让接手同事困惑不已。“解决问题要彻底”——这不仅是态度,更是一种可通过清晰边界、趁手工具和严格流程培养的工程素养。它意味着我们不仅关注功能的“从无到有”,也同等重视工程现场的“整洁有序”。每个变更都应有清晰的开始与干净的结束。而“尽快剪掉小尾巴”,是我们对自己作品的基本尊重,也是对并肩作战的伙伴们最可靠的承诺。记住:最好的清理时机,一个是“上线时”,一个是“现在”。
2026-04-26 22:22:00
353
原创 常见的OOM错误 ( OutOfMemoryError全类型详解)
OOM类型关键特征优先排查点heap space对象太多,GC无法回收大对象、内存泄露、缓存GC时间长,回收效率低循环创建对象、字符串处理Metaspace类加载过多动态代理、反射、热部署堆外内存不足线程数超标线程池配置、递归调用array size数组过大大数组创建OOM Killer系统内存耗尽容器限制、物理内存anyway,预防优于治疗。在生产环境部署前,必须进行压力测试和内存分析,建立完善的监控体系,才能避免OOM对业务造成严重影响。
2026-04-21 22:08:00
398
原创 开发者暴露了一个无需授权访问的裸接口,我问:如果有人暴力请求怎么办?
如下方法,@UnAuthToken 注解代表无需授权访问。这个方法逻辑很简单,入参“key”是一个md5串,程序根据这个“key”去redis拿到数据,经过转换后返回。每次调用这个方法,意味着 ①会调redis ②会记操作日志那么,如果有人通过for循环多线程恶意频繁调用的话,可能就会大量地消耗redis资源。怎么对这个方法做安全加固呢?要防止这种,可以从如下几点入手,进行安全加固。(首先要保证的是操作日志异步化。“记操作日志”不是核心逻辑,将其异步化可以显著提升接口抗压能力。
2026-04-20 21:50:00
356
原创 【SQL性能优化篇】有了!治理慢SQL“WHERE create_time ORDER BY id”的良药
如何将WHERE create_time ORDER BY id的低效查询,优化为极致性能的WHERE id ORDER BY id查询?
2026-04-09 10:19:00
568
原创 【SQL性能优化篇】有了!治理慢SQL“WHERE create_time ORDER BY id”的良药---规避“Using filesort”性能杀手
如何将WHERE create_time ORDER BY id的低效查询,优化为极致性能的WHERE id ORDER BY id查询?
2026-04-09 10:19:00
504
原创 高效查询商户日终余额:一个SQL的优化实践
将“当日有流水”和“当日无流水需回溯”两种场景用UNION ALL结合起来,就得到了查询任意历史日期日终余额的完整、高性能方案。附上我们系统的完整的sql。点击查看代码FROM (SELECTt.*,) AS rnWHERE -- mer_id = '89900002398017098003' AND -- 替换为实际商户号t.create_time < DATE '2026-03-23' -- 截至3月3日。
2026-04-02 13:00:00
452
原创 Hutool 的 `TimedCache` 到期会自动清理吗? ——————hutool cache的“惰性清理“和“定期清理“
清理类型触发条件清理范围是否立即生效惰性清理调用get()等方法只检查被访问的key是定时清理定时任务触发(需手动调用所有过期key是容量清理达到缓存容量上限最近最少使用的过期项是TimedCache的自动清理机制不会立即自动清理:默认只有惰性清理需要手动启动定时清理:通过方法清理策略可配置:可以根据业务需求选择清理频率最佳实践:在创建TimedCache后立即调用,以确保过期数据会被及时清理,避免内存泄漏问题。
2026-03-23 21:04:00
411
原创 Fastjson枚举反序列化:当字符串不是枚举常量名时,会发生什么?
我们知道,对外暴露的 HTTP RestAPI 接口通常使用 JSON 格式传输数据。服务端接收到数据后,会将 JSON 字符串反序列化为对应的请求实体对象。我司灵工系统使用的是作为序列化工具。带着这个疑问,我决定一探究竟。
2026-03-16 20:20:00
421
原创 fastjson-EnumDeserializer类及源码分析
SUCCESS,FAILED,PENDING预计算策略:在初始化时计算所有可能的哈希值高效的哈希算法:FNV-1a 适合短字符串,计算快速优化查找:排序数组 + 二分查找,比 HashMap 更快灵活匹配:支持大小写不敏感、注解别名、备选名称健壮性:完善的异常处理和边界条件检查这个实现平衡了性能、功能和内存使用,是 FastJSON 高效反序列化的一个典型代表。
2026-03-16 18:32:00
422
原创 随笔20260309:我们都是围城里的人
在这几个方面,我需要提高,我的同学需要提高,我需要让我的同学提高。每个人都有自己的认知牢笼:老马看我们是"围城里的人"(觉得我们只会埋头苦干),我们看团队同学也是"围城里的人"(觉得他们用苦劳掩盖方法论的缺失)。所以,我需要思考和实践如何让自己破局,同样,我的同学需要思考和实践如何让自己破局,我需要思考和实践如何让我的同学思考和实践如何让自己破局。开年第一天,在谈到组织建设和团队管理时,老马跟职场的我们几个TL说,“别总靠个人加班、苦劳,长此以往人会崩的。而今,我的老大同样指出我等的这个短板。
2026-03-09 21:11:00
243
原创 认识2个单词:goal/target —————— 为什么Maven是 “goal“ 而不是 “target“?
设计哲学Maven Goal:强调"要完成什么"(声明式)Ant Target:强调"要执行什么"(命令式)简单记忆看到goal→ 想到Maven看到target→ 想到Ant看到task→ 想到Gradle。
2026-03-05 22:04:00
349
原创 聚合系统设计:策略模式(Strategy Pattern)在银行通道对接场景中的应用
策略模式(Strategy Pattern)定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户端。通过策略模式,我们成功地将不同银行的支付逻辑解耦。工商银行:使用特定的签名算法和通信方式建设银行:使用特殊的加密方式和请求头农业银行:需要SSL双向认证创建实现实现该银行的特定逻辑自动被Spring扫描并注册到策略工厂这样的设计使得系统具备了良好的扩展性和维护性,完全符合开闭原则。
2026-03-01 01:21:00
582
原创 这样构建对象,太帅了!—— 阶梯式Builder模式与代码整洁之道
这种阶梯式建造者模式不仅仅是一种技术实现,更是一种设计哲学的体现。优秀的API设计应该引导用户正确使用,而不是依赖文档或记忆编译时检查比运行时检查更可靠代码应该表达业务意图,而不仅仅是技术实现它尊重读者的智慧:通过清晰的命名和结构,让代码不言自明它尊重维护者的时间:通过编译时检查和良好的封装,减少调试时间它尊重业务的变化:通过灵活的设计,优雅地应对需求变更它尊重团队的合作:通过一致的约定,降低沟通成本在《代码整洁之道》中,Robert C. Martin说:"整洁的代码只做好一件事。
2026-02-26 15:09:00
410
原创 灵活用工平台-连续劳务所得税-计算器-工具类,拿走不谢
本文主要讲新规下互联网平台从业人员的劳务报酬所得的计算方法。本文关键词:个人所得(个人收入);劳务报酬所得;互联网平台劳务报酬所得;个人所得税(本文简称“个税”);
2026-02-25 21:49:11
770
原创 注意!字段数据类型不匹配,这个sql会很慢
当SQL语句中参与比较运算的两个数据类型不一致时,MySQL会自动将它们转换为相同类型,这个过程称为隐式类型转换。场景转换方向索引是否可用性能影响字符串列 = 数字值数字→字符串否全表扫描,性能极差数字列 = 字符串值字符串→数字是正常使用索引字符串列 = 字符串值无转换是最佳性能数字列 = 数字值无转换是最佳性能黄金法则永远让查询值的类型与列定义的类型保持一致。
2026-02-13 16:14:00
435
原创 还在用ArrayList?用HashSet吧!--性能对比
/ 必须正确重写equals和hashCode@Override@Override// 使用users.add(new User(1L, "张三"));boolean exists = users.contains(new User(1L, "张三"));// true。
2026-02-10 20:24:00
407
原创 分页查询还在用create_time去做降序?
优化策略核心思想适用场景利用主键排序利用自增ID与时间的强相关性,避免新建索引。按时间顺序获取最新或最旧记录。游标分页记录位置而非页码,跳过OFFSET。无限滚动、只能顺序翻页的场景。延迟关联先通过索引定位主键,再回表,减少无效IO。深分页且排序字段有索引的场景。数据库优化乃至程序优化,转换思路有时比一味增加资源更有效。在面对性能问题时,先深入理解业务逻辑(如数据生成规律)和数据库原理(如索引机制),往往能找到更优雅、更高效的解决方案。
2026-02-04 23:01:00
351
原创 从 synchronized 到 ConcurrentHashMap:一个小小的并发控制策略升级优化,证明我还是初级程序员
从一种较重的“互斥锁”模式,升级为一种更轻量的“无锁编程”模式,这一次并发控制策略的升级CASE,也许证明我还停留在初级编程阶段。当然,此前的项目中也有使用 ConcurrentHashMap,只恨书到用时方恨少。下班后消停了,我又在琢磨并发调用的问题,因为我知道 synchronized 锁的粒度比较粗,会影响性能。代码完成后,考虑到Mybatisplus调用及java反射机制的性能损耗,我使用Map来缓存数据关系。其中,考虑到并发调用,我随即在方法上加了synchronized。
2026-02-04 22:04:00
362
原创 面试题整理
这个表的state=2代表成功,另一个表state=3代表成功,第三个表state=2表示失败,第三个表的state=SUCCESS表示成功。int与Integer-基本类型与包装类型的区别、使用场景, 如 数据表对应的实体类中,int类型字段对应的 属性 为什么是Integer?学生管理系统,同样是定义“学号”,有的叫 xuehao、有的叫 sno、有的叫 studentNo。-- 如何实现这个场景?以调银行出款为例,如何为各银行抽象共同的interface能力。数据的状态字段,如何存值?
2026-01-30 00:54:00
331
原创 面试题沟通整理
这个表的state=2代表成功,另一个表state=3代表成功,第三个表state=2表示失败,第三个表的state=SUCCESS表示成功。int与Integer-基本类型与包装类型的区别、使用场景, 如 数据表对应的实体类中,int类型字段对应的 属性 为什么是Integer?学生管理系统,同样是定义“学号”,有的叫 xuehao、有的叫 sno、有的叫 studentNo。-- 如何实现这个场景?以调银行出款为例,如何为各银行抽象共同的interface能力。数据的状态字段,如何存值?
2026-01-30 00:54:00
334
使用sql server Profiler监听应用程序执行的sql
2013-11-08
tomcat-redis-session-manager-1.2.jar
2021-07-23
jsonclassgenerator源码
2016-04-29
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅