Createsequence's Blog

一个努力前进的程序猿


  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

SpringAOP知识小结

发表于 2020-08-19 | 分类于 Spring
字数统计: 3k

概述

提起Spring,必然就会联想到AOP(面向切面编程)和IOC(控制反转)这两个词,众所周知,Spring框架对这两种思想进行了很好的实现。

在这篇文章,我将大致的介绍Spring对AOP这思想的实现流程。

对于AOP,关注的两个问题:

  • 什么是是AOP/IOC?
  • AOP/IOC解决了什么问题?

一、什么是AOP

Aspect oriented programming 面向切面编程,AOP 是 OOP(面向对象编程)的一种延续。

我们知道,根据面向对象编程的思想,对于一些具有相同属性和方法的类,我们可以抽象出他们共同部分作为一个父类,然后这些子类通过继承来获得他们共同的属性。比如Cat类和Dog都有eat()方法,那么我们可以将eat()方法抽象到他们的父类Animal,让他们去继承父类。

我们管这个抽取成类的方法叫做纵向抽取。

而如果他们的父类的方法中有相同方法,那么就直接抽取成公共方法。,但是有一些一开始就耦合到业务逻辑里的重复代码,比如下面统计方法执行时间的方法:

阅读全文 »

JVM初探(五):类的实例化

发表于 2020-08-13 | 分类于 java
字数统计: 2.2k

概述

我们知道,一个对象在可以被使用之前必须要被正确地实例化。而实例化实际指的就是以一个java类为模板创建对象/实例的过程。比如说常见的 Person = new Person()代码就是一个将Person类实例化并创建引用的过程。

对于类的实例化,我们关注两个问题:

  • 如何实例化?(类的四种实例化方式)
  • 什么时候实例化?(类的一个初始化过程和对象的三个初始化过程)

一、类的四种实例化方式

1.使用new关键字

这也是最常见最简单的创建对象的方法。通过这种方法,我们可以借助类的构造函数实例化对象。

1
Parent p = new Parent();

2.使用newInstance()方法

我们可以先通过类的全限定名获取类,然后通过Class类的newInstance()方法去调用类的无参构造方法创建一个对象:

阅读全文 »

JVM初探(四):类加载器

发表于 2020-08-12 | 分类于 java
字数统计: 1.4k

概述

虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为类加载器。

对于类加载,我们关注两个方面的问题:

  • JVM定义的三个类加载器(Bootstrap,Extension,System)
  • 双亲委派模型(机制,JDBC违背案例)

一、类加载器

JVM使用以下三种类型的类加载器:

  • 启动类(Bootstrap)类加载器:

    这个类存放在,无法被Java程序直接引用;

  • 扩展(Extension)类加载器:

    这个类加载器负责加载,开发者可以直接使用;

  • 引用程序(Application)类加载器:

    这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也称它为系统类加载器,负责加载用户类路径上所指定的类库。开发者可以直接使用。

从java虚拟机的角度来说,一种是启动类加载器,是JVM的一部分;另一种是其他类加载器,独立于JVM,全部继承自抽象类java.lang.ClassLoader。只有其他类加载器程序员才能自己使用。

二、双亲委派模型

1.什么是双亲委派模型

阅读全文 »

JVM初探(三):类加载机制

发表于 2020-08-11 | 分类于 java
字数统计: 3k

概述

我们知道java代码会被编译为.class文件,这里class文件中的类信息最终还是需要jvm加载以后才能使用。

事实上,虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型的过程就是虚拟机的类加载机制。

对于jvm类的加载机制,我们主要关注两个问题:

  • 类的加载时机?(初始化的五种情况)
  • 类的加载过程?(类的五个加载过程)

一、类的加载时机

1.类的生命周期

类从被加载到虚拟机内存中开始,到卸载出内存为止,整个生命周期包括加载、验证、准备、解析、初始化、使用和卸载。其中验证、准备、解析统称为连接。

类加载的时机

值得一提的是,加载,验证,准备,初始化和卸载是固定的,但是解析阶段不是:它在一定情况下可以在初始化后再开始,以支持java语言的动态绑定。

阅读全文 »

String类源码分析

发表于 2020-08-11 | 分类于 java
字数统计: 4.1k

概述

java 的 String 类可以说是日常中使用的最多的类,但是大多数时候都只是简单的拼接或者调用 API,只知其然不知其所以然。为了改变这个情况,我决定结合网上的资料,参考源码,深入一点去了解 String 这个熟悉的陌生人。

要第一时间了解一个类,没有什么比官方的文档更直观的了:

String类表示字符串。Java程序中的所有字符串文本(如“abc”)都作为此类的实例实现。

字符串是常量;它们的值在创建后不能更改。字符串缓冲区支持可变字符串。因为字符串对象是不可变的,所以可以共享它们。

Java语言提供了对字符串连接运算符(+)以及将其他对象转换为字符串的特殊支持。字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。字符串转换是通过toString方法实现的

… …

根据文档,对于String类,我们关注三个问题:

  • String对象的不可变性(为什么是不可变的,这么设计的必要性)
  • String对象的创建方式(两种创建方式,字符串常量池)
  • String对象的拼接(StringBuffer,StringBuilder,加号拼接的本质)

一、String对象的不可变性

1.String为什么是不可变的

文档中提到:

字符串是常量;它们的值在创建后不能更改。

阅读全文 »

JVM初探(二):垃圾回收机制

发表于 2020-08-10 | 分类于 java
字数统计: 2.8k

概述

我们知道自动的垃圾回收机制是Java语言一个特点,它让我们在写程序的时候不再需要考虑内存管理问题。内存管理实际上就是分配内存和回收内存这两个问题,在上一篇文章我大概介绍了jvm是如何划分内存空间以合理的分配内存的,而这篇文章就介绍一下jvm是如何回收内存的。

对于线程私有的程序计数器,虚拟机栈和本地方法栈三块数据区域而言,生命周期是和线程绑定的,线程结束时自然就回收内存了;而对于栈,每一个方法代表每一个栈帧,方法结束的时候就出栈,这时内存也跟着回收了。这些区域的内存回收都是具有确定性的,而堆就不同。

我们知道,堆主要用与存放对象实例,而只有运行时才知道要创建那些对象,而只有对象完全不被使用时才能回收其占用的内存空间。对于这块内容,我们需要明确三个问题:

  • 哪些对象可以回收?(引用计数法、可达性算法)
  • 这些内存什么时候回收?(新生代、老年代、永久代,MinorGC和FullGC)
  • 这些内存怎么回收?(三种垃圾收集算法和分代收集算法,七种垃圾收集器)

一、判断对象是否可回收

我们要判断对象是否可以回收,最有效的方式就是判断这个对象是否正在被别的对象引用。针对这个问题,有两种算法:引用计数算法和可达性分析算法。

1.引用计数算法

引用计数算法是通过判断对象的引用数量来决定对象是否可以被回收。

简单的来说,就是为每一个对象实例配置一个计数器:

阅读全文 »

JVM初探(一):jvm内存结构

发表于 2020-08-09 | 分类于 java
字数统计: 2k

概述

我们知道java代码先编译为.class文件,然后再将.class文件交由jvm执行。在程序运行的这一过程中,jvm会将其管理的内存空间划分为不同的区域,这些区域各有各的用途,我们将其分为五类:

  1. 方法区
  2. 堆
  3. 虚拟机栈
  4. 本地方法栈
  5. 程序计数器

其中方法区和堆是线程共享的,随jvm启动和停止而创建和销毁;

而虚拟机栈、本地方法栈和程序计数器则是线程私有的,随线程的创建和结束而创建和销毁。

jvm内存体系

一、线程隔离数据区

包括程序计数器,虚拟机栈,本地方法栈三部分,是线程私有的数据区。

1.程序计数器

程序计数器

阅读全文 »

java是值传递还是引用传递

发表于 2020-08-05 | 分类于 java
字数统计: 1.3k

概述

以前一鳞半爪的了解过 java 的参数传递方式是什么样的,后面粗略的了解了一鳞半爪以后有了大概的印象:“传参数就是值传递,传对象就是引用传递”,今天同事说起这件事,他却说 java 只有值传递。抱着疑问,我专门查了相关资料和文章,发现我原来的理解确实有问题。

这里先放结论:

  • java中参数的传递可以理解为都是值传递
  • 基础数据类型传递的是值的拷贝
  • 对象类型是共享对象传递,传递的是地址的拷贝

一、形参和实参

要理解参数的传递就必须先理解形参和实参:

  • 形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的。

    形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元。

    因此,形参只在方法内部有效,所以针对引用对象的改动也无法影响到方法外。

  • 实参:就是实际参数,用于调用时传递给方法的参数。

举个例子:

1
2
3
4
5
6
7
8
9
10
public static void main( String[] args ) {
String string = "Hello";
//string是实际参数
sout(string);
}

public static void sout(String str){
//str为形式参数
System.out.println(str);
}

二、值传递和引用传递与共享对象传递

阅读全文 »

数据结构与算法(十八):图

发表于 2020-08-04 | 分类于 数据结构与算法
字数统计: 2.3k

一、什么是图

1.概述

首先,我们已经在之前学习过了树这种数据结构,树能反映一对多的关系,但是却无法反映多对多的关系,因此我们引入了图这种数据结构。

对于图,其节点也可以叫做顶点,每个节点具有零或者多个相连节点,每个节点之间的连接称为边,从一个节点到达另一个节点路线都称为路径。

image-20200804155639505
image-20200804155639505

以上图为例,其中:

  • 无向图:顶点之间连接没有方向。比如从A到C,可是A -> B -> C,也可以是A -> D -> B -> C。
  • 有向图:顶点之间连接有方向。如果A到B,必须是A -> B,不能是B -> A
  • 带权图:边带有权值。

2.树与图的关系

实际上,对于有向图还分为两种情况,即图中含环或者图中不含环的单向图,其中含环的图可以从某个顶点出发最终返回原点。

结合对图的定义,我们不难发现,树也可以理解为不含有环的单向图,是图的子集。

阅读全文 »

数据结构与算法(十七):B树,B+树

发表于 2020-07-25 | 分类于 数据结构与算法
字数统计: 1k

一、什么是多路查找树

二叉树有诸多便利之处,但是当二叉树节点极多时,二叉树的构建速度就会受影响,而且过高的层数也会导致对树的操作效率降低。

过多节点的二叉树

对于树的查找而言,树的高度决定了查找的时间下限,但是同样数量的节点,如果要高度小那每一层容纳的节点就要多,而二叉树每一层固定的节点数导致的高度难以降低,为此每一个节点都能拥有多个子节点的多叉树(multi way tree)就出现了.

多叉树

B树,B+树都是多叉树

二、B树

B树也称B-树,它是一颗多路平衡查找树。

2-3树是最简单的B树,它具有以下特点:

  • 2-3树的所有叶子节点都在同一层(只要是B树都满足该条件)
  • 有两个子节点的节点叫二节点,二节点要么没有子节点,要么有两个子节点。三节点本身包含两个数据项
  • 有三个子节点的节点叫三节点,三节点要么没有子节点,要么有三个子节点。二节点本身包含一个数据项
  • 2-3树是由二节点和三节点构成的树。
阅读全文 »
1…678…10

99 日志
15 分类
22 标签
RSS
© 2022 Createsequence
主题 — NexT.Gemini v5.1.4
0%