![](https://img-blog.csdnimg.cn/c78c5aa086cb47e6a826c9b8510c9e9a.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
从源码探究原理
文章平均质量分 91
深入源码,探究设计思想
向着百万年薪努力的小赵
当注意力专注于一件事上,岁月就会显得十分轻浮,快的有些过于浪荡——远近书疏,莫不手答,笔翰如流,未尝壅滞
展开
-
从Spring源码探究SpringMVC运行流程
随着不断地使用Spring,以及后续的Boot、cloud,不断的体会到这个拯救Java的生态体系的强大,也使我对于这个框架有了极大的好奇心,以至于产生了我为什么不能写一个这样的框架的思考。通过自学及参考谭勇德(Tom)老师的《Spring5核心原理》这本书,记录此系列博客。愿每个想探究Spring原理的人,学习道路一帆风顺。......原创 2022-07-22 09:49:32 · 38726 阅读 · 22 评论 -
从Spring源码探究AOP代码织入的过程
AOP是OOP的延续,是Aspect Oriented Programming 的缩写,意思是面向切面编程。可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。我们现在做的一些非业务,如︰日志、事务、安全等都会写在业务代码中(也即是说,这些非业务类横切于业务类),但这些代码往往是重复,复制今一粘贴式的代码会给程序的维护带来不便,AOP就实现了把这些业务需求与系统.....原创 2022-07-21 21:45:30 · 41074 阅读 · 0 评论 -
从Spring源码探究DI属性注入流程
当Spring loC容器完成了Bean定义资源的定位.载入和解析注册以后JoC容器中已经管理类Bean定义的相关数据,但是此时loC容器还没有对所管理的Bean进行依赖注入,依赖注入在以下两种情况发生:1)、用户第一次调用getBean()方法时,loC容器触发依赖注入。2)、当用户在配置文件中将元素配置了lazy-init=false属性,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入。BeanFactory 接口定义了Spring loC容器的基本功能规范,是Spring loC容器所原创 2022-07-21 15:15:09 · 40677 阅读 · 2 评论 -
从Spring源码探究IOC初始化流程
从Spring2.0以后的版本中,Spring也引入了基于注解(Annotation)方式的配置,注解(Annotation)是JDK1.5中引入的—个新特性,用于简化Bean的配置,可以取代XML配置文件。而开发入员对注解(Annotation)的态度也是萝卜青菜各有所爱,个人认为注解可以大大简化配置,提高开发速度,但也给后期维护增加了难度。目前来说XML方式发展的相对成熟,方便千统—管理。随看SpringBoot的兴起,基于注解的开发甚至实现了零配置。............原创 2022-07-21 12:52:34 · 40951 阅读 · 15 评论 -
从源码探究双亲委派机制
首先我们要知道双亲委派机制是为了解决什么问题?有关类加载器,可以参考我的这篇博客: 所谓的双亲委派,就是先让父亲加载器试图加载该Class,只有在父亲加载器无法加载该类时才尝试从自己的类路径中加载该类。 通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父亲加载器,依次递归,如果父亲加载器可以完成类加载任务,就成功返回; 只有父亲加载器无法完成此加载任务时,才自己去加载。我们通过这张图来理解一下:在被动的情况下,当一个类加载器收到加载请求,他不会首先自己去加载,而是传递原创 2022-07-13 22:40:38 · 25998 阅读 · 1 评论 -
从源码学习线程池的使用原理及核心思想解析
我们都知道线程的作用,能够异步处理任务,并且能处理多个任务。 但是无限制的使用线程,线程之间的创建、销毁,切换,都会带来一定的消耗! 所以,为了控制线程的数量,复用已有线程,同时减少线程切换带来的开销,,线程池这种池化技术就出来了!!给同学们总结了应付面试的要点:线程池核心设计思想:固定的线程数,来消费我们不定量的task本文是对源码层面对线程池解析,有关线程池的使用,大家可以移步这篇文章:链接: Java并发编程——四种线程池的使用及分析大致给出几种常用线程池介绍: 其实,除了newWo原创 2022-07-12 15:17:04 · 58379 阅读 · 9 评论 -
HashMap源码研究——源码一行一行的注释
看过TreeMap的源码之后,终于来到了重头戏探究HashMap的源码首先依旧是新建一个HashMapHashMap hashMap = new HashMap();让我们点进去,啊不,先看看类图很好,继承了AbstractMap,实现了Map<K,V>, Cloneable, Serializable三个接口,关于类图的打开方式请看这篇文章IDEA 查看 UML 类图接下来按照惯例,先看看里面定义了什么参数(注释过长,这里只截取参数)// 默认的HashMap中数组的长度原创 2021-08-23 15:49:38 · 101408 阅读 · 102 评论 -
HashMap为什么用链表加红黑树?目的是什么?原理是什么
关于HashMap的详解文章:链接: HashMap源码研究——源码一行一行的注释关于hashmap的其他有关问题我在源码研究专栏中都有讲解,深入到源码层次的讲解,绝对一看就懂链接: 深入源码,探究设计思想在jdk1.8版本后,Java对HashMap做了改进,在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度。一句话回答:用链表是为了应对哈希冲突这种情况的我们都知道hashmap是根据算得哈希值来确定数据存放的位置,但是我们也知道哈希值会一样,也就是哈希碰撞这种情况。为了让哈希值一样的原创 2022-07-10 10:46:09 · 21790 阅读 · 10 评论 -
为什么HashMap默认初始容量为2次幂?不是2次幂会怎样?讲讲 HashMap 扰动函数?
关于HashMap的详解文章请移步:链接: HashMap源码研究——源码一行一行的注释通过看源码,我们发现,判断桶的索引的实现是 i = ( n - 1 ) & hash,其中 n 是 map 的容量。任何 2 的整数幂 - 1 得到的二进制都是 1,如:16 - 1 = 15(1111);32 - 1 = 31(11111)而 n-1 与 hash 做的是与运算(&),与运算是 两个都为1,才为1既然我们的 n-1 永远都是 1,那 ( n - 1 ) & hash 的计算结果就是 低位的hash原创 2022-07-10 10:32:17 · 16346 阅读 · 1 评论 -
HashMap为什么扩容重新计算位置后,还能找到以前数据的位置
进行扩容,会伴随着一次重新hash分配,并且会遍历hash表中所有的元素,是非常耗时的。在编写程序中,要尽量避免resize。HashMap在进行扩容时,使用的rehash方式非常巧妙,因为每次扩容都是翻倍,与原来计算的 (n-1)&hash的结果相比,只是多了一个bit位,所以节点要么就在原来的位置,要么就被分配到"原位置+旧容量"这个位置。怎么理解呢?例如我们从16扩展为32时,具体的变化如下所示:因此元素在重新计算hash之后,因为n变为2倍,那么n-1的标记范围在高位多1bit(红色),因此新原创 2022-07-09 22:41:57 · 19636 阅读 · 1 评论 -
探究HashMap源码中最大容量为什么是2的30次方(1<<30)?
在阅读hashmap的源码过程中,我看到了关于hashmap最大容量的限制,并产生了一丝疑问。为啥最大容量是 1原创 2022-07-09 22:33:49 · 16012 阅读 · 0 评论 -
Bean的生命周期(不要背了记思想)
你若是真的为面试而来,请把下面这段背下来,应付面试足矣Bean的生命周期主要是Bean的创建过程,使用和销毁都比较简单如上所说大致可以分为四个阶段:实例化 -> 属性赋值 -> 初始化 -> 销毁给出一个可以让你们看着去跟源码一步一步点下去的无敌图其实学习Bean的生命周期有这个图就足够了没有前置知识盲目的去学习Bean的生命周期,是没有任何意义的,或者说这只是为了应付面试而学没有使用场景,没有复习欲望,看完背完你能记多久呢?一周?一个月?你大学学的计算机网络你还记得吗(手动滑稽)在学习Bea原创 2022-07-05 14:50:12 · 29784 阅读 · 0 评论 -
Spring是如何解决循环依赖问题的及三级缓存的作用
前置知识:所谓的三级缓存只是三个可以当作是全局变量的Map,Spring的源码中大量使用了这种先将数据放入容器中等使用结束再销毁的代码风格Spring的初始化过程大致有四步我们说的循环依赖就是第四步在给Bean属性注入的时候发生的一个问题循环依赖就是:假设有两个类 A和B,A中需要注入B,B中需要注入A由于A注入B时B没有创建,B创建时A也无法创建导致的死循环问题我们都知道AOP是Spring的一个重要核心思想,其实现就是根据动态代理来实现的,也就是说我们的Bean其实很大概率都是要生成代理类,让原创 2022-07-05 15:34:41 · 61979 阅读 · 5 评论 -
ThreadLocal原理及源码解析(一步一步点进去,不要背了,学思想)
我们知道,一个共享变量或者资源,在多个线程操作的时候,肯定是会相互影响,不能隔离的比如,这样的代码,那么得到的结果,肯定是每次加10不定,还有因为原子性问题,肯定会出现相同的10.20…。那么假如我有场景,我要做到线程之前的数据相互不影响!!相互隔离,也就是我们讲的线程安全。比如mybatis里面,sqlsession就是存在ThreadLocal里面的,sqlSession这个对象就是线程安全的!!那么实现方式就是我们今天讲的重点:上面的栗子怎么 变得香甜 实现线程安全?如下:这样我们integer原创 2022-07-07 23:08:46 · 29931 阅读 · 1 评论 -
ReentranLock及源码解析(学思想,一步一步点进源码)
我们知道在并发的场景下,如果同时对共享代码块进行访问时,会导致原子性、有序性、可见性问题。从而导致我业务出错。所以有时候,我们有些代码块不能进行并行,就得去改成串行!!之前我们已经知道了一个Synchronized重量级锁。该锁底层是JVM里面,通过monitor锁来实现串行,其他线程进行等待。那么我们今天要讲的,也是一个锁,只不过相关实现是在java层面去做的。就是可重入锁。虽然在性能上ReentrantLock和synchronized没有什么区别,但ReentrantLock相比synchronize原创 2022-07-08 14:10:01 · 59056 阅读 · 1 评论 -
源码研究——TreeMap
继List之后,笔者又开始了Set与Map的源码探究,本次研究HashMap,HashSet,TreeMap,TreeSet。但是点进去后发现,HashSet与TreeSet点进去后其实就是HashMap与TreeMap。。。。。。先分析Map再分析Set 于是乎,先看TreeMap叭 首先让我们点开类图,看看里面的参数如上图,继承自谁,实现了哪些接口一目了然comparator:比较器root:根节点size:集合大小modCount:修改次数还有一个很重要的,保存 key原创 2021-08-17 16:03:53 · 28276 阅读 · 1 评论 -
从源码讲为什么不推荐使用Vector以及集合的线程安全问题
在看Vector时,不由自主的就把它与同为以动态数组的形式来存储数据的ArrayList做一个比较,然后发现Vector在做任何操作的时候,都好像要比ArrayList要慢半拍。 于是乎,本着不断探索的精神,点进去瞅了瞅它的源码,不看不知道,一看吓一跳,好家伙,原来Vector的操作方法都加的有synchronized关键字,多线程环境下,安全是安全了,但是对性能来说影响可谓是天崩地裂级别的。举例:add方法每个操作方法都加的有synchronized关键字,针对性能来说会比较大的影响,慢慢就原创 2021-08-16 14:33:10 · 26773 阅读 · 0 评论 -
LinkedList源码研究
接着上一篇,研究完ArrarList之后,理所应当看看LinkedList什么是LinkedList呢,它是通过双向链表实现的列表,具有双向链表的优缺点相比较ArrarList,增删效率要高,随机访问效率要低LinkedList首先看一下里面定义的参数transient int size = 0;//节点数量transient Node<E> first;//头节点transient Node<E> last;//尾节点经典的双向链表数据结构它包含一个非常重要的原创 2021-08-13 15:33:41 · 28246 阅读 · 1 评论 -
ArrayList源码研究
背景:实习加工作也有近半年时间了,每天增删改查重复的枯燥无味,于是乎,最近开始了源码的研究,首先便是我们最常用的List接口中的ArrayListArrayListList<Object> list = new ArrayList<>();新建一个ArrayList,ctrl加鼠标点进去除了里面的方法以外,是这么一堆代码/** * Default initial capacity. */ private static final int DEF原创 2021-08-12 16:39:11 · 28254 阅读 · 1 评论