1. 程式人生 > >阿里JAVA開發面試常問問題總結3

阿里JAVA開發面試常問問題總結3

Java集合類

Java的集合類都位於java.util包中,Java集合中存放的是物件的引用,而非物件本身。

Java集合主要分為三種類型:
1.Set(集):集合中的物件不按特定方式排序,並且沒有重複物件。它的有些實現類能對集合中的物件按特定方式排序。
2.List(列表):集合中的物件按索引位置排序,可以有重複物件,允許按照物件在集合中的索引位置檢索物件。
3.Map(對映):集合中的每一個元素包含一對鍵物件和值物件,集合中沒有重複的鍵物件,值物件可以重複。它的有些實現類能對集合中的鍵物件進行排序。
Set、List和Map統稱為Java集合。
List和Set都繼承Collection介面,而Map沒有繼承Collection介面。
List的主要實現類有:ArrayList類, LinkedList類, Vector類。
Set的主要實現類有:HashSet類,TreeSet類,LinkedHashSet類。
Map的主要實現類有:HashMap類,HashTable類,TreeMap類,WeekHashMap類和IdentityHahMap類等。

set和list的區別

1、List,Set都是繼承自Collection介面,均為介面
2、List特點:元素有放入順序,元素可重複
Set特點:元素無放入順序,元素不可重複(注意:元素雖然無放入順序,但是元素在set中的位置是有該元素的HashCode決定的,其位置其實是固定的)
3、List介面有三個實現類:LinkedList,ArrayList,Vector ;
Set介面有兩個實現類:HashSet(底層由HashMap實現), LinkedHashSet。

Hibernate中java的物件狀態

在Hibernate中,物件有三種狀態:臨時狀態、持久狀態和遊離狀態。

臨時狀態:當new一個實體物件後,這個物件處於臨時狀態,即這個物件只是一個儲存臨時資料的記憶體區域,如果沒有變數引用這個物件,則會被jre垃圾回收機制回收。這個物件所儲存的資料與資料庫沒有任何關係,除非通過Session的save或者SaveOrUpdate把臨時物件與資料庫關聯,並把資料插入或者更新到資料庫,這個物件才轉換為持久物件。

持久狀態:持久化物件的例項在資料庫中有對應的記錄,並擁有一個持久化表示(ID)。對持久化物件進行delete操作後,資料庫中對應的記錄將被刪除,那麼持久化物件與資料庫記錄不再存在對應關係,持久化物件變成臨時狀態。持久化物件被修改變更後,不會馬上同步到資料庫,直到資料庫事務提交。在同步之前,持久化物件是髒的(Dirty)。

遊離狀態:當Session進行了Close、Clear或者evict後,持久化物件雖然擁有持久化識別符號和與資料庫對應記錄一致的值,但是因為會話已經消失,物件不在持久化管理之內,所以處於遊離狀態(也叫:脫管狀態)。遊離狀態的物件與臨時狀態物件是十分相似的,只是它還含有持久化標識。

資料庫事務的特性

資料庫事務(Transaction)是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。一方面,當多個應用程式併發訪問資料庫時,事務可以在應用程式間提供一個隔離方法,防止互相干擾。另一方面,事務為資料庫操作序列提供了一個從失敗恢復正常的方法。
事務具有四個特性:原子性(Atomicity)、一致性(Consistency)、隔離型(Isolation)、永續性(Durability),簡稱ACID。
1 原子性(Atomicity)
事務的原子性是指事務中的操作不可拆分,只允許全部執行或者全部不執行。
2 一致性(Consistency)
事務的一致性是指事務的執行不能破壞資料庫的一致性,一致性也稱為完整性。一個事務在執行後,資料庫必須從一個一致性狀態轉變為另一個一致性狀態。
3 隔離性(Isolation)
事務的隔離性是指併發的事務相互隔離,不能互相干擾。
4 永續性(Durability)
事務的永續性是指事務一旦提交,對資料的狀態變更應該被永久儲存。

資料庫事務隔離級別及鎖機制

為了平衡隔離效能,SQL92規範定義了四個事務隔離級別:讀未提交(Read Uncommitted)、讀已提交(Read Committed)、可重複讀(Repeatable Read)、序列化(Serializable)。四個級別逐漸增強,每個級別解決上個級別的一個問題。
1 讀未提交(Read Uncommitted)
另一個事務修改了資料,但尚未提交,而本事務中的select會讀到這些未被提交的資料(也稱髒讀)。
2 讀已提交(Read Committed)
本事務讀取到的是最新的資料(其他事務提交後的)。問題是,在同一個事務裡,前後兩次相同的select會讀到不同的結果(不可重複讀)。
不可重複讀是指同一個事務執行過程中,另外一個事務提交了新資料,因此本事務先後兩次讀到的資料結果會不一致。
3 可重複讀(Repeatable Read)
在同一個事務裡,select的結果是事務開始時間點的狀態,同樣的select操作讀到的結果會是一致的。但是,會有幻讀現象。
不可重複讀保證了同一個事務裡,查詢的結果都是事務開始時的狀態(一致性)。但是,如果另一個事務同時提交了新資料,本事務再更新時,就會發現了這些新資料,貌似之前讀到的資料是幻覺,這就是幻讀。
4 序列化(Serializable)
所有事務只能一個接一個序列執行,不能併發。

隔離級別的選擇
事務隔離級別越高,越能保證資料的一致性,但對併發效能影響越大,一致性和高效能必須有所取捨或折中。
一般情況下,多數應用程式可以選擇將資料庫的隔離級別設定為讀已提交,這樣可以避免髒讀,也可以得到不錯的併發效能。儘管這個隔離級別會導致不可重複度、幻讀,但這種個別場合應用程式可以通過主動加鎖進行併發控制。

HTTP報文包含內容


http報文內容

TCP/IP三次握手和四次揮手

TCP是主機對主機層的傳輸控制協議,提供可靠的連線服務,採用三次握手確認建立一個連線:
位碼即tcp標誌位,有6種標示:SYN(synchronous建立聯機) ACK(acknowledgement 確認) PSH(push傳送) FIN(finish結束) RST(reset重置) URG(urgent緊急)
Sequence number(順序號碼) Acknowledge number(確認號碼)

三次握手

第一次握手:主機A傳送位碼為syn=1,隨機產生seq number=1234567的資料包到伺服器,主機B由SYN=1知道,A要求建立聯機;
第二次握手:主機B收到請求後要確認聯機資訊,向A傳送ack number=(主機A的seq+1),syn=1,ack=1,隨機產生seq=7654321的包
第三次握手:主機A收到後檢查ack number是否正確,即第一次傳送的seq number+1,以及位碼ack是否為1,若正確,主機A會再發送ack number=(主機B的seq+1),ack=1,主機B收到後確認seq值與ack=1則連線建立成功。
完成三次握手,主機A與主機B開始傳送資料。

四次揮手

所謂四次揮手(Four-Way Wavehand)即終止TCP連線,就是指斷開一個TCP連線時,需要客戶端和服務端總共傳送4個包以確認連線的斷開。在socket程式設計中,這一過程由客戶端或服務端任一方執行close來觸發,
(1)第一次揮手:Client傳送一個FIN,用來關閉Client到Server的資料傳送,Client進入FIN_WAIT_1狀態。
(2)第二次揮手:Server收到FIN後,傳送一個ACK給Client,確認序號為收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。
(3)第三次揮手:Server傳送一個FIN,用來關閉Server到Client的資料傳送,Server進入LAST_ACK狀態。
(4)第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接著傳送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手。

JVM記憶體

JVM 分配記憶體進入以下區域
1: Heap
2:Stack
3:Code
4:Static
jvm有效的管理分配到這幾個記憶體區域。
Code section 程式碼區 包含這個 位元組碼檔案 (byte code)
Stack section (棧區域) 包含 方法(methods) ,區域性變數 (Local variables) 和 引用變數( reference variables)
Heap section (堆區域)包含 物件 (也許會包含引用變數(下面的例子中有提到))
Static section (靜態區域) 包含 靜態資料/ 方法 (Static 資料 和 方法 為 類的方法,隸屬於類)
1:當一個方法被呼叫時, a frame 是被建立在 棧頂。
2:一旦方法完成執行,控制流返回正在呼叫的方法,stack 中 frame 被 清空(flushed)
3:區域性變數是在棧中建立。
4:例項變數在堆中建立, 是物件的一部分,例項變數 依附於物件。
5:引用變數是在棧中建立。
重點內容關於jvm特推薦一篇部落格如下:
http://blog.csdn.net/tonytfjing/article/details/44278233
再附一篇:
http://blog.csdn.net/u012152619/article/details/46968883

JVM垃圾回收

1.JVM的gc概述
  gc即垃圾收集機制是指jvm用於釋放那些不再使用的物件所佔用的記憶體。
  垃圾收集的目的在於清除不再使用的物件。gc通過確定物件是否被活動物件引用來確定是否收集該物件。gc首先要判斷該物件是否是時候可以收集。兩種常用的方法是引用計數和物件引用遍歷。
  1)引用計數
  引用計數儲存對特定物件的所有引用數,也就是說,當應用程式建立引用以及引用超出範圍時,jvm必須適當增減引用數。當某物件的引用數為0時,便可以進行垃圾收集。
  2)物件引用遍歷
  早期的jvm使用引用計數,現在大多數jvm採用物件引用遍歷。物件引用遍歷從一組物件開始,沿著整個物件圖上的每條連結,遞迴確定可到達(reachable)的物件。如果某物件不能從這些根物件的一個(至少一個)到達,則將它作為垃圾收集。在物件遍歷階段,gc必須記住哪些物件可以到達,以便刪除不可到達的物件,這稱為標記(marking)物件。
  下一步,gc要刪除不可到達的物件。刪除時,有些gc只是簡單的掃描堆疊,刪除未標記的物件,並釋放它們的記憶體以生成新的物件,這叫做清除(sweeping)。這種方法的問題在於記憶體會分成好多小段,而它們不足以用於新的物件,但是組合起來卻很大。因此,許多gc可以重新組織記憶體中的物件,並進行壓縮(compact),形成可利用的空間。
  為此,gc需要停止其他的活動活動。這種方法意味著所有與應用程式相關的工作停止,只有gc執行。結果,在響應期間增減了許多混雜請求。另外,更復雜的 gc不斷增加或同時執行以減少或者清除應用程式的中斷。有的gc使用單執行緒完成這項工作,有的則採用多執行緒以增加效率。
2.幾種垃圾回收機制
  1)標記-清除收集器
  這種收集器首先遍歷物件圖並標記可到達的物件,然後掃描堆疊以尋找未標記物件並釋放它們的記憶體。這種收集器一般使用單執行緒工作並停止其他操作。
  2)標記-壓縮收集器
  有時也叫標記-清除-壓縮收集器,與標記-清除收集器有相同的標記階段。在第二階段,則把標記物件複製到堆疊的新域中以便壓縮堆疊。這種收集器也停止其他操作。
  3)複製收集器
  這種收集器將堆疊分為兩個域,常稱為半空間。每次僅使用一半的空間,jvm生成的新物件則放在另一半空間中。gc執行時,它把可到達物件複製到另一半空間,從而壓縮了堆疊。這種方法適用於短生存期的物件,持續複製長生存期的物件則導致效率降低。
  4)增量收集器
  增量收集器把堆疊分為多個域,每次僅從一個域收集垃圾。這會造成較小的應用程式中斷。
  5)分代收集器
  這種收集器把堆疊分為兩個或多個域,用以存放不同壽命的物件。jvm生成的新物件一般放在其中的某個域中。過一段時間,繼續存在的物件將獲得使用期並轉入更長壽命的域中。分代收集器對不同的域使用不同的演算法以優化效能。
  6)併發收集器
  併發收集器與應用程式同時執行。這些收集器在某點上(比如壓縮時)一般都不得不停止其他操作以完成特定的任務,但是因為其他應用程式可進行其他的後臺操作,所以中斷其他處理的實際時間大大降低。
  7)並行收集器
  並行收集器使用某種傳統的演算法並使用多執行緒並行的執行它們的工作。在多cpu機器上使用多執行緒技術可以顯著的提高java應用程式的可擴充套件性。
  
  JVM垃圾回收器的工作原理
https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/

JVM調優

MVC的各個部分都由那些技術來實現?

MVC是Model-View-Controller的簡寫。
Model 代表的是應用的業務邏輯(通過JavaBean,EJB元件實現);View 是應用的表示面(由JSP頁面產生);
Controller 是提供應用的處理過程控制(一般是一個Servlet)。
通過這種設計模型把應用邏輯、處理過程和顯示邏輯分成不同的元件實現。這些元件可以進行互動和重用。

AOP:設計模式
IOC:反射機制

arrayList底層如何擴充套件的?

arraylist的java底層實現:

public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
arraylist的add方法底層實際就是一個數組,如果這個陣列滿了就將建立比舊陣列大的新陣列,然後複製舊陣列到新陣列中去 。

hashmap的實現

Servlet生命週期及工作原理

Servlet生命週期分為三個階段:
  1,初始化階段 :呼叫init()方法
  2,響應客戶請求階段:呼叫service()方法
  3,終止階段:呼叫destroy()方法
Servlet工作原理:
   Servlet接收和響應客戶請求的過程:首先客戶傳送一個請求,Servlet是呼叫service()方法對請求進行響應的,通過 原始碼可見,service()方法中對請求的方式進行了匹配,選擇呼叫doGet,doPost等這些方法,然後再進入對應的方法中呼叫邏輯層的方法, 實現對客戶的響應。

在Servlet介面和GenericServlet中是沒有doGet、doPost等這些方法的,HttpServlet中定義 了這些方法,但是都是返回error資訊,所以,我們每次定義一個Servlet的時候,都必須實現doGet或doPost等這些方法。
每一個自定義的Servlet都必須實現Servlet的介面,Servlet介面中定義了五個方法,其中比較重要的三個方法涉及到Servlet的生命週期,分別是上文提到的init()、service()、destroy()方法。GenericServlet是一個通用的,不特定於任何協議的 Servlet,它實現了Servlet介面。而HttpServlet繼承於GenericServlet,因此HttpServlet也實現了 Servlet介面。所以我們定義Servlet的時候只需要繼承HttpServlet即可。
Servlet介面和 GenericServlet是不特定於任何協議的,而HttpServlet是特定於HTTP協議的類,所以HttpServlet中實現了 service()方法,並將請求ServletRequest,ServletResponse強轉為HttpRequest和 HttpResponse。