欢迎大家来到IT世界,在知识的湖畔探索吧!
1.java语言是强类型还是弱类型语言?为什么?
Java 是强类语言,在使用变量时有如下规则:
ü 变量必须声明,并且初始化以后才能使用。
ü 变量必须有明确的类型(type)。
ü 变量不能重复定义。
javascript是一种弱类型语言,即变量在声明时,不能明确声明其类型
变量的类型是在运行时确定的,并且可以随时改变
2.JAVA的数据类型有哪些?
⑴基本数据类型(八种):
整型: byte 1字节, short 2字节, int 4字节, long 8字节
浮点型: float 4字节, double 8字节
【float 类型共 32位(不 int相同),其中 1位为符号位, 指数 8 位, 尾数23 位。】【double 类型能表示64位,其中1 位符号位,11位指数,52位尾数】
【浮点数的字面量默认是double】
字符型: char 2字节【unicode编码值】
boolean型: boolean 1字节 【值只有true和false】
隐式类型转换:
正方向: charà
byteàshortà intàlongàfloatàdouble
负方向:
⑵引用类型(自定义类型):对象:比如String
数组:int[]
接口:interface
3.JAVA中成员变量和局部变量的区别?
⑴成员变量:是在类范围内定义的(也叫成员属性)
类属性:使用static修饰的就是类属性。
作用域: 类属性的作用域与这个类的生存范围相同,它作为类的一个成员,与类共存亡。只要类存在,程序就可以访问该类的类属性。
实例属性:不被static修饰的就是实例属性。
作用域: 实例属性则从这个类的实例(对象)被创建开始存在,直到系统完全销毁这个实例,它作为实例(对象)的一个成员,与实例(对象)共存亡。只要实例存在,程序就可以访问该实例的实例属性。
⑵局部变量:在一个方法内定义的变量。(包括方法的形式参数)
1.形参:作用域是整个方法体
2.方法局部变量:一个代码块中
3.代码块局部变量:一个代码块中
注意:局部变量除了形式参数外,都必须显示初使化(必须显示指定初使值)。否则不可以访问它们。
形式参数不须显示初使化,它在被调用时由系统完成。
4.前++和后++的区别?
i++, 后++, 先将 i 的值作为整个表达的值, 然后将i 增加 1。
ü ++i, 先++, 先将 i 增加1, 然后将 i 的值作为整个表达的值。
5. 短路运算符和非短路运算符的区别?
短路运算符[条件1 && 条件 2],如果条件1不成立,则条件2不执行;
非短路运算符[条件1 & 条件 2],两个条件都会执行。
6.怎样取得数组的长度?
数组:arr.length 集合:list.size() 字符串:str.length()
7. 实现数组拷贝(复制)的2种方法?
System.arraycopy(src , srcPos, dest , destPos , length) ;
src – 源数组。
srcPos – 源数组中的起始位置。
dest – 目标数组。
destPos – 目标数据中的起始位置。
length – 要复制的数组元素的数量。
Arrays.copyOf(src , length):是 JDK1.6 版本提供的方法,比起System.arraycopy()使用更简便.
(注:当然,可以用新建数组用for循环的方式进行复制)
8.java中的4种访问制权限有哪些?分别作用范围是什么?
(1).public:最大访问控制权限,对所有的类都可见。
(2).protect:修饰的,在类内部、同一个包、子类中能访问
(3).default:包访问权限,即同一个包中的类可以可见。默认不显式指定访问控制权限时就是default包访问控制权限。
(4).private:最严格的访问控制权限,仅该类本身可见。
(注:访问控制修饰符可以修饰类,成员变量,方法,但是修饰类只用public和default)
9.JAVA5的新特性有哪些?
(1)循环(For-each循环)
for (type variable : array){ body}
for (type variable : arrayList){body}
而1.4必须是:
for (int i = 0; i < array.length; i++){ type variable = array[i]; body}
for (int i = 0; i < arrayList.size(); i++){type variable = (type) arrayList.get(i); body}
(2)泛型
以ArrayList为例,包括创建一个容器对象和取得容器内对象操作:
1.5 ArrayList<Type> arrayList =new ArrayList<Type>(); arrayList.get(i)
1.4 ArrayList arrayList =new ArrayList(); (Type) arrayList.get(i)
(3) 自动装箱拆箱
在JDK5.0以前,在原始类型与相应的包装类之间的转化是不能自动完成的。要完成这种转化,需要手动调用包装类的构造函数,在JDK5.0环境中,可以自动转化:
1.5 Integer wrapper = n; int n = wrapper;
1.4 Integer wrapper = new Integer(n); int n = wrapper.intValue();
自动装包/拆包大大方便了基本类型数据和它们包装类地使用。自动装包:基本类型自动转为包装类.(int >> Integer);自动拆包:包装类自动转为基本类型.(Integer >> int);
(4)静态导入
静态导入功能对于JDK 5.0以前的版本是不支持的。
import static java.lang.Math;
import static java.lang.System;
…
1.5 out.println(sqrt(PI));
1.4 System.out.println(Math.sqrt(Math.PI));
(5) 可变参数(Varargs)可变参数使程序员可以声明一个接受可变数目参数的方法。注意,可变参数必须是函数声明中的最后一个参数。在JDK1.5之前,可以用重载来实现,但是这样就需要写很多的重载函数。line1 public void write(Object… objs) {line2 for (Object obj: objs)line3 System.out.println(obj);line4 }
10.面向对象编程中几种对象组合方式——is-a /has-a/use-a:
(1).is-a组合:一个类继承具有相似功能的另一个类,根据需要在所继承的类基础上进行扩展。
优点:具有共同属性和方法的类可以将共享信息抽象到父类中,增强代码复用性,同时也是多态的基础。
缺点:子类中扩展的部分对父类不可见,另外如果共性比较少的时候使用继承会增加冗余代码。
(2).has-a组合:has-a组合是在一个类中引用另一个类作为其成员变量。
优点:可扩展性和灵活性高。在对象组合关系中应优先考虑has-a组合关系。
缺点:具有共性的类之间看不到派生关系。
(3).use-a组合:是一个类中使用到了另外一个类,依赖关系
11.构造方法(构造器)特点?
ü Java 中的构造器(构造方法)声明在类内部。
ü 方法名与类名一致的方法叫构造方法
ü 构造方法不能声明返回值类型。
ü 构造方法可以包含参数,参数一般是创建对象实例必须依赖的条件(前提条件)。
子类默认调用父类的无参构造器,如果父类没有无参构造器,那么子类必需显示的去调用父类的有参构造器
如果一个类没有提供无参构造器,那么编译器将会自动提供一个无参构造器。
12.JAVA中属性和方法的静态绑定和动态绑定?
静态绑定:Java 根据引用变量类型查找属性
动态绑定:java 根据实际的对象查找方法
13. JavaBean 规范?
1) 必须有包(package)
2) Java 类,具有无参数构造器
3) 有用 getXxx() 和 setXxx() 声明的Bean属性
n 如:getName() 和 setName(String n) 声明的 Bean属性为:name, 不是否有实例变
量 name 无关
n boolean类型的get方法可以有两种形式:getMarried() 戒者 isMarried()
4) 必须实现序列化接口(注:在学习IO 的时候具体学习)
14.static关键字的特点?
static 静态关键字修饰:属性、方法、内部类、代码块
static 修饰的资源属于类级别,是全体对象实例共享的资源
static 变量在类加载期间初始化
静态代码块是在类加载期间运行的代码块,由于类只加载一次,所以静态代码块只执行一次!
15.final关键字的特点?
final可以修饰类,方法,变量
final 修饰的类,不能再被继承
final修饰的方法,不能覆盖final 方法
final 修饰的变量
final的局部变量,只能初始化不能改
final的方法参数,不能改
final 的引用,引用指向不能改,但是对象的属性可以改
16.常见的final类有哪些?
Java 的 String 就是 final类,不能被继承!
Math 是final类,不能被继承!
Integer 、Long、Character 等包装类是 final类,不能被继承!
17.抽象类和接口的区别?
抽象类–不具体的类
1 抽象方法,只有行为的概念,没有具体的行为实现。
使用:abstract 关键字修饰,并且没有方法体。
2 包含抽象方法的类,就一定是抽象类。
使用: abstract 关键字修饰,包含抽象方法。
如:平面图形一定可以计算面积。
public abstract class CRMSystem{
public abstract Client addClient(
String name, String qq);
}
3 抽象方法和抽象类非常适合作为系统的分析和设计的工具。
4 抽象类不能直接创建实例。可以定义引用变量。
5 抽象类只能被继承,一个具体类继承一个抽象类,必须实
现所有抽象方法。
接口
1. 接口:全部的方法都是抽象方法,全部的属性都是常量。
接口用来表示纯抽象概念,没有任何具体的方法和属性。
2 .不能实例化,可以定义变量。
3 .接口变量可以引用具体实现类的实例。
4 .接口只能被实现,一个具体类实现接口,必须使用全部的
抽象方法。
5 .接口之间可以继承。
6 .一个具体类可以实现多个接口,实现多继承现象,表示:
一个概念即是XXX也是XXX.
7 .接口中的属性,默认是常量 public static final
8 .接中的方法一定是:public abstract
9 .实现一个接口,使用关键字implements, 实现实际上是
一种继承关系。接口和实现类是父子类型的关系
18.重载和重写的区别?
重载:方法名相同,参数不同(参数类型或者长度)
重载和修饰符和返回类型无关。
一是方法的参数列表必须改变,包括参数的类型,参数的个数多少,参数顺序。
二是重载对返回类型,访问修饰符,异常声明没有任何限制,可以作任意的修改。实质上,重载只是创建了一个方法而已,特殊的地方在于方法的名字。
重写:两同两小一大(规则)
两同:方法名相同 参数类型 相同
两小:返回值类型(基本数据类型要一致,引用类型可以是其子类)
抛出的异常要小(也可以抛出父类型的异常的部分异常,或者不抛出异常)
一大:访问控制修饰符大
(1)重写方法必须和被重写方法具有相同的参数列表,返回类型必须和被重写方法的返回类型相同或者是返回类型的子类型。
(2)重写方法的访问控制修饰符不能比被重写方法更严格(比如一个在父类中声明为public的方法重写成一个protected的方法)。
(3)只有实例方法才能被重写,超类中的final方法不能被重写。
(4)重写方法不能抛出新的检查异常,或者是抛出比被重写方法声明的检查异常更广泛的检查异常。
19.==和equals()的区别?
“==”,比较引用值和基本数据类型是否相等。
u xxx.equals()方法比较对象的内容是否相等。默认的比较规则是:比较引用
20.为什么要同时覆盖hashcode()和equals()?
hashCode()方法要不equals 方法一同覆盖(Sun公司规定)
u 当两个对象equals 比较为true 时,应具有相同的hashCode()值
u 当两个对象equals 比较为false 时,应具有不相同的hashCode()值
u hashCode() 值要稳定(一致性),一个对象创建以后就不应该再变化
默认的hashCode()值是当前堆对象地址转换的一个整数,这个整数不是内存地址!
在java的中,判断两个对象是否相等的规则是:
首先,判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等
如果相等,则判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等
21.String类有哪些常用的方法?
charAt()
length()
trim()
toLowerCase()
toUpperCase()
indexOf()
lastIndexOf()
endsWith()
startsWith()
substring(int start, int end)
substring(int start)
toCharArray()
22.String,StringBuilder,StringBuffer的区别?
String = char[] + 操作(复制创建新对象) char[]不可变
StringBuilder = char[] + 对char[]操作(处理当前数组内容) char[]可变
1) StringBuilder 是变长字符序列
2) StringBuilder 方法:append,insert … 都返回当前 StringBuilder 对象本身的引用
StringBuffer 和 StringBuilder API 几乎一样!
StringBuffer 是 java早期提供的(JDK1.0),速度稍慢,线程安全
StringBuilder 是 Java5 以后提供的(JDK5.0),速度快,非线程安全
23.谈谈集合框架的理解?
集合框架包括集合不映射(Collection and Map)
List 元素有先后次序的集合, 元素有 index 位置, 元素可以重复,继承自 Collection 接口,实现类: ArrayList, Vector, LinkedList
List 表示有先后次序的对象集合
ArrayList是使用变长数组算法实现的,ArrayList 实现自 List
1) ArrayList 和 Vector 的比较
n Vector(1.0 版本提供的),线程安全的,效率稍低,也是使用变长数组算法实现的,继承自 List 接口
n ArrayList,线程不安全的,效率高速度快(现在较常用)
2) ArrayList 和 LinkedList 的比较
n LinkedList 是采用双向循环链表实现的 List
n ArrayList 是采用变长数组算法实现的的 List
在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
ArrayList查询速度快,而LinkedList增删速度快
Set 元素无续, 不能重复添加, 是数学意义上的集合, 继承自 Collection 接口
n 实现类: HashSet(是一个只有 Key的 HashMap),使用Set时要重写hashCode,equals方法
HashMap 以键-值对(关键字:值)的形式存储对象,关键字 key 是唯一的、不重复的
1) key 可以是任何对象,Value可以任何对象
2) (key:value)成对放置在集合中
3) 重复的 key 算一个,重复添加是替换操作(会覆盖原来的元素)
4)HashMap 根据 key 检索查找value 值
HashMap 新,非线程安全,不检查锁,快
Hashtable 旧 (JDK1.2 版本以前),线程安全,检查锁,慢一点(差的很小)
23.散列表的特点?
散列表中存放的对象是不连续的,所以称为“散列表”
散列表的优点:查找迅速
在 ArrayList 中查找 Mac,顺序查找,需要查找 5 次
ü 在 HashMap 中(底层实现原理是散列表)查找 Mac,经过散列运算,仅需 1 次
24.java泛型的作用是什么?
泛型是 Java5 以后提出的语法现象,作用是在编译期检查的类型约束(运行期不检查泛型),泛型可以用来约束类中元素的类型
25.Collection和Collections的区别?
Collection是集合接口,下面有子接口,List,Set
集合的工具类为 Collections,同数组的工具类 Arrays 相同,其中提供了许多的方法,诸如排序、二分查找、打乱、填充等操作。
26.内部类的分类?各有什么特点?
1) 根据位置的不同,Java 中的内部类分为四种:
n 静态内部类
u 使用 static 修饰,声明在类体中
u 静态内部类中可以访问外部类的静态成员
n 成员内部类
u 声明在类体中,不使用static,具有类的成员特征,也就是,必须有类的实例才能
创建内部类实例
u 内部类实例可以访问共享外部类的成员变量(很常用)
u 如:链表的节点就可以定义为内部类
n 局部内部类 把类声明在方法中,就是局部内部类,作用域
u 类似局部变量(很少见)
n 匿名内部类
匿名类,非常常见,可以写在任何地方,就像一般的语句
语法更象是创建对象:Date d = new Date(){//…};
匿名类是对原类的一个继承,同时创建了实例,{} 就是继承以后的类体
类体中可使用所有类的语法
匿名类不能写构造器
匿名类可以从抽象类或者接口继承,必须提供抽象方法的实现
2) 任何内部类都编译成独立的class 文件
3) 最大的作用:封装!
27.怎么将Date和String互相转换?
28.Java中的异常理解?
异常是程序运行过程过程出现的错误,在Java中用类来描述,用对象来表示具体的异常。Java将其区分为Error与Exception,Error是程序无力处理的错误,Exception是程序可以处理的错误。
1)Error与Exception
Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。Error:一般指虚拟机相关问题,如虚拟机崩溃,虚拟机出错等这种错误无法恢复或不可捕获,将导致应用程序中断。对于Error一般不编写针对性代码对齐进行处理。
Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。
2)运行时异常和非运行时异常
检查异常:当代码中抛出了一个检查异常,那么编译器在编译代码时会检查代码是否有处理该异常的代码片段,没有则编译不通过。
非检查异常:编译器不检查该类异常抛出是否有代码处理。
(ClassNotFoundException不是RuntimeException的子类)
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException,ArrayIndexOutOfBoundsException, ClassCastException
等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
自定义异常 (自己定义异常表达错误)
MyException extends Exception 检测(check)异常
MyException extends RuntimException 运行时(runtime)异常
29.JAVA中异常处理的方式有哪些?
1)try…catch…finally
try{
//(尝试运行的)程序代码
}catch(异常类型 异常的变量名){
//异常处理代码
}finally{
//
}
注:子类异常的处理块必须在父类异常处理块的前面,否则会发生编译错误。
finally块中一定会执行吗?
2)throws,throw
throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。
throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。
30.实现序列化的作用?(implements Serializable)
序列化的作用是,将数据分解成字节流,以便存储在文件中或在网络上传输。
31.IO流的分类?以及常用流的写法?
分为:字节流和字符流 或者 输入流和输出流
InputStream is = new FileInputStream(“gbk.txt”);
Reader in = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(in);
PrintWriter out = new PrintWtirer(
new OutputStreamWriter(
new FileOutputStream(filename)));
32.创建线程的两种方式?
继承 Thread 类(extends Thread)或者实现Runnable 接口(implements Runnable)
1) 继承 Thread 类
n 实现步骤:
ü 继承 Thread 类, 覆盖run()方法, 提供并发运程的过程
ü 创建这个类的实例
ü 使用 start() 方法启动线程
2) 实现 Runnable 接口
n 实现步骤:
ü 实现 Runnable 接口, 实现run()方法, 提供并发运程的过程
ü 创建这个类的实例, 用这个实例作为Thread 构造器参数,创建Thread 类
ü 使用 start() 方法启动线程
33.线程的5 中状态
1) New 新建状态
n 当程序使用new关键字创建了一个线程后,该线程就处于新建状态,此时线程还未启动,
当线程对象调用start()方法时,线程启动,进入Runnable 状态
2) Runnable 可运行(就绪)状态
n 当线程处于Runnable 状态时,表示线程准备就绪,等待获取CPU
3) Running 运行(正在运行)状态
n 假如该线程获取了CPU,则进入Running 状态,开始执行线程体,即run()方法中的内
容
n 注意:
如果系统叧有1个CPU,那么在仸意时间点则叧有1条线程处于Running 状态;
如果是双核系统,那么同一时间点会有2条线程处于Running 状态
但是,当线程数大于处理器数时,依然会是多条线程在同一个CPU 上轮换执行
当一条线程开始运行时,如果它不是一瞬间完成,那么它不可能一直处于Running 状态,
线程在执行过程中会被中断,目的是让其它线程获得执行的机会,像这样线程调度的策
略取决于底层平台。对于抢占式策略的平台而言,系统系统会给每个可执行的线程一小
段时间来处理仸务,当该时间段(时间片)用完,系统会剥夺该线程所占资源(CPU),
让其他线程获得运行机会。
n 调用yield()方法,可以使线程由Running 状态进入Runnable 状态
4) Block 阻塞(挂起)状态
n 当如下情冴下,线程会进入阻塞状态:
ü 线程调用了sleep()方法主动放弃所占CPU 资源
ü 线程调用了一个阻塞式IO 方法(比如控制台输入方法),在该方法返回前,该线
程被阻塞
ü ……
n 当正在执行的线程被阻塞时,其它线程就获得执行机会了。需要注意的是,当阻塞结束
时,该线程将进入Runnable 状态,而非直接进入Running 状态
5) Dead 死亡状态
n 当线程的run()方法执行结束,线程进入Dead 状态
n 需要注意的是,不要试图对一个已经死亡的线程调用start()方法,线程死亡后将不能再次作为线程执行,系统会抛出IllegalThreadStateException 异常
注:
1) new运算创建线程后,线程进入New状态(初始状态)
2) 调用 start()方法后,线程从New状态进入Runnable 状态(就绪状态)
n start()方法是在main()方法(Running 状态)中调用的
3) 线程结束后,进入Dead 状态(死亡状态),被对象垃圾回收
4) main()方法结束后,其它线程,比如上例中p1和p2 开始抢着进入Running 状态
n 由谁抢到是底层操作系统决定(操作系统分配时间片)
n 单核处理器:在一个时间点上叧有一个线程在Running 状态;双核处理器:2 个
n 如果p1 进入Running 状态,当操作系统分配给它的时间片到期时,p1进入 Runnable
状态,p2进入Running 状态
n 在期间有可能其它的进程的线程获得时间片,那么p1和p2同时进入Runnable 状态,
等待操作系统分配时间片
5) 线程进入Dead 状态后,叧能被垃圾回收,不能再开始
6) 如果线程在运行过程中,自己调用了yield()方法,则主动由 Running 状态进入Runnable 状态
34. 异步与同步的区别?
1) 异步
并发, 各干自己的。如: 一群人上卡车
2) 同步
步调一致的处理。 如: 一群人上公交车
35.数据库中,char和varchar类型的区别?
char(n) 表示定长字符串( 方便查询 ) 最长放入n个字符 , 放入的数据如果不够n个字符则补空格 , 无论如何都占n个字符长度。
varchar(n) 表示变长字符串( 节省空间 ) 最长放入n个字符 , 放入的数据是几个长度就占多大空间。
select decode(a2,’A’,’AAAA’,’BBBB’) FROM table ;
select decode(a1,’A ‘,’AAAA’,’BBBB’) FROM TT ; –此处是两个空格
36.在数据库中怎么做表的复制?(一条语句完成)?
create table emp_xxx as select * from emp_yyy ;
(注:如何将一个表中的数据复制到另外一个表中?
insert into table(select * from table2);两个表结构一样
insert into table(name,age) (select name,age from table2);复制指定的字段
)
37.分别简述一下DDL,DML,DQL,TCL,DCL?
1)数据定义语言DDL( Data Definition Language ) , 是 SQL语言集中负责数据结构定义不数据库对象定义的语言 , 主要有create、alter、drop 和truncate 四种常用语句。
DDL对数据结构起作用。
ü create 数据库对象的创建
ü alter 修改数据库对象
ü drop 删除数据库对象
ü truncate 清空表数据
2) 数据操纵语言DML( Data Manipulation Language ) , 用户通过它可以实现对数据表的基本操作, 即对表中数据的增、删、改。
DML对数据起作用。
n insert 插入操作
n update 更新操作
n delete 删除操作
3) 数据查询语言DQL( Data Query Language ) , 用户主要通过它实现对数据的查询操作。
n select 查询操作
4) TCL事务控制语句是用来对DML操作进行确认的。
commit 提交数据
rollback 数据回滚
savepoint 保存点
5) 数据控制语言(Data Control Language,DCL)用于对用户授权或撤销其权限,也可使用角色实现对用户的批量授权或撤销权限,在应用开发层面较少用到。
grant(授予权限)/revoke(回收权限)
38.Oracle常用的单行函数有哪些?
round( 数字 , 小数点后的位数)用于数字的四舍五入
trunc( 数字 , 小数点后的位数)用于截取,如果没有第二个参数 , 默认是 0
to_date()和to_char()是时间处理的函数
ü to_date 将字符串数据 按指定格式 转换为 日期数据
ü to_char 将日期数据 按指定格式 转换为 字符串数据
coalesce( 参数列表 )函数的作用:返回参数列表中第一个非空参数 , 参数列表中最后一个值通常为常量
decode()函数是Oracle 中等价于case when语句的函数 , 作用同case 语句相同。
decode 函数语法如下:
decode(判断条件 , 匹配1 , 值 1 , 匹配2 , 值2 , … , 默认值)
nvl(bonus,0) 空值转换函数
39.常用的组函数有哪些?
AVG 求平均数
COUNT 求数量
MAX 求最大值
MIN 求最小值
SUM 求和
注意:
avg/sum操作数字
max/min可以操作各种数据类型
组函数默认忽略空值
40.判断语句是否正确?
select ename,count(*) from emp where ename=’KING’ group by ename;
select count(*),sum(sal) from emp group by ename;
在SELECT列表中所有未包含在组函数中的列都应该包含在 GROUP BY 子句中。
包含在GROUP BY 子句中的列不必包含在SELECT列表中。
41. 研发部有哪些职位?
select distinct job from emp_xxx
where deptno = ( select deptno
from dept_xxx
where dname = ‘developer’ ) ;
42.ALL,Any,In的用法?
ALL –大于最大值
Any–大于最小值
子查询的条件是单列还是多列没关系 , 关键是要分清返回的是单行还是多行。
如果是单行 , 用单行比较运算符 , = , >, < 这些
如果是多行 , 用 in, >all, >any, <all, <any 这些
43. 哪个部门的平均薪水比部门20的平均薪水高?
select deptno , avg( nvl(salary , 0) ) avg_s
from emp_xxx
group by deptno
having avg(nvl(salary,0)) > ( select avg(nvl(salary,0))
from emp_xxx
where deptno = 20 ) ;
44.什么叫关联子查询?
子查询中不再是独立的Sql语句 , 需要依赖主查询传来的参数 , 这种方式叫关联子查询
哪些员工的薪水比本部门的平均薪水低?不再和整个部门的平均薪水比较。
select ename, salary, deptno
from emp_xxx a
where salary < ( select avg(nvl(salary,0))
from emp_xxx
where deptno = a.deptno ) ;
–子查询不再是独立的Sql 语句 , 需要依赖主查询传来的参数a.deptno
45. 哪些人不是别人的经理?
select ename from emp_xxx a
where not exists (select 1 from emp_xxx
where mgr = a.empno) ;
46. union 和 union all的区别?
union去掉重复记录 , union all不去重
n union排序 , union all不排序
(当列的个数、列的顺序、列的数据类型一致时,我们称这两个结果集结构相同
ü 只有结构相同的结果集才能做集合操作)
47.Oracle中表连接的方式有哪些?
内连接(自然连接)
等值连接、自然连接和不等值连接
{内连接是join 关键字连接两个表,语法为 table1 join table2 on 条件。
根据使用的比较方式不同,内连接又分为等值连接、自然连接和不等值连接。
等值连接:所谓等值连接,是指在连接条件中使用等于(=)运算符比较被连接的值,也就是通过相等的列值连接起来的查询。
例子:Select empno,ename,sal,emp.deptno,dname from emp,dept where emp.deptno=dept.deptno;
非等值连接: 所谓不等连接,就是在连接条件中使用除等号(=)外的其他比较运算符,构成非等值连接查询。可以使用的比较运算符包括:>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、<>(不等于)、!=(不等于)、LIKE、IN和BETWEEN等。
例子:select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal; 查询所有员工的薪水等级
自然连接:自然连接是在两张表中寻找那些数据类型和列名都相同的字段,然后自动地将他们连接起来,并返回所有符合条件的结果。
例子:select * from emp natural join dept;
}
外连接
外连接的结果集 = 内连接的结果集 + 驱动表在匹配表中找不到匹配记录的数据和空值
{
使用一张表中的所有记录去和另一张表中的记录按条件匹配(空值也会匹配),这个表中的所有记录都会显示。
左外连接,右外连接,全外连接
LEFT/RIGHT/FULL OUTER JOIN
}
(1) 左外连接 (左边的表不加限制)
{
【例】t1 left outer join t2 --其中t1是驱动表,t2是匹配表
等价于:t2 right outer join t1
【例】查询每个员工的经理的名字?
select worker.ename,manager.ename from emp worker left outer join emp manager on worker.mgr=manager.empno;
}
(2) 右外连接(右边的表不加限制)
{
t1 right outer join t2 --t2是驱动表,t1是匹配表
等价于: t2 left outer join t1
【例】-哪些员工没有下属(不是别人的领导)? 外连接+匹配表PK is null 表示否定问题,不是,不包括,等等。
select manager.ename from emp worker
right outer join emp manager on worker.mgr = manager.empno
(首先找到所有经理下面的员工是哪些)
where worker.empno is null;
(然后将员工为空的过滤出来)
}
(3) 全外连接(左右两表都不加限制)full outer join
{
左表和右表都不做限制,所有的记录都显示,两表不足的地方用null 填充。
【例】
select e.ename, d.loc from emp e full outer join dept d on (e.deptno = d.deptno);
}
自连接(同一张表内的连接)自连接是等值连接的一种。表中的列外键关联自己表的主键列。
{
自连接(self join)是SQL语句中经常要用的连接方式,使用自连接可以将自身表的一个镜像当作另一个表来对待,从而能够得到一些特殊的数据。
【例】查询每个员工的经理的名字?
select worker.ename,manager.ename from emp worker join emp manager on worker.mgr=manager.empno;
}
48.什么是事务(Transaction)?什么是事务控制?
事务(Transaction)是指组成单个逻辑工作单元的一系列操作
事务控制(Transaction Control)则是指通过将一组相关操作组合为一个要么全部成功、要么全部失败的逻辑工作单元(即事务),以简化错误恢复、提高应用程序的可靠性。
49. 约束条件(constraint)有哪些?
主键( Primary key, 简称 PK )
1) 主键约束( primary key ) = 不能重复 + 不能为null
2) 主键约束可以用两种方式定义:列级约束和表级约束
非空约束( not null , 简称 NN )
注意:非空约束只能定义在列级
唯一约束( Unique , 简称 UK )
可以定义在表级和列级
检查约束( Check , 简称 CK )
可以定义在表级和列级
因为约束条件建立在列级时可读性不好 , 而丐不方便定义约束条件名字 , 一般建议定义在表级。
外键( Foreign key, 简称 FK )
之前讲的几个约束条件都是用来约束单个表中的列 , 而外键约束定义在两个表的两个字段上( 或者一个表的两个字段上 ) , 用亍保证相关两个字段的关系
constraint fk_customerid__cardinfo2 foreign key(customerID) references userInfo(customerID)
注意:一张表中,只能有一个PK,但是可以有多个FK
50. 视图(View), 索引 (Index), 序列(Sequence)?
视图(View):
视图的使用和表相同
视图的好处:简化查询 ;屏蔽数据库表结构、限制对数据的访问
视图不包含任何数据。是基表数据的投影。
视图本身并不在物理上保存数据,在视图上进行的查询或更新操作实际上都是针对其基表来完成的。
当基表变化时,视图也随着变化。
索引 (Index):
index :索引(Index)一种用于提升查询效率的数据库对象,使用索引可以快速定位数据、减少磁盘I/O操作次数。,注意:对于数据变更频繁(DML操作频繁)的表 , 索引会影响查询性能。
如果数据表有PK/Unique 两种约束 , 索引自动创建 , 除此以外 , 索引必须手动创建
自定义索引语法: create index 索引名 on 表名(列名) ;
为什么索引查询快?
(Oracle server 通过rowid快速定位要找的行
通过rowid定位数据能有效的降低读取数据块的数量
索引的使用和维护是自动的,一般情况下不需要用户干预)
序列(Sequence):
序列的特性:产生连续的不同的数字值用来作为数据表的主键。序列这种对象在Oracle、db2 等数据库中有 , 在mysql、sql server 中没有。(在mysql通过 auto_increment自动增长列来实现同样的功能)
51. TRUNCATE 与前述 DELETE 操作的区别?
DELETE 为 DML 操作,可以回滚,而TRUNCATE 为 DDL 操作,一经执行不可撤销,故其效率要高一些;DELETE 操作可以选择删除表中全部或部分数据,而 TRUNCATE 操作只能删除表中全部数据。
如果不再用到表中数据、但又需要保留表的结构,则可该使用 TRUNCATE TABLE操作;如果连表的结构也需要了,则可使用 DROP TABLE 操作将表彻底删除。
52. 第n条到第n条记录的获取方式?
Oracle获取方式:
select ename,sal,rn from (select ename,sal,rownum rn from emp) where rn>=5 and rn<=10;
select ename,sal,rn from (select ename,sal,rownum rn from emp) where rn between 5 and 10;
select id,name,jop,rn from(select id,name,jop,rownum rn from dept10 where rownum<10) where rn>5;
select t2.* from (select t1.*,rownum rn from emp t1 where rownum<=5) t2 where rn>3;
MySql获取方式:
SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
53.JDBC编程步骤?
1)注册Driver
Oracle: Class.forName(“oracle.jdbc.driver.OracleDriver”);
Mysql: Class.forName(“com.mysql.jdbc.Driver”);
2)建立连接
Mysql:String url = “jdbc:mysql://localhost:3306/tarena”;
Oracle: String url = “jdbc:oracle:thin:@localhost:1521:tarena”;
String name=”root”;
String pwd =”root”;
Connection conn = DriverManager.getConnection(url,name,pwd);
3)获得一个 Statement对象(两种方式)
Statement sta = conn.createStatement();
PreparedStatement pstm = conn.prepareStatement();
4) 通过 Statement执行 Sql 语句ResultSet rs = sta.executeQuery(String sql);返回一个查询结果集。用于select语句
int I = sta.executeUpdate(String sql);返回值为 int 型,表示影响记录的条数。用于insert,update,delete语句。
5)处理结果集
while(rs.next()){
System.out.println(rs.getString(“name”));
//——————
}
6) 关闭数据库连接(释放资源) 调用.close()
rs.close(); sta.close(); con.close();
ResultSet Statement Connection 是依次依赖的。
54. Statement和PreparedStatement区别?
1)PreparedStatement代码的可读性和可维护性
2) PreparedStatement尽最大可能提高性能.
数据库会对PreparedStatement语句进行预编译,下次执行相同的sql语句时,数据库端不会再进行预编译了,而直接用数据库的缓冲区,提高数据访问的效率。
3)最重要的一点是极大地提高了安全性.
如果是Statement构建的语句:select * from tb_name = ‘随意’ and passwd = ” or ‘1’ = ‘1’;很容易造成Sql注入。而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系。
55.xml和html的区别?
XML 被设计用来传输和存储数据。
HTML 被设计用来XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:
XML 被设计为传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。显示数据。
1) 超文本标记语言HTML(Hyper Text Markup Language
ü 写法格式: <a href=”link.html”>link</a>
ü 关注数据的展示不用户体验
ü 标记是固定的,不可扩展(如 <a></a>表示超链接)
2) 可扩展的标记语言XML(eXtensible Markup Language
ü 写法格式: 同html样式 <a>link</a>
ü 仅关注数据本身
ü 标记可扩展,可自定义
56.XML的解析方式?
1)DOM(Document Object Model 文档对象模型)
n 关键字:树(Document)
n 优点: 把 xml文件在内存中构造树形结构,可以遍历和修改节点
n 缺点: 如果文件比较大,内存有压力,解析的时间会比较长
2)SAX(Simple API for Xml 基于 XML的简单 API)
n 关键字:流(Stream)
n 把 xml文件作为输入流,触发标记开始,内容开始,标记结束等动作
n 优点: 解析可以立即开始,速度快,没有内存压力
n 缺点: 不能对节点做修改
57. servlet 是如何运行的?
当用户向浏览器地址栏输入http://ip:port/helloweb/sayHello?name=zs
1) 浏览器使用ip:port(端口号)连接服务器
2) 浏览器将请求数据按照http 协议打成一个数据包(请求数据包)发送给服务器
请求数据包的内容包含了请求资源路径(/helloweb/sayHello?name=zs),
另外,在请求数据包当中,还会包含浏览器自动生成的一些信息。
3) 服务器创建两个对象:请求对象(Request)和响应对象(Response)
服务器解析请求数据包,将解析之后的数据存放到请求对象里面,方便servlet读取请求 数据(因为servlet不用解析请求数据包,如果要解析,需要理解http 协议)。
请求对象是HttpServletRequest接口的一个实现。
响应对象是HttpServletResponse 接口的一个实现,响应对象由于存放servlet处理的结果。
4) 依据请求资源路径找到相应的servlet配置,通过反射创建servlet实例。然后调用其service()
方法。
在调用service()方法时,会将事先创建好的请求对象(request)和响应对象(response)作为参数进行传递。在servlet内部,可以通过request获得请求数据,戒者通过response 设置响应数据。
5) 服务器从response 中获取数据,按照 http 协议打成一个数据包(响应数据包),发送给浏览器。
6) 浏览器会解析响应数据包,取出相应的数据,生成相应的界面。
58.get和post请求的区别?
1)哪一些是get请求方式
a, 直接在浏览器地址栏输入某个地址。
b,点击链接地址
c, 表单默认的提交方式
2)get请求方式的特点
a,请求参数会添加到请求资源路径后面。
请求资源路径后面添加的参数数据量大小是有限制的,
b,会将请求参数直接显示在浏览器地址栏,不安全。
c, get方式只适合于向服务器请求资源或者是
向服务器提交少量的数据。
3)哪一些是post请求方式?
a,设置表单的method=”post”
4)post方式的特点
a, post方式会将请求参数及值添加到实体内容里面,可以放置大量的数据
b,因为不会将参数直接显示在浏览器地址栏,所以,相对安全。
get方式会将请求参数及参数值放在请求资源路径里面,携带的数据大小有限制,不适合提交大量的数据; post方式会将请求参数及参数值放在实体内容里面,理论上没有限制,
适合大量数据的提交。
59.重定向和转发的区别?
重定向:
1)什么是重定向?
服务器向浏览器发送一个状态码302 及一个消息头location(location 的值是一个
地址),浏览器会立即向 location所指定的地址发送一个新的请求。我们把这样一种
机制叫重定向。
2)编程:
response.sendRedirect(String url);
3)需要注意的问题
在重定向之前,不能够有任何的输出;如果response 缓存当中有数据,在重定向
之前,会自动清空。
4)重定向的特点:
a,地址任意
b,浏览器地址栏地址会变化(即变化为跳转之后的地址)。
转发
1)什么是转发?
一个web组件(servlet/jsp)将未完成的处理交给另外一个web组件继续完成。转
发所涉及的各个web组件可以共享request和response 对象。
2)编程:
step1 绑订数据到request对象上。
request.setAttribute(String name,Object obj);
request.removeAttribute(String name);
Object request.getAttribute(String name);
//如果绑订名不存在,则返回 null。
step2 获得转发器
RequestDispatcher rd = request.getRequestDispatcher(String url);
step3 转发
rd.forward(request,response);
servlet:负责业务逻辑处理(包括数据访问) 。
jsp:负责生成界面。
3)需要注意的问题:
在转发之前,response缓存的数据会被清空。
主要区别如下:
1) 地址
ü 转发的地址必须是同一个应用内部的某个组件(不能跨应用,不能跨服务器)
比如:
地址1 http://localhost:8080/web06/aaa.jsp
地址2 http://localhost:8080/web06/bbb.jsp
地址3 http://localhost:8080/web07/ccc.jsp
地址4 http://www.tarena.com.cn
在应用web06内部的组件aaa.jsp 可以将信息转发到地址2(同一应用),但是不可以
转发到地址3(跨应用)和地址4(跨服务器)
ü 重定向的地址没有限制
2) 能否共享request
ü 转发可以
ü 重定向不行
原因是转发是一次请求,重定向为两次请求,Request的生命周期叧能在一次请求内,
请求结束,Request 被删除
3) 浏览器地址栏的地址是否变化
ü 转发不变
ü 重定向会变
4) 事件是否处理完毕
ü 转发是一件事未做完
ü 重定向是一件事已经做完
60.get请求和post请求中文乱码问题的处理?
1)、Get请求:
Tomcat 这个容器会用ISO-8859-1这种编码去解析URL里面的值;
1. 解决方法:new String(request.getParameter(“username”).getBytes(“ISO-8859-1″),”UTF-8”);
2.直接改Tomcat配置:conf/server.xml
<Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ URIEncoding=”utf-8″/>
2)、Post请求:
在 html文件中,添加
<meta http-equiv=”content-type” content=”text/html;charset=utf-8″>
另外,表单的提交方式必须是 post。
request.setCharacterEncoding(“utf-8”);
get和post请求的中文乱码问题处理?
当表单提交时,浏览器会对表单中的中文参数值进行编码(会使用打开表单所在的页面时的编码格式来进行编码)。服务器在默认情况下,会使用iso-8859-1这种编码格式进行解码。所以会出现乱码。
1)get请求方式的处理:
第一种方式:
要确保表单所在的页面,使用指定的编码格式打开。对于html文件,可以添加:
<meta http-equiv=”content-type” content=”text/html;charset=utf-8″>,确保表单中的编码为utf8,能够存储中文。
在Servlet中使用name = new String(name.getBytes(“iso-8859-1″),”utf-8”);来处理编码
第二种方式:
找到tomcat—->conf—–>server.xml—-><Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ URIEncoding=”UTF-8″/>后面加上URIEncoding=”UTF-8″
2)post请求方式的处理:
2.1 首先确保html的编码为utf-8
2.1在服务器端,取数据之前,添加request.setCharacterEncoding(“utf-8”);
MySQL的乱码解决方案:
1. 如果第一次安装MySQL数据库:
在选择编码时,选择最后一项,并指定编码为utf8或者gbk(这两种编码支持中文,是我们比较常用的)
2. 如果已经按照完成了MySQL数据库,那么可以进行重新配置修改:
在开始菜单中找到:
然后重复第一个步骤即可。(注意:这样修改完成后,那么数据库中原来保存的数据如果有中文,就会乱码,因为当前的编码已经变为了utf8,而原来保存的可能是其它编码。)
3. 重启MySql的服务.右键管理员身份打开命令提示符窗口,
4. 进入MySQL中,如果通过一下命令查看编码如下图所示,那么表示配置正确:
但是这个时候如果向表中插入数据,会报编码错误,如下图:
这个时候,我们就可以使用set names gbk;命令来设定字符集为gbk。就可以正常插入数据了。(注意:这个只是让显示的时候正确,并不会改变表中的数据的编码。此命令只在当前会话中有效,也就是如果新开一个窗口打开MySql,用select查询时会发现还是乱码,这个时候如果要正确显示,那么还得用此语句。)
Servlet中的数据插入MySql乱码:(我们都用UTF8这样的编码来存储)
1. 首先在Servlet这个java文件得是utf8编码,在其中打印要插入MySql中的数据,查看是否能够正确显示,如果能够正确显示那么说明Servlet中的数据就是utf8编码。
2. 如果上一步不能通过检查,那么插入数据就会出现问题,直到检查第一步完成为止。
3. 建数据库之前首先保证MySql按照上面的安装正确:
4. 创建数据库: create database wuxi default character set ‘utf8’;
5. 可以使用show create database wuxi;来查看这个数据库的SQL语句.
6. 建表时加上: create table t_pic(id bigint primary key auto_increment,picName varchar(100), userId bigint) ENGINE=InnoDB DEFAULT CHARSET=utf8;
7. JDBC连接数据库时: conn = DriverManager.getConnection(
“jdbc:mysql://localhost:3306/jd1105db?useUnicode=true&characterEncoding=utf8″,”root”,”1234″);
1.乱码的解决方案:
1.1、html/jsp
1.1.1、html中:模拟一个消息头(content-type),告诉浏览器正在处理的数据的类型和字符集
<meta http-equiv=”content-type” content=”text/html;charset=utf-8″>,这个编码应该和html文件保存的编码一致(
如果不写这句话,可能浏览器在读取html时使用的编码有些步一致,而且同样会导致提交数据时的编码不一致)
1.1.2、jsp中:<%@ page language=”java” contentType=”text/html; charset=utf-8″ pageEncoding=”utf-8”%>
contentType属性:设置response.setContentType方法的参数值。
pageEncoding属性:告诉容器jsp文件的字符集,容器会按照该属性指定的字符集去解码(容器需要读取jsp文件的内容,有些容器默认情况下会按照iso-8859-1去解码)。
jsp中不需要加<meta charset=”utf-8” />因为contentType已经解决了告诉浏览器的编码问题
1.2、从html提交数据到Servlet
从html/jsp中的form表单将数据提交到Servlet,使用的编码是浏览器打开此页面的编码也就是和1.1中的设置有关系
1.3、Servlet
1.2.1、获取数据:分两种,get和post请求的处理方式不同
GET请求方式:
1.2.1.1、 TOMCAT默认ISO-8859-1 来处理get请求,因此可以设置默认编码为UTF-8解决,在tomcat安装的conf\server.xml文件中设置如下
<Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ URIEncoding=”UTF-8”/>
1.2.1.2、在所写到的Servlet中直接进行处理
String username = request.getParameter(“username”);
username = new String(username.getBytes(“ISO-8859-1“), “UTF-8”);
POST请求方式:
必须在获取参数之前,调用如下方法先解码
request.setCharacterEncoding(“UTF-8”);
String username = request.getParameter(“username”);
1.2.2、输出数据:response.setContentType(“text/html;charset=utf-8”);指定 HTTP 响应的编码,同时指定了浏览器显示的编码.
1.4、连接数据库时的编码:
“jdbc:mysql://localhost:3306/jsd1402db?useUnicode=true&characterEncoding=utf8″,”root”,”1234″);
1.5、DB数据库的编码:
1.5.1、修改整个数据库保存数据的编码: MySQL的乱码解决方案
1.5.2、创建数据库时设置的编码:
1.创建数据库: create database wuxi default character set ‘utf8’;
2.可以使用show create database wuxi;来查看这个数据库的SQL语句
3.create table t_pic(id bigint primary key auto_increment,picName varchar(100), userId bigint) ENGINE=InnoDB DEFAULT CHARSET=utf8;
61. servlet 的生命周期?
所谓生命周期,指的是servlet容器如何创建servlet实例、分配其资源、调用其方法、并销毁其实
例的整个过程。
阶段一: 实例化(就是创建servlet对象,调用构造器)
在如下两种情况下会迚行对象实例化。
第一种情况:
当请求到达容器时,容器查找该servlet对象是否存在,如果不存在,才会创建实例。
第二种情况:
容器在启动时,或者新部署了某个应用时,会检查web.xml当中,servlet是否有 load-on-starup 配置。如果有,则会创建该servlet实例。 load-on-starup 参数值越小,优先级越高(最小值为0,优先级最高)。
阶段二: 初始化
为servlet分配资源,调用init(ServletConfig config);方法 config 对象可以用来访问servlet的初始化参数。
初始化参数是使用init-param配置的参数。
init可以override。
阶段三: 就绪/调用
有请求到达容器,容器调用servlet对象的service()方法。
HttpServlet的service()方法,会依据请求方式来调用doGet()或者doPost()方法。
但是,这两个do 方法默认情况下,会抛出异常,需要子类去override。
阶段四: 销毁
容器依据自身的算法,将不再需要的servlet对象删除掉。
在删除之前,会调用servlet对象的 destroy()方法。
destroy()方法用于释放资源。
在servlet的整个生命周期当中,init,destroy只会执行一次,而service 方法会执行多次。
62.JSP和Servlet的区别?
Servlet是 sun公司制订的一种用于扩展web 服务器功能的组件规范。
java server page(java 服务器端页面技术),是 sun公司制订的一种服务器端动态页面生成技术的规范。 因为直接使用servlet生成页面,如果页面比较复杂,则代码过于繁琐,并且难以维护,所以对于比较复杂的页面,使用jsp 来编写,更容易编写和维护。
当客户端请求访问某个.jsp 文件,则服务器会自劢将.jsp 文件转换成一个.java 文件
(该.java 文件其实是一个servlet)。
63.JSP的隐含对象有哪些?(共9个)
out
request
response
session
application隐含对象其实就是ServletContext(Servlet上下文:容器在启动的时候,会为每一个应用创建唯一的一个Servlet上下文对象,该对象会一直存在,除非容器关闭。)
exception
config:ServletConfig实例。
page:相当于this,代表当前jsp实例。
pageContext:PageContext实例。
容器会为每一个jsp实例创建唯一的一个
pageContext对象。该对象一直存在,除非
jsp实例被容器销毁。
64.Cookie和Session的区别?
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
cookie存放在内存或者硬盘上,cookie.setMaxAge(int seconds); cookie 是一小段文本信息,伴随着用户请求和页面在Web服务器和浏览器之间传递。用户每次访问站点时,Web应用程序都可以读取cookie包含的信息。
session失效时间的设置,这里要分两方面来看:浏览器端和服务端。对于浏览器端而言,session与访问进程直接相关,当浏览器被关闭时,session也随之消失;而服务器端的session失效时间一般是人为设置的,目的是能定期地释放内存空间,减小服务器压力,一般的设置为当会话处于非活动状态达20或30分钟时清除该 session。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE
4、单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能超过3K。
5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
65.谈谈对MVC的理解?
1) 什么是MVC?
MVC是一种设计思想,根据职责不同将程序中的组件分成以下3个部分。
V(View视图):负责与用户交互。将数据展现,或者是接收数据
M(Model模型):负责业务处理。业务模型,数据模型
C(Controller控制器):负责协同模型和视图工作。视图有请求调用模型处理,模型处理完毕调用视图响应。
2)为什么使用MVC?
MVC是一个非常优秀的设计思想,基于该思想架构程序,可以提高程序的结构灵活性,便于日后维护、扩展和升级。
注意,下面内容助于理解:
1) 一个模型可以被多个视图共享模型只负责输出数据,不关心数据的表现形式,同一仹数据,可以使用多个不同的视图展现给用户。模型只负责处理数据,不关心是谁在调用,可以使用多种不同的界面来调用模型。
2) 方便测试
模型一般使用java 类来开发,在开发完成之后,可以立即测试。如果业务逻辑直接写在servlet
里面,则需要部署在服务器上面才能测试,比较麻烦。
3) 组件复用
控制器可以做成一个通用的模块。
4) 代码好维护,利于分工协作。
按照 mvc 的思想,可以对程序迚行分层,一般划分成表示层(包括 v,c)、业务层(m中的业务逻辑部分)、持久层(m中的数据访问逻辑部分)。下一层的代码发生改变,只要接口不变,不会影响到上一层的代码。
mvc的缺点
1) 采用 mvc 以后,会增加代码量,相应的开发周期以及开发的成本会相应增加。
2) 使用 mvc,需要良好的设计。如果设计不当,会增加开发的难度。
结论
一般来说,如果一个程序需要良好的架构,需要良好的代码的可维护性及可扩展性,需要使用mvc
思想来架构。反之,则不必使用。
66.什么是Ajax?
asynchronous javascript and xml(异步的javascript和 xml)。
为了解决传统的web 应用当中“等待-响应-等待”的弊端而创建的一种技术,其实质可以理解为:使用浏览器内置的一个对象(XmlHttpRequest)向服务器发送请求,服务器返回xml数据或者是文本数据给浏览器,然后在浏览器端,使用这些数据更新部分页面,整个过程,页面无任何的刷新。
67. ajax编程步骤?
1) 获得 XmlHttpRequest对象
2) 使用 XmlHttpRequest向服务器发请求。
a.发送get请求:
/* open(请求方式,请求地址,同步/异步)
* 请求方式: get/post
* 请求地址:如果是get请求,请求参数添加到地址之后。
* 比如 check_user.do?username=zs
* 同步/异步:true 表示异步。*/
xhr.open(‘get’,’check_user.do’,true);
b. 发送 post 请求
xhr.open(‘post’,’check_username.do’,true);
//必须添加一个消息头content-type
xhr.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”);
3). 在服务器端,处理请求。
4).在监听器当中,处理服务器返回的响应。
xhr.onreadystatechange=function(){
//编写相应的处理代码
if(xhr.readyState == 4){
//只有 readyState 等亍 4,xhr 才完整地接收到了服务器返回的数据。
//获得文本数据
var txt = xhr.responseText;
//获得一个xml dom对象。
var xml = xhr.responseXML;
//dom操作、更新页面
}
};
5.xhr.send(null)
Ajax技术的优点?
1.页面无刷新
2.不打断用户的操作,用户的体验好
3.按需获取数据,浏览器和服务器之间数据的传输量减少
4.是一个标准技术,不需要下载任何的插件
5.可以利用客户端(浏览器)的计算能力
68.什么是JQuery?
jQuery是一个JS框架,设计思想是将原始的dom对象封装成一个jQuery对象,通过调用jQuery对象的方法来实现对原始的dom对象的操作。这样设计的目的是:是为了更好地兼容不同的浏览器,简化代码。
70.程序,线程,进程的区别?
一般操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序被称为一个进程,当一个程序运行时,内部可能包含多个顺序执行流,每个顺序执行流就是一个线程。
1) 程序 指令 + 数据的 byte 序列,如: qq.exe
2) 进程 正在运行的程序, 是程序动态的执行过程(运行于内存中)
3) 线程 在进程内部,并发运程的过程(Java 中的方法可以看做线程)
71.在做项目的过程中,遇到了中文乱码问题,该如何处理?(比如网站主页查询页面显示乱码)
可以从页面,程序,以及数据库三个方面去查看问题的原因所在,主页面显示中文乱码,无外乎是因为从数据库中取出来的数据传输到主页面的过程中出现了编码问题,那么就应该从这三个方面去查找问题的所在。因为我们常用UTF-8的编码格式,所以我们就检查所有数据的编码是否都是UTF-8编码。
1. 查看一下页面jsp文件的编码格式(1.3.1/1.3.2)
1.1、项目文本文件默认编码:
【右击项目】->【Properties】->【Resource】->【Text file encoding】
1.2、文件默认编码:默认使用项目的默认编码
【右击文件】->【Properties】->【Resource】->【Text file encoding】
1.3、JSP文件编码:由于JSP要翻译为Servlet
1.3.1、JSP文件编码:
【右击文件】->【Properties】->【Resource】->【Text file encoding】
1.3.2、JSP翻译为Servlet时的编码: (此项可以由1.1,1.2,1.3.1代替)
<%@ page language=”java” pageEncoding=”utf-8″%>
1.3.3、从服务器将jsp内容输出到浏览器
<%@page contentType=”text/html;charset=utf-8″%>
在这次输出过程中,由contentType属性中的charset来指定,将servlet编译后的的二进制码以charset的编码形式来输出。
2. 服务器端编码设置
服务器端编码,将客户端传过来的数据进行解码:
浏览器默认使用ISO-8859-1进行编码数据,然后将数据传输到服务器,因此我们默认只需要将浏览器发送过来的数据转换为我们需要的编码即可。
GET请求方式:
2.1 TOMCAT默认ISO-8859-1 因此可以设置默认编码为UTF-8解决,在conf\server.xml文件中设置如下
<Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ URIEncoding=”UTF-8”/>
2.2
String username = request.getParameter(“username”);
username = new String(username.getBytes(“ISO-8859-1“), “UTF-8”);
POST请求方式:
2.3 // 必须在获取参数之前,调用如下方法先解码
request.setCharacterEncoding(“UTF-8”);
String username = request.getParameter(“username”);
response.setContentType(“text/html;charset=utf-8”);
3.数据库的编码设置
3.1 JDBC连接数据库的编码设置
“jdbc:mysql://localhost:3306/jd1203db?useUnicode=true&characterEncoding=utf8“,”root”,”1234″);
3.2 在建表或者建数据库时可以加上:
create database jsd1203db ENGINE=InnoDB DEFAULT CHARSET=utf8;
3.3查看MySql数据中当前联接系统参数 show variables like ‘char%’,显示各个编码类型。
可以show create database dangdang;通过该语句查看建库的语句,看是否有设置编码。
如果各种编码都是对的,可是在数据库中查看数据时是乱码,可以用set names ‘gbk’,设置查看编码为gbk,与系统一致(windows)。 注意,这个设置只对当前会话有效。
72.get和post请求的中文乱码问题处理?
当表单提交时,浏览器会对表单中的中文参数值进行编码(会使用打开表单所在的页面时的编码格式来进行编码)。服务器在默认情况下,会使用iso-8859-1这种编码格式进行解码。所以会出现乱码。
1)get请求方式的处理:
第一种方式:
要确保表单所在的页面,使用指定的编码格式打开。对于html文件,可以添加:
<meta http-equiv=”content-type” content=”text/html;charset=utf-8″>,确保表单中的编码为utf8,能够存储中文。
在Servlet中使用name = new String(name.getBytes(“iso-8859-1″),”utf-8”);来处理编码
第二种方式:
找到tomcat—->conf—–>server.xml—-><Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ URIEncoding=”UTF-8″/>后面加上URIEncoding=”UTF-8″
2)post请求方式的处理:
2.1 首先确保html的编码为utf-8
2.1在服务器端,取数据之前,添加request.setCharacterEncoding(“utf-8”);
MySQL的乱码解决方案:
5. 如果第一次安装MySQL数据库:
在选择编码时,选择最后一项,并指定编码为utf8或者gbk(这两种编码支持中文,是我们比较常用的)
6. 如果已经按照完成了MySQL数据库,那么可以进行重新配置修改:
在开始菜单中找到:
然后重复第一个步骤即可。(注意:这样修改完成后,那么数据库中原来保存的数据如果有中文,就会乱码,因为当前的编码已经变为了utf8,而原来保存的可能是其它编码。)
7. 重启MySql的服务.右键管理员身份打开命令提示符窗口,
8. 进入MySQL中,如果通过一下命令查看编码如下图所示,那么表示配置正确:
但是这个时候如果向表中插入数据,会报编码错误,如下图:
这个时候,我们就可以使用set names gbk;命令来设定字符集为gbk。就可以正常插入数据了。(注意:这个只是让显示的时候正确,并不会改变表中的数据的编码。此命令只在当前会话中有效,也就是如果新开一个窗口打开MySql,用select查询时会发现还是乱码,这个时候如果要正确显示,那么还得用此语句。)
73.Servlet中的数据插入MySql乱码:(我们都用UTF8这样的编码来存储)
8. 首先在Servlet这个java文件得是utf8编码,在其中打印要插入MySql中的数据,查看是否能够正确显示,如果能够正确显示那么说明Servlet中的数据就是utf8编码。
9. 如果上一步不能通过检查,那么插入数据就会出现问题,直到检查第一步完成为止。
10. 建数据库之前首先保证MySql按照上面的安装正确:
11. 创建数据库: create database wuxi default character set ‘utf8’;
12. 可以使用show create database wuxi;来查看这个数据库的SQL语句.
13. 建表时加上: create table t_pic(id bigint primary key auto_increment,picName varchar(100), userId bigint) ENGINE=InnoDB DEFAULT CHARSET=utf8;
14. JDBC连接数据库时: conn = DriverManager.getConnection(
“jdbc:mysql://localhost:3306/jd1105db?useUnicode=true&characterEncoding=utf8″,”root”,”1234″);
74.MySql和Oracle数据库的区别?
查询当前所有的表 |
SQL> select * from tab;SQL> select * from cat where table_type=’TABLE’;//可能会有view SQL>select * from user_tables; |
mysql> show tables;c:/mysql/bin>mysqlshow 库名 |
显示当前连接用户(库) |
SQL> show user |
mysql> connect |
查看帮助 |
SQL> ? |
mysql> help |
显示表结构 |
SQL> desc 表名SQL> describe 表名 |
mysql> desc 表名;mysql> describe 表名;mysql> show columns from 表名;c:/mysql/bin>mysqlshow 库名 表名 |
日期函数 |
SQL> select sysdate from dual; |
mysql> select now();mysql> select sysdate();mysql> select curdate();mysql> select current_date;mysql> select curtime();mysql> select current_time; |
日期格式化 |
SQL> select to_char(sysdate,’yyyy-mm-dd’) from dual;SQL> select to_char(sysdate,’hh24-mi-ss’) from dual; |
mysql> select date_format(now(),’%Y-%m-%d’);mysql> select time_format(now(),’%H-%i-%S’); |
日期函数(增加一个月) |
SQL> select to_char(add_months(to_date(‘20000101′,’yyyymmdd’),1),’yyyy-mm-dd’) from dual;结果:2000-02-01SQL> select to_char(add_months(to_date(‘20000101′,’yyyymmdd’),5),’yyyy-mm-dd’) from dual;结果:2000-06-01 |
mysql> select date_add(‘2000-01-01’,interval 1 month);结果:2000-02-01mysql> select date_add(‘2000-01-01’,interval 5 month);结果:2000-06-01 |
别名 |
SQL> select 1 a from dual; SQL>select 1 as a from dual; //as可以省略 |
mysql> select 1 as a; |
字符串截取函数 |
SQL> select substr(‘abcdefg’,1,5) from dual;SQL> select substr(‘abcdefg’,1,5) from dual;结果:abcde |
mysql> select substring(‘abcdefg’,2,3);结果:bcdmysql> select mid(‘abcdefg’,2,3);结果:bcdmysql> select substring(‘abcdefg’,2);结果:bcdefgmysql> select substring(‘abcdefg’ from 2);结果:bcdefg另有SUBSTRING_INDEX(str,delim,count)函数返回从字符串str的第count个出现的分隔符delim之后的子串。如果count是正数,返回最后的分隔符到左边(从左边数) 的所有字符。如果count是负数,返回最后的分隔符到右边的所有字符(从右边数)。 |
执行外部脚本命令 |
SQL >@a.sql |
1:mysql> source a.sql2:c:/mysql/bin>mysql <a.sql3:c:/mysql/bin>mysql 库名 <a.sql |
导入、导出工具 |
exp.exeexp73.exeimp.exeimp73.exe |
mysqldump.exemysqlimport.exe |
改表名 |
SQL> rename a to b; |
mysql> alter table a rename b; |
执行命令 |
;<回车>/rrun |
;<回车>goego |
distinct用法 |
SQL> select distinct 列1 from 表1;SQL> select distinct 列1,列2 from 表1; |
mysql> select distinct 列1 from 表1;mysql> select distinct 列1,列2 from 表1; |
注释 |
–/*与*/ |
#–/*与*/ |
当作计算器 |
SQL> select 1+1 from dual; |
mysql> select 1+1; |
限制返回记录条数 |
SQL> select * from 表名 where rownum<5; |
mysql> select * from 表名 limit 5; |
新建用户(库) |
SQL> create user 用户名 identified by 密码; |
mysql> create database 库名; |
删用户(库) |
SQL> drop user 用户名; |
mysql> drop database 库名; |
查询索引 |
SQL> select index_name,table_name from user_indexes; |
mysql> show index from 表名 [FROM 库名]; |
通配符 |
“%”和“_” |
“%”和“_” |
SQL语法 |
SELECT selection_list 选择哪些列FROM table_list 从何处选择行WHERE primary_constraint 行必须满足什么条件GROUP BY grouping_columns 怎样对结果分组HAVING secondary_constraint 行必须满足的第二条件ORDER BY sorting_columns 怎样对结果排序 |
SELECT selection_list 选择哪些列FROM table_list 从何处选择行WHERE primary_constraint 行必须满足什么条件GROUP BY grouping_columns 怎样对结果分组HAVING secondary_constraint 行必须满足的第二条件ORDER BY sorting_columns 怎样对结果排序LIMIT count 结果限定 |
自动增长的数据类型处理 |
create sequence myseq increment by 1 start with 1 maxvalue 99999; |
主键列上加auto_increment |
Struts2详细工作流程?
a.浏览器发出welcome.action请求
b.请求到达Struts的Filter控制器(由于web.xml配置)
c.Struts控制器判断请求类型,如果是/welcome.action或/welcome格式请求,将调用struts.xml配置,寻找对应的Action组件
d.调用Action组件的execute方法处理请求,最后返回一个String视图标识
e.Struts控制器根据视图标识寻找相应的JSP(struts.xml中result配置)
f.调用JSP视图生成响应界面给浏览器显示。
Struts2控制流程?
1)请求到来
2)创建ValueStack(Action放栈顶),进行初始化
3)调用拦截器Interceptor,在拦截器中是可以访问ValueStack的
4)调用Action,执行execute()方法
5)调用Result,Result负责把数据显示给用户
6)最后到页面,通过标记库(Taglib)取出数据
Struts2中常用的集中Result组件?
1)JSP响应
dispatcher :采用请求转发方式调用JSP组件响应。
redirect:采用请求重定向方式调用JSP组件响应。(在重定向后,原request和action都被销毁掉,因此在JSP获取不到值)
2)Action响应
redirectAction:采用重定向方式发出一个*.action请求
chain:采用转发方式发出一个*.action请求
3)流响应
典型功能:验证码和下载。
stream:可以将Action中的一个InputStream类型属性以流方式响应输出。
4)JSON响应
负责对Ajax请求进行数据响应。
json:可以将Action中的一个属性或多个属性以json格式响应输出
(注意:使用前需要引入struts-json-plugin.jar,然后将<package>元素的extends设置成”json-default”)
filter(过滤器)和interceptor(拦截器)的区别?
1、拦截器是基于java的反射机制的,而过滤器是基于函数回调 。
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 。
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求 起作用 。
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能 。
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容 器初始化时被调用一次 。
Hibernate是什么,有什么作用和好处?
Hibernate是一个数据库访问框架,用于实现对数据库的增删改查操作。使用Hibernate框架可以简化数据库访问操作,要程序员将更多的经历放在业务层编写上。
原有JDBC操作数据库存在一些问题,主要有以下几个方面:
a)需要编写大量复杂的SQL语句
b)需要设置大量的SQL参数或者将ResultSet取值封装成实体对象
c)当数据库移值时,需要修改部分SQL语句和操作
使用Hibernate框架可以解决以上问题。
什么是ORM?
ORM(Object Relation Mapping)对象关系映射。意思是将程序中的实体对象和关系数据库表中的一行记录进行映射。这样在程序中使用该工具就可以将一个对象写入数据表,或者将数据表记录自动封装成一个对象返回。(这个也是Hibernate实现的原理)
Hibernate的几个核心接口?
Configuration类:Configuration用于配置并启动Hibernate。
SessionFactory接口:一个SessionFactory对应一个数据源,它是个重量级对象,不可随意生成多个实例。它是线程安全的,同一个实例可以被应用中的多个线程共享。
Session接口:Session接口是Hibernate应用中使用最广泛的接口了,它是持久化管理器,提供添加、更新、删除、加载、查询对象。Session不是线程安全的,所以应避免多个线程共享同一个Session实例。Session是轻量级对象,它的创建和销毁不需要太多资源,这意味着在应用中可以经常创建和销毁Session对象。
Transaction接口:Transaction是Hibernate的数据库事务接口,它对底层的事务接口进行了封装。
Query和Criteria接口:这两个是Hibernate的查询接口,用于向数据库查询对象,以及控制执行查询的过程。
Hibernate中的主键生成方式有哪些?
Hibernate一级缓存?
是session级别的缓存。
a.当查询某个对象时,Hibernate首先去一级缓存中查找,如果存在将缓存中的对象取出返回。如果不存在才去数据库查询。
b.当查询某个对象时,Hibernate会自动将数据库查询出的对象放入一级缓存。(例如session的load和get方法查出的对象)
c.一级缓存默认启用,一般被称为Session级别的缓存。因此一级缓存随着Session对象创建,随着Session对象释放而销毁。
d.每个Session都有自己一个独立的一级缓存空间,不能访问其他Session的缓存空间。
———————-一级缓存的好处————————-
在使用同一个Session查询同一个对象若干次的时候,只在第一次时查询数据库,后续几次都会从缓存取出。从而减少对数据库的查询次数。
———————–**使用建议(重点)**—————————-
为了将一级缓存的优势更好的发挥出来,建议在处理一个请求时,使用一个Session对象处理。可以使用ThreadLocal技术封装Session.
在Hibernate中,可以<!– 指定将session与处理线程绑定,实现线程单例 –>
<property name=”current_session_context_class”>
thread
</property>
Hibernate的二级缓存?
二级缓存也称为进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享 ,可以被多个不Session对象访问,二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存。
线程单例及其使用?
Hibernate中session的get和load方法区别?
相同点:作用相同,都是按照主键条件查询某个对象。
不同点:
1).get方法不使用延迟加载机制,load采用延迟加载机制
2).如果没有满足条件的记录,get方法返回null,load则抛出异常
3).load方法返回的对象是一个动态代理类(Hibernate框架动态生成的,是实体类的子类型)。
4).get方法返回的对象类型就是原实体类型
注意:a.在程序中,如果使用上述延迟加载操作,需要避免Session对象过早关闭问题。(could not initialize proxy – no Session)
b.为避免上述异常,一般采用OpenSessionInView模式。
c.可以将Session关闭采用Filter或Interceptor(Struts2推荐)封装。
HQL和SQL的区别?
Hibernate Query Language(Hibernate查询语言)
结构化查询语言(Structured Query Language)简称SQL
HQL语句结构与SQL语句相似, SQL语句是面向数据表和字段进行查询,而HQL是面向映射后的对象和属性进行查询。因此HQL被称为面向对象查询语句。
HQL语句与SQL相似点如下:
a.HQL语句支持select,from,where,order by ,group by,having子句
b.HQL语句支持分组函数max,min,avg,sum,count
c.HQL语句支持运算符和表达式
d.HQL语句支持>,>=,<,<=,in,not in,like,between… and…,
<>,!=等查询条件,也支持and,or关键字
e.HQL语句支持inner join,left outer join,full join 等连接
HQL语句与SQL不同点如下:(下面内容为重点)
a.HQL区分大小写(大小写敏感),除关键字之外
b.HQL语句使用的类名和属性名(将SQL表名替换成类名,字段名替换成属性名)
c.HQL不支持select *写法,但支持select count(*)
d.HQL语句不支持表连接的on子句,on关联条件可以通过关联映射自动追加
Hibernate中操作并发处理?(乐观锁和悲观锁)
Hibernate框架可以使用锁的机制来解决操作并发。
a.悲观锁
在数据查询出来时,就给数据加一个锁,锁定。这样其他用户再执行删、改操作时不允许。当占用着事务结束,锁会自动解除。
Hibernate采用的是数据库锁机制实现悲观锁控制。
缺点:将并发用户操作同步开,一个一个处理。当一个用户处理时间比较长时,效率会比较低。
b.乐观锁
允许同时更新提交,但是最快的会成功,慢的失败。
在记录中追加一个字段值,用该字段值当做版本。当最先提交者提交后,会自动将版本字段值提升,这样其他用户提交,会发现版本低于数据库记录目前版本,因此抛出异常提示失败。
特点:允许用户同时处理,但只能有一个成功,其他失败,以异常方式提示。
Spring框架的作用和好处?
Spring框架提供了一个容器,该容器可以管理应用程序的组件,还提供了IoC和AoP机制,实现组件之间解耦,提高程序结构的灵活性,增强系统的可维护和可扩展性。
在SSH整合开发中,利用Spring管理Service、DAO等组件,利用IoC机制实现Action和Service,Service和DAO之间低耦合调用。利用AoP机制实现事务管理、以及共通功能的切入等。
功能是整合,好处是解耦。
IoC(Inverse of Controller,控制反转)?
控制权:A调用B组件,可以说成A组件拥有控制权。控制权可以代指对象的创建、初始化、销毁等操作。
控制反转:是将控制权转移,转移给第三方(Spring容器),当需要改变对象关系时,只需要修改Spring容器注入配置即可。
IoC是一种思想,Spring框架通过DI(依赖注入:setter注入和构造方法注入)技术实现了控制反转。
什么是AOP?
Aspect Oriented Programming 面向方面编程。
面向方面编程侧重点是关注方面组件(共通处理部分),可以将方面组件作用到某一批目标对象的方法上。
面向对象编程侧重点是关注对象,如何构建一个对象类型。
面向方面编程是基于面向对象编程的,主要用于改善程序结构,降低组件耦合度。
在SSH 的组合框架模式中,三者各自的作用?
Struts 是一个很好的MVC框架,主要技术是Servlet和Jsp。Struts的MVC设计模式可以使我们的逻辑变得很清晰,让我们写的程序层次分明。基于Struts开发可以简化开发难度,提高开发效率。
Spring 提供了管理业务对象的一致方法,并鼓励注入对接口编程而不是对类编程的良好习惯,使我们的产品在最大程度上解耦。
Hibernate 是用来持久化数据的,提供了完全面向对象的数据库操作。Hibernate对JDBC进行了非常轻量级的封装,它使得与关系型数据库打交道变得非常轻松。
在Struts+Spring+Hibernate系统中,对象之间的调用流程如下:
Struts——>Spring——>Hibernate
JSP——>Action——>Service——>DAO——>Hibernate
SSH工作流程?
a.启动服务器,加载工程以及web.xml.
(实例化Lisener,Filter等组件,将Spring容器和Struts2控制创建)
b.客户端发送请求,所有请求进入Struts2控制器。控制器根据请求类型不同,分别处理。
(action请求,*.action会进入struts.xml寻找<action>配置.
其他请求,*.jsp会直接调用请求资源,生成响应信息)
c.Struts2控制器根据<action>配置调用一个Action对象处理。
整合方法一:将Action交给Spring容器
(Action对象由struts2-spring-plugin.jar插件提供的 StrutsSpringObjectFactory负责去Spring容器获取)
整合方法二:将Action置于Spring容器之外
(Action对象由struts2-spring-plugin.jar插件提供的 StrutsSpringObjectFactory负责创建,然后到Spring容器中寻找与Action
属性匹配的Bean对象,给Action对象注入。(默认采用名称匹配规则)
d.Struts2控制器执行defaultStack拦截器、Action对象、Result等组件处理.
e.执行Action的execute业务方法时,如果使用Service或DAO采用Spring的IoC机制调用。
f.执行Result生成响应信息,执行后续拦截器处理
g.将响应信息输出。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/17610.html