自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

沙漏

一步步从无到有的创造

  • 博客(154)
  • 收藏
  • 关注

原创 如何理解数据库事务

在事务执行期间,如果发生了错误或者中断,所有的操作都会被回滚到事务开始之前的状态,不会留下部分完成的结果。3. **隔离性(Isolation)**:事务之间应该是相互隔离的,即一个事务的执行不应该受到其他事务的影响。4. **持久性(Durability)**:一旦事务提交成功,其对数据库的修改应该是持久的,即使系统发生崩溃或者重启,修改的数据也应该被保存。因此,事务的概念是数据库系统设计的基础之一,它为用户提供了一种安全、可靠和高效地访问和管理数据的方式。事务的目的是维护数据的一致性、完整性和可靠性。

2024-04-16 21:05:48 140

原创 SpringBoot相关知识点总结

总的来说,`@SpringBootApplication` 注解标记了一个类作为 Spring Boot 应用程序的主类,并启用了 Spring Boot 的自动配置机制和组件扫描机制,简化了应用程序的配置和启动过程,提高了开发效率。:Spring Boot Starters 遵循 Spring Boot 的约定优于配置的设计原则,通过预定义好的依赖项和配置,简化了应用程序的配置过程,使得开发者可以更专注于业务逻辑的实现,而无需过多地关注底层技术细节。这样的配置类通常会被。

2024-04-16 20:17:27 249

原创 Spring bean的生命周期

5. **销毁**:在容器关闭或者销毁时,容器会调用 Bean 的销毁方法,通常是调用 `@PreDestroy` 注解标注的方法或者实现 DisposableBean 接口的 destroy() 方法。2. **依赖注入(Dependency Injection)**:在实例化完成后,容器会将 Bean 的依赖注入到 Bean 实例中,即将其他 Bean 或者配置的属性值注入到当前 Bean 实例中。4. **使用**:在初始化完成后,Bean 就可以被容器或者其他组件使用了。

2024-04-15 19:33:26 105

原创 如何理解AQS

总的来说,AQS 的核心原理是通过状态管理、等待队列、获取锁与释放锁、模板方法和条件等待与唤醒等机制来实现对共享资源的安全访问和控制。通过合理地组织和管理这些机制,AQS 提供了一个灵活可靠的同步框架,可以用来构建各种类型的同步器,实现不同的同步语义。具体的获取锁和释放锁的逻辑由具体的同步器自行实现,通常通过尝试获取锁、加入等待队列、自旋等方式来实现对锁的控制。等待队列的管理是 AQS 中的关键之一,它通过维护等待队列中的线程状态来实现线程的阻塞和唤醒。AQS 提供了一些模板方法供具体的同步器来实现。

2024-04-15 16:57:09 109

原创 Synchronized的锁升级过程

在自旋过程中,线程会在原地循环等待,不停地检查条件是否满足,而不会进入阻塞状态或释放 CPU 使用权。因此,自旋会消耗 CPU 时间,但避免了线程进入和退出阻塞状态的开销,可以提高程序的响应速度和性能。如果等待时间过长,自旋可能会导致 CPU 时间的浪费,影响系统的整体性能。因此,在使用自旋时需要谨慎考虑等待时间和自旋次数,以及合适的条件。总的来说,synchronized 锁会根据竞争情况逐步升级为偏向锁、轻量级锁和重量级锁,从而保证了多线程环境下对共享资源的安全访问。

2024-04-15 16:04:22 138

原创 CAS算法如何理解

CAS是个原子操作,但是i++并不是,i++其实对应了三步,每一步是一个原子操作。在使用 CAS 的情况下, i++ 操作并不是一个原子操作,因为它包含了读取、计算和写入这三个步骤,并且在这个过程中可能会发生并发冲突。:这一步在工作内存中进行,此时记录下期望值就是期望去更新的时候i的值还是现在读到的这个值E,进行 i++ 操作得到新值,此时新值是+1后的,这个就是新值N。:从主内存中读取i的现在的值,这个叫当前值V,如果当前值V和E相等,那么理解为这个期间该值没有被其他线程操作更新过(ABA除外)。

2024-04-12 16:07:28 188

原创 volatile 关键字

一个i++的赋值其实对应了三个操作,而这三个操作在多线程环境下,在执行的时候是可能存在执行了1,线程切换了,那么这时候i++就不是在原子性操作了,(所以理解他为什么保证不了原理性,最主要的是要理解这个操作中间线程是否会被打断执行别的,这个是否会中断执行别的其实本质也是JVM来控制的,也就是说设计这个字段的时候,JVM在识别到这个的时候不会强行执行完一组操作才切换),就可能导致并发问题。如果我们将一个变量使用 volatile 修饰,这就指示 编译器,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。

2024-04-11 20:33:32 294

原创 Java 内存区域和 JMM 有何区别

这是一个比较常见的问题,很多初学者非常容易搞混。 Java 内存区域和内存模型是完全不一样的两个东西:JVM 内存结构和 Java 虚拟机的运行时区域相关,定义了 JVM 在运行时如何分区存储程序数据,就比如说堆主要用于存放对象实例。 Java 内存模型和 Java 的并发编程相关,抽象了线程和主内存之间的关系就比如说线程之间的共享变量必须存储在主内存中,规定了从 Java 源代码到 CPU 可执行指令的这个转化过程要遵守哪些和并发相关的原则和规范,其主要目的是为了简化多线程编程,增强程序可移植性的。

2024-04-11 11:49:29 298 1

原创 JMM是什么以及如何理解

综上所述,JMM 是 Java 中多线程编程的重要基础,它定义了程序中共享变量的访问规则,确保多线程程序的正确性和可靠性。:JMM 定义了一种抽象的计算机内存模型,描述了程序中各个线程之间共享变量的访问规则。它规定了主内存、工作内存和线程之间的关系,确保线程对共享变量的修改能够及时对其他线程可见。:JMM 保证了一个线程修改的共享变量的值对其他线程是可见的。:JMM 保证了对基本数据类型读取和赋值的原子性,即一个线程执行读取或赋值操作时,不会被其他线程中断,保证了这些操作的原子性。

2024-04-11 11:24:57 178

原创 如何理解JVM

4. **垃圾回收**:JVM的垃圾回收机制负责自动管理程序的内存分配和释放,通过监控对象的引用计数和可达性分析来识别和清理不再使用的对象,以避免内存泄漏和内存溢出。5. **性能调优**:理解JVM还涉及到性能调优和优化技术,包括调整堆内存大小、选择合适的垃圾收集器、优化代码结构和逻辑等方面。总的来说,理解JVM是理解Java程序运行机制和性能优化的关键,它是Java平台的核心,直接影响到Java程序的性能和稳定性。JVM(Java虚拟机)是Java程序的运行环境,它是Java技术的核心组成部分之一。

2024-04-10 17:27:55 377

原创 进程和线程的区别

同一进程内的多个线程之间的并发执行是在共享同一进程的资源下进行的,需要考虑线程同步和互斥的问题。- 不同进程之间的并发执行是真正的并行执行,因为它们拥有独立的内存空间和资源,相互之间不会影响。- 线程是进程中的一个执行单元,是操作系统调度的基本单位,共享所属进程的内存空间和系统资源。- 线程之间的切换开销较小,因为它们共享同一进程的地址空间,切换时只需要保存少量的线程状态。- 进程是程序的一次执行实例,是系统分配资源的基本单位,拥有独立的内存空间和系统资源。

2024-04-10 17:16:17 283

原创 如何理解用户态和内核态

用户态和内核态的切换是由硬件中断和系统调用(syscall)触发的,操作系统通过这种方式来控制用户程序对系统资源的访问权限。- 内核态的代码通常是操作系统内核中的核心代码,需要保护和隔离,防止用户程序对其进行恶意修改或访问。- 用户态和内核态的切换开销较大,因此系统设计中应尽量减少频繁的切换操作,提高系统的性能和响应速度。用户态和内核态是操作系统中的两种不同的运行模式,它们用于区分代码在系统中的执行权限和访问权限。- 在内核态下,操作系统拥有对所有硬件和系统资源的完全访问权限,可以执行特权指令和操作。

2024-04-10 17:11:38 275

原创 Spring如何解决循环依赖

(注意存放的是代理对象的工厂对象并不是代理对象本身):如果 Bean A 依赖于 Bean B,同时 Bean B 也依赖于 Bean A,则在创建 Bean A 的过程中会触发创建 Bean B,而在创建 Bean B 的过程中又会触发创建 Bean A,导致循环依赖。存放代理对象的工厂对象的目的是为了在需要使用代理对象的时候能够快速获取已经创建好的代理对象,而不需要重新创建。总的来说,三级缓存的作用是在处理循环依赖时提供一种机制,确保代理对象的创建和使用能够顺利进行,避免循环依赖导致的问题。

2024-04-03 15:18:22 576 2

原创 java代理模式

代理模式有两种静态代理:需要为每个目标类写个代理类,代理类中需要引用目标类来编码实线动态代理:jdk api和cglib两种。

2023-12-21 17:03:27 778

原创 MySQL的主从和分库分表

主从分离:多读少些的场景MySQL1)主从复制使用的是binlog 异步的方式MySQL 的主从复制是依赖于 binlog 的,也就是记录 MySQL 上的所有变化并以二进制形式保存在磁盘上二进制日志文件。主从复制就是将 binlog 中的数据从主库传输到从库上,一般这个过程是异步的,即主库上的操作不会等待 binlog 同步的完成。主从复制的过程是这样的:首先从库在连接到主节点时会创建一个 IO 线程,用以请求主库更新的 binlog,并且把接收到的 binlog 信息写入一个叫做 rel

2021-03-21 21:22:15 747 1

原创 Spring事务总结

Spring可以使用编程式事务,也可以使用声明式事务。不过一般用的多的是用声明式。1、Spring事务的四种隔离级别MySQL事务有四个特性:ACID原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。隔离性(Isolation):可能有许多事务会同时处理相同的数

2021-03-21 16:01:48 211

原创 Spring的IOC和AOP

Spring最根本的使命上: 简化Java开发。DI所带来的最大收益——松耦合。对象之间的依赖关系交由Spring的IoC容器依赖注入的本质就是装配,装配是依赖注入的具体行为用更通俗的话来说,IoC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。为了降低Java开发的复杂性, Spring采取了以下4种关键策略: 基于POJO的轻量级和最小侵入性编程; 通过依赖注入和面向接口实现松耦合; 基于切面和惯例进行声明式编程;

2021-03-21 15:11:53 199

原创 leetcode---236. 二叉树的最近公共祖先(最近公共祖先)

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉树:root =[3,5,1,6,2,0,8,null,null,7,4]示例 1:输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1输出: 3解释: 节点 5 ...

2020-08-16 15:31:22 263

原创 leetcode---235. 二叉搜索树的最近公共祖先(最近公共祖先)

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树:root =[6,2,8,0,4,7,9,null,null,3,5]示例 1:输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8输出: 6解释: ...

2020-08-16 15:27:12 914

原创 leetcode---110. 平衡二叉树(高度平衡)

给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。示例 1:给定二叉树 [3,9,20,null,null,15,7] 3 / \ 9 20 / \ 15 7返回 true 。示例 2:给定二叉树 [1,2,2,3,3,null,null,4,4] 1 / \ 2 2 / \ 3 3 ...

2020-08-16 14:58:20 400

原创 leetcode---814. 二叉树剪枝

给定二叉树根结点root,此外树的每个结点的值要么是 0,要么是 1。返回移除了所有不包含 1 的子树的原二叉树。( 节点 X 的子树为 X 本身,以及所有 X 的后代。)思路:1)什么是二叉树的剪枝假设有一棵树,最上层的是root节点,而父节点会依赖子节点。如果现在有一些节点已经标记为无效,我们要删除这些无效节点。如果无效节点的依赖的节点还有效,那么不应该删除,如果无效节点和它的子节点都无效,则可以删除。剪掉这些节点的过程,称为剪枝,目的是用来处理二叉树模型中的依赖问题。因此剪..

2020-08-16 14:39:06 223

原创 leetcode---82. 删除排序链表中的重复元素 II

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中没有重复出现的数字。示例1:输入: 1->2->3->3->4->4->5输出: 1->2->5示例2:输入: 1->1->1->2->3输出: 2->3思路:将有序链表中重复的数组都删除掉,之前easy级别的是保留一个。我们采取两个指针,一个是pre记录当前之前的节点,一个是cur,1)如果当前的和其下一个相等,那么当前就...

2020-07-09 15:17:43 179

原创 leetcode---83. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。示例1:输入: 1->1->2输出: 1->2示例2:输入: 1->1->2->3->3输出: 1->2->3思路:这个题目是排序链表,重复出现的只保留一个。跟数组的有些类似。不同的是数组是连续空间。需要将后面的拷贝到前面。而链表只需要将节点指向改变就可以。1、可以像数组那种采用快慢指针法去做。2、也可以只使用一个指针,就是当前的和下一个相比,如果不同,当前的..

2020-07-09 15:02:44 105

原创 leetcode---80. 删除排序数组中的重复项 II

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。示例1:给定 nums = [1,1,1,2,2,3],函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。你不需要考虑数组中超出新长度后面的元素。示例2:给定 nums = [0,0,1,1,1,1,2,3,3],函数应返回新长度 l..

2020-07-09 14:55:16 176

原创 leetcode---26. 删除排序数组中的重复项

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。示例1:给定数组 nums = [1,1,2],函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。你不需要考虑数组中超出新长度后面的元素。示例2:给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, ...

2020-07-09 14:43:13 146

原创 leetcode---61. 旋转链表

给定一个链表,旋转链表,将链表每个节点向右移动k个位置,其中k是非负数。示例1:输入: 1->2->3->4->5->NULL, k = 2输出: 4->5->1->2->3->NULL解释:向右旋转 1 步: 5->1->2->3->4->NULL向右旋转 2 步: 4->5->1->2->3->NULL示例2:输入: 0->1->2-&gt...

2020-07-06 11:29:48 132

原创 leetcode---147. 对链表进行插入排序

插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。插入排序算法:插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。重复直到所有输入数据插入完为止。示例 1:输入: 4->2->1->3输出: 1->2->..

2020-07-03 15:21:26 108

原创 leetcode---86. 分隔链表

给定一个链表和一个特定值x,对链表进行分隔,使得所有小于x的节点都在大于或等于x的节点之前。你应当保留两个分区中每个节点的初始相对位置。示例:输入: head = 1->4->3->2->5->2, x = 3输出: 1->2->2->4->3->5思路:将链表分隔,其实这跟链表的特性相关。因为链表是next属性进行相连接的。我们在调整链表的时候其实只需要不断调整next属性指向即可。那么这个题目我们可以引入两个头...

2020-06-30 15:08:01 99

原创 leetcode---143. 重排链表

给定一个单链表L:L0→L1→…→Ln-1→Ln ,将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。示例1:给定链表 1->2->3->4, 重新排列为 1->4->2->3.示例 2:给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.这个题其实就是将后面的链表的节点依次进行往前面的空里..

2020-06-29 17:30:07 303

原创 leetcode---21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例:输入:1->2->4, 1->3->4输出:1->1->2->3->4->4思路:新链表是通过拼接给定的两个链表的所有节点组成的,这句话限制了我们不能新增一个链表来存储合并后的链表的节点,而是需要在比较的过程中不断调整两个链表的节点的指针指向最后把两个链表合并成一个链表。在遍历时当两个链表都还没有走到最后为空的位置,需要对两个链表当前.

2020-06-24 16:38:20 219

原创 leetcode---2. 两数相加

给出两个非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0开头。示例:输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)输出:7 -> 0 -> 8原因:342 + 465 = 807思路:逆序存储,相加的时候也是逆序相加。这样加出来的新链表每...

2020-06-23 17:25:43 208

原创 leetcode---206. 反转链表

反转一个单链表。示例:输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL思路:反转链表,就是我们需要把链表的当前结点的下一个结点先保存起来。然后将当前结点的next指向它的前一个。然后再移动指向当前结点的和其前一个。/** * Definition for singly-linked list. * public class ListNode { * int..

2020-06-23 15:17:17 232

原创 leetcode---19.删除链表的倒数第N个节点

题目:给定一个链表,删除链表的倒数第n个节点,并且返回链表的头结点。示例:给定一个链表: 1->2->3->4->5, 和 n = 2.当删除了倒数第二个节点后,链表变为 1->2->3->5.说明:给定的 n保证是有效的。思路:考察两个知识点,一是删除结点如果是删除的是都一个结点,那么得特殊处理处理。所以引入虚拟的头结点,让头指针指向头结点,题目要求返回链表的头结点其实就是返回链表的第一个结点。也就是引入的头结点的next二 快...

2020-06-23 14:40:22 145

原创 头结点的含义以及引入头结点的作用

一、概念头结点:是虚拟出来的一个节点,不保存数据。头结点的next指针指向链表中的第一个节点。对于头结点,数据域可以不存储任何信息,也可存储如链表长度等附加信息。头结点不是链表所必需的。头指针:是指向第一个结点的指针,如果链表没有引入头结点,那么头指针指向的是链表的第一个结点。头指针是链表所必需的。[注意]无论是否有头结点,头指针始终指向链表的第一个结点。如果有头结点,头指针就指向头结点。二、为何引入头结点1)对链表的删除、插入操作时,第一个结点的操作更方便如果链表没有头结点,那么头

2020-06-23 11:56:15 18728 6

原创 IDEA "Library source does not match the bytecode for class"问题

Jar包更新后,报错信息:"Library source does not match the bytecode for class"发现Jar内容还是旧版本的。点击 File -> Invalidate Caches and Restart后解决

2020-01-13 15:13:41 2683

原创 mybatis 批量增加 Parameter '__frch_item_0' not found. Available parameters are [list]

1.查看parameterType的类型是不是java.util.List类型,如果是的话,看foreach 的collection属性是不是list,因为 传递一个 List 实例或者数组作为参数对象传给 MyBatis,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list” 作为键,而数组实例将会以“array”作为键2.看一下fo...

2019-12-01 19:49:53 560

原创 Maven 打包 package install deploy 命令的含义和区别

mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。package命令:完成项目编译、单元测试、打包功能,但打包文件未部署到本地Maven仓库和远程Maven仓库。mvn clean install依次执行了clean、resources、compile、...

2019-10-25 16:02:11 350

原创 leetcode---1. 两数之和

给定一个整数数组 nums和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9所以返回 [0, 1]解题思路:...

2019-10-22 16:05:09 115

原创 leetcode---122. 买卖股票的最佳时机 II

给定一个数组,它的第i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例 1:输入: [7,1,5,3,6,4]输出: 7解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交...

2019-10-22 14:47:16 155

原创 leetcode---买卖股票的最佳时机

给定一个数组,它的第i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。注意你不能在买入股票前卖出股票。示例 1:输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 ...

2019-10-18 17:52:23 118

空空如也

空空如也

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

TA关注的人

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