牛客网 Java工程师能力评估 专项练习1

这是对牛客网 Java工程师能力评估的一个总结,大部分解析摘自评论。加入了一些自己的见解,有问题可以留言讨论

这是地址:https://www.nowcoder.net/test/question/analytic?tid=13434195 


1 下面有关JVM内存,说法错误的是?

A程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的

B虚拟机栈描述的是Java方法执行的内存模型,用于存储局部变量,操作数栈,动态链接,方法出口等信息,是线程隔离的

C方法区用于存储JVM加载的类信息、常量、静态变量、以及编译器编译后的代码等数据,是线程隔离的

D原则上讲,所有的对象都在堆区上分配内存,是线程之间共享的

 

答案C

大多数 JVM 将内存区域划分为 Method AreaNon-Heap)(方法区) ,Heap(堆) , Program Counter Register(程序计数器) ,   VM Stack(虚拟机栈,也有翻译成JAVA方法栈的),Native Method Stack   本地方法栈 ),其中Method Area   Heap 是线程共享的  VM StackNative Method Stack  Program Counter Register  是非线程共享的。为什么分为 线程共享和非线程共享的呢?请继续往下看。

首先我们熟悉一下一个一般性的 Java 程序的工作过程。一个 Java 源程序文件,会被编译为字节码文件(以class 为扩展名),每个java程序都需要运行在自己的JVM上,然后告知JVM 程序的运行入口,再被JVM 通过字节码解释器加载运行。那么程序开始运行后,都是如何涉及到各内存区域的呢?

概括地说来,JVM初始运行的时候都会分配好 Method Area(方法区) Heap(堆) ,而JVM每遇到一个线程,就为其分配一个 Program Counter Register(程序计数器) ,   VM Stack(虚拟机栈)和Native Method Stack  (本地方法栈), 当线程终止时,三者(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被释放掉。这也是为什么我把内存区域分为线程共享和非线程共享的原因,非线程共享的那三个区域的生命周期与所属线程相同,而线程共享的区域与JAVA程序运行的生命周期相同,所以这也是系统垃圾回收的场所只发生在线程共享的区域(实际上对大部分虚拟机来说知发生在Heap上)的原因。

 

2 下面有关jdbc statement的说法错误的是?

AJDBC提供了StatementPreparedStatementCallableStatement三种方式来执行查询语句,其中Statement 用于通用查询,PreparedStatement 用于执行参数化查询,而CallableStatement则是用于存储过程

B、对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行计划,由于PreparedStatement 对象已预编译过,所以其执行速度要快于Statement 对象”

CPreparedStatement中,“?” 叫做占位符,一个占位符可以有一个或者多个值

DPreparedStatement可以阻止常见的SQL注入式攻击

 

答案:C

关于CJDBC statement中的PReparedStatement的占位符对应着即将与之对应当值,并且一个占位符只能对应一个值,如果能对应多个就会引起混淆。sql语句是确定的,那么一个占位符必定只能对应一个值

相关知识点:

1.

StatementPreparedStatementCallableStatement都是接口(interface)  
2.

Statement继承自WrapperPreparedStatement继承自StatementCallableStatement继承自PreparedStatement  
3.  
Statement接口提供了执行语句和获取结果的基本方法;  
PreparedStatement接口添加了处理 IN参数的方法;  
CallableStatement接口添加了处理 OUT参数的方法。  
4.  
a.Statement:  
普通的不带参的查询SQL;支持批量更新,批量删除;  
b.PreparedStatement:  
可变参数的SQL,编译一次,执行多次,效率高;  
安全性好,有效防止Sql注入等问题;  
支持批量更新,批量删除;  
c.CallableStatement:  
继承自PreparedStatement,支持带参数的SQL操作;  
支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;  
5.

Statement每次执行sql语句,数据库都要执行sql语句的编译 ,  
最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement  

6.

PreparedStatement是预编译的,使用PreparedStatement有几个好处  
1. 在执行可变参数的一条SQL时,PreparedStatementStatement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。  
2. 安全性好,有效防止Sql注入等问题。  
3.  对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch  
4.  代码的可读性和可维护性。

 

3 下面有关SPRING的事务传播特性,说法错误的是?

APROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行

BPROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就抛出异常

CPROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起

DPROPAGATION_NESTED:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚

 

答案:B

事务属性的种类:   传播行为、隔离级别、只读和事务超时

a)   传播行为定义了被调用方法的事务边界。

 

传播行为

意义

PROPERGATION_MANDATORY

表示方法必须运行在一个事务中,如果当前事务不存在,就抛出异常

PROPAGATION_NESTED

表示如果当前事务存在,则方法应该运行在一个嵌套事务中。否则,它看起来和PROPAGATION_REQUIRED 看起来没什么俩样

PROPAGATION_NEVER

表示方法不能运行在一个事务中,否则抛出异常

PROPAGATION_NOT_SUPPORTED

表示方法不能运行在一个事务中,如果当前存在一个事务,则该方法将被挂起

PROPAGATION_REQUIRED

表示当前方法必须运行在一个事务中,如果当前存在一个事务,那么该方法运行在这个事务中,否则,将创建一个新的事务

PROPAGATION_REQUIRES_NEW

表示当前方法必须运行在自己的事务中,如果当前存在一个事务,那么这个事务将在该方法运行期间被挂起

PROPAGATION_SUPPORTS

表示当前方法不需要运行在一个是事务中,但如果有一个事务已经存在,该方法也可以运行在这个事务中


b)   隔离级别

在操作数据时可能带来 3 个副作用,分别是脏读、不可重复读、幻读。为了避免这 3 中副作用的发生,在标准的 SQL 语句中定义了 4 种隔离级别,分别是未提交读、已提交读、可重复读、可序列化。而在 spring 事务中提供了 5 种隔离级别来对应在SQL 中定义的 4 种隔离级别,如下:

隔离级别

意义

ISOLATION_DEFAULT

使用后端数据库默认的隔离级别

ISOLATION_READ_UNCOMMITTED

允许读取未提交的数据(对应未提交读),可能导致脏读、不可重复读、幻读

ISOLATION_READ_COMMITTED

允许在一个事务中读取另一个已经提交的事务中的数据(对应已提交读)。可以避免脏读,但是无法避免不可重复读和幻读

ISOLATION_REPEATABLE_READ

一个事务不可能更新由另一个事务修改但尚未提交(回滚)的数据(对应可重复读)。可以避免脏读和不可重复读,但无法避免幻读

ISOLATION_SERIALIZABLE

这种隔离级别是所有的事务都在一个执行队列中,依次顺序执行,而不是并行(对应可序列化)。可以避免脏读、不可重复读、幻读。但是这种隔离级别效率很低,因此,除非必须,否则不建议使用。


c)    只读

如果在一个事务中所有关于数据库的操作都是只读的,也就是说,这些操作只读取数据库中的数据,而并不更新数据,那么应将事务设为只读模式( READ_ONLY_MARKER  , 这样更有利于数据库进行优化 

因为只读的优化措施是事务启动后由数据库实施的,因此,只有将那些具有可能启动新事务的传播行为(PROPAGATION_NESTED  PROPAGATION_REQUIRED  PROPAGATION_REQUIRED_NEW) 的方法的事务标记成只读才有意义。

如果使用 Hibernate 作为持久化机制,那么将事务标记为只读后,会将 Hibernate  flush 模式设置为FULSH_NEVER, 以告诉 Hibernate 避免和数据库之间进行不必要的同步,并将所有更新延迟到事务结束。

d)   事务超时

如果一个事务长时间运行,这时为了尽量避免浪费系统资源,应为这个事务设置一个有效时间,使其等待数秒后自动回滚。与设

“只读”属性一样,事务有效属性也需要给那些具有可能启动新事物的传播行为的方法的事务标记成只读才有意义。

 

4、下面有关servletcgi的描述,说法错误的是?

Aservlet处于服务器进程中,它通过多线程方式运行其service方法

BCGI对每个请求都产生新的进程,服务完成后就销毁

Cservlet在易用性上强于cgi,它提供了大量的实用工具例程,例如自动地解析和解码HTML表单数据、读取和设置HTTP头、处理Cookie、跟踪会话状态等

Dcgi在移植性上高于servlet,几乎所有的主流服务器都直接或通过插件支持cgi

 

答案D

关于Dservlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet

知识点:

Servlet  CGI 的比较

CGI程序一样,Servlet可以响应用户的指令(提交一个FORM等等),也可以象CGI程序一样,收集用户表单的信息并给予动态反馈(简单的注册信息录入和检查错误)
然而,Servlet的机制并不仅仅是这样简单的与用户表单进行交互。传统技术中,动态的网页建立和显示都是通过CGI来实现的,但是,有了Servlet,您可以大胆的放弃所有CGI(perl?php?甚至asp!),利用Servlet代替CGI,进行程序编写。
    对比一:当用户浏览器发出一个Http/CGI的请求,或者说 调用一个CGI程序的时候,服务器端就要新启用一个进程 (而且是每次都要调用),调用CGI程序越多(特别是访问量高的时候),就要消耗系统越多的处理时间,只剩下越来越少的系统资源,对于用户来说,只能是漫长的等待服务器端的返回页面了,这对于电子商务激烈发展的今天来说,不能不说是一种技术上的遗憾。
Servlet充分发挥了服务器端的资源并高效的利用。每次调用Servlet时并不是新启用一个进程 ,而是在一个Web服务器的进程敏感词享和分离线程,而线程最大的好处在于可以共享一个数据源,使系统资源被有效利用。
    对比二:传统的CGI程序,不具备平台无关性特征,系统环境发生变化,CGI程序就要瘫痪,而Servlet具备Java的平台无关性,在系统开发过程中保持了系统的可扩展性、高效性。
    对比三:传统技术中,一般大都为二层的系统架构,即Web服务器+数据库服务器,导致网站访问量大的时候,无法克服CGI程序与数据库建立连接时速度慢的瓶颈,从而死机、数据库死锁现象频繁发生。而我们的Servlet有连接池的概念,它可以利用多线程的优点,在系统缓存中事先建立好若干与数据库的连接,到时候若想和数据库打交道可以随时跟系统""一个连接即可,反应速度可想而知。

 

5 下面有关servlet service描述错误的是?

A、不管是post还是get方法提交过来的连接,都会在service中处理

BdoGet/doPost则是在 javax.servlet.GenericServlet中实现的

Cservice()是在javax.servlet.Servlet接口中定义的

Dservice判断请求类型,决定是调用doGet还是doPost方法

 

答案 B

doGet/doPost 则是在 javax.servlet.http.HttpServlet中实现的

GenericServlet 抽象类 给出了设计 servlet 的一些骨架,定义了 servlet 生命周期,还有一些得到名字、配置、初始化参数的方法,其设计的是和应用层协议无关的

 

6 下列有关Servlet的生命周期,说法不正确的是?

A、在创建自己的Servlet时候,应该在初始化方法init()方法中创建Servlet实例

B、在Servlet生命周期的服务阶段,执行service()方法,根据用户请求的方法,执行相应的doGet()或是doPost()方法

C、在销毁阶段,执行destroy()方法后会释放Servlet占用的资源

Ddestroy()方法仅执行一次,即在服务器停止且卸载Servlet时执行该方法

 

答案:A

创建Servlet的实例是由Servlet容器来完成的,且创建Servlet实例是在初始化方法init()之前

知识点:Servlet的生命周期分为5个阶段:加载、创建、初始化、处理客户请求、卸载。

(1)加载:容器通过类加载器使用servlet类对应的文件加载servlet

(2)创建:通过调用servlet构造函数创建一个servlet对象

(3)初始化:调用init方法初始化

(4)处理客户请求:每当有一个客户请求,容器会创建一个线程来处理客户请求

(5)卸载:调用destroy方法让servlet自己释放其占用的资源

 

7 下面有关servletinit,service,destroy方法描述错误的是?

Ainit()方法是servlet生命的起点。一旦加载了某个servlet,服务器将立即调用它的init()方法

Bservice()方法处理客户机发出的所有请求

Cdestroy()方法标志servlet生命周期的结束

Dservlet在多线程下使用了同步机制,因此,在并发编程下servlet是线程安全的

 

答案为D

servlet在多线程下其本身并不是线程安全的。

如果在类中定义成员变量,而在service中根据不同的线程对该成员变量进行更改,那么在并发的时候就会引起错误。最好是在方法中,定义局部变量,而不是类变量或者对象的成员变量。由于方法中的局部变量是在栈中,彼此各自都拥有独立的运行空间而不会互相干扰,因此才做到线程安全。

知识点:

init方法: 是在servlet实例创建时调用的方法,用于创建或打开任何与servlet相的资源和初始 化servlet的状态,Servlet规范保证调用init方法前不会处理任何请求 

 service方法:是servlet真正处理客户端传过来的请求的方法,由web容器调用, 根据HTTP请求方法(GETPOST等),将请求分发到doGetdoPost等方法 

destory方法:是在servlet实例被销毁时由web容器调用。Servlet规范确保在destroy方法调用之 前所有请求的处理均完成,需要覆盖destroy方法的情况:释放任何在init方法中 打开的与servlet相关的资源存储servlet的状态

 

8 下面有关struts1struts2的区别,描述错误的是?

AStruts1要求Action类继承一个抽象基类。Struts 2 Action类可以实现一个Action接口

BStruts1 Action对象为每一个请求产生一个实例。Struts2 Action是单例模式并且必须是线程安全的

CStruts1 Action依赖于Servlet APIStruts 2 Action不依赖于容器,允许Action脱离容器单独被测试

DStruts1整合了JSTLStruts2可以使用JSTL,但是也支持OGNL

 

答案为B

Struts1是单例的   Struts2是多例的  记住这个就OK

action类上分析:
1.Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。 
2. Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去实现常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2Action对象。
Servlet 依赖分析
3. Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequestHttpServletResponse被传递给execute方法。 
4. Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的requestresponse。但是,其他的元素减少或者消除了直接访问HttpServetRequestHttpServletResponse的必要性。
action线程模式分析
5. Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。 
6. Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)

 

9 关于AWTSwing说法正确的是?

ASwingAWT的子类

BAWT在不同操作系统中显示相同的风格

CAWT不支持事件类型,Swing支持事件模型

DSwing在不同的操作系统中显示相同的风格

 

答案为D

AWT :是通过调用操作系统的native方法实现的,所以在Windows系统上的AWT窗口就是Windows的风格,而在Unix系统上的则是XWindow风格。 AWT 中的图形函数与 操作系统 所提供的图形函数之间有着一一对应的关系,我们把它称为peers。 也就是说,当我们利用 AWT 来构件图形用户界面的时候,我们实际上是在利用 操作系统 所提供的图形库。由于不同 操作系统 的图形库所提供的功能是不一样的,在一个平台上存在的功能在另外一个平台上则可能不存在。为了实现Java语言所宣称的"一次编译,到处运行"的概念,AWT不得不通过牺牲功能来实现其平台无关性,也就是说,AWT所提供的图形功能是各种通用型操作系统所提供的图形功能的交集。由于AWT是依靠本地方法来实现其功能的,我们通常把AWT控件称为重量级控件。

Swing :是所谓的Lightweight组件,不是通过native方法来实现的,所以Swing的窗口风格更多样化。但是,Swing里面也有heaveyweight组件。比如JWindowDialog,JFrame

Swing是所谓的Lightweight组件,不是通过native方法来实现的,所以Swing的窗口风格更多样化。但是,Swing里面也有heaveyweight组件。比如JWindowDialog,JFrame

Swing由纯Java写成,可移植性好,外观在不同平台上相同。所以Swing部件称为轻量级组件(Swing是由纯JAVA CODE所写的,因此SWING解决了JAVA因窗口类而无法跨平台的问题,使窗口功能也具有跨平台与延展性的特性,而且SWING不需占有太多系统资源,因此称为轻量级组件!!!)

 

10 看以下代码: 
文件名称:forward.jsp 

1

2

3

4

5

6

<html>  

     <head><title> 跳转  </title> </head> 

     <body>  

         <jsp:forward page="index.htm"/>     

     </body>

 </html> 

如果运行以上jsp文件,地址栏的内容为

Ahttp://127.0.0.1:8080/myjsp/forward.jsp

Bhttp://127.0.0.1:8080/myjsp/index.jsp

Chttp://127.0.0.1:8080/myjsp/index.htm

Dhttp://127.0.0.1:8080/myjsp/forward.htm

 

正确答案: A

redirect:请求重定向:客户端行为,本质上为2次请求,地址栏改变,前一次请求对象消失。举例:你去银行办事(forward.jsp),结果告诉你少带了东西,你得先去公安局办(index.html)临时身份证,这时你就会走出银行,自己前往公安局,地址栏变为index.html.

forward:请求转发:服务器行为,地址栏不变。举例:你把钱包落在出租车上,你去警察局(forward.jsp)报案,警察局说钱包落在某某公司的出租车上(index.html),这时你不用亲自去找某某公司的出租车,警察局让出租车自己给你送来,你只要在警察局等就行。所以地址栏不变,依然为forward.jsp

 

11 下面哪一项不是加载驱动程序的方法?

A、通过DriverManager.getConnection方法加载

B、调用方法 Class.forName

C、通过添加系统的jdbc.drivers属性

D、通过registerDriver方法注册

 

正确答案: A

加载驱动方法

1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

2. DriverManager.registerDriver(new com.mysql.jdbc.Driver());

3.System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");

 

12 关于sleep()wait(),以下描述错误的一项是( )

Asleep是线程类(Thread)的方法,waitObject类的方法;

Bsleep不释放对象锁,wait放弃对象锁

Csleep暂停线程、但监控状态仍然保持,结束后会自动恢复

Dwait后进入等待锁定池,只有针对此对象发出notify方法后获得对象锁进入运行状态

 

D

D错是因为进入的是就绪状态而不是运行状态。

Java线程有5种状态,分别是新建、就绪、运行、阻塞、死亡。线程获得对象锁之后,进入就绪状态,还要等待获得CPU时间才能进入运行状态。

Java中的多线程是一种抢占式的机制,而不是分时机制。抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行。 
共同点  
1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。 
2. wait()sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException 
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。 
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到wait()/sleep()/join()后,就会立刻抛出InterruptedException 
不同点   
1.每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。 
sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。 
2.waitnotifynotifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用 
3.sleep必须捕获异常,而waitnotifynotifyAll不需要捕获异常 

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

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

 

13 根据下面的程序代码,哪些选项的值返回true

1

2

3

4

5

6

7

8

9

10

11

12

13

public class Square {  

    long width;  

    public Square(long l) {   

        width = l;  

    }  

    public static void main(String arg[]) {   

        Square a, b, c;  

        a = new Square(42L);   

        b = new Square(42L);   

        c = b;   

        long s = 42L;  

    } 

}

 

 

Aa == b

Bs == a

Cb == c

Da.equals(s)

 

正确答案: C

1

2

3

4

5

6

7

8

9

10

11

12

这题考的是引用和内存。

//声明了3Square类型的变量a, b, c

//stack中分配3个内存,名字为a, b, c

Square a, b, c; 

//heap中分配了一块新内存,里边包含自己的成员变量width值为48L,然后stack中的a指向这块内存

a = new Square(42L);

//heap中分配了一块新内存,其中包含自己的成员变量width值为48L,然后stack中的b指向这块内存

b = new Square(42L);   

//stack中的c也指向b所指向的内存

c = b;

//stack中分配了一块内存,值为42

long s = 42L; 

如图所示:

 

来看4个选项:

A: a == b

由图可以看出ab指向的不是同一个引用,故A

Bs == a

一个Square类型不能与一个long型比较,编译就错误,故B

cb == c

由图可以看出bc指向的是同一个引用,故C正确

da equal s

程序会把s封装成一个Long类型,由于Square没有重写Objectequals方法, 所以调用的是Object类的equals方法,源码如下

1

2

3

 public boolean equals(Object obj) {

     return (this == obj);

 }

其实就是判断两个引用是否相等,故D也错误。

 

14 jdk1.5的环境下,有如下4条语句:

1

2

3

4

Integer i01 = 59;

int i02 = 59;

Integer i03 =Integer.valueOf(59);

Integer i04 = new Integer(59)

以下输出结果为false的是:

ASystem.out.println(i01== i02);

BSystem.out.println(i01== i03);

CSystem.out.println(i03== i04);

DSystem.out.println(i02== i04);

 

答案为C

Integer i01=59 的时候,会调用 Integer  valueOf 方法,

1

2

3

4

5

  public static Integer valueOf(int i) {

     assert IntegerCache.high>= 127;

     if (i >= IntegerCache.low&& i <= IntegerCache.high)

     return IntegerCache.cache[i+ (-IntegerCache.low)];

     return new Integer(i); }

这个方法就是返回一个 Integer 对象,只是在返回之前,看作了一个判断,判断当前 i 的值是否在 [-128,127] 区别,且 IntegerCache 中是否存在此对象,如果存在,则直接返回引用,否则,创建一个新的对象。

在这里的话,因为程序初次运行,没有 59 ,所以,直接创建了一个新的对象。

 

int i02=59 ,这是一个基本类型,存储在栈中。

 

Integer i03 =Integer.valueOf(59); 因为 IntegerCache 中已经存在此对象,所以,直接返回引用。

 

Integer i04 = new Integer(59) ;直接创建一个新的对象。

 

System. out .println(i01== i02); i01  Integer 对象, i02  int ,这里比较的不是地址,而是值。 Integer 会自动拆箱成 int ,然后进行值的比较。所以,为真。

 

System. out .println(i01== i03); 因为 i03 返回的是 i01 的引用,所以,为真。

 

System. out .println(i03==i04); 因为 i04 是重新创建的对象,所以 i03,i04 是指向不同的对象,因此比较结果为假。

 

System. out .println(i02== i04); 因为 i02 是基本类型,所以此时 i04 会自动拆箱,进行值比较,所以,结果为真。

 

15 下面哪个不对?

ARuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.

BA method is not required to declare in its throws clause any subclasses of RuntimeExeption that might be thrown during the execution of the method but not caught

CAn RuntimeException is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.

DNullPointerException is one kind of RuntimeException

 

正确答案: C  

 

运行时异常: 都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

       运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。 
非运行时异常 (编译异常): RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOExceptionSQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

 

16 关于struts项目中的类与MVC模式的对应关系,说法错误的是

   

AJsp文件实现视图View的功能

BActionServlet这一个类是整个struts项目的控制器

CActionFormAction都属于Model部分

D、一个struts项目只能有一个Servlet

 

正确答案: C D
这是百度的:
Struts工作原理 
MVCModel-View-Controller的缩写,是一种常用的设计模式。MVC  减弱了业务逻辑接口和数据接口之间的耦合,以及让视图层更富于变化。 
Struts   MVC的一种实现,它将  Servlet  JSP   标记(属于  J2EE   规范)用作实现的一部分。Struts继承了MVC的各项特性,并根据J2EE的特点,做了相应的变化与扩展。 
制:有一个XML文件Struts-config.xml,与之相关联的是Controller,在Struts中,承担MVCController角 色的是一个Servlet,叫ActionServletActionServlet是一个通用的控制组件。这个控制组件提供了处理所有发送到StrutsHTTP请求的入口点。它截取和分发这些请求到相应的动作类(这些动作类都是Action类的子类)。另外控制组件也负责用相应的请求参数 填充   Action   From(通常称之为FromBean,并传给动作类(通常称之为ActionBean)。动作类实现核心商业逻辑,它可以访问java   bean   或调用EJB。最后动作类把控制权传给后续的JSP  文件,后者生成视图。所有这些控制逻辑利用Struts-config.xml文件来配置。 
视图:主要由JSP生成页面完成视图,Struts提供丰富的JSP  标签库:   HtmlBeanLogicTemplate等,这有利于分开表现逻辑和程序逻辑。 
型:模型以一个或多个java   bean的形式存在。这些bean分为三类:Action   FormActionJavaBean   or   EJBAction   Form通常称之为FormBean,封装了来自于Client的用户请求信息,如表单信息。Action通常称之为ActionBean,获取从ActionSevlet传来的FormBean,取出FormBean中的相关信息,并做出相关的处理,一般是调用Java   BeanEJB等。 
流程:在Struts中,用户的请求一般以*.do作为请求服务名,所有的*.do请求均被指向ActionSevletActionSevlet根据Struts-config.xml中的配置信息,将用户请求封装成一个指定名称的FormBean,并将此FormBean传至指定名称的ActionBean,由ActionBean完成相应的业务操作,如文件操作,数据库操作等。 每一个*.do均有对应的FormBean名称和ActionBean名称,这些在Struts-config.xml中配置。 
核心:Struts的核心是ActionSevletActionSevlet的核心是Struts-config.xml

 

17 下面有关jsp中静态include和动态include的区别,说法错误的是? 

   

A、动态INCLUDE:jsp:include动作实现

B、静态INCLUDE:include伪码实现,定不会检查所含文件的变化,适用于包含静态页面<%@ include file="included.htm" %>

C、静态include的结果是把其他jsp引入当前jsp,两者合为一体;动态include的结构是两者独立,直到输出时才合并

D、静态include和动态include都可以允许变量同名的冲突.页面设置也可以借用主文件的

 

正确答案: D

动态 INCLUDE  jsp:include 动作实现 <jsp:include page="included.jsp" flush="true" /> 它总是会检查所含文件中的变化 , 适合用于包含动态页面 , 并且可以带参数。各个文件分别先编译,然后组合成一个文件。

静态 INCLUDE  include 伪码实现 , 定不会检查所含文件的变化 , 适用于包含静态页面 <%@ include file="included.htm" %> 。先将文件的代码被原封不动地加入到了主页面从而合成一个文件,然后再进行翻译,此时不允许有相同的变量。 

以下是对 include 两种用法的区别  主要有两个方面的不同 ;

     : 执行时间上 :

    <%@ include file="relativeURI"%> 是在翻译阶段执行

    <jsp:include page="relativeURI" flush="true" /> 在请求处理阶段执行 .

     : 引入内容的不同 :

    <%@ include file="relativeURI"%>

    引入静态文本 (html,jsp),  JSP 页面被转化成 servlet 之前和它融和到一起 .

    <jsp:include page="relativeURI" flush="true" /> 引入执行页面或 servlet 所生成的应答文本 .

 

 

18 定以下JAVA代码,这段代码运行后输出的结果是()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

public class Test

{

    public static int aMethod(int i)throws Exception

    {

        try{

            return i / 10;

        }

        catch (Exception ex)

        {

            throw new Exception("exception in a Method");

        } finally{

            System.out.printf("finally");

        }

    }

 

    public static void main(String [] args)

    {

        try

        {

            aMethod(0);

        }

        catch (Exception ex)

        {

            System.out.printf("exception in main");

        }

        System.out.printf("finished");

    }

}

exception in main finished

finally finished

exception in main finally

finally exception in main finished

 

正确答案: B   

 i / 10;无论i是多少,永远不会抛出异常,所以catch语句不会执行。

finally语句是必定执行的语句。

所以先指向aMathod()finally代码块,输出finally

然后执行main()方法的最后一条输出语句,输出finished

 

 

19 对于JVM内存配置参数:

-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3

,其最小内存值和Survivor区总大小分别是()

 

A5120m1024m

B5120m2048m

C10240m1024m

D10240m2048m

 

答案:D

-Xmx10240m:代表最大堆

 -Xms10240m:代表最小堆

 -Xmn5120m:代表新生代

 -XXSurvivorRatio=3:代表Eden:Survivor = 3   根据Generation-Collection算法(目前大部分JVM采用的算法),一般根据对象的生存周期将堆内存分为若干不同的区域,一般情况将新生代分为Eden ,两块Survivor    计算Survivor大小, Eden:Survivor = 3,总大小为5120,3x+x+x=5120  x=1024

新生代大部分要回收,采用Copying算法,快!

老年代 大部分不需要回收,采用Mark-Compact算法

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值