java基礎以及多個「比較」
1.Collections.sort排序內部原理
在Java 6中Arrays.sort()和Collections.sort()使用的是MergeSort,而在Java 7中,內部實作換成了TimSort,其對物件間比較的實作要求更嚴格
2.hashMap原理,java8做的改變
從結構實作來講,HashMap是陣列鍊錶紅黑樹(JDK1.8增加了紅黑樹部分)實現的。 HashMap最多只允許一筆記錄的鍵為null,允許多筆記錄的值為null。
HashMap非線程安全。 ConcurrentHashMap線程安全。解決碰撞:當發生衝突時,運用拉鍊法,將關鍵字為同義詞的結點連結在一個單鍊錶中,散列表長m,則定義一個由m個頭指標組成的指標數組T,位址為i的結點插入以T(i)為頭指標的單鍊錶中。 Java8中,衝突的元素超過限制(8),用紅黑樹取代鍊錶。
3.String 和StringBuilder 的區別
1)可變與不可變:String不可變,每次執行「 」都會新產生一個新對象,所以頻繁改變字串的情況中不用String,以節省記憶體。
2)是否多執行緒安全:StringBuilder並沒有對方法進行加同步鎖,所以是非執行緒安全的。 StringBuffer和String均線程安全。
4.Vector 與 Array 的差異
1)ArrayList在記憶體不夠時預設是擴充50% 1個,Vector是預設擴充1倍。
2)Vector屬於執行緒安全性等級的,但大多數情況下不使用Vector,因為執行緒安全性需要更大的系統開銷。
5.HashMap 與Hashtable 的區別
1) 歷史原因: Hashtable繼承Dictonary類別, HashMap繼承自abstractMap
2) HashMap允許空的鍵值對, 但最多只有一個空對象,而HashTable不允許。
3) HashTable同步,而HashMap非同步,效率上比HashTable要高
6.ConncurrentHashMap和hashtable比較(兩個執行緒並發存取map同一條鏈,一個線程在尾部刪除,一個線程在前面遍歷查找,問為什麼前面的線程還能正確的查找到後面被另一個線程刪除的節點)
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.一節點到其子孫節點所有路徑上的黑節點數目相同。
7.ArrayList與 LinkedList 的差別?
最明顯的差異是
ArrrayList 底層的資料結構是數組,支援隨機訪問,而 LinkedList 的底層資料結構書鍊錶,不支援隨機存取。使用下標存取一個元素,ArrayList 的時間複雜度是 O(1),而 LinkedList 是 O(n)。 LinkedList是雙向鍊錶
8.Java 中,Comparator 與Comparable 有什麼不同?
Comparable 接口用於定義物件的自然順序,是排序接口,而 comparator 通常用於定義使用者自訂的順序,是比較接口。我們如果需要控制某個類別的順序,而該類別本身不支援排序(即沒有實作Comparable介面),那麼我們就可以建立一個「該類別的比較器」來進行排序。 Comparable 總是只有一個,但可以有多個 comparator 定義物件的順序。
9.抽象類別是什麼?它與介面有什麼區別?為什麼要使用過抽象類別?
抽象類別是指不允許被實例化的類別;一個類別只能使用一次繼承關係。但是,一個類別卻可以實作多個interface。
abstract class和interface所反映的設計理念不同。其實abstract class表示的是"is-a"關係,interface表示的是"like-a"關係
實作抽象類別和介面的類別必須實作其中的所有方法。抽象類別中可以有非抽象方法。接口中則不能有實作方法。但在Java8中允許介面中有靜態預設的方法。
介面中定義的變數預設是public static final 型,且必須給其初步值,所以實作類別中不能重新定義,也不能改變其值。抽象類別中的變數預設是 friendly 型,其值可以在子類別中重新定義,也可以重新賦值。
子類別中實作父類別中的抽象方法時,可見性可以大於等於父類別中的;而介面實作類別中的介面 方法的可見性只能與介面中相同(public)。
用抽象類別是為了重複使用。減少編碼量,降低耦合性。
10.描述 Java 中的重載與重寫?
重載和重寫都允許你用相同的名稱來實現不同的功能,但是重載是編譯時活動,而重寫是運行時活動。你可以在同一個類別中重載方法,但是只能在子類別中重寫方法。重寫必須要有繼承
重寫:1、在子類別中可以根據需要對從基底類別繼承來的方法進行重寫。 2、重寫的方法和被重寫的方法必須具有相同方法名稱、參數清單和傳回類型。 3.重寫方法不能使用比被重寫的方法更嚴格的存取權限。
重載的時候,方法名稱要一樣,但是參數型別和個數不一樣,回傳值型別可以相同也可以不相同。無法以返回型別作為重載函數的區分標準。
11.Collection與Collections的差異是什麼?
Collection是Java集合框架中的基本介面;
Collections是Java集合框架提供的工具類,其中包含了大量用於操作或傳回集合的靜態方法。
12.Java中多態的實作原理
所謂多態,指的就是父類別引用指向子類別對象,呼叫方法時會呼叫子類別的實作而不是父類別的實作。多態的實現的關鍵在於「動態綁定」。
13.object中定義了哪些方法?
clone(), equals(), hashCode(), toString(), notify(), notifyAll(),
wait(), finalize(), getClass()
14.Java泛型和型別擦除?
泛型即參數化類型,在建立集合時,指定集合元素的類型,此集合只能傳入該類型的參數。類型擦除:java編譯器產生的字節碼不包含泛型訊息,所以在編譯時擦除:1.泛型用最頂級父類替換;2.移除。
15.說出 5 個 JDK 1.8 引進的新特性?
Java 8 在Java 歷史上是一個開創新的版本,下面JDK 8 中5 個主要的特性:
Lambda 表達式;允許像物件一樣傳遞匿名函數Stream API,充分利用現代多核心CPU,可以寫出很簡潔的程式碼;Date 與Time API,最終,有一個穩定、簡單的日期和時間庫可供你使用擴充方法,現在,介面中可以有靜態、預設方法; 重複註解,現在你可以將相同的註解在同一類型上使用多次。
16.java中public,private,protected以及預設關鍵字的存取範圍:
Protected可在包內及包外子類別訪問,default只能同一包內訪問,prvate只能同一類
17. 常用資料結構:
集合,線性結構(數組,佇列,鍊錶和棧),樹形結構,圖狀結構
18.Java 中的TreeMap 是採用什麼樹實現的? (答案)
Java 中的 TreeMap 是使用紅黑樹實現的。
19. 匿名內部類別是什麼?如何存取在其外面定義的變數?
匿名內部類別也就是沒有名字的內部類,匿名內部類別只能使用一次,它通常用來簡化程式碼編寫。
匿名內部類別只能存取外部類別的Final變數. Java 8更聰明:如果局部變數被匿名內部類別訪問,那麼該局部變數相當於自動使用了final修飾。
20. 如何建立單例模式?說了雙重檢查,他說不是線程安全的。如何高效的創建一個線程安全的單例?
一種是透過枚舉,一種是透過靜態內部類別。
21.poll() 方法和 remove() 方法的差別?
poll() 和
remove() 都是從佇列中取出一個元素,但poll() 在取得元素失敗的時候會回傳空,但remove() 失敗的時候會拋出異常。
22.寫一段程式碼在遍歷 ArrayList 時移除一個元素
使用迭代器。
Iterator itr = list.iterator();
while(itr.hasNext()) {if(…) { itr.remove();} }
JVM
1.JVM如何載入一個類別的過程,雙親委派模型中有哪些方法
類別加載流程:載入、驗證(驗證階段作用是確保Class檔案的位元組流包含的資訊符合JVM規範,不會造成JVM危害)、準備(準備階段為變數分配記憶體並設定類別變數的初始化)、解析(解析過程是將常數池內的符號引用替換成直接引用)、初始化。
雙親委派模型中方法:雙親委派是指如果一個類別收到了類別載入的請求,不會自己先嘗試加載,先找父類別載入器去完成。當頂層啟動類別載入器表示無法載入這個類別的時候,子類別才會嘗試自己去載入。當回到最開的發起者載入器還無法載入時,並不會往下找,而是拋出ClassNotFound異常。
方法:啟動(Bootstrap)類別載入器,標準擴充(Extension)類別載入器,應用程式類別載入器(Application ),上下文(Custom)類別載入器。意義是防止記憶體中出現多份相同的字節碼 。
2.GC演算法(什麼樣的對象算是可回收對象,可達性分析),CMS收集器
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(是一款並行與並發收集器,並且可建立可預測的停頓時間模型,整體上是基於標記清理,局部採用複製)
3.JVM分為哪些區,每一個區幹嗎的?
1)方法區(method):被所有的執行緒共用。方法區包含所有的類別資訊和靜態變數。
2)堆(heap):被所有的執行緒共享,存放物件實例以及數組,Java堆是GC的主要區域。
3)堆疊(stack):每個執行緒包含一個堆疊區,堆疊中保存一些局部變數等。
4)程式計數器:是目前執行緒執行的字節碼的行指示器。
4.JVM新生代,老年代,持久代,都儲存哪些東西?
持久代主要存放的是Java類別的類別訊息,與垃圾收集要收集的Java物件關係不大。所有新生成的物件首先都是放在年輕代的,年老代中存放的都是一些生命週期較長的物件。
5.記憶體溢位與記憶體洩漏:
記憶體溢位:程式申請記憶體時,沒有足夠的記憶體,out of memory;記憶體洩漏值垃圾物件無法回收,可以使用memory analyzer工具查看洩漏。
6.進程與執行緒:
進程值運行中的程式(獨立性,動態性,並發性),執行緒指進程中的順序執行流。差別是:1.進程間不共享記憶體 2.創建進程進行資源分配的代價要大得多,所以多執行緒在高並發環境中效率高。
7.序列化與反序列化:
序列化指將java物件轉換為位元組序列,反序列化相反。主要是為了java線程間通訊,實現物件傳遞。只有實作了Serializable或Externalizable介面類別物件才可被序列化。
8.64 位元 JVM 中,int 的長度是多數?
Java 中,int 型別變數的長度是固定值,與平台無關,都是 32 位元。意思是說,在 32 位元 和 64 位元 的Java 虛擬機器中,int 類型的長度是相同的。
9.Java 中 WeakReference 與 SoftReference的差異?
Java中一共有四種類型的引用。 StrongReference、 SoftReference、 WeakReference 以及 PhantomReference。
StrongReference 是Java 的預設參考實作, 它會盡可能長時間的存活於JVM 內,當沒有任何物件指向它時將會被GC回收
WeakReference,顧名思義, 是一個弱引用, 當所引用的物件在
JVM 內不再有強引用時, 將被GC回收
雖然WeakReference 與SoftReference 都有利於提高GC 和記憶體的效率,但是WeakReference ,一旦失去最後一個強引用,就會被GC 回收,而SoftReference 會盡可能長的保留引用直到JVM 內存不足時才會被回收(虛擬機保證), 這一特性使得
SoftReference 非常適合快取應用
10.解釋Java 堆空間及GC?
當透過 Java 指令啟動
Java 進程的時候,會為它分配記憶體。記憶體的一部分用於創建堆空間,當程式中創建物件的時候,就從對空間中分配記憶體。 GC 是 JVM 內部的一個進程,回收無效物件的記憶體用於將來的分配。
11.Java 中堆疊和堆疊有什麼不同?
JVM 中堆疊和堆疊屬於不同的記憶體區域,使用目的也不同。棧常用於保存方法幀和局部變量,而物件總是在堆上分配。棧通常都比堆小,也不會在多個執行緒之間共享,而堆被整個 JVM 的所有執行緒共享。
並發,鎖定
1.volatile關鍵字,在 Lock
並發程式設計中:原子性問題,可見性問題,有序性問題。
volatile關鍵字能保證可見性,字能禁止指令重排序,但是不能保證原子性。可見性只能保證每次讀取的是最新的值,但是volatile沒辦法保證對變數的操作的原子性。在產生的會變語句中加入Lock關鍵字和記憶體屏障。
Lock 實作提供了比使用synchronized 方法和語句可獲得的更廣泛的鎖定操作,它能以更優雅的方式處理線程同步問題。用sychronized修飾的方法或語句塊在程式碼執行完之後鎖自動釋放,而用Lock需要我們手動釋放鎖定
2.MYSQL常用優化(sql優化,表結構優化等)
SQL最佳化、表機構最佳化、索引最佳化、快取參數最佳化
3.java每改一點都需要重新編譯打包部署,有沒有更好的方法
可以使用熱載入
4.進程間通訊有哪幾種方式?
1)管道(Pipe),2)命名管道(named pipe),3)訊號(Signal),4)訊息(Message)佇列,5)共享內存,6)記憶體映射( mapped memory),7)信號量(semaphore),8)套介面(Socket)
5.Sychronized修飾靜態方法,鎖定類別本身而不是實例,非靜態方法鎖定實例。
6. 作業系統在什麼情況下會死鎖?
所謂死鎖:是指多個行程在運作過程中因爭奪資源而造成的一種僵局。產生的原因:競爭資源:當系統中多個進程使用共享資源,且資源不足以滿足需要,會造成進程對資源的競爭而產生死鎖。進程間推進的順序非法:請求和釋放資源的順序不當,也同樣會導致產生進程死鎖
7.產生死鎖的四個條件:
#1.互斥條件(進程獨佔資源)2.請求與保持(進程因請求資源而阻塞時,對已獲得的資源保持不放) 3.不剝奪條件(進程已獲得的資源,在末使用完之前,不能強行剝奪) 4.循環等待(若干進程之間形成一種頭尾相接的循環等待資源關係)
8. 如何理解分散式鎖定?
由於在平時的工作中,線上伺服器是分散式多台部署的,經常會面臨解決分散式場景下資料一致性的問題,那麼就要利用分散式鎖定來解決這些問題。
9. 執行緒同步與阻塞的關係?同步一定阻塞嗎?阻塞一定同步嗎?
執行緒同步與否 跟 阻塞非阻塞沒關係,同步是個過程,阻塞是執行緒的一種狀態。多個執行緒操作共享變數時可能會出現競爭。這時需要同步來防止兩個以上的執行緒同時進入臨界區內,在這個過程中後進入臨界區的執行緒將會阻塞,等待先進入的執行緒走出臨界區。
10. 同步和非同步有什麼不同?
同步和非同步最大的差別就在於。一個需要等待,一個不需要等待。同步可以避免出現死鎖,讀取髒數據的發生,一般共享某一資源的時候用,如果每個人都有修改權限,同時修改一個文件,有可能使一個人讀取另一個人已經刪除的內容,就會出錯,同步就會依照順序來修改。
11. 執行緒池
根據系統本身的環境情況,有效的限制執行緒的數量,使得運行效果達到最佳。執行緒主要是透過控制執行的執行緒的數量,超出數量的執行緒排隊等候,等待有任務執行完畢,再從佇列最前面取出任務執行
12. 如何呼叫 wait()方法?使用 if 區塊還是循環?為什麼?
wait() 方法應該在循環調用,因為當線程獲取到 CPU 開始執行的時候,其他條件可能還沒有滿足,所以在處理前,循環檢測條件是否滿足會更好。
wait(),notify()和notifyall()方法是java.lang.Object類別為執行緒提供的實作執行緒間通訊的同步控制方法。等待或喚醒
13. 實作執行緒的幾種方法
(1)繼承Thread類,重寫run函數
(2)實現Runnable接口,重寫run函數
(3)實作Callable接口,重寫call函數
14. 什麼是多執行緒環境下的偽共享(false sharing)?
偽共享是多執行緒系統(每個處理器有自己的局部快取)中一個眾所周知的效能問題。快取系統中是以快取行(cache line)為單位儲存的。快取行是2的整數冪個連續位元組,一般為32-256個位元組。最常見的快取行大小是64個位元組。當多執行緒修改互相獨立的變數時,如果這些變數共享同一個快取行,就會無意中影響彼此的效能,這就是偽共享。
網路、資料庫
1.TCP如何保證可靠傳輸?三次握手過程?
在TCP的連線中,資料流必須以正確的順序送達對方。 TCP的可靠性是透過順序編號和確認(ACK)來實現的。 TCP 連線是透過三次握手進行初始化的。三次握手的目的是同步連接雙方的序號和確認號並交換 TCP 視窗大小資訊。第一次是客戶端發起連線;第二次表示伺服器收到了客戶端的請求;第三次表示客戶端收到了伺服器的回饋。
2. Linux下你常用的指令有哪些?
1. cd指令用來改變所在目錄。 cd / 轉到根目錄中cd ~ 轉到使用者目錄下
2. ls指令用來查看目錄的內容。
3. cp指令用來拷貝檔案 cp
4.mv指令 mv t.txt Document 把檔案t.txt 移到目錄Document。
3. 常用的hash演算法有哪些?
1.加法hash:所謂的加法Hash就是把輸入元素一個一個的加起來構成最後的結果。
2.位元運算hash:這類型Hash函數透過利用各種位元運算(常見的是移位和異或)來充分的混合輸入元素
3.乘法hash:33 *hash key.charAt(i)
4. 什麼是一致性雜湊?
設計目標是為了解決因特網中的熱點(Hot spot)問題,一致性hash演算法提出了在動態變化的Cache環境中,判定哈希演算法好壞的四個定義:1 、平衡(Balance) 2、單調性(Monotonicity) 3、分散性(Spread) 4、負載(Load)
5. 資料庫中的範式有哪些?
第一範式----資料庫中的表(所有欄位值)都是不可分割的原子資料項。
第二範式----資料庫表中的每一列都和主鍵相關,而不能只和主鍵的某一部分相關。
第三範式----資料庫表中每一列資料都和主鍵直接相關,不能間接相關。範式是為了減小資料冗餘。
6. 資料庫中的索引的結構?什麼情況下適合建索引?
資料庫中索引的結構是一種排序的資料結構,資料庫索引是透過B樹和變形的B 樹實現的。什麼情況下不適合建立索引:1.對於在查詢過程中很少使用或參考的列;對於那些只有很少資料值的列;對於那些定義為image,text和bit資料類型的列;當修改效能遠大於檢索效能。
根據系統本身的環境狀況,有效的限制執行緒的數量,使得運行效果達到最佳。線程主要是透過控制執行的線程的數量,超出數量的線程排隊等候,等待有任務執行完畢,再從隊列最前面取出任務執行
7. concurrent包下面,都用過什麼?
java.util.concurrent、java.util.concurrent.atomic和java.util.concurrent.lock
8. 常用的資料庫有哪些? redis用過嗎?
MySQL、SQL Server、Oracle資料庫。
9. 你知道的開源協定有哪些?
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公共授權協議
10. 在表單提交中,get和post區別
1.get從伺服器取得訊息,post傳送訊息
2.get傳送資料量比較小,post可以比較大
3.get安全比較低
#11. TCP 協定與UDP 協定有什麼不同? (answer答案)
TCP(Tranfer Control Protocol)的縮寫,是一種面向連接的保證傳輸的協議,在傳輸資料流前,雙方會先建立一條虛擬的通訊道。可以很少差錯傳輸資料。
UDP(User DataGram Protocol)的縮寫,是一種無連接的協議,使用UDP傳輸資料時,每個資料段都是一個獨立的信息,包括完整的來源位址和目的地,在網路上以任何可能的路徑傳到目的地,因此,能否到達目的地,以及到達目的地的時間和內容的完整性都不能保證。
所以TCP必UDP多了建立連線的時間。相對UDP而言,TCP具有更高的安全性和可靠性。
TCP協議傳輸的大小不限制,一旦連接被建立,雙方可以按照一定的格式傳輸大量的數據,而UDP是一個不可靠的協議,大小有限制,每次不能超過64K
以上是2020年JAVA最常見面試題彙總(收藏)的詳細內容。更多資訊請關注PHP中文網其他相關文章!