基础

作者:加菲猫 2019-02-19 88 0

JVM 内存结构

方法区 程序计数器 本地方法栈
线程私有 线程共享 线程共享 线程私有 线程私有
存放局部变量、操作数、动态链接、方法返回地址等 存放对象实例 存放类信息、常量、静态变量 存放当前执行的字节码和行号 服务于 Native 方法

栈和堆

先进后出 二叉树
线程共享 线程私有

栈代表逻辑,堆代表数据,把它们分开更为清晰。
栈是向上增长的,堆是动态增长的,栈中只保存堆的地址,可节省空间。

栈溢出

递归调用

public void test() {
	test();
}

堆溢出

不断创建对象

for(;;)	{
	List list = new ArrayList(2000);
}

内存中的数组

存储值类型的数组,每个元素是一个引用,指向栈。(值类型的变量在栈上)
存储引用类型的数组,每个元素是一个引用,指向堆。(引用类型的变量在堆上)

数组转化为集合

String[] array = {"a","b","c"};
List<String> list = new ArrayList<String>(Arrays.asList(array));

集合转化为数组

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
liat.add("c");
String[] array = list.toArray(new String[list.size()]);

String 的拼接优化

String a = "hello world";
String b = "hello " + "world";
boolean flag = a == b;

flag = true。当 String 直接相加,编译时会被优化成一个字符串。

String a = "hello world";
String b = "hello ";
String c = b + "world";
boolean flag = a == c;

flag = false。当 String 与对象相加,编译时不会优化。

String、StringBuffer、StringBuilder

String StringBuffer StringBuilder
不可变,线程安全 线程安全 非线程安全

速度:String < StringBuffer < StringBuilder
少量操作用 String,多线程且大量操作用 StringBuffer,单线程且大量操作用 StringBuilder。

List、Set、Map

List Set Map
继承自 Collection 继承自 Collection 键值对
ArrayList HashSet、TreeSet HashMap、TreeMap
有序 无序 用 key 的哈希值计算位置
可重复 不可重复 key 不可重复
查询效率高 查询效率低
添加和删除效率低 添加和删除效率高

频繁查询且不强制数据唯一用 List,存储不可重复的数据用 Set,存储键值对用 Map。

ArrayList 和 LinkedList

ArrayList LinkedList
动态数组结构 链表结构
地址是连续的,需要一块完整的内存空间 地址是任意的,可插空存储,节省内存空间
查询效率高 查询效率低
添加和删除效率低 添加和删除效率高

频繁查询用 ArrayList,频繁添加和删除用 LinkedList。

ArrayList 和 Vector

ArrayList Vector
异步,非线程安全,性能高 同步,线程安全,性能低
扩容增长 50% 扩容 2 倍,可设置增长因子

需要线程安全用 Vector,只需要效率高用ArrayList。

比较 HashSet 和 TreeSet

HashSet TreeSet
哈希表结构 二叉树结构
无序,可存 null 有序,不可存 null

HashSet 和 TreeSet 都不能存储重复数据,HashSet 中的对象元素必须实现 hashCode() 方法,因为要用哈希值判断是否重复。(同一个类的对象哈希值不同,可以存储)
HashSet 的性能比 TreeSet 高,只有需要排序时,才用 TreeSet。

HashMap 和 ConcurrentHashMap

HashMap ConcurrentHashMap
非线程安全 线程安全

ConcurrentHashMap 采用分段锁,将 map 分为多个 segment,每个 segment 都有锁,提高了并发性。
需要线程安全用 ConcurrentHashMap,只需要效率高用 HashMap。

HashTable 和 ConcurrentHashMap

HashTable ConcurrentHashMap
线程安全 线程安全
锁住整个 map,数据量大时,性能低 只锁住当前要写的 segment,支持并发

Iterator 和 ListIterator

Iterator ListIterator
遍历 List 和 Set 遍历 List
只能从前往后 可从前往后,也可从后往前

ListIterator 继承自 Iterator 接口,额外功能:添加 / 替换元素、获取前一个 / 后一个元素的索引。

Enumeration 和 Iterator

Enumeration Iterator
枚举 迭代器
不可删除元素 可删除元素
速度快,占用内存少 线程安全

使用 Iterator 遍历集合时,要用 Iterator 的 remove() 删除元素,如果用集合的 remove(),会抛出 ConcurrentModificationException 异常。

面向对象

将现实世界描述成具有属性和方法的对象。

封装 继承 多态 抽象
封装数据和操作数据的方法,对外只提供接口 从已有的类中继承信息,创建新的类 调用同一个操作,不同子类作出不同的处理 只关注属性和行为,不关注行为的细节

重载和重写

重载 重写
在同一个类中 在父类和子类中
方法名相同、参数不同、返回值类型可以不同 方法名相同、参数相同、返回值类型相同

接口和抽象类

接口 抽象类
可实现多个 只能继承一个
只有 public abstract 方法 可以有抽象方法和普通方法
只有 public static final 类型的变量 可以有任意类型的变量
不能有静态方法 / 代码块 可以有静态方法 / 代码块

类的生命周期

加载(Loading):通过类名获取二进制字节流,在方法区中生成一个代表这个类的对象。
验证(Verification):确保字节流中的信息与当前虚拟机匹配,且无安全隐患。
准备(Preparation):为变量分配内存,设置初始值。
解析(Resolution):将常量池中的符号引用替换为直接引用。
初始化(Initialization):执行类中定义的代码。
使用(Using):根据代码执行。
卸载(Unloading):由 GC 负责回收。

内部类和静态内部类

内部类 静态内部类
属性和方法不能声明为静态的 属性和方法可以声明为静态的
实例化:Parent.Child child = new Parent().new Child(); 实例化:Parent.Child child = new Parent.Child()
可以引用外部类的属性和方法 只能引用外部类的静态属性和方法
依靠外部类存在 完全独立

静态属性和方法是类加载时放到内存中的,而在外部类被实例化后,内部类才会被加载。如果外部类没有被实例化,内部类也无法被加载,直接调用静态属性和方法是不存在的,所以内部类不能声明静态的属性和方法。

强引用、软引用、弱引用、虚引用

强引用 软引用 弱引用 虚引用
new 对象 SoftReference<> WeakReference<> ReferenceQueue<>
只要引用存在,对象就不会被回收 缓存,内存不足时回收 短期缓存,下一次垃圾回收时回收 随时可能被回收

GC

作用:清理对象,整理缓存。
类型:串行垃圾回收器、并行垃圾回收器、并发标记扫描垃圾回收器、G1垃圾回收器。
回收算法:引用计数法、标记清除法、复制算法、标记压缩算法、分代算法、分区算法。

年轻代 年老代 持久代
分为原始区(Eden)、存活区(Survivor) 存储年轻代中多次垃圾回收后依然存活的 存储类、方法、描述信息

绝大多数对象一开始都在 Eden,垃圾回收一次后依然存活的放到 Survivor,当 Eden 满了时,开始 Minor GC(从年轻代回收内存)。
当即将升入老年代的对象所需空间,大于老年代的剩余空间时,开始 Full GC,HandlePromotionFailure 参数也可以强制执行 Full GC。

GIT 和 SVN

GIT SVN
存储元数据 存储文件
没有全局版本号 有全局版本号

GIT 是分布式的,内容的完整性优于 SVN。

final、finalize、finally

final finalize finally
修饰符 方法 关键字
修饰变量,初始化后不能改变、修饰方法,不能被重写、修饰类,不能被继承 对象被回收前执行 与 try catch 组合,异常处理最后执行的代码块

发表评论

下一篇: 没有了,已经是最新文章