自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Night Field' Blog

每天进步一点点

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

原创 MyBatis内置DataSource的连接池实现原理

前言MyBatis是一个流行的ORM框架,它简单易用,支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。作为一款优秀的持久层框架,连接池是必不可少的。本文将分析MyBatis内置的数据源是如何实现连接池功能的(源码基于MyBatis3.4.5)。JDBC对数据库的操作回忆一下,我们用原生的JDBC来操作数据库的一般流程:public class JDBCExample { // JDBC driver name and dat

2020-12-12 14:29:19 24

原创 Hotspot早期的垃圾收集器简介

前言很多人的博文里面会提到JVM三种垃圾收集器:串行,并行和并发。这么分类也不能说错,但事实上也没有这么简单。本文简要介绍Hotspot早期的垃圾收集器(Garbage Collector)。名词解释年轻代和老年代:JVM中不同的对象,生命周期是不同的。比如线程中的临时变量,在方法结束之后便会被销毁;而静态变量,则会一直存在直到其所对应的类被销毁为止。基于这样的事实,才有了分代收集的概念:将JVM堆分为年轻代和老年代。年轻代存放刚被创建的对象,老年代存放经过多次GC之后依然存活的对象。一般年轻代空间

2020-12-10 17:38:36 5

原创 Redis的键过期策略及内存淘汰策略简介

RedisRedis是高性能的基于内存的NoSQL数据库。因为内存是比较宝贵的资源,无法无限制使用,所以Redis提供了:键过期策略来防止内存饱和。内存淘汰策略来使得内存饱和之后继续对外提供服务。内存过期策略expire命令Redis提供了expire命令来给一个键(key)设置过期时间:redis> SET foo "bar""OK"redis> EXPIRE foo 10(integer) 1redis> TTL foo(integer) 10类似set

2020-11-08 17:47:20 27

原创 Netty的ChannelPool导致内存泄漏的排查经历

背景接到了线上机器的报警,登上服务器,发现是Java进程挂了,看日志报了OOM:java.lang.OutOfMemoryError: Java heap space问题描述内存溢出,那当然是看dump文件了。这里推荐大家在产线机器上都加上JVM参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath={path}/{to}/{dump},这样,JVM在OOM的时候,会自动做一个内存dump,相当于保存现场。拿到dump文件,放到MAT里面分析,以下是

2020-08-31 10:07:56 184

原创 自定义Classloader导致ClassCastException:不要轻易破坏双亲委派模型

背景java.lang.ClassCastException: cn.com.nightfield.Plugin cannot be cast to cn.com.nightfield.Plugin相同的class,竟然不能cast?这是什么鬼?问题描述自定义类加载器(Classloader)是很常见的,它可以让我们从自定义的文件系统目录,网络甚至是数据库的各种文件类型(jar, war, zip等)中加载class文件。我们项目中使用了一个开源的类管理工具PF4J,来加载指定目录下的class

2020-08-15 16:19:05 148

原创 深入理解Linux, NIO和Netty中的零拷贝(Zero-Copy)
原力计划

背景零拷贝(Zero Copy)是一个耳熟能详的术语,众多高性能的网络框架如Netty,Kafka,Rocket MQ都将零拷贝标榜为其特性。那么究竟什么是零拷贝?零拷贝Wikipedia上对零拷贝的解释如下:“Zero-copy” describes computer operations in which the CPU does not perform the task of copying data from one memory area to another. This is freq

2020-06-10 10:04:25 315

原创 Quartz Task在Tomcat中重复运行问题解决

问题描述Spring Quartz是很常用的定时任务框架。把一个Quartz的工程部署到Tomcat中启动,意外地发现,每个Task都在同一时间跑了两次,而本地在开发的过程中却没有问题。问题排查为了防止多线程问题,有部分Task上是加了锁的,类似如下方式:@Componentpublic class ExampleTask{ private ReentrantLock lock = new ReentrantLock(); protected void executeInternal()

2020-06-09 16:12:15 41

原创 设计模式总结

经过了两个多月的时间,终于,将常见的设计模式结合例子过了一遍,在此做一个简单的小结。设计模式小结不难发现,应用各种设计模式所带来的好处,都会提到解耦二字。开闭原则要求我们的系统对扩展开放,对修改关闭。高内聚,低耦合的系统,有更高的稳定性与灵活性,也更易于维护。如何来解耦模块之间的关系呢?如果只用一句话来概括的话,那就是:将变与不变分离。细看下来,设计模式通常通过增加一个中间抽象层的方式,来封装会变的部分。创建型模式中,将对象的创建模块抽离出来,使客户端不需要关心对象如何创建;几乎所有的结构模式和行为模式

2020-06-06 17:04:34 57

原创 设计模式,行为模式之责任链模式

1 概述责任链模式(Chain of Responsibility Pattern)是常见的行为模式,它将处理器封装成一条处理链,让请求可以在链上传递。链上的处理器自行决定是否对请求进行处理。2 责任链模式一个典型的责任链模式的使用场景是,当一个事件或请求需要被多个处理器处理时。应用责任链模式,将所有的处理器串在一起,然后把请求从链的头部开始传送。各个处理器可以对请求进行判断,选择执行相关逻辑,或者将它传递给下一个处理器。如此一来,解耦了请求者和接收者(所有的处理器)。一般情况下,链上的处理器需要持

2020-06-06 16:01:09 62

原创 设计模式,行为模式之备忘录模式

1 概述备忘录模式(Memento Pattern),又叫Token模式,它提供了一种方式,来捕捉对象某一时刻的内部状态,并将其保存成备忘录(Memento),如此一来,对象可以根据此备忘录恢复到之前的状态。2 备忘录模式几乎所有的编辑器都支持撤销功能,这其实就是备忘录模式的例子,撤销操作,使得文本得以恢复到之前的状态。面向对象设计中,备忘录模式的实现一般需要三个角色:发起人(Originator):主对象,提供将内容保存成备忘录,或者从备忘录恢复状态的功能。备忘录(Memento):备忘录对象

2020-06-04 11:39:54 39

原创 设计模式,行为模式之命令模式

1 概述命令模式(Command Pattern),是将请求封装成一系列命令对象,以解耦请求发起者和请求接收者的一种行为模式。2 命令模式正常情况下,请求发送者和请求接收者是相互耦合的,发送者直接调用接收者相关的方法,直接交互。用命令模式进行改造,将两者交互的媒介----命令单独抽离出来,使得发送者和接收者相互独立,只依赖于命令对象,提高了扩展性和可维护性。同时,通过命令模式,我们还能完成一些高级操作,如撤销命令,方法参数化,命令入队,批量命令等等。3 案例通过一个简单的例子加深对命令模式的理解

2020-06-03 13:10:06 83

原创 设计模式,行为模式之访问者模式

1 概述访问者模式(Visitor Pattern)是一种行为模式,不常用。它可以将作用在对象上的算法逻辑,与对象本身分离开来。2 访问者模式当需要对一组相似类型的对象执行操作时,我们可以将操作逻辑分别维护在每个对象内部,但这违背了单一职责原则。访问者模式就是来应对这种情况的:将所有的算法逻辑移动到一个新的类----访问者(Visitor)中,统一维护,如果其中的逻辑发生了变化,那么我们只需要在访问者实现中进行更改,而不用影响到原对象。同时,在访问者模式中,扩展变得很容易,增加新的对象以及操作逻辑,

2020-05-31 13:56:07 74

原创 设计模式,行为模式之模板方法模式

1 概述模板方法模式(Template Method Pattern)是一种很常见的行为模式。在超类/抽象类中创建一个模板方法,方法中定义一个算法步骤或框架,让子类在不修改主结构的情况下,重写其中的子步骤。2 模板方法模式假如存在一系列对象的方法,他们的步骤是大体一致的,区别只是其中的一个子步骤。这种情况会导致大量重复冗余的代码,当公共部分需要改变时,不得不修改所有相关的对象。如果用模版方法模式改造,可以简化逻辑:将其中不变的部分抽离出来,作为一个模板方法,然后让子类只实现差异化的部分代码。比如,前

2020-05-31 08:17:59 116

原创 设计模式,行为模式之中介者模式

1 概述中介者模式(Mediator Pattern)是一种行为模式,通过定义一个中介对象,来管理一系列对象之间的依赖,从而解耦原有对象之间的关系。2 中介者模式大量的对象相互依赖,会大大增加系统复杂度,提高维护成本。中介者模式(Mediator Pattern)是迪米特原则的一个很好体现,它通过将对象的依赖关系维护在一个中介者中,使原本耦合在一起的对象变得相互独立。交通信号灯是一个很常见的例子,如果没有信号灯,十字路口的车子必须知道互相之间要去的方向,来决定什么时候踩油门,什么时候踩刹车,如此一来

2020-05-30 12:25:58 127

原创 设计模式,行为模式之状态模式

1 概述状态模式(state Pattern)是行为模式之一,一般用在对象的行为依赖于内部状态的场景。2 状态模式考虑一个场景:对象有状态,而且根据状态不同,对象的行为也会不同。对于该情况,最简单的方式是,对状态做if-else或者swith-case判断,根据状态调用相应的行为。但是这种做法,把对象和状态耦合在了一起,难于扩展和维护。更好的做法是,用状态模式将状态抽离出来形成一个接口,而目标对象依赖该状态接口,来完成对应的行为,由此达到解耦的目的。状态模式跟策略模式非常相像,可视为策略模式的扩展。

2020-05-28 17:12:47 97

原创 设计模式,行为模式之策略模式

1 概述策略模式(Strategy Pattern)是行为模式的一种,复杂度并不高,当完成某项任务的方式有多种时,可以考虑使用策略模式。2 策略模式在策略模式中,我们需要定义一族算法,并将算法放入独立的类中,每种算法代表完成任务的一种方法。如计算器,我们可以定义基本的加,减,乘,除四种策略,对于任意输入的两个数字,调用不同的策略,将得到不同的结果;又如网上购物结算,我们可以定义一系列支付策略,支付宝支付,微信支付,信用卡支付,储值卡支付…顾客可以根据自己的喜好选择相应的支付方式。策略模式解耦了算法的

2020-05-24 16:12:56 48

原创 设计模式,行为模式之观察者模式

layout: posttitle: 行为模式之观察者模式date: 2020-05-04categories:HandbookDesign Patternstags:JavaDesign Patterns1 概述观察者模式(observer Pattern),也叫发布-订阅模式,是一种很重要的行为模式,它被广泛运用在异步编程之中,可以说是异步编程的基础。2 观察者模式当我们需要关注某个对象的状态时,可以不断地轮询,查看状态是否变化,这也就是我们熟知的同步方式。然而这样的方式.

2020-05-10 15:52:08 62

原创 设计模式,行为模式之迭代器

1 概述迭代器模式(iterator Pattern)是最常见的设计模式之一,一般使用过Java集合的人,都接触过这种模式。2 迭代器模式集合(Collection)是编程中常用的一种类型,它们是存储元素的容器。集合有多种类型,如列表(List),集合(Set),栈(Stack),树(Tree)等等,对于使用者来说,需要有一种统一的方式来遍历集合中的元素。除此之外,使用者有时还需要不同的元素...

2020-05-04 12:27:11 32

原创 设计模式,结构模式之享元模式

1 概述享元模式(flyweight Pattern)是通过重用元素来降低内存开销的一种设计模式。2 享元模式所谓享元,意思是共享元素。当程序需要创建大量元素,或创建一些占用大量内存的元素时,对服务器的内存资源是很大的挑战。这时可以应用享元模式,将元素拆分成变量与不变量两部分。其中不变量,是所有的元素共通的部分,可以共享;变量,可以做为不同的元素的区分。比如要渲染一片森林,我们不需要为每一颗...

2020-04-25 14:22:40 53

原创 设计模式,结构模式之装饰模式

1 概述装饰模式(Decorator Pattern),意在不改变原有对象的情况下,改变/增强它的方法。2 装饰模式在不违反开闭原则的前提下,要改变某个对象的行为,可以使用继承。然而继承不适用于类/方法被final修饰的情况,而且一般需要了解类内部的情况,违反了迪米特法则。装饰模式体现了组合优先于继承的思想,通过组合的方式,“装饰”对象的功能,也能达到改变对象行为的目的。装饰模式的实现模式...

2020-04-19 11:15:35 42

原创 设计模式,结构模式之代理模式

1 概述代理模式(Proxy Pattern)是Javaer们最熟悉的设计模式之一,大名鼎鼎的AOP就是通过代理模式来实现的。2 代理模式现实中,如果要邀请某个明星参加活动,我们不是跟这个明星直接沟通,而是找他的经纪人。因为明星只需要负责表演就可以了,其他的事情由经纪人来安排。代理模式就是类似思想的体现:构造一个代理对象作为中间层,当我们需要调用某个功能时,不是直接调用功能本身,而是通过代理...

2020-04-16 22:58:29 35

原创 设计模式,结构模式之组合模式

1 概述组合模式(Composite Pattern),是指把一类有共同抽象的对象组合在一起,形成树状结构,来表示部分-整体的关系。2 组合模式我们经常会遇到一些对象有相同的行为,同时对象之间又有层级结构。像这种情况,使用组合模式可以使系统高内聚,低耦合。通过把类组合成树形结构,调用者能够以统一的方式对待单个对象和整体结构,忽略个体和整体之间的差异。实现组合模式一般需要:定义一个接口/抽...

2020-04-05 21:49:58 52

原创 设计模式,结构模式之适配器模式

1 概述适配器模式(adapter pattern),从名字就可以看出,工作模式类似于适配器:将原本不兼容的两样事物连接,以协同工作。2 适配器模式充电器(电源适配器)是日常生活中常见的例子。大多手机要求输入电压是5V,而家用交流电的电压都是220V,充电器作为适配器,将220V的电压转为目标电器需要的电压。适配器模式也类似,通过适配器,将类的接口转换为目标所期望的另一个接口。适配器模式是...

2020-04-04 14:53:59 37

原创 设计模式,结构模式之桥接模式

1 概述上一篇文章介绍了外观模式,接下来介绍桥接模式。桥接模式有时也被称为桥梁模式,也是一种常见结构模式,它主要体现了面向对象设计中的两个思想:面向接口编程。合成复用原则,即组合优先于继承。2 桥接模式桥接模式的目的是将抽象与实现分离,使二者能独立变化。说白了,其实就是:给对象定义接口,来充当桥梁的作用。调用者要依赖于目标对象的抽象(接口)而不是具体实现,更不是继承目标对象。...

2020-03-30 20:49:00 49

原创 设计模式,结构模式之外观模式

layout: posttitle: 结构模式之外观模式date: 2020-03-29categories:HandbookDesign Patternstags:JavaDesign Patterns1 概述外观模式,也叫门面模式,是一种常见结构模式,它是面向对象设计封装思想的体现。2 外观模式所谓外观,其实是一个额外的类,它包含了复杂多变的子系统,并只对外提供...

2020-03-29 14:32:43 49

原创 设计模式,创建型模式之单例模式
原力计划

1 概述单例模式应该是最简单,同时又是最复杂的一种创建型模式。因为大家都知道这个模式:无非就是保证某个对象在系统中只存在一个实例。然而想要真正实现一个完美的单例模式,却不简单。2 单例模式一般单例模式的实现,都需要包含两个步骤:将类的构造函数私有化。提供一个public的方法,以供外界获取唯一的实例。下面将一一介绍单例模式的各种实现方式。3 案例3.1 注册表式提供一个注册表...

2020-03-28 22:19:47 34

原创 设计模式,创建型模式之原型模式

1 概述原型模式比较好理解,即以某个对象为原型,创建该对象的副本。我们可以不用知道对象内部的属性以及内部的状态,是迪米特法则的很好体现。2 原型模式原型模式一般用在较为复杂对象的创建,并且希望保留对象所持有的状态。Java对这种对象的创建方式也是提供了原生的支持——Object.clone()方法。public class Object { protected native Obj...

2020-03-26 21:17:19 48

原创 设计模式,创建型模式之建造者模式

1 概述前面我们说了工厂模式和抽象工厂模式,下面来说说建造者模式。建造者模式也是一种极为常见的创建型模式,前面提到的两类工厂模式隐藏了类的属性与构造细节,而建造者模式通过Builder类,适当地暴露了类的属性,使得类的创建更具有灵活性和可读性。2 建造者模式当一个类的构造函数包含很多参数,或者参数之间有很多种组合(如肯德基的套餐),调用构造函数来创建类将会变得不方便,可读性也很差。对于多种...

2020-03-22 14:09:00 49

原创 设计模式,创建型模式之抽象工厂模式

1 概述上一篇文章讲到了工厂方法模式,它提供了一种在不指定具体实现的情况下,创建类实例的解决方案。那为什么还需要抽象工厂模式呢?2 抽象工厂模式抽象工厂模式本质上,也是定义一个工厂,用来作为类创建的入口,拥有工厂方法模式的优点:如隐藏类的构造细节,降低类的使用复杂度,与调用者解耦等等。而它与工厂方法模式最大的区别在于,抽象工厂模式更强调创建一族的元素。比如对于不同的浏览器,有不同的按钮,选...

2020-03-21 13:25:45 44

原创 设计模式,创建型模式之工厂模式

1 概述创建型模式,提供了一种创建对象的最佳实践。工厂方法模式的核心思想,是通过统一的工厂类来获取对象,而不需要调用类的构造方法。2 优点可以将类的实例化过程延缓到子类。调用者无需知道接口/抽象类的具体实现是什么,利用工厂方法即可获取类的实例,降低与调用者的耦合度。隐藏类的构造细节,降低类创建的复杂度,提高程序可读性。可以根据不同环境/参数,从工厂构造不同的方法。3 案例有一个饭...

2020-03-20 22:31:40 32

原创 设计模式之六大原则

1 概述在面向对象的编程中,要实现一个功能,可以有非常多的方式。在多年的经验积累总结下来,人们发现优秀的的代码总是遵循一定的范式。其中23种设计模式(Design Patterns),就是前人对优秀代码的编程范式的总结,是面向对象编程的最佳实践。合理地运用这些设计模式,已经是写出高质量,高效率,可读性强,易维护的代码的充要条件。而设计模式的六大原则,则是设计模式都会遵守的通用法则。本文将结合简...

2020-03-15 17:54:19 35

原创 SpringBoot服务无法读取系统变量,我重新认识了profile和bashrc

背景CentOS服务器上,我们用Systemd部署了一个SpringBoot服务。关于如何部署,可以参考这篇文章。这个SpringBoot服务会用ProcessBuilder去调用机器上一个C++的可执行文件。问题描述SpringBoot程序跑得很正常,但是我们发现C++程序却没有log输出,也就是说它从没被执行过。查看了ProcessBuilder的返回值,是127。127的意思是系统找...

2020-03-07 19:44:55 246

原创 SpringBoot以服务形式启动,并设置JVM启动参数

1 概述SpringBoot使得我们可以快速地上手以及开发Spring项目。我们可以把工程打成一个jar包,然后部署到服务器上(这里只讨论Linux,因为没多少人会拿Windows当服务器)。nohup命令可以让程序作为后台进程执行,但是它不好管理维护,也显得很不专业。更好的方法是将SpringBoot作为Service启动。2 步骤2.1 Maven打包通过package命令打jar包:...

2020-03-05 22:33:08 3862

原创 解决pyinstaller打包的程序无法执行,提示Operation not permitted

前言PyInstaller是一个强大的工具,它可以分析我们的python脚本,发现脚本执行所依赖的模块,并将他们打包到一个文件夹,或者封装成一个可执行文件(exe或者binary)。然后,我们就可以将这个文件(文件夹)放到其他机器上去执行,目标机器甚至可以不用安装python环境!这跟docker有异曲同工之妙。问题描述在Centos7上,用PyInstaller将py文件打成一个binar...

2020-03-03 14:37:47 414

原创 Java递归设置文件的用户,组和权限

前言自从1.7版本开始,Java引入了Nio包,提供了更强大的IO功能。本文简单介绍如何用java.nio.file.attribute下的工具类修改文件的权限,用户和组。因为本类库是针对Posix类系统的的,所以主要适用于Linux和Mac上(实测Win7不支持)。测试样例测试代码如下:public class FileTest { public static void mai...

2020-02-29 16:08:21 559

原创 解决Unable to open debugger port错误

原因IntelliJ Debug模式下,启动Tomcat报错Unable to open debugger port可能的原因有二:目标端口被占用文件权限不足解决目标端口占用这种情况比较常见。Tomcat启动需要监听一个端口,如果此端口正好被别的程序占用了,就会报这个错。有两个办法可以解决问题:1. 调整端口:Run/Debug Configuration ->...

2020-01-03 21:03:30 1193

原创 深入理解ThreadLocal

前言并发是Java开发中绕不开的一个话题。现代处理器都是多核心,想要更好地榨干机器的性能,多线程编程是必不可少,所以,线程安全是每位Java Engineer的必修课。应对线程安全问题,可大致分为两种方式:同步: 用Synchronized关键字,或者用java.util.concurrent.locks.Lock工具类给临界资源加锁。避免资源争用: 将全局资源放在ThreadLoca...

2020-01-02 09:30:43 41

原创 Java四种引用类型详解

前言为了满足对不同情况的垃圾回收需求,从Java从版本1.2开始,引入了4种引用类型(其实是额外增加了三种)的概念。本文将详细介绍这四种引用。Java 4种引用类型Java中的4中引用类型分别为强引用(String Reference),软引用(Soft Reference),弱引用(Weak Reference)和虚引用(Phantom Reference)。概念及应用场景强引用:...

2020-01-01 23:48:10 135 1

原创 Spring Scheduler重启的正确打开方式

背景定时任务是一个比较常见的功能,在某些情况下,需要重新启动或者是重设Scheduler Job,但是官方的API上都没有提供类似restart的方法,那该如何完成此需求呢?Spring QuartzSpring Quartz(http://www.quartz-scheduler.org/documentation/)是一整套完整的Cron Job架构,可以完成复杂的任务调度需求,支持任务...

2019-12-26 15:40:36 544

原创 InstanceAlreadyExistsException的解决方案

背景JMXJava Coder们都知道,Java提供了JMX(Java Management Extensions) attach的机制(如JConsole),可以动态获取JVM运行时的一些信息。我们可以自定义MBean,来暴露指定的一些参数值,如DB连接数等。为方便故障排查,我们添加了一些DB相关的metrics,于是在Spring配置文件里面添加了如下代码<bean id="jmx...

2019-12-20 13:10:07 473

空空如也

空空如也

空空如也

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

TA关注的人 TA的粉丝

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