基础知识梳理

简单排序

冒泡排序
冒泡排序,最终排列的数据是从左到右、从小到大排列。相邻的两个元素比较、第一轮将最大的元素放到最后骂你、第二轮将次大的元素放到倒数第二个。这样右侧的数据项位置是比较固定的,代码如下(手写,未测试)

1
2
3
4
5
6
7
8
9
for (int i = num.length - 1; i > 0; i--){
for (int j = 0; j < i; j++){
if (num[j] > num[j+1]){
int temp = num[j];
num[j] = num[j+1];
num[j+1] = temp;
}
}
}

选择排序
选择排序,最终排列的数据也是从左到右、从小到大。不同的是选择排序假设第一个元素是最小的,依次往后比较指定一轮比较完成选出最小的元素和开始元素进行交换。这样左侧的数据项是固定的而且减少了交换次数,代码如下(手写,未测试)

1
2
3
4
5
6
7
8
9
10
int min, j;
for (int i = 0; i < num.length; i++){
min = i;
for (j = i; j < num.length; j++ )
if (num[j] > num[min])
min = j;
int temp = num[min];
num[min] = num[i];
num[i] = temp;
}

多线程

线程池

线程池主要包含四个部分,线程池管理器、工作线程、任务入口、任务队列。他们主要的职责如下

  1. 线程池管理器干了三件事
    a. 创建线程
    b. 销毁线程
    c. 增加任务

  2. 工作线程干了一件事
    a. 线程池中的线程,在空闲状态处于等待状态.可以循环执行任务

  3. 任务接口
    任务入口-每个任务必须实现的接口,提供工作线程的调度执行。主要干了三件事:
    a. 规定任务入口
    b. 规定任务出口
    c. 任务的执行状态

  4. 任务队列
    a. 用户存放没有处理的任务,提供一种缓冲机制。

JVM内存模型

GC-垃圾回收算法

垃圾收集常用的是分带收集算法,主要分新生代和老年代
新生代使用复制算法:
新生代分为eden区和两个survivor区比例为8:2。为啥要分两个survivor呢?因为是为了优化标记清除算法中的内存分片为题。为啥比例要为8:2呢?因为复制清除算法中连个survivor的角色要相互替换,如果不一样大会增加出现fullgc的概率
老年代使用标记-整理算法,这种算法比叫适合处理存活率比较高的垃圾回收。
这两个算法都是从标记清除算法优化过来的,标记清除算法虽然使用很广当时有两个表明显的问题。一个是性能问题(标记和清除的过程性能都不好),一个是会产生垃圾内存碎片(内存不连续容易产生内存碎片)。

GC-垃圾收集器

Serial收集器
ParNew收集器
Parallel收集器
Parallel Old 收集器
CMS收集器
G1收集器

类加载器

类加载的过程分为:加载->验证->准备->解析->初始化->使用->卸载
每个过程做的事情如下:

  1. 加载-加载过程干了三件事:
    a. 通过类全限定名获取二进制字节流
    b. 将二进制字节流中静态存储结构转化为方法区可运行数据结构
    c. 创建该类的java.lang.Class对象,作为方法区访问该类各种数据的入口

  2. 验证-验证过程干了两件事:
    a. 验证字节流中包含的信息是否符合当前jvm规范
    b. 验证字节流中是否包含安全隐患

  3. 准备-准备过程干了两件事:
    a. 分配类属性内存空间
    b. 初始化类属性值

  4. 解析-解析阶段干了一件事:
    a. 将常量池中符号引用替换为直接引用

  5. 初始化-初始化干了一件事:
    a. 根据程序员主管指定的计划去初始化类变量和其他资源,可以理解为调用类构造器
    以上。

双亲委派模型

双亲委派模型主要表示类加载器之间的层次关系:
用户自定义类加载(User ClassLoader)->应用类加载器(Application ClassLoader)->扩展类加载器(Extension ClassLoader)->启动类加载器(Bootstrap ClassLoader)
双亲委派模型-双亲委派模型主要有两个好处:
a. Java类随着类加载器具备了一种带有优先级的层次关系
b. 保障系统中类的稳定性,不会因为同一个类被不同的加载器加载而变的混乱

Spring BeanFactory和FactoryBean

BeanFactory和FactoryBean其实没什么关系,知识名字相似。
BeanFactory是接口定义了IOC容器规范,ApplicationContext就是继承了BeanFactory
FactoryBean也是一个接口,提供了一种自定义工厂Bean的实现方式。就是我们如果有个Bean像使用工厂模式来创建交给Spring的IOC容器管理,那么我们就可以实现FactoryBean接口。

Spring Bean的作用域

spring bean的作用于有一下集中
singleton: Spring Ioc容器中知会存在一个共享的bean实例,这个单利是针对当前IOC容器来说的。
prototype: 每次对该bean请求时(或者以程序的方式调用容器的getBean()方法)都会创建一个新的bean实例。
request:每次请求时创建一个新的bean实例。
session:一个回话范围内创建一个bean实例。
global session: 一个全局session中保持一个bean实例,仅仅在给予portlet的web应用中才有意义(portlet是基于Java的web组件,由Portlet容器管理,并由容器处理请求,生产动态内容)。

Spring Bean的生命周期

Spring AOP

面向切面:切面由切入点+通知组成
通知又分为:前置通知、后置通知、环绕通知、异常通知
AOP常用的实现方式有两种:

  1. jdk-proxy来实现,
  2. cglib字节码加强,优点不需要依赖接口

Spring IOC

Spring 事务传播机制

spring事务传播机制有6中,如下

  1. propagation-require: 支持事务,如果当前有事务使用当前事务、如果当前没有事务新建事务
  2. propagation-support: 支持事务,如果当前有事务使用当前事务、如果当前没有事务不适用事务
  3. propagation-mandatory: 支持事务,如果没有就抛出异常
  4. propagation-require-new: 新建事务,如果当前有事务挂起当前事务
  5. propagation-not-support: 不支持事务,如果当前有事务挂起当前事务
  6. propagation-never: 不支持事务,如果当前有事务抛出异常

Spring 事务隔离级别

spring 事务隔离级别和MySQL的十分相似,主要分一下几种

  1. ISOLATION_DEFAULT: 默认的隔离级别,使用数据库默认的事务隔离级别。MySQL默认隔离级别是repeatable-read可以解决脏读、不可重复读问题;
  2. ISOLATION_READ_UNCOMMITED: 不能解决任何事务问题;
  3. ISOLATION_READ_COMMITED: 可以解决脏读;
  4. ISOLATION_REPEATABLE_READ: 可以解决脏读和不可重复读;
  5. ISOLATION_SERIALIZABLE: 可以解决脏读、不可重复读和幻读。

MySql事务隔离级别

事务的四个特性:原子性->一致性->隔离性->持久性
原子性:一个事务操作要么成功要么失败,是不可分割的部分;
一致性:事务开始前和结束后,数据库的完整性没有遭到破坏。就像转账一样有一个多就有一个少;
隔离性:同一时间只有一个事务请求同一个数据,多个事务之间没有影响;
持久性:事务完成后对数据库的更新操作将被保存到数据库,不能回滚。

不同事务管理级别引起的问题有三个,分别是:

  1. 脏读:事务A读取了事务B未提交的数据,B回滚事务A读取的就是无效数据称之为脏读
  2. 不可重复读:事务A多次读取事务B中的数据,事务B提交后事务A多次读取的数据不一致称之为不可重复读
  3. 幻读: 事务A操作多条记录,在操作过程中事务B插入了一条新的记录。在事务A提交后发现多了一条未操作的数据,就像出现了幻觉一样称之为幻读
    MySQL定义了事务隔离级别来解决这些问题
事务隔离级别 脏读 不可重复读 幻读
读取未提交(read-uncommitted)
读取已提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)

MySql数据库索引原理

数据库存储索引和数据关系使用的时候平衡树(不是二叉树).索引分为,聚集型索引、非聚集型索引和覆盖索引
其实这个索引理解为是主键索引和数据地址的代名词更容易理解
聚集索引:主键索引,索引和数据地址紧凑在一起成为聚集索引。事物都是两方面的,索引能让数据查询的速度提升,但是写入数据的速度却下降了。原因很简单,因为平衡树这个数据结构一直维持在一个正确的状态,增删改数据都会改变平衡树各节点中的索引数据内容,破坏结构。所以每次数据改变是,DBMS必须去重新梳理树(索引)的结构,这会带来不小的性能开销。
非聚集索引:就是平时我们说的常规索引,和聚集索引树一样非聚集索引也是使用平衡树作为索引的数据结构。索引数结构中各个节点的值来自表中的索引字段,非聚集索引的索引结构相互独立,所以创建索引会增加表的体积占用磁盘的存储空间。检索方式是获取非聚集索引中的索引关键字关联的聚集索引ID,然后获取到的具体数据。
详情可参考这边文章: https://www.cnblogs.com/aspwebchh/p/6652855.html

MySql数据库索引和最左原则

数据库索引:
Mysql Innordb 事务形索引 聚集索引使用B+Tree 非聚集索引使用B-Tree
Mysql MyIsAm 非事务型索引 索引使用B-Tree
最左原则:
组合索引 a, b, c
索引命中的组合:

  1. a, b, c
  2. a, b
  3. a, c