+ HashTable和HashMap的区别?
+ 接口和抽象类的区别?
+ 队列和栈的应用场景
+ 同步线程的方法有哪些
+ 说说红黑树
+ JVM的GC有了解吗
## 1、HashTable和HashMap的区别?
> 参考: (HashTable和HashMap的区别详解)[https://www.cnblogs.com/williamjie/p/9099141.html]
### 继承的父类不同
HashTable继承自Dictionary类,而HashMap继承自AbstractMap类。但他们都实现了Map接口
### 线程安全不同
HashTable中的方法是synchronized的,而HashMap则不是。在多线程并发的情况下可以直接使用HashTable。
可以使用`Collections.syncronizedMap`来包装HashMap使得其变成同步的
这里貌似是个包装者模型,于是去探究了一下源码,证明这个想法是没错的
`Collections.syncronizedMap`返回了`Collections`的一个内部静态类`SynchronizedMap`,这个类的部分方法如下:
```java
private static class SynchronizedMap<K,V>
implements Map<K,V>, Serializable {
private static final long serialVersionUID = 1978198479659022715L;
private final Map<K,V> m; // Backing Map
final Object mutex; // Object on which to synchronize
SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNonNull(m);
mutex = this;
}
SynchronizedMap(Map<K,V> m, Object mutex) {
this.m = m;
this.mutex = mutex;
}
public int size() {
synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return m.isEmpty();}
}
public boolean containsKey(Object key) {
synchronized (mutex) {return m.containsKey(key);}
}
public boolean containsValue(Object value) {
synchronized (mutex) {return m.containsValue(value);}
}
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
}
// other methods.
}
```
可以看到其中保存了一个`private final Map<K,V> m`进行包装,同时还持有一个`final Object mutex;`类型以在包装方法中进行加锁
这是一个很典型的包装者模型
### 是否包含contains方法
HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。
Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。
### key和value是否允许null值
Hashtable中,key和value都不允许出现null值。但是如果在Hashtable中有类似put(null,null)的操作,编译同样可以通过,因为key和value都是Object类型,但运行时会抛出NullPointerException异常,这是JDK的规范规定的。
HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
### 遍历方式的内部实现不同
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
### hash值不同
哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
### 内部实现使用的数组初始化和扩容方式不同
HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
查看源码验证,在1.8下,HashMap仍然是扩充成2的整数次幂
```java
// ...
// line 687
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
// ...
```
## 2、接口和抽象类的区别?
> 参考:(抽象类和接口的区别)[https://blog.csdn.net/MrBaymax/article/details/84328918]
### 从形态上看
抽象类可以给出一些成员的实现,接口却不包含成员的实现(排除default方法);
抽象类的抽象成员可被子类部分实现,接口的成员需要实现类完全实现,一个类只能继承一个抽象类,但可实现多个接口等等。
### 如何区分
1. 类是对对象的抽象,抽象类是对类的抽象;接口是对行为的抽象。
2. 若行为跨越不同类的对象,可使用接口;对于一些相似的类对象,用继承抽象类。
3. 抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类;接口是根本不知子类的存在,方法如何实现还不确认,预先定义。
## 3、线程的同步方法有哪些?
+ join()(没有答出来)
+ Java中Object自带的wait()、notify()、notifyAll()方法
+ J.U.C中Condition的await()、singal()、singalAll()方法
+ synchronized关键字
+ 基于AQS的:CyclicBarrier、CounDownLatch、Semaphore(没有答出来)
+ 生产者消费者模型
## 4、JVM的GC有了解吗
参考之前写的文章:(【学习】内存回收器 GC)[http://cong-onion.cn/archives/java-gc]
## 5、说一下红黑树
红黑树的话被提到过好多次,今天下午花点时间去实现以下,到时候单独开一篇文章
【秋招面经】腾讯PCG-秋招提前批-一面总结