java小白入行面试总结——基础篇
-
一、集合
以下是我个人入行总结的面试问题,都是根据自己的理解些的,语言和措辞可能并不完美,内容的正确性也不敢绝对保证,欢迎指正和添加
关于集合,我们首先要关注的就是其继承体系(如图)

如上图,大致说明了关于collection和map派系集合的结构(注意:这里并不是其完整的继承体系,仅仅表述大致继承结构)。集合大致可以分为collection和map两个派系,而collection派系下又可分为list派系和set派系,我们简单的认为list派系代表有序的,可重负的集合,而set代表无序的,不可重复的集合,(当然,set集合也可以是有序的,例如LinkedHashset就是通过双向链表使set集合有序),下面就大致说一下关于集合方面的面试知识点:
1、collection与map派系的区别(也有可能是set与map的区别)
答:collection属于单值集合,map属于key-value集合。
2、ArrayList与LinkedList的区别
答:ArrayList底层是数组实现,其特点是查询快,增删慢;LinkedList底层是双向链表实现,其特点是增删快,查询慢。
3、那么为什么说链表实现会增删快,查询慢呢?
答:因为(双向)链表的实现是由每一个元素记录上一个元素和下一个元素的位置,如此形成的一个链条,其没有索引,所以增删的时候只需要在任意位置增加一个元素,让他记住上一个和下一个元素即可,而查询则需要从头到尾一个一个的去查询对比是不是我们想要的元素。
4、HashMap与HashTable的区别
答:HashMap是线程不安全的集合,可以使用null作为键(仅允许一个);HashTable是线程安全的集合,不允许使用null作为键。
5、请说出你常用的线程安全且效率高的map集合,并说说他为什么线程安全而且能保证效率
答:concurrentHashMap既能保证线程安全也可以保证效率,其原理是利用分段锁技术,我们可以简单地理解为concurrentHashMap是多个HashTable的组合,也就是说是有多把锁控制,没把锁下的数据操作不会阻塞其他锁下的数据操作。
6、hashMap的存储原理
答:hashmap底层是一个数组结构,当一组k-v结构的数据要进行存储时,首先对key的hash值与数组的长度进行位运算(jdk1.8之前是取模运算,1.8及1.8之后是进行位运算),求出该key应该存储的位置,如果相应的位置没有存储任何数据,就直接将该key存入到这个位置,如果已经存储了其他数据(也就是常说的hash碰撞),则通过equase方法与存储的数据一一对比,如果不相等,就以链表的形式挂在其他元素下面(这就是我们常说的桶结构),如果与其中一个相等,就替换掉这个元素。(如果有问题问为什么要重写hashCode方法和equale方法也可采用此答案)
7、如何迭代map集合
答:map集合是k-v结构,要迭代map集合方式有二:
第一是通过foreach或者迭代器迭代entry(一个entry表示一个key-value的整体,可以通过map集合的entryset方法获取所有entry的集合)第二是通过foreach或者迭代器迭代key的集合(可以通过map集合的keyset方法获取集合下所有key的集合)
8、什么是快速失败与安全失败
答:快速失败与安全失败是指的对集合迭代的时候并发修改集合中的元素,迭代时是迭代的集合本身就是快速失败,二迭代集合副本就是安全失败。一般普通的集合都是快速失败,
9、如何让一个线程不安全的集合变成线程安全的集合
答:使用collections的synchronizedCollection或者synchronizedList,synchronizedMap方法传入相应的集合,返回一个线程安全的集合,其原理是在集合的set和get方法中添加synchronized关键字。
-
二、线程
要了解线程必须先知道线程是什么,线程与进程的区别是什么,线程有什么特点;下面就简单总结一下关于线程容易被问到的基础知识点:
1、线程与进程的区别
答:进程是资源分配最小单位,线程是程序执行的最小单位;我们也可以理解为线程是进程的细化
2、实现线程的方式有几种,特点是什么
答:方式一:继承Thread类,并重写run方法,其特点是因为java只支持单继承,所以继承了Thread就不能继承其他类;方式二:实现runnable接口,并重写run方法,其有效的避免了Thread的缺陷;方式三:实现Callable接口,并重写call方法,其特点是以这种方式实现的线程运行可以有返回值,可以抛出异常,但是要注意的是这种方式实现的线程不能通过Thread的start()方法启动线程,其原因是Thread的沟槽方法中只能接收Runnable及其子类对象,Callable并未实现runnable,所以无法使用Thread的start()方法启动该线程。
3、你知道哪几种线程池
答:通过ThreadPoolExecutor可以创建四种线程池,分别是带缓存的线程池,固定线程数的线程池,带定时任务的线程池以及单线程的线程池,其中固定线程数的线程池实际应用最多
4、sleep和wait的区别
答:sleep是Thread的方法,wait是object的方法,sleep执行时不会放弃锁,wait执行时会放弃锁;
5、Lock和synchronized的区别
答:Lock是jdk1.5的特性,是一个java类,其使用更加灵活,但代码执行过程中一旦抛出异常,必须要在finally块中手动释放锁,synchronized是java内置关键字,发生异常会自动释放锁。
8、保证线程安全的方式
(1)使用synchronized关键字修饰相应的方法将方法变成同步方法或用synchronized代码块包裹相应的代码变成同步代码块
(2)将需要同步的方法之前加入Lock的lock方法获取锁,同步结束时在finally块中加入unlock方法释放锁
(3)使用volatile修饰可能出现安全问题的变量,该关键字可保证变量的可见性和防止重排序的作用;
-
三、异常
1、Throw和Throws的区别
答:Throw是指执行抛出的动作,后面一般跟你需要手动让其抛出的异常对象,Throws一般可以理解为建立一个异常管道,供Throws后定义的异常种类及其子类抛出。
2、try{}catch(){}finally{}中代码的执行顺序
答:一般情况,执行顺序为限制性try中的代码,如果不发生异常则继续执行finally中的代码,如果发生异常则先执行catch中的代码,然后执行finally中的代码。
3、如果try{}catch(){}finally{}中try代码块抛出异常,但是在catch中return 3,finally中return 4,最终程序的返回值是什么?为什么?
答:最终的retuen的值为4;因为在try{}catch(){}finally{}中程序首先执行try中的代码,如果try中代码抛出异常并被catch捕获,程序将执行catch中的代码,一旦执行过程中遇到return,将暂停执行return转而执行finally中的代码,最终在finally中return 4,则程序的执行结果为4.
4、error和Exception的区别
答:error一般指的错误,大多是比较严重的,系统级的,exception一般指的异常,大都是可以通过代码避免和处理的。
5、子类可以抛出比父类更多的异常吗?
答:不可以。java规定子类不可以抛出比父类更多或更大的异常
相关文章: