JAVA面试、笔试题

@[TOC]目录

JAVA面试、笔试题
@目录 一、 CoreJava部分 7

1. java中有哪些基本类型? 7

2. java反射 7

3. 易错,理解题 7

4. Java有几种创建对象的方法? 8

  1. java为什么能够跨平台运行? 8
  2. 整型数据转换成字符串的方式? 8
  3. String是基本数据类型吗?我可不可以写个类继承于String? 8
  4. 谈谈&和&&的区别? 8
  5. Switch语句里面的条件可不可以是byte、long、String?使用时候还应注意什么? 8
  6. short s1=1;s1=s1+1;有什么错?short s1 = 1;s1+=1 有什么错? 8
  7. char为什么能存贮一个汉字? 9
  8. 用最效率的办法算出2乘以8等于几? 9
  9. final修饰变量时,该变量是对象时,对象的值可不可以改变? 9
  10. 静态变量和实例变量的区别? 9
  11. 面向对象的基本特征是什么? 9
  12. 作用域public,private,protected,以及不写时的区别? 9
  13. Overload和Override的区别。 10
  14. 构造器可不可以被重载或重写? 10
  15. 抽象类和接口的区别? 10
  16. java中实现多态的机制是什么? 10
  17. int和integer的区别? 10
  18. String和StringBuffer的区别?StringBuffer和StringBuilder区别? 10
  19. String s=new String(“xyz”);创建了几个String Object? 11
  20. 数组中有没有length()方法,String中有没有length()方法? 11
  21. try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后? 11
  22. final, finally, finalize的区别。 11
  23. ‘==’和equals的区别? 11
  24. error和exception有什么区别? 11
  25. JAVA 的checked异常和unchecked异常 11
  26. java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 12
  27. sleep() 和 wait() 有什么区别? 12
  28. 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 12
  29. 线程的基本概念、线程的基本状态以及状态之间的关系 12
  30. ArrayList和Vector的区别? 13
  31. List、Set和Map的区别? 13
  32. Collection 和 Collections的区别。 14
  33. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 14
  34. 什么是java序列化,如何实现java序列化? 14
  35. heap和stack有什么区别。 14
  36. 编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad。 15
  37. 说明生活中遇到的二叉树,用java实现二叉树 17
  38. 第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大? 22
  39. 排序都有哪几种方法?请列举。用JAVA实现一个快速排序。 22
  40. 金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。 23
  41. 什么是内部类?分为哪几种?有什么作用? 24
  42. 为什么需要内部类? 24
  43. 内部类可以引用它的包含类的成员吗?有没有什么限制? 25
  44. Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 25
  45. java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 25
  46. 字节流与字符流的区别 25
  47. 复制文件到指定路径 27
    二、 数据库部分 27
  48. 触发器的作用? 27
  49. 什么是存储过程?用什么来调用? 27
  50. 删除表的方式 27
    Delete truncate drop 27
  51. 索引的作用?和它的优点缺点是什么? 27
  52. 什么是事务?什么是锁? 28
  53. 什么叫视图?游标是什么? 28
  54. 列举几种表连接方式,有什么区别? 28
  55. 主键和外键的区别? 29
  56. 在数据库中查询语句速度很慢,如何优化? 29
  57. 数据库三范式是什么? 29
  58. union和union all有什么不同? 30
  59. 用JDBC如何调用存储过程 30
  60. JDBC中的PreparedStatement相比Statement的好处 31
  61. 什么是sql注入? 31
  62. 写一个用jdbc连接实例。 31
  63. 现在有表: 33
  64. 现有表: 33
  65. 怎样把这样一个表(表名:tmp_table_201307) 34
  66. 数据库中有一张表ismg_icp_flow,结构如下 35
  67. Oracle和Mysql的区别? 35
  68. Varchar2和varchar有什么区别? 36
  69. Statement和preparedstatement有什么区别? 36
    三、 XML部分 36
  70. xml有哪些解析技术?区别是什么? 36
  71. 你在项目中用到了xml技术的哪些方面?如何实现的? 37
  72. 编程用JAVA解析XML的方式. 37
  73. XML文档定义有几种形式?它们之间有何本质区别? 39
  74. XML和HTML的区别? 39
  75. XML文件和普通文件相比有哪些优点? 39
  76. 关于JSON 39
    四、 HTML&CSS部分 40
  77. HTML中定义表格的宽度用80px和80%的区别是什么? 40
  78. CSS样式定义优先级顺序是? 40
  79. div和span的区别? 40
  80. CSS选择器包括? 40
  81. 用css3语法中,如何实现一个矩形框的圆角效果和50%红色透明效果?,请写出关键脚本 40
    五、 JavaScript和ajax部分 41
  82. 请写一段Javascript程序,对以下程序的用户输入日期的有效性进行判断,如果格式错误就提示用户。在程序的恰当位置注明怎样调用你写的程序。日期格式为:年年年年月月日日小时,例如2003010812。 41
  83. Java和Javascript区别在哪? 42
  84. 列举javaScript的3种主要数据类型,2种复合数据类型和2种特殊数据类型。 43
  85. 谈谈你的JS的理解? 43
  86. ajax的优点? 43
  87. JS里Ajax的原理 44
  88. 简述一下ajax调试代码查找错误的方法? 44
  89. 简述ajax中Js脚本缓存问题该如何解决? 44
  90. Ajax应用和传统的web应用有何不同? 44
  91. javascript的作用? 44
  92. 为什么要有jquery? 44
  93. jquery选择器有哪些优势? 45
  94. 你是如何使用jquery中的ajax的? 45
  95. jquery中的 . g e t 和 .get和 .get.post请求区别? 45
  96. jquery中如何操作样式的? 45
  97. 如何设置和获取HTML和文本的值? 45
  98. Jquery能做些什么? 45
  99. 在ajax中data主要有哪几种? 45
    六、 web部分 46
  100. Tomcat的优化经验 46
  101. 解释一下什么是servlet;什么是servlet容器; 46
  102. 说一说Servlet的生命周期? 46
  103. HTTP请求的GET与POST方式的区别 46
  104. 请写一个Servlet的基本架构。 46
  105. forward 和redirect的区别? 47
  106. 过滤器有哪些作用? 47
  107. JSP的常用指令? 47
  108. JSP和Servlet中的请求转发分别如何实现? 47
  109. JSP乱码如何解决? 48
  110. session 和 application的区别? 48
  111. jsp有哪些内置对象?作用分别是什么? 48
  112. Jsp有哪些动作?作用分别是什么? 48
  113. JSP中动态INCLUDE与静态INCLUDE的区别? 49
  114. JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 49
  115. MVC的各个部分都有那些技术来实现?如何实现? 49
  116. 页面传递对象的方法? 49
  117. Cookied和session区别? 49
    七、 框架部分 50
  118. 谈谈你对Struts2的理解。 50
  119. 谈谈你对Hibernate的理解。 50
  120. 你对Spring的理解。 50
  121. Struts2优缺点 51
  122. 说说struts1与struts2的区别。 52
  123. struts的核心组件有哪些? 53
  124. struts2获取request的方式? 53
  125. Strus2的执行过程 53
  126. 为什么要使用struts2? 53
  127. Struts2的优缺点? 53
  128. 拦截器的作用?拦截器和过滤器的区别? 54
  129. struts.xml中result的type有哪些类型? 55
  130. 一般情况下,关系数据模型与对象模型之间有哪些匹配关系? 55
  131. hibernate 数据的三个状态 55
  132. Hibernate中load和get的区别? 56
  133. getCurrentSession与openSession的区别 56
  134. Hibernate的工作原理? 56
  135. 为什么要用hibernate? 56
  136. Hibernate是如何延迟加载的? 57
  137. hibernate的缓存 57
  138. 如何优化Hibernate? 58
  139. 什么是ORM? 58
  140. Hibernate的主键生成策略? 58
  141. Hibernate的级联操作 58
  142. Hibernate有哪5个核心接口? 59
  143. 什么是重量级?什么是轻量级? 59
  144. 谈谈Spring的IOC和DI 59
  145. 解释Spring的IoC? 几种注入依赖的方式?Spring的优点? 60
  146. 什么是AOP? 60
  147. Spring的通知类型有哪些? 60
  148. springMVC的运行原理。 61
    八、 设计模式 61
    请写出你所知道的设计模式? 61
    九、 经典案例 62
  149. 说明生活中遇到的二叉树,用java实现二叉树 62
  150. 从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 67
  151. 写一个Singleton出来。 71
  152. 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 73

一、CoreJava部分
Java基础是在面试过程中最常问到的,因为刚刚出去的我们对项目认知并不
很深,对于后框架的知识并没有达到精通,所以基础最重要。如果你有不怕
死的精神可以尝试让面试官问问你框架的。

1.java中有哪些基本类型?

byte、short、int、long、float、double、char、boolean

2.java反射

Java的反射非常强大,传递class, 可以动态的生成该类、取得这个类的所有信息,包括里面的属性、方法以及构造函数等,甚至可以取得其父类或父接口里面的内容。

obj.getClass().getDeclaredMethods();//取得obj类中自己定义的方法, 包括私有的方法。

obj.getClass().getMethods();//取得obj类中自己定义的方法及继承过来的方法, 但私有方法得不到。

 同样, 对field也是一样,obj.getClass().getDeclaredFields();取得的是这个类中所有的属性,包括私有的field; 对obj.getClass().getFields();//取得是自己以及接继承来的属性, 但不能取得自己的私有属性。

3.易错,理解题

class a
{
a(String a){
System.out.println(“父类1参数”);
}
}
public class Hope extends a{
Hope(){
super(“s”);//由于父类没有无参构造方法,所以这里必须明确调用父类中的有参构造,不然会编译错误
System.out.println(“Hope类无参数”);
}
Hope(String s){
super(“s”);//由于父类没有无参构造方法,所以这里必须明确调用父类中的有参构造,不然会编译错误
System.out.println(“Hope类1参数”);
}
public static void main(String args[]){
Hope hope=new Hope(“s”);
}
}

4.Java有几种创建对象的方法?

Java中创建对象的五种方法 
1、使用new关键字创建对象
2、利用java的反射机制,通过java.lang.Class或者java.lang.reflect.Constructor创建对象
3、实现Cloneable接口,然后重写Object.clone()方法创建对象
4、实现序列化serialiable接口,通过反序列化,ObjectInputStream的readObject()方法创建对象
5、String str="abc" 直接由jvm创建 或者使用 字符串操作符"+"  String str1 = "a"+"bc"由jvm创建

5.java为什么能够跨平台运行?

因为Java程序编译之后的代码不是能被硬件系统直接运行的代码,而是一种“中间码”——字节码。然后不同的硬件平台上安装有不同的Java虚拟机(JVM),由JVM来把字节码再“翻译”成所对应的硬件平台能够执行的代码。因此对于Java编程者来说,不需要考虑硬件平台是什么。所以Java可以跨平台。

6.整型数据转换成字符串的方式?

1、 直接在数字后面加上空格;
2、 使用String.valueOf(int i);
3、 Integer.toString(i);

7.String是基本数据类型吗?我可不可以写个类继承于String?

不是,Strng是引用类型;String是final的类,是不可以被继承的。

8.谈谈&和&&的区别?

&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式。
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作.。

9.Switch语句里面的条件可不可以是byte、long、String?使用时候还应注意什么?

switch里面的条件必须是能隐式的转化成为Int的故long和String不行,byte可以;使用Switch时候还应注意它的穿透,即每个case后要跟break;

10.short s1=1;s1=s1+1;有什么错?short s1 = 1;s1+=1 有什么错?

对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。
  对于short s1 = 1; s1 += 1;由于 += 是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译。

11.char为什么能存贮一个汉字?

char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了全世界所 有的字体。

12.用最效率的办法算出2乘以8等于几?

2<<3 位移运算是最底层的运算,他直接操作的是二进制,故效率最快。

13.final修饰变量时,该变量是对象时,对象的值可不可以改变?

final修饰的变量指的是引用不可变,对象的值是可以改变的。

14.静态变量和实例变量的区别?

静态变量也称为类变量,归全类共有,它不依赖于某个对象,可通过类名直接访问;而实例变量必须依存于某一实例,只能通过对象才能访问到它。

15.面向对象的基本特征是什么?

继承:好比如你继承你老爸的事业,等于你有了你老爸一样的东西。    
在程序里,以class A是爸,class B extends A代表B继承A,B也就有了A的一切,即属性与方法。但不能拥有你爸爸的秘密的东西,比如他的日记,也就是不能继承私有属性与方法。
封装:就是遥控车一样,你有个遥控,就能控制车子,但你是看不到遥控的电路设计的,因为你不必要知道,为什么要封闭,就怕你乱接电路,让遥控用不了。程序里,在属性和方法前面加上private关键字,就表示封闭属性和方法了,只能类的内部访问。
多态:用的是同一个东西,但得到的结果却不一样,同一个方法,可以得到不同结果, 
多态性:发送消息给某个对象,让该对象自行决定响应何种行为。通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。
抽象:比如说人是个抽象,它有的部分行为已经确定,但是不能说人实实在在的存在,只能说张三实实在在存在。只要有抽象方法的类就是抽象类。只能单继承[extends],不能实例化。
       1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意			与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一				部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

2)继承:子类拥有父类一切非私有的属性和方法。
3)封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面 向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装 的对象,这些对象通过一个受保护的接口访问其他对象。
4)多态性:同一种事物的不同种表现形式。

16.作用域public,private,protected,以及不写时的区别?

作用域		  当前类		同包	   子孙类	    其他
public        √         √         √         √ 
protected     √         √         √         × 
default       √         √         ×         × 
private       √         ×         ×         × 
不写时默认为default。

17.Overload和Override的区别。

(Overload)重载:发生在同一个类之中,方法名相同、参数列表不同,与返回值无关、与final无关、与修饰符无关、与异常无关。
(Override)重写:发生在子类和父类之间,方法名相同、参数列表相同、返回值相同、不能是final的方法、重写的方法不能有比父类方法更为严格的修饰符权限、重写的方法所抛出的异常不能比父类的更大。
如果父类私有的方法,子类拥有方法签名相同的方法,子类不属于重写父类的方法,该方法属于子类的新方法。

18.构造器可不可以被重载或重写?

构造器不能被继承,故不能被重写、但可以被重载。

19.Java中有没有多继承?

java中没有多继承,但是可以多实现,即一个类实现多个接口。
虽然没有多继承,但是java中接口可以近似的实现多继承,那就是接口;接口和接口之间可以进行多继承。

20.抽象类和接口的区别?

a.抽象类继承与object接口不继承object.
b.抽象类有构造器,接口中没有构造器。
c.抽象类中可以有普通成员变量和常量,接口中只能有常量,而且只能是
public static final 不写默认。
d.抽象类中可以有抽象方法,也可以由普通的方法,接口中只能有抽象的方法而且修饰符只能是public abstract 不写默认。
e.抽象类中可以有final的方法,接口中不能有final的方法。
f.抽象类只能是单继承,多实现,接口是可以多继承其他接口,但是不能实现接口,和不能继承其他类。
g.抽象类中可以有静态的方法,接口中不可以。

21.java中实现多态的机制是什么?

重写、重载、父类的声明指向子类的对象。

22.int和integer的区别?

int是java的基本数据类型,integer是1.4版本后提供的基本类型包装类,当两者作为成员变量时,初始值分别为;int是0;integer是null;其中integer提供了一些对整数操作的方法,还定义了integer型数值的最值,其他基本类型也有对应的包装类,基本类型包装类的出现,使得java完全面向对象.

23.String和StringBuffer的区别?StringBuffer和StringBuilder区别?

String是不可变的,对String类的任何改变都会返回一个新的String 对象。
StringBuffer是可变的,对StringBuffer中的内容修改都是当前这个对象。
String重写了equals方法和hashCode方法,StringBuffer没有重写equals方 法。
String是final的类。StringBuffer不是。
String创建的字符串是在常量池中,创建的变量初始化一次,如果再对该字符串改变会产生新的字符串地址值,StringBuffer是在堆中创建对象,当对字符串改变时不会产生新的字符串地址值,如果对字符串进行频繁修改的话建议使用StringBuffer,以节省内存。
StringBuffer和StringBuilder,StringBuffer是线程安全的,StringBulider是线程不安全的。当不考虑并发问题时候,请使用StringBulider。

24.String s=new String(“xyz”);创建了几个String Object?

两个对象,一个是"xyx",一个是指向"xyx"的引用对象s。

25.数组中有没有length()方法,String中有没有length()方法?

数组中没有length()方法,但是有length属性,String中有length()方法

26.try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

这道题很有争议,我是通过debug模式分为两种情况进行测试的.
a.finally中没有return时候:
会先执行try里面的,return会执行但是没有真正的return此时去执行了finally里面的,然后再返回来执行return.
b.finally中有return时候(其实这种情况不符合编程规范,会报黄线警告):
会先执行try里面的,return会执行但是没有真正的return此时去执行了finally里面的,然后执行finally里面的return,直接返回。

27.final, finally, finalize的区别。

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用

28.‘==’和equals的区别?

’比较的是两个变量的内容和在内存中的地址值是否全部相等,如果要比较两个基本数据类型那必须用’
equals如果没有重写,则和’==’的意义一样,如果重写了,则会会按照重写的内容进行比较,javaBean规定当重写equals时候必须重写hashCode,如果不重写会出现对象相同但是hashCode不同,这样会出现问题,eg:HashSet存储元素时候是按照hashCode,如果重写equals不重写hashCode会导致同一个对象,存储了两次。

29.error和exception有什么区别?

error表示恢复不是不可能但是很困难的情况下的一种严重问题,例如程序书写错误,虚拟机错误等,exception是一种设计和实现问题,如果程序运行正常,从不会发生的情况。error是可以避免的,exception是不可避免的。

30.JAVA 的checked异常和unchecked异常

1、unchecked异常即运行时异常。即RuntimeException(运行时异常),不需要try…catch …或者throws机制去处理的异常;
2、除了RuntimeException,其他继承自java.lang.exception的异常统称为checked Exception。

31.java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?

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

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

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

33.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

分几种情况:
1.其他方法前是否加了synchronized关键字,如果没加,则能。
2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。

34.线程的基本概念、线程的基本状态以及状态之间的关系

一个新的线程可以使用两种方式创建:1、继承Thread类2、实现Runnable接口,创建之后通过start方法进入到运行状态,在运行状态中可以使用yield方法进行礼让,但是仍然可以进行,如果现在一个线程需要暂停的话,可以使用suspend(暂时挂起,resume表示恢复挂起)、sleep、wait方法,如果现在让线程不再执行,则可以通过stop结束,run方法运行完也表示结束。其中suspend、resume、stop方法都可能产生死锁的问题,所以不建议使用了。应该通过设置标示位来控制线程的停止运行。
一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。
调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。

35.ArrayList和Vector的区别?

这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。
接着才说ArrayList与Vector的区别,这主要包括两个方面:.
(1)同步性:
Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。所以,我们讲课时先讲老的。
(2)数据增长:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。

36.List、Set和Map的区别?
a.List和Set是Collection的子接口,map不是。
b.List的底层是数组的方式实现,Set是散列表的方式实现,map是键值对的方式。
c.list是有序可重复的,Set是无序不可重复的,map是有序,key不重复,value可重复
d.list和Set可直接使用itertator来进行遍历,map只能通过先遍历Key在遍历value.

37.Collection 和 Collections的区别。
Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

38.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用还是equals()? 它们有何区别?
Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。
equals()和
方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

39.什么是java序列化,如何实现java序列化?
通俗的说,就是可以将内存中Java对象可以写在硬盘上(序列化到硬盘上),反序列化就是讲硬盘的内容读取到内存中去;java是通过实现Serializable接口,实现的序列化,Serializable接口里面没有任何的方法,只是个标示接口。

40.heap和stack有什么区别。
Java栈主要用来存储线程执行过程中的局部变量、方法的返回值,以及方法调用上下文。栈空间随着线程的终止而释放。

特点:

  1. 栈的特点是 :
    容量小 速度快 适合存放小型数据
    如基本数据类型和对象类型的引用
    在栈中变量直接指向存放变量值的空间 对于对象引用则存放对象在堆中的内存地址.
    2…堆的特点和栈相反 :
    因此适合存放对象本身
    3… 对象引用访问对象的原理是 :
    先通过该引用找到栈中的数据 即对象的地址 在通过该地址访问对象 这就是为什么 对象 a=null; 调用a.方法(属性) 会引发异常 因为找不到实际对象的地址

堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

java内存分成4块,一块是堆,用来存放new的对象,一个是栈,用来存放局部变量,然后就是静态变量区,存放常量,静态变量,以及代码区,存放代码,所以很说静态变量区是和堆栈并列的,并不从属的.

java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

41.GC是什么? 为什么要有GC?
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

42.编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad。
答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Jad2Java {

public static void main(String[] args) throws Exception {
	File srcDir = new File("java");
	if(!(srcDir.exists() && srcDir.isDirectory()))
			throw new Exception("目录不存在");
	File[] files = srcDir.listFiles(
		new FilenameFilter(){

				public boolean accept(File dir, String name) {
					return name.endsWith(".java");
				}
				
			}
	);
	
	System.out.println(files.length);
	File destDir = new File("jad");
	if(!destDir.exists()) destDir.mkdir();
	for(File f :files){
		FileInputStream  fis = new FileInputStream(f);
		String destFileName = f.getName().replaceAll("\\.java$", ".jad");
		FileOutputStream fos = new FileOutputStream(new File(destDir,destFileName));
		copy(fis,fos);
		fis.close();
		fos.close();
	}
}

private static void copy(InputStream ips,OutputStream ops) throws Exception{
	int len = 0;
	byte[] buf = new byte[1024];
	while((len = ips.read(buf)) != -1){
		ops.write(buf,0,len);
	}

}

}

由本题总结的思想及策略模式的解析:
1.
class jad2java{
1. 得到某个目录下的所有的java文件集合
1.1 得到目录 File srcDir = new File(“d:\java”);
1.2 得到目录下的所有java文件:File[] files = srcDir.listFiles(new MyFileFilter());
1.3 只想得到.java的文件: class MyFileFilter implememyts FileFilter{
public boolean accept(File pathname){
return pathname.getName().endsWith(“.java”)
}
}

2.将每个文件复制到另外一个目录,并改扩展名
	2.1 得到目标目录,如果目标目录不存在,则创建之
	2.2 根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。
	2.3 根据表示目录的File和目标文件名的字符串,得到表示目标文件的File。
		//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。 
	2.4 将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。
		//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。	

}

分析listFiles方法内部的策略模式实现原理
File[] listFiles(FileFilter filter){
File[] files = listFiles();
//Arraylist acceptedFilesList = new ArrayList();
File[] acceptedFiles = new File[files.length];
int pos = 0;
for(File file: files){
boolean accepted = filter.accept(file);
if(accepted){
//acceptedFilesList.add(file);
acceptedFiles[pos++] = file;
}
}

Arrays.copyOf(acceptedFiles,pos);
//return (File[])accpetedFilesList.toArray();

}

43.说明生活中遇到的二叉树,用java实现二叉树
这是组合设计模式。
我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:

代码如下:
package com.huawei.interview;

public class Node {
public int value;
public Node left;
public Node right;

public void store(int value)
{
	if(value<this.value)
	{
		if(left == null)
		{
			left = new Node();
			left.value=value;
		}
		else
		{
			left.store(value);
		}
	}
	else if(value>this.value)
	{
		if(right == null)
		{
			right = new Node();
			right.value=value;
		}
		else
		{
			right.store(value);
		}			
	}
}

public boolean find(int value)
{	
	System.out.println("happen " + this.value);
	if(value == this.value)
	{
		return true;
	}
	else if(value>this.value)
	{
		if(right == null) return false;
		return right.find(value);
	}else
	{
		if(left == null) return false;
		return left.find(value);
	}

}

public  void preList()
{
	System.out.print(this.value + ",");
	if(left!=null) left.preList();
	if(right!=null) right.preList();
}

public void middleList()
{
	if(left!=null) left.preList();
	System.out.print(this.value + ",");
	if(right!=null) right.preList();		
}
public void afterList()
{
	if(left!=null) left.preList();
	if(right!=null) right.preList();
	System.out.print(this.value + ",");		
}	
public static void main(String [] args)
{
	int [] data = new int[20];
	for(int i=0;i<data.length;i++)
	{
		data[i] = (int)(Math.random()*100) + 1;
		System.out.print(data[i] + ",");
	}
	System.out.println();
	
	Node root = new Node();
	root.value = data[0];
	for(int i=1;i<data.length;i++)
	{
		root.store(data[i]);
	}
	
	root.find(data[19]);
	
	root.preList();
	System.out.println();
	root.middleList();
	System.out.println();		
	root.afterList();
}

}
-----------------又一次临场写的代码---------------------------
import java.util.Arrays;
import java.util.Iterator;

public class Node {
private Node left;
private Node right;
private int value;
//private int num;

public Node(int value){
	this.value = value;
}
public void add(int value){
	
	if(value > this.value)
	{
		if(right != null)
			right.add(value);
		else
		{
			Node node = new Node(value);				
			right = node;
		}
	}
	else{
		if(left != null)
			left.add(value);
		else
		{
			Node node = new Node(value);				
			left = node;
		}			
	}
}

public boolean find(int value){
	if(value == this.value) return true;
	else if(value > this.value){
		if(right == null) return false;
		else return right.find(value);
	}else{
		if(left == null) return false;
		else return left.find(value);			
	}

}

public void display(){
	System.out.println(value);
	if(left != null) left.display();
	if(right != null) right.display();
	
}

/*public Iterator iterator(){
	
}*/

public static void main(String[] args){
	int[] values = new int[8];
	for(int i=0;i<8;i++){
		int num = (int)(Math.random() * 15);
		//System.out.println(num);
		//if(Arrays.binarySearch(values, num)<0)
		if(!contains(values,num))
			values[i] = num;
		else
			i--;
	}
	
	System.out.println(Arrays.toString(values));
	
	Node root  = new Node(values[0]);
	for(int i=1;i<values.length;i++){
		root.add(values[i]);
	}
	
	System.out.println(root.find(13));
	
	root.display();
	
}

public static boolean contains(int [] arr, int value){
	int i = 0;
	for(;i<arr.length;i++){
		if(arr[i] == value) return true;
		
	}
	return false;
}

}

44.第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
package cn.itcast;

import java.util.Date;

public class A1 {

public static void main(String [] args)
{
	System.out.println(computeAge(8));
}

public static int computeAge(int n)
{
	if(n==1) return 10;
	return computeAge(n-1) + 2;
}

}

public static void toBinary(int n,StringBuffer result)
{

	if(n/2 != 0)
		toBinary(n/2,result);
	result.append(n%2);		
}

45.排序都有哪几种方法?请列举。用JAVA实现一个快速排序。
public class QuickSort {
/**

  • 快速排序
  • @param strDate
  • @param left
  • @param right
    */
    public void quickSort(String[] strDate,int left,int right){
    String middle,tempDate;
    int i,j;
    i=left;
    j=right;
    middle=strDate[(i+j)/2];
    do{
    while(strDate[i].compareTo(middle)<0&& i<right)
    i++; //找出左边比中间值大的数
    while(strDate[j].compareTo(middle)>0&& j>left)
    j–; //找出右边比中间值小的数
    if(i<=j){ //将左边大的数和右边小的数进行替换
    tempDate=strDate[i];
    strDate[i]=strDate[j];
    strDate[j]=tempDate;
    i++;
    j–;
    }
    }while(i<=j); //当两者交错时停止

if(i<right){
quickSort(strDate,i,right);//从
}
if(j>left){
quickSort(strDate,left,j);
}
}
/**

  • @param args
    */
    public static void main(String[] args){
    String[] strVoid=new String[]{“11”,“66”,“22”,“0”,“55”,“22”,“0”,“32”};
    QuickSort sort=new QuickSort();
    sort.quickSort(strVoid,0,strVoid.length-1);
    for(int i=0;i<strVoid.length;i++){
    System.out.println(strVoid[i]+" ");
    }
    }
    }

46.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
去零的代码:
return sb.reverse().toString().replaceAll(“零[拾佰仟]”,“零”).replaceAll(“零+万”,“万”).replaceAll(“零+元”,“元”).replaceAll(“零+”,“零”);

public class RenMingBi {

/**
 * @param args add by zxx ,Nov 29, 2008
 */
private static final char[] data = new char[]{
		'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'
	}; 
private static final char[] units = new char[]{
	'元','拾','佰','仟','万','拾','佰','仟','亿'
};
public static void main(String[] args) {
	// TODO Auto-generated method stub
	System.out.println(
			convert(135689123));
}

public static String convert(int money)
{
	StringBuffer sbf = new StringBuffer();
	int unit = 0;
	while(money!=0)
	{
		sbf.insert(0,units[unit++]);
		int number = money%10;
		sbf.insert(0, data[number]);
		money /= 10;
	}

	return sbf.toString();
}

}

47.什么是内部类?分为哪几种?有什么作用?
内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权限)。
内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类。
作用:
1、 内部类可以很好的实现隐藏;
2、 内部类拥有外围类的所有元素的访问权限;
3、 可以实现多重继承;
4、 可以避免修改接口而实现同一个类中两种方法的调用。

48.为什么需要内部类?
典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。
使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。

49.内部类可以引用它的包含类的成员吗?有没有什么限制?
完全可以。如果不是静态内部类,那没有什么限制!
如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码:
class Outer
{
static int x;
static class Inner
{
void test()
{
syso(x);
}
}
}

答题时,也要能察言观色,揣摩提问者的心思,显然人家希望你说的是静态内部类不能访问外部类的成员,但你一上来就顶牛,这不好,要先顺着人家,让人家满意,然后再说特殊情况,让人家吃惊。

50.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
可以继承其他类或实现其他接口。不仅是可以,而是必须!

51.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
字节流,字符流。字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便

52.字节流与字符流的区别
把一片二进制数据数据逐一输出到某个设备中,或者从某个设备中逐一读取一片二进制数据,不管输入输出设备是什么,我们要用统一的方式来完成这些操作,用一种抽象的方式进行描述,这个抽象描述方式起名为IO流,对应的抽象类为OutputStream和InputStream ,不同的实现类就代表不同的输入和输出设备,它们都是针对字节进行操作的。
在应用中,经常要完全是字符的一段文本输出去或读进来,用字节流可以吗?计算机中的一切最终都是二进制的字节形式存在。对于“中国”这些字符,首先要得到其对应的字节,然后将字节写入到输出流。读取时,首先读到的是字节,可是我们要把它显示为字符,我们需要将字节转换成字符。由于这样的需求很广泛,人家专门提供了字符流的包装类。
底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节再进行写入。字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向IO设别写入或读取字符串提供了一点点方便。
字符向字节转换时,要注意编码的问题,因为字符串转成字节数组,
其实是转成该字符的某种编码的字节形式,读取也是反之的道理。

讲解字节流与字符流关系的代码案例:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class IOTest {
public static void main(String[] args) throws Exception {
String str = “中国人”;
/*FileOutputStream fos = new FileOutputStream(“1.txt”);

	fos.write(str.getBytes("UTF-8"));
	fos.close();*/
	
	/*FileWriter fw = new FileWriter("1.txt");
	fw.write(str);
	fw.close();*/
	PrintWriter pw = new PrintWriter("1.txt","utf-8");
	pw.write(str);
	pw.close();
	
	/*FileReader fr = new FileReader("1.txt");
	char[] buf = new char[1024];
	int len = fr.read(buf);
	String myStr = new String(buf,0,len);
	System.out.println(myStr);*/
	/*FileInputStream fr = new FileInputStream("1.txt");
	byte[] buf = new byte[1024];
	int len = fr.read(buf);
	String myStr = new String(buf,0,len,"UTF-8");
	System.out.println(myStr);*/
	BufferedReader br = new BufferedReader(
			new InputStreamReader(
				new FileInputStream("1.txt"),"UTF-8"	
				)
			);
	String myStr = br.readLine();
	br.close();
	System.out.println(myStr);
}

53.复制文件到指定路径
流程:首先获取指定需要复制的文件(new File对象),以及获取指定要复制到路径;
对复制到的目标路径进行判断是否存在,再分别创建文件输入流和输出流的实体对象。循环读取数据并同时保存数据。最后关闭输入输出流。

二、数据库部分
1.触发器的作用?
答:触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的。它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算。如,某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。

2.什么是存储过程?用什么来调用?
答:存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。可以用一个命令对象来调用存储过程。
CREATE OR REPLACE PROCEDURE 存储过程名字
(
参数1 IN NUMBER,
参数2 IN NUMBER
) IS
变量1 INTEGER :=0;
变量2 DATE;
BEGIN

END 存储过程名字

3.删除表的方式
Delete truncate drop
drop是删除表,使用drop之后表结构和表的数据都会被删除,truncate 和 delete是删除表里的数据,但不删除表本身,truncate 和 delete相比,truncate要快很多,但缺点就是不能回滚,包括索引等都会变成初始值,数据就无法恢复了。

4.索引的作用?和它的优点缺点是什么?
答:索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速对数据的检索。它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者是多个列。缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。

5.什么是事务?什么是锁?
事务处理:
数据的操作是一个整体,可以理解为一个完整的业务,如果其中出错,则所有的操作都应该不再执行,并且回归到最原始的状态,而这一个操作流程就是事务的操作。
所有的事务操作都是针对每一个session进行的,每一个链接到数据库的用户都成为一个session,每一个session之间彼此独立,不会有任何的通讯,而每一个session独享自己的事务控制,而事务控制之中有两个命令:rollback和commit。
这样会出现一些问题:例如某一个session在更新数据时还没有提交事务,其他session是无法更新的,必须等待之前的session提交后才可以,这种问题从大的方面上讲可以成为死锁。
答:事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。
锁:在所以的DBMS中,锁是实现事务的关键,锁可以保证事务的完整性和并发性。与现实生活中锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。当然锁还分级别的。

6.什么叫视图?游标是什么?
答:视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,试图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。
游标字面理解就是游动的光标。
用数据库语言来描述:游标是映射在结果集中一行数据上的位置实体,有了游标,用户就可以访问结果集中的任意一行数据了,将游标放置到某行后,即可对该行数据进行操作,例如提取当前行的数据等。
游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。

7.列举几种表连接方式,有什么区别?
内连接、自连接、外连接(左、右、全)、交叉连接
内连接:只有两个元素表相匹配的才能在结果集中显示。
自连接:自己跟自己关联查询,数据表使用不同的别名。
外连接:
左外连接:左边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。
右外连接:右边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。 全外连接:连接的表中不匹配的数据全部会显示出来。
交叉连接: 笛卡尔效应,显示的结果是链接表数的乘积。

8.主键和外键的区别?
答:主键在本表中是唯一的、不可唯空的,外键可以重复可以唯空;外键和另一张表的主键关联,不能创建对应表中不存在的外键。

9.在数据库中查询语句速度很慢,如何优化?
答:
1.建索引
2.减少表之间的关联
3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据 量大的表排在前面
4.简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据
5.尽量用PreparedStatement来查询,不要用Statement

10.数据库三范式是什么?
第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式)
数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。

第二范式(2NF):
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
要求数据库表中的每个实例或行必须可以被惟一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。

第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。

第三范式的要求如下:
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
所以第三范式具有如下特征:
1,每一列只有一个值
2,每一行都能区分。
3,每一个表都不包含其他表已经包含的非主关键字信息。
例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。

11.union和union all有什么不同?
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION。
UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
 从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL。

12.用JDBC如何调用存储过程
  代码如下:
package com.huawei.interview.lym;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;

public class JdbcTest {

/**
 * @param args
 */
public static void main(String[] args) {
	// TODO Auto-generated method stub
	Connection cn = null;
	CallableStatement cstmt = null;		
	try {
		//这里最好不要这么干,因为驱动名写死在程序中了
		Class.forName("com.mysql.jdbc.Driver");
		//实际项目中,这里应用DataSource数据,如果用框架,
		//这个数据源不需要我们编码创建,我们只需Datasource ds = context.lookup()
		//cn = ds.getConnection();			
		cn = DriverManager.getConnection("jdbc:mysql:///test","root","root");
		cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
		cstmt.registerOutParameter(3,Types.INTEGER);
		cstmt.setString(1, "wangwu");
		cstmt.setInt(2, 25);
		cstmt.execute();
		//get第几个,不同的数据库不一样,建议不写
		System.out.println(cstmt.getString(3));
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	finally
	{

		/*try{cstmt.close();}catch(Exception e){}
		try{cn.close();}catch(Exception e){}*/
		try {
			if(cstmt != null)
				cstmt.close();
			if(cn != null)				
				cn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

13.JDBC中的PreparedStatement相比Statement的好处
a) 提高性能
b) 防止sql注入
14.什么是sql注入?
是的,注入漏洞是由于在参数值改变了sql的执行逻辑,例如
//username正常情况下应该是一个用户名只包含数字或者英文字母,
//但是当用户填写的是下面的串的时候,注入漏洞就发生了
String username=" a’ or 1=1 “;//注意:此时的1=1是永真条件
String pssword=“xxx”;
String sql=“select * from users where password='”+password+”’ and user_name = ’ "+username;
此时不管密码的什么都能查询到数据。相当于绕过验证了。
PreparedStatement的参数注入功能会把参数里的特殊字符进入转义,单引号这样的是会被转义的,所以sql的逻辑不会因为参数值发生改变,注入漏洞就不可能发生了

15.写一个用jdbc连接实例。
package com.tarena.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**

  • @author lwq
    *jdbc连接数据库
    */
    public class JDBCUtil {
    private static Properties properties = new Properties();
    static {
    InputStream in = JDBCUtil.class
    .getResourceAsStream(“config.properties”);
    try {
    properties.load(in);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    public static Connection getConnection() {
    Connection connection = null;
    try {
    Class.forName(properties.getProperty(“drivername”));
    connection = DriverManager.getConnection(
    properties.getProperty(“url”),
    properties.getProperty(“username”),
    properties.getProperty(“pwd”));
    } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return connection;
    }

    public static void close(ResultSet rs, Statement ps, Connection conn) {

     try {
     	if (rs != null)
     		rs.close();
     	if (ps != null)
     		ps.close();
     	if(conn!=null)
     		conn.close();
     } catch (SQLException e) {
     	// TODO Auto-generated catch block
     	e.printStackTrace();
     }
    

    }
    }

16.现在有表:
A(id ,name,regdate)
B(id,groupid)
C(id,name2)
写出下面的SQL语句
A)统计A表中每个月注册用户数
select count(),to_char(regdate,‘yyyymm’) from A group by to_char(regdate,‘yyyymm’);
B)统计A表中有姓名相同的用户数
select count(
) from (select name from A group by name having count() >1);
C)如果表A中有姓名相同的用户,把相同的查出,写入表C中
nsert into C(name2) select name from A group by name having count(
) >1;
D)A中ID有多个相同的数据,A中姓名相同的ID只保留注册时间最大的数据
delete from E where e.regdate < (select max(regdate) from a X where E.id = X.id);

17.现有表:
Student(S#,SN,SD)学生表
Course(C#,CN,T#)课程表
SC(S#,C#,score)成绩表
1.查询选了课程‘税收’的学生的学号和名字
答:
select SN,SD from Student where S# in(
select S# from Course C , SC where C.C#=SC.C# and CN=’税收基础’);
2.查询选课数量大于5的学生的学号和名字
答:
select SN,SD from Student where S# in (
select S# from SC group by S# having count(distinct C#) > 5);
)

3.建立一个学生表students,包括name,age,head_teacher,id,score(姓名,年龄,班主任,学号,成绩)
Create table students(
Id number(9) not null primary key,
Name varchar2(40) not null,
Age int check(age between 0 and 100),
Head_teacher vachar2(40),
Score float
);

4.对上表插入一条记录,姓名:张三,年龄:18,班主任:李四,学号:22
Insert into student(id,name,age,head_teacher) values(‘22’,’张三’,’18’,’李四’);

5.对上表中的age+name创建一个索引,并说明它的作用和使用方法
Create index student_index on students(age,name);

18.怎样把这样一个表(表名:tmp_table_201307)
year month amount
2012 1 1.1
2012 2 1.2
2012 3 1.3
2012 4 1.4
2012 4 1.6
2013 1 2.1
2013 2 2.2
2013 2 2.2
2013 3 2.3
 2013 4 2.4
  查成这样一个结果
  year m1 m2 m3 m4
  2012 1.1 1.2 1.3 3
  2013 2.1 4.4 2.3 2.4
  Select
  year,
  Sum(case when month = 1 then amount else 0 end) as m1,
  Sum(case when month = 2 then amount else 0 end) as m2,
  Sum(case when month = 3 then amount else 0 end) as m3,
  Sum(case when month = 4 then amount else 0 end) as m4
  From tmp_table_201307 a
  Group by year
  Order by 1;

19.数据库中有一张表ismg_icp_flow,结构如下
SQL> desc ismg_icp_flow
Name Null Type
————————————————————————————————
ICPNO NOT NULL VARCHAR2(6)
SERVICE_ID NOT NULL VARCHAR2(10)
STAT_MIN NOT NULL DATETIME
MT_RECV_OK NOT NULL NUMBER(10)
请写出一条SQL语句同时满足以下3个条件:
计算MT_RECV_OK的总和(显示为total),并以此对结果集进行升序排序
以ICPNO和SERVICE_ID两个字段进行分组
所得出数据的STAT_MIN必须为大于2003年1月1号0时0分并且小于2003 年2月1号0时0分
期望的输出结果如下:
ICPNO SERVICE_ID TOTAL
———— —————— ————————————
901001 7700 271965
901001 7800 3857795

答:
select ICPNO,SERVICE_ID,sum(MT_RECV_OK) TOTAL
from ismg_icp_flow
where STAT_MIN between to_date(‘2003-1-1’,‘yyyy-mm-dd’)
and to_date(‘2003-2-1’,‘yyyy-mm-dd’)
group by ICPNO,SERVICE_ID
order by TOTAL;

20.Oracle和Mysql的区别?
1.库函数不同。
2.Oracle是用表空间来管理的,Mysql不是。
3.显示当前所有的表、用户、改变连接用户、显示当前连接用户、执行外部脚本的语句的不同。
4.分页查询时候时候,mysql用limt oracle用rownum
5.sql的语法的不同。

21.Varchar2和varchar,char有什么区别?
a) Char的长度是固定的,而varchar2的长度是可以变化的,比如,存储字符串“abc”对于char(20),表示你存储的字符将占20个字节,包含17个空,而同样的varchar2(20)只占了3个字节,20只是最大值,当你存储的字符小于20时,按实际长度存储。
b) char的效率要被varchar2的效率高。
c) 目前varchar是varchar2的同义词,工业标准的varchar类型可以存储空字符串,但是oracle不能这样做,尽管它保留以后这样做的权利。Oracle自己开发了一个数据类型varchar2,这个类型不是一个标准的varchar,他将在数据库中varchar列可以存储空字符串的特性改为存储null值,如果你想有向后兼容的能力,oracle建议使用varchar2而不是varchar.
22.Statement和preparedstatement有什么区别?
后者的效率比前者高,在使用preparedStatement对象执行sql时候,命令被数据库编译和解析,然后被放到命令缓冲区,然后每当执行同一个preparedStatement时候,他就被再解析一次,但不会在编译,在缓冲区中可以发现预编译的命令,并且可以重新使用。
如果你要写Insert update delete 最好使用preparedStatement,在有大量用户的企业级应用软件中,经常会执行相同的sql,使用preparedStatement会增加整体的性能。

三、XML部分
1.xml有哪些解析技术?区别是什么?
有DOM,SAX,STAX等 DOM4J、JDOM?
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问,SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问
STAX:Streaming API for XML (StAX)
DOM解析的优缺点:优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
Sax解析的优缺点:优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
DOM4J生成和解析XML文档:DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。
JDOM解析的优缺点:为减少DOM、SAX的编码量,出现了JDOM;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。

2.你在项目中用到了xml技术的哪些方面?如何实现的?
用到了数据存贮,信息配置两方面。在做数据交换平台时,将不能数据源的数据组装成XML文件,然后将XML文件压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时,利用XML可以很方便的进行,软件的各种配置参数都存贮在XML文件中。

3.编程用JAVA解析XML的方式.
答:用SAX方式解析XML,XML文件如下:

<?xml version=1.0 encoding=gb2312?> 王小明 信息学院 6258113 男,1955年生,博士,95年调入海南大学 事件回调类SAXHandler.java import java.io.*; import java.util.Hashtable; import org.xml.sax.*; public class SAXHandler extends HandlerBase { private Hashtable table = new Hashtable(); private String currentElement = null; private String currentValue = null; public void setTable(Hashtable table) { this.table = table; } public Hashtable getTable() { return table; } public void startElement(String tag, AttributeList attrs) throws SAXException { currentElement = tag; } public void characters(char[] ch, int start, int length) throws SAXException { currentValue = new String(ch, start, length); } public void endElement(String name) throws SAXException { if (currentElement.equals(name)) table.put(currentElement, currentValue); }

}
JSP内容显示源码,SaxXml.jsp:

剖析XML文件people.xml <%@ page errorPage=ErrPage.jsp contentType=text/html;charset=GB2312 %> <%@ page import=java.io.* %> <%@ page import=java.util.Hashtable %> <%@ page import=org.w3c.dom.* %> <%@ page import=org.xml.sax.* %> <%@ page import=javax.xml.parsers.SAXParserFactory %> <%@ page import=javax.xml.parsers.SAXParser %> <%@ page import=SAXHandler %> <% File file = new File(c:\people.xml); FileReader reader = new FileReader(file); Parser parser; SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); SAXHandler handler = new SAXHandler(); sp.parse(new InputSource(reader), handler); Hashtable hashTable = handler.getTable(); out.println(); out.println( + ); out.println( + ); out.println( + ); out.println( + ); out.println(
教师信息表
姓名 + (String)hashTable.get(new String(name)) +
学院 + (String)hashTable.get(new String(college))+
电话 + (String)hashTable.get(new String(telephone)) +
备注 + (String)hashTable.get(new String(notes)) +
); %>

4.XML文档定义有几种形式?它们之间有何本质区别?
a: 两种形式 dtd schema,b: 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的),

5.XML和HTML的区别?
a) 设计上的区别:XML用来存储数据,重点在于数据本身,HTML用来定义数据,重在数据的显示模式。
b) XML可扩展性强,因为他本身就是可拓展性标记语言,课创建个性化的标记语言,提供更多数据操作。
c) XML语法比HTML严格。
i. 起始标签和结束标签要匹配
ii. 嵌套标签不能相互嵌套
iii. 区分大小写
d) XML属性必须放在引号中,,HTML可有可无。
e) XML必须有相应值,但HTML可以有不带属性的属性名。

6.XML文件和普通文件相比有哪些优点?
a) XML是一个标准的技术,在处理上可以更加的统一
b) 从对配置文件的后期处理上,对XML的操作的API更多,更方便,而文本文件不是特别方便。
c) XML可以有定义语法的DTD文件,这样兑取配置信息的时候,可以先根据DTD检查当前的XML配置文件是否语法正确,而文本文件没有办法检查语法。
d) XML可以非常方便的转换成其他格式的文件,而文本不可以。
e) XML利用xslt可以非常方便的转换成其他格式的文件,文本文件很难做到。
f) XML可以非常方便的搜索其中的一些配置信息,试想如果配置文件很大,优点还是很明显的,而文本文件则不太方便。
g) XML可以携带很多、更丰富的配置信息,文本文件不容易做到

7.关于JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,主要用于传送数据。
JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。这个字符串看起来有点儿古怪,但是 JavaScript 很容易解释它,而且 JSON 可以表示比"名称 / 值对"更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
四、HTML&CSS部分
1.HTML中定义表格的宽度用80px和80%的区别是什么?
PX标识像素,%标识整个页面的宽度百分比

2.CSS样式定义优先级顺序是?
内联样式最高优先权,然后是内部样式,然后才是外部样式

3.div和span的区别?
  DIV 和 SPAN 元素最大的特点是默认都没有对元素内的对象进行任何格式化渲染。主要用于应用样式表(共同点)。
  两者最明显的区别在于DIV是块元素,而SPAN是行内元素(也译作内嵌元素)。
  详解:1.所谓块元素,是以另起一行开始渲染的元素,行内元素则不需另起一行,测试一下下面的代码你会有更形象的理解:
测试紧跟前面的"测试"显示

这里会另起一行显示

4.CSS选择器包括?
1)类别选择器 用“.”来标识
2)标签选择器 用HTML标签来标识
3)ID选择器 用“#”号来标识

5.用css3语法中,如何实现一个矩形框的圆角效果和50%红色透明效果?,请写出关键脚本

五、JavaScript和ajax部分
1.请写一段Javascript程序,对以下程序的用户输入日期的有效性进行判断,如果格式错误就提示用户。在程序的恰当位置注明怎样调用你写的程序。日期格式为:年年年年月月日日小时,例如2003010812。

NewPage1

查询日期(yyyymmddhh):

答:

查询日期(2003010812):

2.Java和Javascript区别在哪?
Java与JavaScript是目前比较流行的两种语言,单从表面上看,两者名称很相似,于是许多初学者容易将二者混淆,或者直接归为一类,其实不然,虽然两者有着紧密的联系,但确是两个完全不同的语言。接下来,笔者仅就她们的几个主要差别归纳起来。
一.开发厂商
众所周知,Java是SUN公司推出的程序设计语言,特别适合于Internet应用程序开发,其前身是Oak语言,而JavaScript则是NetScape公司的产品,是为了扩展NetScape Navigator功能而开发的一种可嵌入Web页面中的解释性语言,其前身是Live Script。由于Java的普及,NetScape和SUN两家公司签订合同后才将其命名为JavaScript。
二.面向对象与基于对象
Java是一种真正的纯面向对象编程语言,在Java中,一切都是对象;JavaScripr是一种脚本语言,由于她本身提供了非常丰富的内部对象供程序员使用,因而她是基于对象的语言。
三.开发和运行环境的不同
若希望利用Java编写程序并使之运行,必须事先在系统内安装相应版本的JDK和JVM,保证代码能够得到编译和运行的环境;而编写JavaScript则相对简单,只需使用某种HTML文档编辑器甚至某种字符编辑器(如Notepad)即可,然后打开浏览器即可运行。
四.变量的区别
Java中使用变量在编译之前必须声明其数据类型,因而她采用的是强类型变量;JavaScript则不用在变量前声明类型,而是由解释器在运行时自动检查,所以她是弱类型变量。
五.标签的不同
利用Java写出的Applet小程序,在HTML中用……来标识;JavaScript程序在HTML中运行,其代码在标签内。
六.解释与编译
Java源代码在执行前被编译,因而在网络应用中,必须要求客户端安装有解释平台,也就意味着Java应用不与HTML文档集成(Applet小程序例外);JavaScript是一种解释性语言,其代码在发往客户端之前不需编译,而是将其嵌入到HTML文档中,一起发送给客户端,由浏览器解释执行。
另外,JavaScript仅是一种解释性语言,并没有复杂的语法和规则,更不支持如Java里的继承这样的性质,因此也比Java更加容易学习。

3.列举javaScript的3种主要数据类型,2种复合数据类型和2种特殊数据类型。
主要数据类型:string, boolean, number

复合数据类型:function, object

4.谈谈你的JS的理解?
答:
1)是一种脚本编写语言
JavaScript是一种脚本语言,它采用小程序段的方式实现编程。像其它脚本语言一样,JavaScript同样已是一种解释性语言,它提供了一个易的开发过程。它的基本结构形式与C、C++、VB、Delphi十分类似。但它不像这些语言一样,需要先编译,而是在程序运行过程中被逐行地解释。它与HTML标识结合在一起,从而方便用户的使用操作。
2)基于对象的语言。
JavaScript是一种基于对象的语言,同时以可以看作一种面向对象的。这意味着它能运用自己已经创建的对象。因此,许多功能可以来自于脚本环境中对象的方法与脚本的相互作用。 3)简单性
JavaScript的简单性主要体现在:首先它是一种基于Java基本语句和控制流之上的简单而紧凑的设计, 从而对于学习Java是一种非常好的过渡。其次它的变量类型是采用弱类型,并未使用严格的数据类型。
4)安全性
JavaScript是一种安全性语言,它不允许访问本地的硬盘,并不能将数据存入到服务器上,不允许对网络文档进行修改和删除,只能通过浏览器实现信息浏览或动态交互。从而有效地防止数据的丢失。
5)动态性的
JavaScript是动态的,它可以直接对用户或客户输入做出响应,无须经过Web服务程序。它对用户的反映响应,是采用以事件驱动的方式进行的。所谓事件驱动,就是指在主页(Home Page)中执行了某种操作所产生的动作,就称为“事件”(Event)。比如按下鼠标、移动窗口、选择菜单等都可以视为事件。当事件发生后,可能会引起相应的事件响应。
6)跨平台性
JavaScript是依赖于浏览器本身,与操作环境无关,只要能运行浏览器的计算机,并支持JavaScript的浏览器就可正确执行。从而实现了“编写一次,走遍天下”的梦想。实际上JavaScript最杰出之处在于可以用很小的程序做大量的事。无须有高性能的电脑,软件仅需一个字处理软件及一浏览器,无须WEB服务器通道,通过自己的电脑即可完成所有的事情。

5.ajax的优点?
使用ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变过的信息。

6.JS里Ajax的原理
1、通过 new XMLHttpRequest 或其它的形式(指IE activeXObject)生成ajax的对象xhr。
2、通过xhr.open(type, url, async, username, password)的形式建立一个连接。
3、通过setRequestHeader设定xhr的请求头部(request header)。
4、通过send(data)请求服务器端的数据。
5、执行在xhr上注册的onreadystatechange回调处理返回数据。

7.简述一下ajax调试代码查找错误的方法?
这是js调试代码存在已久的问题,简单的我们可以使用浏览器提供的错误提示框,还有可以使用DW CS4提供的纠正错误,或者通过专业的插件,如firebug等

8.简述ajax中Js脚本缓存问题该如何解决?
这个问题是大家遇到最常见的问题之一,因为修改了js内容调试的时候并不能显示新写代码的结果,是因为Js为了加速页面执行,当前页面会使用缓存保持当前调用的相同的连接,为了开发时调试方便可以在连接地址后面增加一个随机函数.

9.Ajax应用和传统的web应用有何不同?
在传统的javascript中,如果想得到服务器端数据库或文件上的信息,或者发送客户端信息到服务器,需要建立一个HTML form然后Post或者get提交数据到服务端。用户需要点击submit 来发送或者接受数据信息,然后等待服务器响应请求,页面重写加载,因为服务器每次都要返回一个新的页面,所以传统的web应用有可能会很慢而且用户交互不友好。
使用ajax就可以使javascript通过XMLHttpRequest对象直接与服务器进行交互。通过HTTPRequest,一个web页面可以发送一个请求道web服务器并且接受web服务器返回的信息(不需要加载任何界面),展示给用户的还是同一个页面,用户感觉不到页面刷新,也看不到Javascript后台进行的发送请求和接受的响应。

10.javascript的作用?
表单验证、网页特效、网页游戏

11.为什么要有jquery?
因为jquery是轻量级的框架,大小不超过30kb,它有强大的选择器,出色的DOM操作的封装,有可靠的时间处理机制,完善的ajax有着出色的浏览器兼容性。而且支持链式操作,隐式迭代行为层和结构层的分离,还支持丰富的插件。

12.jquery选择器有哪些优势?
a) 简单的写法(‘#id’)用来代替document.getElementById()。
b) 支持css选择器。
c) 完善的处理机制,就算写错了Id也不会报错。

13.你是如何使用jquery中的ajax的?
如果是常规的ajax程序的话,使用load()、 . g e t ( ) 、 .get()、 .get().post(),一般我会使用的是 . p o s t ( ) 方 法 , 如 果 需 要 设 定 , b e f o r e S e n d ( 提 交 前 回 调 函 数 ) , e r r o r ( 失 败 后 处 理 ) , s u c c e s s ( 成 功 后 处 理 ) , 及 c o m p l e t e ( 请 求 完 成 后 处 理 ) 毁 掉 函 数 等 , 这 个 时 候 我 会 使 用 .post()方法,如果需要设定,beforeSend(提交前回调函数),error(失败后处理),success(成功后处理),及complete(请求完成后处理)毁掉函数等,这个时候我会使用 .post()beforeSenderror,success()complete使.ajax()

14.jquery中的 . g e t 和 .get和 .get.post请求区别?
a) . g e t 方 法 使 用 g e t 方 法 来 进 行 一 步 请 求 , .get方法使用get方法来进行一步请求, .get使get.post是使用post方法来进行请求。
b) get请求会讲参数跟在url后进行传递,而post请求则是作为Http消息的实体.内容发送给web服务器的,这种传递是对用户不可见的。
c) get方式传输的数据大小不能超过2kb而post请求要大的多
d) get方式请求的数据会被浏览器缓存起来,因此有安全问题

15.jquery中如何操作样式的?
addClass()来追加样式,removeClass()来删除样式,toggle()来切换样式。

16.如何设置和获取HTML和文本的值?
Html()方法,类似于innerHTML属性,可以用来读取或者设置某个元素中的HTML内容,text()类似于innerText属性,可以用来读取或这是某个元素的文本内容,val()可以用来设置和获取元素的值。

17.Jquery能做些什么?
a) 获取页面元素
b) 修改页面的外观
c) 修改页面的内容
d) 响应页面的操作
e) 为页面添加动态效果
f) 无需刷新页面,即可从服务器获取信息
g) 简化常见的javascript的任务

18.在ajax中data主要有哪几种?
html拼接、json数组、form表单经过serialize()序列化的
六、web部分
1.Tomcat的优化经验
答:去掉对web.xml的监视,把jsp提前编辑成Servlet。
有富余物理内存的情况,加大tomcat使用的jvm的内存

2.解释一下什么是servlet;什么是servlet容器;
在web容器中运行的服务器端java程序,主要用于响应HTTP请求。Servlet一般用于mvc中的控制器部分。
用来管理servlet生命周期的应用程序如(tomcat webloc等)

3.说一说Servlet的生命周期?
servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。

Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用service()方法实现,根据请求的不同调用不同的do***()方法。结束服务,web容器调用servlet的destroy()方法。

4.HTTP请求的GET与POST方式的区别
:Form中的get和post方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法。二者主要区别如下:
1)Get是用来从服务器上获得数据,而Post是用来向服务器上传数据;
2)Get将表单中数据按照variable=value的形式,添加到action所指向的URL后面,并且两者使用“?”连接,而各个变量之间使用“&”连接;Post是将表单中的数据放在form的数据体中,按照变量和值相对应的方式,传递到action所指向URL;
3)Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的;
4)Get传输的数据量小,这主要是因为受URL长度限制;而Post可以传输大量的数据,所以在上传文件只能使用Post;
5)Get限制Form表单的数据集必须为ASCII字符,而Post支持整个ISO10646字符集;
6)Get是Form的默认方法。

5.请写一个Servlet的基本架构。
public class ServletName extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
}
}

6.forward 和redirect的区别?
forward是容器中控制权的转向,是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。 redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取,并且从浏览器的地址栏中可以看到跳转后的链接地址。前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接;在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。

7.过滤器有哪些作用?
可以验证客户是否来自可信的网络,可以对客户提交的数据进行重新编码,可以从系统里获得配置的信息,可以过滤掉客户的某些不应该出现的词汇,可以验证用户是否登录,可以验证客户的浏览器是否支持当前的应用,可以记录系统的日志等等。

8.JSP的常用指令?
  <%@page language=”java” contenType=”text/html;charset=gb2312” session=”true” buffer=”64kb” autoFlush=”true” isThreadSafe=”true” info=”text” errorPage=”error.jsp” isErrorPage=”true” isELIgnored=”true” pageEncoding=”gb2312” import=”java.sql.*”%>
isErrorPage:是否能使用Exception对象;isELIgnored:是否忽略EL表达式;
<%@include file=”filename”%>
<%@taglib prefix=”c”uri=”http://……”%>

9.JSP和Servlet中的请求转发分别如何实现?
JSP中的请求转发可利用forward动作实现:<jsp:forward />;
Serlvet中实现请求转发的方式为:
getServletContext().getRequestDispatcher(path).forward(req,res)。

10.JSP乱码如何解决?
  1)JSP页面乱码
  <%@ page contentType=”text/html ; charset=utf-8”%>
  表单提交中文时出现乱码
  request.setCharacterEncoding(“utf-8”);
  数据库连接出现乱码
  是数据库连接中加入
  useUnicode=true&characterEncoding=utf-8;

11.session 和 application的区别?
1)两者的作用范围不同:
Session对象是用户级的,而Application是应用程序级别的
一个用户一个session对象,每个用户的session对象不同,在用户所访问的网站多个页面之间共享同一个session对象
一个Web应用程序一个application对象,每个Web应用程序的application对象不同,但一个Web应用程序的多个用户之间共享同一个application对象。
两者的生命周期不同:
session对象的生命周期:用户首次访问网站创建,用户离开该网站 (不一定要关闭浏览器) 消亡。
application对象的生命周期:启动Web服务器创建,关闭Web服务器销毁。

12.jsp有哪些内置对象?作用分别是什么?
答:JSP共有以下9种基本内置组件
   request:用户端请求,此请求会包含来自GET/POST请求的参数;
  response:网页传回用户端的回应;
  pageContext:网页的属性是在这里管理;
  session:与请求有关的会话期;
  application:servlet正在执行的内容;
  out:用来传送回应的输出;
  config:servlet的构架部件;
  page:JSP网页本身;
  exception:针对错误网页,未捕捉的例外

13. Jsp有哪些动作?作用分别是什么?
:JSP共有以下6种基本动作
jsp:include:在页面被请求的时候引入一个文件。
jsp:useBean:寻找或者实例化一个JavaBean。
jsp:setProperty:设置JavaBean的属性。
jsp:getProperty:输出某个JavaBean的属性。
jsp:forward:把请求转到一个新的页面。
jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记

14.JSP中动态INCLUDE与静态INCLUDE的区别?
动态INCLUDE用jsp:include动作实现
<jsp:include page=included.jsp flush=true />它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数 静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面 <%@ include file=included.htm %>

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

16.MVC的各个部分都有那些技术来实现?如何实现?
MVC是Model-View-Controller的简写。Model 代表的是应用的业务逻辑(通过JavaBean,EJB组件实现), View 是应用的表示面(由JSP页面产生),Controller 是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。

17.页面传递对象的方法?
Request、session、application、cookie等

18.Cookied和session区别?
cookie数据存放在客户的浏览器上,session数据放在服务器上。
b、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
c、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
d、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

七、框架部分
1.谈谈你对Struts2的理解。

2.谈谈你对Hibernate的理解。

  1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化。
    2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息。从Java程序的运行功能上来讲,保存对象状态的功能相比系统运行的其他功能来说,应该是一个很不起眼的附属功能,java采用jdbc来实现这个功能,这个不起眼的功能却要编写大量的代码,而做的事情仅仅是保存对象和恢复对象,并且那些大量的jdbc代码并没有什么技术含量,基本上是采用一套例行公事的标准代码模板来编写,是一种苦活和重复性的工作。
    3.通过数据库保存java程序运行时产生的对象和恢复对象,其实就是实现了java对象与关系数据库记录的映射关系,称为ORM(即Object Relation Mapping),人们可以通过封装JDBC代码来实现了这种功能,封装出来的产品称之为ORM框架,Hibernate就是其中的一种流行ORM框架。使用Hibernate框架,不用写JDBC代码,仅仅是调用一个save方法,就可以将对象保存到关系数据库中,仅仅是调用一个get方法,就可以从数据库中加载出一个对象。
    4.使用Hibernate的基本流程是:配置Configuration对象、产生SessionFactory、创建session对象,启动事务,完成CRUD操作,提交事务,关闭session。
    5.使用Hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件中需要登记每个hbm.xml文件。
    6.在应用Hibernate时,重点要了解Session的缓存原理,级联,延迟加载和hql查询。

3.你对Spring的理解。
1.Spring实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory(实际上是一个接口),在程序中通常BeanFactory的子类ApplicationContext。Spring相当于一个大的工厂类,在其配置文件中通过元素配置用于创建实例对象的类名和实例对象的属性。
2. Spring提供了对IOC良好支持,IOC是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦。IOC也称为DI(Depency Injection),什么叫依赖注入呢?
譬如,Class Programmer
{
Computer computer = null;
public void code()
{
//Computer computer = new IBMComputer();
//Computer computer = beanfacotry.getComputer();
computer.write();
}
public void setComputer(Computer computer)
{
this.computer = computer;
}
}
另外两种方式都由依赖,第一个直接依赖于目标类,第二个把依赖转移到工厂上,第三个彻底与目标和工厂解耦了。在spring的配置文件中配置片段如下:

3. Spring提供了对AOP技术的良好封装, AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,JDK中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice对象进行提供,显然要创建出代理对象,至少需要目标类和Advice类。spring提供了这种支持,只需要在spring配置文件中配置这两个元素即可实现代理和aop功能,例如,

4.Struts2优缺点

  1. 实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现.
    2.有丰富的tag可以用 ,Struts的标记库(Taglib),如能灵活动用,则能大大提高开发效率
  2. 页面导航
    使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
  3. 提供Exception处理机制 .
  4. 数据库链接池管理
  5. 支持I18N
    缺点
    一、 转到展示层时,需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每次修改配置之后,要求重新部署整个项目,而tomcate这样的服务器,还必须重新启动服务器
    二、 二、 Struts 的Action必需是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。
    三、 测试不方便. Struts的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难实现。不过有一个Junit的扩展工具Struts TestCase可以实现它的单元测试。
    四、 类型的转换. Struts的FormBean把所有的数据都作为String类型,它可以使用工具Commons-Beanutils进行类型转化。但它的转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。
    五、 对Servlet的依赖性过强. Struts处理Action时必需要依赖ServletRequest 和ServletResponse,所有它摆脱不了Servlet容器。
    六、 前端表达式语言方面.Struts集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可是JSTL的表达式语言在Collection和索引属性方面处理显得很弱。
    七、 对Action执行的控制困难. Struts创建一个Action,如果想控制它的执行顺序将会非常困难。甚至你要重新去写Servlet来实现你的这个功能需求。
    八、 对Action 执行前和后的处理. Struts处理Action的时候是基于class的hierarchies,很难在action处理前和后进行操作。
    九、 对事件支持不够. 在struts中,实际是一个表单Form对应一个Action类(或DispatchAction),换一句话说:在Struts中实际是一个表单只能 对应一个事件,struts这种事件方式称为application event,application event和component event相比是一种粗粒度的事件

5.说说struts1与struts2的区别。
1.都是MVC的WEB框架,
2 struts1的老牌框架,应用很广泛,有很好的群众基础,使用它开发风险很小,成本更低!struts2虽然基于这个框架,但是应用群众并多,相对不成熟,未知的风险和变化很多,开发人员相对不好招,使用它开发项目的风险系数更大,用人成本更高!
3.struts2毕竟是站在前辈的基础设计出来,它会改善和完善struts1中的一些缺陷,struts1中一些悬而未决问题在struts2得到了解决。
4.struts1的前端控制器是一个Servlet,名称为ActionServlet,struts2的前端控制器是一个filter,在struts2.0中叫FilterDispatcher,在struts2.1中叫StrutsPrepareAndExecuteFilter。
5.struts1的action需要继承Action类,struts2的action可以不继承任何类;struts1对同一个路径的所有请求共享一个Action实例,struts2对同一个路径的每个请求分别使用一个独立Action实例对象,所有对于struts2的Action不用考虑线程安全问题。
6.在struts1中使用formbean封装请求参数,在struts2中直接使用action的属性来封装请求参数。
7.struts1中的多个业务方法放在一个Action中时(即继承DispatchAction时),要么都校验,要么都不校验;对于struts2,可以指定只对某个方法进行校验,当一个Action继承了ActionSupport且在这个类中只编写了validateXxx()方法,那么则只对Xxx()方法进行校验。

(一个请求来了的执行流程进行分析,struts2是自动支持分模块开发,并可以不同模块设置不同的url前缀,这是通过package的namespace来实现的;struts2是支持多种类型的视图;struts2的视图地址可以是动态的,即视图的名称是支持变量方式的,举例,论坛发帖失败后回来还要传递boardid。视图内容显示方面:它的标签用ognl,要el强大很多,在国际化方面支持分模块管理,两个模块用到同样的key,对应不同的消息;)

与Struts1不同,Struts2对用户的每一次请求都会创建一个Action,所以Struts2中的Action是线程安全的。

给我印象最深刻的是:struts配置文件中的redirect视图的url不能接受参数,而struts2配置文件中的redirect视图可以接受参数。

6.struts的核心组件有哪些?
a) FilterDispatcher,struts2的核心组件,整个struts2的调度中心,它对请求进行过滤并决定struts2是否出来该请求。
b) Strtus.xml:struts2的应用配置文件,它负责配置系统中用到的action
c) Action:strtus2的动作执行单元实际处理用户的请求,封装业务所需的数据
d) Result:action运行后要转向下一个资源,可以是视图也可以说其他的action

7.struts2获取request的方式?
1、 实现servletRequest接口,然后写一个request属性,写上set get方法
2、 通过ServletContext上下文来获取

8.Strus2的执行过程
a) 客户端浏览器发出http请求
b) 根据web.xml配置,该请求被filterDispatcher接收。
c) 根据struts.xml配置,找到需要调用的action类和方法,并通过IOC控制反转方式,将值注入给Aciton
d) Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
e) Action执行完毕,根据struts.xml中的配置找到对应的翻译结果Result,并跳转到相应的界面。
f) 返回http响应到客户端浏览器。

9.为什么要使用struts2?
a) 开源
b) mvc框架
c) 纯pojo的action
d) 更好的标签特性
e) 易测性
f) 易扩展性

10.Struts2的优缺点?

优点:

  1. 实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现.
    2.有丰富的tag可以用 ,Struts的标记库(Taglib),如能灵活动用,则能大大提高开发效率
  2. 页面导航
    使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
  3. 提供Exception处理机制 .
  4. 数据库链接池管理
  5. 支持I18N
    缺点
    转到展示层时,需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每次修改配置之后,要求重新部署整个项目,而tomcate这样的服务器,还必须重新启动服务器
    二、 Struts 的Action必需是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。
    测试不方便. Struts的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难实现。不过有一个Junit的扩展工具Struts TestCase可以实现它的单元测试。
    类型的转换. Struts的FormBean把所有的数据都作为String类型,它可以使用工具Commons-Beanutils进行类型转化。但它的转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。
    对Servlet的依赖性过强. Struts处理Action时必需要依赖ServletRequest 和ServletResponse,所有它摆脱不了Servlet容器。
    前端表达式语言方面.Struts集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可是JSTL的表达式语言在Collection和索引属性方面处理显得很弱。
    对Action执行的控制困难. Struts创建一个Action,如果想控制它的执行顺序将会非常困难。甚至你要重新去写Servlet来实现你的这个功能需求。
    对Action 执行前和后的处理. Struts处理Action的时候是基于class的hierarchies,很难在action处理前和后进行操作。
    对事件支持不够. 在struts中,实际是一个表单Form对应一个Action类(或DispatchAction),换一句话说:在Struts中实际是一个表单只能 对应一个事件,struts这种事件方式称为application event,application event和component event相比是一种粗粒度的事件

11.拦截器的作用?拦截器和过滤器的区别?
a) 拦截器是对调用的action起作用,它提供类一种机制可以使开发者可以定义在一个action执行的前后执行的代码。拦截器只能拦截action,说白了拦截器其实就是一个action的功能块。拦截器可以抽象出一部分代码可以用来完善原来的action。同时可以减轻代码冗余提高重用率。
b) 过滤器是拦截用户请求,范围被拦截器大。

12.struts.xml中result的type有哪些类型?
Dispatcher:struts2默认的结果类型,把控制权转发给应用程序里的某个资源,不能把控制权转发给一个外部资源,若需要啊控制权重定向到一个外部资源,应该使用redirect结果类型。
Redirect 把响应重定向到另一个资源
RedirectAction 把响应重定向到另一个Action
Freemarcker、velocity、chain、httpherder、xslt、plainText、stream、json.

13.一般情况下,关系数据模型与对象模型之间有哪些匹配关系?
A)表对应类
B)记录对应对象
C)表的字段对应类的属性

14.hibernate 数据的三个状态
我们把数据库比喻成一个登记簿吧,当我们把信息登记到登记簿上的时候,这个过程就是持久化的过程。当登记完成之后,登记簿上的数据就是持久态数据,所谓持久态就是一直存在的状态。当我们需要用数据的时候,会从登记簿上查信息,我们查到的信息记录在临时的纸张或者脑海里,然后登记簿会放回原位,这时候临时纸张上或者脑海里的数据就是游离态,随时可能被遗忘,在hibernate中就是随时会被销毁的数据。瞬态数据和游离态数据有点儿类似,但是一点,就是他是存在持久化之前的数据,就是说我需要登记个人信息,我的个人信息还没有登记到登记簿上的时候,信息就是瞬态,一旦登记到登记簿上就变成持久态了,然后再查询到的就是游离态。

a. 瞬时状态(临时状态)
当new 对象时候,处于瞬时状态(如果程序运行完了,该对象会被垃圾回收)
b. 持久状态
跟session有关,就是持久状态
持久状态的对象,任何的修改,都会影响到数据库中与之对应的数据
c. 托管状态(游离状态)
当session不在管理对象的时候,脱离了session 的管理,处于托管状态的对象,修改属性,对数据库数据没有任何影响
企业开发中,使用saveOrUpdate(obj): 来替代save(obj)或update(obj)方法
避免因为状态的改变,导致方法出错, saveOrUpdate(obj)
可以根据obj的状态,来选择是save()还是update()

15.Hibernate中load和get的区别?

a) 如果数据库中,没有userId的对象,如果通过get方法加载,则返回的是一个Null;如果通过Load则返回一个代理对象,如果后面代码调用user对象的某个属性,会抛出objectNotFoundException
b) Load支持延迟加载,get不支持。

  1. getCurrentSession与openSession的区别

    1 getCurrentSession创建的session会绑定到当前线程,而openSession不会。

    2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭

17.Hibernate的工作原理?
a) 读取并解析配置文件
b) 读取解析映射信息,创建sessionFactory
c) 打开session
d) 创建事务Transation
e) 持久化操作
f) 提交事务
g) 关闭session
h) 关闭sessionFactory

18.为什么要用hibernate?
a) 对jdbc访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
b) Hibernate是一个基于JDBC的主流持久性框架,是一个优秀的ORM实现,他很大程度的简化DAO的编码工作。
c) Hibernate使用JAVA反射机制,而不是字节码增强程序来实现透明性。

19.Hibernate是如何延迟加载的?

Lazy策略为延迟加载策略,Hibernate通过JDK代理对其进行实现,即使用延迟加载的对象,在获取对象的时候返回的是对象的代理,并不是对象的真正引用,只有在对象真正被调用的时候,Hibernate才会对其进行查询,返回真正的对象。

这在某种程度上对性能起到一定的优化。Hibernate的延迟加载还可以减少程序与数据库的连接次数,因为使用了延迟加载,Hibernate将延缓执行SQL语句,减少对数据库的访问次数,从而提高执行效率。

a) 内部缓存存在Hibernate中又叫一级缓存,属于应用事务级缓存。
b) 二级缓存:是sessionFactory级别缓存,他是属于进程范围货群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载,Hibernate还为查询结果提供了一个查询缓存,它依赖于二级缓存。

20.hibernate的缓存
Hibernate框架也应用了缓存技术,并实现了两级缓存,一级缓存即Session的缓存,二级缓存即SessionFactory的缓存。
1、 一级缓存 session级缓存
一级缓存是Session级的缓存,其生命周期很短,与Session相互对应。一级缓存由Hibernate进行管理,属于事务范围的缓存。
当程序调用Session的load()方法、get()方法、save()方法、saveOrUpdate()方法、update()方法或查询接口方法时,Hibernate会对实体对象进行缓存;当通过load()方法或get()方法查询实体对象时,Hibernate会首先到缓存中查找,在找不到实体对象的情况下,Hibernate才会发出SQL语句到数据库中查询,从而提高了Hibernate的使用效率。
2、 二级缓存 SessionFactory级缓存
二级缓存是SessionFactory级的缓存,其生命周期与SessionFactory一致。二级缓存可以在多个Session之间共享,属于进程范围或群集范围的缓存。
二级缓存是一个可插拔的缓存插件,它的使用需要第三方缓存产品的支持。在Hibernate框架中,通过Hibernate配置文件配置二级缓存的使用策略。
注:对于二级缓存,可以使用一些不经常更新的数据或参考的数据,此时其性能会得到明显的提升。例如一个新闻网站,当发布一条热点新闻时,会有成千上万的访问量,而此条新闻并没有发生任何的变化,如果每一个用户访问都要查询数据库,势必对系统性能造成一定的影响,此时可以考虑应用二级缓存。如果经常变换的数据则不应应用二级缓存。

21.如何优化Hibernate?
a) 使用双向一对多关联,不使用单向一对多
b) 灵活使用单向一对多
c) 不使用一对一,用多对一取代
d) 配置对象缓存,不适用集合缓存
e) 一对多集合使用bag,多对多使用set
f) 继承类使用显式多态
g) 表字段要少,表关联不要怕多,有二级缓存。
22.什么是ORM?
对象到关系的映射,类—>表,对象—>表中的每一条数据,属性—>表中的列
特殊的属性—>主键(作为每条数据的标识)

23.Hibernate的主键生成策略?
a)sequence,通知Hibernate框架,主键的值采用指定序列生成,然后插入数据库,主要用于
Oracle,DB2,不用程序员参与

foo_seq// 必须加上

b)identity,通知hibernate框架,主键值采用数据库自动增长机制,每次进行save()操作,
hibernate都会根据(数据库)自增的方式,生成一个id值,不用程序员参与,主要用于
mySQL , SQLServer

c)uuid(西方常用),hibernate 每次进行save()操作,都会随机生成一个32的不重复的字符串,
不用程序员去参与维护,PO类的Id属性必须为String
d)native 根据dialect(方言)不同,来自动的选择identity或sequence智能选择。是企业中常用的
e)assigned 不推荐使用,程序言要自己维护主键的Id值,当数据量很大时候很难维护

24.Hibernate的级联操作

  1. cascade操作
    all:所有情况下都进行级练操作 ,save-update和delete
    save-update: 在进行save()/update()/saveOrUpdate时候进行级练操作
    delete:在进行delete时候进行级练操作
    all-delete-orphan :适合集合中删除,在返回的集合中执行remove()操作
    none:在任何情况下都不进行级练操作
    2) inverse属性的作用
    是否放弃维护关联关系 true放弃 false不放弃
    25.Hibernate有哪5个核心接口?
    Configuration接口:配置Hibernate,根据其启动hibernate,创建SessionFactory对象;
    SessionFactory接口:初始化Hibernate,充当数据存储源的代理,创建session对象,sessionFactory是线程安全的,意味着它的同一个实例可以被应用的多个线程共享,是重量级、二级缓存;
    Session接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,避免多个线程共享同一个session,是轻量级、一级缓存;
    Transaction接口:管理事务;
    Query和Criteria接口:执行数据库的查询。

26.什么是重量级?什么是轻量级?
轻量级是指它的创建和销毁不需要消耗太多的资源,意味着可以在程序中经常创建和销毁session的对象;重量级意味不能随意的创建和销毁它的实例,会占用很多的资源。

  1. 谈谈Spring的IOC和DI
    首先想说说IoC(Inversion of Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。
    那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。如果你还不明白的话,我决定放弃。
    IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

28.解释Spring的IoC? 几种注入依赖的方式?Spring的优点?
IOC你就认为他是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是有这个IOC容器进行产生,同时,要是产生的是单利的bean,他还可以给管理bean的生命周期!
依赖注入的三种实现类型:接口注入、 Setter 注入和构造器注入。
Spring的优点:主要是根据它的IOC和AOP体现的。我感觉他就是把我们以前用到的工厂模式和代理模式进行了一个封装。IOC主要是解决了代码的耦合性问题,而AOP是面向切面编程的最好解释!

29.什么是AOP?
Aspect Oriented Programming (面向方面编程)
OOP是面向对象编程,AOP是在OOP基础之上一种更高级的设计思想.
OOP和AOP之间也存在一些区别,OOP侧重于对象的提取和封装.
AOP侧重于方面组件,方面组件可以理解成封装了通用功能的组件,
方面组件可以通过配置方式灵活的切入到某一批目标对象方法上.

30.Spring的通知类型有哪些?

通知决定了方面组件功能在目标对象方法上执行的时机.
Spring框架提供了以下5中类型通知.
a.前置通知aop:before
方面功能在目标方法之前调用.
b.后置通知aop:afterReturning
方面功能在目标方法之后调用.(如果目标方法抛出异常则不会执行方面功能)
c.最终通知aop:after
方面功能在目标方法之后调用.(目标方法有无异常都会执行方面功能)
d.环绕通知aop:around
方面功能在目标方法之前和之后调用.
e.异常通知aop:afterThrowing
方面功能在目标方法抛出异常之后调用.

31.springMVC的运行原理。

SpringMVC运行原理

  1. 客户端请求提交到DispatcherServlet

  2. 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller

  3. DispatcherServlet将请求提交到Controller

  4. Controller调用业务逻辑处理后,返回ModelAndView

  5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图

  6. 视图负责将结果显示到客户端

DispatcherServlet是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分。其主要工作有以下三项:

    1. 截获符合特定格式的URL请求。
    2. 初始化DispatcherServlet上下文对应的WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联。
    3. 初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。

八、设计模式
请写出你所知道的设计模式?
设计模式主要分三个类型:创建型、结构型和行为型。
其中创建型有:
一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。
四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。
五、Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
行为型有:
六、Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。
七、Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
八、Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。
九、Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。
十、State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。
十一、Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。
十二、China of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系
十三、Mediator,中介者模式:用一个中介对象封装一些列的对象交互。
十四、Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。
十五、Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
十六、Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
结构型有:
十七、Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。
十八、Facade,外观模式:为子系统中的一组接口提供一致的界面,fa?ade提供了一高层接口,这个接口使得子系统更容易使用。
十九、Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问
二十、Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。
二十一、Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。
二十二、Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。
二十三、Flyweight,享元模式

九、经典案例
1.说明生活中遇到的二叉树,用java实现二叉树
这是组合设计模式。
我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:

代码如下:
package com.huawei.interview;

public class Node {
public int value;
public Node left;
public Node right;

public void store(int value)
{
	if(value<this.value)
	{
		if(left == null)
		{
			left = new Node();
			left.value=value;
		}
		else
		{
			left.store(value);
		}
	}
	else if(value>this.value)
	{
		if(right == null)
		{
			right = new Node();
			right.value=value;
		}
		else
		{
			right.store(value);
		}			
	}
}

public boolean find(int value)
{	
	System.out.println("happen " + this.value);
	if(value == this.value)
	{
		return true;
	}
	else if(value>this.value)
	{
		if(right == null) return false;
		return right.find(value);
	}else
	{
		if(left == null) return false;
		return left.find(value);
	}

}

public  void preList()
{
	System.out.print(this.value + ",");
	if(left!=null) left.preList();
	if(right!=null) right.preList();
}

public void middleList()
{
	if(left!=null) left.preList();
	System.out.print(this.value + ",");
	if(right!=null) right.preList();		
}
public void afterList()
{
	if(left!=null) left.preList();
	if(right!=null) right.preList();
	System.out.print(this.value + ",");		
}	
public static void main(String [] args)
{
	int [] data = new int[20];
	for(int i=0;i<data.length;i++)
	{
		data[i] = (int)(Math.random()*100) + 1;
		System.out.print(data[i] + ",");
	}
	System.out.println();
	
	Node root = new Node();
	root.value = data[0];
	for(int i=1;i<data.length;i++)
	{
		root.store(data[i]);
	}
	
	root.find(data[19]);
	
	root.preList();
	System.out.println();
	root.middleList();
	System.out.println();		
	root.afterList();
}

}
-----------------又一次临场写的代码---------------------------
import java.util.Arrays;
import java.util.Iterator;

public class Node {
private Node left;
private Node right;
private int value;
//private int num;

public Node(int value){
	this.value = value;
}
public void add(int value){
	
	if(value > this.value)
	{
		if(right != null)
			right.add(value);
		else
		{
			Node node = new Node(value);				
			right = node;
		}
	}
	else{
		if(left != null)
			left.add(value);
		else
		{
			Node node = new Node(value);				
			left = node;
		}			
	}
}

public boolean find(int value){
	if(value == this.value) return true;
	else if(value > this.value){
		if(right == null) return false;
		else return right.find(value);
	}else{
		if(left == null) return false;
		else return left.find(value);			
	}

}

public void display(){
	System.out.println(value);
	if(left != null) left.display();
	if(right != null) right.display();
	
}

/*public Iterator iterator(){
	
}*/

public static void main(String[] args){
	int[] values = new int[8];
	for(int i=0;i<8;i++){
		int num = (int)(Math.random() * 15);
		//System.out.println(num);
		//if(Arrays.binarySearch(values, num)<0)
		if(!contains(values,num))
			values[i] = num;
		else
			i--;
	}
	
	System.out.println(Arrays.toString(values));
	
	Node root  = new Node(values[0]);
	for(int i=1;i<values.length;i++){
		root.add(values[i]);
	}
	
	System.out.println(root.find(13));
	
	root.display();
	
}

public static boolean contains(int [] arr, int value){
	int i = 0;
	for(;i<arr.length;i++){
		if(arr[i] == value) return true;
		
	}
	return false;
}

2.从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序:
1,张三,28
2,李四,35
3,张三,28
4,王五,35
5,张三,28
6,李四,35
7,赵六,28
8,田七,35

程序代码如下(答题要博得用人单位的喜欢,包名用该公司,面试前就提前查好该公司的网址,如果查不到,现场问也是可以的。还要加上实现思路的注释):
package com.huawei.interview;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;

public class GetNameTest {

/**
 * @param args
 */
public static void main(String[] args) {
	// TODO Auto-generated method stub
	//InputStream ips = GetNameTest.class.getResourceAsStream("/com/huawei/interview/info.txt");
	//用上一行注释的代码和下一行的代码都可以,因为info.txt与GetNameTest类在同一包下面,所以,可以用下面的相对路径形式
	
	Map results = new HashMap();
	InputStream ips = GetNameTest.class.getResourceAsStream("info.txt");
	BufferedReader in = new BufferedReader(new InputStreamReader(ips));
	String line = null;
	try {
		while((line=in.readLine())!=null)
		{
			dealLine(line,results);
		}
		sortResults(results);
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

static class User
{
	public  String name;
	public Integer value;
	public User(String name,Integer value)
	{
		this.name = name;
		this.value = value;
	}

	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
			
		//下面的代码没有执行,说明往treeset中增加数据时,不会使用到equals方法。
		boolean result = super.equals(obj);
		System.out.println(result);
		return result;
	}
}

private static void sortResults(Map results) {
	// TODO Auto-generated method stub
	TreeSet sortedResults = new TreeSet(
			new Comparator(){
				public int compare(Object o1, Object o2) {
					// TODO Auto-generated method stub
					User user1 = (User)o1;
					User user2 = (User)o2;
					/*如果compareTo返回结果0,则认为两个对象相等,新的对象不会增加到集合中去
					 * 所以,不能直接用下面的代码,否则,那些个数相同的其他姓名就打印不出来。
					 * */
					
					//return user1.value-user2.value;
					//return user1.value<user2.value?-1:user1.value==user2.value?0:1;
					if(user1.value<user2.value)
					{
						return -1;
					}else if(user1.value>user2.value)
					{
						return 1;
					}else
					{
						return user1.name.compareTo(user2.name);
					}
				}
				
			}
	);
	Iterator iterator = results.keySet().iterator();
	while(iterator.hasNext())
	{
		String name = (String)iterator.next();
		Integer value = (Integer)results.get(name);
		if(value > 1)
		{				
			sortedResults.add(new User(name,value));				
		}
	}
	
	printResults(sortedResults);
}
private static void printResults(TreeSet sortedResults) 
{
	Iterator iterator  = sortedResults.iterator();
	while(iterator.hasNext())
	{
		User user = (User)iterator.next();
		System.out.println(user.name + ":" + user.value);
	}	
}
public static void dealLine(String line,Map map)
{
	if(!"".equals(line.trim()))
	{
		String [] results = line.split(",");
		if(results.length == 3)
		{
			String name = results[1];
			Integer value = (Integer)map.get(name);
			if(value == null) value = 0;
			map.put(name,value + 1);
		}
	}
}

}

3.写一个Singleton出来。
第一种:饱汉模式
public class SingleTon {
private SingleTon(){
}

//实例化放在静态代码块里可提高程序的执行效率,但也可能更占用空间	
private final static SingleTon instance = new SingleTon();
public static SingleTon getInstance(){
	return instance;
}

}

第二种:饥汉模式
public class SingleTon {
private SingleTon(){}

private static instance = null;//new SingleTon();

public static synchronized SingleTon getInstance(){
	if(instance == null)
		instance = new SingleTon();
	return instance;
}

}

第三种:用枚举
public enum SingleTon{
ONE;

}

第三:更实际的应用(在什么情况用单例)
public class SequenceGenerator{
//下面是该类自身的业务功能代码
private int count = 0;

public synchronized int getSequence(){
	++count;
}

//下面是把该类变成单例的代码
private SequenceGenerator(){}
private final static instance = new SequenceGenerator();
public static SingleTon getInstance(){
	return instance;
}	

}

第四:
public class MemoryDao
{
private HashMap map = new HashMap();

public void add(Student stu1){ 
		map.put(SequenceGenerator.getInstance().getSequence(),stu1);
}

//把MemoryDao变成单例
}

Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
一般Singleton模式通常有几种种形式:
第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。
public class Singleton {
private Singleton(){}
   //在自己内部定义自己一个实例,是不是很奇怪?
   //注意这是private 只供内部调用
   private static Singleton instance = new Singleton();
   //这里提供了一个供外部访问本class的静态方法,可以直接访问  
   public static Singleton getInstance() {
     return instance;   
   }
}
第二种形式:
public class Singleton {
  private static Singleton instance = null;
  public static synchronized Singleton getInstance() {
  //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次     
  //使用时生成实例,提高了效率!
  if (instance==null)
    instance=new Singleton();
return instance;   
}
}
其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。
一般认为第一种形式要更加安全些

4.古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
/这是一个菲波拉契数列问题
public class lianxi01 {
public static void main(String[] args) {
System.out.println(“第1个月的兔子对数: 1”);
System.out.println(“第2个月的兔子对数: 1”);
int f1 = 1, f2 = 1, f, M=24;
for(int i=3; i<=M; i++) {
f = f2;
f2 = f1 + f2;
f1 = f;
System.out.println(“第” + i +"个月的兔子对数: "+f2);
}
}
}

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论

打赏作者

mpf_45689111

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值