JAVA中級開發應該掌握的小知識點


一.悲觀鎖、樂觀鎖的區別:

悲觀鎖:一段執行邏輯加上悲觀鎖,不同線程同時執行,只有一個線程可以執行,其他線程在入口處等待,直到鎖被釋放。
樂觀鎖:一段執行邏輯加上樂觀鎖,不同線程同時執行,可以同時進入執行,在最后跟新數據時候檢查這些數據是否被其他線程修改,
版本和執行初是否相同),沒有修改進行跟新,有就放棄這次操作。
//0.開始事務
begin;/begin work;/start transaction; (三者選一就可以)
//1.查詢出商品信息
select status from t_goods where id=1 for update;
//2.根據商品信息生成訂單
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status為2
update t_goods set status=2;
//4.提交事務
commit;/commit work;


1.查詢出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根據商品信息生成訂單
3.修改商品status為2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};


 

二.mysql的優化:

1.盡量避免全表查詢,在where和order by 后面建立索引

2.盡量避免where條件后面使用!=和<>的操作符,否則會引起引擎放棄索引而走全表查詢

3.盡量使用數字型字段,不要設計為字符型字段,,這樣會降低查詢和鏈接性能,並會增加存儲開銷
這是因為引擎在處理查詢和鏈接時候會逐個比較字符串中每個字符,而數字型而言只需要一次


 

三.線程池:

在初始化一個多線程程序中創建的一個線程集合,然后在需要執行新的任務時候重用這些線程而不是新建一個線程。

好處:
1、線程池改進了一個應用程序的響應時間。由於線程池中的線程已經准備好且等待被分配任務,應用程序可以直接拿來使用而不用新建一個線程。

2、線程池節省了CLR 為每個短生存周期任務創建一個完整的線程的開銷並可以在任務完成后回收資源。

3、線程池根據當前在系統中運行的進程來優化線程時間片。

4、線程池允許我們開啟多個任務而不用為每個線程設置屬性。

5、線程池允許我們為正在執行的任務的程序參數傳遞一個包含狀態信息的對象引用。

6、線程池可以用來解決處理一個特定請求最大線程數量限制問題。


 

四.JVM里面的概念:

1、Java虛擬機棧:

線程私有;每個方法在執行的時候會創建一個棧幀,存儲了局部變量表,操作數棧,動態連接,方法返回地址等;每個方法從調用到執行完畢,
對應一個棧幀在虛擬機棧中的入棧和出棧。

2、堆:
線程共享;被所有線程共享的一塊內存區域,在虛擬機啟動時創建,用於存放對象實例。

3、方法區:
線程共享;被所有線程共享的一塊內存區域;用於存儲已被虛擬機加載的類信息,常量,靜態變量等。

4、程序計數器:
線程私有;是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱為“線程私有”的內存。

5、本地方法棧:
線程私有;主要為虛擬機使用到的Native方法服務。


 

五.TCP三次握手

TCP三次握手:
三次握手就是建立一個TCP連接,里面客戶端和服務端總共發3個包以確定連接的建立。在socket編程中由客戶端執行
connect來觸發。

TCP三次握手.png
(1)第一次握手:Client將標志位SYN置為1,隨機產生一個值seq=J,並將該數據包發送給Server,Client進入SYN_SENT狀態,
等待Server確認。

(2)第二次握手:Server收到數據包后由標志位SYN=1知道Client請求建立連接,Server將標志位SYN和ACK都置為1,ack=J+1,
隨機產生一個值seq=K,並將該數據包發送給Client以確認連接請求,Server進入SYN_RCVD狀態。

(3)第三次握手:Client收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK置為1,ack=K+1,並將該數據
包發送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態,
完成三次握手,隨后Client與Server之間可以開始傳輸數據了。

簡單來說,就是

1、建立連接時,客戶端發送SYN包(SYN=i)到服務器,並進入到SYN-SEND狀態,等待服務器確認

2、服務器收到SYN包,必須確認客戶的SYN(ack=i+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器進入SYN-RECV狀態

3、客戶端收到服務器的SYN+ACK包,向服務器發送確認報ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,
完成三次握手,客戶端與服務器開始傳送數據。


 

六.TCP四次揮手.png

由於TCP連接時全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務后,發送一個FIN來終止這一方向
的連接,收到一個FIN只是意味着這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,
直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉,上圖描述的即是如此。

(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狀態,完成四次揮手。


七.Kafka、ActiveMQ、RabbitMQ、RocketMQ

一般的業務系統要引入 MQ,最早大家都用 ActiveMQ,但是現在確實大家用的不多了,沒經過大規模吞吐量場景的驗證,社區也不是很活躍,
所以大家還是算了吧,我個人不推薦用這個了;

后來大家開始用 RabbitMQ,但是確實 erlang 語言阻止了大量的 Java 工程師去深入研究和掌控它,對公司而言,幾乎處於不可控的狀態,
但是確實人家是開源的,比較穩定的支持,活躍度也高;

不過現在確實越來越多的公司會去用 RocketMQ,確實很不錯,畢竟是阿里出品,但社區可能有突然黃掉的風險(目前 RocketMQ
已捐給 Apache,但 GitHub 上的活躍度其實不算高)對自己公司技術實力有絕對自信的,推薦用 RocketMQ,否則回去老老實實用
RabbitMQ 吧,人家有活躍的開源社區,絕對不會黃。

所以中小型公司,技術實力較為一般,技術挑戰不是特別高,用 RabbitMQ 是不錯的選擇;大型公司,基礎架構研發實力較強,
用 RocketMQ 是很好的選擇。

如果是大數據領域的實時計算、日志采集等場景,用 Kafka 是業內標准的,絕對沒問題,社區活躍度很高,絕對不會黃,何況
幾乎是全世界這個領域的事實性規范。


 

八.HashMap源碼解析(jdk1.8):

HashMap結構在jdk1.2開始出現,一直到jdk1.7一直沒有太多變化,在1.8后有個大變化
jdk1.7:數組+鏈表(增刪效率高)
jdk1.8:數組+鏈表+紅黑(查詢效率也變快了)

紅黑樹只有在鏈表長度不小於8,而且數組長度不小於64才可以轉化為紅黑樹

什么是紅黑樹:一個自平衡的二叉查找樹,也就是說紅黑樹的查詢效率更高


九.單例模式:

懶漢式單例

public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public synchronized static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}

 

餓漢式單例:

public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getSingleton(){
return singleton;
}
}

 

Java Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。 使用Singleton的好處還在於可以節省內存,
因為它限制了實例的個數,有利於Java垃圾回收


十.sql中exists 和not exists用法:

exist:強調的是返回的結果集,而不要求知道返回的是什么(exists子句不在乎返回什么,而是在乎是不是有結果集返回)

exists 與 in 最大的區別在於 in引導的子句只能返回一個字段,比如:
select name from student where sex = 'm' and mark in (select 1,2,3 from grade where ...)

,in子句返回了三個字段,這是不正確的,exists子句是允許的,但in只允許有一個字段返回,在1,2,3中隨便去了兩個字段即可。


十一.SOA:SOA又叫服務治理,幫助我們把服務之間調用的系統治理起來

統一標准:各系統的協議、地址、交互方式。
新的交互方式:各個系統分別根據統一標准向數據總線進行注冊,各子系統調用其他子系統時,我們並不關心如果找到其他子系統,
我們只招數據總線,數據總線再根據統一標准找其他子系統,所以數據總線在這里充當一個只路人的作用。

SOA的好處:

1、降低用戶成本,用戶不需要關心各服務之間是什么語言的、不需要知道如果調用他們,只要通過統一標准找數據總線就可以了。

2、程序之間關系服務簡單

3、識別哪些程序有問題(掛掉)

缺點:提示了系統的復雜程度,性能有相應影響。

目前應用數據總線的有阿里的dubbo,還有zookeeper。

 


十二.Rest接口簡介:

  就是用URL定位資源,用HTTP動詞(GET,POST,DELETE,PUT)描述操作。

  REST 用來規范應用如何在 HTTP 層與 API 提供方進行數據交互 。REST 描述了 HTTP 層里客戶端和服務器端的數據交互規則;
  客戶端通過向服務器端發送 HTTP(s)請求,接收服務器的響應,完成一次 HTTP 交互。這個交互過程中,
  REST 架構約定兩個重要方面就是 HTTP 請求所采用的方法,以及請求的鏈接。

  在請求層面,REST 規范可以簡單粗暴抽象成以下兩個規則:

  請求 API 的 URL 表示用來定位資源。
  請求的 METHOD 表示對這個資源進行的操作。
  URL 用來定位資源,跟要進行的操作區分開,這就意味這 URL 不該有任何動詞。

  比如,我們有一個friends接口,對於“朋友”我們有增刪改查四種操作,怎么定義REST接口?
  增加一個朋友,uri: generalcode.cn/va/friends 接口類型:POST
  刪除一個朋友,uri: generalcode.cn/va/friends 接口類型:DELETE
  修改一個朋友,uri: generalcode.cn/va/friends 接口類型:PUT
  查找一個朋友,uri: generalcode.cn/va/friends 接口類型:GET

  上面我們定義的四個接口就是符合REST協議的,這幾個接口都沒有動詞,只有名詞friends,
  都是通過Http請求的接口類型來判斷是什么業務操作。定義這樣一套統一的接口,在web,ios,android三端都可以使用相同的接口,十分方便。



十三.Spring的五大神獸:

  服務發現——Netflix Eureka

  客服端負載均衡——Netflix Ribbon

  斷路器——Netflix Hystrix

  服務網關——Netflix Zuul

  分布式配置——Spring Cloud Config

  什么是熔斷?什么是服務降級?
  服務熔斷的作用類似於我們家用的保險絲,當某服務出現不可用或響應超時的情況時,為了防止整個系統出現雪崩,暫時停止對該服務的調用。

  服務降級是從整個系統的負荷情況出發和考慮的,對某些負荷會比較高的情況,為了預防某些功能(業務場景)
  出現負荷過載或者響應慢的情況,在其內部暫時舍棄對一些非核心的接口和數據的請求,而直接返回一個提前准備好的fallback
  (退路)錯誤處理信息。這樣,雖然提供的是一個有損的服務,但卻保證了整個系統的穩定性和可用性。

 

java高級面試題:
https://www.cnblogs.com/java1024/p/8594784.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM