不会,我们是在XP上开发的。
2、GC是什么?(garbage collector)GC是JAVA中的垃圾收集机制,把不再使用的内存空间回收。
3、重载和重写的区别?(简单回答:重载是在一个类中进行,重写是在父类和子类中进行)(1)重载是在一个类中可以定义有相同的名字,但参数不同(个数不同,类型不同)的方法。
(2)在子类中可以根据需要对从基类中继承来的方法进行了重写,重写的方法必须和被重写的方法具有相同方法名称、参数及返回类型。
(3)重写方法不能使用比被重写方法更严格的访问权限。
4、抽象类和接口的区别?(1) 抽象类只是单继承(一个类只能用extends继承一个父类),接口实现了多继承(一个类可以用implements实现多个接口)
(2)在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而接口是一种特殊的抽象类,它只包含常量和方法的定义,而不能有变量和方法的实现,即所有的成员方法都是无方法体的。
Abstract class Person{
public abstract void p();
public void f(){
System.out.println(1234888);
}
}
public interface Runner {
public static final int id = 1;
public int i=2;
public void start();
public void run();
public void stop();
}
(3)抽象类中可以有非抽象方法,接口中则不能有实现方法,接口中的方法默认都是 public类型的。
抽象类是通过类来继承,接口是通过类来实现接口
5、多态:重载是多态的一种体现,通过不同的参数调用不同的方法。
(还有重写、父类的引用指向子类)
6、String 和StringBuffer的区别?String是不可变的字符串,StringBuffer是可变的字符串
StringBuffer只能用new来初始化StringBuffer变量,不能直接用StringBuffer s=”abc”;
7、Collection和Collections的区别?Collection是List和Set接口的父接口;Collections是针对List的帮助类。
8、List接口和Set接口的区别?a) Set 中的数据对象没有顺序且不可以重复。
b) List 中的数据对象有顺序且可以重复。
9、HashMap和HashTable的区别?(请注意,Map没有 继承Collection接口)HashTable线程安全(HashTable的方法是同步的),HashMap线程不安全(HashMap是不同步的)
什么是同步?当两个或多个线程需要访问同一共享资源时,它们需要以某种顺序来确保该资源某一时刻只能被一个线程使用的方式称为同步。
具体区别如下:(1)继承和实现区别Hashtable是基于陈旧的Dictionary类,完成了Map接口;HashMap是Java 1.2引进的Map接口的一个实现(HashMap继承于AbstractMap,AbstractMap完成了Map接口)。
(2)线程安全不同HashTable的方法是同步(Synchronize)的,HashMap是未同步,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
(3)对null的处理不同HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)。即 HashTable不允许null值其实在编译期不会有任何的不一样,会照样执行,只是在运行期的时候Hashtable中设置的话回出现空指针异常。 HashMap允许null值是指可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。
(4)方法不同HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样。
(5)HashTable使用Enumeration,HashMap使用Iterator。10、JAVA中有23种设计模式:
常见模式:单例模式、工厂模式(自身去实例化本身这个类)、策略模式、多例模式
//单例模式的两种形式:
private static Car car = new Car();//饿汉模式
public static Car getInstance(){
return car;
}
private static Car car = null;//懒汉模式
public static Car getInstance(){
if(car == null){
car = new Car();
}
return car;
}
11、在单例模式中怎样控制线程安全问题?用synchronized关键字来修改类或方法。
12、常见异常:NullPointerException :空指针异常
ClassNotFoundException :找不到类的异常
SQLException
IOException
RuntimeException:超时异常
ArrayIndexOutOfBoundsException:下标越界
13、JSP的九个内置对象及作用域:
(1)request:一次服务器请求的范围内
(2)response:默认情况下表示一个页面的保存范围
(3)session:在一次会话的范围内(例如:访问整个网站期间,都是一个用户名)
(4)application:一个应用程序的范围内(作用于整个运行期,从服务器开始到关闭)
(5)page:在一个页面的范围内
(6)pageContext:默认情况下表示一个页面的保存范围
(7)out:默认情况下表示一个页面的保存范围
(8)exception:默认情况下表示一个页面的保存范围
(9)config:默认情况下表示一个页面的保存范围
14、JSP中两种跳转的区别:
(1).forward跳转: <jsp:forward page="跳转页面地址" />
(2).response跳转: response.sendRedirect("跳转页面地址"); //即重定向
两种跳转的区别如下:
1.forward跳转:
a.服务器端跳转,地址栏不改变;
b.执行到跳转语句后马上无条件跳转,之后的代码不再执行(跳转之前一定要释放全部资源);
c.request设置的属性在跳转后的页面仍可以使用;
d.使用<jsp:param name="参数名" value="参数值" />传递参数。
2.response跳转:
a.客户端跳转,地址栏改变;
b.所有代码执行完毕后跳转;
c.跳转后的页面不能使用上一个页面的request属性;
d.使用地址重写传递参数(response.sendRedirect("URL?参数名=参数值"))。
15、JSP中的动态包含和静态包含的区别:
(1)静态包含:<%@include file=”url” %> 先包含后处理
(2)动态包含:<jsp:include page=”url”>
</jsp:include> 先处理后包含,只把结果包含进来
注意:被包含文件不能有<html> <head> <body>
16、会用Cookie?
了解,Cookie是保存在客户端的,但在项目中一般不用。
17、为什么要用MVC思想?
因为mvc分层明确,便于后期维护。我们一般在实际开发中还有数据层(vo包)用来存放数据库的表的实例化类。{ mvc其实就是一种设计理念,即:model(模型)----view(视图)----controller(控制器)。M中一般是用来处理“业务逻辑”;V将视图与代码分开;C控制执行页面的跳转。}
MVC缺点:对于程序员来说文件太多,不好管理。
18、面向对象的特点:
封装、继承和多态。
19、数据库连接池的机制?
数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。当启动Tomca服务器后,预先在缓冲池中创建一定数量的连接,保存起来(池),当池收到连接申请时,就随机分配一个出去,连接用完了,则返回池,循环使用。当申请数量超出了池大小,将创建连接,使用完后,额外创建的连接将直接关闭,不再回池。如果超出了最大连接限制,则等待可用连接。
我们通过设定连接池最大连接数来防止系统无尽的与数据库连接。
20、Servlet的生命周期:
加载、初始化、执行、清除。
21、Error和异常的区别?
异常是在程序执行过程中出现的;
Error是在程序编译的过程中出现的。
23、final 和finally以及finalize()的区别?
final可以声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
final类不能被继承,没有子类,final类中的方法默认是final的。
final方法不能被子类的方法覆盖,但可以被继承。
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
final不能用于修饰构造方法。
finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
finally是异常处理语句结构的一部分,无论是否有异常,finally中的代码总是执行。
24、B/S架构和C/S架构的区别?
B/S平常用IE可以访问的网站;
C/S必须在机器上安装客户端,即在本机上有安装程序,eg:QQ。
a)B/S(Browser/Server)结构即浏览器和服务器结构。 B/S就是浏览器/服务器模式,通过浏览器直接与服务器交互,客户端不用安装软件直接有浏览器就可以使用应用系统,升级时只需升级服务器端,易于升级;不用每台机子都去安装客户端,易于部置;缺点是功能比较有限,大部分工作都在服务器上做。 b)C/S(Client/Server)结构即客户端和服务器结构。 C/S就是客户端/服务端模式,通过客户端程序与服务器交互,需要在每台机器上安装客户端软件,但是可以实现的功能比较多,而且客户端分担了服务器的相关工作,服务器会比较轻松。 25、在I/O流中,以“程序”作为参照物
文件——程序:输入流
程序——文件:输出流
26、将一个文件的内容拷贝到另一个文件中?(I/O流)
public class TestFileInputStream {
public static void main(String args[]) {
int a = 0;
FileInputStream in = null;
FileOutputStream out = null;
try {
//路径中用“//”是为了放在unix系统上也可以运行,第一个为转义字符,其实“//”用“/”代替在windows系统中也可以运行。
in = newFileInputStream("d://test//HW.java");//此文件必须存在
out = new FileOutputStream("d://Hw.txt");
//若D盘无此文件,会自动新建一个
while ((a = in.read()) != -1) {
out.write(a);
}
in.close();
out.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("复制成功!!!");
System.exit(-1); //退出文件
}
}
27、从标准设备中输入若干行英文句子,直到输入"bye"结束,将这些字符串写入文件(使用I/O流)。(1)在JAVA文件中写入如下代码:
(2)在控制台输入如下代码:
(3)刷新工程则会出现一个test.txt文件,如下所示:
(4)JAVA中的具体代码如下:
package com.cstp.io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class TestBye {
/**
* 从标准设备中输入若干行英文句子,
* 直到输入"bye"结束,将这些字符串写入文件。
*/
public static void main(String args[]) {
try {
InputStreamReader rs = new InputStreamReader(System.in);
//键盘输入事件
BufferedReader ps = new BufferedReader(rs);
FileWriter file = new FileWriter("test.txt");//刷新则出现
BufferedWriter pst = new BufferedWriter(file);
PrintWriter psw = new PrintWriter(pst);
String s = null;
while ((s = ps.readLine()) != null) {
if (s.equals("bye")) {
break;//结束while循环
}
psw.write(s);
psw.write('\n');
}
ps.close();//关闭最后一个输入流
psw.close();//关闭最后一个输出流
}
catch (IOException e) {
e.printStackTrace();
}
}
}
28、在刚才输入的文件中查找指定的单词,打印出包含了欲找单词的所
29、为什么在项目中用JXL比POI多?
JXL可以操作简单的、对公式要求不严格的Excel,只支持png的图片;
POI支持带公式的操作,要求严格时用POI。
在项目中对公式要求不严格,用JXL即可。
30、线程中的start() 和run()的区别?
start():是用来启动一个线程,使线程处于就绪状态;使用了start()方法后,系统会自动调用它的run()方法。
run():是用来执行一个线程,使线程处于运行状态。
31、wait() 和notify()的区别?
(1)在线程中有wait()则必须有notify()。
(2)obj.wait():将使本线程挂起;
(3)obj.notify():唤醒被挂起的某一进程,只有其他线程调用obj对象的notify()或notifyAll()时,才可以被唤醒。
32、在线程中遇到资源共享时,怎样使此线程安全?
(1)调用sleep()让另一个线程休眠
(2)wait()等待,让线程处于挂起状态
(3)用synchronized关键字来修饰(即给共享资源加锁)
33、JAVA解析XML的方法:DOM、SAX、JDOM、DOM4J。
(1)其中DOM、SAX是最为主要的两个;
(2)DOM、SAX是JAVA本身自带的一种解析XML的文档,不需要第三方插件(jar包);
(3)JDOM、DOM4J需要第三方插件才能解析XML。
34、常用的套接字Socket有两种:(属于网络编程范围)
(1)服务器端的叫ServerSocket,客户端的叫Socket
(2)运行时需先启动服务器端再启动客户端,关闭时先关客户端再关服务器端
35、JAVA中常用的五个包:
Lang包、io包、util包、sql包和net包
36、数据库优化:
多表连查时使用表别名和列别名;
少用is not null、not in类似的语句;
少用select *来查询记录;
将经常用到的多表连查出来的字段建立成视图;
将where条件中经常用到的列加上索引(建立视图和索引的优点:加快了查询速度);
少用游标;在where条件中尽量不使用or关键字和!= 。
37、为什么使用视图?(目的:数据库优化)
将经常用到的不同的表/相同表的字段组织在一起(简化了代码量,加快了查询速度)
注意:只能select视图,不能insert ,update……
38、数据库的海量优化:
用存储过程。存储过程的结果是放在oracle服务器中的。
39、DELETE、DROP和TRUNCATE的区别?
DELETE:清空内容,但没释放表的所占空间,表结构还存在;
eg:delete from user1
DROP:删除整张表(数据及表结构都删除);
eg:drop table userse1
TRUNCATE:清空内容,并释放该表的所有空间,表结构还存在。
eg:truncate table userse1
40、判断下列sql语句是否有错?
SELECT deptno,COUNT(*) FROM emp;
有,错误如图所示:
count(*)是组函数,deptno是一般的字段,它们不能并写,若想这样写,则必须用group by 进行分组。代码如下:
SELECT deptno,COUNT(*) FROM emp GROUP BY deptno;
41、什么是事务?
数据库事务(Database Transaction)是一组数据库操作的处理单元。事务符合ACID的特性:
(1) Atomic:原子性,要么全部要么一无所有。All or None.
(2) Consistent:一致性,所有依赖关系以及约束一致。
(3) Isolated:分离性,不同事务不互相影响。
(4) Durable:持久性,提交事务的数据需要持久化。
功能:(a) 保证数据库的consistent(一致性状态),保持所有依赖关系以及约束一致)。哪怕数据库管理系统出现故障时(例如断电),也能恢复到一致性状态。例如一个银行转帐系统,张三给李四转3000圆RMB,张三帐号上减3000和李四帐号上加3000需要同时完成,否则系统的帐就不平了。也例如有些销售系统的汇总表和明细表,是一个主表和一个从表,需要同步更新。
(b) 并发时分离不同事务操作。例如编辑过程中的数据不给其他事务查询到。
42、Oracle数据库中为什么会有序列?
因为Oracle中没有自增功能,所以要借助序列实现。
43、DB2和Oracle的区别?
(1) 获取时间不同
Oracle:
Select sysdate from dual;
DB2: Select current timestamp from sysibm.sysdummy1;
select CURRENT DATE from SYSIBM.SYSDUMMY1;获得日期
select CURRENT TIME from SYSIBM.SYSDUMMY1;获得时间
(2) 类型转换不同
a) 转换日期时间到字符类型:
Oracle
TO_CHAR(date_expression_r_r, 'YYYY-MM-DD')
TO_CHAR(date_expression_r_r, 'HH24:MI:SS')
DB2
CHAR(date_expression_r_r,ISO)
CHAR(time_expression_r_r,ISO)
b) 转换日期时间字符串到日期时间类型:
Oracle
TO_DATE(date_expression_r_r, 'YYYY-MM-DD')
TO_DATE(date_expression_r_r, 'HH24:MI:SS')
DB2
DATE('2005-05-20')
TIME('18:59:59')
TIEMSTAMP('2007-2-1', '21:12:12')
TIEMSTAMP('2007-2-1 21:12:12')
DB2也有TO_CHAR 和 TO_DATE函数,但只能提供固定的转换格式,如下
TO_CHAR (timestamp_expression_r_r,'YYY-MM-DD HH24:MI:SS')
TO_DATE (string_expression_r_r, 'YYY-MM-DD HH24:MI:SS')
(3) 表备份
(4) Update区别
Db2:
DB2 update staff set (salary,comm)=(80000,50000);
DB2 update staff set salary=80000,comm=50000;
Oracle:
SQL> update staff set salary=80000,comm=50000;
(5) Insert into区别
DB2 允许有类似这样多行插入:
insert into staff values(1212,'cemy',20,'sales',3,90000,30000;
(1212,'cemy',20,'sales',3,90000,30000);
oracle:
SQL> insert into staff values(1212,'cemy',20,'sales',3,90000,30000),
(1212,'cemy' ,20,'sales',3,90000,3)
(6) Nvl处理空值
Oracle: select productid,loginname,nvl(cur_rate,'0') from tablename;
DB2: select productid,loginname,value(cur_rate,'0') from tablename;
coalesce(cur_rate,'0')
(7) 清空表
Oracle:
truncate table TableName ;
DB2:
alter table TableName active not logged initially with empty table;
44、Jquery选择器(Jquery是JS框架)?
有id选择器、class选择器和标签选择器。
45、AJAX的异步刷新功能?
“异步刷新”通俗的说,就是只改变页面的某个部分,并不进行刷新和重新载入。
AJAX的原理:在客户端和服务器端进行异步刷新。
46、Jquery框架和dwr框架有什么区别?
Jquery框架比dwr框架更容易用。
DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站.它可以允许在浏览器里的代码使用运行在WEB服
务器上的JAVA函数,就像它就在浏览器里一样。
而Jquery是一个优秀的Javascrīpt框架。是一个js库,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+扽等)。jQuery使用户能更方便地处理HTML documents、DOM、events、实现动画效果,并且方便地为网站提供AJAX交互,而且还有许多成熟的插件可供选择。jQuery能够使用户的html页保持代码和html内容分离。
DWR着重点在于java类到js中的映射,更大程度的方便后台方法的调用。
jQuery的着重点在于页面的javascript的组织和管理,UI也较DWR显得更加丰富。
47、ibatis中的动态sql语句?
有些时候,sql语句where条件中,需要一些安全判断。例如:
<dynamic prepend="where">
<isNotNull property="deptno"> e.deptno=#deptno# </isNotNull>
<isNull property="deptno"> e.deptno like '%$deptno$%'</isNull>
<isEqual property="empno" compareValue="7369">empno=#empno# </isEqual>
<isNotEqual property="empno" compareValue="7369"> ename LIKE '%$ename$%' </isNotEqual>
<isEmpty> …… <isNotEmpty>等等
</dynamic>
48、Oracle数据库中都有什么触发器及区别?
(1)before、after、instead of触发器。
(2)区别:before是在记录操作之前触发;
after是在记录操作之后触发。
比如表之间定义的有外键,在删除主键时,必须要先删除外键表,这时就有先后之分。
(3)Instead of: 用于向一个由多个表连接成的视图作UPDATE、INSERT、DELETE操作时用此触发器。
49、数据库中的约束有哪两种?
唯一约束、非空约束、检查约束和主外键约束。
50、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。
51、触发器怎样处理并发操作?
在任何多用户数据库应用程序中,免不了会出现两个用户同时使用同一行的情况。数据库必须保证这从物理上也不可能实现。事物的隔离性原理(ACID测试的I)要求数据库确保:在一个会话的事务完成前,另一个会话的事务不能影响此会话,为此数据库必须对数据的并发访问进行串行化,确保虽然多个会话请求同一行,它们实际上要按顺序排队。借助于纪录和表锁定机制,可以实现并发访问的串行化。Oracle数据库中的锁定是完全自动的。只有在试图结合软件与包含不当代码的自动锁定机制时,或业务分析出错导致会话发生冲突的业务模型时,才会引发某些问题。
3.1共享锁与排他锁
排他锁(exclusive)-Oracle数据库中锁定的标准级别保证了最大可能的并发级别。如果某个会话正在更新一行,那么只有这行会被锁定。锁定这行为了防止其它会话对其进行更新,其它会话可以随时执行读取操作。只有在使用COMMIT或ROLLBACK命令结束事务之后,锁定才会被解除。
共享锁(shared)-共享锁被置于整个表上,同时许多会话可以获得同一个表上的共享锁。在一个表上放置共享锁的目的是为了防止另一个会话获得这个表上的排他锁,如果一个会话已经在一个表上防止了共享锁,那么其它会话就无法执行修改某个对象的语句(如删除这个表的一列)。为了在行上执行DML语句,当前会话必须获取待更改行上的排他锁以及包含这些行的表上的共享锁。如果另一个会话已经获取了待更改行上的排他锁,那么当前会话将被挂起,直至使用COMMIT或ROLLBACK命令解除这些锁定。如果一个会话已经获取了表上的共享锁以及其它行上的排他锁,就不会存在问题,一个表上的排他锁也是允许的,但是除非DDL语句要求这么做,默认锁定机制是不锁定整个表。只有在理由充分情况下,才可以要求在整个表上放置排他锁。
所有DML语句至少都需要两种锁定,受影响记录上的排他锁,以及包含受影响记录的表上的共享锁,排他锁能够防止其他会话干预指定的行,而共享锁则能够阻止其它会话使用DDL语句修改表的定义,这两种锁定会被自动请求。
52、Oracle的存储过程及优点?
CREATE OR REPLACE PACKAGE employee_test IS
TYPE employee_cur IS REF CURSOR;--用来存放员工的查询结果
FUNCTION saveEmployee(e_ename varchar2,
e_age number,
e_sal number,
e_dept number)
RETURN INTEGER;--定义增加员工的函数
PROCEDURE queryAll(emps out employee_cur);--定义查询全部员工过程
END employee_test;
CREATE OR REPLACE PACKAGE BODY employee_test IS
FUNCTION saveEmployee(e_ename varchar2,
e_age number,
e_sal number,
e_dept number) --此处无分号;
RETURN INTEGER IS
BEGIN
INSERT INTO employee
(id, name, age, salary, department)
VALUES
(employee_seq.nextval, e_ename, e_age, e_sal, e_dept);
COMMIT;
RETURN 1;--插入成功
EXCEPTION
WHEN OTHERS THEN
RETURN 0;--插入失败
END;
--实现查询所有员工的一个过程(用的是多表连查)
PROCEDURE queryAll(emps out employee_cur) IS--过程
BEGIN
OPEN emps for
SELECT e.id, e.name, e.age, e.salary, d.dname
FROM employee e, department d
WHERE e.department = d.id;
END queryAll;
END employee_test;
Oracle数据库存储过程的优点:
1. 存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行Update、Insert、Query、Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
3.存储过程可以重复使用,可减少数据库开发人员的工作量。
4.安全性高,可设定只有某用户才具有对指定存储过程的使用权。
使用存储过程有三个主要的好处,即简单、安全、高性能。
53、jobs定时器?
Oracle定时器(Job)各时间段写法汇总
1、每分钟执行 Interval => TRUNC(sysdate,’mi’) + 1 / (24*60)
2、每天定时执行 例如:每天的凌晨2点执行
Interval => TRUNC(sysdate) + 1 +2 / (24)
3、每周定时执行 例如:每周一凌晨2点执行
Interval => TRUNC(next_day(sysdate,2))+2/24 --星期一,一周的第二天
4、每月定时执行 例如:每月1日凌晨2点执行
Interval =>TRUNC(LAST_DAY(SYSDATE))+1+2/24
5、每季度定时执行 例:每季度的第一天凌晨2点执行
Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 2/24
6、每半年定时执行 例如:每年7月1日和1月1日凌晨2点
Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+2/24
7、每年定时执行 例如:每年1月1日凌晨2点执行
Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),12)+2/24
8、每天下午20点执行 trunc(SYSDATE,'dd') + 20/24 或trunc(sysdate+1)+ 20/24
9、每周五下午 11:10:20执行:trunc(next_day(sysdate,'星期五'))+23/24+10/1440+20/86400
10、每月15日下午 11:10:20执行
last_day(add_months(TRUNC(SYSDATE,'MM'),-1))+15 +23/24+10/1440+20/86400
11、每年6月5日下午 11:10:20执行
trunc(to_date(to_char(sysdate,'yyyy')+1||'0605','yyyy-mm-dd'))+23/24+10/1440+20/86400
54、单例模式和工厂模式的优缺点?
单例模式优点:
(1) 控制资源的使用,通过线程同步来控制资源的并发访问;
(2) 控制实例产生的数量,达到节约资源的目的。
(3) 作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。
单例模式缺点:
首先单例模式很难实现序列化,这就导致采用单例模式的类很难被持久化,当然也很难通过网络传输;其次由于单例采用静态方法,无法在继承结构中使用。最后如果在分布式集群的环境中存在多个Java虚拟机的情况下,具体确定哪个单例在运行也是很困难的事情。
工厂方法模式的优点:
当需要增加新的产品时,只需要增加一个具体产品类及其相应的工厂类。克服了简单工厂模式的系统扩展困难的缺点。
工厂方法模式的缺点:
由于当要新增产品时,要增加一个具体类和相应的工厂类,系统开销大。
55、数据库中的三范式?
(1) 第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。
(2) 第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。
假定选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分),关键字为组合关键字(学号, 课程名称),因为存在如下决定关系:
(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
这个数据库表不满足第二范式,因为存在如下决定关系:
(课程名称) → (学分)
(学号) → (姓名, 年龄)
即存在组合关键字中的字段决定非关键字的情况。
(3) 第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系:
关键字段 → 非关键字段x → 非关键字段y
假定学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字"学号",因为存在如下决定关系:
(学号) → (姓名, 年龄, 所在学院, 学院地点, 学院电话)
这个数据库是符合2NF的,但是不符合3NF,因为存在如下决定关系:
(学号) → (所在学院) → (学院地点, 学院电话)
即存在非关键字段"学院地点"、"学院电话"对关键字段"学号"的传递函数依赖。
它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知。
把学生关系表分为如下两个表:
学生:(学号, 姓名, 年龄, 所在学院);
学院:(学院, 地点, 电话)。
这样的数据库表是符合第三范式的,消除了数据冗余、更新异常、插入异常和删除异常。
56、Junit的特点?
写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度,减少回归错误造成的时间消耗,在一般情况下会大大提高效率。
能精确到每一个方法。
57、数组的特点?
把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。
特点:类型相同,长度固定。
58、为什么要使用MVC模式?
分层明确,便于后期维护。
59、List数组和普通数组的区别?
1.数组是固定大小的,不能伸缩;而集合却是可变长的 。
2.数组要声明元素的类型,集合类的元素类型却是object.
3.数组可读可写不能声明只读数组。集合类可以提供ReadOnly方法以只读方式使用集合。
4.数组要有整数下标才能访问特定的元素,然而很多时候这样的下标并不是很有用。集合也是数据列表却不使用下标访问。
60、为什么在建立索引?(因为可以大大提高系统的性能)
(1)CREATE [UNIQUE] INDEX 索引名 ON 表名 (列名)
(2)列名也可以为多个,即复合式索引
(3)如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀特性。
第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
第四,在使用分组和排序子句进行数据检索时,也可以显著减少查询中分组和排序的时间。
第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
61、ArrayList和LinkList的区别?
ArrayList查询快,修改慢;LinkList修改快,查询慢。
62、创建线程的两种方法:
(1)通过继承Thread类,重写run ( ) 方法。
(2)通过实现 Runnable接口,定义run()方法。
class Thread1 extends Thread {
public void run() {
System.out.println("thread1 is running......");
System.out.println("thread1 is 11111");
System.out.println("thread1 is 22222");
}
}
class Thread2 implements Runnable {
public void run() {
System.out.println("thread2 is running......");
System.out.println("thread2 is 33333");
System.out.println("thread2 is 4444444");
}
}
63、struts2的流程:(在页面调用action时才会触发拦截器)
64、struts2拦截器:(有三种)
Struts2拦截器是即插即用的(也就是说,当去掉拦截器的代码后,不影响其它程序的执行)
(1)第一种拦截器是实现Interceptor接口:在action中拦截器的代码:
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.ActionInvocation;
public class MyIntercre implements Interceptor {
public String intercept(ActionInvocation arg0) throws Exception {
System.out.println("before first-----------");
arg0.invoke(); //调用被拦截的action
System.out.println("after first-----------");
return null;
}
public void destroy() {
}
public void init() {
}
}
在普通action中的代码:
public class TestAction {
public String add() {
System.out.println("add........");
return "suc";
}
}
在struts的xml中的代码:
<package name="first1" extends="struts-default">
<interceptors>
<interceptor name="MyInter1" class="com.cstp.action.MyInterceptor1"></interceptor>
</interceptors> //声明拦截器的action
<action name="Test_*" class="com.cstp.action.TestAction" method="{1}">
<interceptor-ref name="MyInter1"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 使用拦截器时必须先引入默认拦截器 -->
<result name="suc">success.jsp</result>
</action>
</package>
在index.jsp中的代码:
<body>
<a href="Test_add.action">链接</a>
</body>
在控制台的打印效果为:
before first-----------
add........
after first-----------
(2)第二种拦截器是继承抽象AbstractInterceptor类,重写intercept方法在action中拦截器的代码:
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.ActionInvocation;
public class MyIntercre2 extends AbstractInterceptor {
public String intercept(ActionInvocation arg0) throws Exception {
System.out.println("before second-----------");
arg0.invoke();//调用被拦截的action
System.out.println("after second-----------");
return null;
}
}
调用方法和第一种方法一样。
(3)第三种拦截器是继承MethodFilterInterceptor类,这种拦截器可以具体到普通action中的某一方法。在action中拦截器的代码:
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
import com.opensymphony.xwork2.ActionInvocation;
public class MyIntercre3 extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation arg0) throws Exception {
System.out.println("before third-----------");
arg0.invoke();//调用被拦截的action
System.out.println("after third-----------");
return null;
}
}
在普通action中的代码:
public class TestAction {
public String add() {
System.out.println("add........");
return "suc";
}
publicString add1() {
System.out.println("add11111........");
return "suc";
}
public String add2() {
System.out.println("add222222........");
return "suc";
}
}
在struts的xml文件中的代码:
<package name="first1" extends="struts-default">
<interceptors>
<interceptor name="MyInter1" class="com.cstp.action.MyIntercre">
</interceptor>
<interceptor name="MyInter2" class="com.cstp.action.MyIntercre2">
</interceptor>
<interceptor name="MyInter3" class="com.cstp.action.MyIntercre3">
<param name="includeMethods">add,add1</param>
<!-- 执行action中的add()和add1()方法时执行此拦截器3 -->
<param name="excludeMethods">add2</param>
<!-- 除了action中的方法add2()以外的方法都执行拦截器3 -->
</interceptor>
</interceptors>
<action name="Test_*" class="com.cstp.action.TestAction" method="{1}">
<interceptor-ref name="MyInter1"></interceptor-ref>
<interceptor-ref name="MyInter2"></interceptor-ref>
<interceptor-ref name="MyInter3"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 使用拦截器时必须先调用默认拦截器 -->
<result name="suc">success.jsp</result>
</action>
</package>
在index.jsp中的代码:
<body>
<a href="Test_add.action">链接</a>
<a href="Test_add1.action">链接111111</a>
<a href="Test_add2.action">链接222222</a>
</body>
在控制台执行的结果: a)点击“链接”的效果:
before first-----------
before second-----------
before third-----------
add........
after third-----------
after second-----------
after first-----------
b)点击“链接111111”的效果:
before first-----------
before second-----------
before third-----------
add11111........
after third-----------
after second-----------
after first-----------
c}点击“链接222222”的效果:
before first-----------
before second-----------
add222222........
after second-----------
after first-----------
(4)可以把拦截器封装栈,称为拦截器栈在struts 的xml文件中的代码:
<package name="first1" extends="struts-default">
<interceptors>
<interceptor name="MyInter1" class="com.cstp.action.MyIntercre">
</interceptor>
<interceptor name="MyInter2" class="com.cstp.action.MyIntercre2">
</interceptor>
<interceptor name="MyInter3" class="com.cstp.action.MyIntercre3">
<param name="includeMethods">add,add1</param>
<!-- 执行action中的add()和add1()方法时执行此拦截器3 -->
<param name="excludeMethods">add2</param>
<!-- 除了action中的方法add2()以外的方法都执行拦截器3 -->
</interceptor>
<interceptor-stack name="MyInter"> <!-- 拦截器栈 -->
<interceptor-ref name="MyInter1"></interceptor-ref>
<interceptor-ref name="MyInter2"></interceptor-ref>
<interceptor-ref name="MyInter3"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 使用拦截器时必须先调用默认拦截器”defaultStack” -->
</interceptor-stack>
</interceptors>
<action name="Test_*" class="com.cstp.action.TestAction" method="{1}">
<interceptor-ref name="MyInter"></interceptor-ref> //调用拦截器栈
<result name="suc">success.jsp</result>
</action>
</package>
在action中拦截器的代码不变,普通action中的代码不变,在index.jsp中的代码也不变,则在控制台的打印结果也不会改变65、struts2中的通配符:
通配符:
<action name="Login_*" class="com.cstp.action.LoginAction" method="{1}">
语法:在页面访问,Login_ + method.action
66、什么时候会用到拦截器:
在写日志、权限判断的时候会用拦截器。
67、struts2的核心是什么?
Web work,它是个低侵入性,可扩展的框架,它的核心也就是拦截器。
68、Struts1框架和Struts2框架的区别?
(1)struts2比struts1好用;
(2)struts1是单例模式;struts2是多例模式,没有线程安全问题。
(3)struts1不好做单元测试;struts2的单元测试比较好做;
(4)struts1依赖传统的servlet;struts2不依赖servlet;
(5)struts2有拦截器。
69、hibernate框架和ibatis框架的区别?
Hibernate和ibatis都可以调用存储过程。
(1) ibatis是半封装的;hibernate是全封装的;
(2) ibatis可以灵活写sql语句;hibernate的sql语句自动生成,但hibernate在做表与表复杂关系时比较麻烦;
(3) ibatis便于后期维护;
(4) 对海量数据的查询最好不要用hibernate;
(5) 两者都可以调用存储过程,但不用hibernate调用,比较复杂。(面试时先不说此区别,如问再说)
70、hibernate框架主键生成策略?
在Hibernate中,提供了主键生成策略。下面是比较常用的几种:
1:assigned
----表示在新增数据时由应用程序指定主键的值。主要针对主键是采用自然主键的形式。这种方式,适用于主键列不是自动增长列。
其缺点为在执行新增操作时,需查询数据库判断生成的主键是否已经存在。
2:increment
----是mysql数据库的,表示新增数据操作时由hibernate自动生成主键值。其生成的值为:先查询该主键列的最大值,然后在最大值的基础上加上1.适用于采用代理主键形式的主键列。同样不能用于主键列是自动增长的表。但是,该主键生成策略也有些缺点。
(1)新增数据前先查询一遍,影响了性能。
(2)主键的类型只能为数值型的int或者long
(3)并发操作时的冲突问题。
3:identity
----不如说是为sqlserver数据库量身定做的。主要适用于sqlserver数据库的自动增长列的表。
4:native
----表示根据不同的数据库采用不同的主键生成策略。比如,当前数据库为sqlserver,则会采用identity,如为oracle,则采用 oracle中的sequence等。区分数据库的不同是以hibernate主配置文件中sessionFactory中配置的数据库方言。
5: sequence
采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。
6、uuid.hex:由 Hibernate 基于128 位 UUID 算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
7、uuid.string:与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。
- <id name="实体类属性名" type="java.lang.Integer">
- <column name="对应表中主键字段名" />
- <generator class="assiged|increment|identity|native|........" />
- </id>
<id name="实体类属性名" type="java.lang.Integer">
<column name="对应表中主键字段名" />
<generator class="assiged|increment|identity|native|........" />
</id>
采用hibernate的主键生成策略,就可以比较灵活和方便的对表中的主键字段进行操作了。而且,不同的数据库,不同的主键形式,也只需要修改下映射文件就可以了。
71、hibernate和JDBC的优缺点?
(1)hibernate自动生成sql语句,其编写的代码比JDBC少;
(2)处理比较复杂的表关系时,用JDBC,它比较有优势;
(3)hibernate比JDBC占内存。
72、ibatis的优缺点?
优点:减少了代码量,灵活写sql语句
缺点:配置文件较多
73、hibernate的优缺点?
优点:自动生成sql语句,减少了代码量;缺点:不便于后期维护,占用内存比较多。
74、hibernate中的两个缓存是什么?区别?
Ø Hibernate缓存的作用:Hibernate是一个持久层框架,经常访问物理数据库,为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能,从而使用缓存。
Ø Hibernate的缓存包括Session的缓存和SessionFactory的缓存两个。
Ø Session是由sessionFactory创建的。Hibernate查询数据去先去缓存中查找,缓存中没有再去数据库中查找。必须经常清理session,否则会报内存溢出的问题。
Ø Hibernate一级缓存又称为“Session的缓存”,它是内置的,不能被卸载(不能被卸载的意思就是这种缓存不具有可选性,必须有的功能,不可以取消session缓存)。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
Ø Hibernate二级缓存又称为“SessionFactory的缓存”,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。第二级缓存是可选的,是一个可选的可插拔的插件,在默认情况下,SessionFactory不会启用这个插件。
75、在项目中,hibernate中的缓存是怎样管理的?
要及时清除缓存,否则会报内存溢出的错误(或者回答:公司框架自动处理不用我们去管理。)
76、hibernate中的清除缓存的方法?
有两种:session.clear()和session.close()。
session.evict(emp);//移除缓存中的对象
77、hibernate中的c3p0?
C3p0指的是数据库连接池
78、 hibernate中,load()和get()方法的区别?1.从返回结果上对比:
load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常
get方法检索不到的话会返回null
eg: Emp emp = (Emp) session.load(Emp.class, 100L);
System.out.println(emp);//数据库中没有此记录,load()方法则返回
org.hibernate.ObjectNotFoundException异常
Emp emp1 = (Emp) session.get(Emp.class, 100L);
System.out.println(emp1);//数据库中没有此记录时,get()方法则返回null
2.从检索执行机制上对比:
get方法和find方法都是直接从数据库中检索;
load方法是懒(延迟)加载的,执行则比较复杂:先查找缓存,没有再去数据库中查找,有则直接返回。
79、 hibernate可不可以生成表?
可以,但很少用其这个功能。
80、 hibernate的生命周期?
暂存Transient——持久Persistent——分离Detached
Transient(暂存对象):使用save()之前都是暂存对象;
Persistent(持久状态):使用了save()方法加以储存且Session 实例尚未关闭(close);
Detached(分离状态):执行session.close()之后
81、 关于hibernate的优化?
(1) HQL的优化
(2) 配置表关系(一对多或多对一,开发时尽量用多对一)
(3) 查询海量数据时用iterator不要使用list
(4) 主键生成策略不要使用native
(5) 尽量配置双向关联
(6) 使用缓存
(7) 数据库配置外键
(8) 尽量使用批量更新
82、 spring和ejb的区别?
ejb相对于spring是重量级的;spring是轻量级的;
spring可以和其他的框架整合一起使用;而ejb不可跟别的框架整合,只能用自己的框架。
83、 AOP是什么?
AOP是面向切面编程,可插拔的,和struts2中的拦截器一样。
OOP是面向对象编程。
AOP是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面(方面)编程。主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
84、 IOC/DI是依赖注入(控制反转)?
控制反转:意味着将你设计好的类交给系统去控制,而不是你的类内部控制。也就是将对象的创建和获取提取到外部。由外部容器提供需要的组件。
依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。
85、 重量级和轻量级的区别?
实际上是以启动程序需要的资源来决定。比如,EJB启动的时候,需要消耗大量的资源,内存,CPU等,所以是重量级。而Spring则不,所以是轻量级框架。
重量级 需要继承或实现框架中的类或接口
轻量级 不需要继承或实现任何类任何接口
86、 AJAX是怎样实现的?
我们用的是Jquery框架(从框架方面答,传统的Ajax、Jquery框架或者是DWR框架)
87、 ibatis的动态sql语句?
依据传入参数的不同来执行相应的where条件语句进行安全判断。
88、 spring中的Bean的生命周期?
(1) 容器Bean的定义信息并且将其实例化;
(2) 受用依赖注入,spring按照Bean定义信息配置Bean的所有属性。
(3) 如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法Bean的ID;
(4) 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身;
(5) 如果BeanPostProcessor和Bean关联,那么它们的postProcessBeforeInitialization()方法将被调用;
(6) 如果Bean指定了init-method方法,它将被调用;
(7) 如果有BeanPostProcessor和Bean关联,那么它们的postProcessAfterInitialization()方法将被调用;
(8) 使用Bean;
(9) 在容器关闭时,如果Bean实现了DisposableBean接口,则执行他的destroy()方法;
(10) 在容器关闭时,可以在Bean定义文件使用destroy-method属性设定方法名称,例如:
<bean id="helloBean"
class="onlyfun.caterpillar.HelloBean"
destroy-method="destroyBean">
如果有以上设定的话,则进行至这个阶段时,就会执行destroyBean()方法。
89、 spring中的Bean采用的模式?
spring中的Bean采用的是单例模式,为了避免线程不安全的问题,可以把其模式设置成为多例模式。
方法:把bean标签中的singleton属性值设为false。如下所示:
<bean id="helloBean" class=“com.cstp.HelloBean" singleton="false">