面試寶典2018

Java基礎部分javascript

1、一個".java"源文件中是否能夠包括多個類(不是內部html

)?有什麼限制?前端

答:能夠有多個類,但只能有一個 public 的類,而且 public 的類名必須與文件名相一致。java

2Java 有沒有 goto?mysql

答:java 中的保留字,如今沒有在 java 中使用。jquery

3、說說&&&的區別。程序員

答:a.&&&均可以用做邏輯與的運算符,表示邏輯與(and),當運算符兩邊的表達式的結果都爲 true , 整個運算結果才爲 true,不然,只要有一方爲 false,則結果爲 falseweb

b.&&還具備短路的功能,即若是第一個表達式爲 false,則再也不計算第二個表達式面試

c.&還能夠用做位運算符,&操做符兩邊的表達式不是 boolean 類型時ajax

 

4、在 JAVA 中如何跳出當前的多重嵌套循環?

使用帶有標號的 break 語句

 

5switch 語句可否做用在 byte ,可否做用在 long ,能 否做用在 String ?

答:a.byte能夠,自動轉換。

   b.long不能夠

   c.jdk1.7以後String是能夠的

   解析:switch後必須:整數表達式或者枚舉常量,byte,short,char 均可以隱含轉換爲 int

6short 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 編譯器會對它進行特殊處理,所以 能夠正確編譯。

7char 型變量中能不能存貯一箇中文漢字?爲何?

答、char 型變量是用來存儲 Unicode 編碼的字符的,unicode 編碼字符集中包含了漢字,因此,char 型變量 中固然能夠存儲漢字。必須是它收錄的。

8、用最有效率的方法算出 2 乘以 8 等於幾?

答:

2 << 3(左移3位至關於乘以23次方,右移3位至關於除以23次方)。

9、使用 final 關鍵字修飾一個變量時,是引用不能變,仍是引用的對象不能變?

答:使用 final 關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容仍是能夠改變的。

10"=="equals 方法究竟有什麼區別?

答:==用來比較內存地址的值

   equals用來比較兩個獨立對象的內容是否相同

11、靜態變量和實例變量的區別?

答:

a.靜態變量前要加 static 關鍵字,而實例變量前則不加。

b.靜態變量能夠直接用類名.也能夠用對象.

c.實例變量只能用對象.

d.類的靜態變量內存中只有一份

12、是否能夠從一個 static 方法內部發出對非 static 方法的 調用?

答:不能夠。

13Integer int 的區別

答:int是原始數據類型,Integer是它的包裝類。

   包裝類有屬性和方法,還能夠判斷是否爲空。

14Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

答:round是四捨五入取整。12   11

15、下面的代碼有什麼不妥之處?

1. if(username.equals(zxx){}

2. int x=1;

   return x==1?true:false;

答:第一題:有可能出現空指針異常

   第二題:永遠都是true

16、請說出做用域 public,private,protected,以及不寫時的區別

答:a.它們是訪問修飾符

   b.public能夠跨包訪問

     protected能夠跨包訪問必須是其子類

 不寫  同包訪問

 private 同類訪問

 

17Overload Override 的區別。Overloaded 的方法是否 能夠改變返回值的類型?

答:

a.Overload方法重載,Override方法重寫

b.方法重載指的是同名不一樣參,方法名相同,參數不一樣(參數個數,參數類型,參數順序).不必定有繼承關係。

c.方法重寫指的是同名又同參,返回類型也要相同。必須存在繼承中。

d.方法重載時,返回類型能夠不一樣。

 

18、構造器 Constructor 是否可被 override?

答:構造方法不能夠被重寫,由於構造方法不能被繼承,但能夠被重載。

 

19、接口是否可繼承接口? 抽象類是否可實現(implements) 接口? 抽象類是否可繼承具體類(concrete class)? 抽象類中 是否能夠有靜態的main方法?

答: 接口能夠繼承接口,抽象類能夠實現接口,抽象類中能夠有靜態的main方法。

20、寫 clone()方法時,一般都有一行代碼,是什麼?

答:

super.clone();

由於首先要把父類中的成員複製到位,而後纔是複製本身的成員。

 

21、面向對象的特徵有哪些方面

答: 面向對象的編程語言有封裝、繼承 、多態、抽象等 4 個主要的特徵。

 

22java 中實現多態的機制是什麼?

答: 父類的引用指向子類的對象。程序調用方法在運行期才動態綁定。

23abstract class interface 有什麼區別?

答:

a.含有 abstract 修飾符的 class 即爲抽象類,abstract 類不能建立的實例對象。

b.抽象類能夠有構造方法,接口中不能有構造方法。

c.抽象類中能夠有普通成員變量,接口中只有靜態常量。

d.抽象類中能夠包含非抽象的方法,接口中的方法只能是抽象的。

e.接口中的抽象方法只能是 public 類型的

f.接口中不能有靜態方法

g.一個類能夠實現多個接口,但只能繼承一個抽象類。接口能夠繼承多個接口。

 

24abstract method 是否可同時是 static,是否可同時是 native,是否可同時是 synchronized?

答:

a.abstract method 不可同時是 static

b.abstract method 不可同時是 native

c.abstract method 不可同時是 synchronized

 

 

25、什麼是內部類?Static Nested Class Inner Class 的不 同。

答:Static Nested Class是靜態嵌套類,Inner Class是內部類。

a.內部類就是在一個類的內部定義的類,內部類中不能定義靜態成員

b.在方法外部定義的內部類前面能夠加上 static 關鍵字,從而成爲 Static Nested Class,它脫離了類的實例,內部類必須先建立實例。

 

26、內部類能夠引用它的包含類的成員嗎?有沒有什麼限制?

答:

a.若是不是靜態內部類,那沒有什麼限制

b.靜態內部類不能訪問外部類的成員

 

27Anonymous Inner Class (匿名內部類) 是否能夠 extends(繼承)其它類,是否能夠 implements(實 現)interface(接口)?

 

答:匿名內部類能夠繼承其餘類或實現其餘接口。

28super.getClass()方法調用

下面程序的輸出結果是多少?

import java.util.Date;

public class Test extends Date{

public static void main(String[] args) { new Test().test();

}

public void test(){ System.out.println(super.getClass().getName());

} }

答案是Test,由於getClass()Object 類中定義成了 final,

子類不能覆蓋該方法.

補充:getClass().getSuperClass().getName();獲得父類名

29String 是最基本的數據類型嗎?

答:

它不是基本數據類型,它是引用數據類型。

java.lang.String 類是 final 類型的,所以不能夠繼承這個類、不能修改這個類。

30String s = "Hello";s = s + " world!";這兩行代碼執行後,

原始的 String 對象中的內容到底變了沒有?

答:沒有。

31、是否能夠繼承 String ?

答:String 類是 final 類故不能夠繼承。

 

32String s = new String("xyz");建立了幾個 String Object? 兩者之間有什麼區別?

答:兩個或一個,xyz」對應一個對象,這個對象放在字符串常量緩衝區,常量」xyz」無論出現 多少遍,都是緩衝區中的那一個。new String 每寫一遍,就建立一個新的對象,它一句那個常 量」xyz」對象的內容來建立出一個新 String 對象。若是之前就用過’xyz,這句表明就不會創 建」xyz」本身了,直接從緩衝區拿。

 

  1、棧區(stack)—   由編譯器自動分配釋放   ,存放函數的參數值,局部變量的值等。其  

  操做方式相似於數據結構中的棧。  

  2、堆區(heap)   —   通常由程序員分配釋放,   若程序員不釋放,程序結束時可能由OS回  

     。注意它與數據結構中的堆是兩回事,分配方式卻是相似於鏈表,呵呵。  

  3、全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的  

  全局變量和靜態變量在一塊區域,   未初始化的全局變量和未初始化的靜態變量在相鄰的另  

  一塊區域。   -   程序結束後由系統釋放。  

  4、文字常量區   —常量字符串就是放在這裏的。   程序結束後由系統釋放  

  5、程序代碼區—存放函數體的二進制代碼。  

 

 

33String StringBuffer 的區別

答:

a.它們能夠儲存和操做字符串

b.String 類提供了數值不可改變的字符串。而這個 StringBuffer 類提供 的字符串進行修改。

c.String 覆蓋了 equals 方法和 hashCode 方法,StringBuffer 沒有覆蓋 equals 方法和 hashCode 方法,因此,StringBuffer 對象存儲進 Java 集合類中時會出現問題。

 

34、如何把一段逗號分割的字符串轉換成一個數組?

答:有兩種

a. 字符串.split(,);

b. StingTokenizer

StringTokenizer tokener = new StringTokenizer("a,b,c", ",");

String[] result = new String[tokener.countTokens()];

int i = 0;

while (tokener.hasMoreElements()) {

result[i++] = tokener.nextToken();

}

 

35、數組有沒有 length()這個方法? String 有沒有 length()這 個方法?

答:數組沒有 length()這個方法,length 的屬性。String 有有 length()這個方法。

 

36、下面這條語句一共建立了多少個對象:String s="a"+"b"+"c"+"d";

答:只建立了一個 String 對象

37try {}裏有一個return語句,那麼緊跟在這個try後的 finally {}裏的code會不會被執行,何時被執行,return 前仍是後?

 

答:會執行,在方法返回調用者前執行。return前。

38final, finally, finalize 的區別。

答:

a.final修飾類,此類不能被繼承,final修飾方法,此方法不能被重寫,final修飾變量變常量。

b.finally 是異常處理語句結構的一部分,表示老是執行,做用是釋放資源。

c.finalize Object 類的一個方法.在垃圾收集器執行的時候會調用被回收對象的此方法.

39、運行時異常與通常異常有何異同?

答:

a.異常表示程序運行過程當中可能出現的非正常狀態

b.運行時異常表示虛擬機的一般操做中可能 遇到的異常,是一種常見運行錯誤。

c.java 編譯器要求方法必須聲明拋出可能發生的非運行時 異常,可是並不要求必須聲明拋出未被捕獲的運行時異常。

40error exception 有什麼區別?

答:

a.error 表示恢復不是不可能但很困難的狀況下的一種嚴重問題。通常指jvm出現的問題。

(好比說內存溢出。不可能期望程序能處理這樣的狀況)

b.exception 表示一種設計或實現問題。它表示若是程序運行正常,從不會發生的狀況。

41Java 中的異常處理機制的簡單原理和應用。

答:

Java 全部異常的根類爲 java.lang.Throwable,它有兩個子類errorException

a.虛擬機死機的錯誤,這是Error.

b.程序能夠死掉也能夠不死掉的錯誤,Exception.

c.程序不該該死掉的錯誤;try..catch throws

d.數組腳本越界(ArrayIndexOutOfBoundsException),空指針異常 (NullPointerException)、類轉換異常(ClassCastException),文件讀寫異常IOException,數字轉換異常NumberFormatException;

42、請寫出你最多見到的 5 runtime exception

ArrayIndexOutOfBoundsException 數組下標越界

ClassNotFoundException 類沒有找到

EFOException 文檔末尾異常

NullPointerException空指針異常

IOException文件讀寫異常

43JAVA 語言如何進行異常處理,關鍵字: throws,throw,try,catch,finally 分別表明什麼意義?try 塊 中能夠拋出異常嗎?

答:

a.Java經過面向對象的方法進行異常處理,把各類不一樣的異常進行分類,並提供了良好的接口。

b.Java中,每一個異常都是一個對象,它是Throwable類或其子類的實例。當一個方法出現異常後便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法能夠捕獲到這個異常並能夠對其進行處理。

c.Java的異常處理是經過5個關鍵詞來實現的:trycatchthrowthrowsfinally。通常狀況下是用try來執行一段程序,若是系統會拋出(throw)一個異常對象,能夠經過它的類型來捕獲(catch)它,或經過老是執行代碼塊(finally)來處理;

try用來指定一塊預防全部異常的程序;

catch子句緊跟在try塊後面,用來指定你想要捕獲的異常的類型;

throw語句用來明確地拋出一個異常;

throws用來聲明一個方法可能拋出的各類異常(固然聲明異常時容許無病呻吟);

finally爲確保一段代碼無論發生什麼異常情況都要被執行;

 

try語句能夠嵌套,每當遇到一個try語句,異常的結構就會被放入異常棧中,直到全部的try語句都完成。若是下一級的try語句沒有對某種異常進行處理,異常棧就會執行出棧操做,直到遇到有處理這種異常的try語句或者最終將異常拋給JVM

d.try 塊 中能夠拋出異常.

44java中有幾種方法能夠實現一個線程?用什麼關鍵字修 飾同步方法? stop()suspend()方法爲什麼不推薦使用?

答:

a.Java 5之前實現多線程有兩種實現方法:一種是繼承Thread類;另外一種是實現Runnable接口。兩種方式都要經過重寫run()方法來定義線程的行爲,推薦使用後者,由於Java中的繼承是單繼承,一個類有一個父類,若是繼承了Thread類就沒法再繼承其餘類了,顯然使用Runnable接口更爲靈活。Java 5之後建立線程還有第三種方式:實現Callable接口,該接口中的call方法能夠在線程執行結束時產生一個返回值。

b.synchronized關鍵字修飾同步方法

c.stop()它不安全,suspend()方法容易發生死鎖

45sleep() wait() 有什麼區別?

sleep()方法給其餘線程運行機會時不考慮線程的優先級,所以會給低優先級的線程以運行的機會;yield()方法只會給相同優先級或更高優先級的線程以運行的機會;

② 線程執行sleep()方法後轉入阻塞(blocked)狀態,而執行yield()方法後轉入就緒(ready)狀態;

sleep()方法聲明拋出InterruptedException,而yield()方法沒有聲明任何異常;

sleep()方法比yield()方法(跟操做系統CPU調度相關)具備更好的可移植性。

 

46、同步和異步有何異同,在什麼狀況下分別使用他們?舉 例說明。

答:

a.若是數據將在線程間共享。例如正在寫的數據之後可能被另外一個線程讀到,或者正在讀的數

據可能已經被另外一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取。

b.當應用程序在對象上調用了一個須要花費很長時間來執行的方法,而且不但願讓程序等待方法的返回時,就應該使用異步編程,在不少狀況下采用異步途徑每每更有效率。

47、多線程有幾種實現方法?同步有幾種實現方法?

答:

a.分別是繼承 Thread ,實現 Runnable 接口,實現Callable接口

b.分別是 synchronized,waitnotify

48、啓動一個線程是用 run()仍是 start()?

答:啓動一個線程是調用 start()方法,使線程就緒狀態,之後能夠被調度爲運行狀態。

49、當一個線程進入一個對象的一個 synchronized 方法後, 其它線程是否可進入此對象的其它方法?

答:

a.其餘方法前是否加了 synchronized 關鍵字,若是沒加,則能。

b.若是這個方法內部調用了 wait,則能夠進入其餘 synchronized 方法。

c..若是其餘個方法都加了 synchronized 關鍵字,而且內部沒有調用 wait,則不能。

d.若是其餘方法是 static,它用的同步鎖是當前類的字節碼,與非靜態的方法不能 同步,由於非靜態的方法用的是 this

50、線程的基本概念、線程的基本狀態以及狀態之間的關係

答:

a.一個程序中能夠有多條執行線索同時執行,一個線程就是程序中的一條執行線索,每一個 線程上都關聯有要執行的代碼,便可以有多段程序代碼同時運行,每一個程序至少都有 一個線程,main 方法執行的那個線程。

b.狀態:就緒(ready),運行(run), 阻塞(synchronize),等待(wait) 和 休眠(sleep),掛起(resume),結束(end)wait 必須在 synchronized 內部調用。

c.調用線程的 start 方法後線程進入就緒狀態,線程調度系統將就緒狀態的線程轉爲運行狀態,遇到 synchronized 語句時,由運行狀態轉爲阻塞,synchronized 得到鎖後, 由阻塞轉爲運行,在這種狀況能夠調用 wait 方法轉爲掛起狀態,當線程關聯的代碼執 行完後,線程變爲結束狀態。

 

51、簡述 synchronized java.util.concurrent.locks.Lock 的 異同 ?

答:

a.主要相同點:Lock 能完成 synchronized 所實現的全部功能

b.主要不一樣點:

Lock 有比 synchronized 更精確的線程語義和更好的性能。

synchronized 會自動釋放鎖,

Lock 必定要求程序員手工釋放,而且必須在 finally 從句中釋放。

Lock還有更強大的功能,例如,它的 tryLock 方法能夠非阻塞方式去拿鎖。

 

52、設計 4 個線程,其中兩個線程每次對 j 增長 1,另外兩 個線程對 j 每次減小 1。寫出程序。

(能夠放棄)

public class ThreadTest1

{

private int j;

public static void main(String args[]){ ThreadTest1 tt=new ThreadTest1(); Inc inc=tt.new Inc();

Dec dec=tt.new Dec();

for(int i=0;i<2;i++){

Thread t=new Thread(inc); t.start();

t=new Thread(dec); t.start();

}

}

private synchronized void inc(){

j++; System.out.println(Thread.currentThread().getName()+"-inc:"+j); }

 private synchronized void dec(){ j--;

System.out.println(Thread.currentThread().getName()+"-dec:"+j);

}

class Inc implements Runnable{

public void run(){

for(int i=0;i<100;i++){ inc();

}

} }

class Dec implements Runnable{ public void run(){

for(int i=0;i<100;i++){ dec();

}

} }

}

----------隨手再寫的一個------------- class A

{

JManger j =new JManager();

main() {

new A().call(); }

void call {

for(int i=0;i<2;i++) {

new Thread(

new Runnable(){ public void run(){while(true){j.accumulate()}}}

).start();

new Thread(new Runnable(){ public void run(){while(true){j.sub()}}}).start(); }

} }

class JManager {

private j = 0;

public synchronized void subtract() {

j-- }

public synchronized void accumulate() {

j++; }

}

53、介紹 Collection 框架的結構

答:

Collection的實現類是AbstractList

List,Set,Vector的父類AbstractList

ListLinkedListArrayList

SetHashSetTreeSet

Vector是線程安全的

54Collection 框架中實現比較要實現什麼接口

答:comparable/comparator

55ArrayList Vector 的區別

答:

a.這兩個類都實現了 List 接口

b.他們都是有序集合,元素可重複

c.Vector 是線程安全的,也就是說是它的方法之間是線程同步的.

ArrayList 是線程序 不安全的,它的方法之間是線程不一樣步的

d.              初始容量   加載因子  擴容增量  擴容後長度

ArrayList   10              0.5           0.5+1    16

Vector        10             1              1                20

 

56HashMap Hashtable 的區別

答:

a.都實現了Map接口

b.HashMap容許空(null),(null),非線程安全,效率要高於 Hashtable

c.Hashtable不容許空(null),(null)值,線程安全,也就是說是同步的。

57List Map 區別?

答:

a. List是存儲單列數據的集合, Map是存儲鍵和值這樣的雙列數據的集合,

b.List 中存儲的數 據是有順序,而且容許重複;

c.Map 中存儲的數據是沒有順序的,其鍵是不能重複的,它的 值是能夠有重複的。

 

58ListMapSet 三個接口,存取元素時,各有什麼特色?

答:

存元素時:

List有序可重複

Set無序不可重複

Map鍵值對存

取元素時:

      Listget

      SetIterator

      Mapkey

59、說出 ArrayList,Vector, LinkedList 的存儲性能和特性

答:

 

a.ArrayList Vector 都是使用數組方式存儲數據

b.Vector 因爲使用了 synchronized 方法(線程安全), 一般性能上較 ArrayList ,

c.LinkedList 使用雙向鏈表實現存儲,增刪改操做優於ArrayList,

查找操做中ArrayList優於LinkedList

詳細說明:

       List以特定索引來存取元素,能夠有重複元素。Set不能存放重複元素(用對象的equals()方法來區分元素是否重複)。Map保存鍵值對(key-value pair)映射,映射關係能夠是一對一或多對一。SetMap容器都有基於哈希存儲和排序樹的兩種實現版本,基於哈希存儲的版本理論存取時間複雜度爲O(1),而基於排序樹版本的實如今插入或刪除元素時會按照元素或元素的鍵(key)構成排序樹從而達到排序和去重的效果。

 

60、去掉一個 Vector 集合中重複的元素

答:

第一種:contains方法

第二種:HashSet set = new HashSet(vector);

61Collection Collections 的區別。

答:

a.Collection是集合類接口,繼承與他的接口主要有 Set List.

b.Collections是集合類的一個幫助類,供一系列靜態方法實現對各類集合的搜索、排 序、線程安全化等操做。

62Set 裏的元素是不能重複的,那麼用什麼方法來區分重 復與否呢? 是用==仍是 equals()? 它們有何區別?

答:

a.equals()能夠

==比較內存地址的值

equals()不一樣對象的內容是否相等

63、你所知道的集合類都有哪些?主要方法?

答:

a.最經常使用的集合類是 List Map

List 的具體實現包括 ArrayList Vector,

它們是 可變大小的列表,比較適合構建、存儲和操做任何類型對象的元素列表。

 List 適用 於按數值索引訪問元素的情形。

Map  供了一個更通用的元素存儲方法。

Map 集合類用於存儲元素對(稱做""" "),其中每一個鍵映射到一個值。

64、兩個對象值相同(x.equals(y) == true),但卻可有不一樣的 hash code,這句話對不對?

答:

也對也不對。

a.若是此對象重寫了equals方法,那麼可能出現這兩個對象的equals相同,而hashcode不一樣。

b.若是對象要保存在 HashSet HashMap ,它們的 equals 相等,那麼,它們的 hashcode 值 就必須相等。

c.若是不是要保存在 HashSet HashMap,則與 hashcode 沒有什麼關係了,這時候 hashcode 不等是能夠的,例如 arrayList 存儲的對象就不用實現 hashcode,固然,咱們沒有理由不實現,一般都會去實現的。

 

65TreeSet 裏面放對象,若是同時放入了父類和子類的實 例對象,那比較時使用的是父類的 compareTo 方法,仍是使 用的子類的 compareTo 方法,仍是拋異常!

答:當前的 add 方法放入的是哪一個對象,就調用哪一個對象 的 compareTo 方法

66、說出一些經常使用的類,,接口,請各舉 5

答:

a.經常使用的類:BufferedReader BufferedWriter FileReader FileWirter String Integer

java.util.Date,System,Class,List,HashMap

b.經常使用的包:java.lang java.io java.util

java.sql ,javax.servlet,org.apache.strtuts.action,org.hibernate

c.經常使用的接口:Remote List Map Document

NodeList ,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)Session(Hibernate),HttpSession

67java 中有幾種類型的流?JDK 爲每種類型的流 供了一 些抽象類以供繼承,請說出他們分別是哪些類?

答:

字節流,字符流。

字節流繼承於 InputStream OutputStream,

字符流繼承於 InputStreamReader OutputStreamWriter

java.io 包中還有許多其餘的流,主要是爲了高性能和使用方便。

 

68、字節流與字符流的區別

答:

a.字節流繼承於InputStreamOutputStream,字符流繼承於ReaderWriter

b.字符流處理的單元爲2個字節的Unicode字符,分別操做字符、字符數組或字符串,

而字節流處理單元爲1個字節,操做字節和字節數組。

c.字節流可用於任何類型的對象,包括二進制對象,而字符流只能處理字符或者字符串

d.字節流提供了處理任何類型的IO操做的功能,但它不能直接處理Unicode字符,而字符流就能夠

 

69、什麼是 java 序列化,如何實現 java 序列化?或者請解 釋 Serializable 接口的做用。

答:

a.java 序列化:將對象轉換成二進制,目的是網絡上進行傳輸。

b.實現Serializable 接口

c.該接口是一個 mini 接口,其中沒有須要實現的方法,

implements Serializable 只是爲了標註該對象是可被序列化的。

另外一種:

序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。序列化是爲了解決對象流讀寫操做時可能引起的問題(若是不進行序列化可能會存在數據亂序的問題)。

要實現序列化,須要讓一個類實現Serializable接口,該接口是一個標識性接口,標註該類對象是可被序列化的,而後使用一個輸出流來構造一個對象輸出流並經過writeObject(Object)方法就能夠將實現對象寫出(即保存其狀態);若是須要反序列化則能夠用一個輸入流創建對象輸入流,而後經過readObject方法從流中讀取對象。序列化除了可以實現對象的持久化以外,還可以用於對象的深度克隆。

 

問:如何實現對象克隆?

答:有兩種方式:

  1). 實現Cloneable接口並重寫Object類中的clone()方法;

  2). 實現Serializable接口,經過對象的序列化和反序列化實現克隆,能夠實現真正的

 

70、 述一下 JVM 加載 class 文件的原理機制?

答:

a.裝載:查找和導入class文件;

b.鏈接:

      (1)檢查:檢查載入的class文件數據的正確性;

      (2)準備:爲類的靜態變量分配存儲空間;

      (3)解析:將符號引用轉換成直接引用(這一步是可選的)

c.初始化:初始化靜態變量,靜態代碼塊。

這樣的過程在程序調用類的靜態成員的時候開始執行,

因此靜態方法main()纔會成爲通常程序的入口方法。類的構造器也會引起該動做。

71heap stack 有什麼區別。

答:

a.java 的內存分爲兩類,一類是棧內存,一類是堆內存。

b.棧內存是指程序進入一個方法時, 會爲這個方法單獨分配一塊私屬存儲空間,用於存儲這個方法內部的局部變量,當這 個方法結束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。

c.堆是與棧做用不一樣的內存,通常用於存放不放在當前方法棧中的那些數據,例如,使用 new 建立的對象都放在堆裏,因此,它不會隨方法的結束而消失。方法中的局部變量 使用 final 修飾後,放在堆中,而不是棧中。

擴展知識:

String str = new String("hello");

上面的語句中變量str放在棧上,用new建立出來的字符串對象放在堆上,而"hello"這個字面量放在靜態區。

 

72GC 是什麼? 爲何要有 GC?

答:

a.GC是垃圾收集的意思(Gabage Collection),

b.內存處理是編程人員容易出現問題的地方, 忘記或者錯誤的內存回收會致使程序或系統的不穩定甚至崩潰,

c.Java  供的 GC 功能 能夠自動監測對象是否超過做用域從而達到自動回收內存的目的,

d.Java 語言沒有 供 釋放已分配內存的顯示操做方法。

 

73、垃圾回收的優勢和原理。並考慮 2 種回收機制。

答:

a.java語言最顯著的特色就是引入了垃圾回收機制,它使java程序員在編寫程序時再也不考慮內存管理的問題。

b.因爲有這個垃圾回收機制,java中的對象再也不有「做用域」的概念,只有引用的對象纔有「做用域」。

c.垃圾回收機制有效的防止了內存泄露,能夠有效的使用可以使用的內存。

d.垃圾回收器一般做爲一個單獨的低級別的線程運行,在不可預知的狀況下對內存堆中已經死亡的或很長時間沒有用過的對象進行清除和回收。

f.程序員不能實時的對某個對象或全部對象調用垃圾回收器進行垃圾回收。

g.垃圾回收機制有分代複製垃圾回收、標記垃圾回收、增量垃圾回收。

 

 

74、垃圾回收器的基本原理是什麼?垃圾回收器能夠立刻回 收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收?

答:

a.對於 GC 來講,當程序員建立對象時,GC 就開始監控這個對象的地址、大小以及使用 狀況。一般,GC 採用有向圖的方式記錄和管理堆(heap)中的全部對象。經過這種方式 肯定哪些對象是"可達的",哪些對象是"不可達的"。當 GC 肯定一些對象爲"不可達" ,GC 就有責任回收這些內存空間。

b.能夠。

c.程序員能夠手動執行 System.gc(),通知 GC 運行,可是 Java 語言規範並不保證 GC 必定會執行。

75、何時用 assert(斷言)

答:

a.assertion(斷言)在軟件開發中是一種經常使用的調試方式,不少開發語言中都支持這種機制。

b.在實現中,assertion 就是在程序中的一條語句,它對一個 boolean 表達式進行檢查,一個正 確程序必須保證這個 boolean 表達式的值爲 true;若是該值爲 false,說明程序已經處於不正確的狀態下,assert 將給出警告或退出。

c.通常來講,assertion 用於保證程序最基本、關鍵的正確性。assertion 檢查一般在開發和測試時開啓。爲了高性能,在軟件發佈後, assertion 檢查一般是關閉的。

76java 中會存在內存泄漏嗎,請簡單述。

答:

a.所謂內存泄露就是指一個再也不被程序使用的對象或變量一直被佔據在內存中。java 中有垃圾 回收機制,它能夠保證一對象再也不被引用的時候,即對象編程了孤兒的時候,對象將自動被 垃圾回收器從內存中清除掉。

b.理論上Java由於有垃圾回收機制(GC)不會存在內存泄露問題(這也是Java被普遍使用於服務器端編程的一個重要緣由)

c.然而在實際開發中,可能會存在無用但可達的對象,這些對象不能被GC回收,所以也會致使內存泄露的發生。

例如hibernateSession(一級緩存)中的對象屬於持久態,垃圾回收器是不會回收這些對象的,然而這些對象中可能存在無用的垃圾對象,若是不及時關閉(close)或清空(flush)一級緩存就可能致使內存泄露。

 

 

77、能不能本身寫個類,也叫 java.lang.String?

答:

a.能夠,但在應用的時候,須要用本身定義全類名加載,不然,系統的類加載器永遠只是去 加載jre.jar包中的那個java.lang.String

 

78、數據類型之間的轉換:

- 如何將字符串轉換爲基本數據類型?

- 如何將基本數據類型轉換爲字符串?

答:

a. 調用基本數據類型對應的包裝類中的方法parseXXX(String)valueOf(String)便可返回相應基本類型;

b. 一種方法是將基本數據類型與空字符串("")鏈接(+)便可得到其所對應的字符串;

    另外一種方法是調用String 類中的valueOf()方法返回相應字符串

79、如何實現字符串的反轉及替換?

 

 public static String reverse(String originStr) {

        if(originStr == null || originStr.length() <= 1)

            return originStr;

        return reverse(originStr.substring(1)) + originStr.charAt(0);

    }

 

80、怎樣將GB2312(簡體中文)編碼的字符串轉換爲ISO-8859-1編碼的字符串?

答:代碼以下所示:

String s1 = "你好";

String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");

 

81、日期和時間:

- 如何取得年月日、小時分鐘秒?

- 如何取得從197011000秒到如今的毫秒數?

- 如何取得某月的最後一天?

- 如何格式化日期?

答:

建立java.util.Calendar 實例,調用其get()方法傳入不一樣的參數便可得到參數所對應的值。

Java 8中能夠使用java.time.LocalDateTimel來獲取

public class DateTimeTest {

    public static void main(String[] args) {

        Calendar cal = Calendar.getInstance();

        System.out.println(cal.get(Calendar.YEAR));

        System.out.println(cal.get(Calendar.MONTH));    // 0 - 11

        System.out.println(cal.get(Calendar.DATE));

        System.out.println(cal.get(Calendar.HOUR_OF_DAY));

        System.out.println(cal.get(Calendar.MINUTE));

        System.out.println(cal.get(Calendar.SECOND));

 

        // Java 8

        LocalDateTime dt = LocalDateTime.now();

        System.out.println(dt.getYear());

        System.out.println(dt.getMonthValue());     // 1 - 12

        System.out.println(dt.getDayOfMonth());

        System.out.println(dt.getHour());

        System.out.println(dt.getMinute());

        System.out.println(dt.getSecond());

    }

}

問題2:如下方法都可得到該毫秒數。

 

Calendar.getInstance().getTimeInMillis();

System.currentTimeMillis();

Clock.systemDefaultZone().millis(); // Java 8

問題3:代碼以下所示。

 

Calendar time = Calendar.getInstance();

time.getActualMaximum(Calendar.DAY_OF_MONTH);

問題4:利用java.text.DataFormat 的子類(如SimpleDateFormat類)中的format(Date)方法可將日期格式化。Java 8中能夠用java.time.format.DateTimeFormatter來格式化時間日期,代碼以下所示。

 

import java.text.SimpleDateFormat;

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import java.util.Date;

 

class DateFormatTest {

 

    public static void main(String[] args) {

        SimpleDateFormat oldFormatter = new SimpleDateFormat("yyyy/MM/dd");

        Date date1 = new Date();

        System.out.println(oldFormatter.format(date1));

 

        // Java 8

        DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        LocalDate date2 = LocalDate.now();

        System.out.println(date2.format(newFormatter));

    }

}

補充:Java的時間日期API一直以來都是被詬病的東西,爲了解決這一問題,Java 8中引入了新的時間日期API,其中包括LocalDateLocalTimeLocalDateTimeClockInstant等類,這些的類的設計都使用了不變模式,所以是線程安全的設計。若是不理解這些內容,能夠參考個人另外一篇文章《關於Java併發編程的總結和思考》。

 

82、打印昨天的當前時刻。

import java.util.Calendar;

 

class YesterdayCurrent {

    public static void main(String[] args){

        Calendar cal = Calendar.getInstance();

        cal.add(Calendar.DATE, -1);

        System.out.println(cal.getTime());

    }

}

Java 8中,能夠用下面的代碼實現相同的功能。

 

import java.time.LocalDateTime;

 

class YesterdayCurrent {

 

    public static void main(String[] args) {

        LocalDateTime today = LocalDateTime.now();

        LocalDateTime yesterday = today.minusDays(1);

 

        System.out.println(yesterday);

    }

}

 

83、比較一下JavaJavaSciprt

答:

a.JavaScript Java是兩個公司開發的不一樣的兩個產品。

b.JavaScript靜態語言,Java是動態語言

 

84、類ExampleA繼承Exception,類ExampleB繼承ExampleA

有以下代碼片段:

 

try {

    throw new ExampleB("b")

} catchExampleA e{

    System.out.println("ExampleA");

} catchException e{

    System.out.println("Exception");

}

請問執行此段代碼的輸出是什麼?

答:輸出:ExampleA。(根據里氏代換原則[能使用父類型的地方必定能使用子類型],抓取ExampleA類型異常的catch塊可以抓住try塊中拋出的ExampleB類型的異常)

 

面試題 - 說出下面代碼的運行結果。(此題的出處是《Java編程思想》一書)

class Annoyance extends Exception {}

class Sneeze extends Annoyance {}

 

class Human {

 

    public static void main(String[] args)

        throws Exception {

        try {

            try {

                throw new Sneeze();

            }

            catch ( Annoyance a ) {

                System.out.println("Caught Annoyance");

                throw a;

            }

        }

        catch ( Sneeze s ) {

            System.out.println("Caught Sneeze");

            return ;

        }

        finally {

            System.out.println("Hello World!");

        }

    }

}

 

85TreeMapTreeSet在排序時如何比較元素?Collections工具類中的sort()方法如何比較元素?

答:TreeSet要求存放的對象所屬的類必須實現Comparable接口,該接口提供了比較元素的compareTo()方法,當插入元素時會回調該方法比較元素的大小。TreeMap要求存放的鍵值對映射的鍵必須實現Comparable接口從而根據鍵對元素進行排序。Collections工具類的sort方法有兩種重載的形式,第一種要求傳入的待排序容器中存放的對象比較實現Comparable接口以實現元素的比較;第二種不強制性的要求容器中的元素必須可比較,可是要求傳入第二個參數,參數是Comparator接口的子類型(須要重寫compare方法實現元素的比較),至關於一個臨時定義的排序規則,其實就是經過接口注入比較元素大小的算法,也是對回調模式的應用(Java中對函數式編程的支持)。

例子1

 

 

public class Student implements Comparable<Student> {

    private String name;        // 姓名

    private int age;            // 年齡

 

    public Student(String name, int age) {

        this.name = name;

        this.age = age;

    }

 

    @Override

    public String toString() {

        return "Student [name=" + name + ", age=" + age + "]";

    }

 

    @Override

    public int compareTo(Student o) {

        return this.age - o.age; // 比較年齡(年齡的升序)

    }

 

}

import java.util.Set;

import java.util.TreeSet;

 

class Test01 {

 

    public static void main(String[] args) {

        Set<Student> set = new TreeSet<>();     // Java 7的鑽石語法(構造器後面的尖括號中不須要寫類型)

        set.add(new Student("Hao LUO", 33));

        set.add(new Student("XJ WANG", 32));

        set.add(new Student("Bruce LEE", 60));

        set.add(new Student("Bob YANG", 22));

 

        for(Student stu : set) {

            System.out.println(stu);

        }

//      輸出結果:

//      Student [name=Bob YANG, age=22]

//      Student [name=XJ WANG, age=32]

//      Student [name=Hao LUO, age=33]

//      Student [name=Bruce LEE, age=60]

    }

}

 

例子2

 

public class Student {

    private String name;    // 姓名

    private int age;        // 年齡

 

    public Student(String name, int age) {

        this.name = name;

        this.age = age;

    }

 

    /**

     * 獲取學生姓名

     */

    public String getName() {

        return name;

    }

 

    /**

     * 獲取學生年齡

     */

    public int getAge() {

        return age;

    }

 

    @Override

    public String toString() {

        return "Student [name=" + name + ", age=" + age + "]";

    }

 

}

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

 

class Test02 {

 

    public static void main(String[] args) {

        List<Student> list = new ArrayList<>();     // Java 7的鑽石語法(構造器後面的尖括號中不須要寫類型)

        list.add(new Student("Hao LUO", 33));

        list.add(new Student("XJ WANG", 32));

        list.add(new Student("Bruce LEE", 60));

        list.add(new Student("Bob YANG", 22));

 

        // 經過sort方法的第二個參數傳入一個Comparator接口對象

        // 至關因而傳入一個比較對象大小的算法到sort方法中

        // 因爲Java中沒有函數指針、仿函數、委託這樣的概念

        // 所以要將一個算法傳入一個方法中惟一的選擇就是經過接口回調

        Collections.sort(list, new Comparator<Student> () {

 

            @Override

            public int compare(Student o1, Student o2) {

                return o1.getName().compareTo(o2.getName());    // 比較學生姓名

            }

        });

 

        for(Student stu : list) {

            System.out.println(stu);

        }

//      輸出結果:

//      Student [name=Bob YANG, age=22]

//      Student [name=Bruce LEE, age=60]

//      Student [name=Hao LUO, age=33]

//      Student [name=XJ WANG, age=32]

    }

}

 

86、什麼是線程池(thread pool)?

答:線程池顧名思義就是事先建立若干個可執行的線程放入一個池(容器)中,須要的時候從池中獲取線程不用自行建立,使用完畢不須要銷燬線程而是放回池中,從而減小建立和銷燬線程對象的開銷。

87XML文檔定義有幾種形式?它們之間有何本質區別?解析XML文檔有哪幾種方式?

答:

a.XML文檔定義分爲DTDSchema兩種形式

b.Schema自己也是一個XML文件,能夠被XML解析器解析,並且能夠爲XML承載的數據定義類型,約束能力較之DTD更強大。

c.dom/dom4j/sax/jdom/pull/StAX

88、你在項目中哪些地方用到了XML

答:

a.數據交互和信息配置,聚合數據大部分接口提供xmljson格式,ssh/ssm框架整合配置。

b.數據交互已經被JSON取代。

 

89、闡述JDBC操做數據庫的步驟。

答:

加載驅動、建立鏈接、建立sql語句、執行sql語句、處理結果、關閉資源(先關近再關遠)

 

90StatementPreparedStatement有什麼區別?哪一個性能更好?

答:與Statement相比,

PreparedStatement接口表明預編譯的語句,它主要的優點在於能夠減小SQL的編譯錯誤並增長SQL的安全性(減小SQL注射攻擊的可能性);

PreparedStatement中的SQL語句是能夠帶參數的,避免了用字符串鏈接拼接SQL語句的麻煩和不安全;

③當批量處理SQL或頻繁執行相同的查詢時,PreparedStatement有明顯的性能上的優點,因爲數據庫能夠將編譯優化後的SQL語句緩存起來,下次執行相同結構的語句時就會很快(不用再次編譯和生成執行計劃)。

91、使用JDBC操做數據庫時,如何提高讀取數據的性能?如何提高更新數據的性能?

答:

a.要提高讀取數據的性能,能夠指定經過結果集(ResultSet)對象的setFetchSize()方法指定每次抓取的記錄數(典型的空間換時間策略);

b.要提高更新數據的性能能夠使用PreparedStatement語句構建批處理,將若干SQL語句置於一個批處理中執行。

 

92、在進行數據庫編程時,鏈接池有什麼做用?

答:

a.因爲建立鏈接和釋放鏈接都有很大的開銷(尤爲是數據庫服務器不在本地時,每次創建鏈接都須要進行TCP的三次握手,釋放鏈接須要進行TCP四次握手,形成的開銷是不可忽視的),

b.爲了提高系統訪問數據庫的性能,能夠事先建立若干鏈接置於鏈接池中,須要時直接從鏈接池獲取,使用結束時歸還鏈接池而沒必要關閉鏈接,從而避免頻繁建立和釋放鏈接所形成的開銷,這是典型的用空間換取時間的策略(浪費了空間存儲鏈接,但節省了建立和釋放鏈接的時間)。

c.池化技術在Java開發中是很常見的,在使用線程時建立線程池的道理與此相同。基於Java的開源數據庫鏈接池主要有:C3P0ProxoolDBCPBoneCPDruid等。

 

93、什麼是DAO模式?

答:

a.DAOData Access Object)顧名思義是一個爲數據庫或其餘持久化機制提供了抽象接口的對象,在不暴露底層持久化方案實現細節的前提下提供了各類數據訪問操做。

b.在實際的開發中,應該將全部對數據源的訪問操做進行抽象化後封裝在一個公共API中。用程序設計語言來講,就是創建一個接口,接口中定義了此應用程序中將會用到的全部事務方法。在這個應用程序中,當須要和數據源進行交互的時候則使用這個接口,而且編寫一個單獨的類來實現這個接口,在邏輯上該類對應一個特定的數據存儲。

c.DAO模式實際上包含了兩個模式,一是Data Accessor(數據訪問器),二是Data Object(數據對象),前者要解決如何訪問數據的問題,然後者要解決的是如何用對象封裝數據。

 

94、事務的ACID是指什麼?

 

答:

- 原子性(Atomic):事務中各項操做,要麼全作要麼全不作,任何一項操做的失敗都會致使整個事務的失敗;

- 一致性(Consistent):事務結束後系統狀態是一致的;

- 隔離性(Isolated):併發執行的事務彼此沒法看到對方的中間狀態;

- 持久性(Durable):事務完成後所作的改動都會被持久化,即便發生災難性的失敗。經過日誌和同步備份能夠在故障發生後重建數據。

 

補充:關於事務,在面試中被問到的機率是很高的,能夠問的問題也是不少的。首先須要知道的是,只有存在併發數據訪問時才須要事務。當多個事務訪問同一數據時,可能會存在5類問題,包括3類數據讀取問題(髒讀、不可重複讀和幻讀)和2類數據更新問題(第1類丟失更新和第2類丟失更新)。

髒讀(Dirty Read):A事務讀取B事務還沒有提交的數據並在此基礎上操做,而B事務執行回滾,那麼A讀取到的數據就是髒數據。

 

時間 轉帳事務A 取款事務B

T1 開始事務

T2 開始事務

T3 查詢帳戶餘額爲1000

T4 取出500元餘額修改成500

T5 查詢帳戶餘額爲500元(髒讀)

T6 撤銷事務餘額恢復爲1000

T7 匯入100元把餘額修改成600

T8 提交事務

不可重複讀(Unrepeatable Read):事務A從新讀取前面讀取過的數據,發現該數據已經被另外一個已提交的事務B修改過了。

 

時間 轉帳事務A 取款事務B

T1 開始事務

T2 開始事務

T3 查詢帳戶餘額爲1000

T4 查詢帳戶餘額爲1000

T5 取出100元修改餘額爲900

T6 提交事務

T7 查詢帳戶餘額爲900元(不可重複讀)

幻讀(Phantom Read):事務A從新執行一個查詢,返回一系列符合查詢條件的行,發現其中插入了被事務B提交的行。

 

時間 統計金額事務A 轉帳事務B

T1 開始事務

T2 開始事務

T3 統計總存款爲10000

T4 新增一個存款帳戶存入100

T5 提交事務

T6 再次統計總存款爲10100元(幻讀)

1類丟失更新:事務A撤銷時,把已經提交的事務B的更新數據覆蓋了。

 

時間 取款事務A 轉帳事務B

T1 開始事務

T2 開始事務

T3 查詢帳戶餘額爲1000

T4 查詢帳戶餘額爲1000

T5 匯入100元修改餘額爲1100

T6 提交事務

T7 取出100元將餘額修改成900

T8 撤銷事務

T9 餘額恢復爲1000元(丟失更新)

2類丟失更新:事務A覆蓋事務B已經提交的數據,形成事務B所作的操做丟失。

 

時間 轉帳事務A 取款事務B

T1 開始事務

T2 開始事務

T3 查詢帳戶餘額爲1000

T4 查詢帳戶餘額爲1000

T5 取出100元將餘額修改成900

T6 提交事務

T7 匯入100元將餘額修改成1100

T8 提交事務

T9 查詢帳戶餘額爲1100元(丟失更新)

數據併發訪問所產生的問題,在有些場景下多是容許的,可是有些場景下可能就是致命的,數據庫一般會經過鎖機制來解決數據併發訪問問題,按鎖定對象不一樣能夠分爲表級鎖和行級鎖;按併發事務鎖定關係能夠分爲共享鎖和獨佔鎖,具體的內容你們能夠自行查閱資料進行了解。

直接使用鎖是很是麻煩的,爲此數據庫爲用戶提供了自動鎖機制,只要用戶指定會話的事務隔離級別,數據庫就會經過分析SQL語句而後爲事務訪問的資源加上合適的鎖,此外,數據庫還會維護這些鎖經過各類手段提升系統的性能,這些對用戶來講都是透明的(就是說你不用理解,事實上我確實也不知道)。ANSI/ISO SQL 92標準定義了4個等級的事務隔離級別,以下表所示:

 

隔離級別   髒讀  不可重複讀   幻讀   第一類丟失更新     第二類丟失更新

READ UNCOMMITED 容許 容許 容許 不容許                  容許

READ COMMITTED 不容許   容許    容許      不容許                   容許

REPEATABLE READ 不容許  不容許    容許     不容許                  不容許

SERIALIZABLE 不容許      不容許      不容許   不容許               不容許

須要說明的是,事務隔離級別和數據訪問的併發性是對立的,事務隔離級別越高併發性就越差。因此要根據具體的應用來肯定合適的事務隔離級別,這個地方沒有萬能的原則。

 

81JDBC中如何進行事務處理?

答:

Connection提供了事務處理的方法,經過調用setAutoCommit(false)能夠設置手動提交事務;

當事務完成後用commit()顯式提交事務;若是在事務處理過程當中發生異常則經過rollback()進行事務回滾。

除此以外,從JDBC 3.0中還引入了Savepoint(保存點)的概念,容許經過代碼設置保存點並讓事務回滾到指定的保存點。

 

82JDBC可否處理BlobClob

答: Blob是指二進制大對象(Binary Large Object),而Clob是指大字符對象(Character Large Objec),所以其中Blob是爲存儲大的二進制數據而設計的,而Clob是爲存儲大的文本數據而設計的。JDBCPreparedStatementResultSet都提供了相應的方法來支持BlobClob操做。

 

83、簡述正則表達式及其用途。

答:在編寫處理字符串的程序時,常常會有查找符合某些複雜規則的字符串的須要。正則表達式就是用於描述這些規則的工具。換句話說,正則表達式就是記錄文本規則的代碼。

 

說明:計算機誕生初期處理的信息幾乎都是數值,可是時過境遷,今天咱們使用計算機處理的信息更多的時候不是數值而是字符串,正則表達式就是在進行字符串匹配和處理的時候最爲強大的工具,絕大多數語言都提供了對正則表達式的支持。

 

84Java中是如何支持正則表達式操做的?

答:Java中的String類提供了支持正則表達式操做的方法,

包括:matches()replaceAll()replaceFirst()split()

 

補充:

面試題: - 若是要從字符串中截取第一個英文左括號以前的字符串,例如:北京市(朝陽區)(西城區)(海淀區),截取結果爲:北京市,那麼正則表達式怎麼寫?

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

class RegExpTest {

 

    public static void main(String[] args) {

        String str = "北京市(朝陽區)(西城區)(海淀區)";

        Pattern p = Pattern.compile(".*?(?=\\()");

        Matcher m = p.matcher(str);

        if(m.find()) {

            System.out.println(m.group());

        }

    }

}

說明:上面的正則表達式中使用了懶惰匹配和前瞻,若是不清楚這些內容,推薦讀一下網上頗有名的《正則表達式30分鐘入門教程》

 

 

 

85、得到一個類的類對象有哪些方式?

答:

a.類型.class,例如:String.class

b.對象.getClass(),例如:"hello".getClass()

c.Class.forName(),例如:Class.forName("java.lang.String")

 

86、如何經過反射建立對象?

答:

- 方法1:經過類對象調用newInstance()方法,例如:String.class.newInstance()

- 方法2:經過類對象的getConstructor()getDeclaredConstructor()方法得到構造器(Constructor)對象並調用其newInstance()方法建立對象,例如:String.class.getConstructor(String.class).newInstance("Hello");

 

87、如何經過反射獲取和設置對象私有字段的值?

答:

能夠經過類對象的getDeclaredField()方法字段(Field)對象,而後再經過字段對象的setAccessible(true)將其設置爲能夠訪問,接下來就能夠經過get/set方法來獲取/設置字段的值了。

88、如何經過反射調用對象的方法?

        String str = "hello";

        Method m = str.getClass().getMethod("toUpperCase");

        System.out.println(m.invoke(str));  // HELLO

 

89、簡述一下面向對象的"六原則一法則"

答:

單一職責原則:一個類只作它該作的事情。

開閉原則:軟件實體應當對擴展開放,對修改關閉

依賴倒轉原則:面向接口編程

里氏替換原則:任什麼時候候均可以用子類型替換掉父類型

接口隔離原則:接口要小而專,毫不能大而全。

合成聚合複用原則:優先使用聚合或合成關係複用代碼。

迪米特法則:迪米特法則又叫最少知識原則,一個對象應當對其餘對象有儘量少的瞭解。

90、簡述一下你瞭解的設計模式。

答:

設計模式,就是一套被反覆使用的代碼設計經驗的總結(情境中一個問題通過證明的一個解決方案)。

- 工廠模式:工廠類能夠根據條件生成不一樣的子類實例,這些子類有一個公共的抽象父類而且實現了相同的方法,可是這些方法針對不一樣的數據進行了不一樣的操做(多態方法)。當獲得子類的實例後,開發人員能夠調用基類中的方法而沒必要考慮到底返回的是哪個子類的實例。

- 代理模式:給一個對象提供一個代理對象,並由代理對象控制原對象的引用。實際開發中,按照使用目的的不一樣,代理能夠分爲:遠程代理、虛擬代理、保護代理、Cache代理、防火牆代理、同步化代理、智能引用代理。

- 適配器模式:把一個類的接口變換成客戶端所期待的另外一種接口,從而使本來因接口不匹配而沒法在一塊兒使用的類可以一塊兒工做。

- 單例模式

 

91、用Java寫一個單例類。

 

答:

- 餓漢式單例

 

public class Singleton {

    private Singleton(){}

    private static Singleton instance = new Singleton();

    public static Singleton getInstance(){

        return instance;

    }

}

懶漢式單例

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {}

    public static synchronized Singleton getInstance(){

        if (instance == null) instance new Singleton();

        return instance;

    }

}

注意:實現一個單例有兩點注意事項,①將構造器私有,不容許外界經過構造器建立對象;②經過公開的靜態方法向外界返回類的惟一實例。

92、什麼是UML

答:UML是統一建模語言(Unified Modeling Language)的縮寫,它發表於1997年,綜合了當時已經存在的面向對象的建模語言、方法和過程,是一個支持模型化和軟件系統開發的圖形化語言,爲軟件開發的全部階段提供模型化和可視化支持。使用UML能夠幫助溝通與交流,輔助應用設計和文檔的生成,還可以闡釋系統的結構和行爲。

93UML中有哪些經常使用的圖?

答:UML定義了多種圖形化的符號來描述軟件系統部分或所有的靜態結構和動態結構,包括:用例圖(use case diagram)、類圖(class diagram)、時序圖(sequence diagram)、協做圖(collaboration diagram)、狀態圖(statechart diagram)、活動圖(activity diagram)、構件圖(component diagram)、部署圖(deployment diagram)等。在這些圖形化符號中,有三種圖最爲重要,分別是:用例圖(用來捕獲需求,描述系統的功能,經過該圖能夠迅速的瞭解系統的功能模塊及其關係)、類圖(描述類以及類與類之間的關係,經過該圖能夠快速瞭解系統)、時序圖(描述執行特定任務時對象之間的交互關係以及執行順序,經過該圖能夠了解對象能接收的消息也就是說對象可以向外界提供的服務)。

94、用Java寫一個冒泡排序。

import java.util.Comparator;

 

/**

 * 排序器接口(策略模式: 將算法封裝到具備共同接口的獨立的類中使得它們能夠相互替換)

 * @author駱昊

 *

 */

public interface Sorter {

 

   /**

    * 排序

    * @param list 待排序的數組

    */

   public <T extends Comparable<T>> void sort(T[] list);

 

   /**

    * 排序

    * @param list 待排序的數組

    * @param comp 比較兩個對象的比較器

    */

   public <T> void sort(T[] list, Comparator<T> comp);

}

import java.util.Comparator;

 

/**

 * 冒泡排序

 *

 * @author駱昊

 *

 */

public class BubbleSorter implements Sorter {

 

    @Override

    public <T extends Comparable<T>> void sort(T[] list) {

        boolean swapped = true;

        for (int i = 1, len = list.length; i < len && swapped; ++i) {

            swapped = false;

            for (int j = 0; j < len - i; ++j) {

                if (list[j].compareTo(list[j + 1]) > 0) {

                    T temp = list[j];

                    list[j] = list[j + 1];

                    list[j + 1] = temp;

                    swapped = true;

                }

            }

        }

    }

 

    @Override

    public <T> void sort(T[] list, Comparator<T> comp) {

        boolean swapped = true;

        for (int i = 1, len = list.length; i < len && swapped; ++i) {

            swapped = false;

            for (int j = 0; j < len - i; ++j) {

                if (comp.compare(list[j], list[j + 1]) > 0) {

                    T temp = list[j];

                    list[j] = list[j + 1];

                    list[j + 1] = temp;

                    swapped = true;

                }

 

 

95、用Java寫一個折半查找。

答:折半查找,也稱二分查找、二分搜索,是一種在有序數組中查找某一特定元素的搜索算法。搜素過程從數組的中間元素開始,若是中間元素正好是要查找的元素,則搜素過程結束;若是某一特定元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半中查找,並且跟開始同樣從中間元素開始比較。若是在某一步驟數組已經爲空,則表示找不到指定的元素。

import java.util.Comparator;

 

public class MyUtil {

 

   public static <T extends Comparable<T>> int binarySearch(T[] x, T key) {

      return binarySearch(x, 0, x.length- 1, key);

   }

 

   // 使用循環實現的二分查找

   public static <T> int binarySearch(T[] x, T key, Comparator<T> comp) {

      int low = 0;

      int high = x.length - 1;

      while (low <= high) {

          int mid = (low + high) >>> 1;

          int cmp = comp.compare(x[mid], key);

          if (cmp < 0) {

            low= mid + 1;

          }

          else if (cmp > 0) {

            high= mid - 1;

          }

          else {

            return mid;

          }

      }

      return -1;

   }

 

   // 使用遞歸實現的二分查找

   private static<T extends Comparable<T>> int binarySearch(T[] x, int low, int high, T key) {

      if(low <= high) {

        int mid = low + ((high -low) >> 1);

        if(key.compareTo(x[mid])== 0) {

           return mid;

        }

        else if(key.compareTo(x[mid])< 0) {

           return binarySearch(x,low, mid - 1, key);

        }

        else {

           return binarySearch(x,mid + 1, high, key);

        }

      }

      return -1;

   }

}

 

 

 

 

96Java 代碼查錯

1.

 abstract class Name {

private String name;

public abstract boolean isStupidName(String name) {}

}

大俠們,這有何錯誤?

答案: 錯。abstract method 必須以分號結尾,且不帶花括號。 2.

public class Something {

void doSomething () { private String s = ""; int l = s.length();

} }

有錯嗎?

答案: 錯。局部變量前不能放置任何訪問修飾符 (private,public,protected)final 能夠 用來修飾局部變量

(final 如同 abstract strictfp,都是非訪問修飾符,strictfp 只能修飾 class method 而非 variable)

3.

abstract class Something {

private abstract String doSomething (); }

這好像沒什麼錯吧?

答案: 錯。abstractmethods不能以private修飾。abstractmethods就是讓子類implement(實 現)具體細節的,怎麼能夠用 private abstract

method 封鎖起來呢? (同理,abstract method 前不能加 final)

4.

public class Something {

public int addOne(final int x) { return ++x;

} }

這個比較明顯。

答案: 錯。int x 被修飾成 final,意味着 x 不能在 addOne method 中被修改。 5.

public class Something {

public static void main(String[] args) { Other o = new Other();

new Something().addOne(o);

}

public void addOne(final Other o) {

o.i++; }

}

 class Other { public int i;

}

和上面的很類似,都是關於 final 的問題,這有錯嗎?

答案: 正確。在 addOne method ,參數 o 被修飾成 final。若是在 addOne method 裏咱們修 改了 o reference

(好比: o = new Other();),那麼如同上例這題也是錯的。但這裏修改的是 o member vairable (成員變量),o reference 並無改變。

6.

class Something {

int i;

public void doSomething() {

System.out.println("i = " + i); }

}

有什麼錯呢? 看不出來啊。

答案: 正確。輸出的是"i = 0"int i 屬於 instant variable (實例變量,或叫成員變量)instant variable default valueint default value 0

7.

class Something {

final int i;

public void doSomething() {

System.out.println("i = " + i); }

}

和上面一題只有一個地方不一樣,就是多了一個 final。這難道就錯了嗎?

答案: 錯。final int i 是個 final instant variable (實例變量,或叫成員變量)final instant variable 沒有 default value,必須在 constructor (構造器)結束以前被賦予一個明確的值。能夠 修改成"final int i = 0;"

8.

public class Something {

public static void main(String[] args) {

Something s = new Something(); System.out.println("s.doSomething() returns " + doSomething());

}

public String doSomething() {

return "Do something ..."; }

}

看上去很完美。

答案: 錯。看上去在 main call doSomething 沒有什麼問題,畢竟兩個 methods 都在同一個 class 裏。但仔細看,main static 的。static method 不能直接 call non-static methods。可改 成"System.out.println("s.doSomething() returns " + s.doSomething());"。同理,static method 不 能訪問 non-static instant variable

 9.

此處,Something 類的文件名叫 OtherThing.java class Something {

private static void main(String[] something_to_do) { System.out.println("Do something ...");

} }

這個好像很明顯。

答案: 正確。歷來沒有人說過 Java Class 名字必須和其文件名相同。但 public class 的名字 必須和文件名相同。

10.

interface A{

int x = 0; }

class B{ int x =1;

}

class C extends B implements A {

public void pX(){ System.out.println(x);

}

public static void main(String[] args) {

new C().pX(); }

}

答案:錯誤。在編譯時會發生錯誤(錯誤 述不一樣的 JVM 有不一樣的信息,意思就是未明確的 x 調用,兩個 x 都匹配(就象在同時 import java.util java.sql 兩個包時直接聲明 Date 同樣)。 對於父類的變量,能夠用 super.x 來明確,而接口的屬性默認隱含爲 public static final.因此可 以經過 A.x 來明確。

11.

interface Playable {

void play(); }

interface Bounceable { void play();

}

interface Rollable extends Playable, Bounceable {

Ball ball = new Ball("PingPang"); }

class Ball implements Rollable { private String name;

public String getName() {

return name; }

public Ball(String name) { this.name = name;

}

public void play() {

ball = new Ball("Football");

System.out.println(ball.getName()); }

}

這個錯誤不容易發現。

答案: 錯。"interface Rollable extends Playable, Bounceable"沒有問題。interface 可繼承多個 interfaces,因此這裏沒錯。問題出在 interface Rollable 裏的"Ball ball = new Ball("PingPang");"。 任何在 interface 裏聲明的 interface variable (接口變量,也可稱成員變量),默認爲 public static final。也就是說"Ball ball = new Ball("PingPang");"其實是"public static final Ball ball = new Ball("PingPang");"。在Ball類的Play()方法中,"ball = new Ball("Football");"改變了ballreference,而這裏的 ball 來自 Rollable interface,Rollable interface 裏的 ball public static final ,final object 是不能被改變 reference 的。所以編譯器將在"ball = new Ball("Football");" 這裏顯示有錯。

 

3、html&JavaScript&ajax

1. 判斷第二個日期比第一個日期大

//實現比較

function compareDate(d1,d2) {

var arrayD1 = d1.split("-");

var date1 = new Date(arrayD1[0],arrayD1[1],arrayD1[2]); var arrayD2 = d2.split("-");

var date2 = new Date(arrayD2[0],arrayD2[1],arrayD2[2]); if(date1 > date2) return false;

return true;

}

//判斷格式是否正確

function verifyDate(d) {

var datePattern = /^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/;

return datePattern.test(d); }

 

 

2. table 顯示 n 條記錄,3 行換一次顏色,1,2,3 用紅色字體,4,5,6 用綠色字體,7,8,9 用紅顏色字體。

window.οnlοad=function()

{

var tbl = document.getElementById("tbl"); rows = tbl.getElementsByTagName("tr"); for(i=0;i<rows.length;i++)

{

var j = parseInt(i/3);

if(j%2==0) rows[i].style.backgroundColor="#f00"; else rows[i].style.backgroundColor="#0f0";

} }

 

3HTML form  交以前如何驗證數值文本框的內容全 部爲數字? 不然的話 示用戶並終止 交?

<form οnsubmit=return chkForm(this)> <input type="text" name="d1"/>

<input type="submit"/>

</form>

<script type=text/javascript/> function chkForm(this)

{

var value = thist.d1.value; var len = value.length; for(var i=0;i<len;i++)

{

if(value.charAt(i)>"9" || value.charAt(i)<"0") {

alert("含有非數字字符");

return false; }

}

return true; }

</script>

4、請寫出用於校驗 HTML 文本框中輸入的內容所有爲數字 的 javascript 代碼

失去焦點事件

<input type="text" id="d1" οnblur=" chkNumber (this)"/> <script type=text/javascript/>

function chkNumber(eleText)

{

var value = eleText.value; var len = value.length; for(var i=0;i<len;i++)

{

if(value.charAt(i)>"9" || value.charAt(i)<"0") {

alert("含有非數字字符");

eleText.focus();

break; }

} }

</script>

 

5、說說你用過那些 ajax 技術和框架,說說它們的區別

百度一下

答:jQuery

       EasyUI

       DWR

       Vue

 

4、Java web 部分

1Tomcat 的優化經驗

去掉對 web.xml 的監視,jsp  前編輯成 Servlet

有富餘物理內存的狀況,加大 tomcat 使用的 jvm 的內存

2HTTP 請求的 GET POST 方式的區別

get請求用來從服務器上得到資源,而post是用來向服務器提交數據; 
②get將表單中數據按照name=value的形式,添加到action 所指向的URL 後面,而且二者使用"?"鏈接,而各個變量之間使用"&"鏈接;post是將表單中的數據放在HTTP協議的請求頭或消息體中,傳遞到action所指向URL 
③get傳輸的數據要受到URL長度限制(1024字節);而post能夠傳輸大量的數據,上傳文件一般要使用post方式; 

④使用get時參數會顯示在地址欄上,若是這些數據不是敏感數據,那麼能夠使用get;對於敏感數據仍是應用使用post 
⑤get使用MIME類型application/x-www-form-urlencodedURL編碼(也叫百分號編碼)文本的格式傳遞參數,保證被傳送的參數由遵循規範的文本組成,例如一個空格的編碼是"%20"

3、解釋一下什麼是 servlet;

答:Servlet是一個特殊的Java程序,它運行於服務器的JVM中,可以依靠服務器的支持向瀏覽器提供顯示內容。

4、說一說 Servlet 的生命週期?

:包括加載和實例化、初始化、處理請求以及服務結束。

這個生存期由 javax.servlet.Servlet 接口的 init,service destroy 方法表達。

Servlet 被服務器實例化後,容器運行其 init 方法,請求到達時運行其 service 方法,service 方法自動派遣運行與請求對應的 doXXX 方法(doGet,doPost),當服務器決定將實例銷 毀的時候調用其 destroy 方法。

5Servlet 的基本架構

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 {

}

}

6SERVLET API forward() redirect()的區別?

答:forward是容器中控制權的轉向,是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL 的響應內容讀取過來,而後把這些內容再發給瀏覽器,瀏覽器根本不知道服務器發送的內容是從哪兒來的,因此它的地址欄中仍是原來的地址。redirect就是服務器端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址,所以從瀏覽器的地址欄中能夠看到跳轉後的連接地址,很明顯redirect沒法訪問到服務器保護起來資源,可是能夠從一個網站redirect到其餘網站。forward更加高效,因此在知足須要時儘可能使用forward(經過調用RequestDispatcher對象的forward()方法,該對象能夠經過ServletRequest對象的getRequestDispatcher()方法得到),而且這樣也有助於隱藏實際的連接;在有些狀況下,好比須要訪問一個其它服務器上的資源,則必須使用重定向(經過HttpServletResponse對象調用其sendRedirect()方法實現)。

7、什麼狀況下調用 doGet()doPost()?

Jsp 頁面中的 FORM 標籤裏的 method 屬性爲 get 時調用 doGet(),post 時調用

doPost()。全部的超連接是調doGet();

8Request 對象的主要方法:

setAttribute(String name,Object):設置名字爲 name request 的參數值 getAttribute(String name):返回由 name 指定的屬性值

getCookies():返回客戶端的全部 Cookie 對象,結果是一個 Cookie 數組

getCharacterEncoding():返回請求中的字符編碼方式 getContentLength():返回請求的 Body 的長度

getMethod():得到客戶端向服務器端傳送數據的方法

getParameter(String name):得到客戶端傳送給服務器端的有 name 指定的參數值 getParameterNames():得到客戶端傳送給服務器端的全部參數的名字,結果是一個枚

舉的實例

getParametervalues(String name):得到有 name 指定的參數的全部值

removeAttribute(String name):刪除請求中的一個屬性

9request.getAttribute() request.getParameter() 有何 區別?

getParameter 是用來接受用postget方法傳遞過來的參數的.

getAttribute 必須先setAttribute.

1request.getParameter() 取得是經過容器的實現來取得經過相似postget等方式傳入的數據,request.setAttribute()getAttribute()只是在web容器內部流轉,僅僅是請求處理階段。

2request.getParameter() 方法傳遞的數據,會從Web客戶端傳到Web服務器端,表明HTTP請求數據。request.getParameter()方法返回String類型的數據。

request.setAttribute() getAttribute() 方法傳遞的數據只會存在於Web容器內部

還有一點就是,HttpServletRequest 類有 setAttribute() 方法,而沒有setParameter() 方法。

10. jsp 有哪些內置對象?做用分別是什麼? 分別有什麼方 法?

:JSP 共有如下 9 個內置的對象:

request 用戶端請求,此請求會包含來自 GET/POST 請求的參數 response 網頁傳回用戶端的迴應

pageContext 網頁的屬性是在這裏管理

session 與請求有關的會話期

application servlet 正在執行的內容

out 用來傳送回應的輸出

config servlet 的構架部件

page JSP 網頁自己

exception 針對錯誤網頁,未捕捉的例外

11. jsp 有哪些動做?做用分別是什麼?

:JSP 共有如下 7 種基本動做

jsp:param指令用於設置參數值,單獨使用沒有意義

jsp:include:在頁面被請求的時候引入一個文件。

jsp:useBean:尋找或者實例化一個 JavaBean

jsp:setProperty:設置 JavaBean 的屬性。

jsp:getProperty:輸出某個 JavaBean 的屬性。

jsp:forward:把請求轉到一個新的頁面。

jsp:plugin:根據瀏覽器類型爲 Java 插件生成 OBJECT EMBED 標記

12JSP 的經常使用指令

三個編譯指令爲:pageincludetaglib

七個動做指令爲:jsp:forwardjsp:paramjsp:includejsp:pluginjsp:useBeanjsp:setPropertyjsp:getProperty

 

13. JSP 中動態 INCLUDE 與靜態 INCLUDE 的區別?

JSP中的靜態包含和動態包含有什麼區別

答:靜態包含是經過JSPinclude指令包含頁面,動態包含是經過JSP標準動做<jsp:forward>包含頁面。靜態包含是編譯時包含,若是包含的頁面不存在則會產生編譯錯誤,並且兩個頁面的"contentType"屬性應保持一致,由於兩個頁面會合二爲一,只產生一個class文件,所以被包含頁面發生的變更再包含它的頁面更新前不會獲得更新。動態包含是運行時包含,能夠向被包含的頁面傳遞參數,包含頁面和被包含頁面是獨立的,會編譯出兩個class文件,若是被包含的頁面不存在,不會產生編譯錯誤,也不影響頁面其餘部分的執行。

 

14、頁面間對象傳遞的方法

request,session,application,cookie

15JSP Servlet 有哪些相同點和不一樣點,他們之間的聯 系是什麼?

Servlet是一個特殊的Java程序,它運行於服務器的JVM中,可以依靠服務器的支持向瀏覽器提供顯示內容。JSP本質上是Servlet的一種簡易形式,JSP會被服務器處理成一個相似於ServletJava程序,能夠簡化頁面內容的生成。ServletJSP最主要的不一樣點在於,Servlet的應用邏輯是在Java文件中,而且徹底從表示層中的HTML分離開來。而JSP的狀況是JavaHTML能夠組合成一個擴展名爲.jsp的文件。Servlet就是在Java中寫HTML,而JSP就是在HTML中寫Java代碼。JSP側重於視圖,Servlet更側重於控制邏輯,在MVC架構模式中,JSP適合充當視圖(view)而Servlet適合充當控制器(controller)。

16MVC 的各個部分都有那些技術來實現?如何實現?

:MVC Model-View-Controller 的簡寫。Model 表明的是應用的業務邏輯(經過 JavaBean,EJB 組件實現), View 是應用的表示面(JSP 頁面產生),Controller 是 供 應用的處理過程控制(通常是一個 Servlet),經過這種設計模型把應用邏輯,處理過程和顯 示邏輯分紅不一樣的組件實現。這些組件能夠進行交互和重用。

17、咱們在 web 應用開發過程當中常常遇到輸出某種編碼的字 符,iso8859-1 ,如何輸出一個某種編碼的字符串?

tempStr = new String(str.getBytes("ISO-8859-1"), UTF-8);

 

18、闡述ServletCGI的區別

答:ServletCGI的區別在於Servlet處於服務器進程中,它經過多線程方式運行其service()方法,一個實例能夠服務於多個請求,而且其實例通常不會銷燬,而CGI對每一個請求都產生新的進程,服務完成後就銷燬,因此效率上低於Servlet

19、經常使用的Web服務器有哪些?

免費HTTP服務器是Apache服務器,而Windows平臺的服務器一般使用IIS做爲Web服務器。選擇Web服務器應考慮的因素有:性能、安全性、日誌和統計、虛擬主機、代理服務器、緩衝服務和集成應用程序等。

IISMicrosoftWeb服務器產品

WebSphereIBM

WebLogicOracle

Apache:目前Apache仍然是世界上用得最多的Web服務器

TomcatTomcat是一個開放源代碼、運行ServletJSP的容器

Nginx:高性能的HTTP和反向代理服務器,也是一個IMAP/POP3/SMTP代理服務器

20、如何實現JSPServlet的單線程模式? 

答: 對於JSP頁面,能夠經過page指令進行設置。

<%@page isThreadSafe=false%>

對於Servlet,可讓自定義的Servlet實現SingleThreadModel標識接口。

說明:若是將JSPServlet設置成單線程工做模式,會致使每一個請求建立一個Servlet實例,這種實踐將致使嚴重的性能問題(服務器的內存壓力很大,還會致使頻繁的垃圾回收),因此一般狀況下並不會這麼作。

21、實現會話跟蹤的技術有哪些?

答:因爲HTTP協議自己是無狀態的,服務器爲了區分不一樣的用戶,就須要對用戶會話進行跟蹤,簡單的說就是爲用戶進行登記,爲用戶分配惟一的ID,下一次用戶在請求中包含此ID,服務器據此判斷究竟是哪個用戶。 

URL 重寫:在URL中添加用戶會話的信息做爲請求的參數,或者將惟一的會話ID添加到URL結尾以標識一個會話。 

②設置表單隱藏域:將和會話跟蹤相關的字段添加到隱式表單域中,這些信息不會在瀏覽器中顯示可是提交表單時會提交給服務器。 

cookie:屬於客戶端技術,cookie有兩種,一種是基於窗口的,瀏覽器窗口關閉後,cookie就沒有了;另外一種是將信息存儲在一個臨時文件中,並設置存在的時間。

在使用cookie時要注意幾點:首先不要在cookie中存放敏感信息;其次cookie存儲的數據量有限(4k),不能將過多的內容存儲cookie中;再者瀏覽器一般只容許一個站點最多存放20cookie

HttpSession:屬於服務端技術,在全部會話跟蹤技術中,HttpSession對象是最強大也是功能最多的。當一個用戶第一次訪問某個網站時會自動建立HttpSession,每一個用戶能夠訪問他本身的HttpSession

22、過濾器有哪些做用和用法? 

Java Web開發中的過濾器(filter)是從Servlet 2.3規範開始增長的功能,並在Servlet 2.4規範中獲得加強。對Web應用來講,過濾器是一個駐留在服務器端的Web組件,它能夠截取客戶端和服務器之間的請求與響應信息,並對這些信息進行過濾。

常見的過濾器用途主要包括:對用戶請求進行統一認證、對用戶的訪問請求進行記錄和審覈、對用戶發送的數據進行過濾或替換、轉換圖象格式、對響應內容進行壓縮以減小傳輸量、對請求或響應進行加解密處理、觸發資源訪問事件、對XML的輸出應用XSLT等。

23、監聽器有哪些做用和用法? 

答:Java Web開發中的監聽器(listener)就是applicationsessionrequest三個對象建立、銷燬或者往其中添加修改刪除屬性時自動執行代碼的功能組件,以下所示: 
①ServletContextListener:對Servlet上下文的建立和銷燬進行監聽。 
②ServletContextAttributeListener:監聽Servlet上下文屬性的添加、刪除和替換。 
③HttpSessionListener:對Session的建立和銷燬進行監聽。

補充:session的銷燬有兩種狀況:1). session超時(能夠在web.xml中經過<session-config>/<session-timeout>標籤配置超時時間);2). 經過調用session對象的invalidate()方法使session失效。

HttpSessionAttributeListener:對Session對象中屬性的添加、刪除和替換進行監聽。 
⑤ServletRequestListener:對請求對象的初始化和銷燬進行監聽。 
⑥ServletRequestAttributeListener:對請求對象屬性的添加、刪除和替換進行監聽。

 

24web.xml文件中能夠配置哪些內容? 

答:web.xml用於配置Web應用的相關信息,如:監聽器(listener)、過濾器(filter)、 Servlet、相關參數、會話超時時間、安全驗證方式、錯誤頁面等

Servlet 3規範提供了基於註解的配置方式,能夠分別使用@WebServlet@WebListener@WebFilter註解進行配置。 

認證的方式很是多,簡單說來能夠分爲三類: A. What you know? — 口令 B. What you have? — 數字證書(U盾、密保卡) C. Who you are? — 指紋識別、虹膜識別 

 

25、你的項目中使用過哪些JSTL標籤?

答:項目中主要使用了JSTL的核心標籤庫,包括<c:if><c:choose><c: when><c: otherwise><c:forEach>等,主要用於構造循環和分支結構以控制顯示邏輯。

說明:雖然JSTL標籤庫提供了coresqlfmtxml等標籤庫,可是實際開發中建議只使用核心標籤庫(core),並且最好只使用分支和循環標籤並輔以表達式語言(EL),這樣才能真正作到數據顯示和業務邏輯的分離,這纔是最佳實踐。

26、使用標籤庫有什麼好處?如何自定義JSP標籤? 

答:使用標籤庫的好處包括如下幾個方面: - 分離JSP頁面的內容和邏輯,簡化了Web開發; - 開發者能夠建立自定義標籤來封裝業務邏輯和顯示邏輯; - 標籤具備很好的可移植性、可維護性和可重用性; - 避免了對Scriptlet(小腳本)的使用(不少公司的項目開發都不容許在JSP中書寫小腳本)

自定義JSP標籤包括如下幾個步驟: - 編寫一個Java類實現實現Tag/BodyTag/IterationTag接口(開發中一般不直接實現這些接口而是繼承TagSupport/BodyTagSupport/SimpleTagSupport類,這是對缺省適配模式的應用),重寫doStartTag()doEndTag()等方法,定義標籤要完成的功能 - 編寫擴展名爲tld的標籤描述文件對自定義標籤進行部署,tld文件一般放在WEB-INF文件夾下或其子目錄中 

27、說一下表達式語言(EL)的隱式對象及其做用。 

答:EL的隱式對象包括:pageContextinitParam(訪問上下文參數)、param(訪問請求參數)、paramValuesheader(訪問請求頭)、headerValuescookie(訪問cookie)、applicationScope(訪問application做用域)、sessionScope(訪問session做用域)、requestScope(訪問request做用域)、pageScope(訪問page做用域)。

用法以下所示:

${pageContext.request.method}

${pageContext["request"]["method"]}

${pageContext.request["method"]}

${pageContext["request"].method}

${initParam.defaultEncoding}

${header["accept-language"]}

${headerValues["accept-language"][0]}

${cookie.jsessionid.value}

${sessionScope.loginUser.username}

補充:表達式語言的.[]運算做用是一致的,惟一的差異在於若是訪問的屬性名不符合Java標識符命名規則,例如上面的accept-language就不是一個有效的Java標識符,那麼這時候就只能用[]運算符而不能使用.運算符獲取它的值

28、表達式語言(EL)支持哪些運算符?

答:除了.[]運算符,EL還提供了: - 算術運算符:+-*/div%mod - 關係運算符:==eq!=ne>gt>=ge<lt<=le - 邏輯運算符:&&and||or!not - 條件運算符:${statement? A : B}(跟Java的條件運算符相似) - empty運算符:檢查一個值是否爲null或者空(數組長度爲0或集合中沒有元素也返回true

29Java Web開發的Model 1Model 2分別指的是什麼? 

答:Model 1是以頁面爲中心的Java Web開發,使用JSP+JavaBean技術將頁面顯示邏輯和業務邏輯處理分開,JSP實現頁面顯示,JavaBean對象用來保存數據和實現業務邏輯。Model 2是基於MVC(模型-視圖-控制器,Model-View-Controller)架構模式的開發模型,實現了模型和視圖的完全分離,利於團隊開發和代碼複用。

30Servlet 3中的異步處理指的是什麼?

答:在Servlet 3中引入了一項新的技術可讓Servlet異步處理請求。

異步特性能夠幫助應用節省容器中的線程,特別適合執行時間長並且用戶須要獲得結果的任務,若是用戶不須要獲得結果則直接將一個Runnable對象交給Executor並當即返回便可。

31、如何在基於JavaWeb項目中實現文件上傳和下載? 

答:在Sevlet 3 之前,Servlet API中沒有支持上傳功能的API,所以要實現上傳功能須要引入第三方工具從POST請求中得到上傳的附件或者經過自行處理輸入流來得到上傳的文件,咱們推薦使用Apachecommons-fileupload

Servlet 3開始,文件上傳變得無比簡單

上傳頁面index.jsp

<%@ page pageEncoding="utf-8"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Photo Upload</title>

</head>

<body>

<h1>Select your photo and upload</h1>

<hr/>

<div style="color:red;font-size:14px;">${hint}</div>

<form action="UploadServlet" method="post" enctype="multipart/form-data">

    Photo file: <input type="file" name="photo" />

    <input type="submit" value="Upload" />

</form>

</body>

</html>

支持上傳的Servlet

package com.jackfrued.servlet;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.annotation.MultipartConfig;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.Part;

 

@WebServlet("/UploadServlet")

@MultipartConfig

public class UploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

 

    protected void doPost(HttpServletRequest request,

            HttpServletResponse response) throws ServletException, IOException {

        // 能夠用request.getPart()方法得到名爲photo的上傳附件

        // 也能夠用request.getParts()得到全部上傳附件(多文件上傳)

        // 而後經過循環分別處理每個上傳的文件

        Part part = request.getPart("photo");

        if (part != null && part.getSubmittedFileName().length() > 0) {

            // ServletContext對象的getRealPath()方法得到上傳文件夾的絕對路徑

            String savePath = request.getServletContext().getRealPath("/upload");

            // Servlet 3.1規範中能夠用Part對象的getSubmittedFileName()方法得到上傳的文件名

            // 更好的作法是爲上傳的文件進行重命名(避免同名文件的相互覆蓋)

            part.write(savePath + "/" + part.getSubmittedFileName());

            request.setAttribute("hint", "Upload Successfully!");

        } else {

            request.setAttribute("hint", "Upload failed!");

        }

        // 跳轉回到上傳頁面

        request.getRequestDispatcher("index.jsp").forward(request, response);

    }

 

}

32Servlet中如何獲取用戶提交的查詢參數或表單數據? 
答:能夠經過請求對象(HttpServletRequest)的getParameter()方法經過參數名得到參數值。若是有包含多個值的參數(例如複選框),能夠經過請求對象的getParameterValues()方法得到。固然也能夠經過請求對象的getParameterMap()得到一個參數名和參數值的映射(Map)。

 

33Servlet中如何獲取用戶配置的初始化參數以及服務器上下文參數? 
答:能夠經過重寫Servlet接口的init(ServletConfig)方法並經過ServletConfig對象的getInitParameter()方法來獲取Servlet的初始化參數。能夠經過ServletConfig對象的getServletContext()方法獲取ServletContext對象,並經過該對象的getInitParameter()方法來獲取服務器上下文參數。固然,ServletContext對象也在處理用戶請求的方法(如doGet()方法)中經過請求對象的getServletContext()方法來得到。

 

34、如何設置請求的編碼以及響應內容的類型? 
答:經過請求對象(ServletRequest)的setCharacterEncoding(String)方法能夠設置請求的編碼,其實要完全解決亂碼問題就應該讓頁面、服務器、請求和響應、Java程序都使用統一的編碼,最好的選擇固然是UTF-8;經過響應對象(ServletResponse)的setContentType(String)方法能夠設置響應內容的類型,固然也能夠經過HttpServletResponsed對象的setHeader(String, String)方法來設置

 

35、解釋一下網絡應用的模式及其特色。

答:典型的網絡應用模式大體有三類:B/SC/SP2P。其中B表明瀏覽器(Browser)、C表明客戶端(Client)、S表明服務器(Server),P2P是對等模式,不區分客戶端和服務器。B/S應用模式中能夠視爲特殊的C/S應用模式,只是將C/S應用模式中的特殊的客戶端換成了瀏覽器,由於幾乎全部的系統上都有瀏覽器,那麼只要打開瀏覽器就能夠使用應用,沒有安裝、配置、升級客戶端所帶來的各類開銷。

 

補充:此題要跟"電子商務模式"區分開,由於有不少人被問到這個問題的時候立刻想到的是B2B(如阿里巴巴)也有寫成 BTB,是Business-to-Business的縮寫、B2C(如噹噹、亞馬遜、京東)Business-to-CustomerC2C(如淘寶、拍拍CustomerCustomerto ConsumerConsumer))、C2B(如威客)Customer to Business,即消費者到企業、O2O(如美團、餓了麼)即Online To Offline(在線離線/線上到線下)。

 

36、什麼是Web ServiceWeb服務)? 

答:從表面上看,Web Service就是一個應用程序,它向外界暴露出一個可以經過Web進行調用的API。如聚合數據。

補充:這裏必需要說起的一個概念是SOAService-Oriented Architecture,面向服務的架構),SOA是一種思想,它將應用程序的不一樣功能單元經過中立的契約聯繫起來,獨立於硬件平臺、操做系統和編程語言,使得各類形式的功能單元可以更好的集成。顯然,Web ServiceSOA的一種較好的解決方案,它更多的是一種標準,而不是一種具體的技術。

37、概念解釋:SOAPWSDLUDDI 

答: - SOAP:簡單對象訪問協議(Simple Object Access Protocol),是Web Service中交換數據的一種協議規範。 - WSDLWeb服務描述語言(Web Service Description Language),它描述了Web服務的公共接口。這是一個基於XML的關於如何與Web服務通信和使用的服務描述;也就是描述與目錄中列出的Web服務進行交互時須要綁定的協議和信息格式。一般採用抽象語言描述該服務支持的操做和信息,使用的時候再將實際的網絡協議和信息格式綁定給該服務。 - UDDI:統一描述、發現和集成(Universal Description, Discovery and Integration),它是一個基於XML的跨平臺的描述規範,能夠使世界範圍內的企業在互聯網上發佈本身所提供的服務。簡單的說,UDDI是訪問各類WSDL的一個門面(能夠參考設計模式中的門面模式)。

38Java規範中和Web Service相關的規範有哪些? 

答:Java規範中和Web Service相關的有三個: - JAX-WS(JSR 224):這個規範是早期的基於SOAPWeb Service規範JAX-RPC的替代版本,它並不提供向下兼容性,由於RPC樣式的WSDL以及相關的API已經在Java EE5中被移除了。WS-MetaDataJAX-WS的依賴規範,提供了基於註解配置Web ServiceSOAP消息的相關API - JAXM(JSR 67):定義了發送和接收消息所需的API,至關於Web Service的服務器端。 - JAX-RS(JSR 311 & JSR 339 & JSR 370):是Java針對RESTRepresentation State Transfer)架構風格制定的一套Web Service規範。REST是一種軟件架構模式,是一種風格,它不像SOAP那樣自己承載着一種消息協議, (兩種風格的Web Service均採用了HTTP作傳輸協議,由於HTTP協議能穿越防火牆,Java的遠程方法調用(RMI)等是重量級協議,一般不能穿越防火牆),所以能夠將REST視爲基於HTTP協議的軟件架構。REST中最重要的兩個概念是資源定位和資源操做,而HTTP協議剛好完整的提供了這兩個點。HTTP協議中的URI能夠完成資源定位,而GETPOSTOPTIONDELETE方法能夠完成資源操做。所以REST徹底依賴HTTP協議就能夠完成Web Service,而不像SOAP協議那樣只利用了HTTP的傳輸特性,定位和操做都是由SOAP協議自身完成的,也正是因爲SOAP消息的存在使得基於SOAPWeb Service顯得笨重而逐漸被淘汰。

39、介紹一下你瞭解的Java領域的Web Service框架。

答:Java領域的Web Service框架不少,包括Axis2Axis的升級版本)、JerseyRESTfulWeb Service框架)、CXFXFire的延續版本)、JBoss SOA等,其中絕大多數都是開源框架。

5、數據庫

1、用兩種方式根據部門號從高到低,工資從低到高列出每

個員工的信息。

employee: eid,ename,salary,deptid;

select * from employee order by deptid desc,salary

2、列出各個部門中工資高於本部門的平均工資的員工數和 部門號,並按部門號排序

建立表:

mysql> create table employee921(id int primary key auto_increment,name varchar(5 0),salary bigint,deptid int);

插入實驗數據:

mysql> insert into employee921 values(null,'zs',1000,1),(null,'ls',1100,1),(null ,'ww',1100,1),(null,'zl',900,1) ,(null,'zl',1000,2), (null,'zl',900,2) ,(null,'z l',1000,2) , (null,'zl',1100,2);

編寫 sql 語句:

()select avg(salary) from employee921 group by deptid;

()mysql> select employee921.id,employee921.name,employee921.salary,employee921.dep

tid tid from employee921 where salary > (select avg(salary) from employee921 where deptid = tid);

效率低的一個語句,僅供學習參考使用(group by 以後不能使用 where,只能使用 having,group by 以前能夠使用 where,即表示對過濾後的結果分組):

mysql> select employee921.id,employee921.name,employee921.salary,employee921.dep

tid tid from employee921 where salary > (select avg(salary) from employee921 group by deptid

having deptid = tid); ()select count(*) ,tid

from (

select employee921.id,employee921.name,employee921.salary,employee921.deptid tid from employee921

where salary >

(select avg(salary) from employee921 where group by tid ;

另一種方式:關聯查詢

select a.ename,a.salary,a.deptid from emp a,

deptid = tid)

) as t

(select deptd,avg(salary) avgsal from emp group by deptid ) b where a.deptid=b.deptid and a.salary>b.avgsal;

 

3、存儲過程與觸發器必須講,常常被面試到?

create procedure insert_Student (_name varchar(50),_age int ,out _id int) begin

insert into student value(null,_name,_age);

select max(stuId) into _id from student; end;

call insert_Student('wfz',23,@id); select @id;

mysql> create trigger update_Student BEFORE update on student FOR EACH ROW -> select * from student;

觸發器不容許返回結果

create trigger update_Student BEFORE update on student FOR EACH ROW insert into student value(null,'zxx',28);

mysql 的觸發器目前不能對當前表進行操做

create trigger update_Student BEFORE update on student FOR EACH ROW delete from articles where id=8; 這個例子不是很好,最好是用刪除一個用戶時,順帶刪除該用戶的全部帖子 這裏要注意使用 OLD.id

觸發器用處仍是不少的,好比校內網、開心網、Facebook,你發一個日誌,自動通知好 友,其實就是在增長日誌時作一個後觸發,再向通知表中寫入條目。由於觸發器效率高。而 UCH 沒有用觸發器,效率和數據處理能力都很低。

存儲過程的實驗步驟:

 mysql> delimiter |

mysql> create procedure insertArticle_Procedure (pTitle varchar(50),pBid int,out

pId int)

-> begin

-> insert into article1 value(null,pTitle,pBid); -> select max(id) into pId from article1;

-> end;

-> |

Query OK, 0 rows affected (0.05 sec)

mysql> call insertArticle_Procedure('傳智播客',1,@pid); -> |

Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ; mysql> select @pid; +------+

| @pid |

+------+

|3|

+------+

1 row in set (0.00 sec)

mysql> select * from article1; +----+--------------+------+ |id|title |bid | +----+--------------+------+ |1|test |1 |

| 2 | chuanzhiboke | 1 | |3 |傳智播客 |1 | +----+--------------+------+

3 rows in set (0.00 sec)

觸發器的實驗步驟:

create table board1(id int primary key auto_increment,name varchar(50),ar ticleCount int);

create table article1(id int primary key auto_increment,title varchar(50) ,bid int references board1(id));

delimiter |

create trigger insertArticle_Trigger after insert on article1 for each ro w begin

-> update board1 set articleCount=articleCount+1 where id= NEW.bid; -> end;

-> |

delimiter ;

insert into board1 value (null,'test',0);

insert into article1 value(null,'test',1);

還有,每插入一個帖子,都但願將版面表中的最後發帖時間,帖子總數字段進行同步 更新,用觸發器作效率就很高。下次課設計這樣一個案例,寫觸發器時,對於最後發帖時間 可能須要用 declare 方式聲明一個變量,或者是用 NEW.posttime 來生成。

4、數據庫三範式是什麼?

第一範式(1NF):字段具備原子性,不可再分。全部關係型數據庫系統都知足第一範式) 數據庫表中的字段都是單一屬性的,不可再分。例如,姓名字段,其中的姓和名必須做 爲一個總體,沒法區分哪部分是姓,哪部分是名,若是要區分出姓和名,必須設計成兩個獨

立的字段。

第二範式(2NF): 第二範式(2NF)是在第一範式(1NF)的基礎上創建起來的,即知足第二範式(2NF)必 須先知足第一範式(1NF)。 要求數據庫表中的每一個實例或行必須能夠被唯一地區分。一般須要爲表加上一個列,以存儲 各個實例的唯一標識。這個唯一屬性列被稱爲主關鍵字或主鍵。

第二範式(2NF)要求實體的屬性徹底依賴於主關鍵字。所謂徹底依賴是指不能存在僅依賴 主關鍵字一部分的屬性,若是存在,那麼這個屬性和主關鍵字的這一部分應該分離出來造成 一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分一般須要爲表加上一個列, 以存儲各個實例的唯一標識。簡而言之,第二範式就是非主屬性非部分依賴於主關鍵字。

第三範式的要求以下: 知足第三範式(3NF)必須先知足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個 數據庫表中不包含已在其它表中已包含的非主關鍵字信息。

因此第三範式具備以下特徵:

1,每一列只有一個值

2,每一行都能區分。 3,每個表都不包含其餘表已經包含的非主關鍵字信息。

例如,帖子表中只能出現發帖人的 id,而不能出現發帖人的 id,還同時出現發帖人姓名, 不然,只要出現同一發帖人 id 的全部記錄,它們中的姓名部分都必須嚴格保持一致,這就 是數據冗餘。

5、說出一些數據庫優化方面的經驗?

PreparedStatement 通常來講比Statement性能高:一個sql 發給服務器去執行,涉及步驟: 語法檢查、語義分析, 編譯,緩存

inert into user values(1,1,1)- 二進制

inert into user values(2,2,2)- 二進制

inert into user values(?,?,?)- 二進制

有外鍵約束會影響插入和刪除性能,若是程序可以保證數據的完整性,那在設計數據庫時就 去掉外鍵。(比喻:就比如免檢產品,就是爲了 高效率,充分相信產品的製造商) (對於 hibernate 來講,就應該有一個變化:empleyee->Deptment 對象,如今設計時就成了 employee deptid)

mysql 幫助文檔子查詢章節的最後部分,例如,根據掃 的原理,下面的子查詢語句要比 第二條關聯查詢的效率高:

1. select e.name,e.salary where e.managerid=(select id from employee where name='zxx');

2. select e.name,e.salary,m.name,m.salary from employees e,employees m where e.managerid = m.id and m.name='zxx';

表中容許適當冗餘,譬如,主題帖的回覆數量和最後回覆時間等 將姓名和密碼單獨從用戶表中獨立出來。這能夠是很是好的一對一的案例喲!

sql 語句所有大寫,特別是列名和表名都大寫。特別是 sql 命令的緩存功能,更加須要統一 大小寫,sql 語句 發給 oracle 服務器 語法檢查和編譯成爲內部指令 緩存和執行指令。 根據緩存的特色,不要拼湊條件,而是用?PreparedStatment

還有索引對查詢性能的改進也是值得關注的。 備註:下面是關於性能的討論舉例

4航班 3個城市

m*n

select * from flight,city where flight.startcityid=city.cityid and city.name='beijing'; m+n

select * from flight where startcityid = (select cityid from city where cityname='beijing');

select flight.id,'beijing',flight.flightTime from flight where startcityid = (select cityid from city where cityname='beijing')

 

6union union all 有什麼不一樣?

假設咱們有一個表 Student,包括如下字段與數據: drop table student;

create table student

(

id int primary key,

name nvarchar2(50) not null,

score number not null

);

insert into student values(1,'Aaron',78);

insert into student values(2,'Bill',76);

insert into student values(3,'Cindy',89);

insert into student values(4,'Damon',90);

insert into student values(5,'Ella',73);

insert into student values(6,'Frado',61);

insert into student values(7,'Gill',99);

insert into student values(8,'Hellen',56);

insert into student values(9,'Ivan',93);

insert into student values(10,'Jay',90);

commit;

Union Union All 的區別。

select *

from student

where id < 4

union

select *

from student

where id > 2 and id < 6

結果將是

1 Aaron 78

2 Bill 76

3 Cindy 89

4 Damon 90

5 Ella 73

若是換成 Union All 鏈接兩個結果集,則返回結果是: 1 Aaron 78

2 Bill 76

3 Cindy 89

3 Cindy 89

4 Damon 90

5 Ella 73

能夠看到,Union Union All 的區別之一在於對重複結果的處理。

UNION 在進行表連接後會篩選掉重複的記錄,因此在表連接後會對所產生的結果集進 行排序運算,刪除重複的記錄再返回結果。實際大部分應用中是不會產生重複的記錄,最常 見的是過程表與歷史表 UNION。如:

select * from gc_dfys

union

select * from ls_jg_dfys

這個 SQL 在運行時先取出兩個表的結果,再用排序空間進行排序刪除重複的記錄,最 後返回結果集,若是表數據量大的話可能會致使用磁盤進行排序。

UNION ALL 只是簡單的將兩個結果合併後就返回。這樣,若是返回的兩個結果集中有 重複的數據,那麼返回的結果集就會包含重複的數據了。

從效率上說,UNION ALL 要比 UNION 快不少,因此,若是能夠確認合併的兩個結果集 中不包含重複的數據的話,那麼就使用 UNION ALL,

7.分頁語句

取出 sql 表中第 31 40 的記錄(以自動增加 ID 爲主鍵)

sql server 方案 1:

select top 10 * from t where id not in (select top 30 id from t order by id )

orde by id

sql server 方案 2:

select top 10 * from t where id in (select top 40 id from t order by id) order by id desc

mysql 方案:select * from t order by id limit 30,10

oracle 方案:select * from (select rownum r,* from t where r<=40) where r>30

--------------------待整理進去的內容------------------------------------- pageSize=20;

pageNo = 5;

1.分頁技術 1(直接利用 sql 語句進行分頁,效率最高和最推薦的) mysql:sql = "select * from articles limit " + (pageNo-1)*pageSize + "," + pageSize;

 oracle: sql = "select * from " +

"(select rownum r,* from " +

"(select * from articles order by postime desc)" +

"where rownum<= " + pageNo*pageSize +") tmp " + "where r>" + (pageNo-1)*pageSize;

註釋:7 行保證 rownum 的順序是肯定的,由於 oracle 的索引會形成 rownum 返回不一樣的 值

 簡洋 :沒有 order by ,rownum 按順序輸出,一旦有了 order by,rownum 不按順序輸 出了,這說明 rownum 是排序前的編號。若是對 order by 從句中的字段創建了索引,那麼, rownum 也是按順序輸出的,由於這時候生成原始的查詢結果集時會參照索引表的順序來構 建。

sqlserver:sql = "select top 10 * from id not id(select top " + (pageNo-1)*pageSize + "id from articles)"

DataSource ds = new InitialContext().lookup(jndiurl); Connection cn = ds.getConnection();

//"select * from user where id=?" --->binary directive PreparedStatement pstmt = cn.prepareSatement(sql); ResultSet rs = pstmt.executeQuery()

while(rs.next()) {

out.println(rs.getString(1)); }

2.不可滾動的遊標 pageSize=20; pageNo = 5;

cn = null

stmt = null;

rs = null;

try

{

sqlserver:sql = "select

* from articles";

DataSource ds = new InitialContext().lookup(jndiurl); Connection cn = ds.getConnection();

//"select * from user where id=?" --->binary directive PreparedStatement pstmt = cn.prepareSatement(sql); ResultSet rs = pstmt.executeQuery()

for(int j=0;j<(pageNo-1)*pageSize;j++) {

rs.next(); }

int i=0;

while(rs.next() && i<10) {

i++; out.println(rs.getString(1));

 }

} cacth(){} finnaly

{

if(rs!=null)try{rs.close();}catch(Exception e){} if(stm.........

if(cn............

}

3.可滾動的遊標 pageSize=20; pageNo = 5;

cn = null

stmt = null;

rs = null;

try

{

sqlserver:sql = "select

* from articles";

DataSource ds = new InitialContext().lookup(jndiurl);

Connection cn = ds.getConnection();

//"select * from user where id=?" --->binary directive

PreparedStatement

cn.prepareSatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,...); //根據上面這行代碼的異常 SQLFeatureNotSupportedException,就可判斷驅動是否支持可滾 動遊標

ResultSet rs = pstmt.executeQuery() rs.absolute((pageNo-1)*pageSize) int i=0;

while(rs.next() && i<10)

{

i++;

out.println(rs.getString(1)); }

} cacth(){} finnaly

{

if(rs!=null)try{rs.close();}catch(Exception e){} if(stm.........

if(cn............

}

pstmt =

 8.用一條 SQL 語句 查詢出每門課都大於 80 分的學生姓名

name kecheng fenshu 張三 語文 81 張三 數學 75 李四 語文 76 李四 數學 90 王五 語文 81 王五 數學 100 王五 英語 90

準備數據的 sql 代碼:

create table score(id int primary key auto_increment,name varchar(20),subject varchar(20),score int);

insert into score values

(null,'張三','語文',81),

(null,'張三','數學',75),

(null,'李四','語文',76),

(null,'李四','數學',90),

(null,'王五','語文',81),

(null,'王五','數學',100),

(null,'王五 ','英語',90);

 :當百思不得其解時,請理想思惟,把小變成大作,把大變成小作,

答案:

A: select distinct name from score where name not in (select distinct name from score where score<=80)

B:select distince name t1 from score where 80< all (select score from score where name=t1);

9.全部部門之間的比賽組合

一個叫 department 的表,裏面只有一個字段 name,一共有 4 條紀錄,分別是 a,b,c,d,對應

四個球對,如今四個球對進行比賽,用一條 sql 語句顯示全部可能的比賽組合.

:select a.name, b.name from team a, team b where a.name < b.name

 10.每月份的發生額都比 101 科目多的科目

請用 SQL 語句實現:TestDB 數據表中查詢出全部月份的發生額都比 101 科目相應月份的 發生額高的科目。請注意:TestDB 中有不少科目,都有 1-12 月份的發生額。 AccID:科目代碼,Occmonth:發生額月份,DebitOccur:發生額。 數據庫名:JcyAudit,數據集:Select * from TestDB

準備數據的 sql 代碼:

drop table if exists TestDB;

create table TestDB(id int primary key auto_increment,AccID varchar(20), Occmonth date, DebitOccur bigint);

insert into TestDB values

(null,'101','1988-1-1',100),

(null,'101','1988-2-1',110),

(null,'101','1988-3-1',120),

(null,'101','1988-4-1',100),

(null,'101','1988-5-1',100),

(null,'101','1988-6-1',100),

(null,'101','1988-7-1',100),

(null,'101','1988-8-1',100);

--複製上面的數據,故意把第一個月份的發生額數字改小一點

insert into TestDB values

(null,'102','1988-1-1',90),

(null,'102','1988-2-1',110),

(null,'102','1988-3-1',120),

(null,'102','1988-4-1',100),

(null,'102','1988-5-1',100),

(null,'102','1988-6-1',100),

(null,'102','1988-7-1',100),

(null,'102','1988-8-1',100);

--複製最上面的數據,故意把全部發生額數字改大一點

insert into TestDB values

(null,'103','1988-1-1',150),

(null,'103','1988-2-1',160),

(null,'103','1988-3-1',180),

(null,'103','1988-4-1',120),

(null,'103','1988-5-1',120),

(null,'103','1988-6-1',120),

(null,'103','1988-7-1',120),

(null,'103','1988-8-1',120);

--複製最上面的數據,故意把全部發生額數字改大一點

insert into TestDB values

(null,'104','1988-1-1',130),

(null,'104','1988-2-1',130),

(null,'104','1988-3-1',140),

 (null,'104','1988-4-1',150),

(null,'104','1988-5-1',160),

(null,'104','1988-6-1',170),

(null,'104','1988-7-1',180),

(null,'104','1988-8-1',140); --複製最上面的數據,故意把第二個月份的發生額數字改小一點 insert into TestDB values

(null,'105','1988-1-1',100), (null,'105','1988-2-1',80), (null,'105','1988-3-1',120), (null,'105','1988-4-1',100), (null,'105','1988-5-1',100), (null,'105','1988-6-1',100), (null,'105','1988-7-1',100), (null,'105','1988-8-1',100); 答案:

select distinct AccID from TestDB where AccID not in

(select TestDB.AccIDfrom TestDB,

(select * from TestDB where AccID='101') as db101

where TestDB.Occmonth=db101.Occmonth and TestDB.DebitOccur<=db101.DebitOccur );

11.統計每一年每個月的信息

year month amount 1991 1 1.1 1991 2 1.2 1991 3 1.3

1991 4 1.4

1992 1 2.1

1992 2 2.2 1992 3 2.3 1992 4 2.4 查成這樣一個結果

year m1    m2    m3    m4

1991 1.1 1.2 1.3 1.4

1992 2.1 2.2 2.3 2.4

 :這個與工資條很是相似,與學生的科目成績也很類似。

準備 sql 語句:

drop table if exists sales;

 create table sales(id int auto_increment primary key,year varchar(10), month varchar(10), amount float(2,1));

insert into sales values

(null,'1991','1',1.1),

(null,'1991','2',1.2),

(null,'1991','3',1.3),

(null,'1991','4',1.4),

(null,'1992','1',2.1),

(null,'1992','2',2.2),

(null,'1992','3',2.3),

(null,'1992','4',2.4);

答案1、

select sales.year ,

(select t.amount from sales t where t.month='1' and t.year= sales.year) '1', (select t.amount from sales t where t.month='1' and t.year= sales.year) '2', (select t.amount from sales t where t.month='1' and t.year= sales.year) '3', (select t.amount from sales t where t.month='1' and t.year= sales.year) as '4' from sales group by year;

12.顯示文章標題,發帖人、最後回覆時間

:id,title,postuser,postdate,parentid

準備 sql 語句:

drop table if exists articles;

create table articles(id int auto_increment primary key,title varchar(50), postuser varchar(10), postdate datetime,parentid int references articles(id));

insert into articles values (null,'第一條','張三','1998-10-10 12:32:32',null), (null,'第二條','張三','1998-10-10 12:34:32',null), (null,'第一條回覆 1','李四','1998-10-10 12:35:32',1), (null,'第二條回覆 1','李四','1998-10-10 12:36:32',2), (null,'第一條回覆 2','王五','1998-10-10 12:37:32',1), (null,'第一條回覆 3','李四','1998-10-10 12:38:32',1), (null,'第二條回覆 2','李四','1998-10-10 12:39:32',2), (null,'第一條回覆 4','王五','1998-10-10 12:39:40',1);

答案:

select a.title,a.postuser,

(select max(postdate) from articles where parentid=a.id) reply

from articles a where a.parentid is null;

註釋:子查詢能夠用在選擇列中,也可用於 where 的比較條件中,還能夠用於 from 從句中。

 13.刪除除了 id 號不一樣,其餘都相同的學生冗餘信息

2.學生表 以下:

id號 學號 姓名課程編號課程名稱分數

1 2005001 張三 0001 數學 69

2 2005002 李四 0001 數學 89

3 2005001 張三 0001 數學 69

A: delete from tablename where id not in(select min(id ) from tablename group by 學號,姓 名,課程編號,課程名稱,分數)

實驗:

create table student2(id int auto_increment primary key,code varchar(20),name varchar(20)); insert into student2 values(null,'2005001','張三'),(null,'2005002','李四'),(null,'2005001','張三');

//以下語句,mysql 報告錯誤,可能刪除依賴後面統計語句,而刪除又致使統計語句結果不 一致。

delete from student2 where id not in(select min(id) from student2 group by name); //可是,以下語句沒有問題:

select * from student2 where id not in(select min(id) from student2 group by name); //因而,我想先把分組的結果作成虛表,而後從虛表中選出結果,最後再將結果做爲刪除的 條件數據。

delete from student2 where id not in(select mid from (select min(id) mid from student2 group by name) as t);

或者:

delete from student2 where id not in(select min(id) from (select * from s tudent2) as t group by t.name);

14.航空網的幾個航班查詢題:

表結構以下:

flight{flightID,StartCityID ,endCityID,StartTime}

city{cityID, CityName)

實驗環境:

create table city(cityID int auto_increment primary key,cityName varchar(20)); create table flight (flightID int auto_increment primary key,

StartCityID int references city(cityID), endCityID int references city(cityID), StartTime timestamp);

//航班原本應該沒有日期部分纔好,可是下面的題目當中涉及到了日期 insert into city values(null,'北京'),(null,'上海'),(null,'廣州');

insert into flight values

(null,1,2,'9:37:23'),(null,1,3,'9:37:23'),(null,1,2,'10:37:23'),(null,2,3,'10:37:23');

 1、查詢起飛城市是北京的全部航班,按到達城市的名字排序

參與運算的列是我起碼可以顯示出來的那些列,但最終我不必定把它們顯示出來。各個表組 合出來的中間結果字段中必須包含全部運算的字段。

select * from flight f,city c

where f.endcityid = c.cityid and startcityid =

(select c1.cityid from city c1 where c1.cityname = "北京") order by c.cityname asc;

mysql> select flight.flightid,'北京' startcity, e.cityname from flight,city e wh ere flight.endcityid=e.cityid and flight.startcityid=(select cityid from city wh ere cityname='北京');

mysql> select flight.flightid,s.cityname,e.cityname from flight,city s,city e wh ere flight.startcityid=s.cityid and s.cityname='北京' and flight.endCityId=e.cit yID order by e.cityName desc;

2、查詢北京到上海的全部航班紀錄(起飛城市,到達城市,起飛時間,航班號) select c1.CityName,c2.CityName,f.StartTime,f.flightID

from city c1,city c2,flight f

where f.StartCityID=c1.cityID

and f.endCityID=c2.cityID

and c1.cityName='北京'

and c2.cityName='上海' 3、查詢具體某一天(2005-5-8)的北京到上海的的航班次數 select count(*) from

(select c1.CityName,c2.CityName,f.StartTime,f.flightID from city c1,city c2,flight f

where f.StartCityID=c1.cityID

and f.endCityID=c2.cityID

and c1.cityName='北京'

and c2.cityName='上海'

and 查幫助得到的某個日期處理函數(startTime) like '2005-5-8%'

mysql 中 取日期部分進行比較的示例代碼以下:

select * from flight where date_format(starttime,'%Y-%m-%d')='1998-01-02'

15.查出比經理薪水還高的員工信息: Drop table if not exists employees;

 create table employees(id int primary key auto_increment,name varchar(50) ,salary int,managerid int references employees(id));

insert into employees values (null,' lhm',10000,null), (null,' zxx',15000,1 ),(null,'flx',9000,1),(null,'tg',10000,2),(null,'wzg',10000,3);

Wzg 大於 flx,lhm 大於 zxx

解題思路:

根據 sql 語句的查詢特色,是逐行進行運算,不可能兩行同時參與運算。

涉及了員工薪水和經理薪水,全部,一行記錄要同時包含兩個薪水,全部想到要把這個表自 關聯組合一下。

首先要組合出一個包含有各個員工及該員工的經理信息的長記錄,譬如,左半部分是 員工,右半部分是經理。而迪卡爾積會組合出不少垃圾信息,先去除這些垃圾信息。

select e.* from employees e,employees m where e.managerid=m.id and e.sala ry>m.salary;

16、求出小於 45 歲的各個老師所帶的大於 12 歲的學生人數

數據庫中有 3 個表 teacher ,student ,tea_stu 關係表。 teacher teaID name age

student stuID name age

teacher_student teaID stuID

要求用一條 sql 查詢出這樣的結果

1.顯示的字段要有老師 name, age 每一個老師所帶的學生人數 2 只列出老師 age 40 如下,學生 age 12 以上的記錄

預備知識:

1.sql 語句是對每一條記錄依次處理,條件爲真則執行動做(select,insert,delete,update)

2.只要是迪卡爾積,就會產生「垃圾」信息,因此,只要迪卡爾積了,咱們首先就要想到清除「垃圾」信息 實驗準備:

drop table if exists tea_stu; drop table if exists teacher; drop table if exists student;

create table teacher(teaID int primary key,name varchar(50),age int);

create table student(stuID int primary key,name varchar(50),age int);

create table tea_stu(teaID int references teacher(teaID),stuID int references student(stuID));

insert into teacher values(1,'zxx',45), (2,'lhm',25) , (3,'wzg',26) , (4,'tg',27); insert into student values(1,'wy',11), (2,'dh',25) , (3,'ysq',26) , (4,'mxc',27); insert into tea_stu values(1,1), (1,2), (1,3);

insert into tea_stu values(2,2), (2,3), (2,4);

insert into tea_stu values(3,3), (3,4), (3,1); insert into tea_stu values(4,4), (4,1), (4,2) , (4,3);

結果:2 3,3 2,4 3

 解題思路:(真實面試答題時,也要寫出每一個分析步驟,若是紙張不夠,就找別人要) 1 要會統計分組信息,統計信息放在中間表中:

select teaid,count(*) from tea_stu group by teaid;

2 接着其實應該是篩除掉小於 12 歲的學生,而後再進行統計,中間表必須與 student 關聯才能獲得 12 歲如下學 生和把該學生記錄從中間表中剔除,代碼是:

select tea_stu.teaid,count(*) total from student,tea_stu

where student.stuid=tea_stu.stuid and student.age>12 group by tea_stu.teaid

3.接着把上面的結果作成虛表與 teacher 進行關聯,並篩除大於 45 的老師

select teacher.teaid,teacher.name,total from teacher ,(select tea_stu.tea

id,count(*) total from student,tea_stu where student.stuid=tea_stu.stuid and stu dent.age>12 group by tea_stu.teaid) as tea_stu2 where teacher.teaid=tea_stu2.tea id and teacher.age<45;

17.求出發帖最多的人:

select authorid,count(*) total from articles group by authorid

having total=

(select max(total2) from (select count(*) total2 from articles group by authorid) as t);

select t.authorid,max(t.total) from

(select authorid,count(*) total from articles )as t 這條語句不行,由於 max 只有一列,不能與其餘列混淆。

select authorid,count(*) total from articles

group by authorid having total=max(total)也不行。

18、一個用戶表中有一個積分字段,假如數據庫中有 100 多 萬個用戶,若要在每一年第一天凌晨將積分清零,你將考慮什 麼,你將想什麼辦法解決?

alter table drop column score;

alter table add colunm score int; 可能會很快,可是須要試驗,試驗不能拿真實的環境來操刀,而且要注意, 這樣的操做時沒法回滾的,在個人印象中,只有 inert update delete DML 語句才能回滾,

 對於 create table,drop table ,alter table DDL 語句是不能回滾。

解決方案一,update user set score=0; 解決方案二,假設上面的代碼要執行好長時間,超出咱們的容忍範圍,那我就 alter table user drop column score;alter table user add column score int

下面代碼實現每一年的那個凌晨時刻進行清零。

Runnable runnable = new Runnable(){

public void run(){ clearDb();

schedule(this,new Date(new Date().getYear()+1,0,0)); }

};

schedule(runnable,

new Date(new Date().getYear()+1,0,1));

19、一個用戶具備多個角色,請查詢出該表中具備該用戶的 全部角色的其餘用戶。

select count(*) as num,tb.id from

tb,

(select role from tb where id=xxx) as t1 where

tb.role = t1.role and tb.id != t1.id group by tb.id

having

num = select count(role) from tb where id=xxx;

20. xxx 公司的 sql 面試 Table EMPLOYEES Structure:

EMPLOYEE_ID FIRST_NAME LAST_NAME

Salary number(8,2), HiredDate DATE, Departmentid number(2)

Table Departments Structure:

Departmentid number(2) Primary Key,

NUMBER VARCHAR2(25),

VARCHAR2(25),

Primary Key,

DepartmentName VARCHAR2(25).

(2)基於上述 EMPLOYEES 表寫出查詢:寫出僱用日期在今年的,或者工資在[1000,2000] 之間的,或者員工姓名(last_name)以’Obama’打頭的全部員工,列出這些員工的所有我的

信息。(4 )

select * from employees

where Year(hiredDate) = Year(date())

or (salary between 1000 and 200) or left(last_name,3)='abc';

(3) 基於上述 EMPLOYEES 表寫出查詢:查出部門平均工資大於 1800 元的部門的全部員工, 列出這些員工的所有我的信息。(4 )

mysql> select id,name,salary,deptid did from employee1 where (select avg(salary)

from employee1 where deptid = did) > 1800;

(4) 基於上述 EMPLOYEES 表寫出查詢:查出我的工資高於其所在部門平均工資的員工, 列出這些員工的所有我的信息及該員工工資高出部門平均工資百分比。(5 )

select employee1.*,(employee1.salary-t.avgSalary)*100/employee1.salary from employee1,

(select deptid,avg(salary) avgSalary from employee1 group by deptid) as t where employee1.deptid = t.deptid and employee1.salary>t.avgSalary;

21、註冊 Jdbc 驅動程序的三種方式

22、用 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();

} }

}

23JDBC 中的 PreparedStatement 相比 Statement 的好處

:一個 sql 命令發給服務器去執行的步驟爲:語法檢查,語義分析,編譯成內部指令,緩 存指令,執行指令等過程。

select * from student where id =3----緩存-- xxxxx 二進制命令

select * from student where id =3----直接取- xxxxx 二進制命令

select * from student where id =4--- - 會怎麼幹?

 若是當初是 select * from student where id =?--- - 又會怎麼幹? 上面說的是性能 高

能夠防止 sql 注入。

24. 寫一個用 jdbc 鏈接並訪問 oracle 數據的程序代碼

25Class.forName 的做用?爲何要用?

:按參數中指定的字符串形式的類名去搜索並加載相應的類,若是該類字節碼已經被加載 過,則返回表明該字節碼的 Class 實例對象,不然,按類加載器的委託機制去搜索和加載該 類,若是全部的類加載器都沒法加載到該類,則拋出 ClassNotFoundException。加載完這個 Class 字節碼後,接着就能夠使用 Class 字節碼的 newInstance 方法去建立該類的實例對象了。 有時候,咱們程序中全部使用的具體類名在設計時(即開發時)沒法肯定,只有程序運行時 才能肯定,這時候就須要使用 Class.forName 去動態加載該類,這個類名一般是在配置文件 中配置的,例如,spring ioc 中每次依賴注入的具體類就是這樣配置的,jdbc 的驅動類名 一般也是經過配置文件來配置的,以便在產品交付使用後不用修改源程序就能夠更換驅動類 名。

26、大數據量下的分頁解決方法。

:最好的辦法是利用 sql 語句進行分頁,這樣每次查詢出的結果集中就只包含某頁的數據 內容。再 sql 語句沒法實現分頁的狀況下,能夠考慮對大的結果集經過遊標定位方式來獲取 某頁的數據。

sql 語句分頁,不一樣的數據庫下的分頁方案各不同,下面是主流的三種數據庫的分頁 sql: sql server:

String sql =

"select top " + pageSize + " * from students where id not in" +

"(select top " + pageSize * (pageNumber-1) + " id from students order by id)" +

"order by id"; mysql:

String sql =

"select * from students order by id limit " + pageSize*(pageNumber-1) + "," + pageSize;

oracle:

String sql =

"select * from " +

(select *,rownum rid from (select * from students order by postime desc) where rid<=" +

 pagesize*pagenumber + ") as t" +

"where t>" + pageSize*(pageNumber-1);

27、用 JDBC 查詢學生成績單, 把主要代碼寫出來(考試概 率極大).

Connection cn = null; PreparedStatement pstmt =null; Resultset rs = null;

try

{

Class.forname(driveClassName);

cn = DriverManager.getConnection(url,username,password);

pstmt = cn.prepareStatement(select score.* from score ,student +

where score.stuId = student.id and student.name = ?); pstmt.setString(1,studentName);

Resultset rs = pstmt.executeQuery();

while(rs.next())

{

}

}catch(Exception e){e.printStackTrace();} finally

{

system.out.println(rs.getInt(subject)

+

+ rs.getFloat(score) );

if(rs != null) try{ rs.close() }catch(exception e){} if(pstmt != null) try{pstmt.close()}catch(exception e){} if(cn != null) try{ cn.close() }catch(exception e){}

}

28、這段代碼有什麼不足之處?

try {

Connection conn = ...;

Statement stmt = ...;

ResultSet rs = stmt.executeQuery("select * from table1");

while(rs.next()) {

}

} catch(Exception ex) {

}

:沒有 finally 語句來關閉各個對象,另外,使用 finally 以後,要把變量的 定義放在 try 語句塊的外面,以便在 try 語句塊以外的 finally 塊中仍能夠訪問 這些變量。

29、說出數據鏈接池的工做機制是什麼?

J2EE 服務器啓動時會創建必定數量的池鏈接,並一直維持很多於此數目的池鏈接。客 戶端程序須要鏈接時,池驅動程序會返回一個未使用的池鏈接並將其表記爲忙。若是 當前沒有空閒鏈接,池驅動程序就新建必定數量的鏈接,新建鏈接的數量有配置參數 決定。當使用的池鏈接調用完成後,池驅動程序將此鏈接表記爲空閒,其餘調用就可 以使用這個鏈接。

實現方式,返回的 Connection 是原始 Connection 的代理,代理 Connection close 方法 不是真正關鏈接,而是把它代理的 Connection 對象還回到鏈接池中。

30、爲何要用 ORM? JDBC 有何不同?

orm 是一種思想,就是把 object 轉變成數據庫中的記錄,或者把數據庫中的記錄轉變成 objecdt,咱們能夠用 jdbc 來實現這種思想,其實,若是咱們的項目是嚴格按照 oop 方 式編寫的話,咱們的 jdbc 程序無論是有意仍是無心,就已經在實現 orm 的工做了。

如今有許多 orm 工具,它們底層調用 jdbc 來實現了 orm 工做,咱們直接使用這些工具, 就省去了直接使用 jdbc 的繁瑣細節, 高了開發效率,如今用的較多的 orm 工具是 hibernate。也據說一些其餘 orm 工具,toplink,ojb 等。

. XML 部分

1xml 有哪些解析技術?區別是什麼?

:DOM,SAX,STAX

DOM:處理大型文件時其性能降低的很是厲害。這個問題是由 DOM 的樹結構所形成的,這 種結構佔用的內存較多,並且 DOM 必須在解析文件以前把整個文檔裝入內存,適合對 XML 的隨機訪問 SAX:不現於 DOM,SAX 是事件驅動型的 XML 解析方式。它順序讀取 XML 文 件,不須要一次所有裝載整個文件。當遇到像文件開頭,文檔結束,或者標籤開頭與標籤結 束時,它會觸發一個事件,用戶經過在其回調事件中寫入處理代碼來處理 XML 文件,適合 對 XML 的順序訪問

STAX:Streaming API for XML (StAX)

 講解這些區別是不須要特別去比較,就像說傳智播客與其餘培訓機構的區別時,咱們只需說 清楚傳智播客有什麼特色和優勢就好了,這就已經間接回答了彼此的區別。

2、你在項目中用到了 xml 技術的哪些方面?如何實現的?

:用到了數據存貯,信息配置兩方面。在作數據交換平臺時,將不能數據源的數據組裝成 XML 文件,而後將 XML 文件壓縮打包加密後經過網絡傳送給接收者,接收解密與解壓縮 後再同 XML 文件中還原相關信息進行處理。在作軟件配置時,利用 XML 能夠很方便的進 行,軟件的各類配置參數都存貯在 XML 文件中。

3、用 jdom 解析 xml 文件時如何解決中文問題?如何解析?

:看以下代碼,用編碼方式加以解決 package test;

import java.io.*;

public class DOMTest

{

private String inFile = "c:\\people.xml"

private String outFile = "c:\\people.xml"

public static void main(String args[])

{

new DOMTest();

}

public DOMTest()

{

try

{

javax.xml.parsers.DocumentBuilder builder = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder(); org.w3c.dom.Document doc = builder.newDocument();

org.w3c.dom.Element root = doc.createElement("老師");

org.w3c.dom.Element wang = doc.createElement("");

org.w3c.dom.Element liu = doc.createElement(""); wang.appendChild(doc.createTextNode("我是王老師"));

root.appendChild(wang);

doc.appendChild(root);

javax.xml.transform.Transformer transformer = javax.xml.transform.TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, "gb2312"); transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes"); transformer.transform(new javax.xml.transform.dom.DOMSource(doc),

new

 javax.xml.transform.stream.StreamResult(outFile)); }

catch (Exception e)

{

System.out.println (e.getMessage()); }

}

}

4、編程用 JAVA 解析 XML 的方式.

:SAX 方式解析 XML,XML 文件以下:

<?xml version=1.0 encoding=gb2312?>

<person>

<name>王小明</name>

<college>信息學院</college> <telephone>6258113</telephone>

<notes>,1955 年生,博士,95 年調入海南大學</notes> </person>

事件回調類 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:

<HTML>

<HEAD>

<TITLE>剖析 XML 文件 people.xml</TITLE>

</HEAD>

<BODY>

<%@ 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(<TABLE BORDER=2><CAPTION>教師信息表</CAPTION>); out.println(<TR><TD>姓名</TD> + <TD> +

(String)hashTable.get(new String(name)) + </TD></TR>); out.println(<TR><TD>學院</TD> + <TD> +

(String)hashTable.get(new String(college))+</TD></TR>); out.println(<TR><TD>電話</TD> + <TD> +

(String)hashTable.get(new String(telephone)) + </TD></TR>); out.println(<TR><TD>備註</TD> + <TD> +

(String)hashTable.get(new String(notes)) + </TD></TR>); out.println(</TABLE>);

%>

</BODY> </HTML>

5XML 文檔定義有幾種形式?它們之間有何本質區別?解 析 XML 文檔有哪幾種方式?

a: 兩種形式 dtd schema,b: 本質區別:schema 自己是 xml ,能夠被 XML 解析器解 析(這也是從 DTD 上發展 schema 的根本目的),c:DOM,SAX,STAX

DOM:處理大型文件時其性能降低的很是厲害。這個問題是由 DOM 的樹結構所形成 的,這種結構佔用的內存較多,並且 DOM 必須在解析文件以前把整個文檔裝入內存, 適合對 XML 的隨機訪問

SAX:不現於 DOM,SAX 是事件驅動型的 XML 解析方式。它順序讀取 XML 文件,不需 要一次所有裝載整個文件。當遇到像文件開頭,文檔結束,或者標籤開頭與標籤結束 時,它會觸發一個事件,用戶經過在其回調事件中寫入處理代碼來處理 XML 文件, 適合對 XML 的順序訪問

STAX:Streaming API for XML (StAX)

 

6、框架部分

1、什麼是ORM

答:

a.對象關係映射(Object-Relational Mapping,簡稱ORM)是一種爲了解決程序的面向對象模型與數據庫的關係模型互不匹配問題的技術.

b.實體中的屬性和數據庫表中列經過xml或註解來完成映射。正向工程:根據實體生成表,逆向工程:根據表生成實體。

2、持久層設計要考慮的問題有哪些?你用過的持久層框架有哪些?

答:

a.所謂"持久"就是將數據保存到可掉電式存儲設備中以便從此使用。就是將內存中的數據保存到關係型數據庫、文件系統、消息隊列等提供持久化支持的設備中。

b.持久層就是系統中專一於實現數據持久化的相對獨立的層面。

持久層設計的目標包括: dao- 數據存儲邏輯的分離,提供抽象化的數據訪問接口。 - 數據訪問底層實現的分離,能夠在不修改代碼的狀況下切換底層實現。 - 資源管理和調度的分離,在數據訪問層實現統一的資源調度(如緩存機制)。 - 數據抽象,提供更面向對象的數據操做。

 

持久層框架有:

Hibernate 

MyBatis 

Spring Data 

ActiveJDBC

 

3HibernateSessionFactory是線程安全的嗎?Session是線程安全的嗎(兩個線程可以共享同一個Session嗎)?

答:

a.SessionFactory對應Hibernate的一個數據存儲的概念,它是線程安全的,能夠被多個線程併發訪問。SessionFactory通常只會在啓動的時候構建。對於應用程序,最好將SessionFactory經過單例模式進行封裝以便於訪問。

Session是一個輕量級非線程安全的對象(線程間不能共享session),它表示與數據庫進行交互的一個工做單元。Session是由SessionFactory建立的,在任務完成以後它會被關閉。Session是持久層服務對外提供的主要接口。Session會延遲獲取數據庫鏈接(也就是在須要的時候纔會獲取)。爲了不建立太多的session,能夠使用ThreadLocalsession和當前線程綁定在一塊兒,這樣可讓同一個線程得到的老是同一個sessionHibernate 3SessionFactorygetCurrentSession()方法就能夠作到。

 

4HibernateSessionloadget方法的區別是什麼?

① 若是沒有找到符合條件的記錄,get方法返回nullload方法拋出異常。 
② get方法直接返回實體類對象,load方法返回實體類對象的代理。 
③ 在Hibernate 3以前,get方法只在一級緩存中進行數據查找,若是沒有找到對應的數據則越過二級緩存,直接發出SQL語句完成數據讀取;load方法則能夠從二級緩存中獲取數據;從Hibernate 3開始,get方法再也不是對二級緩存只寫不讀,它也是能夠訪問二級緩存的。

 

說明:對於load()方法Hibernate認爲該數據在數據庫中必定存在能夠放心的使用代理來實現延遲加載,若是沒有數據就拋出異常,而經過get()方法獲取的數據能夠不存在。

 

5Sessionsave()update()merge()lock()saveOrUpdate()persist()方法分別是作什麼的?有什麼區別?

 

答:Hibernate的對象有三種狀態:瞬時態(transient)、持久態(persistent)和遊離態(detached

把圖畫出來。

 

瞬時態的實例能夠經過調用save()persist()或者saveOrUpdate()方法變成持久態;

遊離態的實例能夠經過調用 update()saveOrUpdate()lock()或者replicate()變成持久態。save()persist()將會引起SQLINSERT語句,而update()merge()會引起UPDATE語句。save()update()的區別在於一個是將瞬時態對象變成持久態,一個是將遊離態對象變爲持久態。merge()方法能夠完成save()update()方法的功能,它的意圖是將新的狀態合併到已有的持久化對象上或建立新的持久化對象。

對於persist()方法,按照官方文檔的說明:① persist()方法把一個瞬時態的實例持久化,可是並不保證標識符被馬上填入到持久化實例中,標識符的填入可能被推遲到flush的時間;② persist()方法保證當它在一個事務外部被調用的時候並不觸發一個INSERT語句,當須要封裝一個長會話流程的時候,persist()方法是頗有必要的;③ save()方法不保證第②條,它要返回標識符,因此它會當即執行INSERT語句,無論是在事務內部仍是外部。至於lock()方法和update()方法的區別,update()方法是把一個已經更改過的脫管狀態的對象變成持久狀態;lock()方法是把一個沒有更改過的脫管狀態的對象變成持久狀態。

 

6、闡述Session加載實體對象的過程。 

 

答:Session加載實體對象的步驟是: 
① Session在調用數據庫查詢功能以前,首先會在一級緩存中經過實體類型和主鍵進行查找,若是一級緩存查找命中且數據狀態合法,則直接返回; 
② 若是一級緩存沒有命中,接下來Session會在當前NonExists記錄(至關於一個查詢黑名單,若是出現重複的無效查詢能夠迅速作出判斷,從而提高性能)中進行查找,若是NonExists中存在一樣的查詢條件,則返回null 
③ 若是一級緩存查詢失敗則查詢二級緩存,若是二級緩存命中則直接返回; 
④ 若是以前的查詢都未命中,則發出SQL語句,若是查詢未發現對應記錄則將這次查詢添加到SessionNonExists中加以記錄,並返回null 
⑤ 根據映射配置和SQL語句獲得ResultSet,並建立對應的實體對象; 
⑥ 將對象歸入Session(一級緩存)的管理; 
⑦ 若是有對應的攔截器,則執行攔截器的onLoad方法; 
⑧ 若是開啓並設置了要使用二級緩存,則將數據對象歸入二級緩存; 
⑨ 返回數據對象。

 

7Query接口的list方法和iterate方法有什麼區別? 

答: 
① list()方法沒法利用一級緩存和二級緩存(對緩存只寫不讀),它只能在開啓查詢緩存的前提下使用查詢緩存;iterate()方法能夠充分利用緩存,若是目標數據只讀或者讀取頻繁,使用iterate()方法能夠減小性能開銷。 
② list()方法不會引發N+1查詢問題,而iterate()方法可能引發N+1查詢問題

 

8.什麼是HibernateN+1問題

http://blog.csdn.net/xtayhicbladwin/article/details/4739852

 

9Hibernate如何實現分頁查詢? 

 

答:經過Hibernate實現分頁查詢,開發人員只須要提供HQL語句(調用SessioncreateQuery()方法)或查詢條件(調用SessioncreateCriteria()方法)、設置查詢起始行數(調用QueryCriteria接口的setFirstResult()方法)和最大查詢行數(調用QueryCriteria接口的setMaxResults()方法),並調用QueryCriteria接口的list()方法,Hibernate會自動生成分頁查詢的SQL語句。

 

setFirstResult()設置查詢起始行數

setMaxResults()最大查詢行

 

10、鎖機制有什麼用?簡述Hibernate的悲觀鎖和樂觀鎖機制。

答:有些業務邏輯在執行過程當中要求對數據進行排他性的訪問,因而須要經過一些機制保證在此過程當中數據被鎖住不會被外界修改,這就是所謂的鎖機制。 

Hibernate支持悲觀鎖和樂觀鎖兩種鎖機制。

 

悲觀鎖,顧名思義悲觀的認爲在數據處理過程當中極有可能存在修改數據的併發事務(包括本系統的其餘事務或來自外部系統的事務),因而將處理的數據設置爲鎖定狀態。悲觀鎖必須依賴數據庫自己的鎖機制才能真正保證數據訪問的排他性。

 

樂觀鎖,顧名思義,對併發事務持樂觀態度(認爲對數據的併發操做不會常常性的發生),經過更加寬鬆的鎖機制來解決因爲悲觀鎖排他性的數據訪問對系統性能形成的嚴重影響。最多見的樂觀鎖是經過數據版本標識來實現的,讀取數據時得到數據的版本號,更新數據時將此版本號加1,而後和數據庫表對應記錄的當前版本號進行比較,若是提交的數據版本號大於數據庫中此記錄的當前版本號則更新數據,不然認爲是過時數據沒法更新。Hibernate中經過Sessionget()load()方法從數據庫中加載對象時能夠經過參數指定使用悲觀鎖;而樂觀鎖能夠經過給實體類加整型的版本字段再經過XML@Version註解進行配置。

提示:使用樂觀鎖會增長了一個版本字段,很明顯這須要額外的空間來存儲這個版本字段,浪費了空間,可是樂觀鎖會讓系統具備更好的併發性,這是對時間的節省。所以樂觀鎖也是典型的空間換時間的策略。

 

11、如何理解Hibernate的延遲加載機制?在實際應用中,延遲加載與Session關閉的矛盾是如何處理的? 

答:延遲加載就是並非在讀取的時候就把數據加載進來,而是等到使用時再加載。

Hibernate使用了虛擬代理機制實現延遲加載,咱們使用Sessionload()方法加載數據或者一對多關聯映射在使用延遲加載的狀況下從一的一方加載多的一方,獲得的都是虛擬代理,簡單的說返回給用戶的並非實體自己,而是實體對象的代理。代理對象在用戶調用getter方法時纔會去數據庫加載數據。但加載數據就須要數據庫鏈接。而當咱們把會話關閉時,數據庫鏈接就同時關閉了。

 

延遲加載與session關閉的矛盾通常能夠這樣處理: 
① 關閉延遲加載特性。這種方式操做起來比較簡單,由於Hibernate的延遲加載特性是能夠經過映射文件或者註解進行配置的,但這種解決方案存在明顯的缺陷。首先,出現"no session or session was closed"一般說明系統中已經存在主外鍵關聯,若是去掉延遲加載的話,每次查詢的開銷都會變得很大。 
② 在session關閉以前先獲取須要查詢的數據,能夠使用工具方法Hibernate.isInitialized()判斷對象是否被加載,若是沒有被加載則能夠使用Hibernate.initialize()方法加載對象。 
③ 使用攔截器或過濾器延長Session的生命週期直到視圖得到數據。Spring整合Hibernate提供的OpenSessionInViewFilterOpenSessionInViewInterceptor就是這種作法。

 

12、舉一個多對多關聯的例子,並說明如何實現多對多關聯映射。

答:例如:商品和訂單、學生和課程都是典型的多對多關係。能夠在實體類上經過@ManyToMany註解配置多對多關聯或者經過映射文件中的和標籤配置多對多關聯,可是實際項目開發中,不少時候都是將多對多關聯映射轉換成兩個多對一關聯映射來實現的。

 

13、談一下你對繼承映射的理解。

答:繼承關係的映射策略有三種: 
① 每一個繼承結構一張表(table per class hierarchy),無論多少個子類都用一張表。 
② 每一個子類一張表(table per subclass),公共信息放一張表,特有信息放單獨的表。 
③ 每一個具體類一張表(table per concrete class),有多少個子類就有多少張表。 
第一種方式屬於單表策略,其優勢在於查詢子類對象的時候無需錶鏈接,查詢速度快,適合多態查詢;缺點是可能致使表很大。後兩種方式屬於多表策略,其優勢在於數據存儲緊湊,其缺點是須要進行鏈接查詢,不適合多態查詢。

 

14、簡述Hibernate常見優化策略。

 

答:這個問題應當挑本身使用過的優化策略回答,經常使用的有: 
① 制定合理的緩存策略(二級緩存、查詢緩存)。 
② 採用合理的Session管理機制。 
③ 儘可能使用延遲加載特性。 
④ 設定合理的批處理參數。 
⑤ 若是能夠,選用UUID做爲主鍵生成器。 
⑥ 若是能夠,選用基於版本號的樂觀鎖替代悲觀鎖。 
⑦ 在開發過程當中, 開啓hibernate.show_sql選項查看生成的SQL,從而瞭解底層的情況;開發完成後關閉此選項。
⑧ 考慮數據庫自己的優化,合理的索引、恰當的數據分區策略等都會對持久層的性能帶來可觀的提高,但這些須要專業的DBA(數據庫管理員)提供支持。

 

15、談一談Hibernate的一級緩存、二級緩存和查詢緩存。

答:HibernateSession提供了一級緩存的功能,默認老是有效的,當應用程序保存持久化實體、修改持久化實體時,Session並不會當即把這種改變提交到數據庫,而是緩存在當前的Session中,除非顯示調用了Sessionflush()方法或經過close()方法關閉Session。經過一級緩存,能夠減小程序與數據庫的交互,從而提升數據庫訪問性能。 SessionFactory級別的二級緩存是全局性的,全部的Session能夠共享這個二級緩存。不過二級緩存默認是關閉的,須要顯示開啓並指定須要使用哪一種二級緩存實現類(能夠使用第三方提供的實現)。一旦開啓了二級緩存並設置了須要使用二級緩存的實體類,SessionFactory就會緩存訪問過的該實體類的每一個對象,除非緩存的數據超出了指定的緩存空間。 
一級緩存和二級緩存都是對整個實體進行緩存,不會緩存普通屬性,若是但願對普通屬性進行緩存,能夠使用查詢緩存。查詢緩存是將HQLSQL語句以及它們的查詢結果做爲鍵值對進行緩存,對於一樣的查詢能夠直接從緩存中獲取數據。查詢緩存默認也是關閉的,須要顯示開啓。

 

16HibernateDetachedCriteria類是作什麼的?

答:DetachedCriteriaCriteria的用法基本上是一致的,但Criteria是由SessioncreateCriteria()方法建立的,也就意味着離開建立它的SessionCriteria就沒法使用了。DetachedCriteria不須要Session就能夠建立(使用DetachedCriteria.forClass()方法建立),因此一般也稱其爲離線的Criteria,在須要進行查詢操做的時候再和Session綁定(調用其getExecutableCriteria(Session)方法),這也就意味着一個DetachedCriteria能夠在須要的時候和不一樣的Session進行綁定。

 

17@OneToMany註解的mappedBy屬性有什麼做用?

答:@OneToMany用來配置一對多關聯映射,但一般狀況下,一對多關聯映射都由多的一方來維護關聯關係,例如學生和班級,應該在學生類中添加班級屬性來維持學生和班級的關聯關係(在數據庫中是由學生表中的外鍵班級編號來維護學生表和班級表的多對一關係),若是要使用雙向關聯,在班級類中添加一個容器屬性來存放學生,並使用@OneToMany註解進行映射,此時mappedBy屬性就很是重要。若是使用XML進行配置,能夠用<set>標籤的inverse="true"設置來達到一樣的效果。

 

 

18MyBatis中使用#$書寫佔位符有什麼區別? 

答:#將傳入的數據都當成一個字符串,會對傳入的數據自動加上引號;$將傳入的數據直接顯示生成在SQL中。注意:使用$佔位符可能會致使SQL注入攻擊,能用#的地方就不要使用$,寫order by子句的時候應該用$而不是#

 

19、解釋一下MyBatis中命名空間(namespace)的做用。 
答:在大型項目中,可能存在大量的SQL語句,這時候爲每一個SQL語句起一個惟一的標識(ID)就變得並不容易了。爲了解決這個問題,在MyBatis中,能夠爲每一個映射文件起一個惟一的命名空間,這樣定義在這個映射文件中的每一個SQL語句就成了定義在這個命名空間中的一個ID。只要咱們可以保證每一個命名空間中這個ID是惟一的,即便在不一樣映射文件中的語句ID相同,也不會再產生衝突了。

 

20MyBatis中的動態SQL是什麼意思? 

答:對於一些複雜的查詢,咱們可能會指定多個查詢條件,可是這些條件可能存在也可能不存在,例如在58同城上面找房子,咱們可能會指定面積、樓層和所在位置來查找房源,也可能會指定面積、價格、戶型和所在位置來查找房源,此時就須要根據用戶指定的條件動態生成SQL語句。若是不使用持久層框架咱們可能須要本身拼裝SQL語句,還好MyBatis提供了動態SQL的功能來解決這個問題。

 

MyBatis中用於實現動態SQL的元素主要有: - if - choose / when / otherwise - trim - where - set - foreach

下面是映射文件的片斷。

    <select id="foo" parameterType="Blog" resultType="Blog">

        select * from t_blog where 1 = 1

        <if test="title != null">

            and title = #{title}

        </if>

        <if test="content != null">

            and content = #{content}

        </if>

        <if test="owner != null">

            and owner = #{owner}

        </if>

   </select>

固然也能夠像下面這些書寫。

    <select id="foo" parameterType="Blog" resultType="Blog">

        select * from t_blog where 1 = 1

        <choose>

            <when test="title != null">

                and title = #{title}

            </when>

            <when test="content != null">

                and content = #{content}

            </when>

            <otherwise>

                and owner = "owner1"

            </otherwise>

        </choose>

    </select>

再看看下面這個例子。

    <select id="bar" resultType="Blog">

        select * from t_blog where id in

        <foreach collection="array" index="index"

            item="item" open="(" separator="," close=")">

            #{item}

        </foreach>

    </select>

 

 

21、什麼是IoCDIDI是如何實現的? 

答:

IoC叫控制反轉,DI叫依賴注入;

IoC就是把對象調用交由容器,

IoC由容器來建立對象並管理對象之間的依賴關係

 

DI是對IoC更準確的描述,即組件之間的依賴關係由容器在運行期決定。

 

依賴注入能夠經過setter方法注入(設值注入)、構造器注入和接口注入三種方式來實現,

 

22SpringBean的做用域有哪些?

答:在Spring的早期版本中,僅有兩個做用域:singletonprototype,前者表示Bean以單例的方式存在;後者表示每次從容器中調用Bean時,都會返回一個新的實例,prototype一般翻譯爲原型。

23、解釋一下什麼叫AOP(面向切面編程)? 
答:AOPAspect-Oriented Programming)指一種程序設計範型,該範型以一種稱爲切面(aspect)的語言構造爲基礎,切面是一種新的模塊化機制,用來描述分散在對象、類或方法中的橫切關注點(crosscutting concern)。

 

24、你是如何理解"橫切關注"這個概念的? 
答:"橫切關注"是會影響到整個應用程序的關注功能,它跟正常的業務邏輯是正交的,沒有必然的聯繫,可是幾乎全部的業務邏輯都會涉及到這些關注功能。一般,事務、日誌、安全性等關注就是應用中的橫切關注功能。

25、你如何理解AOP中的鏈接點(Joinpoint)、切點(Pointcut)、加強(Advice)、引介(Introduction)、織入(Weaving)、切面(Aspect)這些概念? (上課的圖)
答: a. 鏈接點(Joinpoint):程序執行的某個特定位置(如:某個方法調用前、調用後,方法拋出異常後)。一個類或一段程序代碼擁有一些具備邊界性質的特定點,這些代碼中的特定點就是鏈接點。Spring僅支持方法的鏈接點。 b. 切點(Pointcut):若是鏈接點至關於數據中的記錄,那麼切點至關於查詢條件,一個切點能夠匹配多個鏈接點。Spring AOP的規則解析引擎負責解析切點所設定的查詢條件,找到對應的鏈接點。 c. 加強(Advice):加強是織入到目標類鏈接點上的一段程序代碼。Spring提供的加強接口都是帶方位名的,如:BeforeAdviceAfterReturningAdviceThrowsAdvice等。不少資料上將加強譯爲「通知」,這明顯是個詞不達意的翻譯,讓不少程序員困惑了許久。

說明: Advice在國內的不少書面資料中都被翻譯成"通知",可是很顯然這個翻譯沒法表達其本質,有少許的讀物上將這個詞翻譯爲"加強",這個翻譯是對Advice較爲準確的詮釋,咱們經過AOP將橫切關注功能加到原有的業務邏輯上,這就是對原有業務邏輯的一種加強,這種加強能夠是前置加強、後置加強、返回後加強、拋異常時加強和包圍型加強。

d. 引介(Introduction):引介是一種特殊的加強,它爲類添加一些屬性和方法。這樣,即便一個業務類本來沒有實現某個接口,經過引介功能,能夠動態的未該業務類添加接口的實現邏輯,讓業務類成爲這個接口的實現類。 e. 織入(Weaving):織入是將加強添加到目標類具體鏈接點上的過程,AOP有三種織入方式:①編譯期織入:須要特殊的Java編譯期(例如AspectJajc);②裝載期織入:要求使用特殊的類加載器,在裝載類的時候對類進行加強;③運行時織入:在運行時爲目標類生成代理實現加強。Spring採用了動態代理的方式實現了運行時織入,而AspectJ採用了編譯期織入和裝載期織入的方式。 f. 切面(Aspect):切面是由切點和加強(引介)組成的,它包括了對橫切關注功能的定義,也包括了對鏈接點的定義。

補充:代理模式是GoF提出的23種設計模式中最爲經典的模式之一,代理模式是對象的結構模式,它給某一個對象提供一個代理對象,並由代理對象控制對原對象的引用。簡單的說,代理對象能夠完成比原對象更多的職責,當須要爲原對象添加橫切關注功能時,就能夠使用原對象的代理對象。咱們在打開Office系列的Word文檔時,若是文檔中有插圖,當文檔剛加載時,文檔中的插圖都只是一個虛框佔位符,等用戶真正翻到某頁要查看該圖片時,纔會真正加載這張圖,這其實就是對代理模式的使用,代替真正圖片的虛框就是一個虛擬代理;Hibernateload方法也是返回一個虛擬代理對象,等用戶真正須要訪問對象的屬性時,才向數據庫發出SQL語句得到真實對象。

 

26Spring中自動裝配的方式有哪些? 
答: - no:不進行自動裝配,手動設置Bean的依賴關係。 - byName:根據Bean的名字進行自動裝配。 - byType:根據Bean的類型進行自動裝配。 - constructor:相似於byType,不過是應用於構造器的參數,若是正好有一個Bean與構造器的參數類型相同則能夠自動裝配,不然會致使錯誤。 - autodetect:若是有默認的構造器,則經過constructor的方式進行自動裝配,不然使用byType的方式進行自動裝配。

說明:自動裝配沒有自定義裝配方式那麼精確,並且不能自動裝配簡單屬性(基本類型、字符串等),在使用時應注意。

 

27Spring中如何使用註解來配置Bean?有哪些相關的註解? 
答:首先須要在Spring配置文件中增長以下配置:

<context:component-scan base-package="org.example"/>

而後能夠用@Component@Controller@Service@Repository註解來標註須要由Spring IoC容器進行對象託管的類。這幾個註解沒有本質區別,只不過@Controller一般用於控制器,@Service一般用於業務邏輯類,@Repository一般用於倉儲類(例如咱們的DAO實現類),普通的類用@Component來標註。

 

28Spring支持的事務管理類型有哪些?你在項目中使用哪一種方式? 
答:Spring支持編程式事務管理和聲明式事務管理。許多Spring框架的用戶選擇聲明式事務管理,由於這種方式和應用程序的關聯較少,所以更加符合輕量級容器的概念。聲明式事務管理要優於編程式事務管理,儘管在靈活性方面它弱於編程式事務管理,由於編程式事務容許你經過代碼控制業務。

事務分爲全局事務和局部事務。全局事務由應用服務器管理,須要底層服務器JTA支持(如WebLogicWildFly等)。局部事務和底層採用的持久化方案有關,例如使用JDBC進行持久化時,須要使用Connetion對象來操做事務;而採用Hibernate進行持久化時,須要使用Session對象來操做事務。

Spring提供了以下所示的事務管理器。

事務管理器實現類

目標對象

DataSourceTransactionManager

注入DataSource

HibernateTransactionManager

注入SessionFactory

JdoTransactionManager

管理JDO事務

JtaTransactionManager

使用JTA管理事務

PersistenceBrokerTransactionManager

管理ApacheOJB事務

 

 

29、如何在Web項目中配置SpringIoC容器? 
答:若是須要在Web項目中使用SpringIoC容器,能夠在Web項目配置文件web.xml中作出以下配置:

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContext.xml</param-value>

</context-param>

 

<listener>

    <listener-class>

        org.springframework.web.context.ContextLoaderListener

    </listener-class>

</listener>

 

30、如何在Web項目中配置Spring MVC 
答:要使用Spring MVC須要在Web項目配置文件中配置其前端控制器DispatcherServlet,以下所示:

<web-app>

    <servlet>

        <servlet-name>example</servlet-name>

        <servlet-class>

            org.springframework.web.servlet.DispatcherServlet

        </servlet-class>

        <load-on-startup>1</load-on-startup>

    </servlet>

 

    <servlet-mapping>

        <servlet-name>example</servlet-name>

        <url-pattern>*.html</url-pattern>

    </servlet-mapping>

</web-app>

 

說明:上面的配置中使用了*.html的後綴映射,這樣作一方面不可以經過URL推斷採用了何種服務器端的技術,另外一方面能夠欺騙搜索引擎,由於搜索引擎不會搜索動態頁面,這種作法稱爲僞靜態化。

 

31Spring MVC的工做原理是怎樣的? 
答:Spring MVC的工做原理以下圖所示:  
① 客戶端的全部請求都交給前端控制器DispatcherServlet來處理,它會負責調用系統的其餘模塊來真正處理用戶的請求。 
② DispatcherServlet收到請求後,將根據請求的信息(包括URLHTTP協議方法、請求頭、請求參數、Cookie等)以及HandlerMapping的配置找處處理該請求的Handler(任何一個對象均可以做爲請求的Handler)。 
③在這個地方Spring會經過HandlerAdapter對該處理器進行封裝。 
④ HandlerAdapter是一個適配器,它用統一的接口對各類Handler中的方法進行調用。 
⑤ Handler完成對用戶請求的處理後,會返回一個ModelAndView對象給DispatcherServletModelAndView顧名思義,包含了數據模型以及相應的視圖的信息。 
⑥ ModelAndView的視圖是邏輯視圖,DispatcherServlet還要藉助ViewResolver完成從邏輯視圖到真實視圖對象的解析工做。 
⑦ 當獲得真正的視圖對象後,DispatcherServlet會利用視圖對象對模型數據進行渲染。 
⑧ 客戶端獲得響應,多是一個普通的HTML頁面,也能夠是XMLJSON字符串,還能夠是一張圖片或者一個PDF文件。

 

 

32、如何在Spring IoC容器中配置數據源? 
答: DBCP配置:

<bean id="dataSource"

        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

    <property name="driverClassName" value="${jdbc.driverClassName}"/>

    <property name="url" value="${jdbc.url}"/>

    <property name="username" value="${jdbc.username}"/>

    <property name="password" value="${jdbc.password}"/>

</bean>

 

<context:property-placeholder location="jdbc.properties"/>

C3P0配置:

<bean id="dataSource"

        class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

    <property name="driverClass" value="${jdbc.driverClassName}"/>

    <property name="jdbcUrl" value="${jdbc.url}"/>

    <property name="user" value="${jdbc.username}"/>

    <property name="password" value="${jdbc.password}"/>

</bean>

 

<context:property-placeholder location="jdbc.properties"/>

提示: DBCP的詳細配置在第153題中已經完整的展現過了。

 

 

33、如何配置配置事務加強? 
答:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xmlns:aop="http://www.springframework.org/schema/aop"

     xmlns:tx="http://www.springframework.org/schema/tx"

     xsi:schemaLocation="

     http://www.springframework.org/schema/beans

     http://www.springframework.org/schema/beans/spring-beans.xsd

     http://www.springframework.org/schema/tx

     http://www.springframework.org/schema/tx/spring-tx.xsd

     http://www.springframework.org/schema/aop

     http://www.springframework.org/schema/aop/spring-aop.xsd">

 

  <!-- this is the service object that we want to make transactional -->

  <bean id="fooService" class="x.y.service.DefaultFooService"/>

 

  <!-- the transactional advice -->

  <tx:advice id="txAdvice" transaction-manager="txManager">

  <!-- the transactional semantics... -->

  <tx:attributes>

    <!-- all methods starting with 'get' are read-only -->

    <tx:method name="get*" read-only="true"/>

    <!-- other methods use the default transaction settings (see below) -->

    <tx:method name="*"/>

  </tx:attributes>

  </tx:advice>

 

  <!-- ensure that the above transactional advice runs for any execution

    of an operation defined by the FooService interface -->

  <aop:config>

  <aop:pointcut id="fooServiceOperation"

    expression="execution(* x.y.service.FooService.*(..))"/>

  <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>

  </aop:config>

 

  <!-- don't forget the DataSource -->

  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

    destroy-method="close">

  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>

  <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>

  <property name="username" value="scott"/>

  <property name="password" value="tiger"/>

  </bean>

 

  <!-- similarly, don't forget the PlatformTransactionManager -->

  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

  <property name="dataSource" ref="dataSource"/>

  </bean>

 

  <!-- other <bean/> definitions here -->

 

</beans>

 

 

34、選擇使用Spring框架的緣由(Spring框架爲企業級開發帶來的好處有哪些)? 
答:能夠從如下幾個方面做答: - 非侵入式:支持基於POJO的編程模式,不強制性的要求實現Spring框架中的接口或繼承Spring框架中的類。 - IoC容器:IoC容器幫助應用程序管理對象以及對象之間的依賴關係,對象之間的依賴關係若是發生了改變只須要修改配置文件而不是修改代碼,由於代碼的修改可能意味着項目的從新構建和完整的迴歸 HYPERLINK "http://lib.csdn.net/base/softwaretest" \t "_blank" \o "軟件測試知識庫" 測試。有了IoC容器,程序員不再須要本身編寫工廠、單例,這一點特別符合Spring的精神"不要重複的發明輪子" - AOP(面向切面編程):將全部的橫切關注功能封裝到切面(aspect)中,經過配置的方式將橫切關注功能動態添加到目標代碼上,進一步實現了業務邏輯和系統服務之間的分離。另外一方面,有了AOP程序員能夠省去不少本身寫代理類的工做。 - MVCSpringMVC框架是很是優秀的,從各個方面均可以甩Struts 2幾條街,爲Web表示層提供了更好的解決方案。 - 事務管理:Spring以寬廣的胸懷接納多種持久層技術,而且爲其提供了聲明式的事務管理,在不須要任何一行代碼的狀況下就可以完成事務管理。 - 其餘:選擇Spring框架的緣由還遠不止於此,SpringJava企業級開發提供了一站式選擇,你能夠在須要的時候使用它的部分和所有,更重要的是,你甚至能夠在感受不到Spring存在的狀況下,在你的項目中使用Spring提供的各類優秀的功能。

 

35Spring IoC容器配置Bean的方式? 
答: - 基於XML文件進行配置。 - 基於註解進行配置。 - 基於Java程序進行配置(Spring 3+

 

 

36、闡述Spring框架中Bean的生命週期? 
答: 
① Spring IoC容器找到關於Bean的定義並實例化該Bean 
② Spring IoC容器對Bean進行依賴注入。 
③ 若是Bean實現了BeanNameAware接口,則將該Beanid傳給setBeanName方法。 
④ 若是Bean實現了BeanFactoryAware接口,則將BeanFactory對象傳給setBeanFactory方法。 
⑤ 若是Bean實現了BeanPostProcessor接口,則調用其postProcessBeforeInitialization方法。 
⑥ 若是Bean實現了InitializingBean接口,則調用其afterPropertySet方法。 
⑦ 若是有和Bean關聯的BeanPostProcessors對象,則這些對象的postProcessAfterInitialization方法被調用。 
⑧ 當銷燬Bean實例時,若是Bean實現了DisposableBean接口,則調用其destroy方法。

 

 

37、依賴注入時如何注入集合屬性? 
答:能夠在定義Bean屬性時,經過<list> / <set> / <map> / <props>分別爲其注入列表、集合、映射和鍵值都是字符串的映射屬性。

 

38Spring中的自動裝配有哪些限制? 
答: - 若是使用了構造器注入或者setter注入,那麼將覆蓋自動裝配的依賴關係。 - 基本數據類型的值、字符串字面量、類字面量沒法使用自動裝配來注入。 - 優先考慮使用顯式的裝配來進行更精確的依賴注入而不是使用自動裝配。

 

39、在Web項目中如何得到SpringIoC容器? 
答:

WebApplicationContext ctx =

WebApplicationContextUtils.getWebApplicationContext(servletContext);

 

 40SSHSSM的組成及其區別

SSH指的是:spring+Struts+hibernate;而SSM指的是:spring +SpringMVC + MyBatis

SSH 一般指的是 Struts2 作前端控制器,spring 管理各層的組件,hibernate 負責持久化層。

SSM 則指的是 SpringMVC 作前端控制器,spring 管理各層的組件,MyBatis 負責持久化層。

 

共同之處是都使用了Spring的依賴注入DI來管理各層的組件,使用了面向切面編程AOP來實現日誌管理,權限認證,事務等通用功能的切入。

不一樣之處是 Struts2 SpringMVC 作前端控制器的區別,hibernate MyBatis 作持久化時的區別。

Struts2 也能夠和 MyBatis 搭配使用,SpringMVC 也能夠和 Hibernate 搭配使用。

 

41SpringMVCStruts : 

1)二者有個共同之處,那就是二者都數據javaweb層的開發框架,都是mvc模式的的經典產品,都實現了頁面分離控制的功能,可是二者之間是有區別的。 2)在開發中,人們更願意使用SpringMVC而不是Struts。由於SpringMVC分離了控制器、模型對象、分派器以及處理程序對象的角色,這種分離讓它們更容易進行定製。在擴展和靈活性上更勝一籌。

3Struts的優點在於靜態注入,插件機制和攔截器鏈,可是struts存在漏洞,常常會被做爲攻擊點進行衝擊。相比更加安全簡單的SpringMVC,開發者漸漸開發放棄了它。 

 

42Hibernate MyBatis: 1HibernateMybatis都是流行的持久層開發框架,一句話歸納:MyBatis 簡單易上手; 2hibernate成熟,市場推廣率高。 3MyBatis能夠進行更爲細緻的SQL優化,能夠減小查詢字段。 4MyBatis容易掌握,而Hibernate門檻較高。 5)更重要的是,mybatis提供了對應各類用途、功能的插件,而hibernate在這一方面是遠遠比不上mybatis的。 6HibernateDAO層開發比MyBatis簡單,Mybatis須要維護SQL和結果映射。 7Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。 8Hibernate數據庫移植性很好,MyBatis的數據庫移植性很差,不一樣的數據庫須要寫不一樣SQL 9Hibernate有更好的二級緩存機制,能夠使用第三方緩存。MyBatis自己提供的緩存機制不佳。 10)可是hibernat缺點很明確,若是涉及到多張關聯表的調用時:   1. 多表關聯等比較複雜,使用的成本並不低;   2. 效率比較低,在大型項目中不多會使用到它,由於sql都是自動生成的,不太好進行人工的優化。 

 

43Struts 2中,Action經過什麼方式得到用戶從頁面輸入的數據,又是經過什麼方式把其自身的數據傳給視圖的?

答:Action從頁面獲取數據有三種方式:

①經過Action屬性接受參數

②經過域模型獲取參數

③經過模型驅動獲取參數 (ModelDriven<T>

Action將數據存入值棧(Value Stack)中,視圖能夠經過表達式語言(EL)從值棧中獲取數據。

 

44、簡述Struts 2是如何實現MVC

答:MVC架構模式要求應用程序的輸入、處理和輸出三者分離,將系統分紅模型(Model)、視圖(View)、控制器(Controller)三個部分,經過控制器實現模型和視圖的解耦合,使得應用程序的開發和維護變得容易,以下圖所示。其中,模型表明了應用程序的數據和處理這些數據的規則,同時還能夠爲視圖提供的查詢保存相關的狀態,一般由JavaBean來實現,模型的代碼寫一次就能夠被多個視圖重用;視圖用來組織模型的內容,它從模型中得到數據,並將數據展示給用戶,在Struts 2中一般由JSPFreemarker模板等來實現;控制器負責從客戶端接受請求並將其轉換爲某種行爲,行爲完成後再選擇一個視圖來呈現給用戶,控制器自己不須要輸出任何內容,它只是接收請求並決定調用哪一個模型組件去處理請求,StrutsPrepareAndExecuteFilter過濾器是Struts 2中的核心,它和一系列的Action構成了Struts 2中的控制器。

45、闡述Struts 2如何實現用戶輸入驗證。在你作過的項目中使用的是那種驗證方式,爲何選擇這種方式?

答:Struts 2能夠使用手動驗證和自動驗證框架實現用戶輸入驗證。自動驗證框架是將對輸入的驗證規則放在XML文件中,這種方式比較靈活,能夠在不修改代碼的狀況下修改驗證的規則。

 

46、闡述Struts 2中的Action如何編寫?Action是否採用了單例?

答:Struts2Action有三種寫法:

POJO

②實現Action接口重寫execute()方法

③繼承ActionSupport

Action沒有像Servlet同樣使用單實例多線程的工做方式,很明顯,每一個Action要接收不一樣用戶的請求參數,這就意味着Action是有狀態的,所以在設計上使用了每一個請求對應一個Action的處理方式。

47Struts 2中的Action並無直接收到用戶的請求,那它爲何能夠處理用戶的請求,又憑什麼知道一個請求到底交給哪一個Action來處理?

答:Struts2的核心過濾器接收到用戶請求後,會對用戶的請求進行簡單的預處理(例如解析、封裝參數),而後經過反射來建立Action實例,並調用Action中指定的方法來處理用戶請求。

要決定請求交給哪個Action來處理有兩種方式:1利用配置文件:能夠在配置文件中經過<action>標籤配置和請求對應的Action類以及要調用的方法;2利用約定:Struts2中能夠使用約定(convention)插件,例如約定xxx老是對應XxxAction,這是對約定優於配置理念的踐行。

 

48、你常常用到的Struts 2常量配置有哪些?

答:

struts.i18n.encoding– 指定默認編碼

struts.objectFactory/ struts.objectFactory.spring.autoWire – 對象工廠 / Spring的自動裝配方式(名字、類型)

struts.devMode– 是否使用開發模式

struts.locale– 指定默認區域,默認值是en_US

struts.i18n.resources– 國際化使用的資源文件

struts.enable.DynamicMethodInvocation– 是否容許動態方法調用

 

49、簡述Struts2的異常處理機制。

答:Struts 2提供了聲明式的異常處理機制,能夠在配置文件中加入以下代碼:

<global-exception-mappings>

<exception-mapping exception=」…」 result=」…」/>

</global-exception-mappings>

 

50、說一下你對約定優於配置(CoC)的理解。

答:約定優於配置(convention over configuration),也稱做按約定編程,是一種軟件設計範式,旨在減小軟件開發人員需作決定的數量,得到簡單的好處而又不失靈活性。CoC本質是說,開發人員僅需規定應用中不符約定的部分。例如,若是模型中有個名爲Sale的類,那麼數據庫中對應的表就會默認命名爲sales。只有在偏離這一約定時,例如將該表命名爲products_sold,才需寫有關這個名字的配置。若是您所用工具的約定與你的期待相符,即可省去配置;反之,你能夠配置來達到你所期待的方式。遵循約定雖然損失了必定的靈活性,不能隨意安排目錄結構,不能隨意進行函數命名,可是卻能減小配置。更重要的是,遵循約定能夠幫助開發人員遵照構建標準,包括各類命名的規範,這對團隊開發是很是有利的。

 

51Struts2中如何實現I18N

答:首先,爲不一樣語言地區編寫不一樣的資源文件;而後在Struts 2配置文件中配置struts.i18n.custom.resources常量;在Action中能夠經過調用getText()方法讀取資源文件獲取國際化資源。

52、簡述攔截器的工做原理以及你在項目中使用過哪些自定義攔截器。

答:Struts 2中定義了攔截器的接口以及默認實現,實現了Interceptor接口或繼承了AbstractInterceptor的類能夠做爲攔截器。接口中的init()方法在攔截器被建立後當即被調用,它在攔截器的生命週期內只被調用一次,能夠在該方法中對相關資源進行必要的初始化。每攔截一個請求,intercept()方法就會被調用一次。destory()方法將在攔截器被銷燬以前被調用它在攔截器的生命週期內也只被調用一次。

項目中使用過的有權限攔截器、執行時間攔截器、令牌攔截器等。

 

 

53、如何在Struts2中使用Ajax功能?

答:如下是Struts 2中實現Ajax的可選方式:

JSON plugin+  HYPERLINK "http://lib.csdn.net/base/jquery" \t "_blank" \o "jQuery知識庫" jQuery

DOJO plugin

DWR (DirectWeb Remoting)

 

54、談一下攔截器和過濾器的區別。

答:攔截器和過濾器均可以用來實現橫切關注功能,其區別主要在於:

①攔截器是基於Java反射機制的,而過濾器是基於接口回調的。

②過濾器依賴於Servlet容器,而攔截器不依賴於Servlet容器。

③攔截器只能對Action請求起做用,而過濾器能夠對全部請求起做用。

④攔截器能夠訪問Action上下文、值棧裏的對象,而過濾器不能。

55、談一下Struts 1Struts 2的區別。

 

 

56Struts 2中如何訪問HttpServletRequestHttpSessionServletContext三個域對象

答:有兩種方式:

①經過ServletActionContext的方法得到;

②經過ServletRequestAwareSessionAwareServletContextAware接口注入。

 

57Struts 2中的默認包struts-default有什麼做用?

答:它定義了Struts 2內部的衆多攔截器和Result類型,而Struts 2不少核心的功能都是經過這些內置的攔截器實現,如:從請求中把請求參數封裝到action、文件上傳和數據驗證等等都是經過攔截器實現的。在Struts 2的配置文件中,自定義的包繼承了struts-default包就能夠使用Struts 2爲咱們提供的這些功能。

 

58、簡述值棧(Value-Stack)的原理和生命週期

答:Value-Stack貫穿整個 Action 的生命週期,保存在request做用域中,因此它和request的生命週期同樣。當Struts 2接受一個請求時,會建立ActionContextValue-StackAction對象,而後把Action存放進Value-Stack,因此Action的實例變量能夠經過OGNL訪問。因爲Action是多實例的,和使用單例的Servlet不一樣,每一個Action都有一個對應的Value-StackValue-Stack存放的數據類型是該Action的實例,以及該Action中的實例變量,Action對象默認保存在棧頂。

 

59J2EE是什麼?

:Je22Sun公司提出的多層(multi-diered),分佈式(distributed),基於組件(component-base)的企業級應用模型(enterpriese application model).在這樣的一個應用系統中,可按照功能劃分爲不一樣的組件,這些組件又可在不一樣計算機上,而且處於相應的層次(tier)中。所屬層次包括客戶層(clietn tier)組件,web層和組件,Business層和組件,企業信息系統(EIS)層。

 

一個另類的回答:j2ee就是增刪改查。

 

60J2EE是技術仍是平臺仍是框架? 什麼是J2EE

   J2EE自己是一個標準,一個爲企業分佈式應用的開發提供的標準平臺。

   J2EE也是一個框架,包括JDBCJNDIRMIJMSEJBJTA等技術。

 

 

61、開發中都用到了那些設計模式?用在什麼場合?

每一個模式都描述了一個在咱們的環境中不斷出現的問題,而後描述了該問題的解決方案的核心。經過這種方式,你能夠無數次地使用那些已有的解決方案,無需在重複相同的工做。主要用到了MVC的設計模式。用來開發JSP/Servlet或者J2EE的相關應用。簡單工廠模式等

 

 

62SQL Server Oracle 以及 MySQL 有哪些區別?

 

1.數據庫對比。
----1.Oracle:最貴,功能最多,安裝最不方便,Oracle環境裏的其餘相關組件最多,支持平臺數量通常,使用中等方便,開發中等方便,運維中等方便,不開源,速度最慢,最安全。
----2.Microsoft SQL Server 2014:中等貴,功能最少,安裝中等方便,Microsoft SQL Server 2014環境裏的其餘相關組件最少,支持平臺最少,使用最方便,開發最方便,運維最方便,不開源,速度中等,通常安全。
----3.Mysql:免費,功能中等,安裝最方便,Mysql環境裏的其餘相關組件數量中等,支持平臺最多,使用最不方便,開發最不方便,運維最不方便,有開源版本,速度最快,最不安全。

2.從不一樣職業的角度來看。
----1.對於初學數據庫的孩子來講,好比學生,建議學習Microsoft SQL Server 2014。緣由主要是方便。微軟平臺,從Windows操做系統、VS開發工具、C#語言等等,不管安裝、使用、學習都很方便,而且書籍也不少。使用這個平臺,能讓你更集中注意力在學習上,避免不少無關因素的打擾。好比,安裝Oracle的話,須要瞭解不少非數據庫知識,學生時期,原本時間就少,所以不推薦在此時期學習Oracle。

----2.對於在國企、事業單位裏的人來講,建議精通Windows\Office\C#\Microsoft SQL Server 2014,由於這類工做崗位上會常常作一些小軟件的快速開發,以及數據的快速處理。

----3.對於在百度、阿里巴巴這類互聯網企業的人來講,建議精通Mysql。由於這類企業不肯意花錢購買正版軟件,同時又須要對源代碼進行定製,所以Mysql最適合這類企業。

----4.對於專門從事大型軟件項目開發,以及電信、電商、金融等,這類企業有錢,而且對數據安全最重視,所以,這類企業適合使用Oracle

 

 

63

項目開發流程

可行性分析 >>> 可行性分析報告 / 項目開發計劃書

需求分析 >>> 需求規格說明書 

OOAD(用例圖、時序圖、活動圖)

界面原型:幫助理解需求、業務層設計時推導事務腳本

設計 >>> 概要設計說明書/詳細設計說明書 

抽取業務實體(領域對象):類圖、E-R圖(概念設計階段)

分層架構:肯定各層的技術實現方案(具體到使用的框架、數據庫服務器、應用服務器等)。業務層設計:事務腳本模式(事務:用戶發送一次請求就是一個事務;腳本:一個方法或一個函數;事務腳本:把一次請求封裝爲一個方法或一個函數;事務腳本模式:一個事務開始於腳本的打開,終止於腳本的關閉)。業務層涉及的對象有三種類型:事務腳本類(封裝了業務的流程)、數據訪問對象(DAO,封裝了持久化操做)、數據傳輸對象(DTO,封裝了失血/貧血領域對象),三者之間的關係是事務腳本類組合(聚合)數據訪問對象,這兩者都依賴了數據傳輸對象

正向工程(UML類圖生成Java代碼)和逆向工程(Java代碼生成UML類圖)

數據庫物理設計(ER圖轉換成表間關係圖、建庫和建表、使用工具插入測試數據)

編碼

測試 >>> 測試報告 / 缺陷報告 

單元測試:對軟件中的最小可測試單元進行檢查和驗證,在Java中是對類中的方法進行測試,能夠使用JUnit工具來實施。

集成測試:集成測試也叫組裝測試或聯合測試。在單元測試的基礎上,將全部模塊按照設計要求組裝成爲子系統進行測試。

系統測試:將已經確認的軟件、硬件、外設、網絡等元素結合在一塊兒,進行信息系統的各類組裝測試和確認測試,系統測試是針對整個產品系統進行的測試,目的是驗證系統是否知足了需求規格的定義,找出與需求規格不符或與之矛盾的地方,從而提出更加完善的方案。

驗收測試:在軟件產品完成了單元測試、集成測試和系統測試以後,產品發佈以前所進行的軟件測試活動。它是技術測試的最後一個階段,也稱爲交付測試。驗收測試的目的是確保軟件準備就緒,而且可讓最終用戶將其用於執行軟件的既定功能和任務。

交付和維護 >>> 用戶手冊 / 操做手冊

項目管理

版本控制:CVS/SVN/Git

自動構建:Ant/Maven/Ivy/Gradle

持續集成:Hudson/Jenkins

系統架構

負載均衡服務器:F5A10

應用服務器: 

HTTP服務器:ApacheNginXHTTP、反向代理、郵件代理服務器)

Servlet容器:TomcatResin

EJB容器:WildFlyJBoss Application Server)、GlassFishWeblogicWebsphere

數據庫服務器:MySQLOracle

第三方工具(插件)應用

圖表工具:基於jQuery的圖表插件(如jQchartFlotCharted等)、Chart.jsHighcharts等。

報表工具:Pentaho ReportingiReportDynamicReports等。

文檔處理:POIiText等。

工做流引擎:jBPMOpenWFESnakerSWAMP等。

做業調度:QuartzJobServerOddjob等。

緩存服務:EhCachememcachedSwarmCache等。

消息隊列:Open-MQZeroMQ等。

安全框架:ShiroPicketBox等。

搜索引擎:IndexTankLuceneElasticSearch等。

Ajax框架:jQueryExtJSDWR等。

UI插件:EasyUIMiniUI等。

富文本框:UEditorCKEditor等。

 

64

Activiti工做流面試相關知識

1:什麼是工做流,工做流的核心對象是什麼,activiti共操做數據庫多少張表
  * 工做流就是多個參與者,按照某種預約義的規則,傳遞業務信息,進行審覈的功能一個框架(Activiti)
  * processEngine,調用Service,從而操做數據庫的表
  * 23表

2:工做流中RepositoryServiceRuntimeServiceTaskServiceHistoryService分別表示什麼操做
RepositoryService:流程定義和部署對象
RuntimeService:執行管理,包括流程實例和執行對象(正在執行)
TaskService:執行任務相關的(正在執行)
HistoryService:歷史管理
IdentityServiceActiviti表的用戶角色組


3:流程實例和執行對象的區別
 * 流程從開始到結束的最大分支,一個流程中,流程實例只有1個
 * 執行對象,就是按照流程定義的規則執行一次的操做,一個流程中,執行對象能夠有多個


4:流程變量在項目中的做用
 * 1:用來傳遞業務參數,目的就是審覈人能夠經過流程變量查看申請人的一些審覈信息
   2:在連線的condition中設置流程變量,用來指定應該執行的連線${message=='重要'}

   3:使用流程變量指定我的任務和組任務的辦理人#{userID}

5activiti工做流中,若是一個任務完成後,存在多條連線,應該如何處理?
  * 使用流程變量
  * 當一個任務完成以後,根據這幾條連線的條件和設置流程變量,例如${ 流程變量的名稱=='流程變量的值'}{}符號是boolean類型,判斷走哪條連線
6activiti工做流中,排他網關和並行網關都能執行什麼功能
  排他網關:分支,經過連線的流程變量,判斷執行哪條連線,若是條件不符合,會執行默認的連線離開,注意:只能執行其中的一個流程。
  並行網關:能夠同時執行多個流程,直到總流程的結束。能夠對流程進行分支和聚合,注意:流程實例和執行對象是不同的


7:分配我的任務的三種方式
*直接給值,在Xxxx.bpmn文件中指定
*流程變量${ 流程變量的名稱}或者#{}*使用類 監聽這個類(實現一個接口),指定任務的辦理人(setAssgnee())


8:我的任務和組任務的查詢同樣嗎?
  * 不同
  * 都是用TaskService完成(TaskService.createTasQuery)
  * 我的任務(taskAssgnee),組任務(taskCandidateUser)
  * 數據庫存放,我的任務(類型:參與),組任務(類型,參與,候選)

1、 什麼是工做流

以請假爲例,如今大多數公司的請假流程是這樣的

員工打電話(或網聊)向上級提出請假申請——上級口頭贊成——上級將請假記錄下來——月底將請假記錄上交公司——公司將請假錄入電腦

採用工做流技術的公司的請假流程是這樣的

員工使用帳戶登陸系統——點擊請假——上級登陸系統點擊容許

就這樣,一個請假流程就結束了

有人會問,那上級不用向公司提交請假記錄?公司不用將記錄錄入電腦?答案是,用的。可是這一切的工做都會在上級點擊容許後自動運行!

這就是工做流技術。

 

Georgakopoulos給出的工做流定義是:工做流是將一組任務組織起來以完成某個經營過程:定義了任務的觸發順序和觸發條件,每一個任務能夠由一個或多個軟件系統完成,也能夠由一個或一組人完成,還能夠由一個或多我的與軟件系統協做完

 

 

2、 工做流技術的優勢

從上面的例子,很容易看出

工做流系統,實現了工做流程的自動化,提升了企業運營效率、改善企業資源利用、提升企業運做的靈活性和適應性、提升量化考覈業務處理的效率、減小浪費(時間就是金錢)。

而手工處理工做流程,一方面沒法對整個流程情況進行有效跟蹤、瞭解,另外一方面不免會出現人爲的失誤和時間上的延時致使效率低下,特別是沒法進行量化統計,不利於查詢、報表及績效評估。

 

3、 Java開發者會爲何要學Activity工做流

Java領域,JBPMActivity是兩個主流的工做流系統,而Activity的出現無疑將會取代JBPMActivity的開發者就是從Jbpm開發者出來的)。

 

4、 Activity工做流學習要點

 

1. 1個插件

Eclipse中安裝Activity插件,讓你能夠在Eclipse中繪製Activity工做流圖

 

2. 1個引擎

ProcessEngine對象,Activity工做流引擎。這是Activiti工做的核心。負責生成流程運行時的各類實例及數據、監控和管理流程的運行。

全部的操做都是從獲取引擎開始的,因此通常會把引擎做爲全局變量

ProcessEngine processEngine =ProcessEngines.getDefaultProcessEngine();

 

3. 1個配置文件

activiti.cfg.xmlActiviti核心配置文件,配置流程引擎建立工具的基本參數和數據庫鏈接池參數

 

4. 5種數據庫表

Activiti的後臺是有數據庫的支持,全部的表都以ACT_開頭。 第二部分是表示表的用途的兩個字母標識。用途也和服務的API對應。

ACT_RE_*: 'RE'表示repository。 這個前綴的表包含了流程定義和流程靜態資源(圖片,規則,等等)。

ACT_RU_*: 'RU'表示runtime。 這些運行時的表,包含流程實例,任務,變量,異步任務,等運行中的數據。 Activiti只在流程實例執行過程當中保存這些數據,在流程結束時就會刪除這些記錄。 這樣運行時表能夠一直很小速度很快。

ACT_ID_*: 'ID'表示identity。 這些表包含身份信息,好比用戶,組等等。

ACT_HI_*: 'HI'表示history。 這些表包含歷史數據,好比歷史流程實例,變量,任務等等。

ACT_GE_*: 通用數據,用於不一樣場景下,如存放資源文件。

 

5. 23張表

不一樣的表存放不一樣方面的數據,有流程定義表、任務結點表、流程變量表、任務歷史表等等。

 

 

6. 5Service

不一樣的Service類對應不一樣的功能。

好比TaskService,是activiti的任務服務類。能夠從這個類中獲取任務的信息。

HistoryService,則是activiti

相關文章
相關標籤/搜索