天天看點

Java面試題

面向對象程式設計(oop)

    java是一個支援并發、基于類和面向對象和計算機程式設計語言。如下是面向對象軟體開發的優點:

       1、代碼開發子產品化,更容易維護和修改。

       2、代碼複用。

       3、增強代碼的可靠性和靈活性。

       4、增加代碼的可了解性。

面向對象程式設計有很多重要的特性,比如:封裝,繼承,多态和抽象。

       1、封裝:

  1、封裝給對象提供了隐藏内部特性和行為的能力。對象提供一些能被其他對象通路的方法來改變它内部的資料。

  2、在java當中,有4種修飾符:public,private,default和protected。

  3、每一種修飾符給其他的位于同一個包或者不用包下面對象賦予了不同的通路權限。

  4、其中private的作用範圍限定于目前類中;

  5、default是預設的通路修飾符,作用範圍是同一個包中;

  6、protected的作用範圍不包括其他的包,在同一包,目前類和其子類中均能使用;

  7、public是公開的,在目前工程中均可以使用。

      封裝的一些優點:

 1、通過隐藏對象的屬性來保護對象内部的狀态;

 2、提高了代碼的可用性和可維護行,因為對象的行為可以被單獨的改變或者是擴充。

 3、禁止對象之間的不良互動提高子產品化。

       2、多态:

  1、多态是程式設計語言給不同的底層資料類型做相同的接口展示的一種能力。

  2、一個多态類型上的操作可以應用到其他類型的值上面。

       3、繼承:

  1、繼承給對象提供從基類擷取字段的方法和能力。

  2、繼承提供類代碼的重用行,也可以在不修改類的情況下給現存的類添加新特性

       4、抽象:

  1、抽象是把想發從具體的執行個體中分離出來的步驟,是以,要根據他們的功能而不是實作細節類常見類。

  2、java支援建立隻暴露接口而不包含方法實作的抽象的類,

  3、這種抽象技術的主要目的是把類的行為和實作細節分離開。

       抽象個封裝的不同點:

  1、抽象個封裝是互補的概念,一方面,抽象關注對象的行為。另一方面,封裝關注對象行為的細節。

  2、一般是通過隐藏對象内部狀态資訊做到瘋轉,是以,封裝可以看成是用來提供抽象的一種政策。

常見的java問題:

    1、什麼是java虛拟機?為什麼java被稱作是“平台無關的程式設計語言”?

       1、java虛拟機是一個可執行java位元組碼的虛拟機程序。java源檔案被編譯成能被java虛拟機執行的位元組碼檔案。

       2、java被設計成允許應用程式可以運作在任意的平台,而不需要程式員為每一個平台單獨重寫或者重新編譯。

       3、java虛拟機讓這個變為可能,因為它知道底層硬體平台的指令長度和其他特性。

    2、jdk和jre的差別是什麼?

       1、java運作時環境(jre)是将要執行的java程式的java虛拟機。它同時也包含了執行applet需要的浏覽器插件。

       2、java開發工具包(jdk)是完整的java軟體開發包,包含了jre,編譯器和其他的工具(比如:javadoc,java調試器),

可以讓開發者開發、編譯、執行java應用程式。

    3、“static”關鍵字是什麼意思?java中是否可以覆寫(override)一個private或者是static的方法?

       “static”關鍵字表明一個成員變量或者成員方法可以在沒有所屬的類的執行個體變量的情況下被通路。java中static方法不能被覆寫,

        因為方法覆寫是基于運作時動态綁定的,而static方法是編譯時靜态綁定的。static方法跟類的任何執行個體都不相關,是以概念上不适用。

    4、是否可以在static環境中通路非static變量?

        static變量在java中是屬于類的,它在所有的執行個體中的值是一樣的。

        當類被java虛拟機載入的時候,會對static變量進行初始化。如果你的代碼嘗試不用執行個體來通路非static的變量,

編譯器會報錯,因為這些變量還沒有被建立出來,還沒有跟任何執行個體關聯上。

    5、java支援的資料類型有哪些?什麼是自動拆裝箱?

java語言支援的8種基本資料類型是:

  byte byte

short short

int integer

long long

float float

double double

boolean boolean

char character

自動裝箱是java編譯器在基本資料類型和對應的包裝類型之間做一個轉化,比如:把int轉化成integer等等。反之就是自動拆箱。

    6、java中的方法覆寫(override)和方法重載(overloading)是什麼意思?

       java中的方法重載發生在同一個類裡面兩個或者多喝方法的方法名相同凡是參數不同的情況。與此相對,方法覆寫是說子類重新定義了父類的方法。

       方法覆寫必須有相同的方法名,參數清單和傳回類型。覆寫者可能不會限制它所覆寫的方法的通路。

    7、java中,什麼是構造函數?什麼是構造函數重載?什麼是複制構造函數?

當新對象被建立的時候,構造函數會被調用。每一個類都有構造函數。

在程式員沒有給類提供構造函數的情況下,java編譯器會為這個類建立一個預設的構造函數。

java中構造函數重載和方法重載很相似。可以為一個類建立多個構造函數。每一個構造函數必須有它自己唯一的參數清單。

java不支援像c++中那樣的複制構造函數,這個不同點是因為如果你不自己寫構造函數的情況下,java不會建立預設的複制構造函數。

    8、java支援多繼承麼?

不支援,java不支援多繼承。每個類隻能繼承一個類,但是可以實作多個接口。

    9、接口和抽象類的差別是什麼?

1、java提供和支援建立抽象類和接口。它們的實作有共同點,不同點在于:

2、接口中所有的方法隐含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法。

3、類可以實作很多個接口,但是隻能繼續一個抽象類

4、類如果要實作一個接口,它必須要實作接口聲明的所有方法。但是,類可以不是想抽象類聲明的所有方法,當然,在這種情況下,類也必須得聲明成抽象的。

5、抽象類可以在不提供接口方法實作的情況下實作接口。

6、java接口中聲明的變量預設都是final的。抽象類可以包含非final的變量。

7、java接口中的成員函數預設是public的。抽象類的成員函數可以是其他修飾符修飾的。

8、接口是絕對抽象的,不可以被執行個體化。抽象類也不可以被執行個體化,但是,如果它包含main方法的話是可以被調用的。

    10、什麼是值傳遞和引用傳遞?

對象被值傳遞,意味着傳遞了對象的一個副本。是以,就算是改變了對象副本,也不會影響源對象的值。

對象被引用傳遞,意味着傳遞的并不是實際的對象,而是對象的引用。是以,外部對引用對象所做的改變會反映到所有的對象上。

    11、string是最基本的類型嗎?

不是。java中的基本資料類型隻有8個:byte、short、int、long、float、double、char、boolean;

除了基本類型,剩下的都是引用類型,java 5以後引入的枚舉類型也算是一種比較特殊的引用資料類型。

    12、float  f = 3.4;是否正确?

不正确。3.4是雙精度數,将雙精度型(double)指派給浮點型(float)屬于下轉型,會造成精度損失,是以需要強制類型轉換float = (float)3.4或者寫成 float f = 3.4f.。

    13、short s1 = 1 ; s1 = s1 + 1;有錯嗎?short s1 = 1 ; s1+=1;有錯嗎?

對于short s1 = 1; s1 = s1 + 1;由于1是int類型,是以s1 + 1運算結果也是int型,需要強制類型轉換才能指派給short型。

        而short s1 = 1 ; s1+=1;可以正确編譯,因為s1+=1; 相當于s1 = (short)(s1 + 1);其中隐含的強制類型轉換。

    14、java有沒有goto?

goto是java中的保留字,在目前版本的java中沒有使用。除了goto之外,const也是java中的保留字,目前均沒有使用。

    15、&和&&的差別

&運算符有兩種用法:(1)、按位與:(2)、邏輯與。&& 運算符是短路與運算。

    16、解釋記憶體中的棧(stack)、堆(heap)和方法區(method area)的用法。

        通常我們定義一個基本資料類型的變量,一個對象的引用,還有就是函數調用的現場儲存都是用jvm中的棧空間;而通過new關鍵字和構造器建立的對象則放在堆空間,堆是垃圾收集器管理的主要區域,由于現在的垃圾收集器都采用分代收集算法,是以堆空間還可以細分為新生代和老生代,再具體一點可以分為eden、survivor、tenured;方法區和堆都是各個線程共享的記憶體區域,用于存儲已經被jvm加載的類資訊、常量、靜态變量、jit編譯器編譯後的代碼等資料;程式中的字面量(literal)如果直接書寫100  hello 和常量都是放在常量池中,常量池是方法區的一部分。棧空間操作起來最快但是棧很小,通常大量的對象都放在堆空間,棧和堆的大小都可以通過jvm的啟動參數來進行調整,棧空間用光了會引發stactoverflowerror,而對和常量池空間不足則會引發outofmemoryerror。

    17、數組有沒有length()方法?string有沒有length()方法?

        數組中沒有length()方法,有length的屬性。string有length()方法。javascript中,獲得字元的長度是通過length屬性得到的,這一點很容易與java混淆。

    18、在java中,如何跳出目前的多重嵌套循環?

        在最外層循環前加一個标記a,然後用break a;可以跳出多重循環。cuntinue是跳出目前循環。

    19、構造器(constructor)是否可以被重寫(override)?

        構造器不能被繼承,是以不能被重寫,但可以被重載。

    20、string和stringbuilder、stringbuffer的差別?

        java平台提供了兩種類型的字元串:string和stringbuffer/stringbuilder,它們可以儲存和操作字元串。其中string是隻讀字元串,也就意味着string引用的字元串内容是不能被改變的。而stringbuffer/stringbuilder類表示的字元串對象是可以直接進行修改。stringbuiler是java 5中引入的,它和stringbuffer的方法完全相同,差別在于它是在單線程環境下使用的,因為它的所有的方法都沒有被sychronized修飾,是以它的效率要比stringbuffer要高。

   21、程序和線程的差別是什麼?

       程序是執行着的應用程式,而線程是程序内部的一個執行序列。

       一個程序可以有多個線程。線程又叫做輕量級程序。

   22、建立線程有幾種不同的方式?

       有三種方式可以用來建立線程:

   1、繼承thread類

   2、實作runnable接口

   3、應用程式可以使用executor架構來建立線程池

       實作runnable接口這種方式更受歡迎,因為這不需要繼承thread類。

       在應用設計中已經繼承了别的對象的情況下,還需要多繼承(而java不支援多繼承),

       隻能實作接口。同時,線程池也是非常高效的,很容易實作和使用。

   23、概括的解釋下線程的幾種可用狀态。

       線程在執行過程中,可以處于下面幾種狀态:

   就緒(eunnable):線程準備運作,不一定立馬就能開始執行。

   運作中(running):程序正在執行線程的代碼。

   等待中(waiting):線程處于阻塞的狀态,等待外部的處理結束。

   睡眠中(sleeping):線程被強制睡眠。

   i/o阻塞(blocked on i/o):等待i/o操作完成。

   同步阻塞(blocked on sychronization):等待擷取鎖。

   死亡(dead):線程完成了執行。

   24、同步方法和同步代碼塊的差別是什麼?

       在java語言中,每一個對象有一把鎖。線程可以使用sychronized關鍵字來擷取對象上的鎖。

       sychronized關鍵字可應用在方法級别(粗粒度鎖)或者是代碼塊級别(細粒度鎖)。

   25、在螢幕(monitor)内部,是如何做線程同步的?程式應該做哪種級别的同步?

       螢幕和鎖在java虛拟機中是一塊使用的。螢幕件事一塊同步代碼塊,確定一次隻

       有一個線程執行同步代碼塊。每一個螢幕都和一個對象引用相關聯。

       線程在擷取鎖之前不允許執行同步代碼。

   26、什麼是死鎖(deadlock)

       兩個程序都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。

       結果就是兩個程序都陷入了無限的等待中。

   27、如何確定n個線程可以通路n個資源同時又不導緻死鎖?

       使用多線程的時候,一種非常簡單的避免死鎖的方式就是:指定擷取鎖的順序,

       并強制線程按照指定的順序擷取鎖。是以,如果所有的線程都是以同樣的順序加鎖和釋放鎖,

       就不會出現死鎖了。

   28、thread類中的start()和run()方法有什麼差別?

       start()方法被用來啟動新建立的線程,而且start()内部調用了run()方法,

       這和直接調用run()方法的效果不一樣。當你調用run()方法的時候,隻會是

       在原來的線程中調用,沒有新的線程啟動,start()方法才會啟動新線程。

   29、java中runnable和callable有什麼不同?

       runnable和callable都代表那些要在不同的線程中執行的任務。runnable從jdk1.0開始就有了,

       callable是在jdk1.5增加的。它們的主要差別是callable的call()方法可以傳回值和抛出異常,

       而runnable的run()方法沒有這些功能。callable可以放回裝載有計算結果的future對象。

   30、java中cyclicbarrier和countdownlatch有什麼不同?

       cylicbarrier和countdownlatch都可以用來讓一組線程等待其它線程。與cyclicbarrier不同的是,

       countdownlatch不能重新使用。

   31、java記憶體模型是什麼?

       java記憶體模型規定和指引java程式在不同的記憶體架構、cpu和作業系統間有确定性得行為。它在多線

       程的情況下尤其重要。java記憶體模型對一個線程所做的變動能被其它線程可見提供了保證,它們之間

       是先行發生關系。這個關系定義了一些規則讓程式員在并發程式設計時思路更清晰。比如,先行發生關系

       確定了:

   1、線程内的代碼能夠按先後順序執行,這被稱為程式次序規則。

   2、對于同一個鎖,一個解鎖操作一定要發生在時間上後發生的另一個鎖定操作之前,也叫做管程鎖定規則

   3、前一個對volatile的寫操作在後一個volatile的讀操作之前,也叫volatile變量規則。

   4、一個線程内的任何操作必需在這個線程的start()調用之後,也叫做線程啟動規則。

   5、一個線程内的任何操作都會線上程終止之前,線程終止規則。

   6、一個對象的終結操作必需在這個對象構造完成之後,也叫對象終結規則。

   7、可傳遞性

   32、java中的volatile變量是什麼?

       volatile是一個特殊的修飾符,隻有成員變量才能使用它。在java并發程式缺少同步類的情況下,

       多線程對成員變量的操作對其它線程是透明的。volatile變量可以保證下一個讀取操作會在前一個寫

       操作之後發生,就是上一題的volatile變量規則。

   33、什麼是線程安全?vector是一個線程安全類嗎?

       如果你的代碼所在的程序中有多個線程在同時運作,而這些線程可能會同時運作這段代碼。如果每次

       運作結果和單線程運作的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。

       一個線程安全的計數器類的同一個石磊對象再被多個線程使用的情況下也不會出現計算失誤。很顯然

       你可以将集合類分成兩組,線程安全和非線程安全的。vector是用同步方法來實作線程安全的,

       而和它想相似的arraylist不是線程安全的。

   34、java中什麼是競态條件?舉個例子說明

       競态條件會導緻程式在并發情況下出現一個bugs。多線程對一些資源的額競争的時候就會産生競态條

       件,如果首先要執行的程式競争失敗排到後面執行了,那麼整個程式就會出現一些不确定的bugs。

       這種hugs很難發現而且會重複出現,因為線程間的随機競争,一個例子就是無序處理。

   35、java中如何停止一個線程?

       java提供了很豐富的api但沒有為停止線程提供api。jdk 1.0本來有一些像stop(),susoend()和

       resume()的控制方法,但是由于潛在的死鎖威脅是以在後續的jdk版本中他們被棄用了,

       之後java api的設計者就沒有提供一個相容切線程安全的方法來停止一個線程。當run()或者call()

       方法執行完的時候線程會自動結束,如果要手動結束一個線程,你可以用volatile布爾變量來

       退出run()方法的循環或者是取消任務來中斷線程。

   36、一個線程運作時發生異常會怎樣?

       簡單的說,如果異常沒有被捕獲該線程将會停止執行。thread.uncaughtexceptionhandler是用于處理

       未捕獲異常造成線程突然中斷情況的一個内嵌接口。方一個為捕獲異常将造成線程中斷的時候jvm會使用

       thread.getuncaughtexceptionhandler()來查詢線程的uncaughtexceptionhandler并将線程和異常作為參數

       傳遞給handler的uncaughtexception()方法進行處理。

   37、如何在兩個線程間共享資料?

       你可以通過共享對象來實作這個目的,或者是使用像阻塞隊列這樣并發的資料結構。

   38、java中notify和notifyall有什麼差別?

       因為多線程可以等待單監控鎖,java api 的設計人員提供了一些方法當等待條件改的時候通知它們,

       但是這些方法沒有完全實作。notify()不能喚醒某個具體的線程,是以隻有一個線程在等待的時候它

       才有用武之地。而notifyall()喚醒所有線程并允許他們争奪鎖確定至少有一個線程能繼續運作。

   39、為什麼wait,notify和notifyall這個方法不在thread類裡面?

       java提供的鎖是對象及的而不是線程級的,每個對象都有鎖,通過線程獲得。如果線程需要等待某些

       鎖那麼調用對象中的wait()方法就沒有意義了。如果wait()方法定義在thread類中,線程正在等待某

       些鎖那麼調用對象中的wait()方法就有意義了。如果wait()方法定義在thread類中,線程正在等待的

       是哪個鎖就不明顯了。簡單的說,由于wait,notify和notifyall都是鎖級别的操作,是以他們定義

       在object類中因為鎖屬于對象。

   40、什麼是threadlocal變量?

       threadlocal變量是java裡一種特殊的變量。每個線程都有一個threadlocal就是每個線程都擁有了自己

       獨立的一個變量,競争條件被徹底消除了。它是為建立代價高昂的對象擷取線程安全的好方法,比如你

       可以用threadlocal讓simpledatedormat變成線程安全的,因為那個類建立代價高昂且每次調用都需要

       建立不同的執行個體是以不值得在局部範圍使用它,如果為每個線程提供一個自己獨有的變量拷貝,将大大

       提高效率。首先,通過複用減少了代價高昂的對象的建立個數。其次,你在沒有使用高代價的同步或者

       不變性的情況下獲得了線程安全。線程局部變量的另一個不錯的例子是threadlocalrandom類,它在

       多線程環境中減少了建立高昂的random對象的個數。

   41、什麼是futuretask?

       在java并發程式中funturetask表示一個可以取消的異步運算。它有啟動和取消運算、查詢運算是否完成

       和取回運算結果等方法。隻有當運算完成的時候結果才能取回,如果運算尚未完成get方法将會阻塞。一個

       funturetask對象可以對調用了callable和runnable的對象進行包裝,由于funturetask也是調用了runnable

       接口是以它可以送出給excutor來執行。

   42、java中interrupted和isinterrupted方法的差別?

       interrupted()和isinterrupted()的主要差別是前者會将中斷狀态清除而後者不會。java多線程的中斷

       機制是内部辨別來實作的,調用thread.interrupt()來中斷一個線程就會設定中斷辨別為true。

   43、為什麼wait和notify方法要在同步塊中調用?

       主要是因為java api 強制要求這麼做,如果你不這麼做,你的代碼會抛出illegalmonitorstateexception

       異常,還有一個原因是為了避免wait和notify之間産生競态條件。

   44、為什麼你應該在循環中檢查等待條件?

       處于等待狀态的線程可能會收到錯誤警報和僞喚醒,如果不在循環中檢查等待條件,程式就會在沒有

       滿足結束條件的情況下退出。是以,當一個等待線程醒來是,不能認為它原來的等待狀态仍然是有效

       的,在notify()方法調用之後和等待線程醒來之前這段時間可能會改變。這就是在循環中使用wait()

       方法效果更好的原因。

   45、java中的同步集合與并發集合有什麼差別?

       同步集合與并發集合都為多線程和并發提供了合适的線程安全的集合,不過并發集合的可擴充性更

       高。在java 1.5之前程式員們隻有同步集合來用且在多線程并發的時候會導緻争用,阻礙了系統的

       擴充性。java 5介紹了并發集合像concurrenthashmap,不僅提供線程安全還用鎖分離和内部分區等

       現在技術提高了可擴充性。

   46、java中堆和棧有什麼不同?

       棧是一塊和線程緊密相關的記憶體區域,每個線程都有自己的棧記憶體,用于存儲本地變量,方法參數

       和棧調用,一個線程中存儲的變量對其它線程是不可見的。而堆是所有線程共享的一片公用區域内

       存。對象都在堆裡建立,為了提升效率線程會從堆中弄一個緩存到自己的棧,如果多個線程使用該

       變量就可能引發問題,這是volatile變量就可以發揮作用了,它要求線程從主存中讀取變量的值。

   47、什麼是線程池?為什麼要使用它?

       建立線程要花費昂貴的資源和時間,如果任務來了才建立線程,那麼響應的時間會變長,影響到用

       戶體驗,而且一個程序能建立的線程數有限。為了避免這些問題,在程式啟動的時候就建立若幹個

       線程來響應處理,它們被稱為線程池。裡面的線程叫工作線程。從jdk 1.5開始,java api提供了

       executor架構讓你可以建立不同的線程池。比如單線程池,每處理一個任務;數目固定的線程池或者

       是緩存線程池(一個适合很多生存期短的任務的程式的可擴充線程池)。

   48、如何寫代碼來解決生産者消費者問題?

       在現實中你解決的許多線程問題都屬于生産者消費者模型,就是一個線程生産任務供其它線程進行

       消費,你必須知道怎麼進行線程間通信來解決這個問題。比較低級的辦法是用wait和notifyall來解

       決這個問題,比較贊的辦法是用semaphore或者blockingqueue來實作生産者消費者模型。

   49、如何避免死鎖?

       java多線程中的死鎖

       死鎖是指兩個或兩個以上的程序在執行過程中,因争奪資源而造成的一種互相等待的現象,若無外力

       作用,它們都将無法推進下去。這是一個嚴重的問題,因為死鎖會讓你的程式挂起無法完成任務,

       死鎖的發生必須滿足以下四個條件:

       互斥條件:一個資源每次隻能被一個程序使用。

       請求與保持條件:一個程序因請求資源而阻塞時,對已獲得的資源保持不放。

       不剝奪條件:程序已獲得的資源,在末使用完之前,不能強行剝奪。

       循環等待條件:若幹程序之間形成一種頭尾相接的循環等待資源關系。

       避免死鎖的最簡單方法就是阻止循環等待條件,将系統中所有的資源設定标志位、排序,規定所有的

       程序申請資源必須以一定的順序(升序或者降序)做操作來避免死鎖。

   50、java中活鎖和死鎖有什麼差別?

       活鎖和死鎖類似,不同之處在于處于活鎖的線程或程序的狀态是不斷改變的,活鎖可以認為是一種

       特殊的饑餓。一個現實的活鎖例子是兩個人在狹小的走廊碰到,兩個人都試着避讓對方好讓彼此通

       過,但是因為避讓的方向都一樣導緻最後誰都不能通過走廊。簡單的說就是,活鎖和死鎖的主要區

       别是前者程序的狀态可以改變但是卻不能繼續執行。

   51、怎麼檢測一個線程是否擁有鎖?

       在java.lang.thread中有一個方法叫holdslock(),它傳回true如果當且晉檔目前線程擁有某個具體

       對象鎖。

   52、你如何在java中擷取線程堆棧?

       對于不同的作業系統,有多種方法來獲得java程序的線程堆棧。當你擷取線程堆棧是,jvm會把所有

       線程的狀态存到日志檔案或者輸出到控制台。在windows你可以使用ctrl+break組合鍵來擷取線程

       堆棧,linux下用kill -3指令。你也可以用jstack這個工具來擷取,它對線程id進行操作,你可以用

       jps這個工具找到id。

   54、jvm中哪個參數是用來控制線程的棧堆大小的?

       -xss參數使用用來控制線程的堆棧大小的。

   55、java中sychronized和reentrantlock有什麼不同?

       java在過去很長一段時間隻能通過suchronized關鍵字來實作互斥,它有一些缺點。比如你不能擴充

       鎖之外的方法或者塊邊界,嘗試擷取鎖時不能中途取消等。java 5通過lock接口提供了更複雜的控制

       來解決這些問題。reentrantlock類實作了lock,他擁有與sychronized相同的并發性和記憶體語意且它

       還具有可擴充性。

   56、如果有三個線程t1,t2,t3,怎麼確定它們按順序執行?

       在多線程中有多種方法讓線程安特定的順序執行,你可以用線程類的join()方法在一個線程中啟動

       另一個線程,另外一個線程完成該線程繼續執行。為了確定三個線程的順序你應該先啟動最後一個

      (t3調用t2,t2掉用t1),這樣t1就會先完成而t3最後完成。

   57、thread類中的yield方法有什麼作用?

       yield方法可以暫停目前正在執行的線程對象,讓其它有相同優先級的線程執行。他是一個靜态方法

       而且隻保證目前線程放棄cpu占用而不能保證使其它線程一定能占用cpu,執行yield()的線程有可能

       在進入暫停狀态後馬上又被執行。

   58、java中concurrenthashmap的并發度是什麼?

       conrurrenthashmap把實際map劃分成若幹部分來實作它的可擴充性和線程安全。這種劃分是使用

       并發度獲得的,它是concurrenthashmap類構造函數的一個可選參數,預設值為16,這樣在多線程

       的情況下就能避免争用。

   59、java中semaphore是什麼?

       java中的semaphore是一種新的同步類,它是一個計數信号。從概念上講,從概念上講,信号量維  

       護了一個許可集合。如有必要,在許可可用前會阻塞每一個 acquire(),然後再擷取該許可。每

       個 release()添加一個許可,進而可能釋放一個正在阻塞的擷取者。但是,不使用實際的許可對象,

       semaphore隻對可用許可的号碼進行計數,并采取相應的行動。信号量常常用于多線程的代碼中,

       比如資料庫連接配接池。

   60、如果你送出任務是,線程池隊列已滿,會發生什麼?

       抛出一個rejectedexecutionexception異常。

   61、java線程池中submit()和execute()方法有什麼差別?

       兩個方法都可以向線程池送出任務,execute()方法的傳回值類型是void,它定義在executor接口中,而

       submit()方法可以傳回持有計算結果的future對象,它定義在executorservice接口中,它擴充

       了executor接口。

   62、什麼是阻塞式方法?

       阻塞式方法是指程式會一直等待該方法完成期間不做其它事情,serversocket的accept()方法就是一直

       等待用戶端連接配接。這裡的阻塞是指調用結果傳回之前,目前線程會被挂起,直到得到結果之後才傳回。

       此外,還有異步和非阻塞方法在任務完成之前就能傳回。

   63、如何在java中建立immutable對象?

       immutable可以在沒有同步的情況下共享,降低了對該對象進行并發通路時的同步化開銷。可是java沒有

       @immutable這個注解符,要建立不可變類,要實作下面幾個步驟:通過構造方法初始化所有成員、對變量

       不要提供setter方法、将所有成員聲明為私有的,這樣就不允許直接通路這些成員、在getter方法中,

       不要直接傳回對象本身,而是克隆對象,并傳回對象的拷貝。

   64、java多線程中調用wait() 和 sleep()方法有什麼不同?

       java程式中wait 和 sleep都會造成某種形式的暫停,它們可以滿足不同的需要。wait()方法用于線程

       間通信,如果等待條件為真且其它線程被喚醒時它會釋放鎖,而sleep()方法僅僅釋放cpu資源或者讓

       目前線程停止執行一段時間,但不會釋放鎖。

   65、如何強制啟動一個線程?

       這個問題就像是如何強制進行java垃圾回收,目前還沒有覺得方法,雖然你可以使用system.gc()來

       進行垃圾回收,但是不保證能成功。在java裡面沒有辦法強制啟動一個線程,它是被線程排程器控制

       着且java沒有公布相關的api。

   66、java集合類架構的基本接口有哪些?

       java集合類提供了一套設計良好的支援對一組對象進行操作的接口和類。java集合裡面最基本的接口有:

       1、collection:代表一組對象,每一個對象都是它的子元素。

       2、set:不包含重複元素的collection。

       3、list:有順序的collection,并且可以包含重複元素。

       4、map:可以把鍵(key)映射到值(value)的對象,鍵不能重複。

   67、為什麼集合類沒有實作cloneable和serializable接口?

       集合類接口指定了一組叫做元素的對象。集合類接口類的每一種具體的實作類都可以選擇以它自己的方

       式對元素進行保護和排序。有的集合類允許重複的鍵,有些不允許。

   68、什麼是疊代器(iterator)?

       iterator接口提供了很多對集合元素進行疊代的方法。每一個集合元素都包含了可以傳回疊代器執行個體的

       疊代方法。疊代器可以在疊代的過程中删除底層集合的元素。

       克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實作相關的。是以,應該由集合

       類的具體實作來決定如何被克隆或者序列化。

   69、iterator和listiterator的差別是什麼?

       主要差別如下:

       1、iterator可用來周遊set和list集合,但是listiterator隻能用來周遊list。

       2、iterator對集合隻能是前向周遊,listiterator既可以前向也可以後向。

       3、listiterator實作了iterator接口,并包含其他的功能,比如增加元素,替換元素,

          擷取前一個和後一個元素的索引等。

   70、快速失敗(fai-fast)和安全失敗(fail-safe)的差別是什麼?

       iterator的安全失敗是基于對底層集合做拷貝,是以它不受源集合上修改的影響。java.util

       包下面的所有的集合類都是快速失敗的,而java.util.concurrent包下面的所有的類都是

       安全失敗的。快速失敗的疊代器會抛出concurrentmodificationexception異常,而安全失敗

       的疊代器永遠不會抛出這樣的異常。

   71、java中的hashmap的工作原理是什麼?

       java中的hashmap是以鍵值對(key-value)的形式存儲元素的。hashmap需要一個hash函數,它使

       用hashcode()和equals()方法來向集合/從集合添加和檢索元素。當調用put()方法的時候,

       hashmap會計算key的hash值,然後把鍵值對存儲在集合中合适的索引上。如果key已經存在了,

       value會被更新成新值。hashmap的一些重要的特性是它的容量(capacity),負載因子(loadfactor)

       和擴容極限(threshold resizing)。

   72、hashcode()和equals()方法的重要性展現在什麼地方?

       java中的hashmap使用hsahcode()和equals()方法來确定鍵值對的索引,當根據鍵擷取值的時候也會

       用到這兩個方法。如果沒有正确的實作這兩個方法,兩個不同的鍵可能會有相同的hash值,是以,

       可能會被集合認為是相等的。而且,這兩個方法也用來發現重複元素。是以這兩個方法的實作對

       hashmap的精确性和正确性是至關重要的。

   73、hashmap和hashtable有什麼差別?

       hashmap和hashtable都實作了map接口,是以很多特性都非常相似。但是他們也有不同的:

       1、hashmap允許鍵和值是null,而hashtable不允許鍵或者值都是null。

       2、hashtable是同步的,而hashmap不是。是以,hashmap更适合單線程環境,而hashtable适合

         多線程環境。

       3、hashmap提供了可供應用疊代的鍵的集合,是以,hashmap是快速失敗的。另一方面,hashtable

          提供了對鍵的枚舉(enumeration)。

       一般認為hashtable是一個遺留的類。

   74、數組(array)和清單(arraylist)有什麼差別?什麼時候應該使用array而不是arraylist?

       不同點:

       1、array可以包含基本類型和對象類型,arraylist隻能包含對象類型。

       2、arraylist提供了更多的方法和特性,比如:addall(),removeall(),iterator()等等。

       3、array大小是固定的,arraylist的大小是動态變化的。

       4、對于基本類型資料,集合使用自動自動裝箱來減少編碼工作量。但是,當處理固定大小的

          基本資料類型的時候,這種方式相對比較慢。

   75、arraylist和linkedlist有什麼差別?

       arraylist與linkedlist都實作了list接口,他們有以下的不同點:

       1、arraylist是基于索引的資料接口,它的底層是hi數組。他可以以o(1)時間複雜度對元素

          進行随機通路。與此對應,linkedlist是以元素清單的形式存儲他的資料,每一個元素都和

          它的前一個和後一個元素連結在一起,在這種情況下,查找某個元素的時間複雜度是o(n)

       2、相對于arraylist,linkedlist的插入,添加,删除操作速度更快,因為元素被添加到集合

          任意位置的時候,不需要想數組那樣重新計算大小或者是更新索引。

       3、linkedlist比arraylist更占記憶體,因為linkedlist為每一個位元組存儲了兩個引用,一個指向前

          一個元素,一個指向下一個元素。

   76、comparable和comparator接口是幹什麼的?列出它們的差別。

       java提供了隻包含一個compareto()方法的comparable接口。這個方法可以給兩個對象排序。具體

       來說,他傳回負數,0,正數來表明輸入對象小于,等于,大于已經存在的對象。

       java提供了包含compare()和equals兩個方法的comparator接口。compare()方法用來給輸入參數排序,

       傳回負數,0,正數表明第一個參數是小于,等于,大于第二個參數。equals()方法需要一個對象作

       為參數,它用來決定輸入參數是否和comparator相等。隻有當輸入參數也是一個comparator并且輸入

       參數和目前comparator的排序結果是相同的時候,這個方法才傳回true。

   77、什麼是java優先級隊列(priority queue)?

       priorityqueue是一個基于優先級堆的無界隊列,它的元素是按照自然順序(natural order)排序的。

       在建立的時候,我們可以給它提供一個負責給元素排序的比較器。priorityqueue不允許null值,因

       為他們沒有自然順序,或者說他們沒有任何的相關聯的比較器。最後,priorityqueue不是線程安全

       的,入隊和出隊的時間複雜度是o(log(n))。

   78、java集合類架構的最佳實踐有哪些?

       1、根據應用的需要正确選擇要使用的集合類型對性能非常重要,比如:加入元素的大小是固定的,

          而且能事先知道,我們就應該用array而不是arraylist。

       2、有些集合類允許指定初始容量。是以,如果我們能估計出存儲的元素數目,我們可以設定初始化

          來避免重新計算容量hash值或者擴容。

       3、為了類型安全,可讀性和健壯性的原因總是要使用泛型。同時,使用泛型還可以避免運作時的

          classcastexception。

       4、使用jdk提供的不變類(immutable class)作為map的鍵可以避免為我們自己的類實作hashcode()

          和equals()方法。

       5、程式設計的時候接口要優于實作。

       6、底層的集合實際上是空的情況下,傳回長度是0的集合或者是數組,不要傳回null。

   79、enumeration接口和iterator接口的差別有哪些?

       enumeration速度是iterator的2倍,同時占用更少的記憶體。但是,iterator遠遠比enumeration安全,

       因為其他線程不能夠修改正在被iterator周遊的集合裡面的對象。同時,iterator允許調用者删除

       底層集合裡面的元素,這對enumeration來說是不可能的。

   80、hashset和treeset有什麼差別?

       hashset是由一個hash表來實作的,是以,它的元素是無序的。add(),remove(),contains()方法的時間

       複雜度是o(1).

       另一方面,treeset是由一個樹形的結構來實作的,它裡面的元素是有序的。是以,add(),remove()

       contains()方法的時間複雜度是o(logn)。

   81、java中兩種異常類型是什麼?它們有什麼差別?

       java中有兩種異常:受檢查(checked)異常和不受檢查(unchecked)異常。不受檢查的異常不需

       要在方法或者是構造函數上聲明,就算方法或者是構造函數的執行可能會抛出這樣的異常,并

       且不受檢查的異常可以傳播到方法或者是構造函數的外面。相反,受檢查的異常必須要用throws

       語句在方法或者是構造函數上聲明。

   82、java中exception和error有什麼差別?

       exception和error都是throwable的子類。exception用于使用者程式可以捕獲異常的情況。error定義

       了不期望被使用者程式捕獲的異常。

   83、throw和throws有什麼差別?

       throw關鍵字用來在程式中明确的抛出異常,相反,throws語句用來表明方法不能處理的異常。每一

       個方法都必須要指定哪些異常不能處理,是以方法的調用者才能夠確定處理可能發生的異常,多個異

       常是用逗号分隔的。

   84、異常處理的時候,finally代碼塊的重要性是什麼?

       無論是否抛出異常,finally代碼塊總是會被執行。就算是沒有catch語句同時又抛出異常的情況下,

       finally代碼塊任然會被執行。最後要說的是,finally代碼塊主要用來釋放資源,比如:i/o緩沖區,

       資料庫連接配接。。。

   85、異常處理完成以後,exception對象會發生什麼變化?

       exception對象會在下一個垃圾回收過程中被回收掉。

   86、finally代碼塊與finalize()方法有什麼差別?

       無論是否抛出異常,finallly代碼塊都會執行,他主要是用來釋放應用占用的資源。finalize()方法是

       object類的一個protected方法,它是在對象被垃圾回收之前由java虛拟機來調用的。

   87、什麼是jdbc?

       jdbc是允許使用者在不同資料庫之間做選擇的一個抽象層。jdbc允許開發者用java寫資料庫應用程式,

       而不需要關系底層特定資料庫的細節。

   88、解釋下驅動(driver)在jdbc中的角色。

       jdbc驅動提供了特定廠商對jdbc api接口類的實作,驅動必須要提供java.sql包下面的這些類的實作:

       connection,statement,oreparedstatement,callablestatement,resultset和driver。

   89、class.forname()方法有什麼作用?

       這個方法用來載入跟資料庫建立連接配接的驅動。

   90、preparedstatement比statement有什麼優勢?

       preparedstatement是預編譯的,是以,性能會更好。同時,不同的查詢參數值,

       preparedstatement可以重用。

   91、什麼時候使用callablestatement?用來準備callablestatement的方法是什麼?

       callablestatement用來執行存儲過程。存儲過程是由資料庫存儲和提供的。存儲

       過程可以接受輸入參數,也可以有傳回結果。非常鼓勵使用存儲過程,因為它提供

       了安全性和子產品化。準備一個callablestatement的方法是:

       callablestatement.preparecall();

   92、資料庫連接配接池是什麼意思?

       像打開關閉資料庫連接配接這種和資料庫的互動可能是很費時的,尤其是當用戶端數量

       增加的時候,會消耗大量的資源,成本是非常高的。可以在應用伺服器啟動的時候

       建立很多個資料庫連接配接并維護在一個池中。連接配接請求有池中的連接配接提供。在連接配接使用

       完畢以後,把連接配接歸還到池中,以用于滿足将來更多的請求。

   93、什麼是servlet?

       servlet是用來出來用戶端請求,并産生動态網頁内容的java類。servlet主要是用來

       處理或者是存儲html表單送出的資料,産生動态内容,在無狀态的http協定下管理狀态資訊。

   94、說一下servlet的體系結構。

       所有的servlet都必須要實作的核心接口是javax.servlet.servlet。每一個servlet都必須要

       直接或者是間接實作這個接口,或者是繼承javax.servlet.generriservlet或者

       javax.servlet.http.httpservlet。最後,servlet使用多線程可以并行的為多個請求服務。

   95、applet和servlet有什麼差別?

       applet是運作在用戶端主機的浏覽器上的用戶端java程式。而servlet是運作在web伺服器上的服務

       端的元件。applet可以使用使用者界面類,而servlet沒有使用者界面,相反,servlet是等待用戶端的

       http請求,然後為請求産生響應。

   96、genericservlet和httpservlet有什麼差別?

       genericservlet是一個通用的協定無關的servlet,它實作了servlet和servletconfig接口。繼承自

       genericservlet的servlet應該要覆寫service()方法。最後,為了開發一個能用網頁上服務于使用

       http協定請求的servlet,你的servlet必須要繼承自httpservlet。

   97、解釋一下servlet的聲明周期。

       對每一個用戶端的請求,servlet引擎載入servlet,調用它的init()方法,完成servlet的初始化。然

       後,servlet對象通過為每一個請求單獨調用service()方法來處理所有随後來自用戶端的騎牛,最後,

       調用servlet(這裡應該是servlet而不是server)的destroy()方法把servlet删除掉。

   98、doget()方法和dopost()方法有什麼差別?

       doget():get方法會把名值對追加在請求的url後面。因為url對字元數目有限制,進而限制了用在

                用戶端請求的參數值的數目。請求請求中的參數值是可見的,是以,敏感資訊不能用

                這種方式傳遞。

       dopost():post方法通過把請求參數值放在請求體中來克服get方法的限制,是以,可以放松參數

                的數目是沒有限制的。最後,通過post請求傳遞的敏感資訊對外部用戶端是不可見的。

   99、什麼是web應用程式?

       web應用程式是對web或者是應用伺服器的動态擴充。有兩種類型的web應用:面向表現和面向服務的。

       面向表現的web應用程式會産生包含了很多種标記語言和動态内東的互動web頁面作為對請求的響應。

       而面向服務的web應用實作了web服務的端點(endpoint)。一般來說,一個web應用可以看成一組安裝

       在伺服器url名稱空間的特定子集下面的servlet的集合。

   100、什麼是服務端包含(server side include)?

        服務端包含(ssi)是一種簡單的解釋型服務端腳本語言,大多數時候僅用在web上,用servlet标簽嵌

        如進來。ssi最常用的場景是把一個或多個檔案包含到web伺服器的一個web界面中。當浏覽器通路

        web頁面的時候,web伺服器會用對應的servlet産生的文本來替換web頁面中的servlet标簽。

   101、轉發與重定向的差別?

        轉發在伺服器端完成的;重定向是在用戶端完成的

        轉發的速度快;重定向速度慢

        轉發的是同一次請求;重定向是兩次不同請求

        轉發不會執行轉發後的代碼;重定向會執行重定向之後的代碼

        轉發位址欄沒有變化;重定向位址欄有變化

        轉發必須是在同一台伺服器下完成;重定向可以在不同的伺服器下完成

   102、什麼是servlet鍊(servlet chaining)?

        servlet鍊是把一個servlet的輸出發送給另一個servlet的方法。第二個servlet的輸出可以

        發送給第三個servlet,依次類推。聯調上最後一個servlet負責把響應發送給用戶端。

   103、你如何知道是哪一個用戶端的機器正在請求你的servlet?

        servletrequest類可以找出用戶端機器的ip位址或者是主機名。getremoteaddr()方法擷取

        用戶端主機的ip位址,getremotehost()可以擷取主機名。

   104、http響應的結構是怎麼樣的?

        http響應由三個部分組成:

        1、狀态碼(status code):描述了響應的狀态。可以用來檢查是否成功的完成了請求。請求失敗的

           情況下,狀态碼可以用來找出失敗額原因。如果servlet沒有傳回狀态碼,預設會傳回成功的

           狀态嗎httpservletresponse.sc_ok。

        2、http頭部(http header):它們包含了更多關于響應的資訊。比如:頭部可以指定認為響應過期的

            過期日期,或者是指定用來給使用者安全的傳輸實體内容的編碼格式。

        3、主體(body):它包含了響應的内容。它可以包含html代碼,圖檔,等等。主題是由傳輸在http

           消息頭中緊跟在頭部後面的資料位元組組成的。

   105、什麼是cookie?session和cookie有什麼差別?

        cookie是web伺服器發送給浏覽器的一塊資訊。浏覽器會在本地檔案中給每一個web伺服器存儲

        cookie。以後浏覽器在給特定的web伺服器發請求的時候,同時會發送給所有為該伺服器存儲的

        cookie。以下是seesion與cookie的差別:

        1、無論用戶端浏覽器做怎麼樣的設定,session都應該能正常工作。用戶端可以選擇禁用cookie,

           但是,session仍然是能夠工作的,因為用戶端無法禁用服務端的session。

        2、在存儲資料量方面session和cookie也是不一樣的。session能夠存儲任意的java對象,cookie

           隻能存儲string類型的對象。

   106、浏覽器和servlet通信使用的是什麼協定?

        http協定。

   107、什麼是http隧道?

        http隧道是一種利用http或者https把多種網絡協定封裝起來進行通信的技術。是以,http協定扮演

        了一個打通用于通信的網絡協定的管道的包裝器的角色。把其他協定的請求掩蓋成http的請求就是

        http隧道。

   108、什麼是url編碼和url解碼?

        url編碼是負責把url裡面的空格和其他的特殊字元替換成對應的十六進制表示,反之就是解碼。