此文章作为Java学习过程中一些知识点的记录:
1 操作数据库相关
SqlsessionFactory:采用一个全局单例.
Sqlsession:相当于jdbc中的connection,在一次请求事务回话后,将其关闭
Mapper:相当于去执行一条sql语句,由于他们难以控制,当sqlsession销毁的时候,也会销毁它
2 线程安全
ConcurrentHashMap -->
线程安全的HashMap
CopyOnWriteArrayList -->
线程安全的ArrayList (适用于读多写少的场合)
ConcurrentLinkedQueue -->
线程安全的LinkedList
BlockingQueue -->
数据共享通道(大量应用于生产者消费者模式),应用比较广泛
-> ArrayBlockingQueue<E>
适合做有界队列,先进先出
-> DelayedWorkQueue
-> DelayedQueue<E>
-> LinkedBlockingQueue<E>
适合做无界队列
-> PriorityBlockingQueue<E>
-> SynchronousQueue<E>
-> BlockingDeque<E>
- 线程池:
newFixedThreadPool(int)
创建固定大小的线程池,缓冲任务队列为LinkedBlockingQueue,大小为整形的最大数,超过固定大小的task将会放入缓冲队列中
newSingleThreadPool()
创建大小为1单位的固定线程池,当使用此线程池时,同时执行的task只有1个,其他task都在缓冲队列LinkedBlockingQueue中,大小为整形的最大数
newCachedThreadPool()
创建corePoolSize为0,最大线程数为整形最大数,线程keepAliveTime为1分钟,缓存任务队列为SynchronousQuque。
newScheduleThreadPool(int)
创建corePoolSize为传入参数,最大线程数为整形的最大数,线程keepAliveTime为0,缓存队列为DelayedWorkQueue。 - CAS操作 compare and swap
一般不提倡使用递归操作,因为效率比较低,而是采用循环来代替递归做开发时,尽量消除重复代码,简单代码可以使用递归
提高并发效率:合理使用jdk提供的并发包,合理使用CountDownLatch和CyclicBarrier
3 Java中的初始化顺序
JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。
- 初始化顺序:
先初始化父类的静态代码--->
初始化子类的静态代码-->
(创建实例时,如果不创建实例,则后面的不执行)初始化父类的非静态代码(变量定义等)--->
初始化父类构造函数--->
初始化子类非静态代码(变量定义等)--->
初始化子类构造函数。
类只有在使用New调用创建的时候才会被JAVA类装载器装入创建类实例时,首先按照父子继承关系进行初始化类实例创建时候,首先初始化块部分先执行,然后是构造方法;然后从本类继承的子类的初始化块执行,最后是子类的构造方法类 - 销毁的时候,首先消除子类部分,再消除父类部分
4 Instanceof
Instanceof只能用于对象的判断,不能用于基本类型的判断;使用instanceof时,若左操作数是null,则直接返回false,不再运算右操作数是什么类型
5 BIO,NIO,AIO区别
- BIO:
同步并阻塞,服务器模式实现为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中。 - NIO:
同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂。JDK1.4开始支持。 - AIO:
异步非阻塞,异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
6 线程死锁条件
互斥条件:一个资源每次只能被一个线程使用
资源独占条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放
不剥夺条件:线程已获得的资源在未使用完之前,不能强行剥夺
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系
7 Maven学习记录(标签)
groupId:表示开发该项目的组织名称,一般用该组织的倒序网站名称表示
artifactId:该项目的名称
packaging:该项目的打包方式,主要有jar(默认)、war、pom等属性。Pom属性表示该项目由多个子模块整合打包,每个module都是一个maven项目。
scope:标签依赖范围,主要有compile(默认)、test、runtime、provided等属性。
compile:表示参与当前项目的编译、测试、运行周期等,适用于所有阶段,会随着项目一起发布。
test:表示测试阶段使用
runtime:表示运行时使用
provided:表示打包的时候可以不用打包进去,别的设施(web容器等)会提供。理论上可以参与编译、测试、运行等周期。相当于compile,但是在打包阶段做了exclude的动作。
8 ACID和CAP是什么意思
- ACID
A(Atomicity)原子性: 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
C(Consistency)一致性:一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。
其主要特征是保护性和不变性。以4个银行账户的转账为例,不管这四个账户之间如何相互转账,无论并发多少个转账操作,他们的账户总额应该是恒定不变的,也就是等于最初的账户总额。
I(Isolation)独立性 :隔离状态执行事务,使它们好像是系统在指定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的独立性将确保每一个事务在系统中认为只有该事务在使用系统。
D(Durability)持久性:在事务完成以后,该事务对数据库所做的更改便持久的保存在数据库中,并不会被回滚。 - CAP
C:(Consistency)强一致性
A:(Availability)可用性
P:(Partition tolerance)分区容错性
9 面向对象和面向过程的区别
面向过程=数据+算法
面向对象=对象+交互
10 面向对象六大设计原则
- 单一职责原则:一个类尽可能的设计为只负责一个单一的功能,两个完全不一样的功能不应该放在一个类中,一个类中应该是一组相关性很高的函数、数据的封装。
- 开闭原则: 软件中的对象(类、模块、函数等)应该对于扩展是开放的,对于修改是封闭的。
- 里氏替换原则:只要父类出现的地方,子类就能够出现,而且替换为子类不会产生任何错误或异常。但是反过来,子类出现地方,替换为父类就有可能出现问题。(核心原理是抽象)
- 依赖倒置原则:模块之间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。
- 接口分离原则:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口中。
- 迪米特原则:一个对象应该对其他对象尽可能少的了解。降低各个对象之间的耦合,提高系统的可维护性。在模块之间,应该只是通过接口来通信,而不理会模块的内部工作原理,它可以使各个模块耦合程度降到最低,促进软件的复用。
11、设计模式分类(创建型模式、结构型模式、行为模式)
- 1.创建型模式
创建型模式,就是创建对象的模式,抽象了实例化的过程。它帮助一个系统独立于如何创建、组合和表示它的那些对象。关注的是对象的创建,创建型模式将创建对象的过程进行了抽象,也可以理解为将创建对象的过程进行了封装,作为客户程序仅仅需要去使用对象,而不再关系创建对象过程中的逻辑。
社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象的使用分开也就成为了必然趋势。因为对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,它们分别是:
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
创建者模式(Builder)
原型模式(Prototype)
单例模式(Singleton)
简单工厂模式不是GoF总结出来的23种设计模式之一
- 2.结构型模式
结构型模式是为解决怎样组装现有的类,设计它们的交互方式,从而达到实现一定的功能目的。结构型模式包容了对很多问题的解决。例如:扩展性(外观、组成、代理、装饰)、封装(适配器、桥接)。
在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了开发人员关注的焦点,因为如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。对象结构的设计很容易体现出设计人员水平的高低,这里有7个具体的结构型模式可供研究,它们分别是:
适配器模式(Adapter)
代理模式(Proxy)
装饰模式(Decorator)
桥梁模式/桥接模式(Bridge)
组合模式(Composite)
享元模式(Flyweight)
- 3.行为型模式
行为型模式涉及到算法和对象间职责的分配,行为模式描述了对象和类的模式,以及它们之间的通信模式,行为模式刻划了在程序运行时难以跟踪的复杂的控制流可分为行为类模式和行为对象模式。1. 行为类模式使用继承机制在类间分派行为。2. 行为对象模式使用对象聚合来分配行为。一些行为对象模式描述了一组对等的对象怎样相互协作以完成其中任何一个对象都无法单独完成的任务。
在对象的结构和对象的创建问题都解决了之后,就剩下对象的行为问题了,如果对象的行为设计的好,那么对象的行为就会更清晰,它们之间的协作效率就会提高,这里有11个具体的行为型模式可供研究,它们分别是:
观察者模式(Observer)
状态模式(State)
策略模式(Strategy)
职责链模式(Chain of Responsibility)
命令模式(Command)
访问者模式(Visitor)
调停者模式(Mediator)
备忘录模式(Memento)
迭代器模式(Iterator)
解释器模式(Interpreter)
- 三者之间的区别和联系
创建型模式提供生存环境,结构型模式提供生存理由,行为型模式提供如何生存。
创建型模式为其他两种模式使用提供了环境。
结构型模式侧重于接口的使用,它做的一切工作都是对象或是类之间的交互,提供一个门。
行为型模式顾名思义,侧重于具体行为,所以概念中才会出现职责分配和算法通信等内容。
12、强引用、软引用、弱引用、虚引用区别
- 强引用
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。如下:
Object strongReference = new Object();
复制代码当内存空间不足时,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 - 软引用(SoftReference)
如果一个对象只具有软引用,则内存空间充足时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。 - 弱引用(WeakReference)
弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。 - 虚引用(PhantomReference)
虚引用顾名思义,就是形同虚设。与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
13、链表和队列区别
- 链表是一种数据的存储方式,其保存的数据在内存中是不连续的,在java中通过其前驱(prev)或者后继(next)来访问。链表有单向链表和双向链表以及循环链表。
- 队列是一种数据结构,其特点是先进先出,后进后出,只能在队头删除元素,在队尾插入元素,即可以用线性表进行存储,也可以用链表进行存储。