100+经典Java⾯试题及答案解析
⾯向对象编程(OOP)
Java是⼀个⽀持并发、基于类和⾯向对象的计算机编程语⾔。下⾯列出了⾯向对象软件开发的优点:
代码开发模块化,更易维护和修改。
代码复⽤。
增强代码的可靠性和灵活性。
增加代码的可理解性。
⾯向对象编程有很多重要的特性,⽐如:封装,继承,多态和抽象。下⾯的章节我们会逐个分析这些特性。
封装
封装给对象提供了隐藏内部特性和⾏为的能⼒。对象提供⼀些能被其他对象访问的⽅法来改变它内部的数据。在Java当中,有3种修饰符:public,private和protected。每⼀种修饰符给其他的位于同⼀个包或
者不同包下⾯对象赋予了不同的访问权限。
下⾯列出了使⽤封装的⼀些好处:参考文献上哪找
通过隐藏对象的属性来保护对象内部的状态。
提⾼了代码的可⽤性和可维护性,因为对象的⾏为可以被单独的改变或者是扩展。
禁⽌对象之间的不良交互提⾼模块化。
参考这个⽂档获取更多关于封装的细节和⽰例。
多态
多态是编程语⾔给不同的底层数据类型做相同的接⼝展⽰的⼀种能⼒。⼀个多态类型上的操作可以应⽤到其他类型的值上⾯。
继承
继承给对象提供了从基类获取字段和⽅法的能⼒。继承提供了代码的重⽤⾏,也可以在不修改类的情况下给现存的类添加新特性。
抽象
抽象是把想法从具体的实例中分离出来的步骤,因此,要根据他们的功能⽽不是实现细节来创建类。Java⽀持创建只暴漏接⼝⽽不包含⽅法实现的抽象的类。这种抽象技术的主要⽬的是把类的⾏为和实现细节分离开。
抽象和封装的不同点
抽象和封装是互补的概念。⼀⽅⾯,抽象关注对象的⾏为。另⼀⽅⾯,封装关注对象⾏为的细节。⼀般是通过隐藏对象内部状态信息做到封
情侣主装,因此,封装可以看成是⽤来提供抽象的⼀种策略。
常见的Java问题
1.什么是Java虚拟机?为什么Java被称作是“平台⽆关的编程语⾔”?
Java虚拟机是⼀个可以执⾏Java字节码的虚拟机进程。Java源⽂件被编译成能被Java虚拟机执⾏的字节码⽂件。
Java被设计成允许应⽤程序可以运⾏在任意的平台,⽽不需要程序员为每⼀个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。
2.JDK和JRE的区别是什么?
Java运⾏时环境(JRE)是将要执⾏Java程序的Java虚拟机。它同时也包含了执⾏applet需要的浏览器插件。Java开发⼯具包(JDK)是完整的Java软件开发包,包含了JRE,编译器和其他的⼯具(⽐如:JavaDoc,Java调试器),可以让开发者开发、编译、执⾏Java应⽤程序。3.”static”关键字是什么意思?Java中是否可以覆盖(override)⼀个private或者是static的⽅法?
“static”关键字表明⼀个成员变量或者是成员⽅法可以在没有所属的类的实例变量的情况下被访问。
Java中static⽅法不能被覆盖,因为⽅法覆盖是基于运⾏时动态绑定的,⽽static⽅法是编译时静态绑定的。static⽅法跟类的任何实例都不相关,所以概念上不适⽤。
4.是否可以在static环境中访问⾮static变量?
static变量在Java中是属于类的,它在所有的实例中的值是⼀样的。当类被Java虚拟机载⼊的时候,会对static变量进⾏初始化。如果你的代码尝试不⽤实例来访问⾮static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。
5.Java⽀持的数据类型有哪些?什么是⾃动拆装箱?
Java语⾔⽀持的8中基本数据类型是:
byte
小虾的做法
short
int
long
永胜城float
double
boolean
char
⾃动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的⼀个转化。⽐如:把int转化成Integer,double转化成double,等等。反之就是⾃动拆箱。
6.Java中的⽅法覆盖(Overriding)和⽅法重载(Overloading)是什么意思?
Java中的⽅法重载发⽣在同⼀个类⾥⾯两个或者是多个⽅法的⽅法名相同但是参数不同的情况。与此相对,⽅法覆盖是说⼦类重新定义了⽗类的⽅法。⽅法覆盖必须有相同的⽅法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的⽅法的访问。
7.Java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?
当新对象被创建的时候,构造函数会被调⽤。每⼀个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建⼀个默认的构造函数。
Java中构造函数重载和⽅法重载很相似。可以为⼀个类创建多个构造函数。每⼀个构造函数必须有它⾃⼰唯⼀的参数列表。
Java不⽀持像C++中那样的复制构造函数,这个不同点是因为如果你不⾃⼰写构造函数的情况下,Java不会创建默认的复制构造函数。8.Java⽀持多继承么?
不⽀持,Java不⽀持多继承。每个类都只能继承⼀个类,但是可以实现多个接⼝。
9.接⼝和抽象类的区别是什么?
Java提供和⽀持创建抽象类和接⼝。它们的实现有共同点,不同点在于:
接⼝中所有的⽅法隐含的都是抽象的。⽽抽象类则可以同时包含抽象和⾮抽象的⽅法。
类可以实现很多个接⼝,但是只能继承⼀个抽象类
类如果要实现⼀个接⼝,它必须要实现接⼝声明的所有⽅法。但是,类可以不实现抽象类声明的所有⽅法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接⼝⽅法实现的情况下实现接⼝。
Java接⼝中声明的变量默认都是final的。抽象类可以包含⾮final的变量。皈依是什么意思
Java接⼝中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
接⼝是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main⽅法的话是可以被调⽤的。
也可以参考JDK8中抽象类和接⼝的区别
10.什么是值传递和引⽤传递?
对象被值传递,意味着传递了对象的⼀个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引⽤传递,意味着传递的并不是实际的对象,⽽是对象的引⽤。因此,外部对引⽤对象所做的改变会反映到所有的对象上。
Java线程
11.进程和线程的区别是什么?于永波
进程是执⾏着的应⽤程序,⽽线程是进程内部的⼀个执⾏序列。⼀个进程可以有多个线程。线程⼜叫做轻量级进程。
12.创建线程有⼏种不同的⽅式?你喜欢哪⼀种?为什么?
有三种⽅式可以⽤来创建线程:
继承Thread类
实现Runnable接⼝
应⽤程序可以使⽤Executor框架来创建线程池
实现Runnable接⼝这种⽅式更受欢迎,因为这不需要继承Thread类。在应⽤设计中已经继承了别的对象的情况下,这需要多继承(⽽Java 不⽀持多继承),只能实现接⼝。同时,线程池也是⾮常⾼效的,很容易实现和使⽤。
13.概括的解释下线程的⼏种可⽤状态。
线程在执⾏过程中,可以处于下⾯⼏种状态:
就绪(Runnable):线程准备运⾏,不⼀定⽴马就能开始执⾏。
运⾏中(Running):进程正在执⾏线程的代码。
等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。
睡眠中(Sleeping):线程被强制睡眠。
I/O阻塞(Blocked on I/O):等待I/O操作完成。
同步阻塞(Blocked on Synchronization):等待获取锁。
大快人心
死亡(Dead):线程完成了执⾏。
14.同步⽅法和同步代码块的区别是什么?
在Java语⾔中,每⼀个对象有⼀把锁。线程可以使⽤synchronized关键字来获取对象上的锁。synchronized关键字可应⽤在⽅法级别(粗粒度锁)或者是代码块级别(细粒度锁)。
15.在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?
监视器和锁在Java虚拟机中是⼀块使⽤的。监视器监视⼀块同步代码块,确保⼀次只有⼀个线程执⾏同步代码块。每⼀个监视器都和⼀个对象引⽤相关联。线程在获取锁之前不允许执⾏同步代码。
16.什么是死锁(deadlock)?
两个进程都在等待对⽅执⾏完毕才能继续往下执⾏的时候就发⽣了死锁。结果就是两个进程都陷⼊了⽆限的等待中。
17.如何确保N个线程可以访问N个资源同时⼜不导致死锁?
使⽤多线程的时候,⼀种⾮常简单的避免死锁的⽅式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。
Java集合类
18.Java集合类框架的基本接⼝有哪些?
集合类接⼝指定了⼀组叫做元素的对象。集合类接⼝的每⼀种具体的实现类都可以选择以它⾃⼰的⽅式对元素进⾏保存和排序。有的集合类允许重复的键,有些不允许。
口腔溃疡吃什么
Java集合类提供了⼀套设计良好的⽀持对⼀组对象进⾏操作的接⼝和类。Java集合类⾥⾯最基本的接⼝有:
Collection:代表⼀组对象,每⼀个对象都是它的⼦元素。
Set:不包含重复元素的Collection。
List:有顺序的collection,并且可以包含重复元素。
Map:可以把键(key)映射到值(value)的对象,键不能重复。
19.为什么集合类没有实现Cloneable和Serializable接⼝?
克隆(cloning)或者是序列化(rialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类
的具体实现来决定如何被克隆或者是序列化。
20.什么是迭代器(Iterator)?
Iterator接⼝提供了很多对集合元素进⾏迭代的⽅法。每⼀个集合类都包含了可以返回迭代器实例的
迭代⽅法。迭代器可以在迭代的过程中删除底层集合的元素。
21.Iterator和ListIterator的区别是什么?
下⾯列出了他们的区别:
Iterator可⽤来遍历Set和List集合,但是ListIterator只能⽤来遍历List。
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
ListIterator实现了Iterator接⼝,并包含其他的功能,⽐如:增加元素,替换元素,获取前⼀个和后⼀个元素的索引,等等。
22.快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?