(一) Java 部分java
一、 列舉出 JAVA 中 6 個比較經常使用的包【天威誠信面試題】mysql
【參考答案】c++
java.lang;java.util;java.io;java.sql;java.awt;java.net;javax.swing程序員
二、 JDK 中哪些類是不能繼承的? 【信雅達面試題】web
【參考答案】面試
不能繼承的是類是那些用final關鍵字修飾的類。通常比較基本的類型或防止擴展類無心間破壞原來方法的實現的類型都應該是final的。ajax
三、 String 是最基本的數據類型嗎 ? 【天能智健面試題】算法
【參考答案】spring
基本數據類型包括byte、int、char、long、float、double、boolean和short。sql
因此String不屬於基本數據類型範疇內,但String屬於最多見一種引用類型。
四、 short 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編譯器會對它進行特殊處理,所以能夠正確編譯。
【分析】
主要考查幾種基本數據類型在運算時的,由低到高會自動轉換,而由高到低時會強制轉換。
五、 Java 對象初始化順序?【騰鵬科技面試題】
【參考答案】
分爲兩種,一種是本類的初始化,一種是含有父類的初始化順序。這裏分開來講,
本類的初始化順序是:靜態變量、靜態初始化塊、變量、初始化塊、構造函數
繼承類的初始化順序是:父類靜態變量、父類靜態初始化塊、子類靜態變量、子類靜態初始塊、父類變量、父類初始化塊、父類構造函數、子類變量、子類初始化塊、子類構造函數。
【分析】
static{
System.out.println("靜態塊");
}
{
System.out.println("初始化模塊"); }
public ClassName() {
System.out.println("構造方法");
}
說明:
原則上回答全面的話,應該是完整的說出帶有繼承的這種類的初始化過程,下面有個步驟能夠參考:
1.裝載程序的時候首先找到的是它的基(父)類,若是有多層基(父)類則會一級一級的往上找最後找到根基(父)類。
2.執行根基礎(父)類中的static初始化,再執行下一個衍生類中的static,依此類推,一直保持這個順序。
3.此時類已經裝載完畢,開始建立對象,全部的基本數據類型都會設成它們的默認值,對象句柄設爲null
4.調用基礎(父)類的構造方法,基礎(父)類的構建採用與衍生類構造方法徹底相同的處理過程。
5.構造方法初始完以後,進行變量的初始化。
6.執行構造方法中剩餘的部分。
六、 寫幾個線程安全類,不安全的,支持排序的類名?【軟通動力面試題】
【參考答案】
Ø線程安全類:Vector、Hashtable、Stack。
Ø線程不安全的類:ArrayList、Linkedlist、HashSet、TreeSet、HashMap、TreeMap等。
Ø支持排序的類有HashSet、LinkedHashSet、TreeSet等(Set接口下的實現都支持排序)
【分析】
此題主要考查集合框架的知識。在集合框架中Collection接口爲集合的根類型,提供集合操做的經常使用API方法,該接口下派生出兩個子接口,一個是不支持排序的List接口,一個是有自身排序的Set接口,因此回答排序與不排序分別從兩接口的實現中在做答。線程安全上來講,Vector類比同屬於List接口的ArrayList要早,是一個線程安全的類,在JDK1.2之後才推出一個異步的ArrayList類,比Vector類效率高。同理Stack繼承自Vector也線程安全的類,另外在在Map接口的實如今Hashtable也是個線程安全的類。
七、 哪幾個方法能夠實現一個線程?【上海華信面試題】
【參考答案】
一是繼承Thread,重寫Thread類的方法run方法;另種是實現runnable接口並實現run方法。
【分析】
考查線程的基本實現,不少公司喜歡考查這方面知識,另外補充一下關於線程的run方法,在多線程API中啓動一個線程是調用start()方法,線程進入就緒狀態。
八、 STOP() 和 SUSPEND() 不推薦使用的緣由?
【參考答案】
stop()是由於它不安全。它會解除由線程獲取的全部鎖定,當在一個線程對象上調用stop()方法時,這個線程對象所運行的線程就會當即中止,假如一個線程正在執行:synchronized void { x = 3; y = 4;}因爲方法是同步的,多個線程訪問時總能保證x,y被同時賦值,而若是一個線程正在執行到x = 3;時,被調用了stop()方法,即便在同步塊中,它也乾脆地stop了,這樣就產生了不完整的殘廢數據。而多線程編程中最最基礎的條件要保證數據的完整性,因此請忘記線程的stop方法,之後咱們不再要說「中止線程」了。並且若是對象處於一種不連貫狀態,那麼其餘線程能在那種狀態下檢查和修改它們。
suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這以前得到的鎖定。此時,其餘任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來講,若是它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會形成死鎖。因此不該該使用suspend(),而應在本身的Thread類中置入一個標誌,指出線程應該活動仍是掛起。若標誌指出線程應該掛起,便用wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個notify()從新啓動線程。
【分析】
九、 "==" 和 equals 方法有什麼區別? 【中科軟】
【參考答案】
==操做符專門用來比較兩個變量的值是否相等,也就是用於比較變量所對應的內存中所存儲的數值是否相同,要比較兩個基本類型的數據或兩個引用變量是否相等,只能用==操做符。
若是一個變量指向的數據是對象類型的,那麼,這時候涉及了兩塊內存,對象自己佔用一塊內存(堆內存),變量也佔用一塊內存,例如Objet obj = new Object();變量obj是一個內存,new Object()是另外一個內存,此時,變量obj所對應的內存中存儲的數值就是對象佔用的那塊內存的首地址。對於指向對象類型的變量,若是要比較兩個變量是否指向同一個對象,即要看這兩個變量所對應的內存中的數值是否相等,這時候就須要用==操做符進行比較。
equals方法是用於比較兩個獨立對象的內容是否相同,就比如去比較兩我的的長相是否相同,它比較的兩個對象是獨立的。例如,對於下面的代碼:
String a=new String("foo");
String b=new String("foo");
兩條new語句建立了兩個對象,而後用a,b這兩個變量分別指向了其中一個對象,這是兩個不一樣的對象,它們的首地址是不一樣的,即a和b中存儲的數值是不相同的,因此,表達式a==b將返回false,而這兩個對象中的內容是相同的,因此,表達式a.equals(b)將返回true。
在實際開發中,咱們常常要比較傳遞進行來的字符串內容是否等,例如,String input =…;input.equals(「quit」),若是一個類沒有本身定義equals方法,那麼它將繼承Object類的equals方法,Object類的equals方法的實現代碼以下:
boolean equals(Object o){
return this==o;
}
這說明,若是一個類沒有本身定義equals方法,它默認的equals方法(從Object類繼承的)就是使用==操做符,也是在比較兩個變量指向的對象是不是同一對象,這時候使用equals和使用==會獲得一樣的結果,若是比較的是兩個獨立的對象則總返回false。若是你編寫的類但願可以比較該類建立的兩個實例對象的內容是否相同,那麼你必須覆蓋equals方法,由你本身寫代碼來決定在什麼狀況便可認爲兩個對象的內容是相同的。
十、 靜態變量和實例變量的區別?
【參考答案】
在語法定義上的區別:靜態變量前要加static關鍵字,而實例變量前則不加。
在程序運行時的區別:實例變量屬於某個對象的屬性,必須建立了實例對象,其中的實例變量纔會被分配空間,才能使用這個實例變量。靜態變量不屬於某個實例對象,而是屬於類,因此也稱爲類變量,只要程序加載了類的字節碼,不用建立任何實例對象,靜態變量就會被分配空間,靜態變量就能夠被使用了。總之,實例變量必須建立對象後才能夠經過這個對象來使用,靜態變量則能夠直接使用類名來引用。
例如,對於下面的程序,不管建立多少個實例對象,永遠都只分配了一個staticVar變量,而且每建立一個實例對象,這個staticVar就會加1;可是,每建立一個實例對象,就會分配一個instanceVar,便可能分配多個instanceVar,而且每一個instanceVar的值都只自加了1次。
public class VariantTest
{
public static int staticVar = 0;
public int instanceVar = 0;
public VariantTest()
{
staticVar++;
instanceVar++;
System.out.println(「staticVar=」+ staticVar +」,instanceVar=」+ instanceVar);
}
}
備註:這個解答除了說清楚二者的區別外,最後還用一個具體的應用例子來講明二者的差別,體現了本身有很好的解說問題和設計案例的能力,思惟敏捷,超過通常程序員,有寫做能力!
十一、 構造器的名能不能和類的名字相同?
【參考答案】
構造器的名稱必須與類名相同。
【分析】
構造器或構造函數(有些書這樣叫)主要用來對類的成員變量進行初始化,當類建立實例時調用。
十二、 在一個主方法類可不能夠調用一個非靜態的方法?
【參考答案】
能夠調用。由於Java的主方法(main)方法自己也是static類型方法,一個static類型方法,發起對另外一個static方法的調用沒有問題。
【分析】
靜態方法能夠調用其它的靜態方法,可是不能調用非靜態方法,這個比如Java中的類變量與實例變量的關係。類變量是被全部類成員共享,而實例變量只被該實例共享,
1三、 一個類中可不能夠有 2 個公共的方法?
【參考答案】
能夠。Java中對公共方法的個數沒有約束,可是對公共的類有約束,一個Java源文件中只能定義一個public類型的類。
1四、 GC 是什麼,爲何要使用它?【阿斯拓】
【參考答案】
GC是垃圾收集的意思(Gabage Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會致使程序或系統的不穩定甚至崩潰,Java提供的GC功能能夠自動監測對象是否超過做用域,從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操做方法。
【分析】
1五、 說一下垃圾回收的原理,能夠直接從內存中回收嗎 ?
【參考答案】
Java語言中一個顯著的特色就是引入了垃圾回收機制,使c++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候再也不須要考慮內存管理。垃圾回收能夠有效的防止內存泄露,有效的使用能夠使用的內存。垃圾回收器一般是做爲一個單獨的低級別的線程運行,不可預知的狀況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清除和回收,程序員不能實時的調用垃圾回收器對某個對象或全部對象進行垃圾回收,由於Java語言規範並不保證GC必定會執行。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。
【分析】
1六、 Java 的異常有哪幾種,有什麼區別?
【參考答案】
兩大類,通常異常和運行時異常。通常異常,這些異常是在定義方法時聲明拋出的,這些異常必需用try catch拋出,或throws處理,若是不處理,程序將編譯失敗。好比:IOException、FileNotFoundException、SQLException等。
運行時異常是程序運行時可能報出的異常。能夠用try catch抓取,也能夠不作任何處理。例如:NullPointerException異常就是一種比較常見的運行時異常。
【分析】
1七、 switch 語句可否做用在 byte 上,可否做用在 long 上,可否做用在 String 上 ?
【參考答案】
在switch(表達式)中,括號表達式只能是一個整數表達式或者枚舉常量(更大字體),整數表達式能夠是int基本類型或Integer包裝類型,因爲,byte,short,char均可以隱含轉換爲int,因此,這些類型以及這些類型的包裝類型也是能夠的。顯然,long和String類型都不符合switch的語法規定,而且不能被隱式轉換成int類型,因此,它們不能做用於swtich語句中。
1八、 Integer 與 int 的區別?
【參考答案】
int是java提供的8種原始數據類型之一,另外Java爲每一個原始類型提供了封裝類,Integer是java爲int提供的封裝類。int的默認值爲0,而Integer的默認值爲null,即Integer能夠區分出未賦值和值爲0的區別,int則沒法表達出未賦值的狀況。
1九、 Java Reflection 是什麼 ? 【】
【參考答案】
JAVA反射,Reflection是Java程序開發語言的特徵之一,它容許運行中的Java程序對自身進行檢查,或者說"自審",並能直接操做程序的內部屬性。
【分析】
20、 寫幾個 java.lang.Object 類中的方法名稱。
【參考答案】
主要有equals()、toString()、getClass()、hashCode()、clone()、notify()、wait()、notify()方法。
【分析】
這種題能記多少個就說多少個,不必定要求你全部的都記住,可是要理解其中部分重要方法的含義和做用。
2一、 & 和 && 的區別?
【參考答案】
&和&&均可以用做邏輯與的運算符,表示邏輯與(and),當運算符兩邊的表達式的結果都爲true時,整個運算結果才爲true,不然,只要有一方爲false,則結果爲false。
&&還具備短路的功能,即若是第一個表達式爲false,則再也不計算第二個表達式。
&還能夠用做位運算符,當&操做符兩邊的表達式不是boolean類型時,&表示按位與操做,咱們一般使用0x0f來與一個整數進行&運算,來獲取該整數的最低4個bit位。
【分析】
先說分別說二者的做用,再說出&&和&各自的不一樣之處。
2二、 數組有沒有 length() 這個方法, String 有沒有 length() 這個方法。
【參考答案】
數組沒有length()方法,但有length屬性
String有length()方法。
【分析】
考查平時使用數組和字符串的一些細節,通常在使用
2三、 String s=new String( 「 xyz 」 ) 建立了幾個對象
【參考答案】
2個string對象,一個是=null的s,一個是=「xyz」的string
兩個或一個」xyz」對應一個對象,這個對象放在字符串常量緩衝區,常量」xyz」無論出現多少遍,都是緩衝區中的那一個。New String每寫一遍,就建立一個新的對象,它一句那個常量」xyz」對象的內容來建立出一個新String對象。若是之前就用過’xyz’,這句表明就不會建立」xyz」本身了,直接從緩衝區拿。
【分析】
2四、 能不能本身寫個類,也叫 java.lang.String ?
能夠,但在應用的時候,須要用本身的類加載器去加載,不然,系統的類加載器永遠只是去加載jre.jar包中的那個java.lang.String。因爲在tomcat的web應用程序中,都是由webapp本身的類加載器先本身加載WEB-INF/classess目錄中的類,而後才委託上級的類加載器加載,若是咱們在tomcat的web應用程序中寫一個java.lang.String,這時候Servlet程序加載的就是咱們本身寫的java.lang.String,可是這麼幹就會出不少潛在的問題,原來全部用了java.lang.String類的都將出現問題。
雖然java提供了endorsed技術,能夠覆蓋jdk中的某些類,具體作法是….。可是,可以被覆蓋的類是有限制範圍,反正不包括java.lang這樣的包中的類。
例如,運行下面的程序:
package java.lang;
public class String {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("string");
}
}
報告的錯誤以下:
java.lang.NoSuchMethodError: main
Exception in thread "main"
這是由於加載了jre自帶的java.lang.String,而該類中沒有main方法。
2五、 你對面向對象思想的理解?
【參考答案】
面向對象編程(Object-Oriented Programming)簡稱OOP技術,是開發計算機應用程序的一種新方法、新思想。過去的面向過程編程中經常會致使全部的代碼都包含在幾個模塊中,使程序難以閱讀和維護,在作一些修改時經常牽一動百,使之後的開發和維護難覺得繼。而使用OOP技術,使用許多代碼模塊,每一個模塊都只提供特定的功能,它們是彼此獨立的,能夠增長代碼重用的概率,更加有利於軟件的開發、維護和升級。另外OOP的三大核心特性:繼承、封裝、多態的特性,使得在面對象編上可以設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴展,並且成本較低,因此這一編程思想是目前一種應用最爲廣泛的軟件設計思想。
【分析】
2六、 最多見的 runtime exception 運行時異常?
【參考答案】
ClassCastException(類型轉換異常)、NumberFormatException(格式化異常)、
ArrayIndexOutOfBoundsException(數組越界異常)、ArithmeticException(算術異常)、NullPointerException(空指針異常)等等
【分析】
這道題主要考查你們平時在項目開發過程當中常常遇到的一些異常類型信息,經過這些異常來考查你們的項目經驗與項目排錯能力。
2七、 用 JDBC 來實現訪問數據庫記錄能夠採用下面的幾個步驟:
【參考答案】
一、經過驅動器管理器獲取鏈接接口(Connection)。
二、得到Statement或它的子類。
三、指定Statement中的參數。
四、經過Statement發送SQL語句。
五、檢查並處理返回的結果。
六、關閉Statement。
七、關閉鏈接接
【分析】
2八、 Error 和 exception 的區別與聯繫?
【參考答案】
error表示恢復不是不可能,但很困難的狀況下的一種嚴重問題。好比說內存溢,網絡故障等,不可能期望程序能處理的一類錯誤。
Exception表示一種由程序設計或實現問題,像咱們常說的異常處理,就是屬於這類,通常程序能夠捕獲和處理這些異常。
【分析】
這道題的難點在Error不少時候因爲咱們沒法重現這種Error致使不少同窗甚至不知道Error究竟是什麼,因此很容易把題目中的兩種錯誤劃上等號。
2九、 String s = "Hello";s = s + " world!"; 這兩行代碼執行後,原始的 String 對象中的內容到底變了沒有?
【參考答案】
沒有。由於String被設計成不可變(immutable)類,因此它的全部對象都是不可變對象。在這段代碼中,s原先指向一個String對象,內容是"Hello",而後咱們對s進行了+操做,那麼s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另外一個String對象,內容爲"Hello world!",原來那個對象還存在於內存之中,只是s這個引用變量再也不指向它了。
經過上面的說明,咱們很容易導出另外一個結論,若是常常對字符串進行各類各樣的修改,或者說,不可預見的修改,那麼使用String來表明字符串的話會引發很大的內存開銷。由於String對象創建以後不能再改變,因此對於每個不一樣的字符串,都須要一個String對象來表示。這時,應該考慮使用StringBuffer類,它容許修改,而不是每一個不一樣的字符串都要生成一個新的對象。而且,這兩種類的對象轉換十分容易。
同時,咱們還能夠知道,若是要使用內容相同的字符串,沒必要每次都new一個String。例如咱們要在構造器中對一個名叫s的String引用變量進行初始化,把它設置爲初始值,應當這樣作:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
後者每次都會調用構造器,生成新對象,性能低下且內存開銷大,而且沒有意義,由於String對象不可改變,因此對於內容相同的字符串,只要一個String對象來表示就能夠了。也就說,屢次調用上面的構造器建立多個對象,他們的String類型屬性s都指向同一個對象。
上面的結論還基於這樣一個事實:對於字符串常量,若是內容相同,Java認爲它們表明同一個String對象。而用關鍵字new調用構造器,老是會建立一個新的對象,不管內容是否相同。
至於爲何要把String類設計成不可變類,是它的用途決定的。其實不僅String,不少Java標準類庫中的類都是不可變的。在開發一個系統的時候,咱們有時候也須要設計不可變類,來傳遞一組相關的值,這也是面向對象思想的體現。不可變類有一些優勢,好比由於它的對象是隻讀的,因此多線程併發訪問也不會有任何問題。固然也有一些缺點,好比每一個不一樣的狀態都要一個對象來表明,可能會形成性能上的問題。因此Java標準類庫還提供了一個可變版本,即StringBuffer。
30、 Jdk 1.5 的新特性?
【參考答案】
JDK1.5的一個重要主題就是經過新增一些特性來簡化開發,這些特性主要包括:泛型、ForEach循環、自動裝包/拆包、枚舉、可變參數、靜態導入這些。
【分析】
3一、 面向對象的特徵有哪些方面?
【參考答案】
面向對象的編程語言有封裝、繼承、多態等3個主要的特徵。
u封裝
封裝是保證軟件部件具備優良的模塊性的基礎,封裝的目標就是要實現軟件部件的「高內聚、低耦合」,防止程序相互依賴性而帶來的變更影響。面向對象的封裝就是把描述一個對象的屬性和行爲的代碼封裝在一個「模塊」中,也就是一個類中,屬性用變量定義,行爲用方法進行定義,方法能夠直接訪問同一個對象中的屬性。
u繼承
在定義和實現一個類的時候,能夠在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容做爲本身的內容,並能夠加入若干新的內容,或修改原來的方法使之更適合特殊的須要,這就是繼承。繼承是子類自動共享父類數據和方法的機制,這是類之間的一種關係,提升了軟件的可重用性和可擴展性。
u多態
多態是指程序中定義的引用變量所指向的具體類型和經過該引用變量發出的方法調用在編程時並不肯定,而是在程序運行期間才肯定,即一個引用變量倒底會指向哪一個類的實例對象,該引用變量發出的方法調用究竟是哪一個類中實現的方法,必須在由程序運行期間才能決定。由於在程序運行時才肯定具體的類,這樣,不用修改源程序代碼,就可讓引用變量綁定到各類不一樣的類實現上,從而致使該引用調用的具體方法隨之改變,即不修改程序代碼就能夠改變程序運行時所綁定的具體代碼,讓程序能夠選擇多個運行狀態,這就是多態性。多態性加強了軟件的靈活性和擴展性。
3二、 JVM 工做原理?
運行jvm字符碼的工做是由解釋器來完成的。解釋執行過程分三步進行:
代碼的裝入、代碼的校驗、和代碼的執行。
裝入代碼的工做由「類裝載器class loader」完成。類裝載器負責裝入運行一個程序須要的全部代碼,這也包括程序代碼中的類所繼承的類和被調用的類。當類裝載器裝入一個類時,該類被放在本身的名字空間中。除了經過符號引用本身名字空間之外的類,類之間沒有其餘辦法能夠影響其餘類。在本臺計算機的全部類都在同一地址空間中,而全部從外部引進的類,都有一個本身獨立的名字空間。這使得本地類經過共享相同的名字空間得到較高的運行效率,同時又保證它們與從外部引進的類不會相互影響。當裝入了運行程序須要的全部類後,解釋器即可肯定整個可執行程序的內存佈局。解釋器爲符號引用與特定的地址空間創建對應關係及查詢表。經過在這一階段肯定代碼的內佈局,java很好地解決了由超類改變而使子類
崩潰的問題,同時也防止了代碼的非法訪問。隨後,被裝入的代碼由字節碼校驗器進行檢查。校驗器能夠發現操做數棧益處、非法數據類型轉化等多種錯誤。經過校驗後,代碼便開始執行了。
Java字節碼的執行有兩種方式:
1)即時編譯方式:解釋器先將字節編譯成機器碼,而後再執行該機器碼。
2)解釋執行方式:解釋器經過每次解釋並執行一小段代碼來完成java字節。
碼程序的全部操做。
3三、 說說 Java 中的內存分配 ?
Java把內存分紅兩種,一種叫作棧內存,一種叫作堆內存
在函數中定義的一些基本類型的變量和對象的引用變量都是在函數的棧內存中分配。當在一段代碼塊中定義一個變量時,java就在棧中爲這個變量分配內存空間,當超過變量的做用域後,java會自動釋放掉爲該變量分配的內存空間,該內存空間能夠馬上被另做它用。
堆內存用於存放由new建立的對象和數組。在堆中分配的內存,由java虛擬機自動垃圾回收器來管理。在堆中產生了一個數組或者對象後,還能夠在棧中定義一個特殊的變量,這個變量的取值等於數組或者對象在堆內存中的首地址,在棧中的這個特殊的變量就變成了數組或者對象的引用變量,之後就能夠在程序中使用棧內存中的引用變量來訪問堆中的數組或者對象,引用變量至關於爲數組或者對象起的一個別名,或者代號。
引用變量是普通變量,定義時在棧中分配內存,引用變量在程序運行到做用域外釋放。而數組&對象自己在堆中分配,即便程序運行到使用new產生數組和對象的語句所在地代碼塊以外,數組和對象自己佔用的堆內存也不會被釋放,數組和對象在沒有引用變量指向它的時候,才變成垃圾,不能再被使用,可是仍然佔着內存,在隨後的一個不肯定的時間被垃圾回收器釋放掉。這個也是java比較佔內存的主要緣由。可是在寫程序的時候,能夠人爲的控制。
3四、 final, finally, finalize 的區別。
【參考答案】
final用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
內部類要訪問局部變量,局部變量必須定義成final類型,例如,一段代碼……
finally是異常處理語句結構的一部分,表示老是執行。
finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,能夠覆蓋此方法提供垃圾收集時的其餘資源回收,例如關閉文件等。JVM不保證此方法總被調用
3五、 E xtends 和 I mplement 的不一樣?
【參考答案】
extends是繼承父類,只要那個類不是聲明爲final或者那個類定義爲abstract的就能繼承,JAVA中不支持多重繼承,可是能夠用接口來實現,這樣就要用到implements,繼承只能繼承一個類,但implements能夠實現多個接口,用逗號分開就好了
好比class A extends B implements C,D,E
3六、 抽象類是否能夠沒有抽象方法?爲何?
【參考答案】
能夠在java中用abstract關鍵字來修飾一個類時,這個類叫作抽象類。
抽象類中不必定要包含abstract方法,但一個類中包含了abstract方法,則這個類必須聲明爲abstract類。
3七、 靜態的多態和動態的多態的區別?
【參考答案】
靜態的多態:即爲重載;方法名相同,參數個數或類型不相同。(overloading)
動態的多態:即爲重寫;子類覆蓋父類的方法,將子類的實例傳與父類的引用調用的是子類的方法實現接口的實例傳與接口的引用調用的實現類的方法。
3八、 說出一些經常使用的類,包,接口,請各舉 5 個 ?
【參考答案】
經常使用的類:String、StringBuffer、Integer、Vector、ArrayList、Hashtable等
經常使用的包:java.lang java.io java.util、java.sql。
經常使用的接口:集合中的List、Set、Map接口;與Servlet API相關的Servlet接口、HttpServletRequest,HttpServletResponse,HttpSession接口等。
3九、 Collections 和 C ollection 的區別【天晟科技】
【參考答案】
Collection是個java.util下的接口,它是各類集合結構的父接口,定義了集合對象的基本操做方法。Collections是個java.util下的工具類,它包含有各類有關集合操做的靜態方法,主要是針對集合類的一個幫助類或者叫包裝類,它提供一系列對各類集合的搜索,排序,線程安全化等操做方法。
40、 Class.forName 的做用 ? 爲何要用 ?
【參考答案】
按參數中指定的字符串形式的類名去搜索並加載相應的類,若是該類字節碼已經被加載過,則返回表明該字節碼的Class實例對象,不然,按類加載器的委託機制去搜索和加載該類,若是全部的類加載器都沒法加載到該類,則拋出ClassNotFoundException。加載完這個Class字節碼後,接着就能夠使用Class字節碼的newInstance方法去建立該類的實例對象了。有時候,咱們程序中全部使用的具體類名在設計時(即開發時)沒法肯定,只有程序運行時才能肯定,這時候就須要使用Class.forName去動態加載該類,這個類名一般是在配置文件中配置的,例如,spring的ioc中每次依賴注入的具體類就是這樣配置的,jdbc的驅動類名一般也是經過配置文件來配置的,以便在產品交付使用後不用修改源程序就能夠更換驅動類名。
4一、 Socket 如何獲取本地 ip 地址?
【參考答案】
InetAddress類提供的API來訪問。InetAddress.getLocalAddress()
【分析】
4二、 接口是否可繼承接口 ? 抽象類是否可實現 (implements) 接口 ? 抽象類是否可繼承具體類【天威誠信面試題】
【參考答案】
接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類是否可繼承具體類。抽象類中能夠有靜態的main方法。
備註:只要明白了接口和抽象類的本質和做用,這些問題都很好回答,你想一想,若是你是java語言的設計者,你是否會提供這樣的支持,若是不提供的話,有什麼理由嗎?若是你沒有道理不提供,那答案就是確定的了。
只有記住抽象類與普通類的惟一區別就是不能建立實例對象和容許有abstract方法。
4三、 用最有效率的方法算出 2 乘以 8 等於幾 ?
【參考答案】
2 << 3
【分析】
由於將一個數左移n位,就至關於乘以了2的n次方,那麼,一個數乘以8只要將其左移3位便可,而位運算cpu直接支持的,效率最高,因此2乘以8等於幾的最效率的方法是2 << 3。
4四、 char 型變量中能不能存貯一箇中文漢字 ? 爲何 ?
【參考答案】
char型變量是用來存儲Unicode編碼的字符的,unicode編碼字符集中包含了漢字,因此,char型變量中固然能夠存儲漢字啦。不過,若是某個特殊的漢字沒有被包含在unicode編碼字符集中,那麼,這個char型變量中就不能存儲這個特殊漢字。補充說明:unicode編碼佔用兩個字節,因此,char類型的變量也是佔用兩個字節。
4五、 寫 clone() 方法時,一般都有一行代碼,是什麼?
【參考答案】
clone有缺省行爲,super.clone();由於首先要把父類中的成員複製到位,而後纔是複製本身的成員。
4六、 說說經常使用集合類有哪些?有哪些方法?
【參考答案】
一般咱們使用的集合類都大可能是由List、Set、Map這三類接口派生出來的類,例如:
ArrayList、Vector、LinkedList、Stack、TreeSet、Hashtable、HashMap等
集合類的大部分方法都是由Collection接口定義的,主要包括有:
add(Ee)、remove(Object e)、addAll(),remove()、 contains(Object obj) 、clear()等
4七、 請說出做用域 public , private , protected ,以及不寫時的區別 ? 【天威誠信面試題】
【參考答案】
這四個做用域的可見範圍以下表所示。
說明:若是在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。
做用域同一類同一package子孫類其餘package
public√√√√
protected√√√×
friendly√√××
private√×××
備註:只要記住了有4種訪問權限,4個訪問範圍,而後將全選和範圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。
4八、 構造器 Constructor 是否可被 override? 【億陽通信面試題】
【參考答案】
構造器Constructor不能被繼承,所以不能重寫Override,但能夠被重載Overload。
4九、 是否能夠從一個 static 方法內部發出對非 static 方法的調用? 【世承軟件面試題】
【參考答案】
不能夠。由於非static方法是要與對象關聯在一塊兒的,必須建立一個對象後,才能夠在該對象上進行方法調用,而static方法調用時不須要建立對象,能夠直接調用。
50、 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.floor(x+0.5),即將原來的數字加上0.5後再向下取整,因此,Math.round(11.5)的結果爲12,Math.round(-11.5)的結果爲-11。
5一、 abstract class (抽象類)和 interface (接口)有什麼區別 ? 【百度應用中心面試題】
【參考答案】
含有abstract修飾符的class即爲抽象類,abstract類不能建立的實例對象。含有abstract方法的類必須定義爲abstract class,abstract class類中的方法沒必要是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,因此,不能有抽象構造方法或抽象靜態方法。若是的子類沒有實現抽象父類中的全部抽象方法,那麼子類也必須定義爲abstract類型。
接口(interface)能夠說成是抽象類的一種特例,接口中的全部方法都必須是抽象的。接口中的方法定義默認爲public abstract類型,接口中的成員變量類型默認爲public static final。
下面比較一下二者的語法區別:
1.抽象類能夠有構造方法,接口中不能有構造方法。
2.抽象類中能夠有普通成員變量,接口中沒有普通成員變量
3.抽象類中能夠包含非抽象的普通方法,接口中的全部方法必須都是抽象的,不能有非抽象的普通方法。
4.抽象類中的抽象方法的訪問類型能夠是public,protected和(默認類型,雖然
eclipse下不報錯,但應該也不行),但接口中的抽象方法只能是public類型的,而且默認即爲public abstract類型。
5.抽象類中能夠包含靜態方法,接口中不能包含靜態方法
6.抽象類和接口中均可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型能夠任意,但接口中定義的變量只能是public static final類型,而且默認即爲public static final類型。
7.一個類能夠實現多個接口,但只能繼承一個抽象類。
下面接着再說說二者在應用上的區別:
【分析】
這道題的思路是先從整體解釋抽象類和接口的基本概念,而後再比較二者的語法細節,最後再說二者的應用區別。比較二者語法細節區別的條理是:先從一個類中的構造方法、普通成員變量和方法(包括抽象方法),靜態變量和方法,繼承性等方面來回答。
5二、 Collection 框架中實現比較要實現什麼接口 ?
【參考答案】
Comparable、Comparator接口
5三、 是否能夠繼承 String 類 ?
【參考答案】
String類是final類故不能夠繼承。
5四、 String 和 StringBuffer 的區別
【參考答案】
JAVA平臺提供了兩個類:String和StringBuffer,它們能夠儲存和操做字符串,即包含多個字符的字符數據。String類表示內容不可改變的字符串。而StringBuffer類表示內容能夠被修改的字符串。當你知道字符數據要改變的時候你就能夠使用StringBuffer。典型地,你能夠使用StringBuffers來動態構造字符數據。另外,String實現了equals方法,new String(「abc」).equals(new String(「abc」)的結果爲true,而StringBuffer沒有實現equals方法,因此,new StringBuffer(「abc」).equals(new StringBuffer(「abc」)的結果爲false。
String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,因此,將StringBuffer對象存儲進Java集合類中時會出現問題。
5五、 StringBuffer 與 StringBuilder 的區別
【參考答案】
StringBuffer和StringBuilder類都表示內容能夠被修改的字符串,StringBuilder是線程不安全的,運行效率高,若是一個字符串變量是在方法裏面定義,這種狀況只可能有一個線程訪問它,不存在不安全的因素了,則用StringBuilder。若是要在類裏面定義成員變量,而且這個類的實例對象會在多線程環境下使用,那麼最好用StringBuffer。
5六、 try {} 裏有一個 return 語句,那麼緊跟在這個 try 後的 finally {} 裏的 code 會不會被執行,何時被執行,在 return 前仍是後 ? 【杭州天眼科技】
【參考答案】
答案是在return以前。
【分析】
程序代碼的運行結果:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new Test().test());;
}
static int test()
{
int x = 1;
try
{
return x;
}
finally
{
++x;
}
}
}
---------執行結果---------
1
運行結果是1,爲何呢?主函數調用子函數並獲得結果的過程,比如主函數準備一個空罐子,當子函數要返回結果時,先把結果放在罐子裏,而後再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不運行了,你主函數繼續運行吧,這沒什麼結果可言,結果是在說這話以前放進罐子裏的。
下面的程序代碼輸出的結果是多少?
public class smallT
{
public static void main(String args[])
{
smallT t = new smallT();
int b = t.get();
System.out.println(b);
}
public int get()
{
try
{
return 1 ;
}
finally
{
return 2 ;
}
}
}
返回的結果是2。
我能夠經過下面一個例子程序來幫助我解釋這個答案,從下面例子的運行結果中能夠發現,try中的return語句調用的函數先於finally中調用的函數執行,也就是說return語句先執行,finally語句後執行,因此,返回的結果是2。Return並非讓函數立刻返回,而是return語句執行後,將把返回結果放置進函數棧中,此時函數並非立刻返回,它要執行finally語句後才真正開始返回。
在講解答案時能夠用下面的程序來幫助分析:
public class Test {
/**
* @param args add by zxx ,Dec 9, 2008
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new Test().test());;
}
int test()
{
try
{
return func1();
}
finally
{
return func2();
}
}
int func1()
{
System.out.println("func1");
return 1;
}
int func2()
{
System.out.println("func2");
return 2;
}
}
-----------執行結果-----------------
func1
func2
2
結論:finally中的代碼比return和break語句後執行。
5七、 Java 中的異常處理機制的簡單原理和應用。
【參考答案】
異常是指java程序運行時(非編譯)所發生的非正常狀況或錯誤,與現實生活中的事件很類似,現實生活中的事件能夠包含事件發生的時間、地點、人物、情節等信息,能夠用一個對象來表示,Java使用面向對象的方式來處理異常,它把程序中發生的每一個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息。
Java對異常進行了分類,不一樣類型的異常分別用不一樣的Java類表示,全部異常的根類爲java.lang.Throwable,Throwable下面又派生了兩個子類:Error和Exception,Error表示應用程序自己沒法克服和恢復的一種嚴重問題,程序只有死的份了,例如,說內存溢出和線程死鎖等系統問題。Exception表示程序還可以克服和恢復的問題,其中又分爲系統異常和普通異常,系統異常是軟件自己缺陷所致使的問題,也就是軟件開發人員考慮不周所致使的問題,軟件使用者沒法克服和恢復這種問題,但在這種問題下還可讓軟件系統繼續運行或者讓軟件死掉,例如,數組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是運行環境的變化或異常所致使的問題,是用戶可以克服的問題,例如,網絡斷線,硬盤空間不夠,發生這樣的異常後,程序不該該死掉。
java爲系統異常和普通異常提供了不一樣的解決方案,編譯器強制普通異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,因此普通異常也稱爲checked異常,而系統異常能夠處理也能夠不處理,因此,編譯器不強制用try..catch處理或用throws聲明,因此係統異常也稱爲unchecked異常。
5八、 多線程有幾種實現方法 ? 同步有幾種實現方法 ?
【參考答案】
多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口。
同步的實現方面有兩種,分別是synchronized,wait與notify。
a.wait():使一個線程處於等待狀態,而且釋放所持有的對象的lock。
b.sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
c.notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM肯定喚醒哪一個線程,並且不是按優先級。
d.allnotity():喚醒全部處入等待狀態的線程,注意並非給全部喚醒線程一個對象的鎖,而是讓它們競爭。
5九、 啓動一個線程是用 run() 仍是 start()?
【參考答案】
啓動一個線程是調用start()方法,使線程就緒狀態,之後能夠被調度爲運行狀態,一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。
60、 內部類能夠引用外部類的成員嗎?有沒有什麼限制?
【參考答案】
徹底能夠。若是不是靜態內部類,那沒有什麼限制!
若是你把靜態嵌套類看成內部類的一種特例,那在這種狀況下不能夠訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員。
6一、 List 和 Map 區別 ? 【軟通動力】
【參考答案】
一個是存儲單列數據的集合,另外一個是存儲鍵和值這樣的雙列數據的集合,List中存儲的數據是有順序,而且容許重複;Map中存儲的數據是沒有順序的,其鍵是不能重複的,它的值是能夠有重複的。
6二、 ArrayList 和 Vector 的區別【博炎科技】
【參考答案】
這兩個類都實現了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,至關於一種動態的數組,咱們之後能夠按位置索引號取出某個元素,而且其中的數據是容許重複的。
接着說ArrayList與Vector的區別,這主要包括兩個方面:
一、同步性:
Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不一樣步的。若是隻有一個線程會訪問到集合,那最好是使用ArrayList,由於它不考慮線程安全,效率會高些;若是有多個線程會訪問到集合,那最好是使用Vector,由於不須要咱們本身再去考慮和編寫線程安全的代碼。
備註:對於Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是線程安全的,ArrayList與HashMap是java2時才提供的,它們是線程不安全的。
二、數據增加:
ArrayList與Vector都有一個初始的容量大小,當存儲進它們裏面的元素的個數超過了容量時,就須要增長ArrayList與Vector的存儲空間,每次要增長存儲空間時,不是隻增長一個存儲單元,而是增長多個存儲單元,每次增長的存儲單元的個數在內存空間利用與程序效率之間要取得必定的平衡。Vector默認增加爲原來兩倍,而ArrayList的增加爲原來的1.5倍。ArrayList與Vector均可以設置初始的空間大小,Vector還能夠設置增加的空間大小,而ArrayList沒有提供設置增加空間的方法。
6三、 heap 和 stack 有什麼區別。
【參考答案】
Java的內存分爲兩類,一類是棧內存,一類是堆內存。棧內存是指程序進入一個方法時,會爲這個方法單獨分配一塊私屬存儲空間,用於存儲這個方法內部的局部變量,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。
堆是與棧做用不一樣的內存,通常用於存放不放在當前方法棧中的那些數據,例如,使用
new建立的對象都放在堆裏,因此,它不會隨方法的結束而消失。方法中的局部變量使
用final修飾後,放在堆中,而不是棧中。
6四、 J ava 類實現序列化的方法(二種)?如在 collection 框架中實現排序,要實現什麼樣的接口
【參考答案】
java.io.Serializable接口或實現Externalizable接口。
Collection框架中實現比較要實現Comparable接口或Comparator接口,並實現比較方法
6五、 JAVA 實現向數據庫添加一列。
【參考答案】
Connection con = null;
ResultSet rs = null;
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_name";
Connection con = DriverManager.getConnection(url,"","");
StateManager sm =con.createStateMent();
String sql = " alter table student add age int; ";
rs = sm.excute(sql);
6六、 什麼是 J ava 序列化,如何實現 java 序列化?或者請解釋 Serializable 接口的做用。【東軟國際】
【參考答案】
序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。序列化是爲了解決在對對象流進行讀寫操做時所引起的問題。
序列化的實現:將須要被序列化的類實現Serializable接口,該接口沒有須要實現的方法,implements Serializable只是爲了標註該對象是可被序列化的,而後使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(對象流)對象,使用ObjectOutputStream對象的writeObject(Object obj)方法就能夠將參數爲obj的對象寫出,那麼在另外一端,經過ObjectInputStream對象的readObject(Object obj)獲取到字節流數據後,要將字節流轉換成原對象,這叫反序列化,以便將數據存儲在文件中或在網絡傳輸。
Serializable接口描述啓用其序列化功能,未實現此接口的類將沒法使其任何狀態序列化或反序列化。Serializable接口沒有方法或字段,僅用於標識可序列化的語義,標識實現了該接口的對象屬性可被序列化。
6七、 J ava 中有幾種類型的流? JDK 爲每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?
【參考答案】
字節流,字符流兩種類型流。字節流繼承於InputStream、OutputStream;字符流繼承於Reader 、 Writer。其它與IO操做相關的類都是派生至上述4個抽象類,如字節相關的:FileInputStream、FileOutputStream類;字符相關的:BufferedReader、BufferedWriter類
6八、 用 JDBC 如何調用存儲過程
【參考答案】
經過JDBC組件中的CallableStatement接口實現調用存儲過程。
核心代碼以下:
Class.forName("com.mysql.jdbc.Driver");
Connection conn=
DriverManager.getConnection("jdbc:mysql:///test","root","root");
CallableStatement cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1, "wangwu");
cstmt.setInt(2, 25);
cstmt.execute();
6九、 JAVA 事件有哪些模式?
【參考答案】
一、事件直接驅動模式。它的特色是直接並且快,是必須常用的,主要適合於迅速處理前臺的命令,一般就是咱們說的command(命令)模式。。2.監控式事件模式。主要藉助第三者來監控和觸發事件,就是一般咱們說的觀察者模式。特色是:有一個觀察者置身事外在按期獨立運行着,咱們將咱們要監聽的事件向這個觀察者註冊,這樣觀察者就代替咱們來監聽這個事件,應用客戶端經過觀察者來得到事件情況。
【分析】
70、 JVM 加載 class 文件原理?
【參考答案】
所謂裝載就是尋找一個類或是一個接口的二進制形式並用該二進制形式來構造表明這個類或是這個接口的class對象的過程.
在Java中,類裝載器把一個類裝入Java虛擬機中,要通過三個步驟來完成:裝載、連接和初始化,其中連接又能夠分紅校驗、準備、解析
裝載:查找和導入類或接口的二進制數據;
連接:執行下面的校驗、準備和解析步驟,其中解析步驟是能夠選擇的;
校驗:檢查導入類或接口的二進制數據的正確性;
準備:給類的靜態變量分配並初始化存儲空間;
解析:將符號引用轉成直接引用;
初始化:激活類的靜態變量的初始化Java代碼和靜態Java代碼塊
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader是一個重要的Java運行時系統組件。它負責在運行時查找和裝入類文件的類
一個Java應用程序使用兩種類型的類裝載器:根裝載器(bootstrap)和用戶定義的裝載器(user-defined)。
根裝載器以某種默認的方式將類裝入,包括那些Java API的類。在運行期間一個Java程序能安裝用戶本身定義的類裝載器。根裝載器是虛擬機固有的一部分,而用戶定義的類裝載器則不是,它是用Java語言寫的,被編譯成class文件以後而後再被裝入到虛擬機,並像其它的任何對象同樣能夠被實例化。Java類裝載器的體系結構以下所示:
Bootstrap(根裝載器)
|
Extension (擴展裝載器)
|
System
|
UserDefine1
/
UserDefine2 UserDefine3
|
UserDefine4
Java的類裝載模型是一種代理(delegation)模型。當JVM要求類裝載器CL(ClassLoader)裝載一個類時,CL首先將這個類裝載請求轉發給他的父裝載器。只有當父裝載器沒有裝載並沒有法裝載這個類時,CL纔得到裝載這個類的機會。這樣,全部類裝載器的代理關係構成了一種樹狀的關係。樹的根是類的根裝載器(bootstrap ClassLoader) ,在JVM中它以"null"表示。除根裝載器之外的類裝載器有且僅有一個父裝載器。在建立一個裝載器時,若是沒有顯式地給出父裝載器,那麼JVM將默認系統裝載器爲其父裝載器
下面針對各類類裝載器分別進行詳細的說明:
根(Bootstrap)裝載器:該裝載器沒有父裝載器,它是JVM實現的一部分,從sun.boot.class.path裝載運行時庫的核心代碼。
擴展(Extension)裝載器:繼承的父裝載器爲根裝載器,不像根裝載器可能與運行時的操做系統有關,這個類裝載器是用純Java代碼實現的,它從java.ext.dirs (擴展目錄)中裝載代碼。
系統(System or Application)裝載器:裝載器爲擴展裝載器,咱們都知道在安裝JDK的時候要設置環境變量(CLASSPATH ),這個類裝載器就是從java.class.path(CLASSPATH環境變量)中裝載代碼的,它也是用純Java代碼實現的,同時仍是用戶自定義類裝載器的缺省父裝載器。
小應用程序(Applet)裝載器:裝載器爲系統裝載器,它從用戶指定的網絡上的特定目錄裝載小應用程序代碼。
7一、 SOCKET 中有幾中鏈接方式,各有什麼區別?
【參考答案】
Sockets有兩種主要的操做方式:面向鏈接(TCP/IP)的和無鏈接(UDP)的。無鏈接的操做使用數據報協議,無鏈接的操做是快速的和高效的,可是數據安全性不佳.面向鏈接的操做使用TCP協議.面向鏈接的操做比無鏈接的操做效率更低,可是數據的安全性更高
【分析】
7二、 抽象類可否被實例化 ?抽象類的做用是什麼?
【參考答案】
抽象類通常不能被實例化;抽象類一般不是由程序員定義的,而是由項目經理或模塊設計人設計抽象類的緣由一般是爲了規範方法名抽象類必需要繼承,否則無法用,做爲模塊設計者,能夠把讓底層程序員直接用得方法直接調用,而一些須要讓程序員覆蓋後本身作得方法則定義稱抽象方法
【分析】
7三、 Linkedlist 、 A rraylist 內部是如何實現的(更深刻的問了 LinkedList 與 ArrayList 的區別) 【天威誠信面試題】
【參考答案】
ArrayList的內部實現是基於內部數組Object[],它更像是對數組實現的一種封裝,因此在向ArrayList的前面或中間插入數據時,必須將其後的全部數據相應的後移,這樣必然要花費較多時間。
而LinkedList的內部實現是基於一組雙向鏈表實現的存儲特性,因此提供了鏈表同樣訪問的API接口,它們在性能上有很大的差異。當你訪問Linkedlist鏈表中的某個元素時,就必須從鏈表的一端開始沿着鏈接方向一個一個元素地去查找,直到找到所需的元素爲止,因此,當你的操做是在一列數據的前面或中間添加或刪除數據,而且按照順序訪問其中的元素時,就應該使用LinkedList了。
而當你的操做是在一列數據的後面添加數據而不是在前面或中間,而且須要隨機地訪問其中的元素時,使用ArrayList會提供比較好的性能。
【分析】
7四、 H a s htable 的原理【北辰網絡】
【參考答案】
經過節點的關鍵碼肯定節點的存儲位置,即給定節點的關鍵碼k,經過必定的函數關係H(散列函數),獲得函數值H(k),將此值解釋爲該節點的存儲地址
7五、 JDBC 中的 PreparedStatement 相比 Statement 的好處?
【參考答案】
預編譯語句 java .sql.PreparedStatement ,擴展自Statement,不但具備Statement的全部能力並且具備更強大的功能。不一樣的是,PreparedStatement是在建立語句對象的同時給出要執行的sql語句。這樣,sql語句就會被系統進行預編譯,執行的速度會有所增長,尤爲是在執行大語句的時候,效果更加理想
7六、 sleep() 和 wait() 區別
【參考答案】
sleep()方法:線程主動放棄CPU,使得線程在指定的時間內進入阻塞狀態,不能獲得CPU時間,指定的時間一過,線程從新進入可執行狀態。典型地,sleep()被用在等待某個資源就緒的情形:測試發現條件不知足後,讓線程阻塞一段時間後從新測試,直到條件知足爲止。
wait( ):與notify()配套使用,wait()使得線程進入阻塞狀態,它有兩種形式,一種容許指定以毫秒爲單位的一段時間做爲參數,另外一種沒有參數,當指定時間參數時對應的notify()被調用或者超出指定時間時線程從新進入可執行狀態,後者則必須對應的notify()被調用
( 網上的答案 :sleep是線程類(Thread)的方法,致使此線程暫停執行指定時間,給執行機會給其餘線程,可是監控狀態依然保持,到時後會自動恢復。調用sleep不會釋放對象鎖。wait是Object類的方法,對此對象調用wait方法致使本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)後本線程才進入對象鎖定池準備得到對象鎖進入運行狀態。)
sleep就是正在執行的線程主動讓出cpu,cpu去執行其餘線程,在sleep指定的時間事後,cpu纔會回到這個線程上繼續往下執行,若是當前線程進入了同步鎖,sleep方法並不會釋放鎖,即便當前線程使用sleep方法讓出了cpu,但其餘被同步鎖擋住了的線程也沒法獲得執行。wait是指在一個已經進入了同步鎖的線程內,讓本身暫時讓出同步鎖,以便其餘正在等待此鎖的線程能夠獲得同步鎖並運行,只有其餘線程調用了notify方法(notify並不釋放鎖,只是告訴調用過wait方法的線程能夠去參與得到鎖的競爭了,但不是立刻獲得鎖,由於鎖還在別人手裏,別人還沒釋放。若是notify方法後面的代碼還有不少,須要這些代碼執行完後纔會釋放鎖,能夠在notfiy方法後增長一個等待和一些代碼,看看效果),調用wait方法的線程就會解除wait狀態和程序能夠再次獲得鎖後繼續向下運行。對於wait的講解必定要配合例子代碼來講明,才顯得本身真明白。
package com.huawei.interview;
public class MultiThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new Thread1()).start();
try {
Thread.sleep(10);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Thread(new Thread2()).start();
}
private static class Thread1 implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
//因爲這裏的Thread1和下面的Thread2內部run方法要用同一對象做爲監視器,咱們這裏不能用this,由於在Thread2裏面的this和這個Thread1的this不是同一個對象。咱們用MultiThread.class這個字節碼對象,當前虛擬機裏引用這個變量時,指向的都是同一個對象。
synchronized (MultiThread.class) {
System.out.println("enter thread1...");
System.out.println("thread1 is waiting");
try {
//釋放鎖有兩種方式,第一種方式是程序天然離開監視器的範圍,也就是離開了synchronized關鍵字管轄的代碼範圍,另外一種方式就是在synchronized關鍵字管轄的代碼內部調用監視器對象的wait方法。這裏,使用wait方法釋放鎖。
MultiThread.class.wait();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("thread1 is going on...");
System.out.println("thread1 is being over!");
}
}
}
private static class Thread2 implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (MultiThread.class) {
System.out.println("enter thread2...");
System.out.println("thread2 notify other thread can release wait status..");
//因爲notify方法並不釋放鎖,即便thread2調用下面的sleep方法休息了10毫秒,但thread1仍然不會執行,由於thread2沒有釋放鎖,因此Thread1沒法得不到鎖。
MultiThread.class.notify();
System.out.println("thread2 is sleeping ten millisecond...");
try {
Thread.sleep(10);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("thread2 is going on...");
System.out.println("thread2 is being over!");
}
}
}
})
7七、 概述反射和序列化
【參考答案】
Reflection :是Java被視爲動態語言的一個關鍵性質。這個機制容許程序在運行時透過Reflection APIs取得任何一個已知名稱的class的內部信息,包括其modifiers(諸如public, static等等)、superclass(例如Object)、實現之interfaces(例如Cloneable),也包括fields和methods的全部信息,並可於運行時改變fields內容或喚起methods。
序列化 : 就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。序列化是爲了解決在對對象流進行讀寫操做時的問題。
7八、 J ava 中實現多態的機制是什麼 ?
【參考答案】
重寫,重載
方法的重寫Overriding和重載Overloading是Java多態性的不一樣表現。
重寫Overriding是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。若是在子類中定義某方法與其父類有相同的名稱和參數,咱們說該方法被重寫(Overriding)。子類的對象使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被「屏蔽」了。
果在一個類中定義了多個同名的方法,它們或有不一樣的參數個數或有不一樣的參數類型,則稱爲方法的重載(Overloading)。Overloaded的方法是能夠改變返回值的類型。
7九、 Overload 和 Override 的區別? Overloaded 的方法是否能夠改變返回值的類型 ? 【軟通動力】
【參考答案】
Overload是重載的意思,Override是覆蓋的意思,也就是重寫。
重載Overload表示同一個類中能夠有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不一樣)。
重寫Override表示子類中的方法能夠與父類中的某個方法的名稱和參數徹底相同,經過子類建立的實例對象調用這個方法時,將調用子類中的定義方法,這至關於把父類中定義的那個徹底相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,由於子類能夠解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權限只能比父類的更大,不能更小。若是父類的方法是private類型,那麼,子類則不存在覆蓋的限制,至關於子類中增長了一個全新的方法。
是否能夠改變返回值類型,在重載的定義中,與方法是什麼類型返回值無關。
【分析】
override能夠翻譯爲覆蓋,從字面就能夠知道,它是覆蓋了一個方法而且對其重寫,以求達到不一樣的做用。對咱們來講最熟悉的覆蓋就是對接口方法的實現,在接口中通常只是對方法進行了聲明,而咱們在實現時,就須要實現接口聲明的全部方法。除了這個典型的用法之外,咱們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意如下的幾點:
一、覆蓋的方法的標誌必需要和被覆蓋的方法的標誌徹底匹配,才能達到覆蓋的效果;
二、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;
三、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;
四、被覆蓋的方法不能爲private,不然在其子類中只是新定義了一個方法,並無對其進行覆蓋。
overload對咱們來講可能比較熟悉,能夠翻譯爲重載,它是指咱們能夠定義一些名稱相同的方法,經過定義不一樣的輸入參數來區分這些方法,而後再調用時,VM就會根據不一樣的參數樣式,來選擇合適的方法執行。在使用重載要注意如下的幾點:
一、在使用重載時只能經過不一樣的參數樣式。例如,不一樣的參數類型,不一樣的參數個數,不一樣的參數順序(固然,同一方法內的幾個參數類型必須不同,例如能夠是fun(int,float),可是不能爲fun(int,int));
二、不能經過訪問權限、返回類型、拋出的異常進行重載;
三、方法的異常類型和數目不會對重載形成影響;
四、對於繼承來講,若是某一方法在父類中是訪問權限是priavte,那麼就不能在子類對其進行重載,若是定義的話,也只是定義了一個新方法,而不會達到重載的效果。
80、 ClassLoader 如何加載 class 。
【參考答案】
jvm裏有多個類加載,每一個類加載能夠負責加載特定位置的類,例如,bootstrap類加載負責加載jre/lib/rt.jar中的類,咱們平時用的jdk中的類都位於rt.jar中。extclassloader負責加載jar/lib/ext/*.jar中的類,appclassloader負責classpath指定的目錄或jar中的類。除了bootstrap以外,其餘的類加載器自己也都是java類,它們的父類是ClassLoader。
8一、 ArrayList 如何實現插入的數據按自定義的方式有序存放
【參考答案】
實現Comparable比較接口,並實現compareTo方法。排序的方法,取決於compareTo方法中的比較定義的返回值,通常有3個返回值:一、-一、0表示不一樣的比較結果。
程序示例:
class MyBean implements Comparable {
public int compareTo (Object obj){
if(! obj instanceof MyBean)
throw new ClassCastException();
MyBean other = (MyBean) obj;
return age > other.age?1:age== other.age?0:-1;
}
}
class MyTreeSet {
private ArrayList datas = new ArrayList();
public void add(Object obj){
for(int i=0;i
if(obj.compareTo(datas.get(i) != 1){
datas.add(i,obj);
}
}
}
}
8二、 hashCode 方法的做用?
【參考答案】
hashcode這個方法是用來鑑定2個對象是否相等的。hashcode方法通常用戶不會去調用,好比在hashmap中,因爲key是不能夠重複的,他在判斷key是否是重複的時候就判斷了hashcode這個方法,並且也用到了equals方法。這裏不能夠重複是說equals和hashcode只要有一個不等就能夠了!因此簡單來說,hashcode至關因而一個對象的編碼。咱們通常在覆蓋equals的同時也要覆蓋hashcode,讓他們的邏輯一致。
8三、 abstract 的 method 是否可同時是 static, 是否可同時是 native ,是否可同時是 synchronized?
【參考答案】
abstract的method不能夠是static的,由於抽象的方法是要被子類實現的,而static與子類扯不上關係!
native方法表示該方法要用另一種依賴平臺的編程語言實現的,不存在着被子類實現的問題,因此,它也不能是抽象的,不能與abstract混用。例如,FileOutputSteam類要硬件打交道,底層的實現用的是操做系統相關的api實現,例如,在windows用c語言實現的,因此,查看jdk的源代碼,能夠發現FileOutputStream的open方法的定義以下:
private native void open(String name) throws FileNotFoundException;
若是咱們要用java調用別人寫的c語言函數,咱們是沒法直接調用的,咱們須要按照java的要求寫一個c語言的函數,又咱們的這個c語言函數去調用別人的c語言函數。因爲咱們的c語言函數是按java的要求來寫的,咱們這個c語言函數就能夠與java對接上,java那邊的對接方式就是定義出與咱們這個c函數相對應的方法,java中對應的方法不須要寫具體的代碼,但須要在前面聲明native。
關於synchronized與abstract合用的問題,我以爲也不行,由於在我幾年的學習和開發中,歷來沒見到過這種狀況,而且我以爲synchronized應該是做用在一個具體的方法上纔有意義。並且,方法上的synchronized同步所使用的同步鎖對象是this,而抽象方法上沒法肯定this是什麼。
8四、 Anonymous Inner Class ( 匿名內部類 ) 是否能夠 extends( 繼承 ) 其它類,是否能夠 implements( 實現 )interface( 接口 )?
【參考答案】
能夠繼承其餘類或實現其餘接口。不只是能夠,而是必須!
8五、 JAVA 語言如何進行異常處理,關鍵字: throws,throw,try,catch,finally 分別表明什麼意義?在 try 塊中能夠拋出異常嗎?
【參考答案】
Java使用面向對象的方式來處理異常,它把程序中發生的每一個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息。而throws hrow ry、catch、finally就是Java中用來對異常進行處理的幾個關鍵字,在Java編程中規容Java編譯器強制普通異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,通常異常必需要求被捕獲和處理,而系統異常能夠處理也能夠不處理,因此編譯器不強制用try..catch處理或用throws、throw聲明異常。而finally通常與try或trycatch一塊兒使用作爲異常的最後處理出口。
8六、 同步和異步有何異同,在什麼狀況下分別使用他們?舉例說明。
【參考答案】
若是數據將在線程間共享。例如正在寫的數據之後可能被另外一個線程讀到,或者正在讀的數據可能已經被另外一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取。
當應用程序在對象上調用了一個須要花費很長時間來執行的方法,而且不但願讓程序等待方法的返回時,就應該使用異步編程,在不少狀況下采用異步途徑每每更有效率。
8七、 當一個線程進入一個對象的一個 synchronized 方法後,其它線程是否可進入此對象的其它方法 ?
【參考答案】
分幾種狀況:
1.其餘方法前是否加了synchronized關鍵字,若是沒加,則能。
2.若是這個方法內部調用了wait,則能夠進入其餘synchronized方法。
3.若是其餘個方法都加了synchronized關鍵字,而且內部沒有調用wait,則不能。
4.若是其餘方法是static,它用的同步鎖是當前類的字節碼,與非靜態的方法不能同步,由於非靜態的方法用的是this。
8八、 線程的基本概念、線程的基本狀態以及狀態之間的關係
【參考答案】
一個程序中能夠有多條執行線索同時執行,一個線程就是程序中的一條執行線索,每一個線程上都關聯有要執行的代碼,便可以有多段程序代碼同時運行,每一個程序至少都有一個線程,即main方法執行的那個線程。若是隻是一個cpu,它怎麼可以同時執行多段程序呢?這是從宏觀上來看的,cpu一會執行a線索,一會執行b線索,切換時間很快,給人的感受是a,b在同時執行,比如你們在同一個辦公室上網,只有一條連接到外部網線,其實,這條網線一會爲a傳數據,一會爲b傳數據,因爲切換時間很短暫,因此,你們感受都在同時上網。
狀態:就緒,運行,synchronize阻塞,wait和sleep掛起,結束。wait必須在synchronized內部調用。
調用線程的start方法後線程進入就緒狀態,線程調度系統將就緒狀態的線程轉爲運行狀態,遇到synchronized語句時,由運行狀態轉爲阻塞,當synchronized得到鎖後,由阻塞轉爲運行,在這種狀況能夠調用wait方法轉爲掛起狀態,當線程關聯的代碼執行完後,線程變爲結束狀態。
8九、 簡述 synchronized 和 java.util.concurrent.locks.Lock 的異同 ?
【參考答案】
主要相同點:Lock能完成synchronized所實現的全部功能
主要不一樣點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock必定要求程序員手工釋放,而且必須在finally從句中釋放。Lock還有更強大的功能,例如,它的tryLock方法能夠非阻塞方式去拿鎖。
90、 HashMap 和 Hashtable 的區別?【北通網科】
【參考答案】
HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都實現Map接口,主要區別在於HashMap容許空(null)鍵值(key),因爲非線程安全,在只有一個線程訪問的狀況下,效率要高於Hashtable。
HashMap容許將null做爲一個entry的key或者value,而Hashtable不容許。
HashMap把Hashtable的contains方法去掉了,改爲containsvalue和containsKey。由於contains方法容易讓人引發誤解。
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。
最大的不一樣是,Hashtable的方法是synchronized的,而HashMap不是,在多個線程訪問Hashtable時,不須要本身爲它的方法實現同步,而HashMap就必須爲之提供外同步。
Hashtable和HashMap採用的hash/rehash算法都大概同樣,因此性能不會有很大的差別。
9一、 List 、 Set 、 Map 是否繼承自 Collection 接口 ?
【參考答案】
List、Set是,Map不是;Map接口定義的是Key-Value存儲的特性,與List和Set不一樣,Map在存儲對象時,先要定義這個對象的key的值,再存入與這個key相對應的Object,Map集合的取值時根據存入的key(關鍵字)來獲取與這個關鍵字對應的對象。
9二、 List 、 Map 、 Set 三個接口,存取元素時,各有什麼特色?
【參考答案】
首先,List與Set具備類似性,它們都是單列元素的集合,因此,它們有一個功共同的父接口Collection接口。Set裏面不容許有重複的元素,即不能有兩個相等的對象。
List表示有前後順序的集合,當咱們屢次調用add(Obj e)方法時,每次加入的對象就像火車站買票有排隊順序同樣,按先來後到的順序排序。
Map與List和Set不一樣,它是雙列的集合每次存儲時,要存儲一對key/value,不能存儲重複的key,這個重複的規則也是按equals比較相等。取則能夠根據key得到相應的value,即get(Object key)返回值爲key所對應的value。另外,也能夠得到全部的key的結合。
【分析】
總結:List以特定次序來持有元素,可有重複元素。Set沒法擁有重複元素,內部排序。Map保存key-value值,value可多值。上面是大體不一樣,另外上述3個只是接口,而具體實現類中,用法大同小異,只是實現的數據結構不一樣,例如List接口下的LinkedList主要實現了雙鏈表的存儲特色,Vector是線程安全的集合類。
9三、 說出 ArrayList,Vector, LinkedList 的存儲性能和特性。【 大唐動力面試題 】
【參考答案】
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector因爲使用了synchronized方法(線程安全),一般性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。
LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList能夠被看成堆棧和隊列來使用。
9四、 如何去掉一個 Vector 集合中重複的元素
【參考答案】
Vector newVector = new Vector();
for (int i=0;i
{
Object obj = vector.get(i);
if(!newVector.contains(obj);
newVector.add(obj);
}
還有一種簡單的方式,HashSet set = new HashSet(vector);
9五、 Set 裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢 ? 是用 == 仍是 equals()? 它們有何區別 ?
【參考答案】
Set裏的元素是不能重複的,元素重複與否是使用equals()方法進行判斷的。
9六、 兩個對象值相同 (x.equals(y) == true) ,但卻可有不一樣的 hash code ,這句話對不對 ?
【參考答案】
對。
若是對象要保存在HashSet或HashMap中,它們的equals相等,那麼,它們的hashcode值就必須相等。
若是不是要保存在HashSet或HashMap,則與hashcode沒有什麼關係了,這時候hashcode不等是能夠的,例如arrayList存儲的對象就不用實現hashcode方法。
9七、 字節流與字符流的區別
【參考答案】
要把一片二進制數據數據逐一輸出到某個設備中,或者從某個設備中逐一讀取一片二進制數據,無論輸入輸出設備是什麼,咱們要用統一的方式來完成這些操做,用一種抽象的方式進行描述,這個抽象描述方式起名爲IO流,對應的抽象類爲OutputStream和InputStream,不一樣的實現類就表明不一樣的輸入和輸出設備,它們都是針對字節進行操做的。
在應用中,常常要徹底是字符的一段文本輸出去或讀進來,用字節流能夠嗎?計算機中的一切最終都是二進制的字節形式存在。對於「中國」這些字符,首先要獲得其對應的字節,而後將字節寫入到輸出流。讀取時,首先讀到的是字節,但是咱們要把它顯示爲字符,咱們須要將字節轉換成字符。因爲這樣的需求很普遍,人家專門提供了字符流的包裝類。
底層設備永遠只接受字節數據,有時候要寫字符串到底層設備,須要將字符串轉成字節再進行寫入。字符流是字節流的包裝,字符流則是直接接受字符串,它內部將串轉成字節,再寫入底層設備,這爲咱們向IO設別寫入或讀取字符串提供了一點點方便。
字符向字節轉換時,要注意編碼的問題,由於字符串轉成字節數組,
實際上是轉成該字符的某種編碼的字節形式,讀取也是反之的道理。
講解字節流與字符流關係的代碼案例:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class IOTest {
public static void main(String[] args) throws Exception {
String str = "中國人";
/*FileOutputStream fos = new FileOutputStream("1.txt");
fos.write(str.getBytes("UTF-8"));
fos.close();*/
/*FileWriter fw = new FileWriter("1.txt");
fw.write(str);
fw.close();*/
PrintWriter pw = new PrintWriter("1.txt","utf-8");
pw.write(str);
pw.close();
/*FileReader fr = new FileReader("1.txt");
char[] buf = new char[1024];
int len = fr.read(buf);
String myStr = new String(buf,0,len);
System.out.println(myStr);*/
/*FileInputStream fr = new FileInputStream("1.txt");
byte[] buf = new byte[1024];
int len = fr.read(buf);
String myStr = new String(buf,0,len,"UTF-8");
System.out.println(myStr);*/
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("1.txt"),"UTF-8"
)
);
String myStr = br.readLine();
br.close();
System.out.println(myStr);
}
}
9八、 java 裏面的 io 跟 nio 有什麼區別
【參考答案】
一、Java NIO和IO之間第一個最大的區別是,IO是面向流的,NIO是面向緩衝區的。
二、Java IO的各類流是阻塞的。而Java NIO的非阻塞模式,使一個線程從某通道發送請求讀取數據,可是它僅能獲得目前可用的數據,若是目前沒有數據可用時,就什麼都不會獲取。而不是保持線程阻塞,因此直至數據變的能夠讀取以前,該線程能夠繼續作其餘的事情。
三、選擇器上,Java IO無選擇器,而NIO有選擇器,Java NIO的選擇器容許一個單獨的線程來監視多個輸入通道,你能夠註冊多個通道使用一個選擇器,而後使用一個單獨的線程來「選擇」通道:這些通道里已經有能夠處理的輸入,或者選擇已準備寫入的通道。
9九、 J ava 中會存在內存泄漏嗎,請簡單描述。
【參考答案】
所謂內存泄露就是指一個再也不被程序使用的對象或變量一直被佔據在內存中。java中有垃圾回收機制,它能夠保證一對象再也不被引用的時候,即對象變成了孤兒的時候,對象將自動被垃圾回收器從內存中清除掉。因爲Java使用有向圖的方式進行垃圾回收管理,能夠消除引用循環的問題,例若有兩個對象,相互引用,只要它們和根進程不可達的,那麼GC也是能夠回收它們的,例以下面的代碼能夠看到這種狀況的內存回收:
package com.huawei.interview;
import java.io.IOException;
public class GarbageTest {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
try {
gcTest();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("has exited gcTest!");
System.in.read();
System.in.read();
System.out.println("out begin gc!");
for(int i=0;i<100;i++)
{
System.gc();
System.in.read();
System.in.read();
}
}
private static void gcTest() throws IOException {
System.in.read();
System.in.read();
Person p1 = new Person();
System.in.read();
System.in.read();
Person p2 = new Person();
p1.setMate(p2);
p2.setMate(p1);
System.out.println("before exit gctest!");
System.in.read();
System.in.read();
System.gc();
System.out.println("exit gctest!");
}
private static class Person
{
byte[] data = new byte[20000000];
Person mate = null;
public void setMate(Person other)
{
mate = other;
}
}
}
java中的內存泄露的狀況:長生命週期的對象持有短生命週期對象的引用就極可能發生內存泄露,儘管短生命週期對象已經再也不須要,可是由於長生命週期對象持有它的引用而致使不能被回收,這就是java中內存泄露的發生場景,通俗地說,就是程序員可能建立了一個對象,之後一直再也不使用這個對象,這個對象卻一直被引用,即這個對象無用可是卻沒法被垃圾回收器回收的,這就是java中可能出現內存泄露的狀況,例如,緩存系統,咱們加載了一個對象放在緩存中(例如放在一個全局map對象中),而後一直再也不使用它,這個對象一直被緩存引用,但卻再也不被使用。
檢查java中的內存泄露,必定要讓程序將各類分支狀況都完整執行到程序結束,而後看某個對象是否被使用過,若是沒有,則才能斷定這個對象屬於內存泄露。
若是一個外部類的實例對象的方法返回了一個內部類的實例對象,這個內部類對象被長期引用了,即便那個外部類實例對象再也不被使用,但因爲內部類持久外部類的實例對象,這個外部類對象將不會被垃圾回收,這也會形成內存泄露。
[]是對象已不可到達,而內存又沒有回收,真正的內存黑洞。
而Java的泄漏,則是由於各類緣由,對象對應用已經無用,但一直被持有,一直可到達。
總結緣由無外乎幾方面:
1.被生命週期極長的集合類不當持有,號稱是Java內存泄漏的首因。
這些集合類的生命週期一般極長,並且是一個輔助管理性質的對象,在一個業務事務運行完後,若是沒有將某個業務對象主動的從中清除的話,這個集合就會吃愈來愈多內存,能夠用WeakReference,如WeakHashMap,使得它持有的對象不增長對象的引用數。
2.Scope定義不對,這個很簡單了,方法的局部變量定義成類的變量,類的靜態變量等。
3.異常時沒有加finally{}來釋放某些資源,JDBC時代也是很廣泛的事情。
4.另一些我瞭解不深的緣由,如:Swing裏的Listener沒有顯式remove;內部類持有外部對象的隱式引用;Finalizers形成關聯對象沒有被及時清空等。
內存泄漏的檢測
有很多工具輔助作這個事情的,若是手上一個工具也沒有,能夠用JDK自帶的小工具:
·看看誰佔滿了Heap?
用JDK6的jmap能夠顯示運行程序中對象的類型,個數與所佔的大小
先用jps找到進程號,而後jmap -histo pid顯示或jmap -dump:file=heap_file_name pid導出heap文件
·爲何這些對象仍然能夠到達?
用jhat(Java Heap Analysis Tool)分析剛纔導出的heap文件。
先jhat heap_file_name,而後打開瀏覽器http://localhost:7000/瀏覽。
100、 Hashcode 和 Equals 的聯繫
【參考答案】
首先equals()和hashcode()這兩個方法都是從object類中繼承過來的,主要用來比較對象時進行調用。在object類中定義以下:
a)、若是兩個對象相同,那麼它們的hashCode值必定要相同;
b)、若是兩個對象的hashCode相同,它們並不必定相同上面說的對象相同指的是用eqauls方法比較。
10一、 Tread 和 T hreadlocal 的做用及區別?
【參考答案】
答:threadlocal是線程局部變量(thread local variable),爲每個使用該線程的線程都提供一個變量值的副本,使每個線程均可以獨立地改變本身的副本,而不會和其餘線程的副本產生衝突。
10二、 TCP 和 UDP 的區別?
【參考答案】
TCP/IP的運輸層有兩個不一樣的協議:①用戶數據報協議UDP②傳輸控制協議TCP
兩者最大區別:TCP是面向鏈接的,而UDP是無鏈接的.區別大體以下:
1)UDP傳送的數據單位協議是UDP報文或用戶數據報,TCP傳送的數據單位協議是TCP報文段。
2)UDP發送數據以前不須要創建鏈接,所以減小了開銷和發送以前的時延。TCP提供面向鏈接的服務,不提供廣播或多播服務。
3)對方的運輸層在收到UDP報文後,不須要給出任何確認。TCP則須要確認。
4)UDP沒有擁塞控制,所以網絡出現的擁塞不會使源主機的發送速率下降,也不保證可靠交付,所以主機不須要維持具備許多參數的、複雜的鏈接狀態表。TCP要提供可靠的、面向鏈接的運輸服務,所以不可避免地增長了許多的開銷,這不只使協議數據單元的首部增大不少,還要佔用許多的處理機資源。
5)UDP用戶數據報只有8個字節的首部開銷,比TCP的20個字節的首部要短。
10三、 啓動一個線程用什麼方法?【北京永中軟件面試題】
【參考】
使用Thread類的start()方法來啓動一個線程,使線程進入就緒狀態。若是自定義的類是Thread類的子類的話,能夠直接使用Start()來啓,若是是實現的Runnable接口的話,還要將該類的實例做爲參數傳入到Thread對象中來啓動。
10四、 做用域 public 等寫不寫的區別?【北京永中軟件面試題】
【參考】
做用域不寫將採用默認的做用域,默認做用域的訪問權限是包的權限,也就是除本包中的全部類能訪問,不一樣包只有子類能訪問。
10五、 同步和異步有何異同
【參考答案】
同步(synchronized)和異步(asynchronized)是對於多線程(multi-threading)而言的
同步可防止併發主要出於數據安全的考慮
若是數據將在線程間共享。例如正在寫的數據之後可能被另外一個線程讀到,或者正在讀的數據可能已經被另外一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取。
異步容許併發
ajax技術一般都是異步實現的,異步主要使用在當應用程序在對象上調用了一個須要花費很長時間來執行的方法,而且不但願讓程序等待方法的返回時,就應該使用異步編程,在不少狀況下采用異步途徑每每更有效率。
10六、 Static 方法和 static 字段有什麼用處?能夠被重載嗎?
【參考答案】
用static修飾的方法叫類方法,被全部實例共享;static修飾的字段爲類變量,被全部實例共享,在使用類變量時,通常會結合final一塊兒使用定義類常量,不容許被其它的類實例修改。
能夠被重載,重載只是參數類型、順序和個數不一樣。