java 面试题 答案(2018年)

1.jvm的理解:

java虚拟机内存分5个部分,程序计数器、java虚拟机栈、本地方法栈、堆、方法区。

程序计数器记录当前代码执行位置,进行代码流程控制,多线程时记录当前线程执行的位置,从而记录线程返回时上一次执行到哪了,程序计数器是一个很小的内存空间,每个线程都有一个程序计数器,随着线程的启动而创建线程的结束而消亡,不会出现OutOfMemoryError。

java虚拟机栈,java虚拟机会为每一个即将运行的方法分配一个叫“栈帧”的区域,记录该方法执行过程中所需要记录的信息(局部变量表、操作数栈、动态链接,方法出口等信息),方法运行时需要创建的局部变量被存放在局部变量表中,当方法执行完后这个这个方法所对应的栈帧将会出栈,释放空间,java虚拟机栈也是随着线程的创建而创建,线程的结束而释放,会出现2中异常:StackOverFlowError和OutOfMemoryError

本地方法栈和java虚拟机栈类似,只不过是用来运行本地方法的内存模型。

堆是用来存放对象的内存空降,几乎所有的对象都存放在堆中,java中堆时内存共享的随着虚拟机的启动而创建,堆是垃圾回收的主要场所,又可以分为新生代和老年代,堆的大小是可以扩展的,但也会抛出OutOfMemoryError。

方法区是堆的一个逻辑部分,存放着已经被虚拟机加载的类的信息、常量、静态变量、编辑后的代码等,方法区是内存共享的,整个虚拟机只有一个方法区,可以看做是堆的老年代,这里回收效率比较低,主要回收目标是对常量池的回收和类型的卸载。

2.java类创建的过程

当虚拟机遇到一个new指令时,检查常量池中是否有该对象所属类的符号引用,如果没有则抛出ClassNotFoundExecption异常,如果有,则检查这个符号所代表的类是否已经被jvm加载,如果没有被加载,则找到该类的class文件并加载进方法区,如果已经加载,则根据方法区信息为该对象在堆中分配一块内存空间指给新的对象。

3.如何判断哪些对象需要回收

引用计数法:每个对象都有一个计数器,当这个对象被引用时计数器加1,不被引用时减1,当这个计数器为0时则认为这个对象时无效对象。

可达性分析法:所有和gc roots(java虚拟机栈所引用的对象、方法区中静态属性和常量应用的对象、本地方法栈所引用的对象)有直接或间接关系的对象认为是有效对象,和gc roots没有关系的对象认为是无效对象。

4.java类实例创建的过程

先父类后子类;父类静态-子类静态-父类初始化块-父类构造方法-子类初始化块-子类构造方法。

5.synchronized与lock的区别

synchronized在同步块执行完成或者发生异常时释放锁,lock必须在finally中释放锁,不然容易死锁;synchronized假如线程A获得锁,线程B线程等待,如果线程A阻塞,则线程B一直等待lock有多种获取锁的方法,B可以不用等待尝试去获取锁;synchronized锁是非公平的,lock可以公平也可以非公平;synchronized适用于少量的代码同步,lock适用于大量的代码同步。

6.反射中,Class.forName和ClassLoader区别

java类加载的过程包括:加载->验证->准备->解析->初始化->使用->卸载,而初始化就是激活java类中静态变量初始化代码和静态代码块,并初始化程序设置的变量值。

Class.forName会执行类的初始化,而ClassLoader不会执行类的初始化。

7.&和&&的区别?

&运算符有两种用法:(1)按位与;(2)逻辑与。&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(“”),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。

8.什么是值传递和引用传递?

值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量. 
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。 
一般认为,java内的传递都是值传递. java中实例对象的传递是引用传递 。

9.是否可以在static环境中访问非static变量?

static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

10.Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?

Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。

11.Java中,什么是构造方法?什么是构造方法重载?什么是复制构造方法?

当新对象被创建的时候,构造方法会被调用。每一个类都有构造方法。在程序员没有给类提供构造方法的情况下,Java编译器会为这个类创建一个默认的构造方法。 
Java中构造方法重载和方法重载很相似。可以为一个类创建多个构造方法。每一个构造方法必须有它自己唯一的参数列表。 
Java不支持像C++中那样的复制构造方法,这个不同点是因为如果你不自己写构造方法的情况下,Java不会创建默认的复制构造方法。

12.Java支持多继承么?

Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。 但是java中的接口支持多继承,,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。

13.解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;而通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。

14.接口和抽象类的区别是什么?

从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。 
Java提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于: 
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。 
类可以实现很多个接口,但是只能继承一个抽象类 
类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。 
抽象类可以在不提供接口方法实现的情况下实现接口。 
Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。 
Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。 
接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。 
也可以参考JDK8中抽象类和接口的区别。

15.用最有效率的方法计算2乘以8?

答: 2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。

16.手写单例模式(饿汉和饱汉模式)和工厂模式?

(1)单例饿汉模式://饿汉式单例类.在类初始化时,已经自行实例化 
2 public class Singleton1 { 
3 //私有的默认构造子 
4 private Singleton1() {} 
5 //已经自行实例化 
6 private static final Singleton1 single = new Singleton1(); 
7 //静态工厂方法 
8 public static Singleton1 getInstance() { 
9 return single; 
10 } 
11 }

(2)懒汉模式://懒汉式单例类.在第一次调用的时候实例化 
2 public class Singleton2 { 
3 //私有的默认构造子 
4 private Singleton2() {} 
5 //注意,这里没有final 
6 private static Singleton2 single=null; 
7 //静态工厂方法 
8 public synchronized static Singleton2 getInstance() { 
9 if (single == null) { 
10 single = new Singleton2(); 
11 } 
12 return single; 
13 } 
14 }

(3)工厂模式: 
interface IFactory{ 
public IProduct createProduct();} 
Class Factory implements IFactory{ 
public IProduct createProduct(){return new Product();}} 
Public class client{ 
Public Static void main (String [] args){IFactory factory=new Factory(); 
IProduct product=factory.createProduct(); 
product.ProductMethod();}}

17.String和StringBuilder、StringBuffer的区别?

Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,它们可以储存和操作字符串。其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的。而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer要高。
--------------------- 
来源:java面试题网http://www.wityx.com/

猜你喜欢

转载自blog.csdn.net/u011269762/article/details/84974884