自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 缓存淘汰算法LRU

1 概述LRU(Least Recently Used)算法是一种缓存淘汰算法,当系统的缓存过大,达到删除缓存的阀值时,最先删除最久没有被使用过的数据,被用于操作系统和Redis数据库中。LRU的底层是由哈希算法+链表组成的。哈希算法具有查找高效的优点,却没法保存添加顺序,因此采用链表记录数据的使用顺序。说白了就是数据被存为两份,哈希和链表各一份。在没有达到缓存上限时候,它两相安无事,当达到缓存上限时,根据链表中保存的使用顺序进行删除。2 图解数据移动顺序假设系统缓存的上限为3个节点2.1 向缓存

2021-07-27 22:32:55 3024

原创 Spring5 IOC源码解读系列13—createBean方法

一 概述createBean顾名思义是创建bean对象的实例,但是实际干活还是调用doCreateBean去实例化对象。如果对应的bean是单例的,则会被添加到一级缓存中,并将二三级缓存的数据删除。这里有个两个重要的概念,一个是循环依赖,说简单点就是两个Bean存在相互引用的情况,在Sspring中当且仅当Bean的类型为单例且属性注入存在对其他Bean的引用的情况下,Spring通过三级缓存解决了循环依赖问题,其他场景(Bean非单例,构造函数存在对其他Bean的依赖等)都会抛出异常!另外一个就是B

2021-07-03 14:32:33 3157 1

原创 Spring5 IOC源码解读系列12—getBean方法

一 概述getBean方法从缓存中获取Bean对象得实例,如果获取不到,则触发Bean对象的创建方法createBean。Bean根据作用域划有很多种,日常主要打交道的还是单例的比较多,本篇主要详细讲解单例bean的创建,其他的不做展开。二 源码2.1 getBeanpublic Object getBean(String name) throws BeansException { //do开头方法才是实际干活 return doGetBean(name, null, null, fals

2021-06-28 21:01:09 3397

原创 Spring5 IOC源码解读系列11—isFactoryBean方法

一概述FactoryBean是一个接口,通过它可以达到自定义bean的实例化过程的目标,为Spring容器中Bean的实现提供了更加灵活的方式。说简单的,我们编写一个FactoryBean实现类并将其注入到Spring容器中,可以在接口抽线方法getObject的实现方法中完成特定业务的Bean的实例化。二应用2.1 创建POJOpublic class Person { private String name; public Person() { Syst

2021-06-24 19:04:23 3620

原创 Spring5 IOC源码解读系列10—finishBeanFactoryInitialization方法

一 概述finishBeanFactoryInitialization方法是Spring刷新/refresh方法中最核心。这个方法的主要作用是完成非抽象,单例,非懒加载的Bean的实例化。鉴于这个方法太复杂,我把其中部分方法拆出来单独写出博客,详见《Spring5 IOC源码解读系列》后续文章。二 源码2.1 finishBeanFactoryInitialization方法protected void finishBeanFactoryInitialization(ConfigurableLis

2021-06-24 19:01:04 3469

原创 Spring5 IOC源码解读系列9—registerListeners方法

一 概述Spring的事件监听主要涉及三个角色:1)事件:ApplicationEvent抽象类的继承者;2)事件发布者:事件多播器ApplicationEventMulticaster接口的实现类,比如SimpleApplicationEventMulticaster;3)事件监听器:ApplicationListener 接口的实现类。registerListeners方法主要将实现监听器接口(即ApplicationListener接口)的bean们注册到多播器中,即存储到application

2021-06-20 17:44:21 3845

原创 Spring5 IOC源码解读系列8—initApplicationEventMulticaster方法

一 概述initApplicationEventMulticaster主要用于为当前上下文初始化事件多播器。二 源码2.1 initApplicationEventMulticaster方法protected void initApplicationEventMulticaster() { //获取Bean工厂 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //判断beanF

2021-06-19 23:34:32 3618

原创 Spring5 IOC源码解读系列7—initMessageSource方法

1 概述initMessageSource主要用于国际化,说简单点就是不同语言之间的翻译2 应用2.1 添加Bean在Spring的配置文件中名称为messageSource(名称不能错,否则读取失效!)的Bean<bean id="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="bas

2021-06-19 18:04:34 3980

原创 Spring5 IOC源码解读系列6—registerBeanPostProcessors方法

一 概述BeanPostProcessor接口是Spring留给用户,用于bean的拓展。在Spring Bean的生命周期中,BeanPostProcessor接口实现类XX的postProcessBeforeInitialization方法执行时间早于Spring Bean实例化,称为前置处理器;XX的postProcessAfterInitialization方法的执行时间晚于Spring Bean实例化,称为后置处理器。registerBeanPostProcessors方法的主要作用是实例化并

2021-06-16 18:42:21 3793

原创 Spring5 IOC源码解读系列3—prepareBeanFactory方法

一 概述prepareBeanFactory方法的主要作用是配置工厂的标准上下文特征,如上下文的类加载器和后处理器。二 源码2.1 prepareBeanFactoryprotected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. //设置

2021-06-15 23:37:15 3956

原创 Spring5 IOC源码解读系列2—obtainFreshBeanFactory方法

一 概述obtainFreshBeanFactory主要刚了两件大事:1)干掉旧的BeanFactory,生成新的BeanFactory 2)加载Spring配置文件转换为BeanDefinition,并注册到beanDefinitionMap中。第2件事的BeanDefinition加载流程说详细点就是:1)Resource定位,即在Resource类中封装配置文件的路径和对应类加载器 2)将定义的配置文件转换为BeanDefinition 3)执行BeanDefinitionReaderUtils

2021-06-15 23:32:58 4644 1

原创 Spring5 IOC源码解读系列1—prepareRefresh方法

一 概述prepareRefresh是抽象类AbstractApplicationContext中的方法,主要干了刷新前的准备工作,比如设置上下文的属性,配置文件的校验等。如果开启debug模式,执行完prepareRefresh后会打印日志DEBUG org.springframework.context.support.ClassPathXmlApplicationContext -Refreshing org.springframework.context.support.ClassPathXm

2021-06-15 23:30:20 4929 2

原创 Spring5 IOC源码解读系列5—invokeBeanFactoryPostProcessors方法

一 概述invokeBeanFactoryPostProcessor主要作用是实例化已经在容器中注册过的BeanFactoryPostProcessor接口的实现类,回调postProcessBeanFactory方法等。invokeBeanFactoryPostProcessor源码调用链又长又复杂,容易把人绕晕,因此本文主要围绕着先使用,再研究源码顺序,逐步段解析,从易到难。二 BeanFactoryPostProcessor接口及其应用BeanFactory 后置处理器BeanFactory

2021-06-15 23:27:38 5124 3

原创 Java源码解读系列13—HashMap(JDK1.8 )

1 概述JDK7的HashMap底层采用数组+链表数据结构进行存储,会存在一个问题,即当解决哈希碰撞的链表过长的时候,HashMap的查询效率就会变低。红黑树是平衡二叉树(黑色平衡),其查询效率为O(lgn),优于链表的查询效率O(n)。 因此JDK8的HashMap底层采用数组+链表+红黑树数据结构进行存储。具体过程如下, 1)每次新增一个数据,就会被插入到数组中的空位。慢慢的数据多了,就会存在哈希碰撞问题,即2个key的索引一样。HashMap采用的解决方法是链地址法。数组中每个元素设置链表。ke

2021-04-19 01:03:18 3981

原创 Java源码解读系列12—线程池(中,JDK1.8 )

1 概述通过上一篇《Java源码解读系列11—线程池(JDK1.8 )》的学习,对于先线程池的使用应该问题不大。线程池源码非常多,本文主要讲解如何通过线程池复用线程,使用线程池创建的线程跟我们Thread类的start方法究竟有何异同。2 线程池状态将线程池状态存储在二进制的高位置。private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));//32 - 3 = 29private static final int

2021-04-14 00:53:23 3803

原创 Java源码解读系列11—线程池(上,JDK1.8 )

1 概述一开始听到这么牛逼的名字,博主还以为是操作系统的底层直接提供的,可以用来直接创建线程的。看完源码后才知道,线程池实际上是java.util.concurrent包下面用来管理线程的工具,开发语言是java代码,启动线程还是依赖于底层提供的Thread类的Native方法start0()。线程池的优点主要有 1)复用线程对象,降低频繁的创建和销毁线程是带来的开销。2)方便管理线程。线程池已经封装了线程监管,异常处理,线程创建和销毁等方法,开箱即用。 3)提供并发处理性能。因为线程池中核心

2021-04-13 23:19:42 3902 1

原创 Java源码解读系列10—SynchronousQueue(非公平模式,JDK1.8 )

1 概述SynchronousQueue(简称SQ)是BlockingQueue接口的实现类,是一种阻塞、线程安全的、不存储任何元素的同步队列。SQ的底层实现分为两种,一种是非公平模式(默认),采用栈的数据结构,先入队的数据,后出队,即可LIFO;另外一种是公平模式,采用队列的数据结构,先入队的数据,先出队,即FIFO。SQ跟LinkedBlockingQueue(LBQ)和ArrayBlockingQueue(ABQ)等阻塞队列,最大一个不同点是一个线程t1执行put操作后,必须有另外线程t2

2021-04-04 22:28:47 4141

原创 Java源码解读系列9—SynchronousQueue(公平模式,JDK1.8 )

1 概述SynchronousQueue(简称SQ)是BlockingQueue接口的实现类,是一种阻塞、线程安全的、不存储任何元素的同步队列。SQ的底层实现分为两种,一种是非公平模式(默认),采用栈的数据结构,先入队的数据,后出队,即可LIFO;另外一种是公平模式,采用队列的数据结构,先入队的数据,先出队,即FIFO。SQ跟LinkedBlockingQueue(LBQ)和ArrayBlockingQueue(ABQ)等阻塞队列,最大一个不同点是一个线程t1执行put操作后,必须有另外线程t2

2021-04-04 11:50:25 4330 3

原创 Java源码解读系列8—ArrayBlockingQueue(JDK1.8 )

1 概述ArrayBlockingQueue(简称ABQ)是BlockingQueue接口的实现类,是一种有界界、阻塞、线程安全的FIFO队列。ABQ底层存储基于数组,因此需要在初始化时候指定数组容量。相对基于链表实现的阻塞队列LinkedBlockingQueue(简称LBQ),ABQ队列中元素的入队和出队都是使用同一把锁来保证线程安全,实现更加简单。2 构造函数//capacity是数组容量public ArrayBlockingQueue(int capacity) { //默认

2021-03-28 22:24:39 4513

原创 Java源码解读系列6—LinkedBlockingQueue(JDK1.8 )

1 概述LinkedBlockingqueue(简称LBQ)是BlockingQueue接口的实现类,是一种无界、阻塞、线程安全的FIFO队列。LBQ底层存储基于链表,头节点为哨兵节点,里面的数据域(item)为空。插数据时从尾节点插入,取数据时从头节点(若队列非空,则找第一个item不为空的节点)获取。相对于非阻塞的ConcurrentLinkedQueue(简称CLQ队列),LBQ的实现比较简单,就是采用添加和取出两把锁来保证线程安全。2 链表节点的数据结构 static class Node

2021-03-21 16:38:24 4673

原创 Java源码解读系列7—ConcurrentLinkedQueue(JDK1.8 )

1 概述ConcurrentLinkedQueue(简称CLQ队列)是Queue接口的实现类,是一种无界、非阻塞、线程安全的FIFO队列。CLQ底层存储基于链表,头节点为哨兵节点,里面的数据域(item)为空。插数据时从尾节点插入,取数据时从头节点获取。相对于LinkedBlockingqueue(简称LBQ队列)采用读写各一把锁的机制保证线程安全,CLQ队列采用自旋+CAS机制实现无锁非阻塞。无论是同时有又多个生产者,还是多个消费者,都不会发生线程阻塞,遇到插入失败或者取数据失败的线程就会继续自旋,直到

2021-03-21 14:17:41 4752

原创 Java源码解读系列5—FutureTask(JDK1.8 )

1 概述FutureTask类是Future接口和Runnable接口的实现类,主要为了解决异步计算并获取返回值,缺点也很明显,获取返回值的方法get是阻塞的,如果获取不到返回值会阻塞当前线程,是典型的阻塞编程。下面是一个使用用例:public class CallableApp implements Callable<String> { private String name; public CallableApp(String name) { th

2021-03-13 22:28:50 4730 1

原创 Java源码解读系列2—Unsafe类(JDK1.7 )

1 概述Java与C语言一个较大差别是JVM屏蔽底层细节,使我们开发能够更专注于业务实现。Unsafe类,顾名思义就说非安全类,属于sun.misc包下,是java开放给用户直接接触底层。网上大部分文章大部分直接讲解API,楼主这篇文章是通过应用场景去讲解Unsafe类,并且每个用途都附上使用用例,不仅懂你原理,还让你会使用。但还是由衷告诫你,除非是用来开发基础框架,否则不推荐使用。2 初始化方法在ConcurrentHashMap的源码中,我们可以看到Unsafe的示例化方法private st

2021-03-07 23:21:52 4851 1

原创 Java源码解读系列4—ReentrantLock(JDK1.8 )

1 概述Java程序提供两种方法来实现锁功能1)synchronized关键字和2)lock接口,两者最大区别是synchronized是Java内置的关键字,是JVM层面的锁;而lock是java.util.concurrent包下面提供的工具,由Java代码编写的。在JDK1.6之前,synchronized是重量级锁,每次都会调用OS使线程进入阻塞状态;ReentrantLock是轻量锁,如果只是当单纯线程交替等场景,是不会触发OS的,性能优于synchronized关键字。现在两者性能已经差不多,

2021-03-06 12:33:33 4655 3

原创 Java源码解读系列3—ConcurrentHashMap(JDK1.7 )

1 概述普通的的curd业务工作,一般都是单线程居多,key-value操作基本是HashMap一招吃遍天下鲜。博主由于工作原因,每天工作需要使用大量多线程技术,因此本文不是定位为解释ConcurrentHashMap中的每一行代码,而是从解决并发的视角去思考,为什么ConcurrentHashMap能用于多线程环境!涉及到并发场景,我们可以使用线程安全容器HashTable和ConcurrentHashMap替代HashMap。HashTable解决多线程访问时对每个方法都加了synchronized

2021-02-15 21:36:22 4679 1

原创 Jmeter入门:RESTful接口压测

1 安装JDKJmeter 是基于Java,因此需要Java环境。网上安装JDK资料很多,在此不再累述。2 安装Jmeter从官网下载windows版安装包apache-jmeter-5.4.zip,解压到本地D:\apache-jmeter-5.42.1 修改环境变量1)新增全局变量JMETER2)修改CLASSPATH在末尾添加:%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;%JMETER_HOME%\lib\jorphan.jar;3)修改

2021-01-26 23:56:43 5559

原创 Java源码解读系列1—HashMap(JDK1.7 )

1 HashMap的默认构造方法HashMap底层采用数组+链表数据结构进行存储。每次新增一个数据,就会被插入到数组中的空位。慢慢的数据多了,就会存在哈希碰撞问题,即2个key的索引一样。HashMap采用的解决方法是链地址法。数组中每个元素设置链表。key映射到数组某个元素中,而数据项本身插入到元素的链表中。//数组的默认容量为16static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 默认负载因子为0.75,建议不要设置超过

2020-08-24 16:45:32 583 1

原创 数仓工具Hive必知必会

1 Hive架构图1.1 客户端用户通过客户端访问Hive,简单查询一般在Linux上使用belline进行交互;对于Java程序,可以通过JDBC访问Hive。1.2 Metastore元数据相关,Hive默认存储在Derby数据库,缺点用户不能同时执行两个Hive CLI实例,因此实际生产中常常使用Mysq进行替代。1.3 解析器、编译器、优化器和执行器1)解析器:将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段

2020-07-26 21:22:36 500

原创 Elasticsearch环境错误排查

1 ES启动后,本机可以通过localhost访问,但无法通过IP发访问修改配置文件vim ${ES_HOME}/config/elasticsearch.yml 新增如下配置:http host: "[::]"重启ES即可。2 ES启动后,外网无法访问或者外网IP被防火墙拦掉了,用户根据公司环境选择暂时关闭或者永久关闭防火墙。1)暂时关闭防火墙systemctl stop firewalldservice iptables stop2)永久关闭防火墙systemctl dis

2020-07-25 17:48:20 3009 2

原创 分布式存储HDFS必知必会

分布式文件系统HDFS的设计原理

2020-07-22 22:57:15 5636 1

原创 《Hadoop权威指南》读书笔记——MapeReduce入门

1 MR的原理MapeReduce(简称MR)的是大数据计算引擎,相对于Linux awk等工具而已,最大的优势是可以分布式执行,充分利用计算机的多核性能。一个MR作业(job)是客户端需要执行的一个工作单元,包括输入数据、MR程序和配置信息。作业又可以分成若干个任务(task)来执行,包括map任务和reduce任务。原始数据被MR按照HDFS的快大小(默认128M)分片(split),每一个片是启动一个map任务,计算完的中间结果暂时存在本地。reduce拉取中间结果后进行计算输出最终结果,如下图所

2020-07-02 20:28:35 5793

原创 Spark Streaming消费Kafka并手动使用Redis管理Kafka Offset

1 Spark Streaming读取Kafka的两种模式Spark Streaming消费Kafka的数据有两种模式:Receiver和Direct模式,学习时候重点关注下Direct即可,因为在最新读取模方式中已经不支持Receiver。1.1 Receiver模式在Spark 1.3之前,Spark Streaming消费Kafka中的数据采用基于Kafka高级消费API实现的Rece...

2020-04-27 23:19:33 7752

原创 Spark源码分析系列—编译源码

1 Spark源码的下载作为一名大数据开发工程师,研读源码是我们日常开发学习中必不可少的环节,而万里长征的第一步就是编译源码。开源Spark主要有3大发行版Apache,CDH和HDP,本文以Apache Spark 2.4.5为例展开。1) 访问Apache Spark官网http://spark.apache.org/,点击Download2)选择版本和文件类型特别注意最后一行声明...

2020-04-13 20:04:58 5988

原创 深入浅出JVM系列1:类加载器及其用法

1 类产生的原因在Linux上创建hello.c,使用gcc编译器进行编译gcc hello.c -o hello,得到绿色的可执行程序hello,执行./hello便会在控制台输出Hello World!学过编译原理的同学都清楚,整个编译过程经历了以下阶段:这种编译方式的优点很明显,就是可执行文件运行速度快。缺点也很明显,不能跨平台。1)硬件环境原因:如X86和ARM指令集不一样,输出...

2020-04-02 23:44:15 6355

原创 Apahce Avro入门及其在Spark中的应用

1 Avro简介在互联网发展早期,很多项目都是运行在单体架构上,使用Java原生序列化机制能满足大部分场景需求。后面随着业务和访问量的增大,项目架构慢慢迁移到微服务架构。每个微服务可能采用不同的开发语言,而且部分服务对通信性能要求比较高,这时候Java原生的序列化就不能满足要求。因为Java原生序列化机制存在1)不支持跨语言2)序列化后的体积比较大等问题,所以采第三方的序列化协议就显得很有必要。...

2020-03-29 16:35:09 5699

原创 Shell编程入门

1 认识ShellShell,Kernal和Hardware三者的关系如图1所示。在Linux OS中,默认Shell是Bash。通过命令行#echo $SHELL可以查看当前的Shell类型,# vim /etc/shells 可以查看OS支持的Shell类型。2 创建第1个Shell脚本2.1创建脚本root@ubuntu:~# vim hellowrold.sh 2.2编辑内...

2020-03-19 00:11:17 345

原创 Ubuntu14上搭建HIVE-1.1.0-CDH5.9.3

1 安装HadoopHive是建立在Hadoop上的一个数仓工具,说简单点就是真实数据存储在HDFS上。因此需要先安装Hadoop,详见博文hadoop-2.6.0-cdh完全分布式集群的搭建。2 安装MySQLHive是将结构化的数据文件映射为一张表,映射关系需要存放在数据库上。博主选用MySQL数据库存储HIVE元数据信息。MySQL的按装详见在Ubuntu14中安装MySQL数据库并使...

2020-02-14 02:09:00 429

原创 操作系统要点总结-内存篇

1 什么叫做虚拟内存一个32位的PC,内存的最大容量不超过CPU的寻址范围是2^32B,即4G。如果完全装入一个桌面游戏程序所需要的内存为5G,是不是就不能好好玩耍?答案是否定的,可以使用虚拟内存技术。简单点说就是程序不需要全部装入即可运行,运行时根据需求动态调入数据,若内存不够还要换出部分数据。那虚拟内存有哪些特征呢?1)多次性:无需在作用运行时候一次性全部装入内存,而是被运行多次调入内存;...

2020-01-03 23:46:02 618

原创 从C语言系统调用函数read和write到Java阻塞IO

一 背景作为一名Java代码搬运工,我们经常通过java.io包对进行操作IO。由于JVM跨平台的优点,能够帮开发者屏蔽底层细节,使我们不需要直接与操作系统打交道,更加专注业务开发。缺点也很明显,开发者对底层往往一脸懵逼。最近楼主重读了操作系统一书,对底层原理打破沙锅问到底。二 用户程序读写原理在Linux操作系统中,内存划分为用户空间和内核空间,在4G内存的32位X86系统中,两者的内存占...

2019-12-19 22:32:34 664

原创 二叉搜索树

1 重要特性2 完整代码2.1 二叉搜索树的节点/** * 二叉搜索树的节点 * Created by JayLai on 2019-10-05 22:45:58 */public class Node { //索引 int id; //数据项 String name; //右子节点 Node rightNode; /...

2019-10-14 23:40:53 250

空空如也

空空如也

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

TA关注的人

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