自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(90)
  • 收藏
  • 关注

原创 SpringBoot项目打包时的依赖处理

文章摘要:本文分析了SpringBoot项目中JAR包的打包机制。通过jartf命令解析发现,典型的SpringBoot胖JAR(FatJAR)包含BOOT-INF/lib/目录下的所有第三方依赖、BOOT-INF/classes/下的项目代码及SpringBoot类加载器。对比瘦JAR(ThinJAR)需要额外配置类路径,胖JAR可直接通过java -jar命令运行。文中还介绍了Maven依赖作用域(compile/provided/runtime/test/system)对打包的影响,并指出打包方式可通

2025-11-14 11:19:58 1052

原创 SpringBoot项目启动时的依赖处理

摘要:本文探讨了SpringBoot项目在IDEA中启动时如何处理Maven依赖的问题。通过分析target文件夹结构发现,项目运行时实际依赖的是本地Maven仓库中的jar包,而非直接复制到target目录。文章重点解析了类路径(Classpath)的作用机制,包括类加载、资源加载和依赖加载三方面,并详细说明了Maven如何通过pom.xml的依赖声明、作用域设置(Scope)、依赖传递性等机制自动管理类路径配置,确保项目正确运行。

2025-11-14 11:16:01 422

原创 Redisson中的分布式锁

Redisson 的分布式锁(主要实现类 RLock)主要基于 ​​Redis Lua 脚本​​来确保操作的​​原子性​​,利用 Redis 的 ​​SET命令配合 NX(不存在才设置)和 PX(过期时间)选项​​来实现锁的获取。RedLock 是 Redis 的作者提出的一个多节点分布式锁算法,旨在解决使用单节点 Redis 分布式锁可能存在的单点故障问题。除非持有锁的 JVM 挂掉,锁才会过期释放。公平锁会严格按照客户端请求锁的顺序(进入队列的顺序)来授予锁,避免某些线程长时间饥饿。

2025-08-07 23:09:02 904

原创 使用SETNX实现分布式锁

Redis 中,Setnx(SET if Not eXists)命令是指:只有当指定的 key 不存在时,才会为 key 设置指定的值,此时设置成功,返回 1;客户端释放锁的时候,需要先判断该锁是否仍然属于该客户端,如果是,则通过 DEL 命令释放锁。(2)性能较高:由于 SETNX 命令的执行原子性,保证了分布式锁的正确性,而且在 Redis 中,SETNX 命令是单线程执行的,所以性能较高。(1)锁无法续期:如果加锁方在加锁后的执行时间较长,而锁的超时时间设置的较短,可能导致锁被误释放。

2025-08-07 23:04:21 503

原创 Redis持久化机制

所以 Redis 在使用 bgsave 快照过程中,如果主线程修改了内存数据,不管是否是共享的内存数据,RDB 快照都无法写入主线程刚修改的数据,因为此时主线程(父进程)的内存数据和子进程的内存数据已经分离了,子进程写入到 RDB 文件的内存数据只能是原本的内存数据。但是,需要注意的是,bgsave 快照过程中,如果主线程修改了共享数据,发生了写时复制后,RDB 快照保存的是原本的内存数据,而主线程刚修改的数据,是没办法在这一时间写入 RDB 文件的,只能交由下一次的 bgsave 快照。

2025-08-05 22:49:42 1256

原创 Redis集群模式

它会从所有健康的从节点中选举一个新的主节点,并将所有从节点切换到新的主节点,实现自动故障转移。客户端对数据进行存取操作时,Redis 会根据 CRC16 算法得出一个结果,然后把结果对 16384 进行取模,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。当主节点发生故障时,哨兵节点可以自动进行故障转移,选择一个合适的从节点升级为主节点,并通知其他从节点和应用程序进行更新。

2025-08-05 22:44:32 1038

原创 Redis事务机制

在进入正文前,我们首先来明确两个概念。并发编程中的原子性指的是,一组操作"不可拆分、不可中断";数据库事务中的原子性指的是,一组操作"要么执行成功、要么执行失败"。因此,原子性在并发编程中,和在数据库中是两种不同的概念。而 Redis 既是一个数据库,又是一个支持并发编程的系统,当我们讨论其原子性时,一定要明确指的是哪个原子性。

2025-08-02 10:44:51 396

原创 Redis内存淘汰策略

LRU 全称是 Least Recently Used 翻译为最近最少使用,会选择淘汰最近最少使用的数据。传统 LRU 算法的实现是基于「链表」结构,链表中的元素按照操作顺序从前往后排列,最新操作的键会被移动到表头,当需要内存淘汰时,只需要删除链表尾部的元素即可,因为链表尾部的元素就代表最久未被使用的元素。LFU 全称是 Least Frequently Used 翻译为最近最不常用,LFU 算法是根据数据访问次数来淘汰数据的,它的核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

2025-08-02 10:43:46 920

原创 Redis过期策略

因为 Redis 在执行定期删除过期 key 是在单线程模型中的主线程执行的,此时如果有大量的 key 需要删除,那么就得等删除命令执行完毕后才能处理其他 key 的读写操作,也就出现了业务访问延时增大的问题。过期字典的键指向 Redis 数据库中的某个 key(键),过期字典的值是一个 long 类型的整数,这个整数保存了 key 所指向的数据库键的过期时间(毫秒精度的 UNIX 时间戳)。定期删除的具体做法为,每隔一段时间「随机」从缓存中取出一定数量的 key 进行检查,并删除其中的过期key。

2025-07-31 23:13:53 952

原创 Redis线程模型讨论

但其实这个表述并不完全准确,因为 Redis 作为一个成熟的分布式缓存框架,它由很多模块组成,如网络请求模块、数据操作模块、存储模块、索引模块、高可用集群支撑模块等,除了网络请求模块和数据操作模块是单线程处理,其他模块都是多线程的,比如,Redis 中会有很多后台进程异步处理一些耗时较长的操作,如处理关闭文件、AOF 刷盘等。计算操作主要涉及到CPU。所以为了进一步提高网络 I/O 的利用率,Redis 6.0 对于网络 I/O 采用多线程来处理,但是对于数据的读写命令,仍然是单线程处理的。

2025-07-31 23:10:54 1465 1

原创 归档日志-binlog

MySQL 引入了 binlog 组提交(group commit)机制,当有多个事务提交的时候,会将多个 binlog 刷盘操作合并成一个,从而减少磁盘 I/O 的次数,如果说 10 个事务依次排队刷盘的时间成本是 10,那么将这 10 个事务一次性一起刷盘的时间成本则近似于 1。上面的每个阶段都有一个队列,每个阶段有锁进行保护,因此保证了事务写入的顺序,第一个进入队列的事务会成为 leader,leader领导所在队列的所有事务,全权负责整队的操作,完成后通知队内其他事务操作结束。

2025-07-28 20:38:16 1132

原创 回滚日志-undo log

undo log也被称为回滚日志,与redo log(物理日志,记录数据页的修改)不同的是,undo log是一种逻辑日志,用于数据修改的回滚,以此保证事务的原子性。这样,在事务回滚时,我们就可以从undo log中反向读取相应的内容,并进行回滚;另外我们也可以根据undo log中的内容读取到一条被修改后数据的原值。该日志中记录的是数据修改的相反记录,比如:当删除一条记录,日志中会记录一条对应的新增记录。redo log 和 undo log 区别在哪?

2025-07-28 20:35:59 292

原创 如何保证数据库和缓存一致性问题讨论

而如果先删除缓存成功,再更新数据库失败,因为此时缓存已经没有数据了,也不会出现数据不一致的问题了。通过上述分析,无论是「先更新数据库,再更新缓存」,还是「先更新缓存,再更新数据库」,都可能会导致数据不一致,因此我们在做数据更新时,对于缓存的处理不应该是更新,而是删除,因为将缓存删除后,大概率就不会出现数据不一致的问题了。因此,无论是「先更新数据库,再更新缓存」,还是「先更新缓存,再更新数据库」,这两个方案都存在并发问题,当多个请求并发更新同一条数据的时候,可能会出现缓存和数据库中的数据不一致的现象。

2025-07-27 17:13:55 779

原创 重做日志-redo log

首先,提出一个问题:redo log是否对其文件大小有限制?若有限制,当超过其限制时,数据库会做出怎样对应的操作?解一:redo log文件的大小InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是 1GB,那么这个日志总共就可以记录4GB的操作。并且写redo log是环状写日志的形式,如下图。write pos是当前记录的位置,一边写一边后移。check point是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

2025-07-27 17:09:05 635

原创 MySQL中的锁有哪些

导读:在解决读写冲突产生的问题时,不同的数据库厂商使用的方式也不尽相同,但是大致可分为以下两种方案:方案一:读操作利用多版本并发控制(MVCC),写操作进行加锁。对于读操作,一个查询语句会产生一个 Read View(读视图),在不同的隔离级别下,根据 Read View 找到该事务可以访问的历史版本数据;对于写操作,通过对最新版本的数据进行加锁,只有获取到锁的事务才可以对数据进行修改,避免了脏写问题。

2025-07-18 21:05:40 803

原创 搞清MVCC

MVCC,全称 Multi-Version Concurrency Control ,即多版本并发控制,是一种即使不加锁也能够解决并发操作中的读写冲突的并发控制手段,即做到了非阻塞读。其中,不加锁可以大大降低程序开销。补充:读写冲突会造成脏读、幻读、不可重复读。当前读:当前读获取到的记录是最新记录;读取记录时,要对记录进行加锁操作,保证记录不被其他事务所修改。可以看作是悲观锁的一种实现。快照读:快照读可以看作是MVCC的一种实现,主要是为了通过不加锁的方式解决读写冲突。

2025-07-17 21:28:19 1149

原创 并发事务~

READ UNCOMMITTED隔离级别下,可能发生脏读、不可重复读和幻读问题。READ COMMITTED隔离级别下,可能发生不可重复读和幻读问题,但是不可以发生脏读问题。REPEATABLE READ隔离级别下,可能发生幻读问题,但是不可以发生脏读和不可重复读的问题。SERIALIZABLE隔离级别下,各种问题都不可以发生。

2025-07-17 21:25:16 904

原创 事务~~~

从图中大家也可以看出了,只有当事务处于提交的或者中止的状态时,一个事务的生命周期才算是结束了。对于已经提交的事务来说,该事务对数据库所做的修改将永久生效,对于处于中止状态的事务,该事务对数据库所做的所有修改都会被回滚到没执行该事务之前的状态。C 一致性:事务前后的状态要保持一致,可以理解为数据的一致性。只有保证了原子性、隔离性、持久性才能保证事务的一致性。A 原子性:对数据的一组操作,要么执行成功,要么不执行。I 隔离性:多个事务之间是隔离的,互不影响。

2025-07-16 23:19:38 214

原创 Buffer Pool

对于该种场景,InnnDB 设计者们又添加了 innodb_old_blocks_time 这个系统变量,也就是说,从磁盘上被加载到 LRU 链表的 old 区域的某个页来说,如果第一次和最后一次访问该页面的时间间隔小于1s(很明显在一次全表扫描的过程中,多次访问一个页面中的时间不会超过1s),那么该页是不会被加入到young区域的。这样链表尾部的数据就是最近最少使用的数据了,当 Buffer Pool容量不足,或者后台线程主动刷新数据页时,就会优先刷新链表尾部的数据页。

2025-07-16 23:17:34 1048

原创 Explain关键字

- 内层 SELECT 是 DERIVED。SELECT 1 FROM orders WHERE user_id = u.id -- 依赖外层 u.id。查询执行计划的标识符​​,用于表示查询中每个 SELECT 子句的执行顺序和层级关系。-- 内层 SELECT 是 SUBQUERY。​​优化​​:为 ORDER BY/GROUP BY 字段添加联合索引。​​优化​​:为 ORDER BY 字段添加索引。

2025-07-09 23:03:39 960

原创 子查询~~

在一个查询语句里的某个位置也可以有另一个查询语句,这个出现在某个查询语句的某个位置中的查询就被称为子查询。

2025-07-09 22:57:04 313

原创 多表查询~

扫描表的过程就是通过磁盘 I/O 将表的数据加载到内存,然后从内存中比较匹配条件是否满足,因此使用嵌套循环连接算法时,可能需要多次磁盘 I/O 读取被驱动表,势必会造成性能上的损耗。而要想减轻这方面的代价,我们可以通过尽量减少访问被驱动表的次数。在 BNL 中,通过加入一块 join buffer 区域,用于存放若干条驱动表的结果集,然后将 join buffer 区域中的记录与被驱动表记录进行匹配,这样的话,就可以使一条被驱动表的记录一次同时与多条驱动表的记录进行匹配(反入为主)。

2025-07-07 22:27:52 732

原创 单表查询~

导读在熟悉了 MySQL 中数据的存储细节之后,接下来就该了解其数据查询的那些事儿了。作为用户,在查询数据时,我们只需通过一条 SQL 来声明要查询哪些数据,完全不需要注意 MySQL Server 具体是怎样完成查询的,也就是说我们不看重过程,只看重结果;而对于 MySQL Server,执行一条 SQL 的查询逻辑是较为复杂的,首先 Server 端需与 Client 建立连接,然后 Server 端开始语法解析、查询优化,待查询优化模块生成出一个最优执行计划后,再调用存储引擎执行操作并返回结果。

2025-07-07 22:22:59 1003

原创 MySQL的数据目录

根据前面的所学知识,我们知道了InnoDB存储引擎存储数据的数据结构、存储过程,而被组织好的数据则被存储在操作系统的磁盘上,当我们在对表数据进行增删改查时,其实就是InnoDB存储引擎与磁盘的交互。此外,操作系统中对磁盘的管理归属于文件系统,所以我们也可将数据增删改查的过程称为是InnoDB存储引擎与文件系统的交互。之前我们只是通过工具对数据库中的数据进行操作,并没有真正看到过数据库、表等存储文件,接下来我们就来了解一下在文件系统中,MySQL是以什么样的形式对数据进行的存储?保存了哪些数据?

2025-07-05 13:51:03 848

原创 最左匹配原则

导读:首先创建一张 test 表,并插入一些数据:`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',其中,test 表中有一个联合索引 idx_abc,其包含索引(a)、索引(ab)、索引(abc)。

2025-07-05 13:45:16 822

原创 InnoDB索引

一条条数据存储到页中后,各个数据页组成了一个双向链表,而每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表。此时,如果我想根据主键值查询一条记录,只能从第一个数据页开始一个页一个页地去查询,这种全表搜索方式的效率想想也不会很高,因此 MySQL 选择为每一个存储了用户数据的数据页建立目录,通过目录确定目标数据在哪个页,然后再在目标页中根据 Page Directory (页目录) + 二分法查询目标数据。

2025-07-01 23:13:19 1129

原创 InnoDB数据页

首先,在每一个数据页中存在两个虚拟记录,一个代表最小记录,一个代表最大记录,它们被存储在数据页的 Infimum + Supremum 部分。紧接着,当向表中插入一些数据时,这些记录会被存储在数据页中的 User Records 中,这里不仅存储了其真实内容,还有存储了一些额外的数据,比如头信息中的 next_record,通过这个标记加上两个虚拟记录,使得记录形成了一条按照主键值由小到大的顺序的单链表(非插入顺序。

2025-07-01 23:06:09 832

原创 InnoDB行格式

从图中可以看出来,对于 Compact 和 Redundant 行格式来说,如果某一列中的数据非常多的话,在本记录的真实数据处只会存储该列的 前768 个字节的数据和一个指向其他页的地址,然后把剩下的数据存放到其他页中,这个过程也叫做行溢出,存储超出 768 字节的那些页面也被称为溢出页。最后需要注意的是,不只是 VARCHAR(M) 类型的列,其他的 TEXT、BLOB 类型的列在存储数据非常多的时候也会发生行溢出。对于这些类型的列,数据是单独存储的,并且通过行中的指针来访问。

2025-06-29 19:42:55 795

原创 字符集和比较规则

1、字符集是什么?字符集是一个有限的字符集合,其定义了可以表示的字符的范围,这些字符可以是中文、字母、数字、标点符号、控制字符等。有啥用?通过建立字符串与二进制的映射关系,解决了计算机无法存储字符串的问题(计算机只能存储二进制数据上述提到的,将一个字符映射成一个二进制数据的过程也叫做编码,在这里亦称为"字符编码其中,一种字符集可以有不同的编码方案。比如,Unicode 编码方案包括 UTF-8、UTF-16 和 UTF-32 等。但是,MySQL。

2025-06-29 19:39:43 953

原创 MySQL的调控按钮

以本地MySQL服务 MySQL57 为例,通过服务 - MySQL57 - 属性,可看到该服务的可执行文件、配置文件的地址。为了让我们更好的了解服务器程序的运行情况,MySQL服务器程序中维护了好多关于程序运行状态的变量,它们被称为状态变量。因此命令行设置启动选项适合偶尔改动的选项,而对于无需频繁更改的选项配置在文件中将更加方便。),并且同一个启动选项既出现在命令行中,又出现在配置文件中,那么以命令行中的启动选项为准。程序每次启动时都是从配置文件中加载启动选项,而命令行设置启动项只在当次启动有效(

2025-06-29 19:37:24 873

原创 MySQL架构理解

MySQL是一个开源的、轻量级的存储数据工具,因其不错的性能广泛被人们使用。

2025-06-29 19:32:55 321

原创 离奇!Chrome浏览器竟突然无法上网!?

因Charles导致的Chrome浏览器无法上网问题的解决

2024-10-15 14:41:27 1956

原创 npm、nrm、nvm详解与应用

本文全面介绍了 npm、nrm 以及 nvm 这三个与 Node.js 开发密切相关的工具。

2024-03-24 16:34:25 3841

原创 Linux中,配置systemctl操作Nginx

在Linux中,配置systemctl命令操作Nginx,更方便的对Nginx进行相关操作

2024-03-10 23:35:52 3250 1

原创 Linux中防火墙相关操作

Linux中防火墙相关操作

2024-03-10 18:14:32 2264

原创 Docker安装

Docker安装

2024-02-22 16:19:56 411

原创 MySQL模糊查询通配符转义总结

MySQL模糊查询,对%、_的处理

2024-01-26 15:18:32 2631

原创 SpringBoot集成Swagger

1、导包<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version></dependency><dependency> <groupId>io.springfox</groupI

2021-12-22 15:02:45 608

原创 当mybatis where条件中使用in关键字出现的问题

一、出现的问题:1、查询时:Mybatis:Mysql:2、删除时:Mybatis:Mysql:通过分析查询、删除时的两种情况可知,相同的sql语句被执行后,mysql、mybatis的执行结果却不一致。原因: 通过分析可得,Mybatis查询、删除出现不符合预期的问题都是由Mybatis使用#{}替换变量值时导致的。#{}会把传入的数据都当成一个字符串来处理,会在传入的数据上面加一个双引号来处理。比如,select * from s_r.

2021-12-22 10:34:39 3044

原创 Mybatis中#{}和${}的区别

一、作用:替换变量值。二、含义不同:# 会把传入的数据都当成一个字符串来处理,会在传入的数据上面加一个双引号来处理。比如,select * from student where name = #{name},传入周杰伦,经处理,为 select * from student where name = "周杰伦"。而 $ 则是把传入的数据直接拼接在sql语句中,不会添加双引号。比如,select * from student where age= #{age},传入18,经处理,为

2021-12-22 08:51:02 527

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除