最近在回顾java基础知识,收货颇多,在此做个总结
1.List和Set的区别
---List
-----可以允许重复的对象
-----可以插入null元素
-----是一个有序容器,保持着每个元素的插入顺序,输出顺序就是插入顺序
-----常用的实现类有ArrayList、LinkedList和Vector
---Set
-----不允许重复对象
-----无序容器
-----只允许一个null元素
-----最流行的实现类HashMap、LinkedHashMap和TreeSet
2.HashSet是如何保证不重复的
---如果hash码值不同,说明是一个新元素,存
---如果hash码值相同
-----如果equals相等,则不存
-----如果equals不相等,则存
3.HashMap是线程安全的吗,为什么不是线程安全的
---线程不安全
-----当多个线程共同执行put操作时,可能会导致有一个值没有存入
-----当HashMap在扩容时,有多个线程操作,会多个线程同时对HashMap扩容,HashMap的对象指针指向最后分配的一个内存
4.HashMap的扩容过程
---检查HashMap的size()是否超过阈值
-----如果超过,则设置阈值为INT的长度-1
-----如果不超过,创建新的数组,大小为原HashMap的两倍
-------将原HashMap中的Entry复制到新的HashMap中
-------遍历原HashMap的table,遍历table[i]的链表,计算Entry在新HashMap的table中的hash槽位置
-------将新的Entry添加到对应的hash槽链表的开头,e.next = newTable[i]
5.final finally finalize
---final
-----被final修饰的类,不能再派生出新的子类,不能作为父类被子类继承 => 一个类不能同时被abstract和final修饰
-----将变量或方法声明为final,保证在使用过程中不会被修改
-----被final修饰的变量必须在声明时给出初始值
-----被final声明的方法只能被使用,不能被重载
---finally
-----try、catch,无论代码是否发生异常,都会执行finally里的代码块
---finalize
-----在垃圾收集器将对象从内存清除出去之前做必要的清理工作
-----定义在object类中,所有类都继承它
6.强引用、软引用、弱引用、虚引用
---强引用:只要引用还在,垃圾回收器永远不会回收
---软引用:非必须引用,内训溢出之前进行回收
---弱引用:第二次垃圾回收时回收
---虚引用:垃圾回收时回收,无法通过引用取到对象值
7.Java反射
---反射机制:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为反射机制
---什么是反射
-----反射是一种间接操作目标对象的机制,在程序运行时获取或者设置对象自身的信息
-----只要给定类的名字,就可以通过反射获取类的所有信息,接着便能调用它的所有方法和属性
---反射的步骤
-----获取类加载器:ClassLoader loader = Thread.currentThread().getContextClassLoader()//获取当前线程的上下文类加载器
-----通过类加载器获取类:Class class = loader.loadClass(“path”)//通过对象的全称限定来获取对象
-----通过class获得构造函数:Constructors cons = class.getDeclearedConstructors(Class[] null)
-----通过构造函数构造对象:Car car = (Car)cons.newInstance()//获取类的默认构造函数对象并实例化对象
-----得到car对象,调用car的方法:Method method = car.getMethod(“setName”, “String.class”)
-----method.invoke(car, “红旗CA72”)//通过invoke方法,让car的method(setName)方法之行
8.Arrays.sort实现原理和Collection实现原理
---Arrays.sort()
-----该算法是一个经过调优的快速排序,此算法在很多数据集上提供N*log(N)的性能
-----对于传入的数组长度在不同的阈值内,分别对应不同的排序算法,主要有归并排序、快速排序、插入排序、记数排序
-----当byte array字节数组长度大于29时,记数排序优于插排;当short or char array短整型活着字符数组长度大于3200,则记数排序优于快速排序
---Collection.sort()
-----该算法是一个经过修改的合并排序算法,可提供保证的N*log(N)的性能
-----底层将list转成array,调用Arrays.sort()
9.LinkedHashMap的应用
---概述
-----是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序,可存储null键和null值,不保证映射的顺序
-----区别于HashMap,LinkedHashMap维护着一个运行于所有条目的双重链接列表,链接列表定义了迭代顺序,该顺序可以插入或顺序访问
-----非同步
---实现
-----Entry:除了保存当前对象的引用外,还保存了上一个元素before和下一个元素after的引用,从而构成了双向链接列表
-----初始化:调用了父类HashMap的相关构造方法来构造一个底层存放的table数组,重写了父类的init(),header.before=header.after=header;
-----存储:重写了父类的addEntry和createEntry,提供了自己特有的双向链接列表的特性
-----读取:重写了父类的get方法,在调用父类的getEntry()方法后,判断当前的排序模式accessOrder为true时,记录访问顺序,将最新访问的元素添加到双向链表的表头,并从原来的位置删除
-----排序模式:定义了排序模式accessOrder,对于访问顺序,为true;对于插入顺序,为false;一般情况下,迭代顺序为默认的插入顺序
10.cloneable接口实现原理
---什么是clone
-----Clone就是对于给定的一个对象o,得到另一个对象o’,o与o’类型相同,内容相同,就称o’是o的克隆或副本
---什么时候使用Clone
-----当需要修改对象属性,又不想影响原来的属性值
---Java对Clone的支持
-----Object类有clone方法:protected native Object clone() throws CloneNotSupportedException;
-----Object的clone()方法会检查this.getClass()是否实现了Cloneable, Cloneable只是一个接口标志,用来标志该类是否具备克隆功能
---浅克隆、深克隆
-----Object在对某个对象实施Clone时对其一无所知,仅仅简单的执行域对域的copy;深克隆即对所有的引用进行浅克隆
11.异常分类以及处理机制
--异常分类
---Throwable:所有异常共同的祖先,指定代码中可用异常传播机制通过Java应用程序传输的任何问题的共性
-----Error:程序无法处理的错误,表示运行应用程序中较严重的问题,表示代码运行时JVM出现的问题,如:虚拟机运行错误、内存溢出,Error发生时,虚拟机会选择线程终止
-----Exception:程序本身可以处理的异常
-------重要的子类:RuntimeException;RuntimeException及其子类表示“JVM常见操作”引发的错误,如:空对象引用、数组下标越界等
---Java的异常(包括Error和Exception)分为可查异常和不可查异常
-----可查异常:编译器要求必须处置的异常,除RuntimeException及其子类外,其他Exception类及其子类都是可查异常
-----不可查异常:编译器不要求强制处理的异常,包括运行时异常(RuntimeException及其子类)和错误(Error)
---Exception异常分两类
-----运行时异常:都是RuntimeException及其子类异常,包括空指针异常、数组下标越界异常
-----非运行时异常(编译异常):非RuntimeException以外的异常,类型上属于Exception及其子类
--异常处理机制
---抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序信息,运行时代码负责寻找处置异常的代码并执行
---捕获异常:当方法抛出异常后,运行时代码将转为寻找合适的异常处理器
-----潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合,当异常处理器所能处理的异常与方法抛出的异常类型相符时,即为合适的异常处理器
---Throws抛出异常的规则
-----如果是不可查异常,可以不使用throws关键字来抛出,编译能通过,运行时碰到会被系统抛出
-----必须声明方法可抛出的任何可查异常
-----仅当抛出了异常,该方法的调用者才必须处理或者重新抛出异常
-----调用方法必须遵循任何可查异常的处理和声明规则
12.wait和sleep的区别
---sleep
-----属于Thread
-----导致程序暂停指定的时间,让出cpu给其他线程,但它的监控状态一直保持着,当指定时间到了会自动恢复运行状态
-----sleep()过程中不会释放锁
---wait
-----属于Object
-----线程会放弃对象锁,进入等待此对象的等待锁定池
-----只有对该对象调用notify()方法后本线程才进入对象锁定池准备
13.数组在内存中如何分配
---数组的初始化方式
-----静态初始化:初始化时显式指定每个数组元素的初始值,由系统决定长度
-----动态初始化:初始化时显式指定数组的长度,由系统为数据每个元素分配初始值
---数组的内存分配
-----如int[] arr = new int[3],在堆中开辟内存int[3],在栈中创建引用arr,arr指向堆中int[3]的地址
14.JDK1.8新特性
---接口支持默认方法,添加关键字default
---Lambda表达式
---函数式接口:每一个lambda表达式都对应一个类型,通常是接口类型。函数式接口仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法
---方法与构造函数引用:关键字来传递方法或者构造函数引用
---Predicate接口:只有一个参数,返回boolean,如:Predicate<String> predicate = (s) -> s.length>0