面试常见问题

来源:互联网 发布:网络协议 编辑:程序博客网 时间:2024/05/21 17:36

项目刚做完一版,公司大牛正在准备将项目切换到微服务架构。闲下来准备学习点东西,翻看之前从各个地方收集的一些资料,找到一个面试的文件夹,就把里面的所有面试文档看了一遍,也为自己下次跳槽增加筹码,有很多程序员们应该会和我一样工作几年后,发现在面试的时候被问到一些很基础的问题时突然发现在自己不知道怎么回答。so 接下来我就开始复习最基础的Java知识了


  • 看完几个面试文档后总结几个小心得
    • 1,能用代码去吧面试的题的结果输出的就用代码来实现一遍。
    • 2,一定在看完一个文档后在脑子里想想自己刚刚学到了什么。

下面是一些常见面试题供大家学习也记录一下,方便以后自己查看【有些东西长时间不看、不用是会忘记的】

本博文只记录寡人认为比较有经常出现的Java基础,该博客会置顶持续更新,如有好的建议请加qq群227493974 相互学习,也可以进去找我要一些面试文档

1,try..catch..finally执行顺序问题

public static int trycatch(int[] a) {    try {        a[0] = 9;        System.out.println("我是try 我执行了。。。。我返回a[0]=9了");        //int i=9/0;        //return a[0];        throw new NullPointerException();    }  catch (NullPointerException e) {        System.out.println("我是NullPointerException 我执行了。。。。a[0]=2");        a[0] = 2;        return a[0];    } catch (Exception e) {        System.out.println("我是Exception 我执行了。。。。a[0]=8");        a[0] = 8;        return a[0];    } finally {           System.out.println("我是finally我执行了。。。。a[0]=3");        a[0] = 3;        //return a[0];    }}public static void main(String[] args) {    int a[]={0,1,2,3};    System.out.println(trycatch(a));}
上面的执行顺序,最好自己手写运行一遍,可以加深印象。 执行顺序就是:try–catch–finally,返回值是最后一个retrun的值。比如程序出现异常执行到catch中会先执行完return后,把a[0]的值暂存,之后执行finally的语句块,执行完之后把暂存的值返回。
  • 《Java虚拟机规范》中描述:
    • 如果 try 语句中遇到了 return,
        1. 如果有返回值的话,将返回值保存在局部变量中。
        1. 执行 jsr 指令将控制权转到给 finally 语句中。
        1. 在 finally 执行完成后,返回事先保存在局部变量中的值。
    • 编译器会构造特殊的异常处理器,来保证当 try 语句中有异常发生时,它会拦截住任何类型的异常。如果在 try 语句中有异常抛出,异常处理器的行为是:
        1. 将异常保存在局部变量中。
        1. 执行 jsr 指令将控制权转到给 finally 语句中。
        1. 在执行完 finally 语句后,重新抛出这个事先保存好的异常。

2,线程的基本概念、线程的基本状态以及状态之间的关系

一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。
调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。


3,String,StringBuffer, StringBuilder 的区别是什么?String为什么是不可变的?

一,(1),string 是字符创常量,Stringbuffer和StringBuilder是字符串变量;
(2)StringBuffer是线程安全,StringBuild是非线程安全的。因此效率上StringBuild比StringBuffer要高。
二,String在jdk中是final类型 所以是不可变的。

4,各种结合的【List、Map、ArrayList、vetcor。。。】区别
List和set相似,都是单列元素的集合,有一个共同的父接口collection。set里面不允许有重复的值,也就是不能有两个相等的对象。set去元素时,只能以iterator接口取得所有的元素,再逐一遍历

一,List:
  • 1,List接口继承了collection接口,存储的是单列数据的集合,存储的数据是有序的,并且允许重复
    • 1.1 arrayList、vector、linkedList都实现了List接口。
    • 1.2 存储:ArrayList、vector是以类似数组的形式存在内存中的,LinkedList是以链表的形式存在内存中的。so LinkedList适合指定位置插入、删除操作,不适合查找;ArrayList和vector适合查找不适合指定位置的插入、删除操作。
    • 1.3 同步:Vector是线程同步的也就是线程安全的;而ArrayList和LinkedList是线程不安全的。如果只有一个线程会访问到集合,最好使用ArrayList,因为它不需要考虑线程安全,效率会高些;如果有多个线程会访问到集合,最好使用vector,因为不需要我们自己再去考虑和编写线程安全的代码。
    • 1.4 ArrayList在元素填满容器时会自动扩充容器大小的50%,而Vector则是100%,因此ArrayList更节省空间。
二 ,map:
  • Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。
    • 1.1 HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。
    • 1.2 HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
    • 1.3 HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
    • 1.4 Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
    • 1.5 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
    • 1.6 Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
    • 1.7 HashTable线程同步,HashMap非线程同步。
    • 1.8 HashTable使用Enumeration,HashMap使用Iterator
    • 1.9 HashTable中hash数组的默认大小是11,增加方式的old*2+1,HashMap中hash数组的默认大小是16,增长方式一定是2的指数倍。
    • 2.0 TreeMap能够把它保存的记录根据键排序,默认是按升序排序。
      就HashMap与HashTable主要从三方面来说。
原创粉丝点击