导图社区 Java 复习
Java超全复习总结,包括类型转换、内存管理、异常、反射、IO流、序列化、IO多路复用、面向对象、数据结构、并发等内容。
编辑于2021-10-14 22:10:31Java 复习
JVM
类加载
加载
类加载器
bootstrap classloader
extension classloader
Application classloader
Userdefined classloader-e.g.字节码加密,需要在加载时解密
特点
父类委托
缓存
全盘负责
步骤
通过类的全限定名获取二进制字节流
将字节流代表的静态存储结构转化为方法区的运行时数据结构
java堆中生成java.lang.class对象
加载方式
命令行启动时,jvm初始化加载
Class.forName(classname)动态加载
ClassLoader.loadClass(classname) 动态加载
区别
forname(classname, true, classloader), true 已经初始化
loadClass(className, false) false表示不连接,即静态块和静态对象不会执行
链接
验证
准备
为静态变量分配内存,初始化为默认值(0,0L,null,false) 而非显式的赋值
若同时有 final static,则初始化为指定的值
解释(optional)
符号引用转化为直接引用
初始化
执行/初始化
时机
new
访问某个类/接口的静态变量
调用类的静态方法
反射
初始化某个类的子类,其父类也会被初始化
JVM启动时被标明为启动类的类
执行引擎
字节码载入运行时数据区
解释器
JIT(即时编译器) 字节码转换为本地代码
使用
卸载
内存管理
内存分区
线程间共享
堆
新生代
Eden
Survivor_1
Survivor_2
老年代
存放 对象实例
方法区
Classloader引用
运行时常量池
字段数据
方法数据+代码
线程独享
栈(栈帧组成
类当前方法的运行时常量池引用
局部变量表
操作数栈
返回值
PC
本地方法栈
异常处理
OOM-OutOfMemoryError
内存泄漏
对象可达,但是无用。(占用内存但不会被回收)
原因
全局集合
缓存(无限大)
ClassLoader
由于ClassLoader涉及 元数据引用(字段,方法,类),则只要有对字段、方法、类或者ClassLoader对象的引用,则ClassLoader必须驻留在JVM中。
StackOverflowError
clone
Object 中的 clone() 是protected,子类可以调用,但子类调用时,会检查是否实现 Cloneable接口。
浅复制
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象
深复制
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
java不支持复制构造函数,但可以使用clone 复制构造函数是 用对象初始化另一个对象,
GC
优势: 不要求显示分配和释放内存,避免了潜在问题。 管理软指针,即指向对象的引用 具有平台依赖
具有平台依赖
对象判活
引用计数--注意循环引用
可达性分析(利用GCRoot
GC算法
标记清除
标记-整理
复制
分代收集
GC回收器
类型转换
长度
int:32bit
byte 8bit
char &short - 16bit
float - 32bit
long & double - 64bit
转换
自动提升
ps: 在运算时,长度小于int的会自动转换为 int, byte+byte->int
强制转换
异常
final finalize finally区别 1、final (1)final 变量: 值/引用不能被改变,初始化在定义处/构造函数中 (2)final方法: 不能被重写,另外可以转化为行内调用机制,将方法主题插入在调用处,例如保存断点,压栈 (3)final类:不能被继承,不能和static同时修饰 2、finalize JVM调用finalize之前,保证对象不可达,且不保证一定会调用,最多只运行一次 3、finally 关键字,总会执行
Throwable接口派生
Error,JVM生成
Exception,java程序生成
checked exception
派生自 java.lang.Exception, 运行时动态的检测到一个错误
IOException
ClassNotFoundException
CloneNotSupportedException
runtime exception
派生自 java.lang.Runtime.Exception,系统运行时异常,例如 被零除,空字符串。。。
反射
使代码运行时装配,无须在组建之间进行链接,创建灵活的代码
IO流
字符流
Reader
BufferedReader
InputStreamReader
FileReader
StringReader
PipedReader
ByteArrayReader
FilterReader
PushbackReader
Writer
同上
字节流
InputStream
FileInputStream
FilterInputStream
BufferedInputStream
DataInputStream
PushbakInputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
StringBufferInputStream
ByteArrayInputStream
OutputStream
File OutputStream
Filter OutputStream
buffered OutputStream
Data OutputStream
Print OutputStream
Object OutputStream
Piped OutputStream
ByteArray OutputStream
序列化
将实现 Serializable 接口的类转换为一组 byte,日后可以再恢复,补偿操作系统方面的差异。 序列化对象: 1、创建OutputStream,嵌入 ObjectOutputStream,则可以用writeObject() 写入OutputStream 2、读时,需要利用 InputStream 和ObjectInputStream, readObject()读出的是 对象的引用。 对象序列化不仅能保存对象副本,且跟着对象中的引用,把它所引用的对象也保存起来,然后再继续跟踪那些对象的ref
IO多路复用
I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。
select
每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
select支持的文件描述符数量太小了,默认是1024
poll
epoll
没有最大并发连接限制
只关心“活跃”的链接
使用共享内存,避开了内存拷贝
函数
epoll_create 创建专用的文件描述符,申请内和空间
epoll_ctl 控制某个文件描述符上的事件
epoll_wait 等待事件
工作模式
level trigger
edge trigger
NIO
Buffer
类型
普通变量类型
ByteBuffer
间接, HeapByteBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
MappedByteBuffer
文件关闭不确定,在full gc时关闭
使用步骤
分配空间
写入数据到Buffer
使用 filp()
从buffer读取数据
调用clear()/compact()
变量表示位置状态
Capacity 总长度
position 下一个操作的数据元素位置
limit 不可操作的元素位置
mark 记录当前position的前一个位置 或默认为0
Channel
FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel
概要
Selector
一个Selector实例可以同时检查一组信道的I/O状态。
使用
调用工厂方法 open()
将 ServerSocketChannel注册到 selector
interest集合
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SelectionKey.OP_READ
SelectionKey.OP_WRITE
调用select()方法
select() select(int timeout) selectNow() --non blocking return 就绪的channel数量
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
遍历Key 确定就绪状态
selectionKey.isAcceptable();
selectionKey.isConnectable();
selectionKey.isReadable();
selectionKey.isWritable();
遍历后,iter.remove()
注意每次迭代末尾的keyIterator.remove()调用。 Selector不会自己从已选择键集中移除SelectionKey实例。 必须在处理完通道时自己移除。
SelectionKey
interest集合
ready集合
channel
selector
面向对象
多态
继承、实现
不能继承的情况
1、匿名内部类不成继承其他类,但一个内部类可以作为接口,由另一个内部类实现 2、被 final 修饰
抽象类
1、不能被实例化 2、允许包括抽象成员,可以有非抽象方法 3、不能是 final的 4、可以被抽象类继承,但仍是抽象类,且必须覆盖实现所有继承来的抽象成员 5、可以被声明
泛型
只在编译阶段有效
泛型类
通配符
?
? extends class
? super class
优点
类型安全,限制变量类型
消除强制类型转换
提高性能
注意事项
类型参数只能是类类型
不能对泛型类使用 instanceof
不能创建一个确切的泛型类型数组,使用通配符可以
数据结构
collection
Hashmap底层实现
排序
稳定排序
不稳定排序
String & StringBuffer
String s= new String("abc")
String s = "abc"
intern()方法
正则表达式
并发
锁
自旋锁
jvm默认为10次,for争取锁
阻塞锁
被阻塞的线程不会争夺锁
可重入锁
读写锁
悲观/乐观锁
轻量级锁(CAS实现
X锁
对象锁、线程锁
公平/非公平锁
公平:有优先级 非公平:无优先级
线程池
ThreadPoolExecutor
属性
corePoolSize
maximumPoolSize
keepAliveTime
volatile runState
Running
SHUTDOWN
STOP
TERMINATED
方法
execute
流程
那么等于和大于corePoolSize怎么处理呢? 1> 当前活动的线程数量 >= corePoolSize 的时候,都是优先添加到队列中,直到队列满了才会去创建新的线程
submit()
shutdown()
shutdownNow()
初始化(提交任务才会创建线程)
prestartCoreThread() 启动一个
prestartAllCoreThreads()启动所有
任务缓存队列/排队策略
workQueue
ArrayBlockingQueue FIFO
LinkedBlockingQueue, FIFO
synchronousQueue,不保存任务,直接新建线程执行
任务拒绝策略
到达maximumPoolSize 拒绝
AbortPolicy 丢弃任务,抛出异常
DiscardPolicy 丢弃任务,不抛出异常
DiscardOldestPolicy 丢弃队列最前面的任务,重新执行
CallerRunsPolicy 由调用线程处理该任务
配置线程池大小
cpu密集型 -- Ncpu+1
IO密集型 --2*Ncpu
参考值,可以先设置,并根据系统负载及利用率调整
线程局部存储 TLS
concurrent库
队列
BlockingQueue 接口
ArrayBlockingQueue
DelayQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue-容纳单个元素
Map
ConcurrentMap接口
ConcurrentHashMap 只锁表项
闭锁 CountDownLatch
原子性数据类型
Executor
execute
ExecutorService
submit
invokeAll
invokeAny
shutDown
AbstractExecutorService