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个元素时转换为红黑树,元素数量超过阈值时,扩容也可以减少散列冲突
  • 双向链表/双向循环链表