Java中級開發工程師知識點

才智咖 人氣:1.03W

根據IDC的統計數字,在所有軟體開發類人才的需求中,對Java程式設計師的需求達到全部需求量的60%~70%。同時,Java程式設計師的薪水相對較高。本站小編收集了一些關於Java中級開發工程師知識點,希望大家認真閱讀!

Java中級開發工程師知識點

一、版本更新說明:

2015.03.09--------文章釋出

2015.03.11--------添加了Java IO機制中的種類和應用場景的解釋,添加了Java記憶體模型的相關知識點

2015.03.13--------文章按技術劃分,增加J2EE規範的解釋

2015.04.25--------增加對LRU快取設計的描述

2015.04.26--------增加對比較流行的開源技術和開源框架的介紹,對於這些技術的理解或使用可以增加自己的競爭優勢,同時擴充套件自己的眼界

2015.04.27--------增加對資料庫事務的描述

二、正文

(一)Java

1.介面和抽象類的區別

①抽象類裡可以有構造方法,而介面內不能有構造方法。

②抽象類中可以有普通成員變數,而介面中不能有普通成員變數。

③抽象類中可以包含非抽象的普通方法,而介面中所有的方法必須是抽象的,不能有非抽象的普通方法。

④抽象類中的抽象方法的訪問型別可以是public ,protected和預設型別,但介面中的抽象方法只有public和預設型別。

⑤ 抽象類中可以包含靜態方法,介面內不能包含靜態方法。

⑥抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是public static型別,並且預設為public static型別。

⑦一個類可以實現多個介面,但只能繼承一個抽象類。

⑧介面更多的是在系統框架設計方法發揮作用,主要定義模組之間的通訊,而抽象類在程式碼實現方面發揮作用,可以實現程式碼的重用。

2.Java虛擬機器的執行時資料區有幾塊?執行緒私有和執行緒共享區域有哪些?

①程式計數器:執行緒私有,當前縣城執行的位元組碼的行號指示器。

②虛擬機器棧:執行緒私有,存放基本資料型別、物件引用和returnAddress型別。

③本地方法棧:為虛擬機器使用到的Native方法服務。

④Java堆:執行緒共享,存放物件的例項,也是GC回收器管理的主要區域。

⑤方法區:執行緒共享,存放已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯後的程式碼等資料。

⑥執行時常量池:方法區的一部分,存放編譯期生成的各種字面量和符號引用。

⑦直接記憶體:不是虛擬機器執行時資料區的一部分,也不是Java虛擬機器規範中定義的記憶體區域,容易引起OOM異常,NIO會呼叫,不受Java堆大小的限制。

3.HashMap和HashTable區別?

①Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map介面的一個實現。

②Hashtable的方法是同步的,而HashMap的方法不是,因此HashTable是執行緒安全的,但是程式碼的執行效率上要慢於HashMap。

③HashMap允許空值和空鍵,但是HashTable不可以。

④HashMap非同步實現Map介面,是一個“連結串列陣列”的資料結構,最大承載量是16,可以自動變長,由Entry[]控制(key,value,next),hashCode()判斷key是否重複。

⑤建議需要做同步,使用ConcurrentHashMap,降低了鎖的粒度。在hashMap的基礎上,ConcurrentHashMap將資料分為多個segment,預設16個(concurrency level),然後每次操作對一個segment加鎖,避免多執行緒鎖得機率,提高併發效率。這裡在併發讀取時,除了key對應的value為null之外,並沒有使用鎖。

4.ArrayList和LinkedList區別?

ArrayList基於陣列實現,LinkedList基於連結串列實現,ArrayList增加和刪除比LinkedList慢,但是LinkedList在查詢的時需要遞迴查詢,效率比ArrayList慢。關於多執行緒方面,如果要求執行緒安全的,有一個Vector,不過比較多的使用的是CopyOnWriteArrayList替代ArrayList,CopyOnWriteArrayList適合使用在讀操作遠遠大於寫操作的場景裡,比如快取。發生修改時候做copy,新老版本分離,保證讀的高效能,適用於以讀為主的情況。

5.Set介面

①HashSet是Set介面的典型實現,HashSet按hash演算法來儲存元素,因此具有很好的存取和查詢效能。特點:不能保證元素的排列順序,順序有可能發生變化;HashSet是非同步的;集合元素值可以是null;當向HashSet集合中存入一個元素時,HashSet會呼叫該物件的hashCode()方法來得到該物件的hashCode值,然後根據該HashCode值來確定該物件在HashSet中儲存的位置。HashSet還有一個子類LinkedHashSet,其集合也是根據元素hashCode值來決定元素的儲存位置,但它同時用連結串列來維護元素的次序,這樣使得元素看起來是以插入的順序儲存的,也就是說,當遍歷LinkedHashSet集合元素時,它將會按元素的新增順序來訪問集合裡的元素。所以LinkedHashSet的效能略低於HashSet,但在迭代訪問全部元素時將有很好的效能,因為它以連結串列來維護內部順序。

②TreeSet是SortSet介面的唯一實現,TreeSet可以確保集合元素處於排序狀態。TreeSet不是根據元素插入順序進行排序的,而是根據元素的值來排序的。TreeSet支援兩種排序方法:自然排序和定製排序。

③EnumSet中所有值都必須是指定列舉型別的值,它的元素也是有序的,以列舉值在列舉類的定義順序來決定集合元素的順序。EnumSet集合不允許加入null元素,否則會丟擲NullPointerException異常。EnumSet類沒有暴露任何構造器來建立該類的例項,程式應該通過它提供的static方法來建立EnumSet物件。

④總結:A、HashSet的效能比Treeset好,因為TreeSet需要額外的紅黑樹演算法來維護集合元素的次序,只有當需要一個保持排序的Set時,才會用TreeSet。B、EnumSet是效能最好的,但它只能儲存列舉值。

C、它們都是執行緒不安全的。

注:Set是一種不包含重複的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。

關於HashSet,條目數和容量之和來講,迭代是線性的。因此,如果迭代效能很重要,那就應該慎重選擇一個適當的初始容量。容量選得太大,既浪費空間,也浪費時間。預設的初試容量是101,一般來講,它比你所需要的要多。可以使用int建構函式來指定初始容量。要分配HashSet的初始容量為17:

Set s=new HashSet(17);

HashSet另有一個稱作裝載因數(load factor)的"調整引數(tuning parameter)"。

區別:

1. HashSet是通過HashMap實現的,TreeSet是通過TreeMap實現的,只不過Set用的只是Map的key。

2. Map的key和Set都有一個共同的特性就是集合的唯一性.TreeMap更是多了一個排序的功能.

3. hashCode和equal()是HashMap用的, 因為無需排序所以只需要關注定位和唯一性即可.

a. hashCode是用來計算hash值的,hash值是用來確定hash表索引的.

b. hash表中的一個索引處存放的是一張連結串列, 所以還要通過equal方法迴圈比較鏈上的每一個物件 才可以真正定位到鍵值對應的Entry.

c. put時,如果hash表中沒定位到,就在連結串列前加一個Entry,如果定位到了,則更換Entry中的value,並返回舊value

4. 由於TreeMap需要排序,所以需要一個Comparator為鍵值進行大小比較.當然也是用Comparator定位的.

a. Comparator可以在建立TreeMap時指定

b. 如果建立時沒有確定,那麼就會使用key.compareTo()方法,這就要求key必須實現Comparable介面.

TreeMap是使用Tree資料結構實現的,所以使用compare介面就可以完成定位了.

6.Java中Collection和Collections的區別

①java.util.Collection 是一個集合介面,它提供了對集合物件進行基本操作的通用介面方法。java.util.Collections 是一個包裝類。

②它包含有各種有關集合操作的靜態多型方法。此類不能例項化,就像一個工具類,服務於Java的Collection框架。

7.Java容器

JAVA的容器---List,Map,Set

Collection

├List

│├LinkedList

│├ArrayList

│└Vector

│ └Stack

└Set

Map

├Hashtable

├HashMap

└WeakHashMap

!其中的Vector和Stack類現在已經極少使用。

8.Cookie Session區別

具體來說cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在伺服器端保持狀態的方案.同時我們也看到,由於採用伺服器端保持狀態的方案在客戶端也需要儲存一個標識,所以session機制可能需要藉助於cookie機制來達到儲存標識的目的,但實際上它還有其他選擇.

cookie機制.正統的cookie分發是通過擴充套件HTTP協議來實現的,伺服器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie.然而純粹的客戶端指令碼如JavaScript或者VBScript也可以生成cookie.而cookie的使用是由瀏覽器按照一定的原則在後臺自動傳送給伺服器的.瀏覽器檢查所有儲存的cookie,如果某個cookie所宣告的作用範圍大於等於將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上傳送給伺服器.

cookie的內容主要包括:名字,值,過期時間,路徑和域.路徑與域一起構成cookie的作用範圍.若不設定過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關閉瀏覽器視窗,cookie就消失.這種生命期為瀏覽器會話期的cookie被稱為會話cookie.會話cookie一般不儲存在硬碟上而是儲存在記憶體裡,當然這種行為並不是規範規定的.若設定了過期時間,瀏覽器就會把cookie儲存到硬碟上,關閉後再次開啟瀏覽器,這些cookie仍然有效直到超過設定的過期時間.儲存在硬碟上的cookie可以在不同的瀏覽器程序間共享,比如兩個IE視窗.而對於儲存在記憶體裡的cookie,不同的瀏覽器有不同的處理方式

session機制.session機制是一種伺服器端的機制,伺服器使用一種類似於散列表的結構(也可能就是使用散列表)來儲存資訊.

當程式需要為某個客戶端的請求建立一個session時,伺服器首先檢查這個客戶端的請求裡是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端建立過session,伺服器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含sessionid,則為此客戶端建立一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個session id將被在本次響應中返回給客戶端儲存.

儲存這個sessionid的方式可以採用cookie,這樣在互動過程中瀏覽器可以自動的按照規則把這個標識發揮給伺服器.一般這個cookie的名字都是類似於SEEESIONID.但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞迴伺服器.

經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面.還有一種技術叫做表單隱藏欄位.就是伺服器會自動修改表單,新增一個隱藏欄位,以便在表單提交時能夠把session id傳遞迴伺服器.比如:實際上這種技術可以簡單的用對action應用URL重寫來代替.

9、物件導向和麵向過程的區別:

面向過程就是分析出解決問題所需要的步驟,然後用函式把這些步驟一步一步實現,使用的時候一個一個依次呼叫就可以了。

物件導向是把構成問題事務分解成各個物件,建立物件的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為。

10、Java記憶體模型

①Java記憶體模型分為主記憶體和工作記憶體兩個部分,其中主記憶體存放變數,工作記憶體由每個執行緒建立和管理,儲存被該執行緒使用到的變數的主記憶體的副本拷貝。變數從主記憶體複製到工作記憶體,順序執行read和load操作,變數從工作記憶體同步到主記憶體的時候,順序執行store和write操作。

對於volatile變數在各個執行緒的一致性:在各個執行緒的工作記憶體中,volatile存在不一致的情況,但在每次使用前都會重新整理,執行引擎看不到不一致的情況,因此可以認為不存在一致性問題。

②原子性、可見性和有序性

③先行發生原則

11、Java垃圾回收機制

Java的垃圾回收機制是Java虛擬機器提供的能力,用於在空閒時間以不定時的方式動態回收無任何引用的物件佔據的記憶體空間。

System.gc();

Runtime.getRuntime().gc();

上面的方法呼叫時用於顯式通知JVM可以進行一次垃圾回收,但真正垃圾回收機制具體在什麼時間點開始發生動作這同樣是不可預料的,這和搶佔式的執行緒在發生作用時的原理一樣。

12、類載入器,類載入時機

類初始化的時機,有且僅有四個:

A、遇到new、getstatic、putstatic、invokestatic這四條位元組碼指令的時候。

B、使用java.lang.reflect進行反射呼叫的時候。

C、當初始化一個類的時候,發現其父類還沒有初始化,那麼先去初始化它的父類。

D、當虛擬機器啟動的時候,需要初始化main函式所在的類。

13、 Java IO和NIO區別

①NIO操作直接快取區,直接與OS互動,Selector IO複用機制。

IO NIO

面向流 面向緩衝

阻塞IO 非阻塞IO

無 選擇器

Selector:Java NIO的選擇器允許一個單獨的執行緒來監視多個輸入通道,你可以註冊多個通道使用一個選擇器,然後使用一個單獨的執行緒來“選擇”通道:這些通道里已經有可以處理的輸入,或者選擇已準備寫入的通道。這種選擇機制,使得一個單獨的執行緒很容易來管理多個通道。

②NIO與Netty:A、NIO的類庫和API複雜,使用麻煩,需要熟練使用Selector、ServerSocketChannel、SOcketChannel、ByteBuffer等。B、NIO涉及到Reactor模式,需要了解Java多執行緒和網路程式設計。C、JDKNIO Bug-epoll bug容易導致Selector空輪詢,最終導致CPU100%佔用,雖然JDK1.6 update18修復了這個問題,但是直到JDK1.7問題依然存在,只是降低了發生的概率。

③Netty的優點:A、API簡單,開發門檻低;B、功能強大,預置了多種解碼功能,支援多種主流協議;C、可以通過ChannelHandler對通訊框架進行靈活的擴充套件;D、效能高,Netty的綜合性能是最好的;E、Netty修復了一經發現了所有的JDKNIO BUG,成熟,穩定。

同步和非同步的概念描述的是使用者執行緒與核心的互動方式:同步是指使用者執行緒發起IO請求後需要等待或者輪詢核心IO操作完成後才能繼續執行;而非同步是指使用者執行緒發起IO請求後仍繼續執行,當核心IO操作完成後會通知使用者執行緒,或者呼叫使用者執行緒註冊的回撥函式。

引申:

Java中IO的種類和應用場景:

A、同步阻塞式:BIO。用於連線數目較小且固定的架構,對伺服器資源佔用高。

B、偽非同步IO變成:執行緒池和任務佇列。

C、NIO程式設計:a、緩衝徐ByteBuffer;b、通道channel全雙工,同時用於讀寫;c、多路複用器selector。用於連線數目多且較短的架構,如聊天伺服器等,但是程式設計複雜,存在epoll bug,導致Selector空輪詢,直至CPU佔用達到100%,雖然在JDK1.6 update18中有對這個bug的修復,但是在JDK1.7中依然可能會出現這個問題,只是降低了bug出現的概率。

D、AIO程式設計:用於連線數目多且較長的架構,如相簿伺服器等,充分呼叫OS參與併發操作,基於JDK1.7。

阻塞和非阻塞的概念描述的是使用者執行緒呼叫核心IO操作的方式:阻塞是指IO操作需要徹底完成後才返回到使用者空間;而非阻塞是指IO操作被呼叫後立即返回給使用者一個狀態值,無需等到IO操作徹底完成。

14、Java鎖機制

①synchronized:把程式碼塊宣告為 synchronized,有兩個重要後果,通常是指該程式碼具有 原子性和可見性。作用:A、當兩個併發執行緒訪問同一個物件object中的這個synchronized(this)同步程式碼塊時,一個時間內只能有一個執行緒得到執行。另一個執行緒必須等待當前執行緒執行完這個程式碼塊以後才能執行該程式碼塊。B、當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,另一個執行緒仍然可以訪問該object中的非synchronized(this)同步程式碼塊。C、尤其關鍵的是,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,其他執行緒對object中所有其它synchronized(this)同步程式碼塊的訪問將被阻塞。

A、原子性:原子性意味著個時刻,只有一個執行緒能夠執行一段程式碼,這段程式碼通過一個monitor object保護。從而防止多個執行緒在更新共享狀態時相互衝突。

B、可見性:可見性則更為微妙,它要對付記憶體快取和編譯器優化的各種反常行為。它必須確保釋放鎖之前對共享資料做出的更改對於隨後獲得該鎖的另一個執行緒是可見的。

C、volatile只保證可見性和禁止重排序,不保證原子性。

②synchronized限制:

A.它無法中斷一個正在等候獲得鎖的執行緒;

B.也無法通過投票得到鎖,如果不想等下去,也就沒法得到鎖;

C.同步還要求鎖的釋放只能在與獲得鎖所在的堆疊幀相同的堆疊幀中進行,多數情況下,這沒問題(而且與異常處理互動得很好),但是,確實存在一些非塊結構的鎖定更合適的情況。

③java.util.concurrent.lock:

ReentrantLock 類實現了Lock,它擁有與synchronized 相同的併發性和記憶體語義,但是添加了類似鎖投票、定時鎖等候和可中斷鎖等候的一些特性。此外,它還提供了在激烈爭用情況下更佳的效能。

用sychronized修飾的方法或者語句塊在程式碼執行完之後鎖自動釋放,而是用Lock需要我們手動釋放鎖,所以為了保證鎖最終被釋放(發生異常情況),要把互斥區放在try內,釋放鎖放在finally內。

④ReentrantWriteReadLock中的ReadLock和WWriteLock,在全為讀時實現併發讀,併發讀寫或併發寫時候加鎖。

總結:synchronized是Java原語,阻塞的,競爭鎖機制;新鎖更加物件導向,並且支援中斷和支援公平鎖。

15、Java基本資料型別

boolean(1)、byte(8)、16)、short(16)、int(32)、float(32)、long(64)、double(64)

16、Java記憶體模型

①特點:原子性、可見性、有序性。

A、原子性:read、load、use、store、write,synchronized關鍵字保證原子性

B、可見性:synchronized、volatile、final保證可見性

C、有序性:synchronized保證有序性

17、設計模式

①分類:

建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。

其實還有兩類:併發型模式和執行緒池模式。

②設計模式6大原則:

A、開閉原則(Open Close Principle)

開閉原則就是說對擴充套件開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的程式碼,實現一個熱插拔的效果。所以一句話概括就是:為了使程式的擴充套件性好,易於維護和升級。想要達到這樣的效果,我們需要使用介面和抽象類,後面的具體設計中我們會提到這點。

B、里氏代換原則(Liskov Substitution Principle)

里氏代換原則(Liskov Substitution Principle LSP)物件導向設計的基本原則之一。 里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。 LSP是繼承複用的基石,只有當衍生類可以替換掉基類,軟體單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行為。里氏代換原則是對“開-閉”原則的補充。實現“開-閉”原則的關鍵步驟就是抽象化。而基類與子類的繼承關係就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規範。—— From Baidu 百科

C、依賴倒轉原則(Dependence Inversion Principle)

這個是開閉原則的基礎,具體內容:真對介面程式設計,依賴於抽象而不依賴於具體。

D、介面隔離原則(Interface Segregation Principle)

這個原則的意思是:使用多個隔離的介面,比使用單個介面要好。還是一個降低類之間的耦合度的意思,從這兒我們看出,其實設計模式就是一個軟體的設計思想,從大型軟體架構出發,為了升級和維護方便。所以上文中多次出現:降低依賴,降低耦合。

F、迪米特法則(最少知道原則)(Demeter Principle)

為什麼叫最少知道原則,就是說:一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模組相對獨立。

F、合成複用原則(Composite Reuse Principle)

原則是儘量使用合成/聚合的方式,而不是使用繼承。

18、Java反射

反射機制指的是程式在執行時能夠獲取自身的資訊。

為什麼要用反射機制?直接建立物件不就可以了嗎,這就涉及到了動態與靜態的概念,

靜態編譯:在編譯時確定型別,繫結物件,即通過。

動態編譯:執行時確定型別,繫結物件。動態編譯最大限度發揮了java的靈活性,體現了多型的應用,有以降低類之間的藕合性。

一句話,反射機制的優點就是可以實現動態建立物件和編譯,體現出很大的靈活性,特別是在J2EE的開發中

它的靈活性就表現的十分明顯。

作用:①首先得根據傳入的類的全名來建立Class物件。 ②獲得類方法的方法。③ 獲得類中屬性的方法。

缺點:①效能第一:反射包括了一些動態型別,所以JVM無法對這些程式碼進行優化。因此,反射操作的效率要比那些非反射操作低得多。我們應該避免在經常被 執行的程式碼或對效能要求很高的程式中使用反射。②安全限制:使用反射技術要求程式必須在一個沒有安全限制的環境中執行。如果一個程式必須在有安全限制的環境中執行,如Applet。③內部暴露:由於反射允許程式碼執行一些在正常情況下不被允許的操作(比如訪問私有的屬性和方法),所以使用反射可能會導致意料之外的副作用--程式碼有功能上的錯誤,降低可移植性。反射程式碼破壞了抽象性,因此當平臺發生改變的時候,程式碼的行為就有可能也隨著變化。

19、Java引用

①假設我們在函式中寫了如下這個簡單的語句:

StringBuffer str= new StringBuffer("Hello world");

別看這個語句簡單,其實包含了如下三個步驟:

首先,new StringBuffer("Hello world")在堆裡申請了一坨記憶體,把建立好的StringBuffer物件放進去。其次,StringBuffer str聲明瞭一個指標。這個指標本身是儲存在棧上的(因為語句寫在函式中),可以用來指向某個StringBuffer型別的物件。或者換一種說法,這個指標可以用來儲存某個StringBuffer物件的地址。最後,當中這個等於號(賦值符號)把兩者關聯起來,也就是把剛申請的那一坨記憶體的地址儲存成str的值,完成引用。

②final常量的問題

針對引用型別變數的final修飾符也是很多人搞混淆的地方。實際上final只是修飾指標的值(也就是限定指標儲存的地址不能變)。至於該指標指向的物件,內容是否能變,那就管不著了。所以,對於如下語句:

final StringBuffer strConst = new StringBuffer();

你可以修改它指向的物件的內容,比如:

strConst.append(" ");

但是不能修改它的值,比如:

strConst = null;

③傳參的問題:

例如:System.out.println(str);這個語句又是什麼意思捏?這時候就兩說了。

第一種理解:可以認為傳進函式的是str這個指標,指標說白了就是一個地址的值,說得再白一點,就是個整數。按照這種理解,就是傳值的方式。也就是說,引數傳遞的是指標本身,所以是傳值的。

第二種理解:可以認為傳進去的是StringBuffer物件,按照這種理解,就是傳引用方式了。因為我們確實是把物件的地址(也就是引用)給傳了進去。

20、 執行緒、執行緒池:

①建立執行緒有兩種方式:繼承Thread或實現Runnable。Thread實現了Runnable介面,提供了一個空的run()方法,所以不論是繼承Thread還是實現Runnable,都要有自己的run()方法。一個執行緒建立後就存在,呼叫start()方法就開始執行(執行run()方法),呼叫wait進入等待或呼叫sleep進入休眠期,順利執行完畢或休眠被中斷或執行過程中出現異常而退出。

②wait和sleep比較:sleep方法有:sleep(long millis),sleep(long millis, long nanos),呼叫sleep方法後,當前執行緒進入休眠期,暫停執行,但該執行緒繼續擁有監視資源的所有權。到達休眠時間後執行緒將繼續執行,直到完成。若在休眠期另一執行緒中斷該執行緒,則該執行緒退出。等待有其它的執行緒呼叫notify()或notifyAll()進入排程狀態,與其它執行緒共同爭奪監視。

③執行緒池:多執行緒技術主要解決處理器單元內多個執行緒執行的'問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力。一個執行緒池包括以下四個基本組成部分:

A、執行緒池管理器(ThreadPool):用於建立並管理執行緒池,包括建立執行緒池,銷燬執行緒池,新增新任務;

B、工作執行緒(PoolWorker):執行緒池中執行緒,在沒有任務時處於等待狀態,可以迴圈的執行任務;

C、任務介面(Task):每個任務必須實現的介面,以供工作執行緒排程任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀態等;

D、任務佇列(taskQueue):用於存放沒有處理的任務。提供一種緩衝機制。

④執行緒池分類:

A、newFixedThreadPool 建立一個指定工作執行緒數量的執行緒池。

每當提交一個任務就建立一個工作執行緒,如果工作執行緒數量達到執行緒池初始的最大數,則將提交的任務存入到池佇列中。

B、newCachedThreadPool建立一個可快取的執行緒池。

這種型別的執行緒池特點是:

1).工作執行緒的建立數量幾乎沒有限制(其實也有限制的,數目為Interger.MAX_VALUE), 這樣可靈活的往執行緒池中新增執行緒。

2).如果長時間沒有往執行緒池中提交任務,即如果工作執行緒空閒了指定的時間(預設為1分鐘),則該工作執行緒將自動終止。終止後,如果你又提交了新的任務,則執行緒池重新建立一個工作執行緒。

C、newSingleThreadExecutor建立一個單執行緒化的Executor,即只建立唯一的工作者執行緒來執行任務,如果這個執行緒異常結束,會有另一個取代它,保證順序執行(我覺得這點是它的特色)。

單工作執行緒最大的特點是可保證順序地執行各個任務,並且在任意給定的時間不會有多個執行緒是活動的。

D、newScheduleThreadPool 建立一個定長的執行緒池,而且支援定時的以及週期性的任務執行,類似於Timer。

⑤Executors類,提供了一系列靜態工廠方法用於創先執行緒池,返回的執行緒池都實現了ExecutorService介面。

⑥執行緒池引數:

A、corePoolSize(執行緒池的基本大小)

B、runnableTaskQueue(任務佇列):用於儲存等待執行的任務的阻塞佇列。

1)LinkedBlockingQueue:一個基於連結串列結構的阻塞佇列,此佇列按FIFO (先進先出) 排序元素,吞吐量通常要高於ArrayBlockingQueue。靜態工廠方法Executors.newFixedThreadPool()使用了這個佇列。

2)SynchronousQueue:一個不儲存元素的阻塞佇列。每個插入操作必須等到另一個執行緒呼叫移除操作,否則插入操作一直處於阻塞狀態,吞吐量通常要高於LinkedBlockingQueue,靜態工廠方法Executors.newCachedThreadPool使用了這個佇列。

3)PriorityBlockingQueue:一個具有優先順序的無限阻塞佇列。

C、maximumPoolSize(執行緒池最大大小):執行緒池允許建立的最大執行緒數。

D、ThreadFactory:用於設定建立執行緒的工廠,可以通過執行緒工廠給每個創建出來的執行緒設定更有意義的名字。

E、RejectedExecutionHandler(飽和策略):當佇列和執行緒池都滿了,說明執行緒池處於飽和狀態,那麼必須採取一種策略處理提交的新任務。這個策略預設情況下是AbortPolicy,表示無法處理新任務時丟擲異常。以下是JDK1.5提供的四種策略:

1)AbortPolicy:直接丟擲異常。

2)CallerRunsPolicy:只用呼叫者所在執行緒來執行任務。

3)DiscardOldestPolicy:丟棄佇列裡最近的一個任務,並執行當前任務。

4)DiscardPolicy:不處理,丟棄掉。

5)當然也可以根據應用場景需要來實現RejectedExecutionHandler介面自定義策略。如記錄日誌或持久化不能處理的任務。

F、keepAliveTime(執行緒活動保持時間):執行緒池的工作執行緒空閒後,保持存活的時間。所以如果任務很多,並且每個任務執行的時間比較短,可以調大這個時間,提高執行緒的利用率。

G、TimeUnit(執行緒活動保持時間的單位):可選的單位有天(DAYS),小時(HOURS),分鐘(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。

21、J2EE的13種規範

(1)、JDBC(java Database Connectivity):

JDBC API為訪問不同的資料庫提供了一種統一的途徑,就像ODBC一樣,JDBC對開發者遮蔽了一些細節問題,同時,JDBC對資料庫的訪問也具有平臺無關性。

(2)、JNDI(Java Name and Directory Interface):

JNDI API 被用於執行名字和目錄服務。它提供了一致的模型用來存取和操作企業級的資源如DNS和LDAP,本地檔案系統,或應用伺服器中的物件。

(3)、EJB(Enterprise JavaBean):

J2ee技術之所以贏得全體廣泛重視的原因之一就是EJB,他們提供了一個框架開發和實施分散式商務邏輯,由此很顯著簡化了具有可伸縮性和高度複雜的企業級應用開發。EJB規範定義了EJB元件何時如何與他們的容器繼續擰互動作用。容器負責提供公用的服務,例如目錄服務、事務管理、安全性、資源緩衝池以及容錯性。但是注意的是,EJB並不是J2EE的唯一途徑。正是由於EJB的開放性,使得有的廠商能夠以一種和EJB平行的方式來達到同樣的目的。

(4)、RMI(RemoteMethod Invoke):remote(遙遠的) invoke(呼叫):

正如其名字所表示的那樣,RMI協議呼叫遠端物件上方法。它使用了序列化方式在客戶端和伺服器端傳遞資料。RMI是一種被EJB使用的更底層的協議。

(5)、Java IDL(介面定義語言)/CORBA:公共物件請求代理結構(Common Object Request Breaker Architecture):

在java IDL的支援下,開發人員可以將Java和CORBA整合在一起。他們可以建立Java物件並使之可以在CORBA ORB中展開,或者他們還可以建立Java類並做為和其他ORB一起展開的CORBA物件客戶。後一種方法提供了另外一種途徑,通過它可以被用於你的新的應用和舊系統相整合。

(6)、JSP(Java Server Pages):

Jsp頁面由html程式碼和嵌入其中的Java新程式碼所組成。伺服器在頁面被客戶端所請求以後對這些java程式碼進行處理,然後將生成的html頁面返回給客戶端的瀏覽器。

(7)、Java Servlet:

servlet是一種小型的java程式,它擴充套件了web伺服器的功能。作為一種伺服器端的應用,當被請求時開始執行,這和CGI Perl指令碼很相似。Servlet提供的功能大多和jsp類似,不過實現方式不同。JSP通過大多數的html程式碼中嵌入少量的java程式碼,而servlet全部由java寫成並生成相應的html。

(8)、XML(Extensible Markup Language):

XML是一種可以用來定義其他標記語言的語言。它被用來在不同的商務過程中共享資料。XML的發展和Java是互相獨立的,但是,它和java具有相同目標正是平臺立。通過java和xml的組合,我們可以得到一個完美的具有平臺立性的解決方案。

(9)、JMS(Java Message Service):

Ms是用於和麵向訊息的中介軟體相互通訊的應用程式介面(API)。它既支援點對點的域,有支援釋出/訂閱型別的域,並且提供對下列型別的支援:經認可的訊息傳遞,事務性訊息傳遞,一致性訊息和具有永續性的訂閱者的支援。JMS還提供了另一種方式對您的應用與舊的後臺系統相整合。

(10)、JTA(Java Transaction Architecture):

JTA定義了一種標準API,應用系統由此可以訪問各種事務監控。

(11)、JTS(Java Transaction Service):

JTS是CORBA OTS事務監控的基本實現。JTS規定了事務管理器的實現方式。該事務管理器是在高層支援Java Transaction API(JTA)規範,並且在較底層實現OMG OTS specification 的java映像。JTS事務管理器為應用伺服器、資源管理器、獨立的應用以及通訊資源管理器提供了事務服務。

(12)、JavaMail:

JavaMail是用於存取郵件服務的API,它提供了一套郵件伺服器的抽象類。不僅支援SMTP伺服器,也支援IMAP伺服器。

(13)、JAF(JavaBeans Activation Framework):

JavaMail利用JAF來處理MIME編碼的郵件附件。MIME的位元組流可以被轉換成java物件,或者轉換自Java物件。大多數應用都可以不需要直接使用JAF。

22、try/catch/finally/return 作用順序

不管有木有出現異常,finally塊中程式碼都會執行;

當try和catch中有return時,finally仍然會執行;

finally是在return後面的表示式運算後執行的(此時並沒有返回運算後的值,而是先把要返回的值儲存起來,管finally中的程式碼怎麼樣,返回的值都不會改變,任然是之前儲存的值),所以函式返回值是在finally執行前確定的;

finally中最好不要包含return,否則程式會提前退出,返回值不是try或catch中儲存的返回值。

(二)伺服器

1、web伺服器nginx和apache的對比分析

①nginx相對於apache的優點:

輕量級,同樣起web 服務,比apache 佔用更少的記憶體及資源 ,抗併發,nginx 處理請求是非同步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高效能,高度模組化的設計,編寫模組相對簡單。

apache相對於nginx 的優點:A.rewrite ,比nginx 的rewrite 強大;B.動態頁面,模組超多,基本想到的都可以找到;C.少bug ,nginx 的bug 相對較多;D.超穩定.

一般來說,需要效能的web 服務,用nginx 。如果不需要效能只求穩定,那就apache.

②作為 Web 伺服器:相比 Apache,Nginx 使用更少的資源,支援更多的併發連線,體現更高的效率。Nginx採用C進行編寫, 不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多.

③Nginx 配置簡潔,Apache 複雜。Nginx 靜態處理效能比 Apache 高 3倍以上,Apache 對 PHP 支援比較簡單,Nginx 需要配合其他後端用。Apache 的元件比 Nginx 多,現在 Nginx 才是Web 伺服器的首選。

④最核心的區別在於apache是同步多程序模型,一個連線對應一個程序;nginx是非同步的,多個連線(萬級別)可以對應一個程序。

⑤nginx處理靜態檔案好,耗費記憶體少.但無疑apache仍然是目前的主流,有很多豐富的特性.所以還需要搭配著來.當然如果能確定nginx就適合需求,那麼使用nginx會是更經濟的方式。

⑥nginx處理動態請求是雞肋,一般動態請求要apache去做,nginx只適合靜態和反向。

⑦Nginx優於apache的主要兩點:A.Nginx本身就是一個反向代理伺服器 B.Nginx支援7層負載均衡;其他的當然,Nginx可能會比 apache支援更高的併發。