Java面试题集合

来源:互联网 发布:手机开启数据 没有网络 编辑:程序博客网 时间:2024/05/18 02:01

本文版权归笨的无奈和csdn所有,转载请标明出处。


回答java面试题的要点:言辞准确,尽量举例说明。——马士兵老师语。


1.  面向对象的特征。

a)  抽象:(面试的时候这个可以不答,但是底下三个一定要答到)

抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

b) 继承:

继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。

c) 封装:

封装是把过程和数据包围起来(和抽象的概念是类似的),对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。

d) 多态性:

多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

 

引申:

1)  (由多态想到的)向上转型

对象既可以作为它自己本身的类型使用,也可以作为它的基类类型使用。而这种把对某个对象的引用视为对其基类类型的引用的做法称为向上转型。——《java编程思想》第4版,第八章,p148.

2)  java动态绑定

 i.     Java中除了static方法和final方法private方法属于final方法)之外,其他所有的方法都是动态绑定。所以,我们不必判定是否应该进行后期绑定——它会自动发生。——《java编程思想》第4版,第八章,p151

 ii.     域和静态方法没有多态的特性,只有普通(非private和final)方法才有多态的特性。

3)重写(override)和重载(overload)的区别

如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。


2.  int 和 Integer 有什么区别

Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。


3.String 和StringBuffer的区别

String类提供了数值不可改变的字符串。而StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。

 

4.        异常的分类


java所有的异常类都继承于Throwable接口Throwable接口分为Error类Exception类。其中Error类为系统不能够处理的异常。Exception类为系统可以处理的异常。

Exception中,又分为RuntimeException其它的Exception。其中RuntimeException是系统在运行过程中出现的异常,可以捕获(catch)也可以不捕获,用户可以对它进行处理,也可以不做处理。除了RuntimeException之外的异常都需要进行捕获处理

 

5.        Servlet的生命周期

a)       加载 ClassLoader

b)       实例化 new (至始至终只会有一个对象)

c)        初始化 init(ServletConfig) (只执行一次, 第一次初始化的时候)

d)       处理请求 service doGet doPost

e)        退出服务 destroy()

 

6.        几种容器类的区别(ArrayList,LinkList, HashMap,LinkHashMap, TreeMap,

HashSet, TreeSet,  LinkHashSet等)

(答案略)

 

7.        Collection 和 Collections的区别。

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

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

 

8.        HashMap和Hashtable的区别。

HashMapHashtable的轻量级实现(非线程安全的实现,并且HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。

 

9.        final, finally, finalize的区别。

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承(很经典的一句话)

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

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

 

10.    sleep() 和 wait() 有什么区别?

sleep线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持(不解锁),到时后会自动恢复。调用sleep不会释放对象锁。

waitObject类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

 

11.    同步和异步的区别。

(同步和异步的概念,是对于请求者和响应者来说的。如果请求者和响应者需要同时进行通信或者对话,这个就是同步。如果请求者发送请求后,不需要在同时的情况下得到响应者的回答,这个就是异步。)

同步:发送一个请求,等待返回,然后再发送下一个请求

异步:发送一个请求,不等待返回,随时可以再发送下一个请求

同步和异步最大的区别就在于。一个需要等待,一个不需要等待。比如广播,就是一个异步例子。发起者不关心接收者的状态。不需要等待接收者的返回信息电话,就是一个同步例子。发起者需要等待接收者,接通电话后,通信才开始。需要等待接收者的返回信息

同步可以避免出现死锁,读脏数据的发生,一般共享某一资源的时候用,如果每个人都有修改权限,同时修改一个文件,有可能使一个人读取另一个人已经删除的内容,就会出错,同步就会按顺序来修改。

异步则是可以提高效率了,现在cpu都是双核,四核,异步处理的话可以同时做多项工作,当然必须保证是可以并发处理的。

这些都是对的。

12.    abstract class和interface有什么区别?

一、从语法定义层面看abstractclass和interface

  使用abstractclass的方式定义Demo抽象类的方式如下:

  abstract class Demo

abstract void method1();

abstract void method2();

  …

  }

  使用interface的方式定义Demo抽象类的方式如下:

  interface Demo {

void method1();

void method2();

  …

}

abstract class方式中,Demo可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。(需要好好理解这句话)从某种意义上说,interface是一种特殊形式的abstract class。

 

二、从编程层面看abstractclass和interface 

  首先,abstract class在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface(抽象类只能“单继承”,接口却可以实现“多继承”(不是严格意义上的多继承))

其次,abstract class的定义中,我们可以赋予方法的默认行为。但是在interface的定义中,方法却不能拥有默认行为.

三、从设计理念层面看abstract class和interface

考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:

 

使用abstract class方式定义Door:

abstract class Door {

abstract void open();

abstract void close()

}

使用interface方式定义Door:

interface Door {

void open();

void close();

}

其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。

如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢?下面将罗列出可能的解决方案,并从设计理念层面对这些不同的方案进行分析。

解决方案一:

简单的在Door的定义中增加一个alarm方法,如下:

abstract class Door {

abstract void open();

abstract void close()

abstract void alarm();

}

或者

interface Door {

void open();

void close();

void alarm();

}

那么具有报警功能的AlarmDoor的定义方式如下:

class AlarmDoor extends Door {

void open() { … }

void close() { … }

void alarm() { … }

}

或者

class AlarmDoor implements Door

void open() { … }

void close() { … }

void alarm() { … }

这种方法违反了面向对象设计中的一个核心原则ISP(InterfaceSegregation Priciple),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变,反之依然。

 

解决方案二:

既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它们分别定义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用abstract class方式定义;两个概念都使用interface方式定义;一个概念使用abstract class方式定义,另一个概念使用interface方式定义。

显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。

如果两个概念都使用interface方式来定义,那么就反映出两个问题:1、我们可能没有理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分析发现AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用interface方式定义)反映不出上述含义。

如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is a"关系。所以对于Door这个概念,我们应该使用abstarctclass方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。如下所示:

 

abstract class Door {

abstract void open();

abstract void close()

}

 

interface Alarm {

void alarm();

}

 

class AlarmDoor extends Doorimplements Alarm {

void open() { … }

void close() { … }

void alarm() { … }

}

 

这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其实abstractclass表示的是"is a"关系,interface表示的是"likea"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。

具体可以参见这篇文章http://www.enet.com.cn/article/2007/1126/A20071126923475.shtml

里面关于dooralarmalarmdoor分析得挺好的。

13.    sendredirect和forward的区别

Sendredirect

Forward

是不同的request

虽然是不同的对象,但是,可以取到上一个页面的内容

速度慢

速度快

需要到客户端的往返,可以转到任何页面,

服务器内部转换,

地址栏有变化

地址栏没有变化

 

14.    %@include和jsp:include的区别

<%@ include file="date.jsp" %>

<jsp:include page="date.jsp" flush="true"/>

include编译指令是在JSP程序的转换时期就将file属性所指定的程序内容嵌入,然后再编译执行;(静态编译)

而include指令在转换时期是不会被编译的,只有在客户端请求时期如果被执行到才会被动态的编译载入(动态编译)

只生成一个class文件

多个

Include不能带参数

 

<jsp:include>可以

 

同一个request对象

不同的request对象,可以取得包含它的页面的参数,并添加了自己的参数

15.    *(不是很重要)说出数据连接池的工作机制是什么?

J2EE 服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量由配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。

16.    ==与equals()的区别

对于基本类型而言,==和equal都是比较基本类型的值。对于封装类型而言,==是比较两个对象的引用地址是否相等(也就是对象引用的“值”是否相等),而equal是比较两个对象内容是否相等。比如string,==比较两个string是否存储在同一个位置,而equal则是比较两个string是否相等。而对于stringbuffer来说,因为没有重写equal方法,所以equal在stringbuffer中也是比较两个对象的地址是否是同一个值。

17.     写一个Singleton出来。

第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。

public class Singleton {

private Singleton(){}

//在自己内部定义自己一个实例,是不是很奇怪?

//注意这是private只供内部调用

private static Singleton instance= new Singleton();

//这里提供了一个供外部访问本class的静态方法,可以直接访问  

public static SingletongetInstance() {

return instance;

}

}

第二种形式:

public class Singleton {

private static Singleton instance= null;

public static synchronizedSingleton getInstance() {

//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次    

//使用时生成实例,提高了效率!

if (instance==null)

instancenew Singleton();

return instance; }

}

一般认为第一种形式要更加安全些

18.    JSP的内置对象及方法

a)        request表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法。

b)       response表示HttpServletResponse对象,并提供了几个用于设置送回浏览器的响应的方法(如cookies,头信息等)

c)        out对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。

d)       session对象表示目前个别用户的会话状态,用来识别每个用户。

e)        pageContext对象存储本JSP页面相关信息,如属性、内建对象等。

f)        application主要功用在于取得或更改Servlet的设定。

g)       config对象用来存放Servlet初始的配置信息。

h)       exception对象

i)         page对象代表JSP对象本身,或者说代表编译后的servlet对象,可以用( (javax.servlet.jsp.HttpJspPage)page )来取用它的方法和属性。

其它具体可以参照这里JSP九大内置对象

19.    cookie和session的区别

Cookie

session

存储在客户端

存储在服务器端

两种类型

l  有生命周期

l  无生命周期

两种实现方式

l  依赖于cookie

l  url重写

不可靠

可靠

 

20.    JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么?

JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是JavaHTML可以组合成一个扩展名为.jsp的文件JSP侧重于视图,Servlet主要用于控制逻辑。

21.    简述synchronized和java.util.concurrent.locks.Lock的异同

l  主要相同点:Lock能完成synchronized所实现的所有功能

l  主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。

22.    throws,throw,try,catch,finally

(答案略)

23.    MVC的各个部分都有那些技术来实现?如何实现?

MVC (Model View Controller)本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器。使用MVC的目的是将M和V实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据你可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

(具体可以参见百度百科MVC词条

24.    stop()和suspend()方法为何不推荐使用

不使用stop()是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。

25.    垃圾回收器的基本原理是什么?并考虑2种回收机制

Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。

需要注意的是:垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身。70%以上的人回答的含义是回收对象,实际上这是不正确的。

System.gc()

Runtime.getRuntime().gc() 

上面的方法调用时用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。

(具体可以参考全面分析Java的垃圾回收机制)

      

26.    什么是java序列化

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

27.    jsp有哪些动作

jsp有六个基本动作:

jsp:include:在页面被请求的时候引入一个文件。

jsp:useBean:寻找或者实例化一个JavaBean。

jsp:setProperty:设置JavaBean的属性。

jsp:getProperty:输出某个JavaBean的属性。

jsp:forward:把请求转到一个新的页面。

jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。

28.    线程和进程的区别

(1)地址空间:线程是进程内的一个执行单元;进程至少有一个线程;线程之间共享进程的地址空间;而进程有自己独立的地址空间;

(2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源

(3)线程是处理器调度的基本单位,但进程不是.

(4)二者均可并发执行.但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

原创粉丝点击