java面试题大全.docx
《java面试题大全.docx》由会员分享,可在线阅读,更多相关《java面试题大全.docx(27页珍藏版)》请在冰点文库上搜索。
java面试题大全
java工程师面试经典题目整理
1、面向对象的特征有哪些方面?
封装:
通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。
多态性:
多态性是指允许不同子类型的对象对同一消息作出不同的响应。
简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。
多态性分为编译时的多态性和运行时的多态性。
方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。
2、访问修饰符public,private,protected,以及不写(默认)时的区别?
作用域 当前类 同包 子类 其他
public √ √ √ √
protected √ √ √ ×
default √ √ × ×
private √ × × ×
类的成员不写访问修饰时默认为default。
默认对于同一个包中的其他类相当于公开(public),对于不是同一个包中的其他类相当于私有(private)。
受保护(protected)对子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。
3、构造器(constructor)是否可被重写(override)?
答:
构造器不能被继承,因此不能被重写,但可以被重载。
4、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
答:
不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。
Java对于eqauls方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
(2)如果两个对象的hashCode相同,它们并不一定相同。
5、抽象类(abstract class)和接口(interface)有什么异同?
答:
抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。
一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进 行实现,否则该类仍然需要被声明为抽象类。
接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其 中的方法全部都是抽象方法。
抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。
抽象 类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。
有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。
抽象类和接口中都可以包含静态成员变量。
6、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?
答:
都不能。
抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。
本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。
synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
7、接口是否可继承(extends)接口?
抽象类是否可实现(implements)接口?
抽象类是否可继承具体类(concrete class)?
答:
接口可以继承接口。
抽象类可以实现(implements)接口,抽象类可继承具体类,但前提是具体类必须有明确的构造函数。
8、Anonymous Inner Class(匿名内部类)是否可以继承其它类?
是否可以实现接口?
答:
可以继承其他类或实现其他接口,在Swing编程中常用此方式来实现事件监听和回调。
9、数据类型之间的转换:
1)如何将字符串转换为基本数据类型?
2)如何将基本数据类型转换为字符串?
1)调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型; Integer.parseInt(a) Integer.valueOf(a)
2)一种方法是将基本数据类型与空字符串(””)连接(+)即可获得其所对应的字符串;另一种方法是调用String 类中的valueOf(…)方法返回相应字符串 String.valueOf(int) Integer.toString
10、如何实现字符串的反转及替换?
答:
方法很多,可以自己写实现也可以使用String或StringBuffer / StringBuilder中的方法。
有一道很常见的面试题是用递归实现字符串反转,代码如下所示:
[java] viewplain copy
1.1.public static String reverse(String originStr) {
2.2. if(originStr == null || originStr.length() <= 1)
3.3. return originStr;
4.4. return reverse(originStr.substring
(1)) + originStr.charAt(0);
5.5. }
11、列出一些你常见的运行时异常?
答:
ClassNotFoundException不能加载所需的类
ioExceptionSQLException
ClassCastException (类转换异常)
IllegalArgumentException (非法参数异常)
IndexOutOfBoundsException (下表越界异常)
NullPointerException (空指针异常)
SecurityException (安全异常)
12、List、Map、Set三个接口存取元素时,各有什么特点?
答:
List以特定索引来存取元素,可以有重复元素。
Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。
Map保存键值对 (key-value pair)映射,映射关系可以是一对一或多对一。
Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为 O
(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。
13、什么是进程,什么是线程?
为什么需要多线程编程?
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的一个独立单位;
线程是进程的一个实体,是CPU调度和分 派的基本单位,是比进程更小的能独立运行的基本单位。
线程的划分尺度小于进程,这使得多线程程序的并发性高;进程在执行时通常拥有独立的内存单元,而线程之间可以共享内存。
使用多线程的编程通常能够带来更好的性能和用户体验,但是多线程的程序对于其他程序是不友好的,因为它占用了更多的CPU资源。
14.阐述JDBC操作数据库的步骤
答:
下面的代码以连接本机的Oracle数据库为例,演示JDBC操作数据库的步骤。
1. 加载驱动。
[java] viewplain copy
1.Class.forName("oracle.jdbc.driver.OracleDriver");
2. 创建连接。
[java] viewplain copy
1.Connection con = DriverManager.getConnection("jdbc:
oracle:
thin:
@localhost:
1521:
orcl", "scott", "tiger");
3. 创建语句。
[java] viewplain copy
1.PreparedStatement ps = con.prepareStatement("select * from emp where sal between ?
and ?
");
2. ps.setInt(1, 1000);
3. ps.setInt(2, 3000);
4. 执行语句。
[java] viewplain copy
1.ResultSet rs = ps.executeQuery();
5. 处理结果。
[java] viewplain copy
1.while(rs.next()) {
2. System.out.println(rs.getInt("empno") + " - " + rs.getString("ename")); }
6. 关闭资源。
[java] viewplain copy
1.finally {
2. if(con !
= null) {
3. try {
4. con.close();
5. } catch (SQLException e) { e.printStackTrace();
6. }
7. }
8. }
15.Statement和PreparedStatement有什么区别?
哪个性能更好?
与Statement相比
①PreparedStatement接口代表预编译的语句,它主要的优势在于可以减少SQL的编译错误并增加SQL的安全性(减少SQL注射攻击的可能性)
②PreparedStatement中的SQL语句是可以带参数的,避免了用字符串连接拼接SQL语句的麻烦和不安全;
③当批量处理SQL或频繁执行相同的查询时,PreparedStatement有明显的性能上的优势,由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快(不用再次编译和生成执行计划)。
16、在进行数据库编程时,连接池有什么作用?
为了提升系统访问数据库的性能,可以事先创建若干连接置于连接池中,需要时直接从连接池获取,使用结束时归还连接池而不必关闭连接,从而避免频繁创建和释放连接所造成的开销,这是典型的用空间换取时间的策略(浪费了空间存储连接,但节省了创建和释放连接的时间)。
池化技术在Java开发中是很常见的,在使用线程时创建线程池的道理与此相同。
18、获得一个类的类对象有哪些方式?
答:
- 方法1:
类型.class,例如:
String.class
- 方法2:
对象.getClass(),例如:
"hello".getClass()
- 方法3:
Class.forName(),例如:
Class.forName("java.lang.String")
21、简述一下面向对象的"六原则一法则"。
答:
1)单一职责原则:
一个类只做它该做的事情。
(单一职责原则想表达的就是"高内聚",写代码最终极的原则只有六个字"高内聚、低耦合")
2)开闭原则:
软件实体应当对扩展开放,对修改关闭。
(在理想的状态下,当我们需要为一个软件系统增加新功能时,只需要从原来的系统派生出一些新类就可以,不需要修改原来的任何一行代码。
要做到开闭有两个要点:
①抽象是关键,一个系统中如果没有抽象类或接口系统就没有扩展点;②封装可变性,将系统中的各种可变因素封装到一个继承结构中,如果多个可变因素混杂在一起,系统将变得复杂而换乱)
3)依赖倒转原则:
面向接口编程。
(该原则说得直白和具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代)
4)里氏替换原则:
任何时候都可以用子类型替换掉父类型。
(子类一定是增加父类的能力而不是减少父类的能力,因为子类比父类的能力更多,把能力多的对象当成能力少的对象来用当然没有任何问题。
)
5)接口隔离原则:
接口要小而专,绝不能大而全。
(臃肿的接口是对接口的污染,既然接口表示能力,那么一个接口只应该描述一种能力,接口也应该是高度内聚的。
Java中的接口代表能力、代表约定、代表角色,能否正确的使用接口一定是编程水平高低的重要标识。
)
6)合成聚合复用原则:
优先使用聚合或合成关系复用代码。
(通过继承来复用代码是面向对象程序设计中被滥用得最多的东西,记住:
任何时候都不要继承工具类,工具是可以拥有并可以使用的,而不是拿来继承的。
)
迪米特法则:
迪米特法则又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。
(迪米特法则简单的说就是如何做到"低耦合",门面模式和调停者模式就是对迪米特法则的践行。
Java Web开发中作为前端控制器的Servlet或Filter不就是一个门面吗,浏览器对服务器的运作方式一无所知,但是通过前端控制器就能够根据你的请求得到相应的服务。
调停者模式也可以举一个简单的例子来说明,例如一台计算机,CPU、内存、硬盘、显卡、声卡各种设备需要相互配合才能很好的工作。
迪米特法则用通俗的话来将就是不要和陌生人打交道,如果真的需要,找一个自己的朋友,让他替你和陌生人打交道。
)
22.简述一下你了解的设计模式
-工厂模式:
工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作(多态方法)。
当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
- 代理模式:
给一个对象提供一个代理对象,并由代理对象控制原对象的引用。
实际开发中,按照使用目的的不同,代理可以分为:
远程代理、虚拟代理、保护代理、Cache代理、防火墙代理、同步化代理、智能引用代理。
- 适配器模式:
把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起使用的类能够一起工作。
- 模板方法模式:
提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。
不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。
23、用Java写一个单例类。
饿汉式单例
[java] viewplain copy
1.public class Singleton {
2. private Singleton(){}
3. private static Singleton instance = new Singleton();
4. public static Singleton getInstance(){ return instance;
5. }
6.}
懒汉式单例
[java] viewplain copy
1.public class Singleton {
2.private Singleton() {}
3. private static Singleton instance = null;
4. public static synchronized Singleton getInstance(){
5. if (instance == null)
6. instance = new Singleton();
7. return instance;
8. }
9.}
注意:
实现一个单例有两点注意事项,①将构造器私有,不允许外界通过构造器创建对象;②通过公开的静态方法向外界返回类的唯一实例。
这里有一个问题可以思考:
spring的IoC容器可以为普通的类创建单例,它是怎么做到的呢?
24.什么是DAO模式?
答:
DAO(DataAccess Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露数据库实现细节的前提下提供了各种数据操作。
将所有对数据源的访问操作进行抽象化后封装在一个公共API中。
在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口,在逻辑上该类对应一个特定的数据存储。
DAO模式实际上包含了两个模式,一是Data Accessor(数据访问器),二是Data Object(数据对象),前者要解决如何访问数据的问题,而后者要解决的是如何用对象封装数据。
25.Servlet的生命周期
Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;请求到达时调用Servlet的service方法,service方法会调用与请求对应的doGet或doPost等方法;当服务器关闭会项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy方法。
26.转发(forward)和重定向(redirect)的区别?
1)forward是容器中控制权的转向,是服务器请求资源,服务器直接访问目标地址的URL,把那个URL 的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
2)redirect就是服务器端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,因此从浏览器的地址栏中可以看到跳转后的链接地址。
3)前者更加高效,在前者可以满足需要时,尽量使用转发(通过RequestDispatcher对象的forward方法,RequestDispatcher对象可以通过ServletRequest对象的getRequestDispatcher方法获得),并且,这样也有助于隐藏实际的链接;在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用重定向(通过HttpServletResponse对象调用其sendRedirect方法)。
27.get和post请求的区别?
①get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
②get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用“?
”连接,而各个变量之间使用“&”连接;post是将表单中的数据放在HTML头部(header),传递到action所指向URL;
③get传输的数据要受到URL长度限制(1024字节);而post可以传输大量的数据,上传文件只能使用post方式;
④使用get时参数会显示在地址栏上,如果这些数据不是敏感数据,那么可以使用get;对于敏感数据还是应用使用post;
28、JSP 和Servlet 有有什么关系?
答:
其实这个问题在上面已经阐述过了,Servlet是一个特殊的Java程序,它运行于服务器的JVM中,能够依靠服务器的支持向浏览器提供显示内容。
JSP本质上是Servlet的一种简易形式, JSP会被服务器处理成一个类似于Servlet的Java程序,可以简化页面内容的生成。
Servlet和JSP最主要的不同点在于,Servlet 的应用逻辑是在Java 文件中,并且完全从表示层中的HTML分离开来。
而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp 的文件(有人说,Servlet就是在Java中写HTML,而JSP就是在HTML中写Java代码,当然,这个说法还是很片面的)。
JSP侧重于视图,Servlet更侧重于控制逻辑,在MVC架构模式中,JSP适合充当视图(view)而Servlet适合充当控制器(controller)。
29、JSP中的四种作用域?
答:
page、request、session和application,具体如下:
①page 代表与一个页面相关的对象和属性。
②request 代表与Web客户机发出的一个请求相关的对象和属性。
一个请求可能跨越多个页面,涉及多个Web 组件;需要在页面显示的临时数据可以置于此作用域
③session代表与某个用户与服务器建立的一次会话相关的对象和属性。
跟某个用户相关的数据应该放在用户自己的session中
④application代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域。
30.实现会话跟踪的技术有哪些?
答:
由于HTTP协议本身是无状态的,服务器为了区分不同的用户,就需要对用户会话进行跟踪,简单的说就是为用户进行登记,为用户分配唯一的ID,下一次用户在请求中包含此ID,服务器据此判断到底是哪一个用户。
①URL 重写:
在URL中添加用户会话的信息作为请求的参数,或者将唯一的会话ID添加到URL结尾以标识一个会话。
②设置表单隐藏域:
将和会话跟踪相关的字段添加到隐式表单域中,这些信息不会在浏览器中显示但是提交表单时会提交给服务器。
③cookie:
cookie当用户通过浏览器和服务器建立一次会话后,会话ID就会随响应信息返回存储在基于窗口的cookie中,那就意味着只要浏览器没有关闭,会话没有超时,下一次请求时这个会话ID又会提交给服务器让服务器识别用户身份。
会话中可以为用户保存信息。
会话对象是在服务器内存中的,而基于窗口的cookie是在客户端内存中的。
④HttpSession:
在所有会话跟踪技术中,HttpSession对象是最强大也是功能最多的。
当一个用户第一次访问某个网站时会自动创建HttpSession,每个用户可以访问他自己的HttpSession。
与上面三种方式不同的是,HttpSession放在服务器的内存中
31.JSP中的静态包含和动态包含有什么区别?
答:
静态包含是通过JSP的include指令包含页面,动态包含是通过JSP标准动作forward>包含页面。
静态包含是编译时包含,如果包含的页面不存在则会产生编译错误,而且两个页面的"contentType"属性应保持一致,因为两个页面会合二为一,只产生一个class文件,因此被包含页面发生的变动再包含它的页面更新前不会得到更新。
动态包含是运行时包含,可以向被包含的页面传递参数,包含页面和被包含页面是独立的,会编译出两个class文件,如果被包含的页面不存在,不会产生编译错误,也不影响页面其他部分的执行。
代码如下所示:
<%-- 静态包含 --%><%@ include file="..." %> <%-- 动态包含 --%>include page="..."> param name="..." value="..." />
include>
32、什么是Web Service(Web服务)?
答:
从表面上看,Web Service就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。
例如可以创建一个提供天气预报的Web Service,那么无论你用哪种编程语言开发的应用都可以通过调用它的API并传入城市信息来获得该城市的天气预报。
补充:
这里必须要提及的一个概念是SOA(Service-Oriented Architecture,面向服务的架构)显然,Web Service是SOA的一种较好的解决方案,它更多的是一种标准,而不是一种具体的技术。
33、hashmap和has