- 博客(39)
- 收藏
- 关注
原创 ThreadLocal
Java 中的 ThreadLocal 是一个线程的局部变量,它消除了多线程的数据读写争用,它一般用于一个线程在多个不同方法里的数据传递,比如会话登录,一请求一线程,Spring 事务等。
2024-01-25 16:05:54 382
原创 Netty Pipeline
Netty 中的业务处理流程都是在 Pipeline 中被处理的,它底层是一个双向链表,链表元素是ChannelInBoundHandler 和 ChannelOutBoundHandler,二者都是 ChannelHandler 接口类,一个 Channel 拥有一个 Pipeline, 当 Channel 被创建时会创建一个空的Pipeline。
2024-01-25 10:13:24 387
原创 Netty Reactor 模式解析
上面短短的服务端代码做了很多工作,当它刚启动还没有客户端请求连接时,bossGroup 连接线程池里的一个线程 EventLoop 会初始化一个 NioServerSocketChannel ,并把这个Channel注册到这个EventLoop 持有的IO多路复用选择器Selector里,Selector 会监听Channel里的 SelectionKey.OP_ACCEPT 事件,一旦有客户端连接过来,它会通过下面代码获取到一个。在写Netty 服务端代码的时候,下面的代码时必不可少的,这是为什么呢?
2024-01-24 15:26:37 654
原创 Netty 中的读和写
ChannelInboundHandler 使用了责任链模式,每个 ChannelInboundHandler 就相当于一个拦截器,对它感兴趣的数据进行处理,比如编解码,解析http,websocket协议等,ChannelOutboundHandler 对数据进行写操作,它底层是一个Entry 链表。1,在简单的手写Netty demo项目中,Netty 读和写数据都是对 Channel 的读和写,也就是对NioSocketChannel 中的 SelectableChannel 的读和写。
2024-01-23 10:34:56 378
原创 python 全量同步和增量同步实践
简单的增量同步可以使用定时断点同步,即使用定时任务获取从库的上次备份的最后一条数据,从最大的id处开始定时同步数据,同时多传递一个 id 参数,我们的id是long类型,是有序递增的,如果id 不是有序递增的,如果 create_time 是有序递增的也可以。我们可以监听主库的binlog,然后把 insert,update,delete 语句解析出来,到从库重新执行一遍。如果我们要做整库数据迁移和同步,我们可以先同步库表结构等元数据,再去同步表数据。它要求数据库开启 binlog,且数据格式为 row。
2024-01-16 16:22:50 549
原创 写一个水平分表插件
2,SQL 解析,使用 JSqlParser 或 druid 的 SQL 解析器去获取静态 SQL 的路由键和路由键实际参数。因为如果找不到路由键,那就扫全表,如果找不到路由键实际参数,就不知道要路由到哪些子表,也要扫全表。这些只能完成比较简单的单表增删改查,无法应对项目里复杂的 SQL 需求,还需要做其他的工作。1, 解析路由配置,知道哪些表需要路由,哪些表不需要路由,并知道路由参数;3,根据路由键和路由参数计算目标路由表,生成新的 SQL。
2023-09-07 16:06:19 105
原创 Spring Boot 制作 Windows 客户端
2,当客户端更新时就下载一个新的 exe 文件到本地,使用 sc config 修改 exe 文件的地址,然后使用 taskkill 杀死服务,因为该服务有崩溃重启功能,所以过了几秒钟后,服务重启了,服务变为新服务。1,之前我们使用 Spring Boot 去做 Windows 的客户端,使用 exe4j 这个工具把 jar 包打成 exe 文件,选择“服务”模式,最后使用 Windows 的 sc 命令注册该 exe 文件为 windows 服务,并设置为自动模式,失败重启。.bat 批处理脚本。
2023-08-17 19:12:15 280
原创 Netty 思想
但它的所有的 IO 操作都是异步的,全是各种 Future,Promise(Promise也是一种特殊的Future),因为 jdk 1.5 的 Future 没有事件监听功能,所以Netty 自己实现的 Future 具有事件监听回调,这是常规的异步操作,jdk 1.8 有了 CompleteFuture ,就不需要自己手动实现异步监听回调了,非常方便。2,Java 里的异步操作,底层基本上都是通过线程池去实现的,因为新开一个线程去执行任务,其实就是最基本的异步操作。
2023-08-17 18:53:23 44
原创 Mybatis 插件: MySQL sql 语句转换为合法的达梦sql语句
项目已经运行了很多年了,里面有大量的 SQL 语句,底层数据库都是 MySQL,现在要迁移到达梦数据库,怎么办?一开始的解决方案是这样的,先拷贝一份 mapper xml 文件, 再在上面改 SQL ,SQL 功能逻辑不变,可能就是小修小改, SQL 语句无非就是增删改查,而且大多数都是单表的增删改查,只是多费一些时间而已,但怎么知道这个 SQL 语句要不要改?改了后怎么测试它是正确的?很多人都属性 MySQL 但不熟悉达梦,这时候就要开始去看别人踩过的坑,下载一份官方手册,对照着看,估计一下工作量了。
2023-05-12 23:51:20 3386 2
原创 单调栈的用法
1,只有对题目和解法真的知根知底,对算法的每一个运算过程都能在草稿纸上画出来,才算是懂了,为了避免遗忘,最好要记一下笔记。解法: 1,使用单调栈对数组for循环。2,用栈顺序地记录每一个数组元素的索引位置。3,对于当前遍历的数组元素值C 大于当前栈顶索引所指向的数组元素值B,使用while循环依次弹出小于C的栈顶元素,每弹出一个元素,记录C和栈顶元素值的差值,保存到res数组。class Solution { public int[] dailyTemperat...
2021-08-25 00:26:43 154
原创 树的递归题解
今天做了三道解法差不多的三道题目,它们的递归形式都很类似,因为树的题目大多都和遍历,递归有关,就是深度优先搜索。然后总结了一下树递归的模板:1,定义一个dfs()的递归函数,传入一棵树和保存的容器。2,对该树为null的情况进行判断。3,对左子树进行dfs()的递归,保存左子树的递归结果。4,对右子树进行dfs()的递归,保存右子树的递归结果。5,已知本树的根节点的值,本节点左子树的递归结果,本节点右子树的递归结果,做一些计算,用map或list保存计算结果。6,返回本次的递归结
2021-06-22 22:54:39 180 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人