- 博客(77)
- 收藏
- 关注
原创 JVM 常见的问题
(Java Virtual Machine,Java虚拟机)是运行所有Java应用程序的软件平台。它与硬件无关,并且在任何具有JVM实现的平台上运行Java字节码,从而提供了Java程序的跨平台能力。JVM是Java运行时环境(JRE)的一部分,负责代码的加载、验证、编译以及运行。
2026-01-08 14:33:14
684
原创 redis消息队列
redis中也为我们提供了消息队列,那么是消息队列呢?Redis的list数据结构是一个双向链表,可以用来模拟出队列效果。这里的出队列操作需要使用带有R版本的拥有阻塞效果的命令,使得当消息队列中没有信息时能够阻塞等待。基于List的消息队列有哪些优缺点?优点:缺点:PubSub(发布订阅)是Redis2.0版本引入的消息传递模型。这使得消费者可以通过订阅一个或多个channel,当生产者向channel中发送信息后,订阅者能够收到相关信息,达到消息传递的效果。基于PubSub的消息队列有哪些优缺点?优点:缺
2025-10-10 22:44:11
557
原创 Redission
前面我们说的基于redis`setnx`实现的的分布式锁会存在下述问题:不可重入问题:获得锁的线程可以再次进入到相同的锁的代码块而不会死锁就叫可重入不可重试:之前基于redis实现的分布式锁只能尝试一次,我们希望当前线程在获取锁失败后,能在我们允许大的访问内再次尝试获取锁超时释放:过期时间虽然可以避免死锁的产生,但是也可能由于业务执行时间过长而超时释放锁,进而出现锁的误删问题主从一致性:数据从主机异步的同步到从机的过程中,由于主机宕机产生问题。
2025-10-10 22:37:08
1196
原创 redis分布式锁
持有锁的线程1内部由于执行业务时出现的阻塞问题,导致锁的超时释放,此时当其他线程来尝试获取这把锁,就可以拿到这把锁,然后在其他线程持有这把锁执行业务的过程中,线程1就有可能从阻塞中醒来继续执行线程1的业务,并释放这把由其他线程占有的锁。redis实现的分布式锁的释放则依靠。通过`setnx` 获取锁的同时要给锁添加一个过期时间,避免获取锁成功线程因服务宕机而无法正确释放锁,进而产生业务问题。为了解决这类问题,我们可以在手动释放锁的时候判断一下当前这把锁的归属问题,当这把锁属于自己时才能够进行锁的释放。
2025-10-09 11:52:02
295
原创 缓存大杀器-redis
当获取互斥锁失败后,直接返回过期数据。线程2想要获取数据,先查询缓存中的数据,当缓存为命中时(缓存中数据被线程1删除),线程2会接着去查询数据库,并将数据库中还未发生修改的旧数据写入缓存(缓存中依然是数据库中的旧数据),并返回给线程2。线程1查询缓存时,缓存正好失效(缓存未命中),此时线程1会去查询数据库数据,当准备将查询的数据库数据写入缓存时恰好发生线程调度,切换到线程2。缓存数据与数据库数据不一致,使得用户使用的是缓存中的过时数据,而不是数据库中的实时数据,这就会给我们的程序带来灾难性的业务问题。
2025-10-09 11:48:36
1240
原创 MySQL中的事务
事务把⼀组SQL语句打包成为⼀个整体,在这组SQL的执行过程中,要么全部成功,要么全部失败。这组SQL语句可以是一条也可以是多条。
2025-10-08 12:00:00
934
原创 Java Database Connectivity
JDBC的工作原理(Java Database Connectivity)是一种用于的API(应用程序接口)。它提供了一种标准的方法,允许Java程序使用SQL语句来访问和操作关系型数据库,使开发者能够编写数据库的程序。
2025-10-07 20:34:19
438
原创 Linux的常用命令
z代表的是gzip,通过gzip命令处理文件,gzip可以对文件压缩或者解压。:x代表的是extract,实现从包文件中还原文件。:v代表的是verbose,显示命令的执行过程。:c代表的是create,即创建新的包文件。:f代表的是file,用于指定包文件的名称。作用:对文件进行打包、解包、压缩、解压。命令提供了一种简写方式,即。作用:显示指定目录下的内容。作用:对文件内容进行编辑。
2025-10-06 21:43:03
754
原创 git 中常用的命令
Git 是一款(Distributed Version Control System, DVCS) ,可以有效、高速地处理从很小到非常大的项目版本管理。
2025-10-06 21:37:07
1694
2
原创 SpringBoot配置文件
为了解决程序中带来的硬编码问题,SpringBoot中支持并定义了配置文件的格式,将可能会发生改变的信息配置到配置文件中,让应用程序启动时从配置文件中读取数据,并加载运行。
2025-10-05 21:25:19
647
原创 过滤器Filter
定义一个类来实现Filter接口,并重写其方法。Filter// 初始化方法,用于完成资源准备工作。web服务器启动时创建Filter实例时才会调用一次//核心方法:拦截到请求后,调用该方法,可以多次调用//销毁方法:销毁资源,web服务器关闭时才会调用一次Filter接口中为我们提供了三个方法,其中两个方法提供了默认实现,因此我们可以只实现其中doFilter方法。定义过滤器Filter的实现类//初始化@Override。
2025-10-05 21:23:26
282
原创 密码学中的Salt
摘要算法(又称哈希函数)是一种单向加密函数,用于将任意长度的输入数据(如消息或文件)转换为固定长度的输出值(称为摘要或哈希值)。摘要算法时不可逆的(无法解密),通常用来检验数据的完整性。基于上述,我们可以利用MD5来实现对(32位盐值+明文)的加密形成32位密文,这里我们规定存储在数据库中的数据是(32位盐值+32位密文)即盐值+MD5(盐值+明文),从而便于我们实现数据的验证。/*** encrypt* 对密码加密* @return salt + md5(salt + 明文)*/
2025-10-04 15:20:01
346
原创 SpringBoot日志
Test运行单元测试,观察控制台中输出日志,如下:日志框架不仅可以输出日志的信息,还包括:日志的输出时间、线程名、具体是在那个类中输出的日志。
2025-10-04 15:18:51
623
原创 拦截器Interceptor
创建HandlerInterceptor接口的实现类,并重写其方法。//目标方法执行前执行//通过返回值决定是否放行 true:放行 false:不放行//目标方法执行后执行//视图渲染完后执行(最后执行)我们可以根据业务需要重写需要的方法达到在指定方法的前后执行预设代码的逻辑。自定义拦截器 (HandlerInterceptor的实现类)@Component//访问资源前执行// 通过返回值控制是否访问目标资源 true:放行 false: 不放行@Override。
2025-10-03 23:30:22
422
原创 全局异常处理器
在项目中我们往往不能全面的捕获抛出的异常,这就使得异常最终会上抛至框架,框架底层就会返回一个封装着错误信息的JSON格式的数据,但这样的数据通常并不是我们想要的。我们希望能够对上抛的异常实现统一处理,进而返回我们希望的错误信息,这时候就可以借助Spring中提供的全局异常处理器进行处理,并最终返回我们希望的错误信息。
2025-10-03 23:27:53
265
原创 WebSocket
创建一个类继承TextWebSocketHandler并重写其中的几个关键流程方法作为自定义的WebSocketHandler来处理websocket通信中的各个流程。@Component@Slf4j@Override//这个方法会在websocket 连接建立成功后自动调用log.info("[websocket connection established 连接成功]...");@Override//这个方法会在websocket 收到消息后自动调用。
2025-10-02 23:29:36
456
原创 ThreadLocal
是一个线程的局部变量,我们可以通过ThreadLocal为每个线程提供一份单独的存储空间,各个线程间的threadLocals具有线程隔离的特性。
2025-10-02 23:27:54
381
原创 Spring的事务管理机制
事务是一组操作的集合,是一个不可分割的操作。事务会将所有的操作视为一个整体向系统提交或撤销操作请求,这一组操作集合要么全部成功,妖媚全部失败。
2025-10-01 15:30:43
867
1
原创 SpringBoot 自动装配原理剖析
当我们启动Spring项目后,一些来自第三方的bean对象就自动存入到IOC容器中,这个过程不需要我们手动声明,却可以直接使用,这就是SpringBoot中的自动装配。selectImports()方法中返回值的内容源于方法底层调用的getAutoConfigurationEntry()方法,为了搞清楚自动装配的原理,我们得从SpringBoot启动类上的。方法的作用就是从该文件中读取这些需要自动装配的配置类集合信息。这个方法获取到配置文件中配置的自动配置类的集合信息。
2025-10-01 15:26:39
1497
原创 SpringAop的快速入门
AOP:Aspect Oriented Programming(面向切面编程),是一种编程范式,。此外AOP对原有代码是没有任何侵入性的,不需要修改任何的业务代码。
2025-09-28 17:51:07
942
原创 MyBatis中如何实现数据封装
在使用MyBatis的时候,我们发现有些查询后的数据库表的字段名能够正确封装到实体类的属性名中,而有些数据库表中的字段名却不能够正确封装到实体类的对应属性中,这是为什么呢?观察控制台输出打印日志以及实体类属性和数据库表字段的关系如下:只有实体类属性名和数据库表中查询返回的字段名保持一致时,MyBatis才会为我们实现自动映射,在实体类属性名和数据库表字段名不一致时,通过控制台打印的日志可以知道MyBatis并不能为我们实现对应数据的自动映射。那么该如何解决数据映射的问题呢?
2025-09-27 23:54:07
310
原创 MyBatis中的动态SQL
在我们执行查询操作的时候,我们常希望查询条件是动态的,可以根据我们的查询需求进行改变。这时候就需要借助MyBatis中向我们提供的动态SQL来实现,所谓就是能够根据用户的输入或外部条件的变化而变化的SQL语句。<if>标签通过<if>标签中提供的test属性用来判断条件是否成立,如果条件为true,则拼接对应的SQL片段。当我们想要动态拼接以上SQL片段,我们可以根据标签中判断条件是否成立来决定是否拼接。<trim>标签通过标签我们可以实现对包裹SQL片段的前缀和后缀的动态控制。
2025-09-26 11:30:29
574
原创 MyBatis
MyBatis一款为了简化JDBC开发而诞生的优秀的持久层框架,通过MyBatis提供的功能可以简化原生的JDBC程序代码的编写。
2025-09-26 11:24:00
1030
原创 Maven-继承与聚合
当然我们也可以在pom.xml文件中通过标签来自定义属性并通过${...}的方式引用自定义标签内的属性。自定义属性--自定义属性lombock.version--> < lombok.version > 1.18.30 </ lombok.version > </ properties >--自定义属性lombock.version--> < lombok.version > 1.18.30 </ lombok.version > </ properties ></
2025-09-24 16:17:17
388
原创 Axios的快速入门
AJAX(Asynchronous JavaScript and XML)是一种用于创建动态网页的技术。它允许网页在不重新加载整个页面的情况下,异步地从服务器请求数据并更新部分内容,从而提高用户体验和响应速度。
2025-09-24 16:15:35
538
原创 IP 协议
过去提到的划分网络号和主机号的方案,实际上是不合理的,实际的网络架设中较少出现A类 和 B类这种需要大量主机号的方案,也就是说这类子网中大量IP地址被浪费。:由于网络层有最大传输单元(MTU)的限制,当数据报的长度超过MTU时,就需要将其拆分成多个较小的数据包进行传输,这就是拆包的过程。也就是在复杂的网络结构中,找出一条通往终点的路线,这个找路的过程相当于一跳一跳问路的过程。通过子网划分我们能够合理的分配适合的主机号,减少IP地址的浪费。:描述拆包后多个包的向后顺序,偏移小的在前面,偏移大的在后面。
2025-04-07 12:00:00
1148
原创 文件IO的一些问题
谈到相对路径,就要先能够明确基准路径。如果在代码中写一个相对路径,那么这个相对路径的基准路径是谁呢?Java中针对流对象的打开必须要能够准确的关闭。例如:每次程序打开一个文件的时候,就会在中 (可以理解为一个固定长度的顺序表)申请一个表项。如果我们不断打开文件,而不能关闭文件,久而久之就会将文件描述符表中的表项消耗殆尽,后续再次尝试打开新的文件,就会打开失败。上述为了确保我们能够在使用完文件后,正确关闭文件,我们使用了try - finally 这样的语法来确保 finally 代码块中的关闭逻辑一定能够
2025-04-07 12:00:00
718
原创 HTTPS是如何确保安全的
HTTPS也是一个应用层协议,HTTPS协议是在HTTP协议的基础上引入一个加密层。(也就是说实际上我们可以认为臭名昭著的运营商劫持由于HTTP进行数据传输的过程都是以“明文”形式进行的,这也就给运营商劫持提供了条件,使得运营商能够在你进行数据传输的过程中捕获你要进行传输的数据,从而进行篡改。就是在这样的情况下,我们推进了HTTPS协议的诞生。
2025-04-03 12:00:00
1905
原创 UDP协议 和 TCP协议
UDP数据报格式我们这里主要基于TCP 和 UDP 的协议来进行学习掌握它们各自的特点和作用。前面学习UDP对应的socket对象时,我们知道UDP是无连接、面向数据包、全双工、不可靠传输的协议。UDP数据报格式我们知道UDP是活跃于运输层的协议,运输层关注端对端的通信情况。16位源端口号16位目的端口号16位UDP长度16位UDP校验和4位首部长度TCP Header保留(6位)16位校验和16位紧急指针6为标志位URG:判断紧急指针是否有效(该位为1时代表包中有需要紧急处理的数据)ACK。
2025-04-03 12:00:00
846
原创 Java操作传输层的核心类
TCPUDP操作系统向上提供一组api 来完成应用层和传输层的交互。Java中为我们封装了两套Socket api 进行网络通信。TCP和UDP。TCP。
2025-04-02 12:00:00
406
原创 HTTP协议
HTTP协议报文格式超文本传输协议(Hypertext,HTTP)是一个简单的请求 - 响应协议 (客户端 - 服务器协议)。HTTP 遵循经典的,客户端打开一个连接以发出请求,然后等待直到收到服务器端响应。HTTP往往是基于传输层的TCP协议实现的 (HTTP1.0HTTP1.1HTTP2.0均是基于传输层的TCP协议实现) ,而最新的HTTP3.0的底层是基于传输层的UDP协议进行实现的。由于当前网络上流行的主流仍是HTTP1.1,所以我们这里以1.1版本展开。HTTP协议报文格式。
2025-04-02 12:00:00
1350
原创 Hashtable 和 ConcurrentHashMap 的区别
在多线程并发执行的环境下使用哈希表,HashMap 本身是线程不安全的、Hashtable 虽然是线程安全的,但是相比ConcurrentHashMap 这个同样线程安全的哈希表来说效率太低。
2025-04-01 12:00:00
1741
原创 网络通信中涉及的内容
IP地址是用来描述一个在网络上的设备的网络地址的,通过IP地址我们能够定位一台网络设备的具体位置。IP地址是一个 32 位的二进制数,也就是说一个IP地址需要4个字节来表示。为了使用的方便,通常用“点分十进制”来表示。如果说IP地址描述了一台网络设备的位置,那么端口号就描述了这台网络设备上的某个具体程序(进程)。进行网络通信的多个通信实体间共同约定遵守的一系列规则和约定 (简单说网络协议就是针对数据收发和传输的一组约定和规则)。五元组TCP/IP 协议进行一次网络通信中,涉及到的关键信息 (五元组)。
2025-04-01 12:00:00
1703
原创 CAS 机制
CAS (Compare and Swap)比较和交换,是一种用于实现多线程同步的原子指令。CAS操作包含三个关键参数:要更改变量的内存位置、预期的值和新值。通过上述伪代码,我们能够了解CAS (Compare and Swap) 指令的工作流程,。
2025-03-31 12:00:00
1124
原创 JUC(java.util.concurrent) 的常见类
Callable 接口 和 Runnable 接口是并列关系,都是描述一个要执行的任务,不同的是Callable接口需要重写带返回值的call 方法,而Runnable 接口重写的是不带返回值的run 方法。也就是说Callable 为我们提供了能够接受任务返回值的方法。除此此外,Callable 所描述的任务并不能直接交由Thread类,需要借助 类的封装。运行程序,执行结果如下:ReentrantLock 是一把可重入互斥锁,和synchronized 是并列的关系,都是用来实现互斥效果,来保证线程安
2025-03-31 12:00:00
643
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅