- 博客(27)
- 收藏
- 关注
原创 Redis 持久化详解
AOF重写完成后,会向主进程发送信号,这时主进程会将重写缓冲区内的数据写入AOF,并将新的AOF文件替换原来的。子线程重写AOF文件,具体就是逐一把内存数据的键值对转换成一条命令,再将命令记录到重写日志,誊录完覆盖原有的AOF日志。内存数据的全量快照,加载比较快,数据量也更小,但由于是全量,不可能像AOF一样秒级存储,相对来说RDB丢失数据的风险更大。bgsave的子进程赋值数据与AOF重写是类似的,主进程要修改此时共享的内存里的数据,发生。写入AOF,这期间主进程执行的写操作产生的新数据依旧会存在。
2024-07-22 20:38:07
97
原创 JVM类加载机制详解
Java在运行期才对类进行加载到内存、连接、初始化过程。这使得Java应用具有极高的灵活性和拓展性,可以依赖运行期进行动态加载和动态连接。主要加载哪些?Java中的数据类型分为基本数据类型和引用数据类型,基本数据类型由虚拟机预先定义,而引用数据类型需要进行类的加载。对于同一个类加载器,类只加载一次,但对于不同的类加载器可以将类多次加载到内存并相互隔离。装载阶段,查找并加载类的二进制数据,生成该类的数据结构和Class的实例。验证阶段保证加载的字节码是合法、合理并符合规范的。为类的静态分配内存,并将其初始化
2024-07-22 19:42:59
614
原创 RabbitMQ线程和连接模型详解
客户端单个connection对应的单个channel实际上是单线程的,每次收到Socket消息都触发处理逻辑,从任务队列里面取出一定的任务进行依次处理,如果一个channel订阅了多个topic的话也是单线程依次处理的。rabbitmq采用的amqp协议,是一个高级的应用层协议。消息底层是用帧来包装,有分心跳帧和携带方法或信息的帧。Consumer也是带有queue的。工作线程池和心跳线程会在消费者(服务端)启动时初始化。客户端的消息(请求)需要进过经过信道到达服务端。信道是一种逻辑上的连接通道,多个信道
2024-07-20 16:05:35
610
原创 敲详细的springboot中使用RabbitMQ的源码解析
@RabbitListener的方式在实际使用时创建MessagingMessageListenerAdapter,这个对象是ChannelAwareMessageListener接口的实现类,实现了onMessage()方法,这个方法利用了适配器模式。使用消费者Consumer和监听器Listener的概念。默认情况下,springboot中消费者为单线程串行消费的模型,体现了队列的特性。MessageListenerContainer是在spring项目中使用RabbitMQ关键的类,用来接收并处理消息
2024-07-19 20:28:52
1641
原创 Redis 主从复制、哨兵机制关键参数与命令
replicaof psync进行数据同步命令folk()创建子进程。bgsave主服务器节点异步持久化,生成RGB文件runID主服务器的 runID。offset复制的进度replication buffer第一次同步期间的新数据,命令传播即连接中的新数据,重连后增量数据repl backlog buffer增量同步,环形缓冲区,主节点记录近期的数据master_repl_offsetslave_repl_offset
2024-07-19 14:00:36
570
原创 MySQL中的幻读究竟是怎么回事?
幻读是指同一条select语句在不同时刻返回不同的结果集。例如第二次查询比第一次多了一条记录,就如同幻象一般。
2024-07-18 22:03:29
313
原创 MySQL中为什么不推荐使用 text 类型?
或者使用对象存储,有些业务场景表用到TEXT,BLOB类型,存储的一些图片信息,比如商品的图片,更新频率比较低,可以考虑使用对象存储,例如阿里云的OSS,AWS的S3都可以,能够方便且高效的实现这类需求。由于text类型的数据的长度是可变的,会有和varchar一样的问题,由于存储在数据页中,频繁的更新或删除可能导致产生较多的空间碎片,造成磁盘空间浪费和使得查询性能下降。但如果对于需要经常读取的场合,则就需要考虑借用其他专门的文件系统来存储,而在我们的表中就使用文件系统的路径或引用。
2024-07-18 21:59:06
449
原创 MySQL 溢出页、页分裂、表空间碎片
页分裂主要出现在数据乱序插入时,需要插入到数据页的中间位置,并且数据页已经没有办法存下插入的数据,就需要考虑页分裂,拉取一个新的空白页,并将新纪录和原数据页的部分内容迁移。页的大小是固定的(16K),如果有一条记录非常大(如text类型),则一个页无法存储这条记录,需要借助溢出页。表空间碎片是指数据页中没有被填满数据,总是留有一些不连续的空隙,且这些空隙往往不能被利用。
2024-07-16 13:15:05
681
原创 布隆过滤器、HyperLogLog、BitMap
布隆过滤器、HyperLogLog和BitMap是Redis中重要的组件和数据类型,应该它们有相似的特性,所以放一起记录一下。
2024-07-16 11:05:28
258
原创 分分钟开发一个能用Spring快速启动的SDK
SDK例如下载的mybatis包,引入starter 依赖,在pom中配置,就可以轻松使用。比如API调用平台项目每次调用接口都需要自己写客户端,并且写签名认证算法、传递签名参数、生成随机数、时间戳等一系列东西非常麻烦。开发者在实际使用时只关心要提供的参数(密钥等)和APP的配置与使用,对于随机数、时间戳并不关心。有了SDK就只需要引入starter 依赖,在pom中配置,就可以直接创建一个客户端,轻松使用。
2024-06-06 19:09:55
1023
原创 Springboot项目Netty-WebSocket前后端消息交互
最近在用消息队列处理可能会时间较长的任务,用户在提交后可以先做别的,处理的过程会异步完成,完成后及时通知用户。如何实现?首先分析一下我们的需求:(1)即时通信,我不知道什么时候需要发送消息,所以希望双方能提前建立连接或者保持长时间的连接(2)需要服务器端主动向客户端发送消息。Netty作为一个成熟的开源项目,经过了广泛的实战检验,拥有活跃的社区支持和持续的更新维护。Netty 提供异步的、基于事件驱动的网络应用程序框架,用以快速开发高性能、高可靠性的网络 IO 程序,是目前最流行的 NIO 框架。
2024-06-06 13:23:07
710
原创 WebSocket实现前后端消息交互
这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。要保持客户端程序的在线状态,就需要向服务器轮询,即不断地向服务器发起连接请求,举例来说,我们想要查询当前的排队情况,只能是页面轮询向服务器发出请求,服务器返回查询结果。首先分析一下我们的需求:(1)即时通信,我不知道什么时候需要发送消息,所以希望双方能提前建立连接或者保持长时间的连接(2)需要服务器端主动向客户端发送消息。
2024-06-05 20:11:30
2233
原创 用NIO实现在线群聊
用Java里NIO的原生API搭建一个在线群聊系统。编写一个NIO群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞)能够实现多人群聊(多客户端)服务器端:可以监测用户上线,离线,并实现消息转发功能客户端:通过Channel可以无阻塞发送消息给其它所有用户,同时可以接受其它用户发送的消息(由服务器转发得到)serverSocketChannel是否有,有就会在中把serverSocketChannel的下来)socketChannel是否有,有就会在中把socketChannel的下来)触发。
2024-06-05 19:54:41
750
原创 AT分布式事务机制剖析
AT模式一种分布式事务模式,支持本地 ACID 事务的关系型数据库(mysql、oracle)的Java 应用的分布式事务管理。不同的微服务需要操作多个数据库,需要保证它们同时成功或同时失败。阿里巴巴的seata框架为例介绍AT事务模式,以事务管理器TM,事务协调者,资源管理器RM组成。一阶段业务数据和回滚日志记录同一个本地事务中在获取全局锁后提交,释放本地锁和连接资源;二阶段:如果没有异常异步化提交,非常快速地完成;如果有异常回滚通过一阶段的回滚日志进行反向补偿;
2024-06-05 19:49:27
1014
原创 【解惑】RabbitMQ中交换机Exchange的定义
消息发送端配置rabbitmq去找交换机,接收端还是去找同一个交换机。队列的定义是放发送端,而在后面是放在消费端,交换机在接收端和发送端都有定义。消费者和生产者两端都有信道channel,但是连接两者的(交换机+队列)都是绑定好的。找到消费端找到交换机,就说明找到组织了,因为队列相对来说没有那么重要,很多时候都可以使用临时队列(没有名字的)。连接消费者和生产者(交换机+队列)只有一组,消息可以被被转发到不同的交换机,交换机可以绑定多个队列(fanout),队列也可以绑定多个交换机,队列可以被多个消费者消费。
2024-01-05 15:00:25
872
1
原创 RabbitMQ消息确认机制详解
RabbitMQ消息确认详解:消费者在获取到消息后,会向服务端发送ACK确认,这时消息会立刻删除。消息发布确认要确保消息成功发送到服务端broker。确保RabbitMQ消息的可靠性。开启生产者确认机制,确保生产者的消息能到达队列;设置备份交换机,将无法路由到队列的消息送到备份队列;开启持久化功能,确保消息未消费前在队列中不会丢失;开启消费者应答机制,设置自动应答或手动应答回调;开启消费者失败重试机制,设置重试次数和间隔时间;开启消息恢复机制,重试机会耗尽的消息投递到异常交换机,交由人工处理。
2024-01-05 14:46:02
1576
1
原创 【ServerSocketChannel详解】
ServerSocketChannel是面向流的监听socket套接字的可选择性通道。具有以下特点:具有阻塞和非阻塞两种模式;可以注册到多路复用器上(且一般都与复用器配合使用);基于TCP连接;需要绑定到特定端口上;是线程安全的。SocketChannel提供了连接到socket的通道,提供了类似于java.net包中对于网络操作的api的功能。既然已经有连接到Socket套接字的通道,可以主动发起连接、传输数据(client端),功能就是接收连接、接收数据的通道(server端)。
2023-12-05 14:39:29
585
原创 【SocketChannel详解】
SocketChannel是一种面向流的连接socket套接字的可选择通道。SocketChannel 作为网络 IO 通道,具体负责进行读写操作。NIO把缓冲区的数据写入通道,或者把通道里的数据读到缓冲区。具有特点:是用来连接Socket套接字的,主要用途用来处理网络I/O的通道,是基于TCP连接传输,SocketChannel实现了可选择通道,可以被多路复用的。
2023-12-05 14:29:27
856
原创 HttpServlet和DispatcherServlet的区别
HttpServlet和DispatcherServlet是原生和MVC中封装的servlet的区别。Servlet定义一套处理网络请求的规范,但并不能直接处理请求,而是由tomcat监听端口,根据url等信息,确定要将请求交给哪个servlet去处理,service方法返回响应对象,再返回给客户端。dispatcherServlet是子接口,作为一个前端控制器为每个请求配置一个统一的servlet来处理,体现了MVC和代码解耦理念的支持,起到了路由分发的作用,根据配置的节点有效地将请求转发到控制器方法。
2023-12-03 16:24:47
507
1
原创 JAVA属性初始化顺序
属性分为静态属性和非静态属性,参与初始化或者说赋值顺序的,JAVA类的属性的初始化方式有默认初始化,定义时显式初始化,代码块赋值,构造器赋值,spring@value属性注入。为考虑不同的情况,细分为①静态变量默认初始化②静态变量显式赋值③非静态代码块赋值④静态代码块赋值⑤创建对象⑥构造器赋值⑦spring@value属性注入⑧非静态变量默认初始化⑨非静态变量显式初始化,此外我们额外插入一个⑤创建对象来对标划分整个过程以便更好理解。现在来一一比较各种方式赋值的先后顺序。
2023-10-19 16:30:04
194
1
原创 【解惑】全搞懂弗洛伊德算法
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。弗洛伊德算法可以说是求最短距离算法中代码最简单的(就三层for循环),但是它的思想却不简单,本文的重点在于彻底搞懂弗洛伊德算法,解答可能的疑点!
2023-09-07 19:46:42
1312
1
原创 一文秒懂迪克斯特拉Dijkstra算法
迪克斯特拉Dijkstra算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块,且权值不能为负。
2023-09-03 11:01:10
2468
原创 一文搞懂KMP算法和next数组
本文结合了较多博主的见解,结合自己的思考,全面详细地剖析KMP算法以及next数组的运作过程,帮助大家直接痛处,分分钟拿下KMP算法。
2023-08-31 14:05:14
120
原创 线索化二叉树的遍历(容易理解)
二叉树的遍历,以中序遍历为例,参考下图1,需要频繁的递归和出入栈,如当节点没有右儿子,后继节点其实没有那么容易判断,如图2的E点,而且如果不通过递归和栈的性质将很难获得其后继, 这可能会占用额外的内存,而且也不容易理解。线索是一种对二叉树的操作,意思是对二叉树进行线索化,其目的是使线索化后的二叉树具有方便被遍历的特点,即。
2023-08-26 04:00:00
68
原创 希尔排序详解
希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序(Diminishing Increment Sort)。
2023-08-21 11:57:53
720
1
原创 泛型通配符“?“的使用详解
Java在使用泛型时,C 与 C 是并列的两个类,没有子父类关系,也就不能相互赋值。如 ArrayList 与 ArrayList 没有关系,这使得在给方法传参时,通用性很差。使用通配符C能使得代码的兼容性更好。但是通配符?在读取和写入数据及有限制条件的情况下的使用有特别的规定,本文主要讲解了这方面的内容。
2023-08-16 15:18:20
564
1
原创 一文搞懂JAVA中forEach()方法的使用
在集合、Stream中都出现了forEach()方法实现对其中元素的遍历,forEach()传入的Consumer对象参数可以用lambda表达式或方法引用来进一步简化表达。
2023-08-14 17:40:38
565
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人