自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 学习日志:MySQL 记录锁+间隙锁可以防止删除操作而导致的幻读吗?

当同一个查询在不同的时间产生不同的结果集时,事务中就会出现所谓的幻象问题。例如,如果 SELECT 执行了两次,但第二次返回了第一次没有返回的行,则该行是“幻像”行。举个例子,假设一个事务在 T1 时刻和 T2 时刻分别执行了下面查询语句,途中没有执行其他任何语句:只要 T1 和 T2 时刻执行产生的结果集是不相同的,那就发生了幻读的问题,比如:T1 时间执行的结果是有 5 条行记录,而 T2 时间执行的结果是有 6 条行记录,那就发生了幻读的问题。

2024-08-03 11:29:04 646

原创 学习日志:update 没加索引会锁全表

在线上执行一条 update 语句修改数据库数据的时候,where 条件没有带上索引,导致业务直接崩了为什么会发生这种的事故?又该如何避免这种事故的发生?说个前提,接下来说的案例都是基于 InnoDB 存储引擎,且事务的隔离级别是可重复读。不要小看一条 update 语句,在生产机上使用不当可能会导致业务停滞,甚至崩溃。当我们要执行 update 语句的时候,确保 where 条件中带上了索引列,并且在测试机确认该语句是否走的是索引扫描,防止因为扫描全表,而对表中的所有记录加上锁。

2024-08-03 11:06:42 991

原创 学习日志:mysql加锁

当查询的记录是「存在」的,在索引树上定位到这一条记录后,将该记录的索引中的 next-key lock 会退化成「记录锁」。当查询的记录是「不存在」的,在索引树找到第一条大于该查询记录的记录后,将该记录的索引中的next-key lock 会退化成「间隙锁」。当查询的记录「存在」时,由于不是唯一索引,所以肯定存在索引值相同的记录,于是非唯一索引等值查询的过程是一个扫描的过程,直到扫描到第一个不符合条件的二级索引记录就停止扫描,然后。

2024-08-03 10:46:26 876

原创 学习日志:MySQL 的锁

在 MySQL 里,根据加锁的范围,可以分为全局锁、表级锁和行锁三类。

2024-08-02 14:19:31 1095

原创 学习日志:MySQL 可重复读隔离级别,处理幻读

针对快照读(普通 select 语句),是通过 MVCC方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。针对当前读(select … for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读。

2024-08-02 10:24:18 742

原创 学习日志:事务隔离级别

转账这一动作在程序里会涉及到一系列的操作,假设我向你转账 100 万的过程是有下面这几个步骤组成的:可以看到这个转账的过程涉及到了两次修改数据库的操作。假设在执行第三步骤之后,服务器忽然掉电了,就会发生一个蛋疼的事情,我的账户扣了 100 万,但是钱并没有到你的账户上,也就是说这 100 万消失了!要解决这个问题,就要保证转账业务里的所有数据库的操作是不可分割的,要么全部执行成功 ,要么全部失败,不允许出现中间状态的数据。数据库中的「事务(Transaction)」就能达到这样的效果。

2024-08-02 09:40:38 861

原创 学习日志:不同的count 性能

当我们对一张数据表中的记录进行统计的时候,习惯都会使用 count 函数来统计,但是 count 函数传入的参数有很多种,比如 count(1)、count(*)、count(字段) 等。

2024-08-01 15:06:42 644

原创 学习日志:索引失效

常见的 6 种会发生索引失效的场景。当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;当我们在查询条件中对索引列使用函数,就会导致索引失效。当我们在查询条件中对索引列进行表达式计算,也是无法走索引的。MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较。

2024-08-01 14:26:10 743

原创 学习日志:MySQL 采用 B+ 树作为索引

MySQL 采用 B+ 树作为索引不单单要从数据结构的角度出发,还要考虑磁盘 I/O 操作次数,因为 MySQL 的数据是存储在磁盘中的。MySQL 是会将数据持久化在硬盘,而存储功能是由 MySQL 存储引擎实现的,所以讨论 MySQL 使用哪种数据结构作为索引,实际上是在讨论存储引使用哪种数据结构作为索引,InnoDB 是 MySQL 默认的存储引擎,它就是采用了 B+ 树作为索引的数据结构。

2024-08-01 11:30:16 829

原创 学习日志:从数据页的角度看 B+ 树

从数据页的角度看 B+ 树,看看每个节点长啥样。InnoDB 的数据是按「数据页」为单位来读写的,默认数据页大小为 16 KB。每个数据页之间通过双向链表的形式组织起来,物理上不连续,但是逻辑上连续。数据页内包含用户记录,每个记录之间用单向链表的方式组织起来,为了加快在数据页内高效查询记录,设计了一个页目录,页目录存储各个槽(分组),且主键值是有序的,于是可以通过二分查找法的方式进行检索从而提高效率。为了高效查询记录所在的数据页,InnoDB 采用 b+ 树作为索引,每个节点都是一个数据页。

2024-08-01 11:05:25 599

原创 学习日志:索引

从索引的基本原理,再到索引的使用场景索引底层使用了什么数据结构和算法?为什么 MySQL InnoDB 选择 B+tree 作为索引的数据结构?什么时候适用索引?什么时候不需要创建索引?什么情况下索引会失效?有什么优化索引的方法?这次主要介绍了索引的原理、分类和使用。我把重点总结在了下面这个表格。

2024-08-01 10:32:15 810

原创 学习日志:MySQL 一行记录的存储结构

MySQL 的 NULL 值会占用空间吗?MySQL 怎么知道 varchar(n) 实际占用数据的大小?varchar(n) 中 n 最大取值为多少?行溢出后,MySQL 是怎么处理的?这些问题看似毫不相干,其实都是在围绕「 MySQL 一行记录的存储结构」这一个知识点,所以攻破了这个知识点后,这些问题就引刃而解了。MySQL 的 NULL 值是怎么存放的?

2024-07-31 11:15:19 900

原创 学习日志:MySql的执行流程

MySQL 执行一条 select 查询语句,在 MySQL 中期间发生了什么?执行一条 SQL 查询语句,期间发生了什么?连接器:建立连接,管理连接、校验用户身份;查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0 已删除该模块;解析 SQL,通过解析器对 SQL 查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型;预处理阶段:检查表或字段是否存在;将 select * 中的 * 符号扩展为表上的所有列。优化阶段。

2024-07-31 10:15:19 998

原创 Java ArrayList

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。ArrayList 继承了 AbstractList ,并实现了 List 接口。ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

2024-07-29 15:59:30 330

原创 Java HashMap

HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,是常用的 Java 集合之一,是非线程安全的。HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。

2024-07-29 15:00:53 394

原创 项目总结:JWT

官网:https://jwt.io/拿到了jwt令牌下一步就要携带令牌去访问资源服务中的资源,本项目各个微服务就是资源服务,比如:内容管理服务,客户端申请到jwt令牌,携带jwt去内容管理服务查询课程信息,此时内容管理服务要对jwt进行校验,只有jwt合法才可以继续访问。令牌采用JWT格式即可解决上边的问题,用户认证通过后会得到一个JWT令牌,JWT令牌中已经包括了用户相关的信息,客户端只需要携带JWT访问资源服务,资源服务根据事先约定的算法自行完成令牌校验,无需每次都请求认证服务完成授权。

2024-07-28 19:53:58 587

原创 学习日志:双亲委派模型

类加载器有很多种,当我们想要加载一个类的时候,具体是哪个类加载器加载呢?这就需要提到双亲委派模型了。ClassLoader 类使用委托模型来搜索类和资源。双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载器。ClassLoader 实例会在试图亲自查找类或资源之前,将搜索类或资源的任务委托给其父类加载器。

2024-07-28 16:44:06 630

原创 学习日志:类加载器

类加载过程:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。加载是类加载过程的第一步,主要完成下面 3 件事情:1.通过全类名获取定义此类的二进制字节流2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构3.在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口类加载器类加载器从 JDK 1.0 就出现了,最初只是为了满足 Java Applet(已经被淘汰) 的需要。

2024-07-28 15:32:54 796

原创 学习日志:类加载过程

(字节码)。对于 () 方法的调用,虚拟机会自己确保其在多线程环境中的安全性。因为 () 方法是带锁线程安全,所以在多线程环境下进行类初始化的话可能会引起多个线程阻塞,并且这种阻塞很难被发现。

2024-07-27 15:09:10 621

原创 项目总结: OAuth2认证

微信扫码认证,这是一种第三方认证的方式,这种认证方式是基于OAuth2协议实现,OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP、JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OAUTH是简易的。Oauth协议目前发展到2.0版本,1.0版本过于复杂,2.0版本已得到广泛应用。

2024-07-25 16:47:22 585

原创 项目总结:Spring Security工作原理

根据前边知识的学习,可以通过Filter或AOP等技术来实现,Spring Security对Web资源的保护是靠Filter实现的,所以从这个Filter来入手,逐步深入Spring Security原理。FilterChainProxy是一个代理,真正起作用的是FilterChainProxy中SecurityFilterChain所包含的各个Filter,同时这些Filter作为Bean被Spring管理,它们是Spring Security核心,各有各的职责,但他们并不直接处理用户的。

2024-07-25 15:07:31 777

原创 项目总结:认证授权

会议发布后用户通过页面进行查看。如何去记录用户的会议记录呢?要想掌握用户需要参会的情况就需要知道用户的身份信息,记录哪个用户在什么时间参加什么会议,如果用户要下载会议资料也需要知道用户的身份信息。所以,去管理用户的参会过程最基本的要实现用户的身份认证。认证授权模块实现平台所有用户的身份认证与用户授权功能。

2024-07-25 14:57:58 1014

原创 学习日志:类文件结构

在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效,而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。

2024-07-24 16:04:50 906

原创 学习日志:JVM垃圾回收

当需要排查各种内存溢出问题、当垃圾收集成为系统达到更高并发的瓶颈时,我们就需要对这些“自动化”的技术实施必要的监控和调节。可达性算法中描述的对象引用,一般指的是强引用,即是GCRoot对象对普通对象有引用关系,只要这层关系存在普通对象就不会被回收。

2024-07-23 19:39:32 1981

原创 项目总结:Feign进行远程调用

微服务之间难免会存在远程调用,在Spring Cloud中可以使用Feign进行远程调用,Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign其作用就是帮助我们优雅的实现http请求的发送。

2024-07-23 14:51:41 950

原创 项目总结:分布式事务

相关人员在会议审核并编排后即可发布会议,会议发布后会公开展示在网站上供员工查看、下载相关资料。在网站上展示会议信息需要解决会议信息显示的性能问题,如果速度慢(排除网速)会影响用户的体验性。如何去快速搜索会议?打开会议详情页面仍然去查询数据库可行吗?为了提高网站的速度需要将会议相关信息进行缓存,并且要将会议信息加入索引库方便搜索。1、向会议信息管理数据库的会议发布表存储会议发布信息,更新会议基本信息表中发布状态为已发布。2、向Redis存储会议缓存信息。

2024-07-23 13:22:33 853

原创 学习日志:HotSpot 虚拟机对象

详细介绍了 HotSpot 虚拟机在 Java 堆中对象分配、布局和访问的全过程。

2024-07-22 19:26:59 719

原创 学习日志:Java内存区域

在虚拟机自动内存管理机制下,不再需要像 C/C++程序开发程序员这样为每一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。

2024-07-22 17:09:42 734

原创 项目总结:分布式任务调度

通常任务调度的程序是集成在应用中的,比如:优惠卷服务中包括了定时发放优惠卷的的调度程序,结算服务中包括了定期生成报表的任务调度程序,由于采用分布式架构,一个服务往往会部署多个冗余实例来运行我们的业务,在这种分布式系统环境下运行任务调度,我们称之为。当任务调度以集群方式部署,同一个任务调度可能会执行多次,比如在上面提到的电商系统中到点发优惠券的例子,就会发放多次优惠券,对公司造成很多损失,所以我们需要控制相同的任务在多个运行实例上只执行一次。每个执行器收到广播任务有两个参数:分片总数、分片序号。

2024-07-21 21:50:47 977

原创 学习日志:线程池

顾名思义,线程池就是管理一系列线程的资源池。当有任务要处理时,直接从线程池中获取线程来处理,处理完之后线程并不会立即被销毁,而是等待下一个任务。

2024-07-20 16:37:59 539

原创 学习日志:ThreadLocal

通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢?JDK 中自带的ThreadLocal类正是为了解决这样的问题。ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的本地副本,这也是ThreadLocal变量名的由来。

2024-07-20 15:49:43 662

原创 学习日志:Atomic 原子类

Atomic 翻译成中文是原子的意思。Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。所以,所谓原子类说简单点就是具有原子/原子操作特征的类。并发包 java.util.concurrent 的原子类都存放在java.util.concurrent.atomic下,如下图所示。根据操作的数据类型,可以将 JUC 包中的原子类分为 4 类1.基本类型使用原子的方式更新基本类型AtomicInteger:整型原子类。

2024-07-20 15:23:15 886

原创 学习日志:AQS抽象队列同步器

AQS 的全称为 AbstractQueuedSynchronizer ,翻译过来的意思就是抽象队列同步器。这个类在 java.util.concurrent.locks 包下面。AQS 就是一个抽象类,主要用来构建锁和同步器。

2024-07-20 14:53:41 1053

原创 项目总结:分布式文件系统Minio

文件系统是负责管理和存储文件的系统软件,操作系统通过文件系统提供的接口去存取文件,用户通过操作系统访问磁盘上的文件。常见的文件系统:FAT16/FAT32、NTFS、HFS、UFS、APFS、XFS、Ext4等。

2024-07-20 11:26:47 926

原创 学习日志:ReentrantLock

由于 synchronized锁是可重入的,同一个线程在调用method1() 时可以直接获得当前对象的锁,执行 method2() 的时候可以再次获取这个对象的锁,不会产生死锁问题。假如synchronized是不可重入锁的话,由于该对象的锁已被当前线程所持有且无法释放,这就导致线程在执行 method2()时获取锁失败,会出现死锁问题。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果是不可重入锁的话,就会造成死锁。

2024-07-18 19:49:35 618

原创 学习日志:synchronized 关键字

在 Java 早期版本中,synchronized 属于重量级锁,效率低下。这是因为监视器锁(monitor)是依赖于底层的操作系统的 Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高。

2024-07-18 17:12:03 717

原创 学习日志:乐观锁与悲观锁

JDK 1.5 以后的 AtomicStampedReference 类就是用来解决 ABA 问题的,其中的 compareAndSet() 方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。当多个线程同时使用 CAS 操作一个变量时,只有一个会胜出,并成功更新,其余均会失败,但失败的线程并不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作。并且,悲观锁还可能会存在死锁问题,影响代码的正常运行。

2024-07-18 16:15:01 1727

原创 学习日志:volatile 关键字

在 Java 中,volatile 关键字可以保证变量的可见性,如果将变量声明为 volatile ,这就指示 JVM,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。

2024-07-18 15:17:15 1834

原创 学习日志:JMM(Java 内存模型)

JMM(Java 内存模型)主要定义了对于一个共享变量,当另一个线程对这个共享变量执行写操作后,这个线程对这个共享变量的可见性。要想理解透彻 JMM(Java 内存模型),我们先要从CPU 缓存模型和指令重排序说起!ava 是最早尝试提供内存模型的语言,其主要目的是为了简化多线程编程,增强程序可移植性的。CPU 可以通过制定缓存一致协议(比如 MESI协议open in new window)来解决内存缓存不一致性问题。为了提升执行速度/性能,计算机在执行程序代码的时候,会对指令进行重排序。

2024-07-17 16:16:53 961

原创 学习日志:多线程

并发与并行并发:两个及两个以上的作业在同一 时间段内执行。并行:两个及两个以上的作业在同一时刻执行。同步和异步同步:发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。异步:调用在发出之后,不用等待返回结果,该调用直接返回。

2024-07-17 14:40:28 914

空空如也

空空如也

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

TA关注的人

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