牛客网Java测试题解析

另有:java基础总结

1.String、StringBuffer、StringBuilder

String字符串是常量,其值不能改变
StringBuilder是线程不安全的,速度更快
StringBuffer是线程安全的,速度比StringBuilder慢

2 .下面有关JVM内存,说法错误的是?C

  1. 程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的
  2. 虚拟机栈描述的是Java方法执行的内存模型,用于存储局部变量,操作数栈,动态链接,方法出口等信息,是线程隔离的
  3. 方法区用于存储JVM加载的类信息、常量、静态变量、以及编译器编译后的代码等数据,是线程隔离的-------应是(不隔离,线程共享)
  4. 原则上讲,所有的对象都在堆区上分配内存,是线程之间共享的

 

3.下面有关jdbc statement的说法错误的是 C

 
  • A.JDBC提供了Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程
  • B.对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行计划,由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象”
  • C.PreparedStatement中,“?” 叫做占位符,一个占位符可以有一个或者多个值
  • D.PreparedStatement可以阻止常见的SQL注入式攻击
 

       

 解析:C:JDBC statement中的PreparedStatement的占位符对应着即将与之对应当值,且一个占位符只对应一个值,如能对应多个会引起混淆。sql语句是确定的,一个占位符必定只对应一个值

 

一些拓展说明

1.Statement、PreparedStatement和CallableStatement都是接口(interface)。  
2.Statement继承自Wrapper、PreparedStatement继承自Statement、CallableStatement继承自PreparedStatement。  
3.  

  •  Statement接口提供了执行语句和获取结果的基本方法;  
  • PreparedStatement接口添加了处理 IN 参数的方法;  
  • CallableStatement接口添加了处理 OUT 参数的方法。  

4.     

  • Statement:  普通的不带参的查询SQL;支持批量更新,批量删除;  
  • PreparedStatement: 是预编译的,可变参数的SQL,编译一次执行多次,效率高;  安全性好,有效防止Sql注入等; 支持批量更新,批量删除;  代码的可读性和可维护性;
  • CallableStatement:  继承自PreparedStatement,支持带参数的SQL操作;  支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;  
  • Statement每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement。  

4.spring事务传播特性

1.PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 

2.PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 
3.PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 
4.PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 
5.PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
6.PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。 

 

5.CGI和servlet 

  • servlet一种用来拓展web服务器功能的组件规范,代替CGI,更加高效,更可移植
  • 使用到javax.servlet 和 javax.servlet.http两个包下面的类和接口
  • 生命周期:客户端(浏览器)发起请求,建立链接——》加载servlet类到内存---实例化调用init初始化--service根据请求方法不同调用doget、dopost,此外还有doHead()、doPut()、doTrace()、doDelete()、doOptions()----destroy销毁
  • CGI(Common Gateway Interface),通用网关接口,每个请求都需要启动一个新的进程,servlet只需一个,所以线程不安全。

 

servlet常用接口和类

 

  • 接口:Servlet、ServletConfig、ServletRequest,ServletResponse、HttpServletRequest、HttpServletResponse、ServletContext
  • 类:HttpServlet(抽象类)、GenericServlet(抽象类)

关系图 

GenericServlet

  • 实现了Servlet接口

1.init方法 妥善的保存config对象并实现getServletInfo,getServletConfig,
2.增加一个空参init方法,供开发人员初始化,为了防止开发人员重写 原生init方法
3.service方法空实现=> 声明城抽象(强制开发人员实现该方法)
4.destory方法空实现 
5.实现了servletConfig接口. 接口中的方法直接调用config实现类实现.

 

HTTPServlet

  • 在GenericServlet的基础上针对http服务做的一些优化

1.service函数中强转参数

ServletRequest--->HttpServletRequest;
ServletResponse--->HttpServletResponse
2.根据不同的请求方式(get,post等)调用不同的方法(doGet,doPost等)

3.所以是http服务的话,直接继承HTTPServlet就可以了,然后再doGet等方法中处理响应

 

注意:

1.service方法是在servlet生命周期中的服务期,默认在HttpServlet类中实现,根据HTTP请求方法(GET、POST等),将请求分发到doGet、doPost等方法实现。

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

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

 

 

6.Struts1和Struts2的区别和对比:

Action 类:  
• Struts1 Action类继承一个抽象基类。Struts1一个普遍问题是使用抽象类编程而不是接口,而struts2的Action是接口。 
 
• Struts2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去实现常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。 
线程模式:  
• Struts1 Action是单例模式且必须是线程安全的,仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事。Action资源必须是线程安全的或同步的。 
• Struts2 Action对象为每一个请求产生一个实例,没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,且不会导致性能和垃圾回收问题) 
Servlet 依赖:  
• Struts1 Action依赖于Servlet API ,当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。 
• Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如需,Struts2 Action仍然可以访问初始的request和response。但是其他的元素减少或消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。 
可测性:  
• 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。 
• Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。  
捕获输入:  
• Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因其他JavaBean不能用作ActionForm,开发者常创建多余的类捕获输入。动态Bean(DynaBeans)可作为创建传统ActionForm的选择,但开发者可能是在重新描述(创建)已经存在的JavaBean(仍会导致有冗余的javabean)。 
• Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。 
表达式语言:  
• Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。  
• Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL). 

 

7.AWT和Swing

  • 都是java中的包,swing是awt的升级版,移植性好,各平台外观相同
  • AWT:抽象窗口工具包,建立图形用户界面的工具集,可用于生成现代的、鼠标控制的图形应用接口,且无需修改,就可以在各种软硬件平台上运行。
  • swing:Java语言在编写图形用户界面方面的新技术,Swing采用模型-视图-控制设计范式,Swing可以使Java程序在同一个平台上运行时能够有不同外观以供用户选择。

8.加载驱动的方法

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");

  • DriverManager.getConnection方法返回一个Connection对象,这是加载驱动之后才能进行的

 

9.sleep和wait

 
  1. sleep是线程类(Thread)的方法,wait是Object类的方法;
  2. sleep不释放对象锁,wait放弃对象锁
  3. sleep暂停线程、但监控状态仍然保持,结束后会自动恢复
  4. wait后进入等待锁定池,只有针对此对象发出notify方法后获得对象锁进入就绪状态
  • Java中的多线程是抢占式的机制,而非分时机制。有多个线程处于可运行状态,但只有一个线程在运行。

10.内存和引用例子

//声明了3个Square类型的变量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; 

如图所示:

11.Integer.valueOf

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 中是否存在此对象,如存在,则直接返回引用,否则创建一个新的对象。

---------------------------------------------------------------------------------------------------------------------------

 

  • Integer i01 = 59; 在这里的话,因为程序初次运行,没有 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 会自动拆箱,进行值比较,所以,结果为真。

 

12.异常

13.static

1. public class HasStatic{

2.     private static int x=100;

3.     public static void main(String args[]){

4.          HasStatic hs1=new HasStatic();

5.          hs1.x++;

6.          HasStatic  hs2=new HasStatic();

7.          hs2.x++;

8.          hs1=new HasStatic();

9.          hs1.x++;

10.        HasStatic.x--;

11.        System.out.println("x="+x);

12.     }

13.   } 

输出102

  • static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
  • static变量在第一次使用的时候初始化,但只会有一份成员对象。

14.struts的MVC

15.静动态jsp中的include

  1. 动态 INCLUDE 用 jsp:include 动作实现 <jsp:include page="included.jsp" flush="true" /> 它会检查所含文件中的变化 , 适合用于包含动态页面 , 并且可以带参数。各个文件分别先编译,然后组合成一个文件。
  2. 静态 INCLUDE 用 include 伪码实现 , 定不会检查所含文件的变化 , 适用于包含静态页面 <%@ include file="included.htm" %> 。先将文件的代码被原封不动地加入到了主页面从而合成一个文件,然后再进行翻译,此时不允许有相同的变量。 

     : 执行时间上 :

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

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

     : 引入内容的不同 :

    <%@ include file="relativeURI"%>

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

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

   

静态的include不允许变量同名

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值