Java面试宝典基础篇.docx
《Java面试宝典基础篇.docx》由会员分享,可在线阅读,更多相关《Java面试宝典基础篇.docx(37页珍藏版)》请在冰豆网上搜索。
Java面试宝典基础篇
Java面试宝典(基础篇)
1.java基础
1.Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?
重写和重载的区别?
答:
Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。
与此相对,方法覆盖是说子类重新定义了父类的方法。
方法覆盖必须有相同的方法名,参数列表和返回类型。
覆盖者可能不会限制它所覆盖的方法的访问。
重载(Overloading)
(1)方法重载是让类以统一的方式处理不同类型数据的一种手段。
多个同名函数同时存在,具有不同的参数个数/类型。
重载Overloading是一个类中多态性的一种表现。
(2)Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。
调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法,这就是多态性。
(3)重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。
无法以返回型别作为重载函数的区分标准。
重写(Overriding)
(1)父类与子类之间的多态性,对父类的函数进行重新定义。
如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。
在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。
但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。
方法重写又称方法覆盖。
(2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。
如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
(3)子类函数的访问修饰权限不能少于父类的;
2.Java中,什么是构造函数?
什么是构造函数重载?
什么是复制构造函数?
答:
当新对象被创建的时候,构造函数会被调用。
每一个类都有构造函数。
在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数。
Java中构造函数重载和方法重载很相似。
可以为一个类创建多个构造函数。
每一个构造函数必须有它自己唯一的参数列表。
Java不支持像C++中那样的复制构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java不会创建默认的复制构造函数。
3.Java支持多继承么?
答:
Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。
但是java中的接口支持多继承,,即一个子接口可以有多个父接口。
(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。
4.接口和抽象类的区别是什么?
答:
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。
接口中的方法定义默认为publicabstract类型,接口中的成员变量类型默认为publicstaticfinal(这里需要说一点,既然一个变量被final修饰了,那么这个变量就是一个常量!
!
!
!
!
变量必须初始化成常量!
!
!
!
!
)
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量!
!
!
!
!
!
!
(注意重点在普通即非静态 和 变量!
!
!
!
)
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4.抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为publicabstract类型。
5.抽象类中可以包含静态方法(static),接口中不能包含静态方法.
6.抽象类和接口中都可以包含静态成员变量(static),抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是publicstaticfinal类型,并且默认即为publicstaticfinal类型。
7.一个类可以实现多个接口,但只能继承一个抽象类。
何时用接口,何时用抽象类?
子类继承抽象类就不能再继承其他类(java的单继承原则),所以有抽象方法时优先使用接口定义.
如果所有方法都没有实现,优先使用接口.
一些方法已经可以实现,而另一些方法无法或不想实现时,且继承(实现)关系很简单时,考虑用抽象类定义,留给后代去实现。
jdk8之后,也可以在接口中定义default方法或static方法来实现.
5.什么是值传递和引用传递?
答:
值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象本身。
所以对引用对象进行操作会同时改变原对象.
一般认为,java内的传递都是值传递.
6.创建线程有几种不同的方式?
你喜欢哪一种?
为什么?
答:
有两种方式可以用来创建线程:
继承Thread类
实现Runnable接口
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。
在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。
同时,线程池也是非常高效的,很容易实现和使用。
7.概括的解释下线程的几种可用状态。
答:
1.新建(new):
新创建了一个线程对象。
2.可运行(runnable):
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。
该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu的使用权。
3.运行(running):
可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。
4.阻塞(block):
阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cputimeslice,暂时停止运行。
直到线程进入可运行(runnable)状态,才有机会再次获得cputimeslice转到运行(running)状态。
阻塞的情况分三种:
(一).等待阻塞:
运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waittingqueue)中。
(二).同步阻塞:
运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lockpool)中。
(三).其他阻塞:
运行(running)的线程执行Thread.sleep(longms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。
当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
5.死亡(dead):
线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。
死亡的线程不可再次复生。
8.同步方法和同步代码块的区别是什么?
答:
区别:
同步方法默认用this或者当前类class对象作为锁;
同步代码块可以选择以什么来加锁,比同步方法要更细颗粒度,我们可以选择只同步会发生同步问题的部分代码而不是整个方法;
9.什么是死锁(deadlock)?
如何确保N个线程可以访问N个资源同时又不导致死锁?
答:
两个线程或两个以上线程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。
结果就是这些线程都陷入了无限的等待中.
使用多线程的时候,一种非常简单的避免死锁的方式就是:
指定获取锁的顺序,并强制线程按照指定的顺序获取锁。
因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。
10.Java集合类框架的基本接口有哪些?
答:
集合类接口指定了一组叫做元素的对象。
集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序。
有的集合类允许重复的键,有些不允许。
Java集合类提供了一套设计良好的支持对一组对象进行操作的接口和类。
Java集合类里面最基本的接口有:
Collection:
代表一组对象,每一个对象都是它的子元素。
Set:
不包含重复元素的Collection。
List:
有顺序的collection,并且可以包含重复元素。
Map:
可以把键(key)映射到值(value)的对象,键不能重复。
11.什么是迭代器(Iterator)?
答:
Iterator接口提供了很多对集合元素进行迭代的方法。
每一个集合类都包含了可以返回迭代器实例的
迭代方法。
迭代器可以在迭代的过程中删除底层集合的元素,但是不可以直接调用集合的
remove(ObjectObj)删除,可以通过迭代器的remove()方法删除。
12.数组(Array)和列表(ArrayList)有什么区别?
什么时候应该使用Array而不是ArrayList?
答:
下面列出了Array和ArrayList的不同点:
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:
addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。
但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢
13.ArrayList和LinkedList有什么区别?
答:
ArrayList和LinkedList都实现了List接口,他们有以下的不同点:
ArrayList是基于索引的数据接口,它的底层是数组。
它可以以O
(1)时间复杂度对元素进行随机访问。
与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
14.HashSet和TreeSet有什么区别?
答:
HashSet是由一个hash表来实现的,因此,它的元素是无序的。
add(),remove(),contains()方法的时间复杂度是O
(1)。
另一方面,TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。
因此,add(),remove(),contains()方法的时间复杂度是O(logn)。
15.Java中的两种异常类型是什么?
他们有什么区别?
答:
Java中有两种异常:
受检查的(checked)异常和不受检查的(unchecked)异常。
不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面。
相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。
这里有Java异常处理的一些小建议。
16.Java中Exception和Error有什么区别?
答:
Exception和Error都是Throwable的子类。
Exception用于用户程序可以捕获的异常情况。
Er