JAVA基础
值传递和引用传递的区别?
- Java只有一种参数传递方式:值传递(值的复制)
- 基本类型变量作为方法参数时候,将变量的值赋值一份传递到方法中。
- 引用类型变量作为方法参数时候,也是将变量的值(地址值)赋值一份传递到方法中.可见基本类型参数传递和引用类型参数传递是没有区别的。
静态变量和实例变量的区别
- 静态变量是只在类中使用static声明的变量,静态变量是属于类的变量,再类加载期间分配,内存中只有一份,可以被类的全体实例共享。
- 实例变量,是指在类中不使用static定义成员变量,这些变量属于对象的属性,在创建对象时候,随着对象在堆空间中分配,每个对象都有一份实例变量。
集合
HashMap底层原理是什么?
- HashMap底层是一个散列桶数组,每个散列桶是一个单向链表结构
- 散列桶容量从16开始,每次扩容为2倍
- 当出现散列冲突的时候,散列桶中元素形成链表结构。当散列表容量大于64,散列桶中元素超过8个的时候,会转换为红黑树,来提升查询性能。
- 查询时,利用散列算法,计算到散列桶位置,直接定位到散列桶定位。定位速度很快
- 散列表加载寅子是75%,也就是最多75%充满率,出现散列冲突机会少,严重散列冲突还有红黑树优化,在散列桶中查询性能很快。
Java7 Java8中的HashMap区别
- Java7采用:散列桶数组+链表方式实现,Java7以前,Java很少管理超过2GB的内存,散列数组很少会达到数组上限,利用适当数组扩容就可以减少因为散列冲突出现的链表长度问题,就可以解决链表查询性能问题。
- Java8采用:散列桶数组+链表/红黑树方法实现。Java8时代是大数据时代,Java面对的内存经常达到2GB内存,理论上,散列桶数组完全可能达到Java数组的上限2G,不能通过扩容解决散列冲突问题,Java8的优化方法就是引入了红黑树,利用红黑树解决链表查询问题。在链表长度超过8个节点时转换为红黑树。
HashMap扩容机制是什么?
- 实例化的HashMap默认内部数组是null。第一次调用put方法时初始化,长度为16。
- 创建HashMap时候设定了扩容阈值,默认为散列数组容量的75%。添加元素时先添加元素,然后判断是否需要扩容,如果容量达到阈值,则容量变为原来的2倍,阈值也变为原来的2倍,作为下次扩容的阈值。
- 扩容后数组长度始终是2的整次幂,这个是散列算法的要求。
ArrayList和LinkedList的区别?
- 数据结构实现:ArrayList:基于数组,容量不够时候采用复制方式扩容。LinkedList:使用链表实现。
- 随机访问效率:ArrayList比LinkedList在随机访问的时候效率更高,因为LinkedList是链表结构,需要依次查找元素,性能不高。
- 增加和删除效率:LinkedList首尾操作具备很高效率。ArrayList的头部性能稍差。
- 线程安全:ArrayList和LinkedList都是不同步的,不保证线程安全。
- 综合来说,需要频繁读取集合中的元素时,更推荐使用ArrayList;而在头尾增删操作较多时,更推荐使用LinkedList。ArrayList综合性能优秀,优选。
手写一下HashMap的几种遍历方式
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapTraverse {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("1","zhangsan");
map.put("2","lisi");
map.put("3","wanger");
//遍历方式1:获取keySet
Set<String> keys = map.keySet();
for (String key:keys){
System.out.println(key+"--"+map.get(key));
}
//遍历方式2:entrySet
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> entry:entrySet){
System.out.println("key:"+entry.getKey()+",value:"+entry.getValue());
}
//遍历方式3:获取map迭代器
Iterator<Map.Entry<String,String>> it=map.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String,String> entry=it.next();
System.out.println("key:"+entry.getKey()+",value:"+entry.getValue());
}
//遍历方式4:遍历map.values的方式
for(String value:map.values()){
System.out.println(value);
}
}
}
Collection和Collections的区别?
- Collection是一个集合接口,集合类的一个顶级接口。它定义了集合通用方法。
- Collection接口直接继承接口有LIst和Set。
- Collections则是集合类的一个工具类,其中提供了一系列静态方法,用于对集合中元素进行排序,搜索以及线程安全等各种操作。
HashMap和Hashtable的区别?
\ | HashMap | Hashtable |
线程是否安全 | 非线程安全 | 线程安全 |
效率 | 高 | 基本被淘汰 |
对Null的支持 | 可以存储null的key和value,但null作为Key只能有一个,为value可以有多个 | 不允许有null键和null值,否则会抛出空指针异常 |
Map、List和Set的区别是什么?
- List线性表,有序可以重复的集合,元素有先后次序,可以按照位置访问元素,可以存储null
- Set元素不重复集合,重复元素算同一个,不保证元素的先后次序,可以存储一个null
- Map元素按照key:value 成对存储,可以按照赵key查找value,查找性能好,key不可以重复,可以存储一个null key。
HashMap,LinkedHashMap,TreeMap区别?底层数据结构?
- HashMap:内部是一个散列表,查找数据性能很高。
- LinkedHashMap基本特点:继承自HashMap,对Entry集合添加了一个双向链表。
- TreeMap内部的红黑树,也就是二叉树,按照key进行排序。
Hash碰撞是什么?怎么解决?
- 散列计算时候,当两个不同的key.hashCode(),计算出相同的散列值的现象,我们就把它们叫做散列冲突(哈希碰撞)
- HashMap中的解决办法是利用链表结构存储,超过8个元素时转换为红黑树,元素数量超过阈值时,扩容也可以减少散列冲突
- 双向链表/双向循环链表