自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Spring源码深度解析之spring整合mybatis原理分析(上)

spring整合mybatis原理分析

2022-03-23 23:28:17 775

原创 Dubbo源码分析-服务导出源码解析(三)

在这个版本中dubbo会通过注解@PostConstruct把ServiceBean实例放到ConfigManager中public abstract class AbstractConfig implements Serializable { @PostConstruct public void addIntoConfigManager() { ApplicationModel.getConfigManager().addConfig(this); }......

2022-03-17 22:44:20 586

原创 Dubbo源码分析-Spring与Dubbo整合原理与源码分析(二)

Spring与Dubbo整合的整体流程(基于apache-dubbo-2.7.15)因为dubbo有较多的兼容以前的代码比如@DubboReference 以前就有两个版本@Reference 和@com.alibaba.dubbo.config.annotation.Reference ,为了方便文章如果提到@DubboReference其实可能还包括的其他两个注解,其他情况也类似。Spring启动时先根据properties配置生成9个Config对象,如应用配置,注册中心配置等。Spirng

2022-03-14 16:26:25 2931

原创 Dubbo源码分析-SPI实现源码解析(一)

Dubbo约定如下SPI文件存储路径在META-INF/dubbo/internal目录下,并且文件名为接口名的全路径名接口包名+接口名每个SPI文件里面格式定义为:扩展名=具体类名,例如dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol实现路径:getExtensionLoader(Class<T> type) 就是为该接口new一个ExtensionLoader,然后缓存起来。getAdaptiveEx

2022-03-12 21:08:39 1422

原创 SQL sum函数一对多场景,消除笛卡尔积

场景:借还款统计数据,一笔贷款可以对应多笔还款。贷款表DROP TABLE IF EXISTS `load_contract`;CREATE TABLE `load_contract` ( `load_id` bigint(0) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '贷款ID', `load_amt` decimal(10, 2) UNSIGNED NULL DEFAULT NULL COMMENT '贷款金额', `persion` var

2022-01-08 00:25:00 1425

原创 设计模式之模板方法模式

前言模板方法设计模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构情况下,重新定义算法中的步骤。一、模板方法设计模式我们以冲咖啡和茶为例。当我们不使用模板模式的时候我们会定义如下两个类。public class Coffee { public final void prepareRecipe(){ boilWater(); brew(); pourInCup(); addCond

2021-08-22 23:24:12 153

原创 高级排序--希尔排序

文章目录前言一、插入排序的缺点二、希尔排序三、 寻找间隔四、java实现五、总结前言希尔排序是基于插入排序实现的(如果不了解插入排序,可以先阅读这篇文章)一、插入排序的缺点假设数据中最小的数排在靠右端位置上,这本来是较大值的数据所在位置,把这个小数据移动到左边位置上,所有的中间数据项都必须向右移动一位。这个步骤对每一个数据项都执行了将近N次的复制。(虽然不是所有数据项都必须移动N个位置,但是数据项平均移动了N/2位置)执行N次N/2个位移,总共是N2/2N^2/2N2/2次复制。因此,插入排序

2021-08-21 10:24:47 110

原创 简单排序--插入排序(三)

前言插入排序算法任然需要O(N^2)的时间,但是一般情况下,他要比冒泡排序快一倍,比选择排序要快一点。一、插入排序假定排序从中间开始,可以更好的理解插入排序。此时,队列左边已经排好序,在队列中间标记一个元素,在这个作为标记的元素左边已经是局部有序,(注意,局部有序在冒泡排序和选择排序中不会出现)这个被标记的元素右边是未排序的。我们需要做的是在左边有序的队列中的适当位置插入被标记的元素。这意味着左边有序的队列需要先向右移腾出空间。而被标记的元素需要出列,以提供位移空间。插入排序的代码如下: pu

2021-08-14 12:23:32 112

原创 简单排序--选择排序(二)

前言选择排序改进了冒泡排序,将必要的交换次数从O(N2)O(N^2) O(N2)减少到O(N)O(N)O(N).不幸的是比较次数仍保持为O(N2)O(N^2)O(N2).一、选择排序进行选择排序就是把所有的元素扫描一趟,从中挑出最小的元素,最小的元素和队列最左端的元素交换位置,即放到0号位置。现在最左端的元素是有序的,不需要再交换位置了。(注意,这个算法中有序的元素都排在队列的左边,而冒泡排序则是排在队列右边)排序代码如下: public void selectionSort(){

2021-08-11 23:29:20 104

原创 使用LinkedHashMap实现LRU算法

LinkedHashMap是比HashMap多了一个链表的结构。与HashMap相比LinkedHashMap维护的是一个具有双重链表的HashMap,LinkedHashMap支持2中排序一种是插入排序,即插入是什么顺序,读出来的就是什么顺序。一种是使用排序,最近使用的会移至尾部例如 key1 key2 key3 key4,使用key3后为 key1 key2 key4 key3了。accessOrder为true表示使用顺序,false表示插入顺序。基于LinkedHashMap的使用顺序的特性,我们

2021-08-08 11:10:16 437

原创 java使用栈解析算术表达式

系列文章目录1. java使用栈翻转字符串2. java使用栈解析分隔符匹配文章目录系列文章目录前言一、后缀表达法二、把中缀表达式转换成后缀表达式1. 人类是如何计算中缀表达式的值2.如何将中缀表达式转换成后缀表达式三、转换规则1. 中缀表达式转成后缀表达式的java代码2. 后缀表达式求值过程3. 后缀表达式的求值规则4. 后缀表达式求值的java代码总结前言前面两篇文章分析了栈的基本使用,最后我们使用栈来解析算术表达式。如 4+6,或者5*(2+3),或者((2+4)7)+3*(8-4)

2021-08-01 17:02:39 2015 2

原创 java使用栈解析分隔符匹配

文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言栈通常用于解析某种类型的文本串。通常提示:以下是本篇文章正文内容,下面案例可供参考一、pandas是什么?示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。二、使用步骤1.引入库代码如下(示例):import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn a

2021-07-31 11:06:21 409

原创 java使用栈翻转字符串

最近面试遇到现场写代码解析算术表达式,当时只想到使用栈来解析,但是没有最终写完,所以重新温习栈的知识。栈的定义:只允许访问一个数据项即最后插入的数据项。移除这个数据项后才能访问倒数第二个数据项。即先进后出代码实现如下:public class Main { public static void main(String[] args) { String s = "abcdef"; System.out.println(reverse(s)); }

2021-07-31 10:08:13 365

原创 设计模式之装饰器模式

装饰器模式: 动态的将责任附加到对象上。若要扩展功能,装饰器提供了比继承更有弹性的替代方案。装饰器中有两个比较重要的角色,装饰者和被装饰者。被装饰者实现我们的核心逻辑,装饰者只是对这些逻辑进行增强。比如点一杯饮料,冰,加豆浆等都是装饰者,是对我们饮料的增强,而饮料 是被装饰者。装饰器模式UML从UML中可以看到装饰者和被装饰者实现同一接口。装饰者中有一个被装饰者的对象引用。被装饰者的行为增强是通过旧逻辑前后添加新逻辑来实现的。下面以一个饮料费用计算为例,来简单介绍装饰者模式的使用。购买一杯饮料的时

2021-07-26 22:41:43 165

原创 设计模式之单例模式

饿汉模式有点类加载时便实例化,线程安全。public class HungrySingleton { private static HungrySingleton hungrySingleton = new HungrySingleton(); private HungrySingleton(){ } public static HungrySingleton getInstance(){ return hungrySingleton; }

2021-07-25 22:32:07 81

原创 ReentrantLock实现原理-如何实现一把锁(一)

锁作用可以抽象理解为避免共享资源被并发访问。按照这条概念我们在JAVA中可以定义一下实现。定义一个锁变量state。当多个线程同时范围同一个共享资源时,我们通过cas保证只有一个线程修改成功这个锁变量state成功,即获得锁。其他没有获得锁的线程,不断自旋尝试获得锁。当使用完共享资源时,还原state的值,让其他线程获得锁。定义锁接口public interface Lock { void lock(); void unlock();}按照上面原则具体实现如下:publ

2021-07-25 17:14:08 329

原创 java 中Unsafe介绍

Unsafe 是位于sun.misc包下的一个类,它可以让我们直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。Unsafe类为一单例实现,提供静态方法getUnsafe获取Unsafe实例,当且仅当调用getUnsafe方法的类为引导类加载器所加载时才合法,否则抛出SecurityException异常。

2021-07-25 11:42:37 1937

原创 Spring 监听器listener原理-spring监听器源码分析(三)

Spring 监听器listener原理-基本使用(一)Spring 监听器listener原理-手写监听器(二)Spring 监听器listener原理-spring监听器源码分析(三)概述要理解ApplicationListener的实现原理,需要对Spring的扩展点BeanPostProcessor有一点了解。这个接口是Spring最重要的接口之一,这个接口与Spring Bean的生命周期息息相关,我们常说的实例化前,实例化后,属性注入,初始化前,初始化后等等,其实都是调用了BeanP.

2021-07-25 08:31:16 2152 3

原创 简单排序--冒泡排序(一)

冒泡排序算法运行起来非常缓慢,但在概念上它是排序算法中最简单的,因此冒泡排序算法在刚开始研究排序技术时时一个非常好的算法。使用冒泡排序对无序数据进行排序如下图冒泡排序的执行过程如下:从数组的最左边开始,比较0号位置和1号位置的数字。如果左边的数字(0号位置)大,就交换两个数字位置。如果右边数字大,就什么也不做。然后右移一个位置比较1号位置和2号位置的大小。重复上述流程。以下是冒泡排序要遵循的规则:比较两个数字。如果左边数字比较大,则两个数字交换位置。向右移动一个位置,继续比较下面两个数字。

2021-05-05 23:06:02 221

原创 结构体注入VS setter 注入

结构体注入,setter注入是比较常用的依赖注入方式,都有各自的优缺点。setter注入是Spring推荐的依赖注入方式。首先结构体注入有什么问题?1. 不能重新配置和重新注入在Spring参考文档 中基于结构体注入和setter注入有以下陈述:Spring团队通常主张使用setter注入,因为大量的的结构体参数可能会使结构体变得笨重,特别是有些属性是可选的时候。相反setter注入可使对象在以后进行重新配置和重新注入。JMX管理MBean便是一个很好的例子。一些纯粹主义者喜欢基于结构体注入。在实

2021-05-05 09:01:21 194

原创 Spring Boot Logging 配置

Spring Boot 能够使用Logback, Log4J2 , java util logging 作为日志记录工具。Spring Boot 默认使用Logback作为日志记录工具。日志默认输出到控制台但也能输出到文件中。我们通过spring-boot-starter-logging 加入Logback依赖,其实只要我们加入任意的Spring Boot starter 都会默认引入spring-boot-starter-logging,因此 我们不需要分开加入他们。如果Logback JAR在类路径

2021-05-05 08:59:55 10678

原创 Spring 监听器listener原理-手写监听器(二)

Spring 监听器listener原理-基本使用(一)Spring 监听器listener原理-手写监听器(二)Spring 监听器listener原理-spring监听器源码分析(三)原本计划从0开始,实现spring的扫描注入,然后在自定义我们的监听器。但是spring容器并不是我们关注的重点。所以最终还是决定使用spring框架来探究监听器的实现原理基于接口的监听器实现原理接口定义配置类@ComponentScan({"com.zhu.demo.customer"})@Con.

2021-05-05 08:55:11 549

原创 Spring 监听器listener原理-基本使用(一)

Spring 监听器listener原理-基本使用(一)Spring 监听器listener原理-手写监听器(二)Spring 监听器listener原理-spring监听器源码分析(三)介绍Spring的监听器也可以说是一种观察者模式,它能实现事件与事件监听者直接的解耦,在Spring中监听器的实现主要有一下重要组件:ApplicationListener:事件监听者,观察者;ApplicationEvent:Spring 事件,记录事件源、事件内容、时间等数据;@EventListe.

2021-05-05 08:51:08 896

原创 Spring源码深度解析之AnnotationConfigApplicationContext概述

Spring的配置由基于XML,逐渐演变为基于注解,常用的应用程序上下文也由ClassPathXmlApplicationContext转为AnnotationConfigApplicationContext但基本流程都是一样的。AnnotationConfigApplicationContext代码如下所示public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //这里由于他有父类,故而会先调用

2021-05-05 08:46:54 462

原创 Spring源码深度解析之Spring扩展点BeanPostProcessor和BeanFactoryPostProcessor简述

通常,应用程序开发人员不需要为ApplicationContext实现类提供子类。 相反,可以通过插入特殊集成接口的实现来扩展Spring IoC容器。Spring提供了两个非常重要的扩展接口BeanPostProcessor和BeanFactoryPostProcessorBeanFactoryPostProcessor 主要是在对象实例化前对beanDefinition中的元数据进行修改并且BeanDefinitionRegistryPostProcessor继承BeanFactoryPostPr

2021-05-05 08:44:28 488

原创 BlockingQueue 使用(生产者-消费者)

java.util.concurrent包中的Java BlockingQueue接口表示一个线程安全的队列,可以放入并获取实例。在这篇文章中,我会告诉你如何使用这个BlockingQueue。本文将不讨论如何在Java中实现BlockingQueue。如果您对此感兴趣,在我的偏理论的Java并发教程中有一个关于阻塞队列的文章。###BlockingQueue 使用BlockingQueue通常用于使线程产生对象,而另一线程则使用该对象。这是一张阐明这一原理的图表。生产线程将持续生产新对象并将它

2021-05-04 22:20:37 395

原创 CountDownLatch 使用

java.util.concurrent.CountDownLatch是一个并发结构,它允许一个或多个线程等待一组给定的操作完成。CountDownLatch用给定的计数进行初始化。该计数通过调用countDown()方法递减。等待此计数达到零的线程可以调用await()方法之一。调用await()会阻塞该线程,直到计数达到零。下面是一个简单的例子。在Decrementer在CountDownLatch上调用countDown()3次之后,等待的Waiter将从await()调用中释放。CountDow

2021-05-04 22:18:21 131

原创 CyclicBarrier 使用

java.util.concurrent.CyclicBarrier类是一种同步机制,可以同步通过某种算法进行的线程。换句话说,它是所有线程必须等待的障碍,直到所有线程到达它为止,然后才能继续执行任何线程。这是一个图表说明:这些线程通过调用CyclicBarrier上的await()方法来相互等待。一旦有N个线程在CyclicBarrier中等待,所有线程都被释放并且可以继续运行。创建一个CyclicBarrier当你创建一个CyclicBarrier时,你可以指定有多少个线程等待它,然后释放它们

2021-05-04 22:15:59 208

原创 设计模式之适配器模式

适配器模式将一个类接口,转换成客户期望的另一个接口。适配器让原本不兼容的类可以合作无间。适配器的例子,现实生活随处可见。比如你只有USB-C接口的耳机,但是你的手机只有TYPE-C接口,这个时候你可能需要一个TYPE-C适配器。适配器工作起来就如同一个中间人,他将客户所发出的请求转换成原有接口能理解的请求。定义两个接口类public interface TYPEProtocol { /** * TYPE-协议 */ void typeProtocol();}

2021-05-04 22:12:01 89

原创 设计模式之代理模式

代理模式主要为其他对象提供一种代理以控制这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,我们可以在代理类中做一些辅助逻辑,把一些次要逻辑与主分隔逻辑开来,减少重复代码,比如日志记录,事务的管理等等。#静态代理既然说到代理,自然联想到静态代理。下面我们就先从简单的开始,下面数据库操作为例,用Java代码实现静态代理。代理模式中涉及到的角色抽象角色:为真实对象和代理对象提供一个共同的接口,一般是抽象类或者接口。代理角色:代理角色

2021-05-04 22:09:09 73

原创 设计模式之策略模式

策略模式定义算法族 , 分别封装起来,从而使得它们可以相互替换。策略模式使得算法的变化独立于使用算法的客户端。分别封装起来, 需要他们实现相同的接口。因为它们实现相同的接口,所以它们在运行时可以相互替换(子类对象赋给父类引用,这是Java面向对象中的多态,也是设计原则中针对接口编程,而不是针对实现编程。)***策略模式使得算法的变化独立于使用算法的客户端。***设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起策略模式优点(组合优于继承)使用继承去获得行

2021-05-04 22:08:06 74

原创 二分查找的实现细节(java 代码)

如果数据存储是有序的,那么我们可以考虑使用二分查找,查询我们需要的数据,这种查找比线性查找快很多,尤其对大数组来说更为明显。二分查找也叫折半查找。可以看出使用二分查找在查找数字 37 时只需3次,而线性查找查找37时需要11次。线性查找最坏的情况需要遍历整个数据。二分查找步骤如下:步数所猜的数结果可能值的范围01~59123太低29~59241太高29~37331太低37~37437正确二分查找代码实现如下:/

2021-05-04 22:04:00 184

原创 java并发编程之hook钩子线程

hook钩子线程简介JVM进程中没有活跃的非守护线程,或者受到了系统的中断信号,JVM进程便会退出。想JVM程序中添加一个hook线程,在JVM进程退出的时候,hook线程便会执行。我们可以使用hook线程防止程序重复启动或者回收系统资源。public class HookTest { public static void main(String[] args) { Runtime.getRuntime().addShutdownHook(new Thread(){

2021-05-04 21:55:29 489

空空如也

空空如也

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

TA关注的人

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