1.是否可以從一個static方法內部發出對非static方法的調用?
不可以。當一個static方法被調用時,可能還沒有創建任何實例對象,如果從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪個對象上的呢?這個邏輯無法成立.
2.Integer與int的區別?
int是java提供的8種原始數據類型之一,Integer是java為int提供的封裝類。int的默認值為0,而Integer的默認值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況。
在JSP開發中,Integer的默認為null,所以用el表達式在文本框中顯示時,值為空白字符串,而int默認的默認值為0,所以用el表達式在文本框中顯示時,結果為0,所以,int不適合作為web層的表單數據的類型。
在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm映射文件中設置其unsaved-value屬性為0。
3.Math.round(11.5)等於多少?Math.round(-11.5)等於多少?
Math類中提供了三個與取整有關的方法:ceil、floor、round,
- ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結果為12,Math.ceil(-11.3)的結果是-11。
- floor的英文意義是地板,該方法就表示向下取整,Math.floor(11.6)的結果為11,Math.floor(-11.6)的結果是-12.
- round表示“四舍五入”,Math.round(11.5)的結果為12,Math.round(-11.5)的結果為-11。
4.Overload和Override的區別?Overloaded的方法是否可以改變返回值的類型?
Overload是重載的意思,Override是覆蓋的意思,也就是重寫。重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不同)。
重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數完全相同,通過子類創建的實例對象調用這個方法時,將調用子類中的定義方法,這相當於把父類中定義的那個完全相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權限只能比父類的更大,不能更小。如果父類的方法是private類型,那么,子類則不存在覆蓋的限制,相當於子類中增加了一個全新的方法。
5.接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承具體類(concreteclass)?抽象類中是否可以有靜態的main方法?
接口可以繼承接口。抽象類可以實現(implements)接口,抽象類可以繼承具體類。抽象類中可以有靜態的main方法。抽象類與普通類的唯一區別就是不能創建實例對象和允許有abstract方法。
6.Java中實現多態的機制是什么?
- 抽象的來講,多態的意思就是同一消息可以根據發送對象的不同而采用多種不同的行為方式。(發送消息就是函數調用)
- 實現的原理是動態綁定,程序調用的方法在運行期才動態綁定,追溯源碼可以發現,JVM 通過參數的自動轉型來找到合適的辦法。
7.abstractclass和interface語法上有什么區別?
抽象類可以有構造方法,接口中不能有構造方法。
抽象類中可以有普通成員變量,接口中沒有普通成員變量
抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。
抽象類中的抽象方法的訪問類型可以是public,protected和(默認類型,雖然eclipse下不報錯,但應該也不行),但接口中的抽象方法只能是public類型的,並且默認即為public abstract類型。
抽象類中可以包含靜態方法,接口中不能包含靜態方法
抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是publicstatic final類型,並且默認即為publicstatic final類型。
一個類可以實現多個接口,但只能繼承一個抽象類。
8.abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
- abstract的method不可以是static的,因為抽象的方法是要被子類實現的,而static與子類扯不上關系!
- native方法表示該方法要用另外一種依賴平台的編程語言實現的,不存在着被子類實現的問題,所以,它也不能是抽象的,不能與abstract混用。
- synchronized與abstract不可同時修飾一個方法,synchronized應該是作用在一個具體的方法上才有意義.
9.內部類可以引用它的包含類的成員嗎?有沒有什么限制?
完全可以。如果不是靜態內部類,那沒有什么限制!如果你把靜態嵌套類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員.
10.String s = "Hello";s = s + "world!";這兩行代碼執行后,原始的String對象中的內容到底變了沒有?
-
沒有。因為String被設計成不可變(immutable)類,所以它的所有對象都是不可變對象。在這段代碼中,s原先指向一個String對象,內容是 "Hello",然后我們對s進行了+操作,那么s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另一個 String對象,內容為"Hello world!",原來那個對象還存在於內存之中,只是s這個引用變量不再指向它了。
-
通過上面的說明,我們很容易導出另一個結論,如果經常對字符串進行各種各樣的修改,或者說,不可預見的修改,那么使用String來代表字符串的話會引起很大的內存開銷。因為String對象建立之后不能再改變,所以對於每一個不同的字符串,都需要一個String對象來表示。這時,應該考慮使用StringBuffer類,它允許修改,而不是每個不同的字符串都要生成一個新的對象。
11.String s = new String("xyz");創建了幾個StringObject?是否可以繼承String類?
兩個或一個都有可能,”xyz”對應一個對象,這個對象放在字符串常量緩沖區,常量”xyz”不管出現多少遍,都是緩沖區中的那一個。new String每寫一遍,就創建一個新的對象 ,它使用常量”xyz”對象的內容來創建出一個新String對象。如果以前就用過’xyz’,那么這里就不會創建”xyz”了,直接從緩沖區拿,這時創建了一個StringObject;但如果以前沒有用過"xyz",那么此時就會創建一個對象並放入緩沖區,這種情況它創建兩個對象。至於String類是否繼承,答案是否定的,因為 String默認final修飾,是不可繼承的 。
12.String、StringBuffer與StringBuilder的區別?
-
String 類型和 StringBuffer 類型的主要性能區別其實在於 String 是不可變的對象
-
StringBuffer和StringBuilder底層是 char[]數組實現的
-
StringBuffer是線程安全的,而StringBuilder是線程不安全的
13.對於如下代碼:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一條語句打印的結果為false,s2=a1+"b",相當於構建了一個新的string對象,並將對象引用賦予s2變量,s2的變量值此時就和常量池中“ab”不一致了,只是他們對象值是相等的。
第二條語句打印的結果為true.javac編譯可以對字符串常量直接相加的表達式進行優化,不必要等到運行期再去進行加法運算處理,而是在編譯時去掉其中的加號,直接將其編譯成一個這些常量相連的結果.
14.下面這條語句一共創建了多少個對象:String s="a"+"b"+"c"+"d";
第一行代碼被編譯器在編譯時優化后,相當於直接定義了一個”abcd”的字符串,所以,上面的代碼應該只創建了一個String對象。
15.try {}里有一個return語句,那么緊跟在這個try后的finally{}里的code會不會被執行,什么時候被執行,在return前還是后?
首先finally{}中的語句是一定會執行的,那么這個可能正常脫口而出就是return之前.
16.final, finally, finalize的區別?
- final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。內部類要訪問局部變量,局部變量必須定義成final類型。
- finally是異常處理語句結構的一部分,表示總是執行。
- finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。但是JVM不保證此方法總被調用.
17.error和exception有什么區別?
error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。不可能指望程序能處理這樣的情況。exception表示一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。
18.簡單說說Java中的異常處理機制的簡單原理和應用。
異常是指java程序運行時(非編譯)所發生的非正常情況或錯誤,與現實生活中的事件很相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等信息,可以用一個對象來表示,Java使用面向對象的方式來處理異常,它把程序中發生的每個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息。
Java對異常進行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個子類: Error和Exception,Error表示應用程序本身無法克服和恢復的一種嚴重問題,程序只有奔潰了,例如,說內存溢出和線程死鎖等系統問題。
19.Java中堆和棧有什么區別?
-
JVM 中堆和棧屬於不同的內存區域,使用目的也不同。棧常用於保存方法幀和局部變量,而對象總是在堆上分配。棧通常都比堆小,也不會在多個線程之間共享,而堆被整個 JVM 的所有線程共享。
-
棧:在函數中定義的一些基本類型的變量和對象的引用變量都是在函數的棧內存中分配,當在一段代碼塊定義一個變量時,Java 就在棧中為這個變量分配內存空間,當超過變量的作用域后,Java 會自動釋放掉為該變量分配的內存空間,該內存空間可以立即被另作它用。
-
棧內存是指程序進入一個方法時,會為這個方法單獨分配一塊私屬存儲空間,用於存儲這個方法內部的局部變量,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。
-
堆:堆內存用來存放由 new 創建的對象和數組,在堆中分配的內存,由 Java 虛擬機的自動垃圾回收器來管理。
20.能將 int 強制轉換為 byte 類型的變量嗎?如果該值大於 byte 類型的范圍,將會出現什么現象?
可以做強制轉換,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果強制轉化,int 類型的高 24 位將會被丟棄,因為byte 類型的范圍是從 -128 到 127。
21.a.hashCode() 有什么用?與 a.equals(b) 有什么關系?
hashCode() 方法對應對象整型的 hash 值。它常用於基於 hash 的集合類,如 Hashtable、HashMap、LinkedHashMap等等。它與 equals() 方法關系特別緊密。根據 Java 規范,兩個使用 equal() 方法來判斷相等的對象,必須具有相同的 hashcode。
java集合中有 list 和 set 兩類,其中 set不允許元素重復實現,那個這個不允許重復實現的方法,如果用 equal 去比較的話,如果存在1000個元素,你 new 一個新的元素出來,需要去調用1000次 equal 去逐個和他們比較是否是同一個對象,這樣會大大降低效率。hashcode實際上是返回對象的存儲地址,如果這個位置上沒有元素,就把元素直接存儲在上面,如果這個位置上已經存在元素,這個時候才去調用equal方法與新元素進行比較,相同的話就不存了,散列到其他地址上
22.字節流與字符流的區別?
要把一段二進制數據數據逐一輸出到某個設備中,或者從某個設備中逐一讀取一段二進制數據,不管輸入輸出設備是什么,我們要用統一的方式來完成這些操作,用一種抽象的方式進行描述,這個抽象描述方式起名為IO流,對應的抽象類為OutputStream和InputStream,不同的實現類就代表不同的輸入和輸出設備,它們都是針對字節進行操作的。
底層設備永遠只接受字節數據,有時候要寫字符串到底層設備,需要將字符串轉成字節再進行寫入。字符流是字節流的包裝,字符流則是直接接受字符串,它內部將串轉成字節,再寫入底層設備,這為我們向IO設備寫入或讀取字符串提供了一點點方便。
23.什么是java序列化,如何實現java序列化?Serializable接口的作用?
將一個java對象變成字節流的形式傳出去稱為序列化,從字節流中恢復一個對象稱為反序列化。 實現serializable接口,這樣,javac編譯時就會進行特殊處理,編譯的類才可以被writeObject方法操作,這就是所謂的序列化。需要被序列化的類必須實現Serializable接口,該接口是一個mini接口,其中沒有需要實現方法,implements Serializable只是為了標注該對象是可被序列化的。
24.Java 中,throw 和 throws 有什么區別
- throw代表的是動作,throws是狀態
- throw用在方法中,而throws用在方法聲明中
- throw只能拋出一種異常,而throws可以拋出多個
25.volatile關鍵字是否能保證線程安全?
否,volatile變量自身具有下列特性: 1. 可見性:對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入。 2. 禁止進行指令重排序 3. 不保證原子性:對任意單個volatile變量的讀/寫具有原子性,但類似於volatile++這種符合操作不具有原子性。 多線程共享變量的讀寫是通過主內存進行復制到線程本地內存中和把本地內存中值寫入主內存中來實現的。
當寫一個volatile變量時,JMM(Java內存模型)會把該線程對應的本地內存中的共享變量值刷新到主內存。
當讀一個volatile變量時,JMM會把該線程對應的本地內存置為無效。線程接下來將從住內存中讀取共享變量。
只能在有限的一些情形下使用 volatile 變量替代鎖。要使 volatile 變量提供理想的線程安全,必須同時滿足下面兩個條件:
- 對變量的寫操作不依賴於當前值。
- 該變量沒有包含在具有其他變量的不變式中。
正確使用 volatile 的模式
- 模式 #1:狀態標志 >這種類型的狀態標記的一個公共特性是:通常只有一種狀態轉換;volatile 變量僅僅是使用一個布爾狀態標志,用於指示發生了一個重要的一次性事件,例如完成初始化或請求停機。
- 模式 #2:一次性安全發布(one-time safe publication) >實現安全發布對象的一種技術就是將對象引用定義為 volatile 類型。該模式的一個必要條件是:被發布的對象必須是線程安全的,或者是有效的不可變對象(有效不可變意味着對象的狀態在發布之后永遠不會被修改)。volatile 類型的引用可以確保對象的發布形式的可見性,但是如果對象的狀態在發布后將發生更改,那么就需要額外的同步。
- 模式 #3:獨立觀察(independent observation) >安全使用 volatile 的另一種簡單模式是:定期 “發布” 觀察結果供程序內部使用。該模式是前面模式的擴展;將某個值發布以在程序內的其他地方使用,但是與一次性事件的發布不同,這是一系列獨立事件。這個模式要求被發布的值是有效不可變的 —— 即值的狀態在發布后不會更改。使用該值的代碼需要清楚該值可能隨時發生變化。
- 模式 #4:“volatile bean” 模式 >volatile bean 模式適用於將 JavaBeans 作為“榮譽結構”使用的框架。在 volatile bean 模式中,JavaBean 被用作一組具有 getter 和/或 setter 方法 的獨立屬性的容器。volatile bean 模式的基本原理是:很多框架為易變數據的持有者(例如 HttpSession)提供了容器,但是放入這些容器中的對象必須是線程安全的。在 volatile bean 模式中,JavaBean 的所有數據成員都是 volatile 類型的,並且 getter 和 setter 方法必須非常普通 —— 除了獲取或設置相應的屬性外,不能包含任何邏輯。此外,對於對象引用的數據成員,引用的對象必須是有效不可變的。(這將禁止具有數組值的屬性,因為當數組引用被聲明為 volatile 時,只有引用而不是數組本身具有 volatile 語義)。對於任何 volatile 變量,不變式或約束都不能包含 JavaBean 屬性。
-
模式 #5:開銷較低的讀-寫鎖策略 >如果讀操作遠遠超過寫操作,您可以結合使用內部鎖和 volatile 變量來減少公共代碼路徑的開銷。
>結合使用 volatile 和 synchronized 實現 “開銷較低的讀-寫鎖”
@ThreadSafe public class CheesyCounter { // Employs the cheap read-write lock trick // All mutative operations MUST be done with the 'this' lock held @GuardedBy("this") private volatile int value;
public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
之所以將這種技術稱之為 “開銷較低的讀-寫鎖” 是因為您使用了不同的同步機制進行讀寫操作。因為本例中的寫操作違反了使用 volatile 的第一個條件,因此不能使用 volatile 安全地實現計數器 —— 您必須使用鎖。然而,您可以在讀操作中使用 volatile 確保當前值的可見性,因此可以使用鎖進行所有變化的操作,使用 volatile 進行只讀操作。其中,鎖一次只允許一個線程訪問值,volatile 允許多個線程執行讀操作,因此當使用 volatile 保證讀代碼路徑時,要比使用鎖執行全部代碼路徑獲得更高的共享度 —— 就像讀-寫操作一樣。
26.Java能不能不通過構造函數創建對象()
*能
Java創建對象的幾種方式: 1. 用new語句創建對象,這是最常見的創建對象的方法。 2. 運用反射手段,調用java.lang.Class或者java.lang.reflect.Constructor類的newInstance()實例方法。 3. 調用對象的clone()方法。 4. 運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。 (1)和(2)都會明確的顯式的調用構造函數 ;(3)是在內存上對已有對象的影印,所以不會調用構造函數 ;(4)是從文件中還原類的對象,也不會調用構造函數。
27.下列哪個敘述是正確的()
- A.子類繼承父類的構造方法。
- B.abstract類的子類必須是非abstract類。
- C.子類繼承的方法只能操作子類繼承和隱藏的成員變量。
- D.子類重寫或新增的方法也能直接操作被子類隱藏的成員變量。
答案:C
28.下列哪個敘述是正確的()
- A.final類可以有子類。
- B.abstract類中只可以有abstract方法。
- C.abstract類中可以有非abstract方法,但該方法不可以用final修飾。
- D.不可以同時用final和abstract修飾同一個方法。
- E.允許使用static修飾abstract方法。
答案:D
29.當檢索一個壓縮文件時,首先要建立壓縮文件輸入流對象,該對象()
- A、以選中的壓縮文件為參數
- B、以FileInputStream對象為參數
- C、以InputStreamReader對象為參數
- D、以BufferedReader對象為參數 答案:B 在java.io包中提供了對壓縮文件進行操作的能力。它是通過壓縮文件輸入流與壓縮文件輸出流來實現的,其分別繼承自InflaterInputStream與DeflaterOutputStream。
在創建壓縮文件輸入流時,其初始化參數是一個FileInputStream類的實例。
30.下列選項中,不屬於模塊間耦合的是( )
- A.數據耦合
- B.標記耦合
- C.異構耦合
- D.公共耦合 答案:C 模塊之間的耦合程度反映了模塊的獨立性,也反映了系統分解后的復雜程度。 按照耦合程度從弱到強,可以將其分成7級。
分別是非直接耦合、數據耦合、標記耦合、控制耦合、外部耦合、公共耦合和內容耦合。其中沒有異構耦合這種方式。
31.什么是LinkedHashSet()
- A、是一個HashSet,保留了對象插入的順序
- B、是一個HashSet,擁有一個鏈表的性能
- C、是一個HashSet,能很容易地轉換為一個鏈表
- D、HashSet對象的超類 正確答案:A
擴展:
LinkedHashSet是HashSet的一個“擴展版本”,HashSet並不管什么順序,不同的是LinkedHashSet會維護“插入順序”。HashSet內部使用HashMap對象來存儲它的元素,而LinkedHashSet內部使用LinkedHashMap對象來存儲和處理它的元素。
32.以下兩個片段執行結果差異的原因是什么?
片段一: short s=1; s=s+1;
片段二: short s=1; s+=1;
片段一是編譯不通過的 ,提示損失精度 。 s=s+1這句先執行s+1然后把結果賦給s,由於1為int類型,所以s+1的返回值是int,編譯器自動進行了隱式類型轉換,所以將一個int類型賦給short就會出錯。 而s+=1不同,由於他是使用+=操作符,在解析的時候s+=1就等價於s = (short)(s+1),也就是s+=1 <=> s = (s的類型)(s+1)。
33.基本數據類型之間的轉換規則
- 在一個雙操作數以及位運算等算術運算式中,會根據操作數的類型將低級的數據類型自動轉換為高級的數據類型,分為以下幾種情況:
1)只要兩個操作數中有一個是double類型的,另一個將會被轉換成double類型,並且結果也是double類型;
2)只要兩個操作數中有一個是float類型的,另一個將會被轉換成float類型,並且結果也是float類>型;
3)只要兩個操作數中有一個是long類型的,另一個將會被轉換成long類型,並且結果也是long類型;
4)兩個操作數(包括byte、short、int、char)都將會被轉換成int類型,並且結果也是int類型。
- 如果低級類型為char型,向高級類型(整型)轉換時,會轉換為對應ASCII碼值,再做其它類型的自動轉換。
-
對於byte,short,char三種類型而言,他們是平級的,因此不能相互自動轉換,可以使用下述的強制類型轉換。 如: >short i=99 ; char c=(char)i; System.out.println("output:"+c);
-
不能在布爾值和任何數字類型間強制類型轉換;
-
不同級別數據類型間的強制轉換,可能會導致溢出或精度的下降。
-
當字節類型變量參與運算,java作自動數據運算類型的提升,將其轉換為int類型。
34.float f=3.4;是否正確?
答:不正確。3.4是雙精度數,將雙精度型(double)賦值給浮點型(float)屬於下轉型(down-casting,也稱為窄化)會造成精度損失,因此需要強制類型轉換float f =(float)3.4; 或者寫成float f =3.4F;。
35.面向對象的特征有哪些方面?
-
抽象:抽象是將一類對象的共同特征總結出來構造類的過程,包括數據抽象和行為抽象兩方面。抽象只關注對象有哪些屬性和行為,並不關注這些行為的細節是什么。
-
繼承:繼承是從已有類得到繼承信息創建新類的過程。提供繼承信息的類被稱為父類(超類、基類);得到繼承信息的類被稱為子類(派生類)。繼承讓變化中的軟件系統有了一定的延續性,同時繼承也是封裝程序中可變因素的重要手段。
-
封裝:通常認為封裝是把數據和操作數據的方法綁定起來,對數據的訪問只能通過已定義的接口。面向對象的本質就是將現實世界描繪成一系列完全自治、封閉的對象。我們在類中編寫的方法就是對實現細節的一種封裝;我們編寫一個類就是對數據和數據操作的封裝。可以說,封裝就是隱藏一切可隱藏的東西,只向外界提供最簡單的編程接口(可以想想普通洗衣機和全自動洗衣機的差別,明顯全自動洗衣機封裝更好因此操作起來更簡單;我們現在使用的智能手機也是封裝得足夠好的,因為幾個按鍵就搞定了所有的事情)。
-
多態性:多態性是指允許不同子類型的對象對同一消息作出不同的響應。簡單的說就是用同樣的對象引用調用同樣的方法但是做了不同的事情。多態性分為編譯時的多態性和運行時的多態性。如果將對象的方法視為對象向外界提供的服務,那么運行時的多態性可以解釋為:當A系統訪問B系統提供的服務時,B系統有多種提供服務的方式,但一切對A系統來說都是透明的。方法重載(overload)實現的是編譯時的多態性(也稱為前綁定),而方法重寫(override)實現的是運行時的多態性(也稱為后綁定)。運行時的多態是面向對象最精髓的東西,要實現多態需要做兩件事:1). 方法重寫(子類繼承父類並重寫父類中已有的或抽象的方法);2). 對象造型(用父類型引用引用子類型對象,這樣同樣的引用調用同樣的方法就會根據子類對象的不同而表現出不同的行為)。
36.ava有沒有goto?
答:goto 是Java中的保留字,在目前版本的Java中沒有使用。
37.&和&&的區別?
- &運算符有兩種用法:(1)按位與;(2)邏輯與。
- &&運算符是短路與運算。 >如果&&左邊的表達式的值是false,右邊的表達式會被直接短路掉,不會進行運算。
38.在JAVA與JSP中要調用一個LINUX上的腳本程序,或WINDOWS上的腳本程序,該怎么寫?
答:System.getRuntime().exec("bash < aaa.sh");
39.jsp如何獲得客戶端的IP地址?
答: request.getRemoteAddr()
40.提交表單后驗證沒有通過,返回提交頁面,如何使原提交頁面中的數據保留?
答:javascript的go(-1)可以把上頁的表單內容重新顯示出來,但password域沒有。 疑問,現在不都是異步提交嗎?還有同步表單提交的方式?
41.表單成功提交了,點后退顯示網頁過期
答: 在\<head>\</head>里面加以下代碼 : <br> \<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
\<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
\<META HTTP-EQUIV="Expires" CONTENT="0">
或者在表單頁中加上 <br> \<%
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires",0);
\%>
42.WEB上面怎么樣連接上一個EXCEL表格?
答: 定義頁面得contentType="application/vnd.ms-excel",讓頁面以excel得形式打開。同樣也可以以word得形式打開:application/msword。
43.indexOf()的使用需要注意什么?
答:參數是指從第幾位(1,2,3,...)開始搜索,而返回值是指搜索到的位置(0,1,2,3.......)注意是從零算起的。
44.Switch能否用string做參數?
在 Java 7 之前, switch 只能支持byte,short,char,int 或者其對應的封裝類,以及 Enum 類型。在JAVA 7中,String 支持被加上了。
45.什么是OOM?
> OOM,全稱“Out Of Memory”,翻譯成中文就是“內存用完了”,來源於java.lang.OutOfMemoryError。看下關於的官方說明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. 意思就是說,當JVM因為沒有足夠的內存來為對象分配空間並且垃圾回收器也已經沒有空間可回收時,就會拋出這個error(注:非exception,因為這個問題已經嚴重到不足以被應用處理)
### 46.4. Java的四種引用,強弱軟虛,用到的場景 1. 強引用:如果一個對象具有強引用,它就不會被垃圾回收器回收。即使當前內存空間不足,JVM也不會回收它,而是拋出 OutOfMemoryError 錯誤,使程序異常終止。如果想中斷強引用和某個對象之間的關聯,可以顯式地將引用賦值為null,這樣一來的話,JVM在合適的時間就會回收該對象 2. 軟引用:在使用軟引用時,如果內存的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收,只有在內存不足時,軟引用才會被垃圾回收器回收。 3. 弱引用:具有弱引用的對象擁有的生命周期更短暫。因為當 JVM 進行垃圾回收,一旦發現弱引用對象,無論當前內存空間是否充足,都會將弱引用回收。不過由於垃圾回收器是一個優先級較低的線程,所以並不一定能迅速發現弱引用對象. 4. 虛引用:顧名思義,就是形同虛設,如果一個對象僅持有虛引用,那么它相當於沒有引用,在任何時候都可能被垃圾回收器回收。
. 利用軟引用和弱引用解決OOM問題:用一個HashMap來保存圖片的路徑和相應圖片對象關聯的軟引用之間的映射關系,在內存不足時,JVM會自動回收這些緩存圖片對象所占用的空間,從而有效地避免了OOM的問題 . 通過軟可及對象重獲方法實現Java對象的高速緩存:比如我們創建了一Employee的類,如果每次需要查詢一個雇員的信息。哪怕是幾秒中之前剛剛查詢過的,都要重新構建一個實例,這是需要消耗很多時間的。我們可以通過軟引用和 HashMap 的結合,先是保存引用方面:以軟引用的方式對一個Employee對象的實例進行引用並保存該引用到HashMap 上,key 為此雇員的 id,value為這個對象的軟引用,另一方面是取出引用,緩存中是否有該Employee實例的軟引用,如果有,從軟引用中取得。如果沒有軟引用,或者從軟引用中得到的實例是null,重新構建一個實例,並保存對這個新建實例的軟引用.
47.解析XML的幾種方式的原理與特點:DOM、SAX、PULL
-
DOM:DOM的全稱是Document Object Model,也即文檔對象模型。在應用程序中,基於DOM的XML分析器將一個XML文檔轉換成一個對象模型的集合(通常稱DOM樹),應用程序正是通過對這個對象模型的操作,來實現對XML文檔數據的操作。通過DOM接口,應用程序可以在任何時候訪問XML文檔中的任何一部分數據,因此,這種利用DOM接口的機制也被稱作隨機訪問機制。 > 優點: >1. 形成了樹結構,有助於更好的理解、掌握,且代碼容易編寫。 >2. 解析過程中,樹結構保存在內存中,方便修改。 > 缺點: >1. 由於文件是一次性讀取,所以對內存的耗費比較大。 >2. 如果XML文件比較大,容易影響解析性能且可能會造成內存溢出。
-
SAX:SAX的全稱是Simple APIs for XML,也即XML簡單應用程序接口。與DOM不同,SAX提供的訪問模式是一種順序模式,這是一種快速讀寫XML數據的方式。當使用SAX分析器對XML文檔進行分析時,會觸發一系列事件,並激活相應的事件處理函數,應用程序通過這些事件處理函數實現對XML文檔的訪問,因而SAX接口也被稱作事件驅動接口。 > 優點: >1. 采用事件驅動模式,對內存耗費比較小。 >2. 適用於只處理XML文件中的數據時。 > 缺點: >1. 編碼比較麻煩。 >2. 很難同時訪問XML文件中的多處不同數據。
- PULL: 與 SAX 類似,也是基於事件驅動,我們可以調用它的next()方法,來獲取下一個解析事件(就是開始文檔,結束文檔,開始標簽,結束標簽),當處於某個元素時可以調用XmlPullParser的getAttributte()方法來獲取屬性的值,也可調用它的nextText()獲取本節點的值。
48.java中 sleep 和 wait 的區別
- 來自不同的類 : sleep來自Thread類,是Thread類的靜態方法。而wait來自於object類。sleep是Thread的靜態方法,那個線程調用的了sleep,那個線程就會休眠.
- 持有鎖:這一點很重要,sleep是沒有釋放鎖的,使得該線程仍然占用這系統資源,wait方法則會釋放鎖,使得其他線程可以使用同步控制塊或者方法。sleep 不釋放系統資源並且有時間限制,需要調用sleep(milliseconds)來指定休眠時間 wait會釋放資源,並且進入線程等待池等待,這個時候其他線程可以占用CPU,直到其他線程調用notify/notifyAll喚醒等待池中的線程,然后進入就緒隊列等待系統分配資源
- 使用范圍: wait,notify,notifyAll只能在synchronized塊中或者synchronied控制的方法中調用。而sleep可以在任何地方調用
49.JAVA 垃圾回收算法?
- 標記回收法:遍歷對象圖並且記錄可到達的對象,以便刪除不可到達的對象,一般使用單線程工作並且可能產生內存碎片
- 標記-壓縮回收法:前期與第一種方法相同,只是多了一步,將所有的存活對象壓縮到內存的一端,這樣內存碎片就可以合成一大塊可再利用的內存區域,提高了內存利用率
- 復制回收法:把現有內存空間分成兩部分,gc運行時,它把可到達對象復制到另一半空間,再清空正在使用的空間的全部對象。這種方法適用於短生存期的對象,持續復制長生存期的對象則導致效率降低。
- 分代回收發:把內存空間分為兩個或者多個域,如年輕代和老年代,年輕代的特點是對象會很快被回收,因此在年輕代使用效率比較高的算法。當一個對象經過幾次回收后依然存活,對象就會被放入稱為老年的內存空間,老年代則采取標記-壓縮算法
- 引用計數(最簡單古老的方法):指將資源(可以是對象、內存或磁盤空間等等)的被引用次數保存起來,當被引用次數變為零時就將其釋放的過程
- 對象引用遍歷(現在大多數 jvm 使用的方法):對象引用遍歷從一組對象開始,沿着整個對象圖上的每條鏈接,遞歸確定可到達(reachable)的對象。如果某對象不能從這些根對象的一個(至少一個)到達,則將它作為垃圾收集
50.內存溢出和內存泄露
- 內存溢出(out of memory),是指程序在申請內存時,沒有足夠的內存空間供其使用
- 內存泄露(menory leak):是指程序在申請內存后,無法釋放已申請的內存空間。簡單點說及就是,內存中存在可到達(即在有向圖中,存在通路可以與其相連)且不再使用的對象。
51.JVM的組成部分
- Class Loader 類加載器
- Execution Engine 執行引擎,執行引擎也叫做解釋器(Interpreter) ,負責解釋命令,提交操作系統執行。
- Native Interface 本地接口
- Runtime data area 運行數據區
52.synchronized和lock的區別?
- 主要相同點:Lock能完成Synchronized所實現的所有功能。
- > 主要不同點:Lock有比Synchronized更精確的線程予以和更好的性能。 > 1. Synchronized會自動釋放鎖,但是Lock一定要求程序員手工釋放,並且必須在finally從句中釋放。 > 2. synchronized修飾方法時 表示同一個對象在不同的線程中 表現為同步隊列 如果實例化不同的對象 那么synchronized就不會出現同步效果了。
53.什么是值傳遞和引用傳遞?java中是值傳遞還是引用傳遞,還是都有?
- 對象被值傳遞,意味着傳遞了對象的一個副本。因此,就算是改變了對象副本,也不會影響源對象的值。
- 對象被引用傳遞,意味着傳遞的並不是實際的對象,而是對象的引用。因此,外部對引用對象所做的改變會反映到所有的對象上。 >>java中方法參數傳遞方式是按值傳遞。 如果參數是基本類型,傳遞的是基本類型的字面量值的拷貝。 如果參數是引用類型,傳遞的是該參量所引用的對象在堆中地址值的拷貝。
54..構造器(constructor)是否可被重寫(override)?
構造方法是不能被子類重寫的,但是構造方法可以重載,也就是說一個類可以有多個構造方法。
55.happens-before規則:
- 程序順序規則: 一個線程中的每個操作,happens-before於該線程中的任意后續操作。 >在一個線程里,所有的操作都是按順序的,但是在JMM里其實只要執行結果一樣,是允許重排序的,這邊的happens-before強調的重點也是單線程執行結果的正確性,但是無法保證多線程也是如此。
- 監視器鎖規則:對一個線程的解鎖,happens-before於隨后對這個線程的加鎖.
- volatile變量規則: 對一個volatile域的寫,happens-before於后續對這個volatile域的讀 > 如果一個線程去寫一個變量,同時另外一個線程再去讀,那么寫入操作一定在讀操作之前。
- 傳遞性:如果A happens-before B ,且 B happens-before C, 那么 A happens-before C
- start()規則: 如果線程A執行操作ThreadBstart()(啟動線程B) , 那么A線程的ThreadBstart()happens-before 於B中的任意操作
- join()原則: 如果A執行ThreadB.join()並且成功返回,那么線程B中的任意操作happens-before於線程A從ThreadB.join()操作成功返回。
- interrupt()原則: 對線程interrupt()方法的調用先行發生於被中斷線程代碼檢測到中斷事件的發生,可以通過Thread.interrupted()方法檢測是否有中斷發生
- finalize()原則:一個對象的初始化完成先行發生於它的finalize()方法的開始
56.創建線程有幾種不同的方式?你喜歡哪一種?為什么?
有三種方式可以用來創建線程: 1. 繼承Thread類 2. 實現Runnable接口 3. 應用程序可以使用Executor框架來創建線程池
57.Comparable和Comparator接口是干什么的?列出它們的區別。
-
Java提供了只包含一個compareTo()方法的Comparable接口。這個方法可以個給兩個對象排序。具體來說,它返回負數,0,正數來表明輸入對象小於,等於,大於已經存在的對象。
-
Java提供了包含compare()和equals()兩個方法的Comparator接口。compare()方法用來給兩個輸入參數排序,返回負數,0,正數表明第一個參數是小於,等於,大於第二個參數。equals()方法需要一個對象作為參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator並且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。
58.finalize()方法什么時候被調用?
在釋放對象占用的內存之前,且對象的finalize()還沒被垃圾收集器調用過,則垃圾收集器會調用對象的finalize()方法。
59.如果對象的引用被置為null,垃圾收集器是否會立即釋放對象占用的內存?
不會,在下一個垃圾回收周期中,這個對象將是可被回收的。
60.什么是JDBC?
JDBC(Java Data Base Connectivity,java數據庫連接)是一種用於執行SQL語句的Java API,可以為多種關系數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基准,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序。
61.面向對象的五大基本原則
- 單一職責原則SRP(Single Responsibility Principle) >>一個類應該僅有一個引起它變化的原因,例如:比如在職員類里,將工程師、銷售人員、銷售經理這些情況都放在職員類里考慮,其結果將會非常混亂,在這個假設下,職員類里的每個方法都要if else判斷是哪種情況,從類結構上來說將會十分臃腫,並且上述三種的職員類型,不論哪一種發生需求變化,都會改變職員類!這個是大家所不願意看到的!
- 開放封閉原則OCP(Open-Close Principle)
- 既開放又封閉,對擴展是開放的,對更改是封閉的!
-
擴展即擴展現行的模塊,當我們軟件的實際應用發生改變時,出現新的需求,就需要我們對模塊進行擴展,使其能夠滿足新的需求!
-
替換原則(the Liskov Substitution Principle LSP) >* 子類可以替換父類並且出現在父類能夠出現的任何地方 >>在這個原則中父類應盡可能使用接口或者抽象類來實現!,子類通過實現了父類接口,能夠替父類的使用地方! 通過這個原則,我們客戶端在使用父類接口的時候,通過子類實現! 意思就是說我們依賴父類接口,在客戶端聲明一個父類接口,通過其子類來實現 這個時候就要求子類必須能夠替換父類所出現的任何地方,這樣做的好處就是,在根據新要求擴展父類接口的新子類的時候而不影響當前客戶端的使用!
-
依賴倒置原則(the Dependency Inversion Principle DIP) 具體依賴抽象,上層依賴下層。 > 傳統的結構化編程中,最上層的模塊通常都要依賴下面的子模塊來實現,也稱為高層依賴低層! 所以DIP原則就是要逆轉這種依賴關系,讓高層模塊不要依賴低層模塊,所以稱之為依賴倒置原則!
-
接口分離原則(the Interface Segregation Principle ISP) 模塊間要通過抽象接口隔離開,而不是通過具體的類強耦合起來
62.用最有效率的方法計算2乘以8?
答: 2 << 3(左移3位相當於乘以2的3次方,右移3位相當於除以2的3次方)。
63.在Java中,如何跳出當前的多重嵌套循環?
在最外層循環前加一個標記如A,然后用break A;可以跳出多重循環。
64.兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
答:不對,如果兩個對象x和y滿足x.equals(y) == true,它們的哈希碼(hash code)應當相同。Java對於eqauls方法和hashCode方法是這樣規定的: 1. 如果兩個對象相同(equals方法返回true),那么它們的hashCode值一定要相同; 2. 如果兩個對象的hashCode相同,它們並不一定相同。
如果違背了上述原則就會發現在使用容器時,相同的對象可以出現在Set集合中,同時增加新元素的效率會大大下降(對於使用哈希存儲的系統,如果哈希碼頻繁的沖突將會造成存取性能急劇下降)。
65.是否可以繼承String類?
答:String 類是final類,不可以被繼承。
66.char 型變量中能不能存貯一個中文漢字,為什么?
答:char類型可以存儲一個中文漢字,因為Java中使用的編碼是Unicode(不選擇任何特定的編碼,直接使用字符在字符集中的編號,這是統一的唯一方法),一個char類型占2個字節(16比特),所以放一個中文是沒問題的。
補充:使用Unicode意味着字符在JVM內部和外部有不同的表現形式,在JVM內部都是Unicode,當這個字符被從JVM內部轉移到外部時(例如存入文件系統中),需要進行編碼轉換。所以Java中有字節流和字符流,以及在字符流和字節流之間進行轉換的轉換流,如InputStreamReader和OutputStreamReader,這兩個類是字節流和字符流之間的適配器類,承擔了編碼轉換的任務;對於C程序員來說,要完成這樣的編碼轉換恐怕要依賴於union(聯合體/共用體)共享內存的特征來實現了。
67.如何實現對象克隆?
答:有兩種方式: 1. 實現Cloneable接口並重寫Object類中的clone()方法; 2. 實現Serializable接口,通過對象的序列化和反序列化實現克隆,可以實現真正的深度克隆,代碼如下。 注意:基於序列化和反序列化實現的克隆不僅僅是深度克隆,更重要的是通過泛型限定,可以檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,不是在運行時拋出異常,這種是方案明顯優於使用Object類的clone方法克隆對象。讓問題在編譯的時候暴露出來總是優於把問題留到運行時。
68.Collection和Collections的區別?
答:Collection是一個接口,它是Set、List等容器的父接口;Collections是個一個工具類,提供了一系列的靜態方法來輔助容器操作,這些方法包括對容器的搜索、排序、線程安全化等等。
69.事務的ACID是指什么?
- 原子性(Atomic):事務中各項操作,要么全做要么全不做,任何一項操作的失敗都會導致整個事務的失敗;
- 一致性(Consistent):事務結束后系統狀態是一致的;
- 隔離性(Isolated):並發執行的事務彼此無法看到對方的中間狀態;
-
持久性(Durable):事務完成后所做的改動都會被持久化,即使發生災難性的失敗。通過日志和同步備份可以在故障發生后重建數據。
-
臟讀(Dirty Read):A事務讀取B事務尚未提交的數據並在此基礎上操作,而B事務執行回滾,那么A讀取到的數據就是臟數據。
- 不可重復讀(Unrepeatable Read):事務A重新讀取前面讀取過的數據,發現該數據已經被另一個已提交的事務B修改過了。
- 幻讀(Phantom Read):事務A重新執行一個查詢,返回一系列符合查詢條件的行,發現其中插入了被事務B提交的行。
70.設計模式
共23種設計模式,包括:Abstract Factory(抽象工廠模式),Builder(建造者模式),Factory Method(工廠方法模式),Prototype(原始模型模式),Singleton(單例模式);Facade(門面模式),Adapter(適配器模式),Bridge(橋梁模式),Composite(合成模式),Decorator(裝飾模式),Flyweight(享元模式),Proxy(代理模式);Command(命令模式),Interpreter(解釋器模式),Visitor(訪問者模式),Iterator(迭代子模式),Mediator(調停者模式),Memento(備忘錄模式),Observer(觀察者模式),State(狀態模式),Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibility(責任鏈模式)。 1. 工廠模式:工廠類可以根據條件生成不同的子類實例,這些子類有一個公共的抽象父類並且實現了相同的方法,但是這些方法針對不同的數據進行了不同的操作(多態方法)。當得到子類的實例后,開發人員可以調用基類中的方法而不必考慮到底返回的是哪一個子類的實例。 2. 代理模式:給一個對象提供一個代理對象,並由代理對象控制原對象的引用。實際開發中,按照使用目的的不同,代理可以分為:遠程代理、虛擬代理、保護代理、Cache代理、防火牆代理、同步化代理、智能引用代理。 3. 適配器模式:把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起使用的類能夠一起工作。 4. 模板方法模式:提供一個抽象類,將部分邏輯以具體方法或構造器的形式實現,然后聲明一些抽象方法來迫使子類實現剩余的邏輯。不同的子類可以以不同的方式實現這些抽象方法(多態實現),從而實現不同的業務邏輯。 除此之外,還可以講講上面提到的門面模式、橋梁模式、單例模式、裝潢模式(Collections工具類和I/O系統中都使用裝潢模式)等,反正基本原則就是揀自己最熟悉的、用得最多的作答,以免言多必失。
71.什么是線程?
線程是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。程序員可以通過它進行多處理器編程,你可以使用多線程對運算密集型任務提速。
72.線程和進程有什么區別?
線程是進程的子集,一個進程可以有很多線程,每條線程並行執行不同的任務。不同的進程使用不同的內存空間,而所有的線程共享一片相同的內存空間。別把它和棧內存搞混,每個線程都擁有單獨的棧內存用來存儲本地數據。
73.Thread 類中的start() 和 run() 方法有什么區別?
這個問題經常被問到,但還是能從此區分出面試者對Java線程模型的理解程度。start()方法被用來啟動新創建的線程,而且start()內部調用了run()方法,這和直接調用run()方法的效果不一樣。當你調用run()方法的時候,只會是在原來的線程中調用,沒有新的線程啟動,start()方法才會啟動新線程。
74.Java中Runnable和Callable有什么不同?
Runnable和Callable都代表那些要在不同的線程中執行的任務。Runnable從JDK1.0開始就有了,Callable是在JDK1.5增加的。它們的主要區別是Callable的 call() 方法可以返回值和拋出異常,而Runnable的run()方法沒有這些功能。Callable可以返回裝載有計算結果的Future對象.
75.Java中CyclicBarrier 和 CountDownLatch有什么不同?
CyclicBarrier 和 CountDownLatch 都可以用來讓一組線程等待其它線程。與 CyclicBarrier 不同的是,CountdownLatch 不能重新使用。 CountDownLatch :允許一個或多個線程等待其他線程完成操作。 CyclicBarrier :同步屏障,它可以讓一組線程到達一個屏障(也可以叫做同步點)時被阻塞,直到最后一個線程到達屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續運行。
76.什么是FutureTask?
在Java並發程序中FutureTask表示一個可以取消的異步運算。它有啟動和取消運算、查詢運算是否完成和取回運算結果等方法。只有當運算完成的時候結果才能取回,如果運算尚未完成get方法將會阻塞。一個FutureTask對象可以對調用了Callable和Runnable的對象進行包裝,由於FutureTask也是調用了Runnable接口所以它可以提交給Executor來執行。
77.Java中interrupted 和 isInterrupted方法的區別?
interrupted() 和 isInterrupted()的主要區別是前者會將中斷狀態清除而后者不會。Java多線程的中斷機制是用內部標識來實現的,調用Thread.interrupt()來中斷一個線程就會設置中斷標識為true。當中斷線程調用靜態方法Thread.interrupted()來檢查中斷狀態時,中斷狀態會被清零。而非靜態方法isInterrupted()用來查詢其它線程的中斷狀態且不會改變中斷狀態標識。簡單的說就是任何拋出InterruptedException異常的方法都會將中斷狀態清零。無論如何,一個線程的中斷狀態有有可能被其它線程調用中斷來改變。
78.為什么wait和notify方法要在同步塊中調用?
主要是因為Java API強制要求這樣做,如果你不這么做,你的代碼會拋出IllegalMonitorStateException異常。還有一個原因是為了避免wait和notify之間產生競態條件。
79.Java中Semaphore是什么?
Java中的Semaphore是一種新的同步類,它是一個計數信號。從概念上講,信號量維護了一個許可集合。如有必要,在許可可用前會阻塞每一個 acquire(),然后再獲取該許可。每個 release()添加一個許可,從而可能釋放一個正在阻塞的獲取者。但是,不使用實際的許可對象,Semaphore只對可用許可的號碼進行計數,並采取相應的行動。信號量常常用於多線程的代碼中,比如數據庫連接池
80.Java線程池中submit() 和 execute()方法有什么區別?
兩個方法都可以向線程池提交任務,execute()方法的返回類型是void,它定義在Executor接口中, 而submit()方法可以返回持有計算結果的Future對象,它定義在ExecutorService接口中,它擴展了Executor接口,其它線程池類像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有這些方法。
81.JDBC的DriverManager是用來做什么的?
- JDBC的DriverManager是一個工廠類,我們通過它來創建數據庫連接。
- 當JDBC的Driver類被加載進來時,它會自己注冊到DriverManager類里面然后我們會把數據庫配置信息傳成DriverManager.getConnection()方法,DriverManager會使用注冊到它里面的驅動來獲取數據庫連接,並返回給調用的程序。
82.JDBC的ResultSet是什么?
- 在查詢數據庫后會返回一個ResultSet,它就像是查詢結果集的一張數據表。
- ResultSet對象維護了一個游標,指向當前的數據行。開始的時候這個游標指向的是第一行。如果調用了ResultSet的next()方法游標會下移一行,如果沒有更多的數據了,next()方法會返回false。可以在for循環中用它來遍歷數據集。
- 默認的ResultSet是不能更新的,游標也只能往下移。也就是說你只能從第一行到最后一行遍歷一遍。不過也可以創建可以回滾或者可更新的ResultSet
- 當生成ResultSet的Statement對象要關閉或者重新執行或是獲取下一個ResultSet的時候,ResultSet對象也會自動關閉。
- 可以通過ResultSet的getter方法,傳入列名或者從1開始的序號來獲取列數據。
83.JDBC的DataSource是什么,有什么好處?
DataSource即數據源,它是定義在javax.sql中的一個接口,跟DriverManager相比,它的功能要更強大。我們可以用它來創建數據庫連接,當然驅動的實現類會實際去完成這個工作。除了能創建連接外,它還提供了如下的特性: 緩存PreparedStatement以便更快的執行 可以設置連接超時時間 提供日志記錄的功能 ResultSet大小的最大閾值設置 * 通過JNDI的支持,可以為servlet容器提供連接池的功能
84.JDBC中存在哪些不同類型的鎖?
- 樂觀鎖——只有當更新數據的時候才會鎖定記錄。
- 悲觀鎖——從查詢到更新和提交整個過程都會對數據記錄進行加鎖。
85.JDBC的RowSet是什么,有哪些不同的RowSet?
RowSet用於存儲查詢的數據結果,和ResultSet相比,它更具靈活性。RowSet繼承自ResultSet,因此ResultSet能干的,它們也能,而ResultSet做不到的,它們還是可以。RowSet接口定義在javax.sql包里。 RowSet提供的額外的特性有: 1. 提供了Java Bean的功能,可以通過settter和getter方法來設置和獲取屬性。RowSet使用了JavaBean的事件驅動模型,它可以給注冊的組件發送事件通知,比如游標的移動,行的增刪改,以及RowSet內容的修改等。 2. RowSet對象默認是可滾動,可更新的,因此如果數據庫系統不支持ResultSet實現類似的功能,可以使用RowSet來實現。 RowSet分為兩大類: 1. 連接型RowSet——這類對象與數據庫進行連接,和ResultSet很類似。JDBC接口只提供了一種連接型RowSet,javax.sql.rowset.JdbcRowSet,它的標准實現是com.sun.rowset.JdbcRowSetImpl。 2. 離線型RowSet——這類對象不需要和數據庫進行連接,因此它們更輕量級,更容易序列化。它們適用於在網絡間傳遞數據。
有四種不同的離線型RowSet的實現:
- CachedRowSet——可以通過他們獲取連接,執行查詢並讀取ResultSet的數據到RowSet里。我們可以在離線時對數據進行維護和更新,然后重新連接到數據庫里,並回寫改動的數據。
- WebRowSet繼承自CachedRowSet——他可以讀寫XML文檔。
- JoinRowSet繼承自WebRowSet——它不用連接數據庫就可以執行SQL的join操作。
- FilteredRowSet繼承自WebRowSet——我們可以用它來設置過濾規則,這樣只有選中的數據才可見。
86.在Java中定義一個不做事且沒有參數的構造方法的作用
Java程序在執行子類的構造方法之前,如果沒有用super()來調用父類特定的構造方法,則會調用父類中“沒有參數的構造方法”。因此,如果父類中只定義了有參數的構造方法,而在子類的構造方法中又沒有用super()來調用父類中特定的構造方法,則編譯時將發生錯誤,因為Java程序在父類中找不到沒有參數的構造方法可供執行。解決辦法是在父類里加上一個不做事且沒有參數的構造方法。
87.實現一個線程有哪幾種方式,各有什么優缺點,比較常用的是那種?
- 通過繼承Thread類,優點:可以直接調用start方法啟動。缺點:繼承一個類后,不能再繼承別的類。需要重寫run方法。無返回值。
- 實現Runnable接口,優點:可以實現多個接口或繼承一個類;缺點:不能直接啟動,要通過構造一個Thread把自己傳進去。需要重寫run方法,無返回值。
- 實現Callable接口,優點:可以拋出異常,有返回值;缺點:只有jkd1.5以后才支持。需要重寫call方法。結合FutureTask和Thread類一起使用,最后調用start啟動。
- 一般最常用的是第二種,實現Runnable接口。比較方便,可擴展性高。
88.一般的線程優先級是什么回事,線程優先級高的線程一定會先執行嗎?如果不設置優先級的話,那么線程優先級是多少,設置線程優先級用那個函數
線程的優先級就是設置哪個線程優先執行,但也不是絕對的,只是讓優先級高的線程優先運行的幾率高一些。線程默認是NORM_PRIORITY = 5; 設置優先級使用的是setPriority()函數。
89.Java中的內存划分
- 程序計數器:(線程私有) > 每個線程擁有一個程序計數器,在線程創建時創建, > 指向下一條指令的地址 > * 執行本地方法時,其值為undefined
- 虛擬機棧:(線程私有) > 每個方法被調用的時候都會創建一個棧幀,用於存儲局部變量表、操作棧、動態鏈接、方法出口等信息。局部變量表存放的是:編譯期可知的基本數據類型、對象引用類型。<br/> >每個方法被調用直到執行完成的過程,就對應着一個棧幀在虛擬機中從入棧到出棧的過程。
- 在Java虛擬機規范中,對這個區域規定了兩種異常情況: > 1. 如果線程請求的棧深度太深,超出了虛擬機所允許的深度,就會出現StackOverFlowError(比如無限遞歸。因為每一層棧幀都占用一定空間,而 Xss 規定了棧的最大空間,超出這個值就會報錯) > 2. 虛擬機棧可以動態擴展,如果擴展到無法申請足夠的內存空間,會出現OOM
- 本地方法棧: >本地方法棧與java虛擬機棧作用非常類似,其區別是:java虛擬機棧是為虛擬機執行java方法服務的,而本地方法棧則為虛擬機執使用到的Native方法服務。<br/> >本地方法棧也會拋出StackOverFlowError和OutOfMemoryError。
- 堆:即堆內存(線程共享) > 1. 堆是java虛擬機所管理的內存區域中最大的一塊,java堆是被所有線程共享的內存區域,在java虛擬機啟動時創建,堆內存的唯一目的就是存放對象實例幾乎所有的對象實例都在堆內存分配。 > 2. 堆是GC管理的主要區域,從垃圾回收的角度看,由於現在的垃圾收集器都是采用的分代收集算法,因此java堆還可以初步細分為新生代和老年代。 > 3. Java虛擬機規定,堆可以處於物理上不連續的內存空間中,只要邏輯上連續的即可。在實現上既可以是固定的,也可以是可動態擴展的。如果在堆內存沒有完成實例分配,並且堆大小也無法擴展,就會拋出OutOfMemoryError異常。
- 方法區:(線程共享) > 1. 用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。 > 2. Sun HotSpot虛擬機把方法區叫做永久代(Permanent Generation),方法區中最重要的部分是運行時常量池。
90.垃圾收集器
- Serial收集器:(串行收集器) >> 這個收集器是一個單線程的收集器,但它的單線程的意義並不僅僅說明它只會使用一個CPU或一條收集線程去完成垃圾收集工作,更重要的是在它進行垃圾收集時,必須暫停其他所有的工作線程(Stop-The-World:將用戶正常工作的線程全部暫停掉),直到它收集結束。
- ParNew收集器:Serial收集器的多線程版本(使用多條線程進行GC) >>ParNew收集器是Serial收集器的多線程版本。<br /> 它是運行在server模式下的首選新生代收集器,除了Serial收集器外,目前只有它能與CMS收集器配合工作。CMS收集器是一個被認為具有划時代意義的並發收集器,因此如果有一個垃圾收集器能和它一起搭配使用讓其更加完美,那這個收集器必然也是一個不可或缺的部分了。
- ParNew Scanvenge收集器 >> 類似ParNew,但更加關注吞吐量。目標是:達到一個可控制吞吐量的收集器。 停頓時間和吞吐量不可能同時調優。我們一方買希望停頓時間少,另外一方面希望吞吐量高,其實這是矛盾的。因為:在GC的時候,垃圾回收的工作總量是不變的,如果將停頓時間減少,那頻率就會提高;既然頻率提高了,說明就會頻繁的進行GC,那吞吐量就會減少,性能就會降低。<br /> 吞吐量:CPU用於用戶代碼的時間/CPU總消耗時間的比值,即=運行用戶代碼的時間/(運行用戶代碼時間+垃圾收集時間)。比如,虛擬機總共運行了100分鍾,其中垃圾收集花掉1分鍾,那吞吐量就是99%。
- G1收集器: >>是當今收集器發展的最前言成果之一,直到jdk1.7,sun公司才認為它達到了足夠成熟的商用程度。
- CMS收集器:(老年代收集器) >> CMS收集器(Concurrent Mark Sweep:並發標記清除)是一種以獲取最短回收停頓時間為目標的收集器。適合應用在互聯網站或者B/S系統的服務器上,這類應用尤其重視服務器的響應速度,希望系統停頓時間最短。
