1.总结:
抽象类和接口
jdk1.8之前
接口
1.多实现
2.变量类型默认且只能为public static final
3.函数类型默认且只能为public, 只能有public 类型的静态成员函数
4.非静态成员函数没有方法体,静态成员函数有方法体
5.子类必须实现所有的接口函数
6.可以有main方法,可以new 一个接口,需要在方法体中实现所有接口函数
7.没有构造器
抽象类:
1.单继承
2.变量类型不限(静态变量+非静态变量)
3.函数类型不限(静态函数+非静态函数)
4.非静态函数包含没有方法体的抽象函数.有方法体的普通函数
5.子类可以不覆写父类的抽象方法,但子类也要申明为抽象类;子类可以选择覆写父类的非抽象方法
6.可以有main方法,不可以new一个抽象类
7.可以有构造器
jdk1.8
接口中可以有default类型的方法,实现类可以选择实现该方法
意义:默认方法的主要优势是提供一种拓展接口的方法,而不破坏现有代码。另一个优势为该方法是可选的,子类可以根据不同的需求Override或默认实现
补充总结:关于抽象类:
JDK1.8以前,抽象类的方法默认访问权限是protected
JDK1.8时,抽象类的方法默认访问权限变为default
关于接口
JDK1.8以前,接口中的方法必须是public的
JDK1.8时,接口中的方法可以是public的,也可以是default的
JDK1.9时,接口中的方法可以是private的
2.final和finally、finalize
final
final关键字可用于修饰类、变量和方法。final修饰的类不可以被继承,修饰的方法不可以被重写,修饰的变量不可以被修改,一旦获得初始值,该变量就不能被重新赋值。
finally
异常处理时提供finally块来执行任何清除操作,如果抛出一个异常,那么相匹配的catch子句就会执行,然后控制就会进入finally块(如果有的话).
finalize()
Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它,子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
-
JDK, JRE , JVM区别与联系?
JDK :Java Development ToolKit(Java 开发工具包)。JDK是整个Java的核心,包括了Java运行环境(Java Runtime Environment), 一堆Java工具(Java,java,jdb等)和Java基础的类库(即Java API 包括rt.jar).
JRE:Java Runtime Enviroment(java运行时环境)。也就是我们说的JAVA平台,所有的Java程序都要在JRE下才. 能运行。包括JVM和JAVA核心类库和支持文件。与JDK相比,它不包含开发工具——编译器、调试器和其它工具。
JVM:Java Virtual Mechine(JAVA虚拟机)。JVM是JRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 的主要工作是解释自己的指令集(即字节码)并映射到本地的 CPU 的指令集或 OS 的系统调用。Java语言是跨平台运行的,其实就是不同的操作系统,使用不同的JVM映射规则,让其与操作系统无关,完成了跨平台性。JVM 对上层的 Java 源文件是不关心的,它关注的只是由源文件生成的类文件( class file)。类文件的组成包括 JVM 指令集,符号表以及一些补助信息。
只有JVM的底层实现是用C、C++和汇编写的,其他组件都是用Java写的
4.关系数据模型与对象模型之间匹配关系
一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性
5.jvm中垃圾回收分为scanvenge gc和full GC,其中full GC触发的条件
1⃣️. 新生代:
(1)所有对象创建在新生代的Eden区,当Eden区满后出发新生代的Minor GC,将Eden区和非空闲Survivor区存活的对象复制到另外一个空闲的Survivor区中。
(2)保证一个Survivor区是空的,新生代Minor GC就是在两个Survivor区之间相互复制存活对象,直到Survivor区满为止。
2⃣️.老年代: 当Survivor区也满了之后就通过Minor GC 将对象复制到老年代。老年代也满了的话,就将触发Full GC, 针对整个堆(包括新生代、老年代、持久代)进行垃圾回收。
3⃣️.持久代:持久代如果满了,将触发Full GC。
4⃣️.System.gc 有可能触发full gc ,这个方法的调用是建议jvm进行full gc,只是建议并非一定.
6.关于ThreadLocal类
1⃣️、ThreadLocal的类声明:
public class ThreadLocal<T>
可以看出ThreadLocal并没有继承自Thread,也没有实现 Runnable接口
2⃣️.ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有自己独立的一个变量。
所以ThreadLocal的重要作用并不在于多线程之间的数据共享,而是数据的独立。
由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,不会被其他线程访问,变量被彻底封闭在每个访问的线程中.
3⃣️. ThreadLocal中定义了一个哈希表用于为每个线程都提供一个变量的副本
static class Entry extends WeakReference<ThreadLocal> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal k, Object v) {
super(k);
value = v;
}
}
/**
* The table, resized as necessary.
* table.length MUST always be a power of two.
*/
private Entry[] table;
}
7.Java并发相关
1⃣️.CopyOnWriteArrayList 适用于写少读多的并发场景
2⃣️.ReadWriteLock即为读写锁,他要求写与写之间互斥,读与写之间互斥,读与读之间可以并发执行。在读
多写少的情况下可以提高效率。
3⃣️.ConcurrentHashMap是同步的HashMap 读写都加锁.
4⃣️. volatile只保证多线程操作的可见性,不保证原子性
8.wait 、 notify 、notifyAll 总结
wait() 、notify()、和notifyAll()是Object类中的方法
1⃣️. wait() .notify() 和notifyAll()是本地方法,并且为final方法,无法被重写
2⃣️. 调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor
3⃣️.调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor线程, 如果有多个线程都在等待这个对象的monitor,则只能唤醒其中的一个线程。
4⃣️ 调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程
注意: 如果调用某个对象的wait()方法,当前线程必须拥有这个对象的monitor(锁),因此调用wait()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)
5⃣️Condition是java1.5中才出现的,它用来代替传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify()使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。因此通常来说比较推荐使用Condition,阻塞队列实际上是使用了Condition来模拟线程间协作。
9.String , StringBuffer 和StringBuilder
String、StringBuffer、StringBuilder都实现了CharSequence接口
String是个不可继承类(final修饰),也是个不可变类,(内部char数组被final修饰。
StringBuffer和StringBuilder内部都是一般的动态数组,所以可变,前者是线程安全的,因为方法基本都被sychronized修饰了。
10.java.lang包是java语言包,定义了一些基本的类型,包括Integer,String之类的,是java程序必备的包,由解释器自动引入,无需手动导入。
system是属于java.lang.system。
java.util包是java的工具包,需要手动导入。
Java.sql包,JDBC接口类,需要手动导入。
Java.io;各种输入输出流,需要手动导入。
11.枚举相关
枚举类在后台实现时,实际上是转化为一个继承了java.lang.Enum类的实体类,原先的枚举类型变成了对应的实体类型。有几个实例,会调用几次构造方法。
12.类的加载顺序
1⃣️.父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
2⃣️.子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
3⃣️.父类非静态代码块(包括非静态初始化块,非静态属性)
4⃣️.父类构造函数
5⃣️.子类非静态代码块(包括非静态初始化块,非静态属性)
6⃣️.子类构造函数
13.局部内部类
局部内部类是放在代码块或方法中的,不能有访问控制修饰符,且不能用static修饰
14.java里面的queue
1.LinkedBlockingQueue:基于链接节点的可选限定的blocking queue。这个队列排列元素FIFO。
队列的头部是队列中最长时间的元素,队列尾部是队列中最短时间的元素。新元素插入队列的尾部,队列检索
操作获取队列头部的元素。链接队列通常具有比基于阵列的队列更高的吞吐量,但在大多数并发应用程序中的可预测性能较低。
blocking queue说明:不接受null元素。可能是容量有限的,实现被设计为主要用于生产者-消费者队列;
不支持任何类型的‘关闭’操作,表示不再添加项目实现是线程安全的。
LinkedBlockingQueue是一个基于节点链接的可选是否有界的阻塞队列,不允许null值。
LinkedBlockingQueue是一个线程安全的阻塞队列,实现了先进先出等特性
PriorityQueue是一个无界队列,不允许null值,入队和出队的时间复杂度是O(log(n))
PriorityQueue是不同于先进先出队列的另一种队列,每次从队列中取出的是具有最高优先级的元素。
ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,该队列的元素遵循FIFO原则
-
数组的复制效率比较
结论:
效率:System.arraycopy > clone > Arrays.copyOf > for循环
-
Thread.sleep() 和 Object.wait(),都可以抛出InterruptedException ,这个异常是不能忽略的,因为它是一个检查异常。
- thread.join把指定的线程加入到当前线程,可以将两个交替执行的线程合并成顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。
t.join() ; //使调用线程t在此之前执行完毕。
t.join(1000); //等待t线程,等待时间是1000毫秒
**18.总结一下 HashMap和HashTable的区别**
1⃣️.继承不同。public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
2⃣️. Hashtable中的方法是同步的,而HashMap中的方法在缺省的情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。
3⃣️、Hashtable中,key和value都不允许出现null值,在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回值为null时,既可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此, 在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断
4⃣️. 两个遍历方式的内部实现上不同。
Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式。
5⃣️. 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
6⃣️. Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组的默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
19.访问修饰符
访问修饰符.png-
jvm classLoader:
a. BootStrap ClassLoader /启动类加载器
主要负责jdk_home/lib目录下的核心api或 -Xbootclasspath 选项指定的jar包装入工作
b. Extension ClassLoader /扩展类加载器 主要负责jdk_home/lib/ext目录下的jar包或者-Djava.ext.dirs指定目录下的jar包装入工作
c.System ClassLoader /系统类加载器
主要负责java -classpath/ -Djava.class.path 所指定目录下的类与jar包装入工作
d. User Custom ClassLoader /用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间,通过java.lang.ClassLoader的子类动态加载class文件,体现java动态实时装入特性。
网友评论