1、(Java)程序员面试-12 及答案解析(总分:100.00,做题时间:90 分钟)一、论述题(总题数:26,分数:100.00)1.什么是守护线程 (分数:4.00)_2.join()方法的作用是什么 (分数:4.00)_3.如何通过 JDBC 访问数据库 (分数:4.00)_4.JDBC 处理事务采用什么方法 (分数:4.00)_5.Class.forName 的作用是什么 (分数:4.00)_6.Statement、PreparedStatement 和 CallableStatement 有什么区别 (分数:4.00)_7.getString()方法与 getObject()方法有什么
2、区别 (分数:4.00)_8.使用 JDBC 时需要注意哪些问题 (分数:4.00)_9.什么是 JDO (分数:4.00)_10.JDBC 与 Hibernate 有什么区别 (分数:4.00)_11.页面请求的工作流程是怎样的 (分数:4.00)_12.HTTP 中 GET 与 POST 方法有什么区别 (分数:4.00)_13.什么是 Servlet (分数:4.00)_14.doPost()方法与 doGet()方法怎么选择 (分数:4.00)_15.什么是 Servlet 的生命周期 (分数:4.00)_16.JSP 有哪些优点 (分数:4.00)_17.JSP 与 Servlet
3、有何异同 (分数:4.00)_18.如何使用 JSP 与 Servlet 实现 MVC 模型 (分数:4.00)_19.Servlet 中 forward 和 redirect 有什么区别 (分数:4.00)_20.JSP 的内置对象有哪些 (分数:4.00)_21.request 对象主要有哪些方法 (分数:4.00)_22.JSP 有哪些动作 (分数:4.00)_23.JSP 中 include 指令和 include 动作有什么区别 (分数:3.00)_24.会话跟踪技术有哪些 (分数:3.00)_25.Web 开发中如何指定字符串的编码 (分数:3.00)_26.什么是 Ajax (分
4、数:3.00)_(Java)程序员面试-12 答案解析(总分:100.00,做题时间:90 分钟)一、论述题(总题数:26,分数:100.00)1.什么是守护线程 (分数:4.00)_正确答案:()解析:Java 提供了两种线程:守护线程与用户线程。守护线程又被称为“服务进程”“精灵线程”或“后台线程”,是指在程序运行时在后台提供一种通用服务的线程,这种线程并不属于程序中不可或缺的部分。通俗点讲,任何一个守护线程都是整个 JVM 中所有非守护线程的“保姆”。 用户线程和守护线程几乎一样,唯一的不同之处就在于如果用户线程已经全部退出运行,只剩下守护线程存在了,JVM 也就退出了。因为当所有非守护
5、线程结束时,没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了,程序也就终止了,同时会“杀死”所有守护线程。也就是说,只要有任何非守护线程还在运行,程序就不会终止。 在 Java 语言中,守护线程一般具有较低的优先级,它并非只由 JVM 内部提供,用户在编写程序时也可以自己设置守护线程,例如,将一个用户线程设置为守护线程的方法就是在调用 start()方法启动线程之前调用对象的 setDaemon(true)方法,若将以上参数设置为 false,则表示的是用户进程模式。需要注意的是,当在一个守护线程中产生了其他线程,那么这些新产生的线程默认还是守护线程,用户线程也是如此,
6、示例如下: class ThreadDemo extends Thread public void run() System.out.println(Thread.currentThread().getName()+“:begin“); try Thread.sleep(1000); catch(InterruptedException e) e.printStaekTrace(); System.out.println(Thread.currentThread().getName()+“:end“); public class Test public static void main(str
7、ingargs) System.out.println(“test3:begin“); Thread t1=new ThreadDemo(); t1.setDaemon(true); t1.start(); System.out.println(“test3:end“); 程序运行结果为: test3:begin test3:end Thread-0:begin 从运行结果中可以发现,没有输出 Thread-0:end。之所以结果是这样,是在启动线程前将其设置为守护线程了,当程序中只有守护线程存在时,JVM 是可以退出的,也就是说,当 JVM 中只有守护线程运行时,JVM 会自动关闭。因此,当
8、 test3 方法调用结束后,。main 线程将退出,此时线程 t1 还处于休眠状态没有运行结束,但是由于此时只有这个守护线程在运行,JVM 将会关闭,因此不会输出“Thread-0:end”。 守护线程的一个典型的例子就是垃圾回收器。只要 JVM 启动,它始终在运行,实时监控和管理系统中可以被回收的资源。 常见笔试题: 1Java 的 Daemon 线程,setDaemon 设置必须要_。 A在调用 start()方法之前 B调用在 start()方法之后 C前后都可以 答案:A。见上面讲解。 2关于守护线程的说法,正确的是_。 A所有非守护线程终止,即使存在守护线程,进程运行终止 B所有守
9、护线程终止,即使存在非守护线程,进程运行终止 C只要有守护线程或者非守护进程其中之一存在,进程就不会终止 D只要所有守护线程和非守护线程终止运行之后,进程才会终止 答案:A。见上面讲解。2.join()方法的作用是什么 (分数:4.00)_正确答案:()解析:在 Java 语言中,join()方法的作用是让调用该方法的线程在执行完 run()方法后,再执行 join 方法后面的代码。简单点说,就是将两个线程合并,用于实现同步功能。具体而言,可以通过线程 A 的join()方法来等待线程 A 的结束,或者使用线程 A 的 join(2000)方法来等待线程 A 的结束,但最多只等待 2s,示例如
10、下: public class JoinTest public static void main(Stringargs) Thread t=new Thread(new ThreadImp(); t.start(); tfy t.join(1000); /主线程等待 t 结束,只等 1 秒 if(t.isAlive()/t 已经结束 System.out.println(“t has not finished“); else System.out.println(“t has finished“); System.out.println(“joinFinish“); catch(Interru
11、ptedException e) e.printStackTrace(); class ThreadImp implements Runnable public void run() try System.out.println(“Begin ThreadImp“); Thread.sleep(5000); System.out.println(“End ThreadImp“); catch(InterruptedException e) e.printStackTrace(); 程序运行结果为: Begin ThreadImp t has not finished joinFinish En
12、d ThreadImp3.如何通过 JDBC 访问数据库 (分数:4.00)_正确答案:()解析:Java 数据库连接(Java DataBase Connectivity,JDBC)用于在 Java 程序中实现数据库操作功能,它提供了执行 SQL 语句、访问各种数据库的方法,并为各种不同的数据库提供统一的操作接口,java.sql包中包含了 JDBC 操作数据库的所有类。通过 JDBC 访问数据库一般有如下几个步骤: 1)加载 JDBC 驱动器。将数据库的 JDBC 驱动加载到 classpath 中,在基于 JavaEE 的 Web 应用开发过程中,通常要把目标数据库产品的 JDBC 驱动
13、复制到 WEB-INF/lib 下。 2)加载 JDBC 驱动,并将其注册到 DriverManager 中。一般使用反射 Class.forName(String driveName)。3)建立数据库连接,取得 Connection 对象。一般通过DriverManager.getConnection(url,username,passwd)方法实现,其中,url 表示连接数据库的字符串,username 表示连接数据库的用户名,passwd 表示连接数据库的密码。 4)建立 Statement 对象或是 PreparedStatement 对象。 5)执行 SQL 语句。 6)访问结果集
14、ResultSet 对象。 7)依次将 ResuhSet、Statement、PreparedStatement、Connection 对象关闭,释放掉所占用资源,例如rs.close(),con.close()等。为什么要这么做呢?原因在于 JDBC 驱动在底层通常都是通过网络 IO 实现SQL 命令与数据传输的。 常见笔试题: 1举出一个用 JDBC 访问 MySQL 的例子。 答案:首先,创建 Employee 表。 create table Employee( id int primary key, name varehar(20), age int ); 其次,创建一个示例程序,如下
15、所示。 import java.sql.*; public class Test public static void main(Stringargs)throws Exception String user=“user1“; String password=“pwd1“; String url=“jdbc:mysql:/localhost:3306/Test“; String driver=“com.mysql.jdbc.Driver“; Connection con=null; Statement stmt=null; ResultSet rs=null; try Class.forNam
16、e(driver); con=DriverManager.getConnection(url, user, password); stmt=con.createStatement(); stmt.execute(“insert into Employee values(1, “James1“, 25)“); stmt.execute(“insert into Employee values(2, “James2“, 26)“); rs=stmt.executeQuery(“select*from Employee“); while(rs.next() System.out.println(rs
17、.getInt(1)+“+rs.getString(2)+“+rs.getInt(3); catch(SQLException e1) e1.printStackTrace(); finally try if(rs!=null)rs.close(); if(stmt!=null)stmt.close(); if(con!=null)con.close(); catch(SQLException e) System.out.println(e.getMessage(); 程序运行结果为: 1 James1 25 2 James2 26 2JDBC 的主要功能有_。 A创建与数据库的连接 B发送
18、SQL 语句到数据库中 C处理数据并查询结果 D以上都是 答案:D。见上面讲解。 3提供 Java 存取数据库能力的包是_。 Ajava.sql Bjava.awt Cjava.lang Djava.swing 答案:A。对数据库操作的所有类都在 java.sql 包中。4.JDBC 处理事务采用什么方法 (分数:4.00)_正确答案:()解析:一个事务是由一条或多条对数据库操作的 SQL 语句所组成的一个不可分割的工作单元,只有当事务中的所有操作都正常执行完了,整个事务才会被提交给数据库。在 JDBC 中,一般是通过 commit()方法或rollback()方法来结束事务的操作。其中 co
19、mmit()方法表示完成对事务的提交,rollback()方法表示完成事务回滚,多用于在处理事务的过程中出现了异常的情况,这两种方法都位于 java.sql.Connection 类中。一般而言,事务默认操作是自动提交,即操作成功后,系统将自动调用 commit()方法,否则将调用rollback()方法。 当然,在 JDBC 中,也可以通过调用 setAutoCommit(false)方法来禁止自动提交,然后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用 commit()方法实现整体提交,如果其中一个表达式操作失败,就会抛出异常而不会调用 commit()方法。在这种情况下,就
20、可以在异常捕获的代码块中调用rollback()方法进行事务回滚。通过此种方法可以保持对数据库的多次操作后,数据仍然保持一致性。 引申:JDBC 有哪些事务隔离级别? 为了解决与“多个线程请求相同数据”相关的问题,事务之间通常会用锁相互隔离开。如今,大多数主流的数据库支持不同类型的锁。因此,JDBC APl 支持不同类型的事务,它们由 Connection 对象指派或确定。在 JDBC 中,定义了以下 5 种事务隔离级别: 1)TRANSACTION_NONE JDB。不支持事务。 2)TRANSACTTON_READ_UNCOMMITTED。未提交读。说明在提交前一个事务可以看到另一个事务的
21、变化。这样读“脏”数据、不可重复读和虚读都是允许的。 3)TRANSACTION_READ_COMMITTED。已提交读。说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚读产生。 4)TRANSACTION_REPEATABLE_READ。可重复读。说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。 5)TRANSACTION_SERIALIZABLE。可序列化。是最高的事务级别,它防止读“脏”数据、不可重复读和虚读。(备注:读“脏”数据。一个事务读取了另一个事务尚未提交的数据,例如,当事务 A 与事务 B 并发执行时,当事务 A 更新后,事务 B 查询读取到 A
22、尚未提交的数据,此时事务 A 回滚,则事务 B 读到的数据是无效的“脏”数据。不可重复读。一个事务的操作导致另一个事务前后两次读取到不同的数据,例如,当事务 A 与事务 B 并发执行时,当事务 B 查询读取数据后,事务 A 更新操作更改事务 B 查询到的数据,此时事务 B 再次读去该数据,发现前后两次的数据不一样。虚读。一个事务的操作导致另一个事务前后两次查询的结果数据量不同,例如,当事务 A 与事务 B 并发执行时,当事务 B 查询读取数据后,事务 A 新增或删除了一条满足事务 A 的查询条件的记录,此时,事务 B 再次查询,发现查询到前次不存在的记录,或者前次的某个记录不见了。) 事务隔离
23、级别越高,为避免冲突所花的精力也就越多。可以通过 Connection 对象的conn.setTransactionLevel()方法来设置隔离级别,通过 conn.getTransactionIsolation()方法来确定当前事务的级别。5.Class.forName 的作用是什么 (分数:4.00)_正确答案:()解析:在 Java 语言中,任何类只有被装载到 JVM 上才能运行。Class.forName()方法的作用就是把类加载到 JVM 中,它会返回一个与带有给定字符串名的类或接口相关联的 Class 对象,并且 JVM 会加载这个类,同时 JVM 会执行该类的静态代码段。 在使用
24、 JDBC 连接数据库前,一般都会调用 Class.forName(“com.mysql.jdbc.Driver“)方法来加载 JDBC驱动,那么是否一定需要调用这个方法呢?如果是,那为什么要调用这个方法呢?其实,并不一定非要调用这种方法,例如 Test t=(Test)Class.forName(“Test“).newInstance()语句和 Test t=new Test()语句就具有相同的效果,所以使用 new 也可以,但二者的区别也非常明显:创建对象的方式不同。前者使用类加载机制,后者是创建了一个新的类。使用第一种方法往往能提高软件的可扩展性,例如,一个软件项目开发后会被多家公司来使
25、用,每家公司的处理流程大致相同,只有个别公司的业务逻辑不同,在开发过程中,完全可以把不通用的地方抽取出来定义成一个接口 BussinessInterface,针对每个公司不同的业务流程定义不同的实现类 sub1、sub2、sub3 等,通过创建不同的子类来完成不同公司的业务需求。为了达到良好的可扩展性,可以把子类采用配置文件的方式放到 XML 文件中。在程序部署时,只需要从读配置文件中读取类名 className,然后采用 BussinessInterface b=(BussinessInterface)Class.forName(className).newInstance()创建实例即可提
26、高开发人员的开发效率。当以后再有新的需求时,即使开发了新的子类,也不需要修改创建实例的代码,只需要修改配置文件即可,从而使得程序具有很好的可扩展性。 JDBC 规范中要求 Driver 类在使用前必须向 DriverManager 注册自己,所以,当执行Class.forName(“com.mysql.jdbc.Driver“)时,JVM 会加载名字为“com.mysql.jdbc.Driver“对应的Driver 类,而 com.mysql.Driver 类的实现如下例所示: public class Driver extends NonRegisteringDrjver implement
27、s Java.sql.Driver static try java.sql.DriverManager.registerDriver(new Driver(); catch(SQLException E) throw new RuntimeException(“Can“t register driver!“); 在调用 Class.forName()方法时,这个 Driver 类被加载了,由于静态部分被执行,因此 Driver 也被注册到了 DriverManager 中。6.Statement、PreparedStatement 和 CallableStatement 有什么区别 (分数:4
28、.00)_正确答案:()解析:Statement 用于执行不带参数的简单 SQL 语句,并返回它所生成结果的对象,每次执行 SQL 语句时,数据库都要编译该 SQL 语句。以下是一个最简单的 SQL 语句: Statement strut=corm.getStatement(); stmt.executeUpdate(“insert into client values(“aa“, “aaaa“)“); PreparedStatement 表示预编译的 SQL 语句的对象,用于执行带参数的预编译 SQL 语句。 CallableStatement 则提供了用来调用数据库中存储过程的接口,如果有
29、输出参数要注册,说明是输出参数。下面给出一个使用 PreparedStatement 的例子: import java.sql.*; public class Test public static void main(Stringargs)throws Exception String user=“user1“; String password=“pwd1“; String url=“jdbc:mysql:/localhost:3306/Test“; String driver=“com.mysql.jdbc.Driver“; Connection con=null; PreparedStat
30、ement stmt=null; ResultSet rs=null; try Class.forName(driver); con=DriverManager.getConnection(url, user, password); stmt=con.prepareStatement(“select*from Employee where id=?“); stmt.setInt(1, 1);/传递参数(第一个问号,传递的值) rs=stmt.executeQuery(); while(rs.next() System.out.println(rs.getInt(1)+“+rs.getStrin
31、g(2)+“+rs.getInt(3); catch(SQLException e1) e1.printStackTrace(); finally try if(rs!=null) rs.close(); if(stmt!=null) stmt.close(); if(con!=null) con.close(); catch(SQLException e) System.out.println(e.getMessage(); 程序运行结果为: 1 James1 25 虽然 Statemetlt 对象与 PreparedStatement 对象能够完成相同的功能,但相比之下,PreparedS
32、tatement具有以下优点: 1)效率更高。在使用 PreparedStatement 对象执行 SQL 命令时,命令会被数据库进行编译和解析,并放到命令缓冲区。然后,每当执行同一个 PreparedStatement 对象时,由于在缓冲区中可以发现预编译的命令,虽然它会被再解析一次,但不会被再次编译,是可以重复使用的,能够有效提高系统性能,因此,如果要执行插入、更新、删除等操作,最好使用 PreparedStatement。鉴于此,PreparedStatement 适用于存在大量用户的企业级应用软件中。 2)代码可读性和可维护性更好。以下两种方法分别使用 Statement 与 Prep
33、aredStatement 来执行 SQL 语句,显然方法 2 具有更好的可读性。 方法 1: stmt.executeUpdate(“insert into t(col1, col2)values(“+var1+“, “+vat2+“)“); 方法 2: perstmt=con.prepareStatement(“insert into tb_name(col1, col2)values(?, ?)“); perstmt.setString(1, var1); perstmt.setString(2, var2); 3)安全性更好。使用 PreparedStatement 能够预防 SQL
34、注入攻击,所谓 SQL 注入,指的是通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器,达到执行恶意 SQL 命令的目的。注入只对 SQL 语句的编译过程有破坏作用,而执行阶段只是把输入串作为数据处理,不再需要对SQL 语句进行解析,因此也就避免了类似 select*from user where name=“aa“ and password=“bb“ or 1=1 的 SQL 注入问题的发生。 CallableStatement 由 prepareCall()方法所创建,它为所有 DBMS(Database Management System,数
35、据库管理系统)提供了一种以标准形式调用已储存过程的方法。它从 PreparedStatement 中继承了用于处理输入参数的方法,而且还增加了调用数据库中的存储过程和函数以及设置输出类型参数的功能。 常见笔试题: 用于调用存储过程的对象是_。 AResultSet BDriverManager CCallableStatemet DPreparedStatement 答案:C。JDBC 中的 CallableStatement 对象为所有 RDBMS(Relational Database Management System,关系数据库管理系统)提供了一种标准形式调用存储过程的方法。其对存储过
36、程的调用存在两种形式:带结果参数和不带结果参数。结果参数是一种输出参数,是存储过程的返回值。两种形式都可带有数量可变的输入(IN 参数)、输出(OUT 参数)或输入和输出(IN-OUT 参数)的参数。7.getString()方法与 getObject()方法有什么区别 (分数:4.00)_正确答案:()解析:JDBC 提供了 getString()、getInt()和 getData()等方法从 ResultSet 中获取数据,当查询结果集中的数据量较小时,不用考虑性能,使用这些方法完全能够满足需求,但是当查询结果集中的数据量非常大时,则会抛出异常:OracleException 未处理:O
37、RA-01000:maximum open cursors exceeded(以访问Oraele 数据库为例)。而通常情况下,使用 getObject()方法就可以解决这个问题。 getString()或 getInt()等方法在被调用时,程序会一次性地把数据都放到内存中,然后通过调用ResultSet 的 next()和 getString()等方法来获取数据。当数据量大到内存中放不下时就会抛出异常,而使用 getObject()方法就不会这种问题,因为数据不会一次性被读到内存中,每次调用时会直接从数据库中去获取数据,因此使用这种方法不会因为数据量过大而出错。8.使用 JDBC 时需要注意哪
38、些问题 (分数:4.00)_正确答案:()解析:在使用 JDBc 编程时,首先需要建立于数据库的连接,才能完成对数据库的访问,由于与数据库的连接是非常重要的资源。JDBC 连接池提供了 JDBC 连接定义和数目有限的连接,如果连接数量不够,就需要长时间的等待。不正常关闭 JDBC 连接会导致等待回收无效的 JDBC 连接。只有正常的关闭和释放 JDBC连接,JDBC 资源才可以被快速地重用,从而使得系统性能得到改善。因此在编程时,一定要保证释放不再使用的连接。 一般来讲,在使用 JDBC 访问数据库时,createStatement 和 prepareStatement 最好放在循环外面,而且
39、使用了这些 Statement 后,需要及时关闭。最好是在执行了一次 executeQuery、executeUpdate 等之后,如果不需要使用结果集(ResultSet)的数据,就马上将 Statment 关闭。因为每次执行conn.createStatement()或 conn.prepareStatement(),实际上都相当于在数据库中打开了一个cursor(游标),如果把对这两个方法的调用放到循环内,会一直不停地打开 cursor。如果不能及时地关闭,会导致程序抛出异常。9.什么是 JDO (分数:4.00)_正确答案:()解析:Java 数据对象(JavaData Object,JDO)是
copyright@ 2008-2019 麦多课文库(www.mydoc123.com)网站版权所有
备案/许可证编号:苏ICP备17064731号-1