主頁 > 後端開發 > Java 基礎面試題整理,希望也能幫到你

Java 基礎面試題整理,希望也能幫到你

2021-03-05 11:07:13 後端開發

目錄

1.談談對面向物件的理解?

2.Java語?和其他語?區別?

3.JRE、JDK、JVM區別?

4.什么是位元組碼?采?位元組碼的好處是什么?

5.配置classpath的作??

6.JDK1.8之前和JDK1.8之后介面不同?

7.介面和抽象類區別?

8.Java 應?程式與?程式之間有哪些差別?

9.Java中的常用容器有哪些?

10.執行緒和行程有什么區別?

11.final、finally、finalize區別,怎么使??

12.區域變數和成員變數的區別?

13.字符型常量和字串常量的區別?

14.構造器是否可被 重寫?

15.多載和重寫的區別?

16.聊一下?動裝箱與拆箱?

17.值傳遞和引?傳遞區別?

18.equals與==的區別?

19.Hashcode和equals的區別?

20.創建物件在JVM中的程序?

21.String 是最基本的資料型別嗎?

22.包裝類和基本類區別?如何互相轉換?

23.構造器代碼塊、區域代碼塊、靜態代碼塊執?順序和執?次數?

24.構造代碼塊的作??

25.Integer是否可以被繼承?為什么?

26.談談"abc" 和 new String("abc")區別?

27.、StringString StringBuffer 和 StringBuilder 的區別是什么?怎么做到執行緒安全?

28.講下java中的math類有那些常用方法?

29.JDK1.8之后有哪些新特性?

30.Java中深克隆和淺克隆的區別?如何實作物件克隆?

31.Comparable 和Comparator的區別,分別說出使?場景?

32.Object類和泛型的區別,說出范型的執?機制,為什么要使?范型?

33.Collection包結構,與Collections的區別 ?

34.HashMap 和Hashtable 的區別?

35.如何解決Hash沖突問題?

36.HashMap是如何實作自動擴容的?

37.談談ArrayList和linkedList的區別 ?

38.HashMap的底層原理?

39.說說List,Set,Map三者的區別?

40.執行緒創建4種方式?

41.并發和并行有什么區別?

42.為什么要使用執行緒池?

43.執行緒池的構造方法里幾個引數的作用分別都是什么?

44.什么是執行緒安全問題?如何解決執行緒安全問題?

45.談一談執行緒生命周期(狀態)?

47.sleep()和wait() 有什么區別?

48.談談JAVA的后臺執行緒?

49.你都知道哪些執行緒相關的基本方法?

50.請說出sql陳述句中 left join ,inner join 和right join的區別?

51.講一下JDBC操作流程?

52.資料庫連接池的作業機制?

53.Java 中常用的設計模式?說說工廠模式或者幾種比較熟悉的說一下?

54.char 型變數中能不能存盤一個中文漢字?為什么?

55.error 和exception 有什么區別?

56.Thow與thorws區別?

57.TCP與UDP的區別?

58.執行緒和行程的區別?

59.什么是反射?

60.什么是java序列化,如何實作java序列化?

61.動態代理是什么?有哪些應用?

62.說一下 JVM 的主要組成部分?及其作用?

63.說一下堆疊的區別?

64.什么是雙親委派模型?

65.怎么判斷物件是否可以被回收?

66.你知道哪些JVM性能調優?

67.你知道的垃圾收集演算法?還有其底層原理

68.什么情況下會出現堆記憶體溢位?

69.什么是類加載器?及類加載器的分類?

70.說一下類加載的執行程序?

71.簡單的介紹?下強引?,軟引?,弱引?,虛引??

72.什么是死鎖?死鎖產生的原因?怎么防止死鎖?


1.談談對面向物件的理解?

答:在我理解,面向物件是向現實世界模型的自然延伸,這是一種“萬物皆物件”的編程思想,在現實生活中的任何物體都可以歸為一類事物,而每一個個體都是一類事物的實體,面向物件的編程是以物件為中心,以訊息為驅動,所以程式=物件+訊息

說到面向物件就不得不提,他的三大特性,封裝繼承多型

  • 封裝就是將一類事物的屬性和行為抽象成一個類,使其屬性私有化,行為公開化,提高了資料的隱秘性的同時,使代碼模塊化,這樣做使得代碼的復用性更高
  • 繼承則是進一步將一類事物共有的屬性和行為抽象成一個父類,而每一個子類是一個特殊的父類--有父類的行為和屬性,也有自己特有的行為和屬性,這樣做擴展了已存在的代碼塊,進一步提高了代碼的復用性
  • 如果說封裝和繼承是為了使代碼重用,那么多型則是為了實作介面重用,簡單來說,多型就是允許父類參考(或介面)指向子類(或實作類)物件,

2.Java語?和其他語?區別?

答:這就得從java語言的特點說起了,1.?處編譯,多處運?(Java 虛擬機實作平臺?關性),2.?帶記憶體管理機制,3.?持多執行緒(C++ 語?沒有內置的多執行緒機制,因此必須調?作業系統的多執行緒功能來進?多執行緒程式設計),4.屬于解釋型語言(C語言是編譯型語言,C中有指標的概念,java取消了指標的概念)

3.JRE、JDK、JVM區別?

答:首先看他們各自的概念:

JVM:Java 虛擬機,是運? Java 位元組碼的虛擬機,JVM 有針對不同系統的特定實作(Windows,Linux,macOS),?的是使?相同的位元組碼,它們都會給出相同的結果

JRE: 運?時環境,它是運?已編譯 Java 程式所需的所有內容的集合,包括 Java 虛擬機(JVM),Java 類別庫,java 命令和其他的?些基礎構件,

JDK:是功能?全的 Java SDK,它擁有 JRE 所擁有的?切,還有編譯器(javac)和?具(如 javadoc 和 jdb),它能夠創建和編譯程式,

簡單理解:JDK=JRE(包含JVM+核心類別庫(JavaAPI))+開發工具

4.什么是位元組碼?采?位元組碼的好處是什么?

答:在 Java 中,JVM 可以理解的代碼就叫做 位元組碼 (即擴展名為 .class 的?件),它不?向任何特定的處理器,只?向虛擬機

Java 語?通過位元組碼的?式,在?定程度上解決了傳統解釋型語?執?效率低的問題,同時?保留了解釋型語?可移植的特點

5.配置classpath的作??

答:這是java系統環境變數,我們編譯.java是通過javac命令來實作,運?是通過java來實作,這2個命令是在JDK包中存放的,如果我們的.java?件不放在javac命令所在的?錄下系統就會報找不到javac,配置classpath是為了在系統的任意?錄下都可以運?javac java命令

6.JDK1.8之前和JDK1.8之后介面不同?

答:先來回顧一下什么是介面,介面指系統對外提供的所有服務(Interface定義的實實在在的介面,即介面型別)【只能有抽象方法】 的入口,是一個抽象型別,一個類通過實作介面的方式,從而繼承介面的抽象方法一個類只能繼承一個類,但可以繼承多個介面一個介面不能實作另一個介面,但可以繼承多個其他介面

JDK1.8之前:

1.介面中的變數都是靜態變數(public static final),必須顯式初始化

2.介面中所有方法默認都是public abstract

3.介面沒有構造方法,不可以被實體化,但可以被實作(常作為型別使用,也就是父類參考指向子類物件)

4.實作類必須實作介面的所有的方法

5.實作類可以實作多個介面(java中的多繼承)

JDK1.8之后:

1.介面里可以有(default關鍵字修飾的)默認方法(方法體)

默認方法可以被繼承,通過實體呼叫,可以有多個,如果一個類實作了多個介面,多個介面都定義了多個同樣的默認方法時就需要實作類覆寫重寫介面中的默認方法,不然會報錯,可以使用super來呼叫指定介面的默認方法,

2.介面里可以宣告(并且可以提供實作)的靜態方法

介面中的靜態方法必須是public的,public修飾符可以省略,static修飾符不能省略,靜態方法不能被繼承即覆寫,所以只被具體所在的介面呼叫,介面中靜態方法可以有多個,

簡單來說:JDK1.8之前介面只能有抽象?法,JDK1.8之后介面中可以有不同?法,但是?法必須?static或者default來修飾

7.介面和抽象類區別?

答:相同點:都代表系統的抽象層;都不能被實體化;都能包含抽象方法(用于描述系統提供的服務,不必提供具體實作)

不同點:一個類只能繼承一個直接父類,但可以實作多個介面;

抽象類有構造器 介面沒有構造器;抽象類中可以有普通?法 介面中有沒有要區分JDK版本;

抽象類中成員變數??定義權限修飾 介面成員變數默認為public static final;

從設計層?來說,抽象是對類的抽象,是?種模板設計,?接?是對?為的抽象,是?種?為的規范

8.Java 應?程式與?程式之間有哪些差別?

答:簡單說應?程式是從主執行緒啟動(也就是 main() ?法),applet ?程式沒有 main() ?法,主要是嵌在瀏覽器??上運?(調? init() 或者 run() 來啟動)

9.Java中的常用容器有哪些?

答:資料容器主要分為了兩類,Collection:(存放獨立元素的序列)和Map(存放key-value型的元素對)常用的容器有:

ArrayList:其資料結構采用的是線性表,此種結構的優勢是訪問和查詢十分方便,但添加和洗掉的時候效率很低,

LinkedList :其資料結構采用的是鏈表,此種結構的優勢是洗掉和添加的效率很高,但隨機訪問元素時效率較ArrayList類低,

HashSet: Set類不允許其中存在重復的元素(集),無法添加一個重復的元素(Set中已經存在),HashSet利用Hash函式進行了查詢效率上的優化,其contain()方法經常被使用,以用于判斷相關元素是否已經被添加過

HashMap: 提供了key-value的鍵值對資料存盤機制,可以十分方便的通過鍵值查找相應的元素,而且通過Hash散列機制,查找十分的方便,

10.執行緒和行程有什么區別?

答: 什么是行程?

行程是程式的?次執?程序,是系統運?程式的基本單位,因此行程是動態的系統運??個程式即是?個行程從創建,運?到消亡的程序,在 Java 中,當我們啟動 main 函式時其實就是啟動了?個 JVM 的行程,? main 函式所在的執行緒就是這個行程中的?個執行緒,也稱主執行緒,

什么是執行緒?

執行緒與行程相似,但執行緒是?個?行程更?的執?單位,?個行程在其執?的程序中可以產?多個執行緒,與行程不同的是同類的多個執行緒共享行程的堆和?法區資源,但每個執行緒有??的程式計數器、虛擬機堆疊和本地?法堆疊,所以系統在產??個執行緒,或是在各個執行緒之間作切換?作時,負擔要?行程?得多,也正因為如此,執行緒也被稱為輕量級行程

兩者的區別?

地址空間:同一行程的執行緒共享本行程的地址空間,而行程之間則是獨立的地址空間

資源擁有:同一行程內的執行緒共享本行程的資源如記憶體、I/O、cpu等,但是行程之間的資源是獨立的,

執行程序:每個獨立的行程程有一個程式運行的入口、順序執行序列和程式入口,但是執行緒不能獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制,

執行緒是處理器調度的基本單位,但是行程是系統運?程式的基本單位,

11.final、finally、finalize區別,怎么使??

答: 區別:final 在java中他是一個關鍵字,可以用來修飾類,方法和變數(成員變數或區域變數),而finally例外處理陳述句結構的一部分,表示總是執行,finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,供垃圾收集時的其他資源回收,例如關閉檔案等;

final的使用:

1.修飾類:當用final修飾類的時,表明該類不能被其他類所繼承,final類中所有的成員方法都會隱式的定義為final方法

2.修飾方法:把方法鎖定,以防止繼承類對其進行更改,就是該方法不能被重寫

3.修飾變數:final成員變數表示常量,只能被賦值一次,賦值后其值不再改變,

finally的使用:用在try/catch陳述句中并且附帶著一個finally陳述句塊,表示這段陳述句最終總是被執行(不管有沒有拋出例外),經常被用在需要釋放資源的情況下,但注意finally陳述句塊并不一定會執行(遇到try/catch中有return就不執行)

finalize的使用:finalize()方法是在GC清理它所從屬的物件時被呼叫的,如果執行它的程序中拋出了無法捕獲的例外(uncaughtexception,GC將終止對改物件的清理,并且該例外會被忽略;直到下一次GC開始清理這個物件時,它的finalize()會被再次呼叫,

12.區域變數和成員變數的區別?

答:1.從語法形式上看:成員變數是屬于類的,?區域變數是在?法中定義的變數或是?法的引數;成員變數可以被 public,private,static 等修飾符所修飾,?區域變數不能被訪問控制修飾符及static 所修飾;但是,成員變數和區域變數都能被 final 所修飾,

2.成員變數如果沒有被賦初值:則會?動以型別的默認值?賦值(?種情況例外:被 final 修飾的
成員變數也必須顯式地賦值),?區域變數則不會?動賦值

3.從變數在記憶體中的?存時間上看:成員變數是物件的?部分,它隨著物件的創建?存在?區域變數隨著?法的調???動消失

4.從變數在記憶體中的存盤?式來看:如果成員變數是使? static 修飾的,那么這個成員變數是屬于類的,如果沒有使? static 修飾,這個成員變數是屬于實體的,物件存于堆記憶體,如果區域變數型別基本資料型別,那么存盤在堆疊記憶體,如果為引?資料型別,那存放的是指向堆記憶體物件的引?或者是指向常量池中的地址,

13.字符型常量和字串常量的區別?

答:分為三個方面

1.形式上: 字符常量是單引號引起的?個字符; 字串常量是雙引號引起的若?個字符

2.含義上: 字符常量相當于?個整型值( ASCII 值),可以參加運算式運算; 字串常量代表?個地址值(該字串在記憶體中存放位置)

3.占記憶體??:字符常量只占 2 個位元組; 字串常量占若?個位元組 (注意: char 在 Java 中占兩個位元組)

14.構造器是否可被 重寫?

答:Constructor 不能被 override(重寫),但是可以 overload(多載),所以你可以看到?個類中有多個建構式的情況,

15.多載和重寫的區別?

答:多載就是同樣的?個?法能夠根據輸?資料的不同,做出不同的處理,引數不同

重寫就是當?類繼承??類的相同?法,輸?資料?樣,但要做出有別于?類的回應時,你就要覆寫?類?法

16.聊一下?動裝箱與拆箱?

答:裝箱:將基本型別?它們對應的引?型別包裝起來;拆箱:將包裝型別轉換為基本資料型別;

17.值傳遞和引?傳遞區別?

答:java 都是參考傳遞,對于 基本資料型別,傳遞是值的副本 而不是值本身 對于物件型別,傳遞是物件的參考 ,當在一個方法操作操作引數的時候,其實操作的是參考所指向的物件,

18.equals==的區別?

答:==:== 比較的是變數(堆疊)記憶體中存放的物件的()記憶體地址,用來判斷兩個物件的地址是否相同,即是否是指相同一個物件,比較的是真正意義上的指標操作,

1、比較的是運算子兩端的運算元是否是同一個物件

2、兩邊的運算元必須是同一型別的(可以是父子類之間)才能編譯通過,

3 比較的是地址,如果是具體的阿拉伯數字的比較,值相等則為true ,如: int a=10 與 long b=10L double c=10.0 都是相同的(為 true ),因為他們都指向地址為 10 的堆,
equals: equals用來比較的是兩個物件的內容是否相等 ,由于所有的類都是繼承自 java.lang.Object 類的,所以 適用于所有物件,如果沒有對該方法進行覆寫的話,呼叫的仍然 Object 類中的方法,而 Object 中的 equals 方法回傳的卻是 == 的判斷,
所有比較是否相等時,都是用 equals 并且在對常量相比較時,把常量寫在前面,因為使用 object 的 equals object可能為 null 則空指標

19.Hashcode和equals的區別?

答:equals方法用于比較物件的內容是否相等(覆寫以后),hashcode方法只有在集合中用到,hashCode是為了提高在散列結構存盤中查找的效率,在線性表中沒有作用,在java中,如果hashcode相同,物件可以相同,可以不同,但若hashcode不同,物件必然不同

20.創建物件在JVM中的程序?

答:虛擬機遇到一條new指令時,首先將去檢查這個指令的引數是否能在常量池中定位到一個類的符號參考,并且檢查這個符號參考表的類是否已被加載,決議和初始化過,如果沒有,那必須先執行相應的類加載程序,在類加載檢查通過后,接下來虛擬機將為新生物件分配記憶體,

21.String 是最基本的資料型別嗎?

答:不是!最基本的資料型別只有八種,整型:byte(),short,int,long;浮點型float,double;字符型:char;布爾型:boolean;

22.包裝類和基本類區別?如何互相轉換?

答:先回顧一下基本類對應的包裝類byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacter booleanBoolean,

區別:1、包裝類是一個類,擁有方法和屬性

2、包裝類是參考的傳遞,而基本類是值得傳遞

3、包裝類需要使用new關鍵字創建物件,基本類不需要

4、基本資料型別存盤在虛擬機堆疊的區域變數表中,而包裝類存盤在Java堆中

5、基本資料型別的初始值是0值,整形是0,浮點型是0.0,boolean是false,而包裝類初始值是null

如何相互轉換:以int為例, Integer->int:Integer A=new Integer(5);int a=A.intValue();

int->Integer:int a=3;Integer A=new Integer(a);

23.構造器代碼塊、區域代碼塊、靜態代碼塊執?順序和執?次數?

答:執行順序:靜態代碼塊--->構造器代碼塊(類中直接用{}定義)--->區域代碼塊

執行次數:靜態代碼塊一次,其他創建物件時就會執行

對于靜態變數、靜態初始化塊、變數、初始化塊、構造器,它們的初始化順序依次是(靜態變數、靜態初始化塊)>(變數、初始化塊)>構造器,

24.構造代碼塊的作??

答:構造代碼塊的作用是給物件進行初始化

構造代碼塊與建構式的區別是:物件一建立就運行構造代碼塊了,而且優先于建構式執行,這里要強調一下,有物件建立,才會運行構造代碼塊,類不能呼叫構造代碼塊的,而且構造代碼塊與建構式的執行順序是前者先于后者執行, 構造代碼塊是給所有物件進行統一初始化,而建構式是給對應的物件初始化,因為建構式是可以多個的,運行哪個建構式就會建立什么樣的物件,但無論建立哪個物件,都會先執行相同的構造代碼塊,也就是說,構造代碼塊中定義的是不同物件共性的初始化內容

25.Integer是否可以被繼承?為什么?

答:Integer直接繼承自父類、它被final修飾、不可以被繼承,String 類也被final修飾所以也不可以被繼承,一旦建立物件就不能改變,

26.談談"abc" 和 new String("abc")區別?

答:String str1= “abc”; 在編譯期,JVM會去常量池來查找是否存在“abc”,如果不存在,就在常量池中開辟一個空間來存盤“abc”;如果存在,就不用新開辟空間,然后在堆疊記憶體中開辟一個名字為str1的空間,來存盤“abc”在常量池中的地址值,

String str2 = new String("abc") ;在編譯階段JVM先去常量池中查找是否存在“abc”,如果過不存在,則在常量池中開辟一個空間存盤“abc”,在運行時期,通過String類的構造器在堆記憶體中new了一個空間,然后將String池中的“abc”復制一份存放到該堆空間中,在堆疊中開辟名字為str2的空間,存放堆中new出來的這個String物件的地址值

總結,前者在初始化的時候可能創建了一個物件,也可能一個物件也沒有創建;后者因為new關鍵字,至少在記憶體中創建了一個物件,也有可能是兩個物件,

27.StringString StringBuffer StringBuilder 的區別是什么?怎么做到執行緒安全?

答:String是只讀字串,它并不是基本資料型別,而是一個物件,每次+操作 : 隱式在堆上new了一個跟原字串相同的StringBuilder物件,再呼叫append方法 拼接 +后面的字符StringBufferStringBuilder繼承了AbstractStringBulder類,而AbtractStringBuilder又實作了CharSequence介面,兩個類都是用來進行字串操作的,在做字串拼接修改洗掉替換時,效率比string更高StringBuffer是執行緒安全的,Stringbuilder是非執行緒安全的,所以Stringbuilderstringbuffer效率更高,StringBuffer的方法大多都加了 synchronized關鍵字,

28.講下java中的math類有那些常用方法?

答:Pow() :冪運算 ;Sqrt():平方根 ;Round():四舍五入 ;Abs():求絕對值 ;Random():生成一個 0-1 的亂數,包括 0 不包括 1

29.JDK1.8之后有哪些新特性?

答:有很多方面的回答,大概列舉幾個實體
1. default關鍵字: 在介面中引入了新的關鍵字default,通過使用default修飾方法,可以讓我們在介面里面定義具體的方法實作
2 .Lambda 運算式:這是一個重要的更新,這意味著 java也開始承認了函式式編程,大大 簡化了代碼的開發
3. Date Api更新:加強對日期與時間的處理,
4. map集合中紅黑樹:原來的hashMap采用的資料結構是哈希表 (陣列+鏈表),在1.8之后,在 陣列+鏈表+紅黑樹來實作hashmap,當碰撞的元素個數大于8時 & 總容量大于64,會有紅黑樹的引入
5. 并行流和串行流:在jdk1.8新的stream包中針對集合的操作也提供了并行操作流和串行操作流,并行流就是把內容切割成多個資料塊,并且使用多個執行緒分別處理每個資料塊的內容,Stream api中宣告可以通過parallel()與sequential()方法在并行流和串行流之間進行切換,
jdk1.8并行流使用的是fork/join框架進行并行操作

30.Java中深克隆和淺克隆的區別?如何實作物件克隆?

答:淺克隆:創建一個新物件,新物件的屬性和原來物件完全相同,對于非基本型別屬性,仍指向原有屬性所指向的物件的記憶體地址,

深克隆:創建一個新物件,屬性中參考的其他物件也會被克隆,不再指向原有物件地址,

總之深淺克隆都會在堆中新分配一塊區域,區別在于物件屬性參考的物件是否需要進行克隆(遞回性的),

有兩種方式: 1). 實作 Cloneable 介面并重寫 Object 類中的 clone()方法; 2). 實作Serializable 介面,通過物件的序列化和反序列化實作克隆,可以實作真正的深度克隆

31.Comparable 和Comparator的區別,分別說出使?場景?

答:comparable是需要比較的物件來實作介面(內部比較器),這樣物件呼叫實作的方法來比較,對物件的耦合度高(需要改變物件的內部結構,破壞性大),comparator(外部比較器)相當于一通用的比較工具類介面,它更像是一個補救措施,是將物件按照該比較器的規則進行比較,我們可以用comparator實作多種比較方式,按姓名按學號按成績等等,這些功能在一開始創建物件時,并沒有完全考慮,需要定制一個比較類去實作它,重寫里面的compare方法,方法的引數即是需要比較的物件,物件不用做任何改變,解耦,

32.Object類和泛型的區別,說出范型的執?機制,為什么要使?范型?

答:區別:Object是類泛型是?種約束機制,確保在編譯時不會出現型別錯誤

好處:以集合來舉例,使用泛型的好處是我們不必因為添加元素型別的不同而定義不同型別的集合,如整型集 合類,浮點型集合類,字串集合類,我們可以定義一個集合來存放整型、浮點型,字串型資料,而 這并不是最重要的,因為我們只要把底層存盤設定了Object即可,添加的資料全部都可向上轉型為 Object, 更重要的是我們可以通過規則按照自己的想法控制存盤的資料型別

33.Collection包結構,與Collections的區別 ?

答:Collection是集合類的上級介面,子介面有 SetListLinkedListArrayListVectorStackSet

Collections是集合類的一個幫助類, 它包含有各種有關集合操作的靜態多型方法,用于實作對各種集合的搜索、排序、執行緒安全化等操作,此類不能實體化,就像一個工具類,服務于Java的Collection框架

34.HashMap 和Hashtable 的區別?

答:1、兩者父類不同 HashMap是繼承自AbstractMap類,而Hashtable是繼承自Dictionary類,不過它們都實作了同時實作 了mapCloneable(可復制)、Serializable(可序列化)這三個介面,

2、對外提供的介面不同 :HashtableHashMap多提供了elments() contains() 兩個方法,

3、對null的支持不同 :Hashtable:keyvalue都不能為null, HashMap:key可以為null,但是這樣的key只能有一個,因為必須保證key的唯一性;可以有多個key 值對應的value為null

4、安全性不同 HashMap是執行緒不安全的,在多執行緒并發的環境下,可能會產生死鎖等問題,因此需要開發人員自己處理多執行緒的安全問題, Hashtable是執行緒安全的,它的每個方法上都有synchronized 關鍵字,因此可直接用于多執行緒中, 雖然HashMap是執行緒不安全的,但是它的效率遠遠高于Hashtable,這樣設計是合理的,因為大部分的使用場景都是單執行緒,當需要多執行緒操作的時候可以使用執行緒安全的ConcurrentHashMap, ConcurrentHashMap雖然也是執行緒安全的,但是它的效率比Hashtable要高好多倍,因為 ConcurrentHashMap使用了分段鎖,并不對整個資料進行鎖定,

5、初始容量大小和每次擴充容量大小不同

6、計算hash值的方法不同

35.如何解決Hash沖突問題?

答:當hash沖突產生時,一般有以 下幾種方式來處理:

1.拉鏈法:每個哈希表節點都有一個next指標,多個哈希表節點可以用next指標構成一個單向鏈表,被分配到同一個索引上的多個節點可以用這個單向鏈表進行存盤.

2. 開放定址法:一旦發生了沖突,就去尋找下一個空的散列地址,只要散串列足夠大,空的散列地址總能找到,并將記錄存入

3. 再哈希:又叫雙哈希法,有多個不同的Hash函式.當發生沖突時,使用第二個,第三個….等哈希函式計算地址,直到無沖突.

36.HashMap是如何實作自動擴容的?

答:首先要知道HashMap的容量,默認是16,HashMap的加載因子,默認是0.75,當HashMap中元素數超過容量*加載因子時,HashMap會進行擴容,當HashMap決定擴容時,會呼叫HashMap類中的resize(int newCapacity)方法,引數是新的table長度,

擴容必須滿足兩個條件:

1. 存放新值的時候當前已有元素必須大于閾值

2.存放新值的時候當前存放資料發生hash碰撞(當前key計算的hash值計算出的陣列索引位置已經存在值)

37.談談ArrayListlinkedList的區別

答:List—是一個有序的集合,可以包含重復的元素,提供了按索引訪問的方式,它繼承Collection, List有兩個重要的實作類:ArrayListLinkedList,

ArrayList: 可以看作是能夠自動增長容量的陣列 ArrayList的toArray方法回傳一個陣列 ArrayList的asList方法回傳一個串列 ArrayList底層的實作是Array, 陣列擴容實作,

LinkList:是一個雙鏈表,在添加和洗掉元素時具有比ArrayList更好的性能.但在get與set方面弱于 ArrayList.當然,這些對比都是指資料量很大或者操作很頻繁,

38.HashMap的底層原理?

答:JDK1.8之前:HashMap底層由陣列+鏈表組成,鏈表由兩部分組成,一部分存盤的自身值,另一部分存盤指向下一個元素的記憶體地址值,HashMap集合物件創建時,會在構造方法種創建一個長度為16的Entry[ ] table 陣列,用來存盤鍵值對資料(1.8之前)執行流程:
JDK1.8之后:HashMap底層引入了紅黑樹當陣列長度超過64,鏈表長度超過8后(同時滿足),會將鏈表轉換為紅黑樹結構,在第一次呼叫put方法時,創建長度為16的Node[ ] table陣列,用來存盤鍵值對(1.8之后)

hashMap存盤元素的步驟:
1)先通過hash值計算出key映射到哪個桶;
2)如果桶上沒有發生碰撞沖突,則直接插入;
3)如果出現碰撞沖突了,則需要處理沖突:
a:如果該桶使用紅黑樹處理沖突,則呼叫紅黑樹的方法插入資料;
b:否則采用傳統的鏈式方法插入,如果鏈的長度達到臨界值,陣列長度超過64,則把鏈表轉變為紅黑樹;
4)如果桶中存在重復的鍵,則為該鍵替換新值value;
5)如果size大于閾值threshold,則進行擴容

39.說說List,Set,Map三者的區別?

答:List(對付順序的好幫手) List介面存盤一組不唯一(可以有多個元素參考相同的物件),有序的物件

Set(注重獨一無二的性質):不允許重復的集合,不會有多個元素參考相同的物件,

Map(Key來搜索的專業戶): 使用鍵值對存盤Map會維護與Key有關聯的值,兩個Key可以參考相 同的物件,但Key不能重復,典型的KeyString型別,但也可以是任何物件,

40.執行緒創建4種方式?

答:1)繼承Thread類創建執行緒

定義Thread類的子類,并重寫該類的run()方法,該方法的方法體就是執行緒需要完成的任務,run()方法也稱為執行緒執行體,

創建Thread子類的實體,也就是創建了執行緒物件

啟動執行緒,即呼叫執行緒的start()方法

2)實作Runnable介面創建執行緒

定義Runnable介面的實作類,一樣要重寫run()方法,這個run()方法和Thread中的run()方法一樣是執行緒的執行體

創建Runnable實作類的實體,并用這個實體作為Thread的target來創建Thread物件,這個Thread物件才是真正的執行緒物件

第三步依然是通過呼叫執行緒物件的start()方法來啟動執行緒

3)使用Callable和Future創建執行緒

創建Callable介面的實作類,并實作call()方法,然后創建該實作類的實體(從java8開始可以直接使用Lambda運算式創建Callable物件)

使用FutureTask類來包裝Callable物件,該FutureTask物件封裝了Callable物件的call()方法的回傳值

使用FutureTask物件作為Thread物件的target創建并啟動執行緒(因為FutureTask實作了Runnable介面)

呼叫FutureTask物件的get()方法來獲得子執行緒執行結束后的回傳值

4)使用執行緒池例如用Executor框架創建

41.并發和并行有什么區別?

答:1.并行是指兩個或者多個事件在同一時刻發生;而并發是指兩個或多個事件在同一時間間隔發生,

2.并行是在不同物體上的多個事件并發是在同一物體上的多個事件

42.為什么要使用執行緒池?

答:執行緒和資料庫連接這些資源都是非常寶貴的資源,那么每次需要的時候創建,不需要的時候銷毀,是非常浪費資源的,那么我們就可以使用快取的策略,也就是使用執行緒池

第一:降低資源消耗,通過重復利用已創建的執行緒降低執行緒創建和銷毀造成的消耗,

第二:提高回應速度,當任務到達時,任務可以不需要等到執行緒創建就能立即執行,

第三:提高執行緒的可管理性,執行緒是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用執行緒池可以進行統一的分配,調優和監控

43.執行緒池的構造方法里幾個引數的作用分別都是什么?

答:corePollSize核心執行緒數,在創建了執行緒池后,執行緒中沒有任何執行緒,等到有任務到來時才創建執行緒去執行任務,

maximumPoolSize最大執行緒數,表明執行緒中最多能夠創建的執行緒數量,

keepAliveTime空閑的執行緒保留的時間

TimeUnit空閑執行緒的保留時間單位

BlockingQueue阻塞佇列,存盤等待執行的任務,引數有ArrayBlockingQueue、 LinkedBlockingQueue、SynchronousQueue可選,

ThreadFactory執行緒工廠,用來創建執行緒

RejectedExecutionHandler佇列已滿,而且任務量大于最大執行緒的例外處理策略

   ThreadPoolExecutor.AbortPolicy:丟棄任務并拋出RejectedExecutionException例外,

   ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不拋出例外,

   ThreadPoolExecutor.DiscardOldestPolicy:丟棄佇列最前面的任務,然后重新嘗試執行任務(重復此程序)

   ThreadPoolExecutor.CallerRunsPolicy:由呼叫執行緒處理該任務

44.什么是執行緒安全問題?如何解決執行緒安全問題?

答:執行緒安全就是說多執行緒訪問同一代碼,不會產生不確定的結果

那么執行緒安全問題就是當多個執行緒同時共享,同一個全域變數或者靜態變數,做寫的操作時,可能會發生資料沖突問題,也就是執行緒安全問題,多執行緒操作共享資源時,導致共享資源出現錯亂,執行緒安全問題都是由全域變數及靜態變數引起的,若每個執行緒中對全域變數、靜態變數只有讀操作,而無寫操作,一般來說,這個全域變數是執行緒安全的;若有多個執行緒同時執行寫操作,一般都需要考慮執行緒同步,否則的話就可能影響執行緒安全,

解決執行緒安全問題:執行緒同步:**即當有一個執行緒在對記憶體進行操作時,其他執行緒都不可以對這個記憶體地址進行操作,直到該執行緒完成操作, 其他執行緒才能對該記憶體地址進行操作,而其他執行緒又處于等待狀態,Java中提供了同步機制(synchronized)來解決;同步代碼塊;同步方法;鎖機制

45.談一談執行緒生命周期(狀態)?

答:當執行緒被創建并啟動以后,它既不是一啟動就進入了執行狀態,也不是一直處于執行狀態,在執行緒的生命周期中,它要經過新建(New)、就緒(Runnable)、運行(Running)、阻塞(Blocked)和死亡(Dead)5 種狀態,尤其是當執行緒啟動以后,它不可能一直"霸占" CPU 獨自運行,所以 CPU 需要在多條執行緒之間切換,于是執行緒狀態也會多次運行、阻塞之間切換

新建狀態(NEW):當程式使用 new 關鍵字創建了一個執行緒之后,該執行緒就處于新建狀態,此時僅由 JVM 為其分配記憶體,并初始化其成員變數的值

就緒狀態(RUNNABLE):當執行緒物件呼叫了 start()方法之后,該執行緒處于就緒狀態, Java 虛擬機會為其創建方法呼叫堆疊和程式計數器,等待調度運行,

運行狀態(RUNNING):如果處于就緒狀態的執行緒獲得了 CPU,開始執行 run()方法的執行緒執行體,則該執行緒處于運行狀態,

阻塞狀態(BLOCKED):阻塞狀態是指執行緒因為某種原因放棄了 cpu 使用權,也即讓出了 cpu timeslice,暫時停止運行,直到執行緒進入可運行(runnable)狀態,才有機會再次獲得 cpu timeslice 轉到運行(running)狀態,阻塞的情況分三種: 等待阻塞(o.wait->等待對列)運行(running)的執行緒執行 o.wait()方法, JVM 會把該執行緒放入等待佇列(waitting queue)中, 同步阻塞(lock->鎖池) :運行(running)的執行緒在獲取物件的同步鎖時,若該同步鎖被別的執行緒占用,則 JVM 會把該執行緒放入鎖池(lock pool)中,其他阻塞(sleep/join) :運行(running)的執行緒執行 Thread.sleep(long ms) t.join()方法,或者發出了 I/O 請求時,JVM 會把該執行緒置為阻塞狀態,當 sleep()狀態超時、 join()等待執行緒終止或者超時、或者 I/O處理完畢時,執行緒重新轉入可運行(runnable)狀態,

執行緒死亡(DEAD):執行緒會以下面三種方式結束,結束后就是死亡狀態, 正常結束 :1. run()或 call()方法執行完成,執行緒正常結束,例外結束 :2. 執行緒拋出一個未捕獲的 Exception Error,呼叫 stop :3. 直接呼叫該執行緒的 stop()方法來結束該執行緒該方法通常容易導致死鎖,不推薦使用,

46.notify()和 notifyAll()有什么區別?

答: 1.notify可能會導致死鎖,而notifyAll則不會

2.任何時候只有一個執行緒可以獲得鎖,也就是說只有一個執行緒可以運行synchronized 中的代碼

使用notifyall,可以喚醒所有處于wait狀態的執行緒 ,使其重新進入鎖的爭奪佇列中,而 notify只能喚醒一個
3. wait() 應配合 while 回圈使用,不應使用 if ,務必在 wait() 呼叫前后都檢查條件,如果不滿足,必須呼叫
notify() 喚醒另外的執行緒來處理,自己繼續 wait() 直至條件滿足再往下執行,
4. notify() 是對notifyAll()的一個優化,但它有很精確的應用場景,并且要求正確使用 ,不然可能導致死 鎖,正確的場景應該是 WaitSet 中等待的是相同的條件,喚醒任一個都能正確處理接下來的事項,如果 喚醒的執行緒無法正確處理,務必確保繼續 notify() 下一個執行緒,并且自身需要重新回到 WaitSet 中,

47.sleep()wait() 有什么區別?

答:1. 對于 sleep()方法,我們首先要知道該方法是屬于 Thread 類中的,而 wait()方法,則是屬于

Object 類 中的,
2. sleep()方法導致了程式暫停執行指定的時間,讓出 cpu 該其他執行緒 ,但是他的監控狀態依然 保持者,當指定的時間到了又會自動恢復運行狀態
3.在呼叫 sleep() 方法的程序中, 執行緒不會釋放物件鎖
4. 而當呼叫 wait()方法的時候,執行緒會放棄物件鎖,進入等待此物件的等待鎖定池,只有針對此物件呼叫 notify()方法后本執行緒才進入物件鎖定池 準備獲取物件鎖進入運行狀態,

48.談談JAVA的后臺執行緒?

答:1.后臺執行緒也叫守護執行緒--也稱“服務執行緒”,它有一個特性,即為用戶執行緒 提供 公共服務, 在沒有用戶執行緒可服務時會自動離開,

2.優先級:守護執行緒的優先級比較低,用于為系統中的其它物件和執行緒提供服務

3. 設定:通過 setDaemon(true)來設定執行緒為守護執行緒”;將一個用戶執行緒設定為守護執行緒的方式是在 執行緒物件創建 之前 用執行緒物件的 setDaemon 方法,在 Daemon 執行緒中產生的新執行緒也是 Daemon 的,

4.執行緒則是 JVM 級別的,以 Tomcat 為例,如果你在 Web 應用中啟動一個執行緒,這個執行緒的生命周期并不會和 Web 應用程式保持同步,也就是說,即使你停止了 Web 應用,這個執行緒依舊是活躍的,垃圾回收執行緒就是一個經典的守護執行緒,當我們的程式中不再有任何運行的Thread, 程式就不會再產生垃圾,垃圾回收器也就無事可做, 所以當垃圾回收執行緒是 JVM 上僅剩的執行緒時,垃圾回收執行緒會自動離開,它始終在低級別的狀態中運行,用于實時監控和管理系統中的可回收資源,

5.生命周期:守護行程(Daemon)是運行在后臺的一種特殊行程,它獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件,也就是說守護執行緒不依賴于終端,但是依賴于系統,與系統“同生共死,當 JVM 中所有的執行緒都是守護執行緒的時候, JVM 就可以退出了;如果還有一個或以上的非守護執行緒則 JVM 不會退出,

49.你都知道哪些執行緒相關的基本方法?

答: wait notify notifyAll sleep join yield

執行緒等待(wait):呼叫該方法的執行緒進入 WAITING 狀態,只有等待另外執行緒的通知或被中斷才會回傳,需要注意的是呼叫 wait()方法后, 會釋放物件的鎖,因此, wait 方法一般用在同步方法或同步代碼塊中,

執行緒睡眠(sleep):sleep 導致當前執行緒休眠,與 wait 方法不同的是 sleep 不會釋放當前占有的鎖,sleep(long)會導致執行緒進入 TIMED-WATING 狀態,而 wait()方法會導致當前執行緒進入 WATING 狀態

執行緒讓步(yield):yield 會使當前執行緒讓出 CPU 執行時間片,與其他執行緒一起重新競爭 CPU 時間片,一般情況下, 優先級高的執行緒有更大的可能性成功競爭得到 CPU 時間片, 但這又不是絕對的,有的作業系統對執行緒優先級并不敏感,

執行緒中斷(interrupt中斷一個執行緒,其本意是給這個執行緒一個通知信號,會影響這個執行緒內部的一個中斷標識位, 這個執行緒本身并不會因此而改變狀態(如阻塞,終止等)

等待其他執行緒終止(join):join() 方法,等待其他執行緒終止,在當前執行緒中呼叫一個執行緒的 join() 方法,則當前執行緒轉為阻塞 狀態,回到另一個執行緒結束,當前執行緒再由阻塞狀態變為就緒狀態,等待 cpu 的寵幸,很多情況下,主執行緒生成并啟動了子執行緒,需要用到子執行緒回傳的結果,也就是需要主執行緒需要 在子執行緒結束后再結束,這時候就要用到 join() 方法 ,

執行緒喚醒(notify) :Object 類中的 notify() 方法, 喚醒在此物件監視器上等待的單個執行緒,如果所有執行緒都在此物件上等待,則會選擇喚醒其中一個執行緒,選擇是任意的,并在對實作做出決定時發生,執行緒通過呼叫其中一個 wait() 方法,在物件的監視器上等待, 直到當前的執行緒放棄此物件上的鎖定,才能繼續執行被喚醒的執行緒,被喚醒的執行緒將以常規方式與在該物件上主動同步的其他所有執行緒進行競爭,類似的方法還有 notifyAll() ,喚醒再次監視器上等待的所有執行緒,

50.請說出sql陳述句中 left join ,inner join 和right join的區別?

答:left join(左聯接) 回傳包括左表中的所有記錄和右表中聯結欄位相等的記錄
right join(右聯接) 回傳包括右表中的所有記錄和左表中聯結欄位相等的記錄
inner join(等值連接)回傳兩個表中聯結欄位相等的行

左連接和右連接的區別在于以哪個表為主(主表中的資料都會出現在表中)

51.講一下JDBC操作流程?

答:1.加載資料庫驅動類 2.打開資料庫連接 3.執行sql陳述句 4.處理回傳結果 5.關閉資源

52.資料庫連接池的作業機制?

答:資料庫連接池在初始化時將創建一定數量的資料庫連接放到連接池中,這些資料庫連接的數量是由最小資料庫連接數來設定的,無論這些資料庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量,連接池的最大資料庫連接數量限定了這個連接池能占有的最大連接數,當應用程式向連接池請求的連接數超過最大連接數量時,這些請求將被加入到等待佇列中,

53.Java 中常用的設計模式?說說工廠模式或者幾種比較熟悉的說一下?

答:1.單例(Singleton)模式:某個類只能生成一個實體,該類提供了一個全域訪問點供外部獲取該實體,其拓展是有限多例模式,

2.原型(Prototype)模式:將一個物件作為原型,通過對其進行復制而克隆出多個和原型類似的新實體,

3.工廠方法(Factory Method)模式:定義一個用于創建產品的介面,由子類決定生產什么產品,

4.抽象工廠(AbstractFactory)模式:提供一個創建產品族的介面,其每個子類可以生產一系列相關的產品,

5.建造者(Builder)模式:將一個復雜物件分解成多個相對簡單的部分,然后根據不同需要分別創建它們,最后構建成該復雜物件,

6.代理(Proxy)模式:為某物件提供一種代理以控制對該物件的訪問,即客戶端通過代理間接地訪問該物件,從而限制、增強或修改該物件的一些特性,

7.配接器(Adapter)模式:將一個類的介面轉換成客戶希望的另外一個介面,使得原本由于介面不兼容而不能一起作業的那些類能一起作業,

8.橋接(Bridge)模式:將抽象與實作分離,使它們可以獨立變化,它是用組合關系代替繼承關系來實作,從而降低了抽象和實作這兩個可變維度的耦合度,

9.裝飾(Decorator)模式:動態的給物件增加一些職責,即增加其額外的功能,

10.外觀(Facade)模式:為多個復雜的子系統提供一個一致的介面,使這些子系統更加容易被訪問,

11.享元(Flyweight)模式:運用共享技術來有效地支持大量細粒度物件的復用,

12.組合(Composite)模式:將物件組合成樹狀層次結構,使用戶對單個物件和組合物件具有一致的訪問性,

13.模板方法(TemplateMethod)模式:定義一個操作中的演算法骨架,而將演算法的一些步驟延遲到子類中,使得子類可以不改變該演算法結構的情況下重定義該演算法的某些特定步驟,

14.策略(Strategy)模式:定義了一系列演算法,并將每個演算法封裝起來,使它們可以相互替換,且演算法的改變不會影響使用演算法的客戶,

15.命令(Command)模式:將一個請求封裝為一個物件,使發出請求的責任和執行請求的責任分割開,

16.職責鏈(Chain of Responsibility)模式:把請求從鏈中的一個物件傳到下一個物件,直到請求被回應為止,通過這種方式去除物件之間的耦合,

17.狀態(State)模式:允許一個物件在其內部狀態發生改變時改變其行為能力,

18.觀察者(Observer)模式:多個物件間存在一對多關系,當一個物件發生改變時,把這種改變通知給其他多個物件,從而影響其他物件的行為,

19.中介者(Mediator)模式:定義一個中介物件來簡化原有物件之間的互動關系,降低系統中物件間的耦合度,使原有物件之間不必相互了解,

20.迭代器(Iterator)模式:提供一種方法來順序訪問聚合物件中的一系列資料,而不暴露聚合物件的內部表示,

21.訪問者(Visitor)模式:在不改變集合元素的前提下,為一個集合中的每個元素提供多種訪問方式,即每個元素有多個訪問者物件訪問,

22.備忘錄(Memento)模式:在不破壞封裝性的前提下,獲取并保存一個物件的內部狀態,以便以后恢復它,

23.解釋器(Interpreter)模式:提供如何定義語言的文法,以及對語言句子的解釋方法,即解釋器,

54.char 型變數中能不能存盤一個中文漢字?為什么?

答:char型變數是用來存盤Unicode編碼的字符的,unicode編碼字符集中包含了漢字,所以,char型變數中當然可以存盤漢字啦,不過,如果某個特殊的漢字沒有被包含在unicode編碼字符集中,那么,這個char型變數中就不能存盤這個特殊漢字,補充說明:unicode編碼占用兩個位元組,所以,char型別的變數也是占用兩個位元組

55.error 和exception 有什么區別?

答:error 表示恢復不是不可能但很困難的情況下的一種嚴重問題,比如說記憶體溢位,不可能指望程式能處理這樣的情況; exception 表示一種設計或實作問題,也就是說,它表示如果程式運行正常,從不會發生的情況,

56.Thowthorws區別?

答:位置不同 throws 用在函式上,后面跟的是例外類,可以跟多個;而 throw 用在函式內,后面跟的是例外物件,

功能不同: 1.throws 用來宣告例外,讓呼叫者只知道該功能可能出現的問題,可以給出預先的處理方式;throw 拋出具體的問題物件,執行到 throw,功能就已經結束了,跳轉到呼叫者,并將具體的問題物件拋給呼叫者,也就是說 throw 陳述句獨立存在時,下面不要定義其他陳述句,因為執行不到,

2.throws 表示出現例外的一種可能性,并不一定會發生這些例外;throw 則是拋出了例外,執行 throw 則一定拋出了某種例外物件,

3.兩者都是消極處理例外的方式,只是拋出或者可能拋出例外,但是不會由函式去處理例外,真正的處理例外由函式的上層呼叫處理,

57.TCP與UDP的區別?

答:1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送資料之前不需要建立連接

2、TCP提供可靠的服務,也就是說,通過TCP連接傳送的資料,無差錯,不丟失,不重復,且按序到達;UDP盡最大努力交付,即不保證可靠交付

3、TCP面向位元組流,實際上是TCP把資料看成一連串無結構的位元組流;UDP是面向報文的 UDP沒有擁塞控制,因此網路出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)

4、每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的互動通信

5、TCP首部開銷20位元組;UDP的首部開銷小,只有8個位元組

6、TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道

58.執行緒和行程的區別?

答:行程是作業系統分配資源的最小單元執行緒是作業系統調度的最小單元 一個程式至少有一個行程,一個行程至少有一個執行緒

59.什么是反射?

答:是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法對于任意一個物件,都能夠呼叫它的任意一個方法和屬性,這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制,

60.什么是java序列化,如何實作java序列化?

答:序列化就是一種用來處理物件流的機制,所謂物件流也就是將物件的內容進行流化,可以對流化后的物件進行讀寫操作,也可將流化后的物件傳輸于網路之間,序列化是為了解決在對物件流進行讀寫操作時所引發的問題

序列化的實作:將需要被序列化的類實作Serializable介面,該介面沒有需要實作的方法,implements Serializable只是為了標注該物件是可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(物件流)物件,接著,使用ObjectOutputStream物件的writeObject(Object obj)方法就可以將引數為obj的物件寫出(即保存其狀態),要恢復的話則用輸入流,

61.動態代理是什么?有哪些應用?

答:當想要給實作了某個介面的類中的方法,加一些額外的處理,比如說加日志,加事務等,可以給這個類創建一個代理,故名思議就是創建一個新的類,這個類不僅包含原來類方法的功能,而且還在原來的基礎上添加了額外處理的新類,這個代理類并不是定義好的,是動態生成的,具有解耦意義,靈活,擴展性強

動態代理實作:首先必須定義一個介面,還要有一個InvocationHandler(將實作介面的類的物件傳遞給它)處理類,再有一個工具類Proxy(習慣性將其稱為代理類,因為呼叫他的newInstance()可以產生代理物件,其實他只是一個產生代理物件的工具類),利用到InvocationHandler,拼接代理類原始碼,將其編譯生成代理類的二進制碼,利用加載器加載,并將其實體化產生代理物件,最后回傳,

動態代理的應用:Spring的AOP,加事務,加權限,加日志

62.說一下 JVM 的主要組成部分?及其作用?

答:JVM主要包含兩個子系統和兩個組件:
子系統:類加載系統,執行引擎
組件運行時資料區,本地方法介面
類加載系統:根據給定的類的全限定類名(java.lang.obejct)將位元組碼檔案加載到運行時資料區的方法區,
執行引擎執行classes中的指令
運行時資料區:即是我們常說的jvm記憶體,里邊包含了執行緒共享區(方法區,堆),執行緒獨占區(本地方法堆疊,程式計數器,虛擬機堆疊)
本地方法介面連接本地方法庫,是與其他編程語言互動的介面

63.說一下堆疊的區別?

答:1. 堆疊記憶體存盤的是區域變數堆記憶體存盤的是物體

2.堆疊記憶體的更新速度要快于堆記憶體,因為區域變數的生命周期很短

3.堆疊記憶體存放的變數生命周期一旦結束就會被釋放,而堆記憶體存放的物體會被垃圾回識訓制不定時的回收

JVM 中堆和堆疊屬于不同的記憶體區域,使用目的也不同,堆疊常用于保存方法幀和區域變數,而物件總是在堆上分配,堆疊通常都比堆小,也不會在多個執行緒之間共享,而堆被整個 JVM 的所有執行緒共享

64.什么是雙親委派模型?

答:如果一個類加載器收到了類加載的請求,它首先不會自己去加載這個類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣所有的加載請求都會被傳送到頂層的啟動類加載器中,只有當父加載無法完成加載請求(它的搜索范圍中沒找到所需的類)時,子加載器才會嘗試去加載類

65.怎么判斷物件是否可以被回收?

答:判斷物件是否存活一般有兩種方式:

參考計數每個物件有一個參考計數屬性,新增一個參考時計數加1,參考釋放時計數減1,計數為0時可以回收,此方法簡單,無法解決物件相互回圈參考的問題,

可達性分析(Reachability Analysis):從GC Roots開始向下搜索,搜索所走過的路徑稱為參考鏈,當一個物件到GC Roots沒有任何參考鏈相連時,則證明此物件是不可用的,不可達物件

66.你知道哪些JVM性能調優?

答:1. 設定堆記憶體大小 2.設定新生代大小, 新生代不宜太小,否則會有大量物件涌入老年代 3.設定垃圾回收器 年輕代用

67.你知道的垃圾收集演算法?還有其底層原理

答:GC最基礎的演算法有三種: 標記 -清除演算法復制演算法標記-壓縮演算法,我們常用的垃圾回收器一般都采用分代收集演算法

標記 -清除演算法,“標記-清除”(Mark-Sweep)演算法,如它的名字一樣,演算法分為“標記”和“清除”兩個階段:首先標記出所有需要回收的物件,在標記完成后統一回收掉所有被標記的物件

復制演算法,“復制”(Copying)的收集演算法,它將可用記憶體按容量劃分為大小相等的兩塊,每次只使用其中的一塊,當這一塊的記憶體用完了,就將還存活著的物件復制到另外一塊上面,然后再把已使用過的記憶體空間一次清理掉

標記-壓縮演算法,標記程序仍然與“標記-清除”演算法一樣,但后續步驟不是直接對可回收物件進行清理,而是讓所有存活的物件都向一端移動,然后直接清理掉端邊界以外的記憶體

分代收集演算法,“分代收集”(Generational Collection)演算法,把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點采用最適當的收集演算法

68.什么情況下會出現堆記憶體溢位?

答:堆中主要存盤的是物件,如果不斷的new物件則會導致堆中的空間溢位;可以通過 -Xmx4096M 調整堆的總大小

69.什么是類加載器?及類加載器的分類?

答:類加載器是一個重要的 Java 運行時系統組件,它負責在運行時查找和裝入類檔案中的類,分為三類:

啟動類加載器(Bootstrap ClassLoader)負責加載 JAVA_HOME\lib 目錄中的, 或通過-Xbootclasspath 引數指定路徑中的, 且被虛擬機認可(按檔案名識別, 如 rt.jar) 的類,

擴展類加載器(Extension ClassLoader) 負責加載 JAVA_HOME\lib\ext 目錄中的,或通過 java.ext.dirs 系統變數指定路徑中的類別庫

應用程式類加載器 (Application ClassLoader) 負責加載用戶路徑(classpath)上的類別庫 JVM 通過雙親委派模型進行類的加載, 當然我們也可以通過繼承 java.lang.ClassLoader 實作自定義的類加載器,

70.說一下類加載的執行程序?

答:類加載(加載,鏈接{驗證,準備,決議},初始化):

加載:指的是把class位元組碼檔案從各個來源通過類加載器裝載入記憶體中

鏈接:(1)驗證:主要是為了保證加載進來的位元組流符合虛擬機規范,不會造成安全錯誤

(2)準備:主要是為類變數(注意,不是實體變數)分配記憶體,并且賦予初值

(3)決議:將常量池內的符號參考替換為直接參考的程序

初始化:這個階段主要是對類變數初始化,是執行類構造器的程序,

71.簡單的介紹?下強引?,軟引?,弱引?,虛引??

答:強引?(StrongReference):這是使?最普遍的引?,如果?個物件具有強引?,那就類似于必不可少的?活?品,垃圾回收器絕不會回收它,當記憶體空 間不?,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程式例外終?,也不會靠隨意回收具有強引?的物件來解決記憶體不?問題,

軟引?(SoftReference):如果?個物件只具有軟引?,那就類似于可有可?的?活?品,如果記憶體空間?夠,垃圾回收器就不會回收它,如果記憶體空間不?了,就會回收這些物件的記憶體,只要垃圾回收器沒有回收它,該物件就可以被程式使?,軟引?可?來實作記憶體敏感的?速快取,軟引?可以和?個引?佇列(ReferenceQueue)聯合使?,如果軟引?所引?的物件被垃圾回收,JAVA虛擬機就會把這個軟引?加?到與之關聯的引?佇列中,

弱引?(WeakReference):如果?個物件只具有弱引?,那就類似于可有可?的?活?品,弱引?與軟引?的區別在于:只具有弱引?的物件擁有更短暫的?命周期,在垃圾回收器執行緒掃描它 所管轄的記憶體區域的程序中,?旦發現了只具有弱引?的物件,不管當前記憶體空間?夠與否,都會回收它的記憶體,不過,由于垃圾回收器是?個優先級很低的執行緒, 因此不?定會很快發現那些只具有弱引?的物件,弱引?可以和?個引?佇列(ReferenceQueue)聯合使?,如果弱引?所引?的物件被垃圾回收,Java虛擬機就會把這個弱引?加?到與之關聯的引?佇列中,

虛引?(PhantomReference):"虛引?"顧名思義,就是形同虛設,與其他?種引?都不同,虛引?并不會決定物件的?命周期,如果?個物件僅持有虛引?,那么它就和沒有任何引??樣,在任何時候都可能被垃圾回收,

72.什么是死鎖?死鎖產生的原因?怎么防止死鎖?

答:Java 中的死鎖是一種編程情況,其中兩個或多個執行緒被永久阻塞,Java 死鎖情況出現至少兩個執行緒和兩個或更多資源,

發生死鎖的根本原因是:在申請鎖時發生了交叉倍訓申請

1. 因競爭資源發生死鎖現象:系統中供多個行程共享的資源的數目不足以滿足全部行程的需要時,就會引起對諸資源的競爭而發生死鎖現象;

2. 行程推進順序不當發生死鎖

防止死鎖: 1.預防死鎖:通過設定一些限制條件,去破壞產生死鎖的必要條件
2.避免死鎖:在資源分配程序中,使用某種方法避免系統進入不安全的狀態,從而避免發生死鎖
3.檢測死鎖:允許死鎖的發生,但是通過系統的檢測之后,采取一些措施,將死鎖清除掉
4.解除死鎖:該方法與檢測死鎖配合使用





轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/266362.html

標籤:java

上一篇:Mybatis學習筆記 【1】

下一篇:SpringBoot核心技術

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more