Java基礎面試(一)
Java基礎
1、Java中的幾種基本資料型別是什麼,各自佔用多少個位元組。
Boolean(1位,只有true和false)、byte(8位,1位元組)、char(16位,2位元組)、short(16位,2位元組)、int(32位,4位元組)、long(64位,8位元組)、float(32位,4位元組)、double(64位,8位元組)。
long型整數在記憶體中佔用8位元組共64位,它表示的數值有2的64次方,平分正負,數值範圍是-2^63~2^63-1。
而float在記憶體中佔4位元組32位。數值表示為:
2、String類能被繼承嗎,為什麼。
不能,public final class String { }。
3、Array List和LinkedList的區別。
(1)ArrayList是基於動態陣列實現的,LinkedList是基於連結串列的資料結構。
(2)相對於Array List,LinkedList插入更快,因為LinkedList不像ArrayList一樣,不需要改變陣列大小,也不需要在陣列裝滿時將所有資料重新裝入一個新的陣列,ArrayList插入最壞的時間複雜度是O(n),而LinkedList中插入或刪除的時間複雜度僅為O(1)。
(3)ArrayList是基於索引的資料結構,它使用索引在陣列中搜索和讀取更快,時間複雜度是O(1)。
4、IO模型有哪些,NIO是什麼。
5、中斷和異常是什麼?有什麼區別?
中斷是CPU暫停當前工作,有計劃的去處理其他的事情。系統停止當前正在執行的程式而轉向其他服務,可能是因為優先順序高的請求。中斷的發生一般是可以預知的,處理過程也是事先制定好的。處理中斷時程式是正常執行的。
異常是CPU遇到了無法響應的工作,而後進入一種非正常的狀態,異常的出現表明程式有缺陷。異常是軟體執行過程中的一種開發過程中沒有考慮到的程式錯誤。
中斷是CPU所具備的功能,屬於硬體層面。而異常屬於軟體層面。
6、虛擬記憶體和虛擬地址是什麼?
虛擬地址:程式訪問儲存器所使用的邏輯地址稱為虛擬地址,虛擬地址是4G虛擬地址空間中的地址程式中使用的都是虛擬地址。每一個程序都分配有一個4G的虛擬地址。通過虛擬地址訪問記憶體的形式稱為保護模式。
虛擬記憶體:通常是再系統實體記憶體用完時,才會使用到。所謂的虛擬記憶體其實就是記憶體的一種管理方式,實現對於邏輯上對於記憶體容量的擴充套件,使用硬碟(檔案)來模擬的記憶體空間。
資料結構(紅黑數、B+Tree)
1、synchronized的原理?
synchronized是Java中解決併發問題的一種常用方法,作用主要有3個:(1)確保執行緒互斥的訪問同步程式碼;(2)確保共享變數的修改能夠即時可見;(3)有效的解決重排序問題。
Java中每個物件都可以作為鎖,(1)普通同步方法,鎖是當前例項物件;(2)靜態同步方法,鎖是當前類的class物件;(3)同步方法塊,鎖是括號裡面的物件。
synchronized是通過一個monitor(監視器鎖)物件來完成。
同步指令執行到monitorenter時,(1)每個物件都有一個監視器鎖(monitor)。當monitor被佔用時就會處於鎖定狀態,執行緒執行monitorenter指令時嘗試獲取monitor的所有權,,過程如下:(1)如果monitor的進入數為0,則該執行緒進入monitor,然後將進入數設定為1,該執行緒即為monitor的所有者;(2)如果執行緒已經佔有了該monitor,只是重新進入,則進入monitor的進入數加1;(3)如果其他執行緒已經佔用了monitor,則該執行緒進入阻塞狀態,直到monitor的進入數為0,再重新嘗試獲取monitor的所有權。
同步指令執行到monitorexit時,執行monitor exit的執行緒必須是objectref所對應的monitor的所有者。指令執行時,monitor的進入數減1,如果減1後進入數為0,那執行緒退出monitor,不再是這個monitor的所有者,其他被這個monitor阻塞的執行緒可以嘗試去獲取這個monitor的所有權。
2、紅黑樹的定義?為什麼是平衡樹?怎麼維護平衡?
RB Tree又稱為紅黑樹,是一種特殊的二叉查詢樹,每個節點上的儲存位表示節點的顏色,可以是紅(Red)或黑(Black)。是通過旋轉保持平衡的。
紅黑樹的五個特性:
(1)每個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每個葉子節點是黑色(葉子節點指為空或null的葉子節點)。
(4)如果一個節點是紅色的,則它的兩個兒子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。
紅黑樹的時間複雜度為: O(lgn)
(1)左旋虛擬碼如下:
LEFT-ROTATE(T, x)
y ← right[x] // 前提:這裡假設x的右孩子為y。下面開始正式操作
right[x] ← left[y] // 將 “y的左孩子” 設為 “x的右孩子”,即 將β設為x的右孩子
p[left[y]] ← x // 將 “x” 設為 “y的左孩子的父親”,即 將β的父親設為x
p[y] ← p[x] // 將 “x的父親” 設為 “y的父親”
if p[x] = nil[T]
then root[T] ← y // 情況1:如果 “x的父親” 是空節點,則將y設為根節點
else if x = left[p[x]]
then left[p[x]] ← y // 情況2:如果 x是它父節點的左孩子,則將y設為“x的父節點的左孩子”
else right[p[x]] ← y // 情況3:(x是它父節點的右孩子) 將y設為“x的父節點的右孩子”
left[y] ← x // 將 “x” 設為 “y的左孩子”
p[x] ← y // 將 “x的父節點” 設為 “y”
(2)插入操作
①將紅黑樹當作一棵二叉查詢樹,將節點插入。紅黑樹本身是一棵二叉查詢樹,將節點插入後,仍然是一棵二叉查詢樹。
②將插入的節點著色為紅色。