在Java 6中Arrays.sort()和Collections.sort()使用的是MergeSort,而在Java 7中,內部實現換成了TimSort,其對對象間比較的實現要求更加嚴格java
從結構實現來說,HashMap是數組+鏈表+紅黑樹(JDK1.8增長了紅黑樹部分)實現的。HashMap最多隻容許一條記錄的鍵爲null,容許多條記錄的值爲null。HashMap非線程安全。ConcurrentHashMap線程安全。解決碰撞:當出現衝突時,運用拉鍊法,將關鍵詞爲同義詞的結點連接在一個單鏈表中,散列表長m,則定義一個由m個頭指針組成的指針數組T,地址爲i的結點插入以T(i)爲頭指針的單鏈表中。Java8中,衝突的元素超過限制(8),用紅黑樹替換鏈表。面試
1)可變與不可變:String不可變,每一次執行「+」都會新生成一個新對象,因此頻繁改變字符串的狀況中不用String,以節省內存。redis
2)是否多線程安全:StringBuilder並無對方法進行加同步鎖,因此是非線程安全的。StringBuffer和String均線程安全。算法
1)ArrayList在內存不夠時默認是擴展50% + 1個,Vector是默認擴展1倍。sql
2)Vector屬於線程安全級別的,可是大多數狀況下不使用Vector,由於線程安全須要更大的系統開銷。數據庫
1) 歷史緣由: Hashtable繼承Dictonary類, HashMap繼承自abstractMap編程
2) HashMap容許空的鍵值對, 但最多隻有一個空對象,而HashTable不容許。數組
3) HashTable同步,而HashMap非同步,效率上比HashTable要高緩存
ConcurrentHashMap融合了hashtable和hashmap兩者的優點。hashtable是作了同步的,即線程安全,hashmap未考慮同步。因此hashmap在單線程狀況下效率較高。hashtable在的多線程狀況下,同步操做能保證程序執行的正確性。可是hashtable是阻塞的,每次同步執行的時候都要鎖住整個結構,ConcurrentHashMap正是爲了解決這個問題而誕生的,安全
ConcurrentHashMap容許多個修改操做併發進行,其關鍵在於使用了鎖分離技術(一個Array保存多個Object,使用這些對象的鎖做爲分離鎖,get/put時隨機使用任意一個)。它使用了多個鎖來控制對hash表的不一樣部分進行的修改。在JDK 1.6中,有HashEntry結構存在,每次插入將新添加節點做爲鏈的頭節點(同HashMap實現),並且每次刪除一個節點時,會將刪除節點以前的全部節點拷貝一份組成一個新的鏈,而將當前節點的上一個節點的next指向當前節點的下一個節點,從而在刪除之後有兩條鏈存 在,於是能夠保證即便在同一條鏈中,有一個線程在刪除,而另外一個線程在遍歷,它們都能工做良好,由於遍歷的線程能繼續使用原有的鏈。
Java8中,採用volatile HashEntry保存數據,table元素做爲鎖;從table數組+單向鏈表加上了紅黑樹。紅黑樹是一種特別的二叉查找樹,特性爲:1.節點爲紅或者黑 2.根節點爲黑 3.葉節點爲黑 4.一節點爲紅,則葉節點爲黑 5.一節點到其子孫節點全部路徑上的黑節點數目相同。
與 LinkedList 的區別?
最明顯的區別是
ArrrayList 底層的數據結構是數組,支持隨機訪問,而 LinkedList 的底層數據結構書鏈表,不支持隨機訪問。使用下標訪問一個元素,ArrayList 的時間複雜度是 O(1),而 LinkedList 是 O(n)。LinkedList是雙向鏈表
Comparable 有什麼不一樣?
Comparable 接口用於定義對象的天然順序,是排序接口,而 comparator 一般用於定義用戶定製的順序,是比較接口。咱們若是須要控制某個類的次序,而該類自己不支持排序(即沒有實現Comparable接口),那麼咱們就能夠創建一個「該類的比較器」來進行排序。Comparable 老是隻有一個,可是能夠有多個 comparator 來定義對象的順序。
抽象類是指不容許被實例化的類;一個類只能使用一次繼承關係。可是,一個類卻能夠實現多個interface。
abstract class和interface所反映出的設計理念不一樣。其實abstract class表示的是」is-a」關係,interface表示的是」like-a」關係
實現抽象類和接口的類必須實現其中的全部方法。抽象類中能夠有非抽象方法。接口中則不能有實現方法。但在Java8中容許接口中有靜態默認的方法。
接口中定義的變量默認是public static final 型,且必須給其初值,因此實現類中不能從新定義,也不能改變其值。抽象類中的變量默認是 friendly 型,其值能夠在子類中從新定義,也能夠從新賦值。
子類中實現父類中的抽象方法時,可見性能夠大於等於父類中的;而接口實現類中的接口 方法的可見性只能與接口中相同(public)。
用抽象類是爲了重用。減小編碼量,下降耦合性。
重載和重寫都容許你用相同的名稱來實現不一樣的功能,可是重載是編譯時活動,而重寫是運行時活動。你能夠在同一個類中重載方法,可是隻能在子類中重寫方法。重寫必需要有繼承
重寫:一、在子類中能夠根據須要對從基類中繼承來的方法進行重寫。二、重寫的方法和被重寫的方法必須具備相同方法名稱、參數列表和返回類型。三、重寫方法不能使用比被重寫的方法更嚴格的訪問權限。
重載的時候,方法名要同樣,可是參數類型和個數不同,返回值類型能夠相同也能夠不相同。沒法以返回型別做爲重載函數的區分標準。
Collection是Java集合框架中的基本接口;
Collections是Java集合框架提供的一個工具類,其中包含了大量用於操做或返回集合的靜態方法。
所謂多態,指的就是父類引用指向子類對象,調用方法時會調用子類的實現而不是父類的實現。多態的實現的關鍵在於「動態綁定」。
clone(), equals(), hashCode(), toString(), notify(), notifyAll(),
wait(), finalize(), getClass()
泛型即參數化類型,在建立集合時,指定集合元素的類型,此集合只能傳入該類型的參數。類型擦除:java編譯器生成的字節碼不包含泛型信息,因此在編譯時擦除:1.泛型用最頂級父類替換;2.移除。
Java 8 在 Java 歷史上是一個開創新的版本,下面 JDK 8 中 5 個主要的特性:
Lambda 表達式;容許像對象同樣傳遞匿名函數 Stream API,充分利用現代多核 CPU,能夠寫出很簡潔的代碼 ;Date 與 Time API,最終,有一個穩定、簡單的日期和時間庫可供你使用 擴展方法,如今,接口中能夠有靜態、默認方法; 重複註解,如今你能夠將相同的註解在同一類型上使用屢次。
Protected可在包內及包外子類訪問,default只能同一包內訪問,prvate只能同一類
集合,線性結構(數組,隊列,鏈表和棧),樹形結構,圖狀結構
18.Java 中的 TreeMap 是採用什麼樹實現的?(答案)
Java 中的 TreeMap 是使用紅黑樹實現的。
匿名內部類也就是沒有名字的內部類,匿名內部類只能使用一次,它一般用來簡化代碼編寫。
匿名內部類只能訪問外部類的Final變量. Java 8更加智能:若是局部變量被匿名內部類訪問,那麼該局部變量至關於自動使用了final修飾。
一種是經過枚舉,一種是經過靜態內部類。
poll() 和
remove() 都是從隊列中取出一個元素,可是 poll() 在獲取元素失敗的時候會返回空,可是 remove() 失敗的時候會拋出異常。
使用迭代器。
Iterator itr = list.iterator();
while(itr.hasNext()) {if(…) { itr.remove();} }
類加載過程:加載、驗證(驗證階段做用是保證Class文件的字節流包含的信息符合JVM規範,不會給JVM形成危害)、準備(準備階段爲變量分配內存並設置類變量的初始化)、解析(解析過程是將常量池內的符號引用替換成直接引用)、初始化。
雙親委派模型中方法:雙親委派是指若是一個類收到了類加載的請求,不會本身先嚐試加載,先找父類加載器去完成。當頂層啓動類加載器表示沒法加載這個類的時候,子類纔會嘗試本身去加載。當回到最開的發起者加載器還沒法加載時,並不會向下找,而是拋出ClassNotFound異常。
方法:啓動(Bootstrap)類加載器,標準擴展(Extension)類加載器,應用程序類加載器(Application ),上下文(Custom)類加載器。意義是防止內存中出現多份一樣的字節碼 。
jvm是如何判斷一個對象已經變成了可回收的「垃圾」,通常是兩個方法:引用記數法和根搜索算法。引用記數法沒辦法解決循環引用的問題,因此用根搜索。從一系列的」GC Roots「對象開始向下搜索,搜索走過的路徑稱爲引用鏈。當一個對象到」GC Roots「之間沒有引用鏈時,被稱爲引用不可達。引用不可到的對象被認爲是可回收的對象。
幾種垃圾收集器:1,Serial New/Serial Old(串行),2,Parrallel New (並行),3,Parrallel Scavenge,4,Parrallel Old,5,CMS(CMS收集器是一個以得到最短回收停頓時間爲目標的收集器,它是一種併發收集器,採用的是Mark-sweep算法。),6,G1(是一款並行與併發收集器,而且可創建可預測的停頓時間模型,總體上是基於標記清理,局部採用複製)
1)方法區(method):被全部的線程共享。方法區包含全部的類信息和靜態變量。
2)堆(heap):被全部的線程共享,存放對象實例以及數組,Java堆是GC的主要區域。
3)棧(stack):每一個線程包含一個棧區,棧中保存一些局部變量等。
4)程序計數器:是當前線程執行的字節碼的行指示器。
持久代主要存放的是Java類的類信息,與垃圾收集要收集的Java對象關係不大。全部新生成的對象首先都是放在年輕代的,年老代中存放的都是一些生命週期較長的對象。
內存溢出:程序申請內存時,沒有足夠的內存,out of memory;內存泄漏值垃圾對象沒法回收,可使用memory analyzer工具查看泄漏。
進程值運行中的程序(獨立性,動態性,併發性),線程指進程中的順序執行流。區別是:1.進程間不共享內存 2.建立進程進行資源分配的代價要大得多,因此多線程在高併發環境中效率高。
序列化指將java對象轉化爲字節序列,反序列化相反。主要是爲了java線程間通信,實現對象傳遞。只有實現了Serializable或Externalizable接口類對象纔可被序列化。
Java 中,int 類型變量的長度是一個固定值,與平臺無關,都是 32 位。意思就是說,在 32 位 和 64 位 的Java 虛擬機中,int 類型的長度是相同的。
Java中一共有四種類型的引用。StrongReference、 SoftReference、 WeakReference 以及 PhantomReference。
StrongReference 是 Java 的默認引用實現, 它會盡量長時間的存活於 JVM 內,當沒有任何對象指向它時將會被GC回收
WeakReference,顧名思義, 是一個弱引用, 當所引用的對象在
JVM 內再也不有強引用時, 將被GC回收
雖然 WeakReference 與 SoftReference 都有利於提升 GC 和 內存的效率,可是 WeakReference ,一旦失去最後一個強引用,就會被 GC 回收,而 SoftReference 會盡量長的保留引用直到 JVM 內存不足時纔會被回收(虛擬機保證), 這一特性使得
SoftReference 很是適合緩存應用
當經過 Java 命令啓動
Java 進程的時候,會爲它分配內存。內存的一部分用於建立堆空間,當程序中建立對象的時候,就從對空間中分配內存。GC 是 JVM 內部的一個進程,回收無效對象的內存用於未來的分配。
JVM 中堆和棧屬於不一樣的內存區域,使用目的也不一樣。棧經常使用於保存方法幀和局部變量,而對象老是在堆上分配。棧一般都比堆小,也不會在多個線程之間共享,而堆被整個 JVM 的全部線程共享。
併發編程中:原子性問題,可見性問題,有序性問題。
volatile關鍵字能保證可見性,字能禁止指令重排序,可是不能保證原子性。可見性只能保證每次讀取的是最新的值,可是volatile沒辦法保證對變量的操做的原子性。在生成的會變語句中加入Lock關鍵字和內存屏障。
Lock 實現提供了比使用synchronized 方法和語句可得到的更普遍的鎖定操做,它能以更優雅的方式處理線程同步問題。用sychronized修飾的方法或者語句塊在代碼執行完以後鎖自動釋放,而用Lock須要咱們手動釋放鎖
SQL優化、表機構優化、索引優化、緩存參數優化
可使用熱加載
1)管道(Pipe),2)命名管道(named pipe),3)信號(Signal),4)消息(Message)隊列,5)共享內存,6)內存映射(mapped memory),7)信號量(semaphore),8)套接口(Socket)
所謂死鎖:是指多個進程在運行過程當中因爭奪資源而形成的一種僵局。產生的緣由:競爭資源:當系統中多個進程使用共享資源,而且資源不足以知足須要,會引發進程對資源的競爭而產生死鎖。進程間推動的順序非法:請求和釋放資源的順序不當,也一樣會致使產生進程死鎖
1.互斥條件(進程獨佔資源)2.請求與保持(進程因請求資源而阻塞時,對已得到的資源保持不放) 3.不剝奪條件(進程已得到的資源,在末使用完以前,不能強行剝奪) 4.循環等待(若干進程之間造成一種頭尾相接的循環等待資源關係)
因爲在平時的工做中,線上服務器是分佈式多臺部署的,常常會面臨解決分佈式場景下數據一致性的問題,那麼就要利用分佈式鎖來解決這些問題。
線程同步與否 跟 阻塞非阻塞不要緊,同步是個過程,阻塞是線程的一種狀態。多個線程操做共享變量時可能會出現競爭。這時須要同步來防止兩個以上的線程同時進入臨界區內,在這個過程當中後進入臨界區的線程將阻塞,等待先進入的線程走出臨界區。
同步和異步最大的區別就在於。一個須要等待,一個不須要等待。同步能夠避免出現死鎖,讀髒數據的發生,通常共享某一資源的時候用,若是每一個人都有修改權限,同時修改一個文件,有可能使一我的讀取另外一我的已經刪除的內容,就會出錯,同步就會按順序來修改。
根據系統自身的環境狀況,有效的限制執行線程的數量,使得運行效果達到最佳。線程主要是經過控制執行的線程的數量,超出數量的線程排隊等候,等待有任務執行完畢,再從隊列最前面取出任務執行
wait() 方法應該在循環調用,由於當線程獲取到 CPU 開始執行的時候,其餘條件可能尚未知足,因此在處理前,循環檢測條件是否知足會更好。
wait(),notify()和notifyall()方法是java.lang.Object類爲線程提供的用於實現線程間通訊的同步控制方法。等待或者喚醒
(1)繼承Thread類,重寫run函數 (2)實現Runnable接口,重寫run函數 (3)實現Callable接口,重寫call函數
僞共享是多線程系統(每一個處理器有本身的局部緩存)中一個衆所周知的性能問題。緩存系統中是以緩存行(cache line)爲單位存儲的。緩存行是2的整數冪個連續字節,通常爲32-256個字節。最多見的緩存行大小是64個字節。當多線程修改互相獨立的變量時,若是這些變量共享同一個緩存行,就會無心中影響彼此的性能,這就是僞共享。
在TCP的鏈接中,數據流必須以正確的順序送達對方。TCP的可靠性是經過順序編號和確認(ACK)來實現的。TCP 鏈接是經過三次握手進行初始化的。三次握手的目的是同步鏈接雙方的序列號和確認號並交換 TCP 窗口大小信息。第一次是客戶端發起鏈接;第二次表示服務器收到了客戶端的請求;第三次表示客戶端收到了服務器的反饋。
1. cd命令用來改變所在目錄。cd / 轉到根目錄中cd ~ 轉到用戶目錄下 2. ls命令用來查看目錄的內容。 3. cp命令用來拷貝文件cp <source filename> <target filename> 4.mv命令 mv t.txt Document 把文件t.txt 移動到目錄Document中。
1.加法hash:所謂的加法Hash就是把輸入元素一個一個的加起來構成最後的結果。
2.位運算hash:這類型Hash函數經過利用各類位運算(常見的是移位和異或)來充分的混合輸入元素
3.乘法hash:33*hash + key.charAt(i)
設計目標是爲了解決因特網中的熱點(Hot spot)問題,一致性hash算法提出了在動態變化的Cache環境中,斷定哈希算法好壞的四個定義:一、平衡性(Balance) 二、單調性(Monotonicity) 三、分散性(Spread) 四、負載(Load)
第一範式—-數據庫中的表(全部字段值)都是不可分割的原子數據項。
第二範式—-數據庫表中的每一列都和主鍵相關,而不能只和主鍵的某一部分相關。
第三範式—-數據庫表中每一列數據都和主鍵直接相關,不能間接相關。範式是爲了減少數據冗餘。
數據庫中索引的結構是一種排序的數據結構,數據庫索引是經過B樹和變形的B+樹實現的。什麼狀況下不適合創建索引:1.對於在查詢過程當中不多使用或參考的列;對於那些只有不多數據值的列;對於那些定義爲image,text和bit數據類型的列;當修改性能遠大於檢索性能。
根據系統自身的環境狀況,有效的限制執行線程的數量,使得運行效果達到最佳。線程主要是經過控制執行的線程的數量,超出數量的線程排隊等候,等待有任務執行完畢,再從隊列最前面取出任務執行
java.util.concurrent、java.util.concurrent.atomic和java.util.concurrent.lock
…
GPL (GNU General Public License) :GNU通用公共許可協議
LGPL (GNU Lesser General Public License) :GNU寬通用公共許可協議
BSD
(Berkeley Software Distribution) :伯克利軟件分發許可協議
MIT (Massachusetts Institute of Technology):MIT之名源自麻省理工學院
Apache (Apache License) :Apache許可協議
MPL (Mozilla Public License) :Mozilla公共許可協議
1.get從服務器獲取信息,post向服務器傳信息 2.get傳送數據量比較小,post能夠比較大 3.get安全性比較低
TCP(Tranfer Control Protocol)的縮寫,是一種面向鏈接的保證傳輸的協議,在傳輸數據流前,雙方會先創建一條虛擬的通訊道。能夠不多差錯傳輸數據。
UDP(User DataGram Protocol)的縮寫,是一種無鏈接的協議,使用UDP傳輸數據時,每一個數據段都是一個獨立的信息,包括完整的源地址和目的地,在網絡上以任何可能的 路徑傳到目的地,所以,可否到達目的地,以及到達目的地的時間和內容的完整性都不能保證。
因此TCP必UDP多了創建鏈接的時間。相對UDP而言,TCP具備更高的安全性和可靠性。
TCP協議傳輸的大小不限制,一旦鏈接被創建,雙方能夠按照必定的格式傳輸大量的數據,而UDP是一個不可靠的協議,大小有限制,每次不能超過64K。
END
歷史推薦