<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ongoing's blog</title><link>https://ongoingblog.org/</link><description>ongoing 的中文技术博客：Java、Spring、数据库、DevOps、工具链等</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Tue, 23 Jun 2026 10:53:51 +0800</lastBuildDate><atom:link href="https://ongoingblog.org/index.xml" rel="self" type="application/rss+xml"/><item><title>个人对账模块架构</title><link>https://ongoingblog.org/2026/06/personal-reconciliation-module-architecture/</link><pubDate>Tue, 23 Jun 2026 10:53:51 +0800</pubDate><guid>https://ongoingblog.org/2026/06/personal-reconciliation-module-architecture/</guid><description>一、背景 大学时期，我曾经用过记账软件，就是支出了一笔，就手动记一笔，但是没几个星期，这种记法就停掉了，因为很麻烦。
后来，使用了表格软件，自己按照一些字段简单记起来，当然也是手动记账，这次是按照周来记的，每周一去记上周的开销，逐个去打开银行软件和支付软件，找到上周的账单，逐个统计到我的表中，这次坚持了比较长的时间，一两年吧。
很快，我又不再去进行了，还是两个字，麻烦。
我找到了一个叫作 beancount 的复式记账 cli 软件，依然也是需要手动的，没咋开始用，也没有继续尝试。
不再进行记账了，似乎记账、不记账都无所谓，因为我记了之后也不会去翻看过去...</description></item><item><title>为博客接入 AI search 和 AI chat</title><link>https://ongoingblog.org/2026/06/enable-ai-search-and-ai-chat-for-the-blog/</link><pubDate>Mon, 22 Jun 2026 19:32:58 +0800</pubDate><guid>https://ongoingblog.org/2026/06/enable-ai-search-and-ai-chat-for-the-blog/</guid><description>一、建立博客的 AI search 实例，让平台实例抓取博客网页生成数据库 二、整合 AI search 和 AI chat 到博客中，部署 三、查看下效果 AI search Cloudflare 官方博客 用的也是这个 AI chat 四、注意 如果被爬取的网页内容是中文的，那最好用中文来提问，效果好的不是一星半点。
如果出现了问题，要用好平台上这个“Ask AI”的工具，最好用英文去询问。中文组织好后，让 AI 翻译下，贴到这个工具里，这个工具比较智能的一点是，它会先去看你当前的界面信息 如果你的问题就是当前界面出现的，那回答就会很准确。比较好用。...</description></item><item><title>Cloudflare Workers AI</title><link>https://ongoingblog.org/2026/06/cloudflare-workers-ai/</link><pubDate>Mon, 22 Jun 2026 10:45:41 +0800</pubDate><guid>https://ongoingblog.org/2026/06/cloudflare-workers-ai/</guid><description>一、调用方式对比 WORKERS AI VS AI GATEWAY AI gateway 仅仅是调用者和模型之间的代理。 通过 Workers AI 调用和 AI gateway 调用的区别 日志 26.06.21 Sun 放弃直连方式了，第一个是因为使用 Workers AI 可以联结更多平台上的组件，第二个是因为 api key 可以部署在平台内部，而非让客户端去传递到平台。</description></item><item><title>擦除 pdf 隐私文字区域</title><link>https://ongoingblog.org/2026/05/erase-privacy-text-areas-in-pdf/</link><pubDate>Wed, 20 May 2026 14:56:57 +0800</pubDate><guid>https://ongoingblog.org/2026/05/erase-privacy-text-areas-in-pdf/</guid><description>有时 pdf 文档中有些隐私的内容需要抹掉，可以使用 macos preview 工具。</description></item><item><title>照片隐私处理</title><link>https://ongoingblog.org/2026/05/photo-privacy-processing/</link><pubDate>Mon, 18 May 2026 11:13:31 +0800</pubDate><guid>https://ongoingblog.org/2026/05/photo-privacy-processing/</guid><description>MacOS 平台。
重新设置更新时间
touch -m your_photo.jpg 重新设置创建时间
SetFile -d &amp;amp;#34;$(date &amp;amp;#39;+%m/%d/%Y %H:%M:%S&amp;amp;#39;)&amp;amp;#34; your_photo.jpg 添加水印
使用预览打开图片
添加文字
设置文字不透明度</description></item><item><title>银行交易中的借贷方向</title><link>https://ongoingblog.org/2026/05/debit-and-credit-directions-in-banking-transactions/</link><pubDate>Sat, 16 May 2026 09:55:47 +0800</pubDate><guid>https://ongoingblog.org/2026/05/debit-and-credit-directions-in-banking-transactions/</guid><description>一句话总结“借”和“贷”的含义： 在复式记账里，它们只是“左”和“右”两个记账方向，不代表生活里的借钱或贷款。哪个方向代表增加，要看账户类型，跟“借、贷”这两个字本身的意思完全无关。
之前的开发模式 一般记账的话，例如 A 给 B 转账 5 元，之前的就是借 A 贷 B，这里借就是扣减，贷就是增加。 当时所有的都是这样开发的，自然去认为谁转钱，谁就是借方了。
问了下 deepseek 后，它说我给搞反了。
它先给我介绍了下
要看账户类型： 资产类账户（现金、银行存款、应收账款等）：借增贷减 负债/权益类账户（借款、应付账款、实收资本等）：贷增借减 收入类...</description></item><item><title>WPS 行转列方法</title><link>https://ongoingblog.org/2026/05/wps/</link><pubDate>Tue, 12 May 2026 16:51:43 +0800</pubDate><guid>https://ongoingblog.org/2026/05/wps/</guid><description> 02/21复制到wps表格总是变成2月21日，有什么办法让它不变</description></item><item><title>Claude Code</title><link>https://ongoingblog.org/2026/05/claude-code-cli/</link><pubDate>Mon, 04 May 2026 11:29:19 +0800</pubDate><guid>https://ongoingblog.org/2026/05/claude-code-cli/</guid><description>最近因为 cursor 额度用完了，需要找个替代品。但是我想着另起一个账号再订阅一次的，刷短视频看到好多博主在用 claude cli + deepseek v4 pro。 我想着也尝试了。
很久之前都听说过 claude code，自己也尝试过 cursor cli，试用了下，发现并不是很惊艳，还是用回了自己的 gui 界面
但是这次使用 cc cli + v4 pro 模型，这个体验可以说很好、很好。
一个是关于配置的，一些规范可以集成到我维护很久的 dotfiles 仓库中去，但是 cursor 属于那种用完了，就用完了，我也没心思去把这个工具的配...</description></item><item><title>java.time.format.DateTimeFormatter</title><link>https://ongoingblog.org/2026/05/java-date-time/</link><pubDate>Mon, 04 May 2026 11:15:21 +0800</pubDate><guid>https://ongoingblog.org/2026/05/java-date-time/</guid><description>今天在解析账单时，解析日期时突然报错，根据字符串和给定的日期格式得到了 null，因为涉及到很多种账单，发现这些账单的日期其实是不同的，有的月是 09，有的月是 9，这种两位和一位的情况比较多。
但是原先我设置的格式就是按照yyyy-MM-dd HH:mm来的，所以遇到不符合这种严格格式的日期，就解析不出来了。
我第一个想法是在 catch 语句块中去尝试第二种适配的日期格式去解析，如果还是不行，就再选一个，当然这种做饭很“丑陋”。
我之前还看到过有人是按照位置去截取，我认为这种方法会更危险。
问了下 deepseek，它回答我说
正确解析方法：使用“宽...</description></item><item><title>一致性哈希</title><link>https://ongoingblog.org/2026/01/consistent-hashing/</link><pubDate>Fri, 23 Jan 2026 10:52:33 +0800</pubDate><guid>https://ongoingblog.org/2026/01/consistent-hashing/</guid><description>对服务器数量取模，当服务器新增或者减少时，导致每个元素都是重新计算哈希值。
对固定值取模，每个新增或者减少一个，只会影响到下一个结点，影响范围大大减少。</description></item><item><title>MySQL 中的锁</title><link>https://ongoingblog.org/2026/01/lock-in-mysql/</link><pubDate>Wed, 21 Jan 2026 20:25:48 +0800</pubDate><guid>https://ongoingblog.org/2026/01/lock-in-mysql/</guid><description>https://dev.mysql.com/doc/refman/8.4/en/innodb-locking.html#innodb-gap-locks
Shared and Exclusive Locks Record Locks Gap Locks 中文名间隙锁，索引记录间的间隙。
Next-Key Locks 是 recode lock 和 gap lock 的组合。</description></item><item><title>MySQL 主从复制</title><link>https://ongoingblog.org/2026/01/mysql-repli/</link><pubDate>Wed, 21 Jan 2026 10:58:49 +0800</pubDate><guid>https://ongoingblog.org/2026/01/mysql-repli/</guid><description>使用 dump 命令可以进行数据库的复制。
通过 binlog 进行主从复制。 主从复制的整体流程如下：
主库在事务内写入 binlog 主库通过 dump 线程和 从库 IO 线程之间建立的连接，把 binlog event 传输给从库 从库 IO 线程读取到主库传输的 binlog event，写入本地的 relay log 从库的 SQL 线程读取 relay log，回放对应事务操作 从库
IO 线程负责从主库接收 binlog 日志，并保存在本地的 relay log 中 SQL 线程负责解析和重放 relay log 中的 event bin...</description></item><item><title>The Z Garbage Collector</title><link>https://ongoingblog.org/2026/01/zgc/</link><pubDate>Fri, 16 Jan 2026 19:25:33 +0800</pubDate><guid>https://ongoingblog.org/2026/01/zgc/</guid><description> https://wiki.openjdk.org/spaces/zgc/overview
支持从 8 MB 到 16 TB 的堆
保持一致的亚毫秒暂停时间
可以使用以下命令启用 ZGC
-XX:+UseZGC G1 收集器的设计目标是取代 CMS 收集器，它同 CMS 相比，在以下方面表现的更出色：
G1 是一个有整理内存过程的垃圾收集器，不会产生很多内存碎片。 G1 的 Stop The World(STW) 更可控，G1 在停顿时间上添加了预测机制，用户可以指定期望停顿时间。 注：这里的 Mutator 代指应用程序线程。</description></item><item><title>布隆过滤器</title><link>https://ongoingblog.org/2026/01/bloom-filter/</link><pubDate>Mon, 05 Jan 2026 12:51:22 +0800</pubDate><guid>https://ongoingblog.org/2026/01/bloom-filter/</guid><description>缓存经典的三种异常场景
场景 描述 解决方案 缓存穿透 数据库根本没有数据，所以缓存也没有。大量无效 key 全部涌入数据库查询 布隆过滤器 缓存击穿 缓存失效瞬间并发打到数据库，也就是很多都是无效查询。 在 redis 和数据库之间加分布式锁，限制只有一个会去查成功。 缓存雪崩 大量 key 同时过期 解决：差异化缓存时间，不要让那么多的 key 同时失效。 一、角色 初始时过滤器的位数组内容全都为 0:
put 元素进去后，这个元素经过不同的 hash 函数计算出对应的下标，命中的置为 1:
只有全为 1 的元素才被允许继续，有为 0 的那就不用再走...</description></item><item><title>JDK21 - Virtual Thread(虚拟线程)</title><link>https://ongoingblog.org/2025/12/virtual-thread/</link><pubDate>Fri, 26 Dec 2025 11:24:13 +0800</pubDate><guid>https://ongoingblog.org/2025/12/virtual-thread/</guid><description> 虚拟线程是 JVM 层面的用户态线程，上下文切换由 JVM 完成，避免了内核态和用户态的切换。
目标：方便写出 thread-per-request style 的代码。
下面是一些 https://openjdk.org/jeps/444 的摘抄。
A virtual thread is an instance of java.lang.Thread that is not tied to a particular OS thread. A platform thread, by contrast, is an instance of...</description></item><item><title>LongAdder</title><link>https://ongoingblog.org/2025/12/longadder/</link><pubDate>Fri, 19 Dec 2025 10:36:08 +0800</pubDate><guid>https://ongoingblog.org/2025/12/longadder/</guid><description>LongAdder 真的好快啊。 如果不是金额类的计算，是那种接受误差的实时统计的话，肯定要用这个工具了。
8 线程共享计数器，每个线程计算 100 万。 80 线程共享计数器，每个线程计算 100 万。 在当前 Cell 竞争失败了，会去其他 Cell 再进行竞争，不会在当前的 Cell 进行竞争。</description></item><item><title>调用 Object.wait() 方法之后</title><link>https://ongoingblog.org/2025/12/after-call-object-wait-method/</link><pubDate>Thu, 18 Dec 2025 11:03:24 +0800</pubDate><guid>https://ongoingblog.org/2025/12/after-call-object-wait-method/</guid><description>因为之前看到一个词叫作虚假唤醒，我一遍只是记得书中在强调使用 while 子句进行检查，而不是用if子句检查，但是对这个印象比较深刻。
但是我并不知道是为什么，因为我觉得这两种效果都是一样的，先来看下我之前是如何理解的。
之前的理解 (错误的) if 版本 synchronized (lock) { // 2、当线程唤醒后，我之前理解的再次获取锁是从这里开始的 if (condition == false) { lock.wait(); // 1、线程停在这里... } doBusinessLogic(); } where 版本 synchronized...</description></item><item><title>Springboot starter 的初始化时机</title><link>https://ongoingblog.org/2025/12/springboot-starter/</link><pubDate>Fri, 12 Dec 2025 14:53:04 +0800</pubDate><guid>https://ongoingblog.org/2025/12/springboot-starter/</guid><description>先来看下自动配置类是如何被加载的，流程如下：
来一个简单的示例，你定义的一个自己的场景启动器（starter）
这里项目的 spring.factories 文件中定义了一个键值对，键就是熟悉的注解@EnableAutoConfiguration，值是业务定义的配置类。
这个配置类只是简单地声明了一个业务类。
这就是一个简单的 starter 项目。</description></item><item><title>中断</title><link>https://ongoingblog.org/2025/12/interrupt/</link><pubDate>Wed, 03 Dec 2025 19:00:48 +0800</pubDate><guid>https://ongoingblog.org/2025/12/interrupt/</guid><description>我之前一直不太理解中断这个概念在程序中到底是什么含义。
生活中这个概念当然很容易理解，比如你在做事情 A，别人打断你，让你去做其他事情。
但是在 Java 中中断是什么含义呢？ 线程 A 在执行，其他线程去中断线程 A。似乎是同样的含义。 之前我以为线程 A 当场就会反应针对这个中断进行反应，可能是直接报错什么的。 现在我在看了一些资料后，发现中断也是一种线程间的沟通交流方式，就像 wait 和 notify 一样。
它是一种通知，一种信号。 类似酶和受体， 有对酶起反应的受体，受体就会有相应的化学反应发生。 如果没有受体或者没有对那种酶产生反应的受体的...</description></item><item><title>Spring MVC</title><link>https://ongoingblog.org/2025/11/spring-mvc/</link><pubDate>Wed, 26 Nov 2025 09:46:49 +0800</pubDate><guid>https://ongoingblog.org/2025/11/spring-mvc/</guid><description>框架接受请求并处理的流程。
一、DispatcherServlet 继承图 二、扫描流程 三、触发流程 （一）、@GetMapping （二）、@PostMapping</description></item><item><title>hikaricp</title><link>https://ongoingblog.org/2025/11/hikaricp/</link><pubDate>Wed, 26 Nov 2025 09:46:30 +0800</pubDate><guid>https://ongoingblog.org/2025/11/hikaricp/</guid><description>版本 1.1.1 主要版本的参数配置 todo
com.zaxxer.hikari.util.FastList
add 和 remove 都取消了范围检查 remove 从最后位置进行遍历</description></item><item><title>Spring retry</title><link>https://ongoingblog.org/2025/11/spring-retry/</link><pubDate>Wed, 26 Nov 2025 09:46:06 +0800</pubDate><guid>https://ongoingblog.org/2025/11/spring-retry/</guid><description/></item><item><title>MBean</title><link>https://ongoingblog.org/2025/11/mbean/</link><pubDate>Mon, 24 Nov 2025 18:27:52 +0800</pubDate><guid>https://ongoingblog.org/2025/11/mbean/</guid><description>在看 hikaricp 源码时，看到了这样一句
初始化 HikariPool 时
检查配置合法性 赋值配置属性 注册 MBean 启动内务整理 daemon 线程 填满连接池 这里第 3 点，会将连接池对象和连接池配置对象注册为 MBean。
主要是为了方便监控，如下图，这是在 jconsole 中显示的内容：</description></item><item><title>jconsole</title><link>https://ongoingblog.org/2025/11/jconsole/</link><pubDate>Mon, 24 Nov 2025 18:11:44 +0800</pubDate><guid>https://ongoingblog.org/2025/11/jconsole/</guid><description>直接在命令行中输入jconsole即可打开，选择对应的进程。可以查看堆的使用情况。</description></item><item><title>Spring 注解：@Value</title><link>https://ongoingblog.org/2025/11/annotation-value/</link><pubDate>Wed, 19 Nov 2025 16:05:09 +0800</pubDate><guid>https://ongoingblog.org/2025/11/annotation-value/</guid><description>处理流程图如下</description></item><item><title>WeakReference</title><link>https://ongoingblog.org/2025/11/weak-reference/</link><pubDate>Wed, 19 Nov 2025 10:12:15 +0800</pubDate><guid>https://ongoingblog.org/2025/11/weak-reference/</guid><description>Java 中的 Reference 类型
strong reference WeakReference SoftReference PhantomReference 一、WeakReference</description></item><item><title>Java label 语法</title><link>https://ongoingblog.org/2025/11/java-label/</link><pubDate>Wed, 12 Nov 2025 23:36:59 +0800</pubDate><guid>https://ongoingblog.org/2025/11/java-label/</guid><description> 我在 java.util.concurrent.ThreadPoolExecutor 中看到上图的这个 retry 字段
看了下，是 java 的一种 label 语法，通常用于多层循环。 不然还得一层层剥开往外跳。</description></item><item><title>this 引用的逃逸</title><link>https://ongoingblog.org/2025/11/this-escape/</link><pubDate>Tue, 04 Nov 2025 19:50:10 +0800</pubDate><guid>https://ongoingblog.org/2025/11/this-escape/</guid><description>今天继续在看《JCIP》这本书。关于线程安全这里有说一个名词this escape，叫作 this 引用逃逸。它举了一个例子，但是不是很理解，给的例子如下
public class ThisEscape { public ThisEscape(EventSource eventSource) { eventSource.registerListener() { new EventListener() { public void handleEvent(Object event) { doSomething(e); } } } } } 之后去问了下...</description></item><item><title>draw.io 如何打开多个文件</title><link>https://ongoingblog.org/2025/10/drawio-open-mulit-files/</link><pubDate>Thu, 30 Oct 2025 10:47:26 +0800</pubDate><guid>https://ongoingblog.org/2025/10/drawio-open-mulit-files/</guid><description/></item><item><title>rocketmq: broker store</title><link>https://ongoingblog.org/2025/10/broker-store/</link><pubDate>Fri, 24 Oct 2025 13:16:05 +0800</pubDate><guid>https://ongoingblog.org/2025/10/broker-store/</guid><description>一、broker 收取消息流程 二、MessageStore 存储消息流程</description></item></channel></rss>