Java知识总结_第1页
Java知识总结_第2页
Java知识总结_第3页
Java知识总结_第4页
Java知识总结_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、JAVA中堆和栈的区别 堆内存:用于存储局部变量,当数据使用完,所占空间会自动释放* 栈内存o 数组和对象,通过new建立的实例都放在堆内存中o 每一个实体都有内存地址值o 实体中的变量都有默认的初始值o 实体不再被使用,会在不确定的时间被垃圾回收器回收 方法区o 本地方法,寄存器在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作 他用。堆内存用来存放由 new创建的对象和数组。在堆中分配的内存,由 Java虚拟

2、机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。java中变量在内存中的分配1、类变量(static修饰的变量):在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命周期-一直持续到整个系统咲闭2、实例变量:当你使用 java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量(比如说类实例),然后根据零散

3、的堆内存地址,通过哈希算法换算为一长串数 字以表征这个变量在堆中的 物理位置”。实例变量的生命周期-当实例变量的引用丢失后, 将被GC (垃圾回收器)列入可回收名单”中,但并不是马上就释放堆中内存3、局部变量:局部变量,由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放附:java的内存机制Java把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基 本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放

4、掉为该变量分配的内存空间,该内存空间可以立即被另作它用。堆内存用来存放由 new创建的对象和数组, 在堆中分配的内存,由Java虚拟机的自 动垃圾回收器来管理。 在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new产生数组或者对象的语句所在的代

5、码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是Java比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针!优缺点:栈的优势是,存取速度比堆要快, 仅次于直接位于 CPU中的寄存器。但缺点是,存在 栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较

6、慢。java集合类说明与区别1. ArrayList:元素单个,效率高,多用于查询2. Vector:元素单个,线程安全,多用于查询3. LinkedList:元素单个,多用于插入和删除4. HashMap:元素成对,元素可为空5. HashTable:元素成对,线程安全,元素不可为空集合类说明及区别Collectio n卜 ListI 卜 LinkedListI 卜 ArrayListI L VectorI L StackL SetMap卜 Hashtable 卜 HashM apL WeakHashMapCollection 接口Collection 是最基本的集合接口,一个 Collec

7、tion 代表一组 Object ,即 Collection 的元 素( Elements )。一些 Collection 允许相同的元素而另一些不行。一些能排序而另一些不 行o Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口 ”如 List 和 Set。所有实现 Collection 接口的类都必须提供两个标准的构造函数: 无参数的构造函数用于 创建一个空的 Collection ,有一个 Collection 参数的构造函数用于创建一个新的 Collection , 这个新的Collection与传入的Collec

8、tion有相同的元素。后一个构造函数允许用户复制一 个 Collection o如何遍历 Collection 中的每一个元素?不论 Collection 的实际类型如何, 它都支持一个 iterator() 的方法,该方法返回一个迭代子, 使用该迭代子即可逐一访问 Collection 中每一个 元素。典型的用法如下:Iterator it = collection.iterator(); /获得一个迭代子while(it.hasNext() Object obj = it.next(); / 得到下一个元素由 Collection 接口派生的两个接口是 List 和 Set。List 接口

9、List 是有序的 Collection ,使用此接口能够精确的控制每个元素插入的位置。用户能够 使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素,这类似于 Java 的数组。和下面要提到的 Set 不同, List 允许有相同的元素。除了具有 Collection 接口必备的 iterator() 方法外, List 还提供一个 listIterator() 方法, 返回一个 ListIterator 接口,和标准的 Iterator 接口相比, ListIterator 多了一些 add() 之类 的方法,允许添加,删除,设定元素, 还能向前或向后遍历。实现

10、 List 接口的常用类有 LinkedList ,ArrayList ,Vector 和 Stack。LinkedList 类LinkedList 实现了 List 接口,允许 null 元素。此外 LinkedList 提供额外的 get,remove , insert 方法在 LinkedList 的首部或尾部。这些操作使 LinkedList 可被用作堆栈( stack ), 队列( queue )或双向队列( deque )。注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建 List 时构造一个同步的 List:Li

11、st list = Collections.synchronizedList(new LinkedList(.);ArrayList 类ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。size, isEmpty ,get,set方法运行时间为常数。但是 add方法开销为分摊的常数,添加 n 个元素需要0(n)的时间。其他的方法运行时间为线性。每个ArrayList实例都有一个容量(Capacity ),即用于存储元素的数组的大小。这个 容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用 ensur

12、eCapacity方法来增加ArrayList的容量以提高插入效率。和 LinkedList 一样,ArrayList 也是非同步的(unsynchronized )。Vector 类Vector非常类似 ArrayList ,但是Vector是同步的。由Vector创建的Iterator ,虽然和 ArrayList创建的Iterator是同一接口,但是,因为 Vector是同步的,当一个 Iterator被创 建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationExceptio

13、n,因此必须捕获该异常。在考虑并发的情况下用Vector (保证线程的安全)。在不考虑并发的情况下用ArrayList (不能保证线程的安全)Stack 类Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得 Vector 得以被当作堆栈使用。基本的 push和pop方法,还有peek方法得到栈顶的元素,empty 方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。 Stack刚创建后是空栈。2, Set 接口Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像前面有几个 不同的List。实际上Set就是Collecti

14、on ,只是行为不同。(这是继承与多态思想的典型 应用:表现不同的行为)。其次,Set是一种不包含重复的元素的Collection ,加入Set的元素必须定义 equals()方法以确保对象的唯一性(即任意的两个元素 e1和e2都有e1.equals(e2)=false ),与List不同的是,Set接口不保证维护元素的次序。最后,Set最多有一个 null元素。很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。请注意:必须小心操作可变对象(Mutable Object )。如果一个 Set中的可变兀素改变了自身状态导致Object.equals(Obj

15、ect)=true将导致一些问题。HashSet 类为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。LinkedHashSet 类:具有 HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。TreeSet 类保存次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。Map 接口请注意,Map没有继承 Collection 接口,Map提供key到value的映射。一个 Map中 不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map 的内容

16、可以被当作一组 key集合,一组value集合,或者一组 key-value映射。Hashtable 类Hashtable 继承 Map接口,实现一个 key-value 映射的哈希表。任何非空( non-null ) 的对象都可作为 key或者value。添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为 常数。Hashtable 通过initial capacity 和load factor两个参数调整性能。通常缺省的load factor0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大,这

17、会影响像 get和put这样的操作。由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现 hashCode和equals方法。hashCode和equals方法继承自根 类Object,如果你用自定义的类当作 key的话,要相当小心,按照散列函数的定义,如果 两个对象相 同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的 hashCode不一定不同,如果两个不同对象的 hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode

18、()方法,能加快哈希 表的操作。如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode 方法,而不要只写其中一个。Hashtable是同步的。HashMap 类HashMap和Hashtable 类似,不同之处在于 HashMap 是非同步的,并且允许null,即 null value 和 null key。,但是将 HashMap 视为 Collection 时(values()方法可返回 Collection ),其迭代子操作时间开销和HashMap的容量成比例

19、。因此,如果迭代操作的性能相当重要的话,不要将 HashMap的初始化容量设得过高,或者load factor过低。WeakHashM ap类WeakHashMap 是一种改进的 HashMap,它对key实行 弱引用”,如果一个key不再 被外部所引用,那么该key可以被GC回收。总结如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList 。如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。要特别注意对哈希表

20、的操作,作为key的对象要正确复写 equals和hashCode方法。尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。同步性Vector 是同步的。 这个类中的一些方法保证了 Vector 中的对象是线程安全的。 而 ArrayList 则是异步的,因此 ArrayList 中的对象并 不是线程安全的。因为同步的要求会影响执行的 效率,所以如果你不需要线程安全的集合那么使用 ArrayList 是一个很好的选择,这样可以 避免由于同步带 来的不必要的性能开销。数据增长从内

21、部实现机制来讲 ArrayList 和 Vector 都是使用数组 (Array) 来控制集合中的对象。当你 向这两种类型中增加元素的时候,如果元素的数目 超出了内部数组目前的长度它们都需要 扩展内部数组的长度, Vector 缺省情况下自动增长原来一倍的数组长度, ArrayList 是原来 的 50%, 所以最 后你获得的这个集合所占的空间总是比你实际需要的要大。 所以如果你要在 集合中保存大量的数据那么使用 Vector 有一些优势, 因为你可以通过设置集合的初 始化大 小来避免不必要的资源开销。使用模式在 ArrayList 和 Vector 中,从一个指定的位置(通过索引)查找数据或

22、是在集合的末尾增 加、移除一个元素所花费的时间是一样的,这个时间我们用 O(1) 表示。但是,如果在集合 的其他位置增加或移除元素那么花费的时间会呈线形增长:O(n-i) ,其中 n 代表集合中元素的个数, i 代表元素增加或移除 元素的索引位置。 为什么会这样呢?以为在进行上述操作的 时候集合中第 i 和第 i 个元素之后的所有元素都要执行位移的操作。这一切意味着什么呢? 这意味着, 你只是查找特定位置的元素或只在集合的末端增加、 移除元素, 那么使用 Vector 或 ArrayList 都可以。如果是其他操作,你最好选择其他 的集合操作类。比如, LinkList 集合类在增加或移除集合

23、中任何位置的元素所花费的时间都是一样的?O(1) ,但它在索引一个元素的使用缺比较慢-0(i),其中i是索引的位置使用ArrayList也很容易,因为你可以简单的使用索引来代替创建 iterator 对象的操作。 LinkList 也 会为每个插入的元素创建对 象,所有你要明白它也会带来额外的开销。最后,建议使用一个简单的数组( Array )来代替 Vector 或 ArrayList 。尤其是对于执行效 率要求高的程序更应如此。因为使用数组 (Array) 避免了同步、额外的方法调用和不必要的 重新分配空间的操作。相互区别Vector 和 ArrayList1, vector 是线程同步的

24、,所以它也是线程安全的,而 ArrayList 是线程异步的,是不安全 的。如果不考虑到线程的安全因素,一般用ArrayList 效率比较高。2,如果集合中的元素的数目大于目前集合数组的长度时,vector 增长率为目前数组长度的100%, 而 ArrayList 增长率为目前数组长度的 50%. 如过在集合中使用数据量比较大的数据, 用 vector 有一定的优势。3,如果查找一个指定位置的数据, vector 和 ArrayList 使用的时间是相同的,都是 0(1), 这个时候使用 vector 和 arraylist 都可以。而如果移动一个指定位置的数据花费的时间为 0(n-i)n 为

25、总长度, 这个时候就应该考虑到使用 linklist, 因为它移动一个指定位置的数据所花费的时间为 0(1), 而查询一个指定位置的数据时 花费的时间为 0(i) 。ArrayList 和 Vector 是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增 加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动 等内存操 作,所以索引数据快插入数据慢, Vector 由于使用了 synchronized 方法(线程安全)所以 性能上比 ArrayList 要 差, LinkedList 使用双向链表实现存储,按序号索引数据需要进行 向前或向后遍历,但是插入数据时只需要记

26、录本项的前后项即可,所以插入数度较快! arraylist 和 linkedlist1. ArrayList 是实现了基于动态数组的数据结构, LinkedList 基于链表的数据结构。2. 对于随机访问 get 和 set,ArrayList 觉得优于 LinkedList ,因为 LinkedList 要移动指针。3. 对于新增和删除操作 add 和 remove , LinkedList 比较占优势,因为 ArrayList 要移动数 据。这一点要看实际情况的。若只对单条数据插入或删除, ArrayList 的速度反而优于 LinkedList 。但若是批量随机的插入删除数 据, Lin

27、kedList 的速度大大优于 ArrayList. 因 为 ArrayList 每插入一条数据,要移动插入点及之后的所有数据。HashMap 与 TreeMap1、HashMap 通过 hashcode 对其内容进行快速查找,而 TreeMap 中所有的元素都保 持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用 TreeMap ( HashMap 中元素的排列顺序是不固定的)。HashMap 中元素的排列顺序是不固定的)。TreeMap 中所有的元素都2、HashMap 通过 hashcode 对其内容进行快速查找,而 保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该

28、使用 TreeMap(HashMap 中元素的排列顺序是不固定的)。集合框架 ”提供两种常规的 Map 实现: HashMap 和 TreeMap (TreeMap 实现 SortedMap 接口 ) 。3 、在 Map 中插入、删除和定位元素, HashMap 是最好的选择。但如果您要按自然 顺序或自定义顺序遍历键,那么 TreeMap 会更好。使用 HashMap 要求添加的键类明确定 义了 hashCode() 和 equals() 的实现。 这个 TreeMap 没有调优选项, 因为该树总处于平 衡状态。结过研究,在原作者的基础上我还发现了一点,二树 map 一样,但顺序不一样,导致

29、hashCode() 不一样。同样做测试:在 hashMap 中,同样的值的 map, 顺序不同, equals 时, false;而在treeMap中,同样的值的 map,顺序不同equals时,true,说明,treeMap在equals。 时是整理了顺序了的。hashtable 与 hashmapHashMap 是 Java 1.2 引进的 Map一. 历史原因 :Hashtable 是基于 陈旧的 Dictionary 类的, 接口的一个实现 二同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的, 不是同步的 三.值:只有 HashMap 可以让

30、你将空值作为一个表的条目的 key 或 value数据库的优化(数据库内部优化和sql优化)1数据库内部优化调整服务器内存分配;数据库管理员可以根据数据库运行状况调整数据库系统全局区(SGA区)的数据缓冲区、日志缓冲区和共享池的大小;还可以调整程序全局区(PGA区)的大小2. sql优化尽量使用索引不要使用like (迷糊查询)要尽量避免在 where子句中对字段进行 NULL值判断;不要使用* (全局查询)3硬件优化CPU参数的调整;硬件的好坏也起到关键作用Java线程:概念与原理一、操作系统中线程和进程的概念现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。进程是指一个内存中运

31、行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在 Windows系统中,一个运行的 exe就是一个进程。线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。SQL语句优化1、应尽量避免在 where子句中使用!=或 操作符,否则将引擎放弃使用索引而进行全表扫描。where 及 order by 涉及2、对查询进行优化,应尽量避免全表扫描,首先应考虑在的列上建立索引。3、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用 索

32、引而进行全表扫描,如:select id from t where num is null可以在 num 上设置默认值 0 ,确保表中 num 列没有 null 值,然后这样查询:select id from t where num=04、尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而 进行全表扫描,如:select id from t where num=10 or num=20可以这样查询:select id from t where num=10union allselect id from t where num=205、下面的查询也将导致全表扫描:

33、 (不能前置百分号 )select id from t where name like%c%若要提高效率,可以考虑全文检索。6、in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)对于连续的数值,能用 between 就不要用 in 了:select id from t where num between 1 and 37、如果在 where 子句中使用参数,也会导致全表扫描。因为 SQL 只有在运行时才会 解析局部变量, 但优化程序不能将访问计划的选择推迟到运行时; 它必须在编译时进行选择。 然 而,如果在编译时建

34、立访问计划,变量的值还是未知的,因而无法作为索引选择的输入 项。如下面语句将进行全表扫描。select id from t where num=num可以改为强制查询使用索引:select id from t with(index( 索引名 ) where num=num8、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引 而进行全表扫描。如:select id from t where num/2=100应改为 :select id from t where num=100*29、应尽量避免在 where 子句中对字段进行函数操作, 这将导致引擎放弃使用索引而进

35、 行全表扫描。如:select id from t where substring(name,1,3)=name 以bab开头的 idselect id from t where datediff(day,createdate,-11- 30 )=0 -200520030 生成的id应改为 :select id from t where name like abc% select id from t where createdate=-11-30 20fiWd createdate-1- 200510 、不要在 where 子句中的 “ =左”边进行函数、算术运算或其他表达式运算,否则系统将可

36、能无法正确使用索引。11、在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使 用,并且应尽 可能的让字段顺序与索引顺序相一致。12、不要写一些没有意义的查询,如需要生成一个空表结构:select col1,col2 into #t from t where 1=0这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:create table #t()13 、很多时候用 exists 代替 in 是一个好的选择:select num from a where num in(select num from

37、 b)用下面的语句替换:select num from a where exists(select 1 from b where num=a.num)14 、并不是所有索引对查询都有效, SQL 是根据表中数据来进行查询优化的,当索引 列有大量数据重复时, SQL 查询可能不会去利用索引, 如一表中有字段 sex,male、female 几乎各一半,那么即使在 sex 上建了索引也对查询效率起不了作用。15、索引并不是越多越好,索引固然可以提高相应的 select 的效率, 但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎

38、样建索引 需要慎重考虑, 视具体情况而定。 一个表的索引数最好不要超过 6 个,若太多则应考虑一些 不常使用到的列上建的索引是否有必要。16. 应尽可能的避免更新clustered 索引数据列, 因为 clustered 索引数据列的顺序就是表记录的物理存储顺序, 一旦该列值改变将导致整个表记录的顺序的调整, 会耗费相当大 的资源。 若应用系统需要频繁更新 clustered 索引数据列, 那么需要考虑是否应将该索引建 为 clustered 索引。17、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会

39、逐个比较字 符串中每一个字符,而对于数字型而言只需要比较一次就够了。18 、尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间 小,可以节省存储空间, 其次对于查询来说, 在一个相对较小的字段内搜索效率显然要高些。19、任何地方都不要使用 select * from t ,用具体的字段列表代替 “ *,”不要返回用 不到的任何字段。20、尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限 (只有主键索引)。21、避免频繁创建和删除临时表,以减少系统表资源的消耗。22、临时表并不是不可使用,适当地使用它们可以使某些例程更有效

40、,例如,当需要 重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使 用导出表。23、在新建临时表时,如果一次性插入数据量很大,那么可以使用select into 代替create table ,避免造成大量 log ,以提高速度; 如果数据量不大, 为了缓和系统表的资源, 应先 create table ,然后 insert 。24、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。25 、尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1 万行,那么

41、就应该考虑改写。26、使用基于游标的方法或临时表方法之前, 应先寻找基于集的解决方案来解决问题, 基于集的方法通常更有效。27 、与临时表一样,游标并不是不可使用。对小型数据集使用FAST_FORWARD 游标通常要优于其他逐行处理方法, 尤其是在必须引用几个表才能获得所需的数据时。 在结果集 中包括 “合计 ”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。28、在所有的存储过程和触发器的开始处设置SET NOCOUNT ON,在结束时设置SET NOCOUNT OFF。无需在执行存储过程和触发器的每个语句后向客户端发

42、送DONE_IN_PROC 消息。29、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。30、尽量避免大事务操作,提高系统并发能力。数据库的存储过程存储过程就是将常用的或很复杂的工作,预先用SQL语句写好并用一个指定的名称存储起来,并且这样的语句是放在数据库中的,还可以根据条件执行不同 SQL语句,那么以后要叫数据库提供与已定义好的存储过程的功能相同的服务时,只需调用execute,即可自动完成命令。存储过程的优点1.存储过程只在创造时进行编译即可,以后每次执行存储过程都不需再重新编译,而我们通常使用的SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。

43、2.经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作。当对数据库进行复杂操作时(如对多个表进行Updatensert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。可以极大的提高数据库的使用效率,减少程序的执行时间,这一点在较大数据量的数据库的操作中是非常重要的。在代码上看,SQL语句和程序代码语句的分离,可以提高程序代码的可读性。3.存储过程可以设置参数,可以根据传入参数的不同重复使用同一个存储过程,从而高效的提高代码的优化率和可读性。4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权存储过程的种类:(

44、1)系统存储过程:以sp_开头,用来进行系统的各项设定.取得信息相关管理工作,如sp_help就是取得指定对象的相 关信息。(2)扩展存储过程 以XP_开头用来调用操作系统提供的功能execmaster.xp_cmdshell pi ng 10.8.16.1(3 )用户自定义的存储过程,这是我们所指的存储过程常用格式 模版: Create procedure procedue_name parameter data_typeoutputwithrecompile|encryption as sql_statement解释: output :表示此参数是可传回的with recompiled n

45、cryptio n recompile:表示每次执行此存储过程时都重新编译一次;en crypti on:所创建的存储过程的内容会被加密springmvc 和 struts2 的区另U1、springmvc基于方法开发的,struts2基于类开发的。springmvc将url和controller方法映射。映射成功后 springmvc生成一个 Handler对象,对象中只包括了一个 method。方法执行结束,形参数据销毁。struts2的action类中的所有方法用的都是action类中的成员变量,一旦方法变得很多的时候,我们就会不知道 action类中那么多成员变量是给那个方法去使用的。

46、十分混乱。但是springmvc的所有参数都是定义为方法的形参,这样使用什么方法就将参数注入至对应方法的形参,所以 springmvc的controller开发类似service开发。2、 springmvc可以进行单例开发,并且建议使用 单例开发,struts2通过类的成员变量接收参 数,无法使用单例,只能使用多例。3、 经过实际测试,struts2速度慢,在于 使用struts标签,如果使用struts建议使用jstl。最后我们无法实际定义springmvc与struts到底谁好谁坏,只能说struts早期由于用的比较多,它的漏洞就比较多。建议如果使用struts,就使用最新的包,因为以前

47、的可能会有漏洞。但springmv目前几乎没有漏洞, 这就是springmvc最近几年开始流行起来的原因,再有一个spri ngmvc 是基于 :方法开发的,更接近于service开发。springmvc 总结springmvc 框架:DispatcherServlet 前端控制器:接收 request,进行 responseHandlerMapping处理器映射器:根据url查找Handler。(可以通过xml配置方式,注解方式)HandlerAdapter处理器适配器:根据特定规则去执行Handler,编写Handler时需要按照HandlerAdapter的要求去编写。Handler处理

48、器(后端控制器):需要程序员去编写,常用注解开发方式。Handler处理器执行后结果 是ModelAndView,具体开发时 Handler返回方法值类型包括 : ModelAndView、String (逻辑视图名)、void (通过在 Handler 形参中添加 request 和 response, 类似原始servlet开发方式,注意:可以通过指定response响应的结果类型实现 json数据输 出)View resolver视图解析器:根据逻辑视图名生成真正的视图(在springmvc中使用View对象表示)View视图:jsp页面,仅是数据展示,没有业务逻辑。servlet 生命

49、周期(1)加载和实例化Servlet容器负责加载和实例化Servlet。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Servlet实例。当Servlet容器启动后,它必须要知道所需的Servlet类在什么位置,Servlet容器可以从本地文件系统、远程文件系统或者其 他的网络服务中通过类加载器加载 Servlet类,成功加载后,容器创建Servlet的实例。因为容器是通过Java的反射API来创建Servlet实例,调用的是Servlet的默认构造方法(即 不带参数的构造方法),所以我们在编写Servlet类的时候,不应该提供带参数的构造方法。(2

50、)初始化在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,如建立数据库的连接,获取配置信息等。对于每一个Servlet实例,init()方法只被调用一次。在初始化期间,Servlet实例可以使用容器为它准备的ServletConfig 对象从 Web应用程序的配置信息(在web.xml中配置)中获取初始化的参数信息。在初始化期间,如果发生错误,Servlet实例可以抛出ServletException 异常或者 UnavailableException 异常来通知容器。ServletException 异常 用于指明一般的初始化失败,例如没有找到初始化参数;而Un availableException异常用于通知容器该Servlet实例不可用。例如,数据库服务器 没有启动,数据库连接无法建立,Servlet就可以抛出UnavailableException异常向容器指出它暂时或永久不可用。(3 )请求处理Servlet容器调用Servlet的service()方法对请求进行处理。要注意的是,在service()方法调用之前,init()方法必须成功执行。在service()方法中,Servlet实例通过S

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论