Java面試
執行緒池
首先要明確為什麼要使用執行緒池,使用執行緒池會帶來什麼好處?
• 執行緒是稀缺資源,不能頻繁的建立。
• 應當將其放入一個池子中,可以給其他任務進行復用。
• 解耦作用,執行緒的創建於執行完全分開,方便維護。
執行緒池是一種多執行緒處理形式,處理過程中將任務提交到執行緒池,任務的執行交由執行緒池來管理。
如果每個請求都建立一個執行緒去處理,那麼伺服器的資源很快就會被耗盡,使用執行緒池可以減少建立和銷燬執行緒的次數,每個工作執行緒都可以被重複利用,可執行多個任務。
抽象類與介面區別
1.抽象類可以有構造方法,介面中不能有構造方法。
2.抽象類中可以有普通成員變數,介面中沒有普通成員變數!!!!!!!(注意重點在 普通 即 非靜態 和 變數!!!!)
3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。
悲觀鎖和樂觀鎖使用場景
樂觀鎖是在應用層加鎖,而悲觀鎖是在資料庫層加鎖(for update)
樂觀鎖顧名思義就是在操作時很樂觀,這資料只有我在用,我先儘管用,最後發現不行時就回滾。
悲觀鎖在操作時很悲觀,生怕資料被其他人更新掉,我就先將其先鎖住,讓別人用不了,我操作完成後再釋放掉。
悲觀鎖需要資料庫級別上的的實現,程式中是做不到的,如果在長事務環境中,資料會一直被鎖住,導致併發效能大大地降低。
一般來說如果併發量很高的話,建議使用悲觀鎖,否則的話就使用樂觀鎖。
如果併發量很高時使用樂觀鎖的話,會導致很多的併發事務回滾、操作失敗。
總之,衝突機率大用悲觀,小就用樂觀。
樂觀鎖不會發生併發搶佔資源
在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會產生衝突。這就是著名的併發性問題。
1.悲觀鎖:指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態
2.樂觀鎖:假設不會發生併發衝突,只在提交操作時檢查是否違反資料完整性。樂觀鎖不能解決髒讀的問題。
執行緒安全就是多執行緒訪問時,採用了加鎖機制,當一個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用。不會出現資料不一致或者資料汙染。
執行緒不安全就是不提供資料訪問保護,有可能出現多個執行緒先後更改資料造成所得到的資料是髒資料。
死鎖和髒資料就是典型的執行緒安全問題。
簡單來說,執行緒安全就是: 在多執行緒環境中,能永遠保證程式的正確性。
只有存在共享資料時才需要考慮執行緒安全問題。
多執行緒會引出很多難以避免的問題, 如死鎖,髒資料,執行緒管理的額外開銷,等等。更大大增加了程式設計的複雜度。
在Java 8 中,如果一個桶中的元素個數超過 TREEIFY_THRESHOLD(預設是 8 ),就使用紅黑樹來替換連結串列
java記憶體區域:
hashmap
key value
初始化容量 1左移4位16容量 2的4次方
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
載入因子係數
1分成4等分0.25 0.25*3=0.75 在容量的3/4(0.75)的時候擴容
static final float DEFAULT_LOAD_FACTOR = 0.75f;
HashMap和Hashtable的區別
HashMap沒有考慮同步,是執行緒不安全的;Hashtable使用了synchronized關鍵字,是執行緒安全的
前者允許null作為key,後者不允許null作為key
從ConcurrentHashMap程式碼中可以看出,它引入了一個“分段鎖”的概念,具體可以理解為把一個大的Map拆分成N個小的HashTable,根據key.hashCode()來決定把key放到哪個HashTable中。
在ConcurrentHashMap中,就是把Map分成了N個Segment,put和get的時候,都是現根據key.hashCode()算出放到哪個Segment中,ConcurrentHashMap中預設是把segments初始化為長度為16的陣列。通過把整個Map分為N個Segment(類似HashTable),可以提供相同的執行緒安全,但是效率提升N倍,預設提升16倍。
HashMap的底層實現
Java8之前,其底層實現是陣列+連結串列實現,Java8使用了陣列+連結串列+紅黑樹實現
ConcurrentHashMap的具體實現
1、該類包含兩個靜態內部類HashEntry(節點)和Segment(桶);前者用來封裝對映表的鍵值對,後者用來充當鎖的角色
List有序 可以重複 set無序不可以重複
ArrayList的初始容量10 載入因子0.5
Vector的初始容量10 載入因子1
HashSet的初始容量為16,載入因子0.75
HashMap的初始容量為16,載入因子0.75 擴容增量:原容量的1倍
資料庫索引原理
索引原理必須清楚一種資料結構「平衡樹」(非二叉),也就是b tree或者 b+ tree,重要的事情說三遍:“平衡樹,平衡樹,平衡樹”。當然, 有的資料庫也使用雜湊桶作用索引的資料結構 , 然而, 主流的RDBMS都是把平衡樹當做資料表預設的索引資料結構的。
執行緒和程序的區別
1、程序是一個“執行中的程式”,是系統進行資源分配和排程的一個獨立單位;
2、執行緒是程序的一個實體,一個程序中擁有多個執行緒,執行緒之間共享地址空間和其它資源
volatile關鍵字
該關鍵字可以保證可見性不保證原子性
ThreadLocal關鍵字
當使用ThreadLocal維護變數時,其為每個使用該變數的執行緒提供獨立的變數副本,所以
每一個執行緒都可以獨立的改變自己的副本,而不影響其他執行緒對應的副本
執行緒池
java.util.concurrent.ThreadPoolExecutor類就是一個執行緒池。客戶端呼叫
ThreadPoolExecutor.submit(Runnabletask)提交任務
JVM劃分
1、方法區:常量、靜態變數、即時編譯器
2、堆記憶體:垃圾回收的主要場所
3、程式計數器
4、虛擬機器棧(棧記憶體):儲存區域性變數、基本資料型別變數以及堆記憶體中某個物件的引用變數
5、本地方法棧
垃圾回收演算法有哪些
1、引用計數
2、標記-清除 分兩個階段 第一階段從引用根節點開始標記所有被引用的物件,第二階段遍歷整個堆,把未標記的物件清除。
GC經常發生的區域是堆區,堆區還可以細分為新生代、老年代、
記憶體溢位 記憶體洩露是導致記憶體溢位的原因之一
NIO和IO的主要區別
IO 面向流 阻塞IO
NIO 面向緩衝區 非阻塞IO 選擇器 選擇一個通道
雙親委派模型
(1).BootStrap ClassLoader:啟動類載入器,負責載入存放在%JAVA_HOME%lib目錄中的
(2).Extension ClassLoader:擴充套件類載入器,由sun.misc.Launcher$ExtClassLoader實現,負責載入%JAVA_HOME%libext目錄中的
(3).Application ClassLoader:應用程式類載入器,由sun.misc.Launcher$AppClassLoader實現,負責載入使用者類路徑classpath上所指定的類庫
Java8新特性
1、Lambda表示式允許我們將函式當成引數傳遞給某個方法
2、函式式介面@Functionallnterface來標明該介面是一個函式式介面
3、引入重複註解@Repeatable
4、介面中可以實現方法default方法
5、註解的使用場景拓寬
6、新的包java.time包
dubbo
Provider在容器裡面進行啟動,啟動之後往服務中心進行服務一個註冊,然後Consume訂閱之前註冊過的服務,如果服務發生改變註冊中心會通知Consume,Consume拿到訂閱關係之後就直接invoke呼叫Provider同時有個Monitor監控他們的呼叫情況
會員中心呼叫訂單中心
訂單需要提供一個介面給會員呼叫
Consumer:192.168.0-.192/com.tl.IOrderService?application=UserCp
資料庫索引作用 底層資料結構 為什麼使用這種結構
索引 是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊
底層資料結構B+樹
使用B+樹的原因:查詢速度快,效率高,
聚集索引和非聚集索引根本區別
是表記錄的排列順序和與索引的排列順序是否一致
聚集索引表記錄的排列順序和索引的排列順序一致
非聚集索引制定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致
MyISAM和InnoDB的區別
MyISAM不支援事務,InnoDB是事務型別的儲存引擎
MyISAM只支援表級鎖InnoDB支援行級鎖和表級鎖
MyISAM不支援外來鍵InnoDB支援外來鍵
MyISAM支援全文索引InnoDB不支援
MyISAM表不支援事務、不支援行級鎖、不支援外來鍵
InnoDB表支援事務、支援行級鎖、支援外來鍵
Spring 知識點
Spring 的 IOC 和 AOP
• IOC:控制反轉,(解耦合)將物件間的依賴關係交給 Spring 容器,使用配置檔案來建立所依賴的物件,由主動建立物件改為了被動方式;
• AOP:面向切面程式設計,將功能程式碼從業務邏輯程式碼中分離出來;
AOP 的實現方式有哪幾種?如何選擇?
JDK 動態代理實現和 cglib 實現
選擇:
- 如果目標物件實現了介面,預設情況下會採用 JDK 的動態代理實現 AOP,也可以強制使用 cglib 實現 AOP;
- 如果目標物件沒有實現介面,必須採用 cglib 庫,Spring 會自動在 JDK 動態代理和 cglib 之間轉換。
擴充套件:JDK 動態代理如何實現
JDK 動態代理,只能對實現了介面的類生成代理,而不是針對類,該目標型別實現的介面都將被代理。
原理是通過在執行期間建立一個介面的實現類來完成對目標物件的代理
Mybatis 知識點
關於 MyBatis 主要考察佔位符#和 $ 的區別,區別如下:
-
符號將傳入的資料都當做一個字串,會對自動傳入的資料加一個雙引號;
- $ 符號將傳入的資料直接顯示生成 SQL 中;
-
符號存在預編譯的過程,對問號賦值,防止 SQL 注入;
- $符號是直譯的方式,一般用在 order by ${列名}語句中;
- 能用#號就不要用 $ 符號
Linux常用命令
檔案和目錄:
pwd 顯示當前目錄
ls 顯示當前目錄下的檔案和目錄:
- ls -F 可以區分檔案和目錄;
- ls -a 可以把隱藏檔案和普通檔案一起顯示出來;
- ls -R 可以遞迴顯示子目錄中的檔案和目錄;
- ls -l 顯示長列表
- ls -l test 過濾器,檢視某個特定檔案資訊。可以只檢視 test 檔案的資訊
處理檔案方面的命令有:touch、cp、 In、mv、rm
處理目錄方面的命令:mkdir
檢視檔案內容:file、cat、more、less、tail、head
eg. 找出程序名中包括 java 的所有程序:ps -ef | grep java
top 命令 實時監測程序
壓縮資料
- tar -xvf 檔名
- tar -zxvf 檔名
- tar -cvzf 檔名
結束程序:kill PID 或者 kill all