java學習筆記總略

二、正文
(一)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)、char(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支持更高的并發。
(三)數據庫
1、數據庫優化:
①方法:MySQL可以建分表,讀寫分離,建索引,一般經常更新的字段不適合建索引,建索引會降低數據非查詢操作的效率。主鍵是一種特殊的索引。
②導致索引失效的情況:
A、如果條件中有or,即使其中有條件帶索引也不會使用到。
B、對于多列索引,不是使用的第一部分,則不會使用索引。
C、like查詢是以%開頭,而不是以%結尾的。
D、如果索引列類型是字符串,一定要在條件中將數據使用引號引用起來,否則不使用索引。
E、如果MySQL估計使用全表掃描要比使用索引快,則不使用索引。
2、MySQL引擎的種類和區別
①種類:MyISAM、InnoDB、MEMORY、MERGE、Archive、Blackhole、CSV、Federate、Merge、NDB集群引擎,第三方引擎:OLTP類引擎、面向列的存儲引擎、社區存儲引擎。
②區別:
A、MyISAM是MySQL5.1及之前的默認存儲引擎。MyISAM不支持事務、也不支持外鍵,但其訪問速度快,對事務完整性沒有要求。MyISAM表還支持3中不同的存儲格式:
1 靜態表
2 動態表
3 壓縮表
B、InnoDB存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是比起MyISAM存儲引擎,InnoDB寫的處理效率差一些并且會占用更多的磁盤空間以保留數據和索引。 InnoDB存儲方式為兩種:1 使用共享表空間存儲 2 使用多表空間
C、MEMORY存儲引擎使用存在內存中的內容來創建表。每個MEMORY表只實際對應一個磁盤文件。MEMORY類型的表訪問非常得快,因為它的數據是放在內存中的,并且默認使用HASH索引。但是一旦服務關閉,表中的數據就會丟失掉。
D、MERGE存儲引擎是一組MyISAM表的組合,這些MyISAM表必須結構完全相同。MERGE表本身沒有數據,對MERGE類型的表進行查詢、更新、刪除的操作,就是對內部的MyISAM表進行的。
3、數據庫事務
(1)四個特性:ACID,原子性,一致性,隔離性,持久性。
(2)四個隔離級別:
√: 可能出現 ×: 不會出現

臟讀 不可重復讀 幻讀
Read uncommitted √ √ √
Read committed × √ √
Repeatable read × × √
Serializable × × ×
Read Uncommitted(讀取未提交內容)
在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用于實際應用,因為它的性能也不比其他級別好多少。讀取未提交的數據,也被稱之為臟讀(Dirty Read)。
Read Committed(讀取提交內容)
這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離級別 也支持所謂的不可重復讀(Nonrepeatable Read),因為同一事務的其他實例在該實例處理其間可能會有新的commit,所以同一select可能返回不同結果。
Repeatable Read(可重讀)
這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在并發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本并發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
Serializable(可串行化)
這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。
這四種隔離級別采取不同的鎖類型來實現,若讀取的是同一個數據的話,就容易發生問題。例如:
i. 臟讀(Drity Read):某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由于某些原因,前一個RollBack了操作,則后一個事務所讀取的數據就會是不正確的。
ii. 不可重復讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的數據。
iii. 幻讀(Phantom Read):在一個事務的兩次查詢中數據筆數不一致,例如有一個事務查詢了幾列(Row)數據,而另一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。
(3)一致性處理:
A、開啟事務。B、申請寫權限,也就是給對象(表或記錄)加鎖。C、假如失敗,則結束事務,過一會重試。D、假如成功,也就是給對象加鎖成功,防止其他用戶再用同樣的方式打開。E、進行編輯操作。F、寫入所進行的編輯結果。G、假如寫入成功,則提交事務,完成操作。 H、假如寫入失敗,則回滾事務,取消提交。I、(G、H)兩步操作已釋放了鎖定的對象,恢復到操作前的狀態。
(4)基于事務的數據庫引擎的選型:如果考慮到事務,推薦選用MySQL INNODB引擎;如果考慮速度,建議考慮MySQL MyISAM引擎,并且需要在代碼層面做比較復雜的處理,如通過多線程、異步、非阻塞等方式對數據庫進行清理,同時需要信號量、欄柵、數據庫標志位等工具保證數據一致性。
4、海量數據處理
(1)數據庫擴展:
①縱向擴展:基于業務的高度隔離性和數據的安全性,對業務和數據進行合理的切分,進行主-備機分離,主-主同步,主-從同步(對于MySQL數據庫是單向異步同步機制),主-從熱備等操作。
②橫向擴展:對數據表進行橫向切分,按一定的規則(hash取模分、user_id尾數、自定義算法等)對數據表進行橫向切分。
關于數據庫架構和擴展方面的文章請見:Mysql在大型網站的應用架構演變。
(2)分布式數據方案:
①提供分庫規則和路由規則(RouteRule簡稱RR),將上面的說明中提到的三中切分規則直接內嵌入本系統,具體的嵌入方式在接下來的內容中進行詳細的說明和論述;
②引入集群(Group)的概念,保證數據的高可用性;
③引入負載均衡策略(LoadBalancePolicy簡稱LB);
④引入集群節點可用性探測機制,對單點機器的可用性進行定時的偵測,以保證LB策略的正確實施,以確保系統的高度穩定性;
⑤引入讀/寫分離,提高數據的查詢速度。
具體描述請參見博文:MySQL 海量數據的存儲和訪問解決方案。
(3)數據庫切分策略介紹,請見博文:數據庫Sharding的基本思想和切分策略。
(4)隨著數據量隨著業務的發展不斷增大,傳統的關系型數據庫RDB已經無法滿足需要,這時需要引入新的海量數據處理解決方案:ApacheHbase。
(四)框架
1、Struts2
①工作原理
A、在Struts2框架中的處理大概分為以下幾個步驟:
1)客戶端初始化一個指向Servlet容器(例如Tomcat)的請求
2)這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin)
3)接著FilterDispatcher被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action
4)如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy
5)ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類
6)ActionProxy創建一個ActionInvocation的實例。
7)ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用。
8)一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標簽。在這個過程中需要涉及到ActionMapper。
②工作流程:
1)客戶端在瀏覽器中輸入一個url地址。
2)這個url請求通過http協議發送給tomcat。
3)tomcat根據url找到對應項目里面的web.xml文件。
4)在web.xml里面會發現有struts2的配置。
5)然后會找到struts2對應的struts.xml配置文件。
6)根據url解析struts.xml配置文件就會找到對應的class。
7)調用完class返回一個字String,根據struts.xml返回到對應的jsp。
2、spring原理
①IoC(Inversion of control): 控制反轉,依賴注入
1)IoC:
概念:控制權由對象本身轉向容器;由容器根據配置文件去創建實例并創建各個實例之間的依賴關系
2)依賴IoC容器負責管理bean,有兩種,一種是BeanFactory,另一種是ApplicationContext,但是ApplicationContext繼承與BeanFactory。
核心:bean工廠;在spring中,bean工廠創建的各個實例稱作bean
②AOP(Aspect-Oriented Programming): 面向方面編程
1)代理的兩種方式:
靜態代理:
? 針對每個具體類分別編寫代理類;
? 針對一個接口編寫一個代理類;
動態代理:
針對一個方面編寫一個InvocationHandler,然后借用JDK反射包中的Proxy類為各種接口動態生成相應的代理類
2) AOP的主要原理:動態代理
實現:有兩種:JDK Proxy和Cglib,Spring規定對于有接口的類用JDK Proxy,對于無接口和抽象類用Cglib,雖然Cglib均可以代理,但是Cglib復雜,效率低。但是Cglib有例外,就是代理的類中不能是final修飾的類或者類中有final方法。
3、Spring、Struts2、Servlet對比
①Servlet原理:Tomcat 的容器等級中,Context 容器是直接管理 Servlet 在容器中的包裝類 Wrapper,所以 Context 容器如何運行將直接影響 Servlet 的工作方式。
A、Servlet生命周期詳解
Servlet的生命周期可以分為四個階段,即裝載類及創建實例階段、初始化階段、服務階段和實例銷毀階段。下面針對每個階段的編程任務及注意事項進行詳細的說明。
B、Servlet創建過程
在默認情況下Servlet實例是在第一個請求到來的時候創建,以后復用。一旦Servlet實例被創建,Web服務器會自動調用init(ServletConfig config)方法來初始化該Servlet。其中方法參數config中包含了Servlet的配置信息,比如初始化參數,該對象由服務器創建。init方法在Servlet生命周期中只執行一次,而且該方法執行在單線程的環境下,因此開發者不用考慮線程安全的問題。
C、服務
一旦Servlet實例成功創建及初始化,該Servlet實例就可以被服務器用來服務于客戶端的請求并生成響應。在服務階段Web服務器會調用該實例的service(ServletRequest request,ServletResponse response)方法,request對象和response對象有服務器創建并傳給Servlet實例。request對象封裝了客戶端發往服務器端的信息,response對象封裝了服務器發往客戶端的信息。
為了提高效率,Servlet規范要求一個Servlet實例必須能夠同時服務于多個客戶端請求,即service()方法運行在多線程的環境下,Servlet開發者必須保證該方法的線程安全性。
Serlvet接口只定義了一個服務方法就是service,而HttpServlet類實現了該方法并且要求調用下列的方法之一:
doGet:處理GET請求
doPost:處理POST請求
當發出客戶端請求的時候,調用service 方法并傳遞一個請求和響應對象。Servlet首先判斷該請求是GET 操作還是POST 操作。然后它調用下面的一個方法:doGet 或 doPost。如果請求是GET就調用doGet方法,如果請求是POST就調用doPost方法。
②對比:Spring主要有IoC和AOP,Spring中IoC管理的bean為單例模式的,可以配置成原型模式。如果用Spring管理struts2的bean,必須要設置成原型模式,因為struts2封裝來了servlet,隔離了servlet的特性,Action不同于Spring,已經是原型模式了。
4、memcached和Redis區別
①Memcached出現于2003年,key支持250bytes,value支持1MB;Redis出現于2009年,key和value都是支持512MB的。
持久化方面,memcached過期失效,redis可以緩存回收(6種回收機制),有存儲,可算為NOSQL,有優化,支持190多種命令。
集群方面,memcached不支持集群,基于兩次哈希,第一次哈希找到服務器節點,第二次哈希找到存儲的值。
1)Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲。
2)Redis支持數據的備份,即master-slave模式的數據備份。
3)Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用。
Redis只會緩存所有的key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據“swappability= age*log(size_in_memory)”計算出哪些key對應的value需要swap到磁盤。然后再將這些key對應的value持久化到磁盤中,同時在內存中清除。這種特性使得Redis可以保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。
②memcached、redis和MongoDB三者之間的對比:
1)性能
都比較高,性能對我們來說應該都不是瓶頸
總體來講,TPS(每秒事務處理量)方面redis和memcache差不多,要大于MongoDB
2)操作的便利性
memcache數據結構單一
redis豐富一些,數據操作方面,redis更好一些,較少的網絡IO次數
mongodb支持豐富的數據表達,索引,最類似關系型數據庫,支持的查詢語言非常豐富
3)內存空間的大小和數據量的大小
redis在2.0版本后增加了自己的VM特性,突破物理內存的限制;可以對key value設置過期時間(類似memcache)
memcache可以修改最大可用內存,采用LRU算法
mongoDB適合大數據量的存儲,依賴操作系統VM做內存管理,吃內存也比較厲害,服務不要和別的服務在一起
4)可用性(單點問題)
對于單點問題,
redis,依賴客戶端來實現分布式讀寫;主從復制時,每次從節點重新連接主節點都要依賴整個快照,無增量復制,因性能和效率問題,
所以單點問題比較復雜;不支持自動sharding,需要依賴程序設定一致hash 機制。
一種替代方案是,不用redis本身的復制機制,采用自己做主動復制(多份存儲),或者改成增量復制的方式(需要自己實現),一致性問題和性能的權衡
Memcache本身沒有數據冗余機制,也沒必要;對于故障預防,采用依賴成熟的hash或者環狀的算法,解決單點故障引起的抖動問題。
mongoDB支持master-slave,replicaset(內部采用paxos選舉算法,自動故障恢復),auto sharding機制,對客戶端屏蔽了故障轉移和切分機制。
5)可靠性(持久化)
對于數據持久化和數據恢復,
redis支持(快照、AOF):依賴快照進行持久化,aof增強了可靠性的同時,對性能有所影響;memcache不支持,通常用在做緩存,提升性能;MongoDB從1.8版本開始采用binlog方式支持持久化的可靠性。
6)數據一致性(事務支持)
Memcache 在并發場景下,用cas保證一致性。
redis事務支持比較弱,只能保證事務中的每個操作連續執行。
mongoDB不支持事務
7)數據分析
mongoDB內置了數據分析的功能(mapreduce),其他不支持。
8)應用場景
redis:數據量較小的更性能操作和運算上。
memcache:用于在動態系統中減少數據庫負載,提升性能;做緩存,提高性能(適合讀多寫少,對于數據量比較大,可以采用sharding)。
MongoDB:主要解決海量數據的訪問效率問題。
5、設計一個緩存
A、過期時間
B、多態實現訪問量
C、弱引用、軟引用。
D、WeakHashMap的使用。
緩存技術的實現原理:LRU(Least Recently Used)緩存技術
可以使用兩個標準的數據結構來實現,Map和Queue。因為需要支持多線程,需要使用實現了java.util.concurrent.*的Map和Queue。主要思路是使用一個Queue來維護FIFO和Map來對數據進行排序,當向緩存添加新的元素時,共有以下三種可能:
①如果該元素已經在Cache中存在(Map),我們會從Queue中刪除元素并將其添加到Queue的第一個位置;
②如果緩存已經無法滿足新增新的元素,我們會從Queue和Map中刪除最后面的那個元素并把新元素添加進來;
③同時在Map和Queue中增加新的元素。
參考代碼:
[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class LRUCache<K, V> {

// LRU 緩存的最大容量.
private final int capacity;
// 用來保持最近使用的元素的 Queue.
private ConcurrentLinkedQueue<K> queue;

private ConcurrentHashMap<K, V> map;

/**
* 初始化 LRU 緩存
*
* @param capacity
*/
public LRUCache(final int capacity) {
this.capacity = capacity;
this.queue = new ConcurrentLinkedQueue<K>();
this.map = new ConcurrentHashMap<K, V>(capacity);
}

/**
* 檢查該元素釋放在緩存中存在,如果不存在則返回 null
*
* @param key
* @return
*/
public V get(final K key) {
return map.get(key);
}

/**
* 將元素添加到 LRU 緩存。如果 Key 已存在,則將其放到緩存的第一位置
*
* @param key
* @param value
* @throws NullPointerException
*/
public synchronized void put(final K key, final V value) {
if (key == null || value == null) {
throw new NullPointerException();
}
if (map.containsKey(key)) {
queue.remove(key);
}
while (queue.size() >= capacity) {
K expiredKey = queue.poll();
if (expiredKey != null) {
map.remove(expiredKey);
}
}
queue.add(key);
map.put(key, value);
}
}
6、RPC
7、序列化
8、新技術
(1)Netty:
Netty是由JBOSS提供的一個java開源框架。Netty提供異步的、事件驅動的網絡應用程序框架和工具,用以快速開發高性能、高可靠性的網絡服務器和客戶端程序。 也就是說,Netty 是一個基于NIO的客戶,服務器端編程框架,使用Netty 可以確保你快速和簡單的開發出一個網絡應用,例如實現了某種協議的客戶,服務端應用。Netty相當簡化和流線化了網絡應用的編程開發過程,例如,TCP和UDP的socket服務開發。 “快速”和“簡單”并不意味著會讓你的最終應用產生維護性或性能上的問題。Netty 是一個吸收了多種協議的實現經驗,這些協議包括FTP,SMTP,HTTP,各種二進制,文本協議,并經過相當精心設計的項目,最終,Netty 成功的找到了一種方式,在保證易于開發的同時還保證了其應用的性能,穩定性和伸縮性。
(2)MongoDB:
Mongo DB 是目前在IT行業非常流行的一種非關系型數據庫(NoSql),其靈活的數據存儲方式備受當前IT從業人員的青睞。Mongo DB很好的實現了面向對象的思想(OO思想),在Mongo DB中 每一條記錄都是一個Document對象。Mongo DB最大的優勢在于所有的數據持久操作都無需開發人員手動編寫SQL語句,直接調用方法就可以輕松的實現CRUD操作。
(3)Hadoop:
Hadoop是一個由Apache基金會所開發的分布式系統基礎架構。 用戶可以在不了解分布式底層細節的情況下,開發分布式程序。充分利用集群的威力進行高速運算和存儲。Hadoop實現了一個分布式文件系統(Hadoop Distributed File System),簡稱HDFS。HDFS有高容錯性的特點,并且設計用來部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)來訪問應用程序的數據,適合那些有著超大數據集(large data set)的應用程序。HDFS放寬了(relax)POSIX的要求,可以以流的形式訪問(streaming access)文件系統中的數據。 Hadoop的框架最核心的設計就是:HDFS和MapReduce。HDFS為海量的數據提供了存儲,則MapReduce為海量的數據提供了計算。
(4)Solr:
Solr是一個高性能,采用Java5開發,SolrSolr基于Lucene的全文搜索服務器。同時對其進行了擴展,提供了比Lucene更為豐富的查詢語言,同時實現了可配置、可擴展并對查詢性能進行了優化,并且提供了一個完善的功能管理界面,是一款非常優秀的全文搜索引擎。
(5)ActiveMQ:
ActiveMQ 是Apache出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個完全支持JMS1.1和J2EE 1.4規范的 JMS Provider實現,盡管JMS規范出臺已經是很久的事情了,但是JMS在當今的J2EE應用中間仍然扮演著特殊的地位。
(6)Velocity:Velocity是一個基于java的模板引擎(template engine)。它允許任何人僅僅使用簡單的模板語言(template language)來引用由java代碼定義的對象。
(7)Openfire :Openfire 采用Java開發,開源的實時協作(RTC)服務器基于XMPP(Jabber)協議。Openfire安裝和使用都非常簡單,并利用Web進行管理。單臺服務器可支持上萬并發用戶。
(8)Node.js:
Node.js是一個基于Chrome JavaScript運行時建立的平臺, 用于方便地搭建響應速度快、易于擴展的網絡應用。Node.js 使用事件驅動, 非阻塞I/O 模型而得以輕量和高效,非常適合在分布式設備上運行的數據密集型的實時應用。 V8引擎執行Javascript的速度非常快,性能非常好。 Node是一個Javascript運行環境(runtime)。實際上它是對Google V8引擎進行了封裝。V8引 擎執行Javascript的速度非常快,性能非常好。Node對一些特殊用例進行了優化,提供了替代的API,使得V8在非瀏覽器環境下運行得更好。
(9)Ruby on Rails:
Ruby on Rails 是一個可以使你開發,部署,維護 web 應用程序變得簡單的框架。ruby on rails使用的實時映射技術和元編程技術,免去了開發人員在開發過程中編寫大量樣板文件代碼的煩惱。在少數需要使用樣板文件代碼的時候,開發人員可以通過ruby on rails內建的生成器腳本實時創建,而不再是通過手工編寫。rails的這個特點可以使開發人員更專注于系統的邏輯結構,而不必為一些瑣碎的細節所煩擾。
(10)Docker:
Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發布到任何流行的Linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app)。幾乎沒有性能開銷,可以很容易地在機器和數據中心中運行。最重要的是,他們不依賴于任何語言、框架或包括系統。
(11)ElasticSearch:
ElasticSearch是一個基于Lucene的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java開發的,并作為Apache許可條款下的開放源碼發布,是第二最流行的企業搜索引擎。設計用于云計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
(12)RESTful WebService:
RESTful WebService是比基于SOAP消息的WebService簡單的多的一種輕量級Web服務,RESTful WebService是沒有狀態的,發布和調用都非常的輕松容易。
(13)Hessian:
Hessian是一個輕量級的remoting onhttp工具,使用簡單的方法提供了RMI的功能。 相比WebService,Hessian更簡單、快捷。采用的是二進制RPC協議,因為采用的是二進制協議,所以它很適合于發送二進制數據。
(14)WebLogic:
WebLogic是美國Oracle公司出品的一個application server,確切的說是一個基于JAVAEE架構的中間件,WebLogic是用于開發、集成、部署和管理大型分布式Web應用、網絡應用和數據庫應用的Java應用服務器。將Java的動態功能和Java Enterprise標準的安全性引入大型網絡應用的開發、集成、部署和管理之中。
(15)OSGi:
OSGi(Open Service Gateway Initiative)技術是面向Java的動態模型系統。OSGi服務平臺向Java提供服務,這些服務使Java成為軟件集成和軟件開發的首選環境。Java提供在多個平臺支持產品的可移植性。OSGi技術提供允許應用程序使用精煉、可重用和可協作的組件構建的標準化原語。這些組件能夠組裝進一個應用和部署中。

轉載于:https://www.cnblogs.com/aibabel/p/6766806.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372328.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372328.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372328.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

react實現路由跳轉_react實現hash路由

眾所周知&#xff0c;目前單頁面使用的路由有兩種實現方式&#xff1a;hash 模式history 模式hash 模式路由原理&#xff1a;我們先來看hash模式&#xff0c;頁面首次加載時需要在load事件中解析初始的URL&#xff0c;從而展示進入的頁面。當 # 后面的哈希值發生變化時&#xf…

Java中的Google協議緩沖區

總覽 協議緩沖區是一種用于結構化數據的開源編碼機制。 它是由Google開發的&#xff0c;旨在實現語言/平臺中立且可擴展。 在本文中&#xff0c;我的目的是介紹Java平臺上下文中協議緩沖區的基本用法。 Protobuff比XML更快&#xff0c;更簡單&#xff0c;并且比JSON更緊湊。 當…

匈牙利哦模板 二分匹配 完全匹配問題

匈牙利算法的核心思想就是 騰空間, 有條件 創造,沒條件也要創造! bool find(int x){int i,j;for (j1;j<m;j){ //掃描每個被匹配的人 if (line[x][j]true && used[j]false) //如果有關系并且還沒有標記過(這里標記的意思是這次查找曾試圖改變過的歸屬問題&a…

ThinkPHP 中驗證碼的看不清切換

<!--HTML頁面--> <!DOCTYPE html><html><head> <title></title></head><body><script type"text/javascript" src"__PUBLIC__/js/jquery-1.8.2.min.js"></script><form action"{:U(H…

mysql從表截取信息_mysql中循環截取用戶信息并插入到目標表對應的字段中

操作環境&#xff1a;有表game_list&#xff0c;字段&#xff1a;uid&#xff0c;score1&#xff0c;score2&#xff0c;seat_id&#xff0c;last_update&#xff1b;傳入參數為i_player_detail &#xff0c;傳入的值為多個用戶的id、之前分數、之后分數、座位號&#xff0c;每…

Java中的數組,列表,集合,映射,元組,記錄文字

有時&#xff0c;當我對JavaScript的強大功能和表現力感到興奮時&#xff0c;我發現自己錯過了Java世界中的一兩個功能。 除了lambda表達式/閉包或任何您想稱為“匿名函數”的東西之外&#xff0c;它還對數組&#xff0c;數組&#xff0c;列表&#xff0c;集合&#xff0c;映射…

mysql鎖表問題的解決方法_MYSQL鎖表問題的解決方法

本文實例講述了MYSQL鎖表問題的解決方法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;很多時候&#xff01;一不小心就鎖表&#xff01;這里講解決鎖表終極方法&#xff01;案例一mysql>show processlist;參看sql語句一般少的話mysql>kill thread_id;就可以解…

linux——(1)初識linux

linux有窗口管理員環境和純文本界面環境&#xff0c;同時linux默認提供6個Terminal來讓用戶登錄。crtlaltF1-6可自由切換。其中如果窗口管理員環境處于運行狀態&#xff0c;那么可以按crtlaltF7直接切過去。 常用命令&#xff1a; cd [dir] #進入dir目錄下 ls #列出當前目錄下的…

4.26學習成果

哇&#xff0c;今天終于開始接觸Web了&#xff0c;感覺有點小興奮&#xff0c;這幾天看來那個視頻感覺挺有趣的&#xff0c;挺奇妙的。看到人家敲代碼&#xff0c;感覺好厲害。但是感覺不懂&#xff0c;所以&#xff0c;要努力學習了。 今天的學習成果&#xff1a; 網頁由什么組…

將Glassfish 3連接到外部ActiveMQ 5代理

介紹 在ONVZ&#xff0c;我們將Glassfish 3用作開發和生產應用服務器&#xff0c;我們對其性能和穩定性以及周圍的廣大社區感到非常滿意。 我很少遇到在stackoverflow或java.net上沒有匹配解決方案的問題。 作為我們開源策略的一部分&#xff0c;我們還運行了一個定制的ActiveM…

esp8266 lcd 天氣_ESP8266 顯示實時天氣信息

代碼文件getdata.h#include #include #include #include #include #include #include #define DEBUG 1#define MAX_CONTENT_SIZE 2000const char* ssid "weather";const char* password "mymymymy";WiFiClient client;HTTPClient http;char response[MAX…

【VS開發】visual studio 2015的NuGet Manager解決方案管理功能

NuGet的官方說明是&#xff1a;NuGet是一款Visual Studio的擴展&#xff0c;它可以簡單的安裝、升級開源庫和工具。 官網地址&#xff1a;http://www.nuget.org/ 官網最醒目的位置就是下載鏈接&#xff0c;安裝完成后我們來快速體驗一把。 手上有個小項目需要使用到json格式&am…

五. 面向對象高級特性4. 接口的概念和使用

在抽象類中&#xff0c;可以包含一個或多個抽象方法&#xff1b;但在接口(interface)中&#xff0c;所有的方法必須都是抽象的&#xff0c;不能有方法體&#xff0c;它比抽象類更加“抽象”。接口使用 interface 關鍵字來聲明&#xff0c;可以看做是一種特殊的抽象類&#xff0…

智能配料

我們都有多少次聽說“分批處理”會增加延遲&#xff1f; 作為對低延遲系統充滿熱情的人&#xff0c;這讓我感到驚訝。 以我的經驗&#xff0c;正確完成批處理不僅可以提高吞吐量&#xff0c;還可以減少平均延遲并保持一致。 那么&#xff0c;批處理如何神奇地減少延遲呢&#x…

mysql從myisam_將MySQL從MyISAM轉換成InnoDB錯誤和解決辦法

原來自己用的是為了裝的&#xff0c; 所以在設置database usage(如下圖1)的時候按照discuz官方的建議&#xff0c;選的都是Non-Transactional Database Only(只支持MyISAM數據引擎的非事務數據庫)&#xff0c;用MyISAM數據庫&#xff0c;還沒涉及到需要InnoDB&#xff0c;因此打…

相似性度量中用到的一些距離函數

本文目錄 1. 歐氏距離 2. 曼哈頓距離 3. 切比雪夫距離 4. 閔可夫斯基距離 5. 標準化歐氏距離 6. 馬氏距離 7. 漢明距離 8. 杰卡德距離 & 杰卡德相似系數 9. 相關系數 & 相關距離 10. 信息熵 1. 歐氏距離(Euclidean Distance) 歐氏距離是最易于理解的一種距離計算方法&a…

Spring 3.1配置文件和Tomcat配置

Spring 3.1引入了非常有用的功能&#xff0c;稱為配置文件 。 因此&#xff0c;它易于構建&#xff0c;可以在所有環境&#xff08;開發&#xff0c;測試&#xff0c;生產等&#xff09;中部署的軟件包。 通過定義系統屬性spring.profiles.active&#xff0c; Spring允許我們使…

計算1~n之間所有奇數之和_所有奇數長度子數組的和

所有奇數長度子數組的和題目&#xff1a;給你一個正整數數組 arr &#xff0c;請你計算所有可能的奇數長度子數組的和。子數組 定義為原數組中的一個連續子序列。請你返回 arr 中 所有奇數長度子數組的和 。示例 1&#xff1a;輸入&#xff1a;arr [1,4,2,5,3]輸出&#xff1a…

MYSQL AND OR的聯用

MYSQL AND OR的聯用 MYSQL中”AND”和”OR”都是條件控制符。”AND”是求交集&#xff0c;而”OR”則是求并集&#xff0c;非常多情況下&#xff0c;須要聯用它們兩個。下面是兩張表,我僅僅列出實用的字段。 Table:student_score 學生成績 sid(學生ID) cid(課程ID) score(分數)…

九度oj 題目1456:勝利大逃亡

題目描述&#xff1a;Ignatius被魔王抓走了,有一天魔王出差去了,這可是Ignatius逃亡的好機會.魔王住在一個城堡里,城堡是一個A*B*C的立方體,可以被表示成A個B*C的矩陣,剛開始Ignatius被關在(0,0,0)的位置,離開城堡的門在(A-1,B-1,C-1)的位置,現在知道魔王將在T分鐘后回到城堡,I…