20道Java面试必考题

系统整理了一下有关Java的面试题,包括基础篇,javaweb篇,框架篇,数据库篇,多线程篇,并发篇,算法篇等等,陆续更新中。其余方面如前端后端等等的面试题也在整理中,都会有的。前端

注:文末有福利!pdf版本可在文章末尾获取java


 

一、ArrayList和Vector的区别web

        这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,至关于一种动态的数组,咱们之后能够按位置索引号取出某个元素,而且其中的数据是容许重复的,这是与HashSet之类的集合的最大不一样处,HashSet之类的集合不能够按索引号去检索其中的元素,也不容许有重复的元素。面试

         ArrayList与Vector的区别主要包括两个方面:.
1)同步性:算法

       Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不一样步的。若是只有一个线程会访问到集合,那最好是使用ArrayList,由于它不考虑线程安全,效率会高些;若是有多个线程会访问到集合,那最好是使用Vector,由于不须要咱们本身再去考虑和编写线程安全的代码。数据库

2)数据增加:编程

       ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就须要增长ArrayList与Vector的存储空间,每次要增长存储空间时,不是只增长一个存储单元,而是增长多个存储单元,每次增长的存储单元的个数在内存空间利用与程序效率之间要取得必定的平衡。Vector默认增加为原来两倍,而ArrayList的增加策略在文档中没有明确规定(从源代码看到的是增加为原来的1.5倍)。ArrayList与Vector均可以设置初始的空间大小,Vector还能够设置增加的空间大小,而ArrayList没有提供设置增加空间的方法。后端

    总结:即Vector增加原来的一倍,ArrayList增长原来的0.5倍。数组

 

二、HashMap和Hashtable的区别安全

        HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap容许空(null)键值(key),因为非线程安全,在只有一个线程访问的状况下,效率要高于Hashtable。

        HashMap容许将null做为一个entry的key或者value,而Hashtable不容许。

HashMap把Hashtable的contains方法去掉了,改为containsvalue和containsKey。由于contains方法容易让人引发误解。

        Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

        最大的不一样是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不须要本身为它的方法实现同步,而HashMap就必须为之提供同步。

     就HashMap与HashTable主要从三方面来讲。
        一.历史缘由:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
        二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
        三.值:只有HashMap可让你将空值做为一个表的条目的key或value

 

三、List和 Map区别?

        一个是存储单列数据的集合,另外一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,而且容许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是能够有重复的。

 

四、List,Set, Map是否继承自Collection接口?

   List,Set是,Map不是

 

五、List、Map、Set三个接口,存取元素时,各有什么特色?

(这样的题比较考水平,两个方面的水平:一是要真正明白这些内容,二是要有较强的总结和表述能力。)

        首先,List与Set具备类似性,它们都是单列元素的集合,因此,它们有一个共同的父接口,叫Collection。Set里面不容许有重复的元素,即不能有两个相等(注意,不是仅仅是相同)的对象,即假设Set集合中有了一个A对象,如今我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,因此,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法没法加入该元素,返回结果为false。Set取元素时,不能细说要取第几个,只能以Iterator接口取得全部的元素,再逐一遍历各个元素。

       List表示有前后顺序的集合,注意,不是那种按年龄、按大小、按价格之类的排序。当咱们屡次调用add(Obje)方法时,每次加入的对象就像火车站买票有排队顺序同样,按先来后到的顺序排序。有时候,也能够插队,即调用add(intindex,Obj e)方法,就能够指定当前对象在集合中的存放位置。一个对象能够被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并非把这个对象自己存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add屡次时,即至关于集合中有多个索引指向了这个对象,如图x所示。List除了能够用Iterator接口取得全部的元素,再逐一遍历各个元素以外,还能够调用get(index i)来明确说明取第几个。

       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对象的集合。

 List以特定次序来持有元素,可有重复元素。Set没法拥有重复元素,内部排序。Map保存key-value值,value可多值。

 

六、说出ArrayList,Vector,LinkedList的存储性能和特性

        ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增长和插入元素,它们都容许直接按序号索引元素,可是插入元素要涉及数组元素移动等内存操做,因此索引数据快而插入数据慢,Vector因为使用了synchronized方法(线程安全),一般性能上较ArrayList差。而LinkedList使用双向链表实现存储,按序号索引数据须要进行前向或后向遍历,索引就变慢了,可是插入数据时只须要记录本项的先后项便可,因此插入速度较快。

        LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList能够被看成堆栈和队列来使用。

 

七、去掉一个Vector集合中重复的元素

Vector newVector = new Vector();

For (int i=0;i<vector.size();i++)

{

Object obj = vector.get(i);

       if(!newVector.contains(obj);

             newVector.add(obj);

}

还有一种简单的方式,利用了Set不容许重复元素:

HashSetset = new HashSet(vector);

八、Collection和Collections的区别。

        Collection是集合类的上级接口,继承他的接口主要有Set和List.

        Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各类集合的搜索、排序、线程安全化等操做。

 

九、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==仍是equals()?它们有何区别?

        Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。

        ==和equal区别也是考烂了的题,这里说一下:

        ==操做符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操做符。

        equals方法是用于比较两个独立对象的内容是否相同,就比如去比较两我的的长相是否相同,它比较的两个对象是独立的。 

        好比:两条new语句建立了两个对象,而后用a/b这两个变量分别指向了其中一个对象,这是两个不一样的对象,它们的首地址是不一样的,即a和b中存储的数值是不相同的,因此,表达式a==b将返回false,而这两个对象中的内容是相同的,因此,表达式a.equals(b)将返回true。


10、你所知道的集合类都有哪些?主要方法?

        最经常使用的集合类是 List 和 Map。 List的具体实现包括 ArrayList和 Vector,它们是可变大小的列表,比较适合构建、存储和操做任何类型对象的元素列表。 List适用于按数值索引访问元素的情形。

        Map 提供了一个更通用的元素存储方法。 Map集合类用于存储元素对(称做"键"和"值"),其中每一个键映射到一个值。

        它们都有增删改查的方法。

        对于set,大概的方法是add,remove, contains等

        对于map,大概的方法就是put,remove,contains等

        List类会有get(int index)这样的方法,由于它能够按顺序取元素,而set类中没有get(int index)这样的方法。List和set均可以迭代出全部元素,迭代时先要获得一个iterator对象,因此,set和list类都有一个iterator方法,用于返回那个iterator对象。map能够返回三个集合,一个是返回全部的key的集合,另一个返回的是全部value的集合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value,这个自由发挥,也不是考记方法的能力,这些编程过程当中会有提示,结合他们三者的不一样说一下用法就行。

1一、String s = new String("xyz");建立了几个StringObject?是否能够继承String类?

        两个或一个都有可能,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”无论出现多少遍,都是缓冲区中的那一个。NewString每写一遍,就建立一个新的对象,它使用常量”xyz”对象的内容来建立出一个新String对象。若是之前就用过’xyz’,那么这里就不会建立”xyz”了,直接从缓冲区拿,这时建立了一个StringObject;但若是之前没有用过"xyz",那么此时就会建立一个对象并放入缓冲区,这种状况它建立两个对象。至于String类是否继承,答案是否认的,由于String默认final修饰,是不可继承的

 

1二、String和StringBuffer的区别

        JAVA平台提供了两个类:String和StringBuffer,它们能够储存和操做字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串能够进行修改。当你知道字符数据要改变的时候你就可使用StringBuffer。典型地,你可使用StringBuffers来动态构造字符数据。

      

1三、下面这条语句一共建立了多少个对象:String s="a"+"b"+"c"+"d";

对于以下代码:

String s1 = "a";

String s2 = s1 + "b";

String s3 = "a" + "b";

System.out.println(s2 == "ab");

System.out.println(s3 == "ab");

第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译能够对字符串常量直接相加的表达式进行优化,没必要要等到运行期再去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。

题目中的第一行代码被编译器在编译时优化后,至关于直接定义了一个”abcd”的字符串,因此,上面的代码应该只建立了一个String对象。写以下两行代码,

 String s ="a" + "b" +"c" + "d";

 System.out.println(s== "abcd");

最终打印的结果应该为true。

1五、final, finally, finalize的区别。 

        final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。内部类要访问局部变量,局部变量必须定义成final类型。

        finally是异常处理语句结构的一部分,表示老是执行。

        finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,能够覆盖此方法提供垃圾收集时的其余资源回收,例如关闭文件等。可是JVM不保证此方法总被调用

 

1六、运行时异常与通常异常有何异同?

        异常表示程序运行过程当中可能出现的非正常状态,运行时异常表示虚拟机的一般操做中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,可是并不要求必须声明抛出未被捕获的运行时异常。

 

1七、error和exception有什么区别?

        error 表示恢复不是不可能但很困难的状况下的一种严重问题。好比说内存溢出。不可能期望程序能处理这样的状况。exception表示一种设计或实现问题。也就是说,它表示若是程序运行正常,从不会发生的状况。

 

1八、简单说说Java中的异常处理机制的简单原理和应用。

        异常是指java程序运行时(非编译)所发生的非正常状况或错误,与现实生活中的事件很类似,现实生活中的事件能够包含事件发生的时间、地点、人物、情节等信息,能够用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每一个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。

        Java对异常进行了分类,不一样类型的异常分别用不一样的Java类表示,全部异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:

        Error和Exception,Error表示应用程序自己没法克服和恢复的一种严重问题,程序只有奔溃了,例如,说内存溢出和线程死锁等系统问题。

        Exception表示程序还可以克服和恢复的问题,其中又分为系统异常和普通异常:

        系统异常是软件自己缺陷所致使的问题,也就是软件开发人员考虑不周所致使的问题,软件使用者没法克服和恢复这种问题,但在这种问题下还可让软件系统继续运行或者让软件挂掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);

        普通异常是运行环境的变化或异常所致使的问题,是用户可以克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不该该死掉。

java为系统异常和普通异常提供了不一样的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,因此普通异常也称为checked异常,而系统异常能够处理也能够不处理,因此,编译器不强制用try..catch处理或用throws声明,因此系统异常也称为unchecked异常。

 

1九、Java 中堆和栈有什么区别?
        JVM 中堆和栈属于不一样的内存区域,使用目的也不一样。栈经常使用于保存方法帧和局部变量,而对象老是在堆上分配。栈一般都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的全部线程共享。

        栈:在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的做用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间能够当即被另做它用。

        堆:堆内存用来存放由 new 建立的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象以后,还能够在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,之后就能够在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就至关因而为数组或者对象起的一个名称。

 

20、能将 int 强制转换为 byte 类型的变量吗?若是该值大于 byte 类型的范围,将会出现什么现象? 
        咱们能够作强制转换,可是 Java 中 int 是 32 位的,而 byte 是 8 位的,因此,若是强制转化,int 类型的高 24 位将会被丢弃,由于byte 类型的范围是从 -128 到 127。


 

 

关注微信公众号回复  Java面试题  便可获取pdf版本!

 

一个良心公众号【IT资源社】:

 

本公众号致力于免费分享全网最优秀的视频资源,学习资料,面试经验等,前端,PHP,JAVA,算法,Python,大数据等等,你想要的这都有

 

IT资源社-QQ交流群:625494093

 

也可添加微信拉你进微信群: super1319164238

 

微信搜索公众号:ITziyuanshe 或者扫描下方二维码直接关注,

 

相关文章
相关标签/搜索