JVM的內存結構
根據 JVM 規範,JVM 內存共分為虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。
1. Java虛擬機棧:線程私有;每個方法在執行的時候會創建一個棧幀,存儲了局部變量表,操作數棧,動態連接,方法返回地址等;每個方法從調用到執行完畢,對應一個棧幀在虛擬機棧中的入棧和出棧。
2. 堆:線程共享;被所有線程共享的一塊內存區域,在虛擬機啟動時創建,用於存放對象實例。
3. 方法區:線程共享;被所有線程共享的一塊內存區域;用於存儲已被虛擬機加載的類信息,常量,靜態變量等。
4. 程序計數器:線程私有;是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱為“線程私有”的內存。
5. 本地方法棧:線程私有;主要為虛擬機使用到的Native方法服務。
為什麼要用線程池
那先要明白什麼是線程池
線程池是指在初始化一個多線程應用程序過程中創建一個線程集合,然後在需要執行新的任務時重用這些線程而不是新建一個線程。
使用線程池的好處
- 線程池改進了一個應用程序的響應時間。由於線程池中的線程已經準備好且等待被分配任務,應用程序可以直接拿來使用而不用新建一個線程。
- 線程池節省了CLR 為每個短生存週期任務創建一個完整的線程的開銷並可以在任務完成後回收資源。
- 線程池根據當前在系統中運行的進程來優化線程時間片。
- 線程池允許我們開啟多個任務而不用為每個線程設置屬性。
- 線程池允許我們為正在執行的任務的程序參數傳遞一個包含狀態信息的對象引用。
- 線程池可以用來解決處理一個特定請求最大線程數量限制問題。
MySQL優化經驗
- 對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
- 應儘量避免在 where 子句中使用!=或<>操作符,否則引擎將放棄使用索引而進行全表掃描。
- 儘量使用數字型字段,若只含數值信息的字段儘量不要設計為字符型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠了。
- 任何地方都不要使用 select from t ,用具體的字段列表代替“ ”,不要返回用不到的任何字段。
- 避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。諸如此類,等等等等......
什麼是線程死鎖?死鎖如何產生?如何避免線程死鎖?
死鎖的介紹:
線程死鎖是指由於兩個或者多個線程互相持有對方所需要的資源,導致這些線程處於等待狀態,無法前往執行。當線程進入對象的synchronized代碼塊時,便佔有了資源,直到它退出該代碼塊或者調用wait方法,才釋放資源,在此期間,其他線程將不能進入該代碼塊。當線程互相持有對方所需要的資源時,會互相等待對方釋放資源,如果線程都不主動釋放所佔有的資源,將產生死鎖。
死鎖的產生的一些特定條件:
- 互斥條件:進程對於所分配到的資源具有排它性,即一個資源只能被一個進程佔用,直到被該進程釋放 。
- 請求和保持條件:一個進程因請求被佔用資源而發生阻塞時,對已獲得的資源保持不放。
- 不剝奪條件:任何一個資源在沒被該進程釋放之前,任何其他進程都無法對他剝奪佔用。
- 循環等待條件:當發生死鎖時,所等待的進程必定會形成一個環路(類似於死循環),造成永久阻塞。
如何避免:
1. 加鎖順序:當多個線程需要相同的一些鎖,但是按照不同的順序加鎖,死鎖就很容易發生。如果能確保所有的線程都是按照相同的順序獲得鎖,那麼死鎖就不會發生。當然這種方式需要你事先知道所有可能會用到的鎖,然而總有些時候是無法預知的。
2. 加鎖時限:加上一個超時時間,若一個線程沒有在給定的時限內成功獲得所有需要的鎖,則會進行回退並釋放所有已經獲得的鎖,然後等待一段隨機的時間再重試。但是如果有非常多的線程同一時間去競爭同一批資源,就算有超時和回退機制,還是可能會導致這些線程重複地嘗試但卻始終得不到鎖。
3. 死鎖檢測:死鎖檢測即每當一個線程獲得了鎖,會在線程和鎖相關的數據結構中(map、graph等等)將其記下。除此之外,每當有線程請求鎖,也需要記錄在這個數據結構中。死鎖檢測是一個更好的死鎖預防機制,它主要是針對那些不可能實現按序加鎖並且鎖超時也不可行的場景。
spring中Bean的作用域
1. singleton:Spring IoC容器中只會存在一個共享的Bean實例,無論有多少個Bean引用它,始終指向同一對象。Singleton作用域是Spring中的缺省作用域。
2. prototype:每次通過Spring容器獲取prototype定義的bean時,容器都將創建一個新的Bean實例,每個Bean實例都有自己的屬性和狀態,而singleton全局只有一個對象。
3. request:在一次Http請求中,容器會返回該Bean的同一實例。而對不同的Http請求則會產生新的Bean,而且該bean僅在當前Http Request內有效。
4. session:在一次Http Session中,容器會返回該Bean的同一實例。而對不同的Session請求則會創建新的實例,該bean實例僅在當前Session內有效。
5. global Session:在一個全局的Http Session中,容器會返回該Bean的同一個實例,僅在使用portlet context時有效。
Spring框架中都用到了哪些設計模式?
1. 代理模式:在AOP和remoting中被用的比較多。
2. 單例模式:在spring配置文件中定義的bean默認為單例模式。
3. 模板方法模式:用來解決代碼重複的問題。
4. 前端控制器模式:Spring提供了DispatcherServlet來對請求進行分發。
5. 依賴注入模式:貫穿於BeanFactory / ApplicationContext接口的核心理念。
6. 工廠模式:BeanFactory用來創建對象的實例。
springmvc的核心是什麼,請求的流程是怎麼處理的,控制反轉怎麼實現的
核心:控制反轉和麵向切面
請求處理流程:
- 首先用戶發送請求到前端控制器,前端控制器根據請求信息(如URL)來決定選擇哪一個頁面控制器進行處理並把請求委託給它,即以前的控制器的控制邏輯部分;
- 頁面控制器接收到請求後,進行功能處理,首先需要收集和綁定請求參數到一個對象,並進行驗證,然後將命令對象委託給業務對象進行處理;處理完畢後返回一個ModelAndView(模型數據和邏輯視圖名);
- 前端控制器收回控制權,然後根據返回的邏輯視圖名,選擇相應的視圖進行渲染,並把模型數據傳入以便視圖渲染;
- 前端控制器再次收回控制權,將響應返回給用戶。
控制反轉如何實現:
- 我們每次使用spring框架都要配置xml文件,這個xml配置了bean的id和class。
- spring中默認的bean為單實例模式,通過bean的class引用反射機制可以創建這個實例。
- 因此,spring框架通過反射替我們創建好了實例並且替我們維護他們。
- A需要引用B類,spring框架就會通過xml把B實例的引用傳給了A的成員變量。
BAT大廠Java高級面試題常見30問
- Spring DAO 中最常用的類是什麼?
- 如何在Spring應用中使用SLF4J?
- Spring bean 的默認作用範圍是?
- 使用@Required但不關聯bean 來註解setter方法,將會發生?
- 已知一棵二叉樹前序遍歷和中序遍歷分別為ABDEGCFH和DBGEACHF,則該二叉樹的後序遍歷為?
- volatile關鍵字是否能保證線程安全?
- Java能不能不通過構造函數創建對象?
- Java程序的併發機制是?
- 方法resume()負責恢復哪些線程的執行?
- 什麼是LinkedHashSet?
- 什麼是可變參數?
- 斷言的用途?
- 什麼時候使用斷言?
- 什麼是垃圾回收?
- 用一個例子解釋垃圾回收?
- 什麼時候運行垃圾回收?
- 垃圾回收的最佳做法?
- 什麼是初始化數據塊?
- 什麼是靜態初始化器?
- 什麼是實例初始化塊?
- 什麼是正則表達式?
- 什麼是令牌化?
- 給出令牌化的例子?
- 如何使用掃描器類(Scanner Class)令牌化?
- 如何添加小時(hour)到一個日期對象(Date Objects)?
- 如何格式化日期對象?
- Java中日曆類(Calendar Class)的用途?
- 如何在Java中獲取日曆類的實例?
- 解釋一些日曆類中的重要方法?
- 數字格式化類(Number Format Class)的用途?
讀者福利
由於篇幅有限,部分答案就不做全部展示了,這些面試題的答案我已經整理成PDF文檔了,同時也整理了一些問題詳解;雖然說花了一點時間,但是我也願意把它免費分享出來,希望能夠幫助到有需要的Java工程師朋友,也省的大家再去網上花時間找資料。
JVM的內存結構
根據 JVM 規範,JVM 內存共分為虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。
1. Java虛擬機棧:線程私有;每個方法在執行的時候會創建一個棧幀,存儲了局部變量表,操作數棧,動態連接,方法返回地址等;每個方法從調用到執行完畢,對應一個棧幀在虛擬機棧中的入棧和出棧。
2. 堆:線程共享;被所有線程共享的一塊內存區域,在虛擬機啟動時創建,用於存放對象實例。
3. 方法區:線程共享;被所有線程共享的一塊內存區域;用於存儲已被虛擬機加載的類信息,常量,靜態變量等。
4. 程序計數器:線程私有;是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱為“線程私有”的內存。
5. 本地方法棧:線程私有;主要為虛擬機使用到的Native方法服務。
為什麼要用線程池
那先要明白什麼是線程池
線程池是指在初始化一個多線程應用程序過程中創建一個線程集合,然後在需要執行新的任務時重用這些線程而不是新建一個線程。
使用線程池的好處
- 線程池改進了一個應用程序的響應時間。由於線程池中的線程已經準備好且等待被分配任務,應用程序可以直接拿來使用而不用新建一個線程。
- 線程池節省了CLR 為每個短生存週期任務創建一個完整的線程的開銷並可以在任務完成後回收資源。
- 線程池根據當前在系統中運行的進程來優化線程時間片。
- 線程池允許我們開啟多個任務而不用為每個線程設置屬性。
- 線程池允許我們為正在執行的任務的程序參數傳遞一個包含狀態信息的對象引用。
- 線程池可以用來解決處理一個特定請求最大線程數量限制問題。
MySQL優化經驗
- 對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
- 應儘量避免在 where 子句中使用!=或<>操作符,否則引擎將放棄使用索引而進行全表掃描。
- 儘量使用數字型字段,若只含數值信息的字段儘量不要設計為字符型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠了。
- 任何地方都不要使用 select from t ,用具體的字段列表代替“ ”,不要返回用不到的任何字段。
- 避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。諸如此類,等等等等......
什麼是線程死鎖?死鎖如何產生?如何避免線程死鎖?
死鎖的介紹:
線程死鎖是指由於兩個或者多個線程互相持有對方所需要的資源,導致這些線程處於等待狀態,無法前往執行。當線程進入對象的synchronized代碼塊時,便佔有了資源,直到它退出該代碼塊或者調用wait方法,才釋放資源,在此期間,其他線程將不能進入該代碼塊。當線程互相持有對方所需要的資源時,會互相等待對方釋放資源,如果線程都不主動釋放所佔有的資源,將產生死鎖。
死鎖的產生的一些特定條件:
- 互斥條件:進程對於所分配到的資源具有排它性,即一個資源只能被一個進程佔用,直到被該進程釋放 。
- 請求和保持條件:一個進程因請求被佔用資源而發生阻塞時,對已獲得的資源保持不放。
- 不剝奪條件:任何一個資源在沒被該進程釋放之前,任何其他進程都無法對他剝奪佔用。
- 循環等待條件:當發生死鎖時,所等待的進程必定會形成一個環路(類似於死循環),造成永久阻塞。
如何避免:
1. 加鎖順序:當多個線程需要相同的一些鎖,但是按照不同的順序加鎖,死鎖就很容易發生。如果能確保所有的線程都是按照相同的順序獲得鎖,那麼死鎖就不會發生。當然這種方式需要你事先知道所有可能會用到的鎖,然而總有些時候是無法預知的。
2. 加鎖時限:加上一個超時時間,若一個線程沒有在給定的時限內成功獲得所有需要的鎖,則會進行回退並釋放所有已經獲得的鎖,然後等待一段隨機的時間再重試。但是如果有非常多的線程同一時間去競爭同一批資源,就算有超時和回退機制,還是可能會導致這些線程重複地嘗試但卻始終得不到鎖。
3. 死鎖檢測:死鎖檢測即每當一個線程獲得了鎖,會在線程和鎖相關的數據結構中(map、graph等等)將其記下。除此之外,每當有線程請求鎖,也需要記錄在這個數據結構中。死鎖檢測是一個更好的死鎖預防機制,它主要是針對那些不可能實現按序加鎖並且鎖超時也不可行的場景。
spring中Bean的作用域
1. singleton:Spring IoC容器中只會存在一個共享的Bean實例,無論有多少個Bean引用它,始終指向同一對象。Singleton作用域是Spring中的缺省作用域。
2. prototype:每次通過Spring容器獲取prototype定義的bean時,容器都將創建一個新的Bean實例,每個Bean實例都有自己的屬性和狀態,而singleton全局只有一個對象。
3. request:在一次Http請求中,容器會返回該Bean的同一實例。而對不同的Http請求則會產生新的Bean,而且該bean僅在當前Http Request內有效。
4. session:在一次Http Session中,容器會返回該Bean的同一實例。而對不同的Session請求則會創建新的實例,該bean實例僅在當前Session內有效。
5. global Session:在一個全局的Http Session中,容器會返回該Bean的同一個實例,僅在使用portlet context時有效。
Spring框架中都用到了哪些設計模式?
1. 代理模式:在AOP和remoting中被用的比較多。
2. 單例模式:在spring配置文件中定義的bean默認為單例模式。
3. 模板方法模式:用來解決代碼重複的問題。
4. 前端控制器模式:Spring提供了DispatcherServlet來對請求進行分發。
5. 依賴注入模式:貫穿於BeanFactory / ApplicationContext接口的核心理念。
6. 工廠模式:BeanFactory用來創建對象的實例。
springmvc的核心是什麼,請求的流程是怎麼處理的,控制反轉怎麼實現的
核心:控制反轉和麵向切面
請求處理流程:
- 首先用戶發送請求到前端控制器,前端控制器根據請求信息(如URL)來決定選擇哪一個頁面控制器進行處理並把請求委託給它,即以前的控制器的控制邏輯部分;
- 頁面控制器接收到請求後,進行功能處理,首先需要收集和綁定請求參數到一個對象,並進行驗證,然後將命令對象委託給業務對象進行處理;處理完畢後返回一個ModelAndView(模型數據和邏輯視圖名);
- 前端控制器收回控制權,然後根據返回的邏輯視圖名,選擇相應的視圖進行渲染,並把模型數據傳入以便視圖渲染;
- 前端控制器再次收回控制權,將響應返回給用戶。
控制反轉如何實現:
- 我們每次使用spring框架都要配置xml文件,這個xml配置了bean的id和class。
- spring中默認的bean為單實例模式,通過bean的class引用反射機制可以創建這個實例。
- 因此,spring框架通過反射替我們創建好了實例並且替我們維護他們。
- A需要引用B類,spring框架就會通過xml把B實例的引用傳給了A的成員變量。
BAT大廠Java高級面試題常見30問
- Spring DAO 中最常用的類是什麼?
- 如何在Spring應用中使用SLF4J?
- Spring bean 的默認作用範圍是?
- 使用@Required但不關聯bean 來註解setter方法,將會發生?
- 已知一棵二叉樹前序遍歷和中序遍歷分別為ABDEGCFH和DBGEACHF,則該二叉樹的後序遍歷為?
- volatile關鍵字是否能保證線程安全?
- Java能不能不通過構造函數創建對象?
- Java程序的併發機制是?
- 方法resume()負責恢復哪些線程的執行?
- 什麼是LinkedHashSet?
- 什麼是可變參數?
- 斷言的用途?
- 什麼時候使用斷言?
- 什麼是垃圾回收?
- 用一個例子解釋垃圾回收?
- 什麼時候運行垃圾回收?
- 垃圾回收的最佳做法?
- 什麼是初始化數據塊?
- 什麼是靜態初始化器?
- 什麼是實例初始化塊?
- 什麼是正則表達式?
- 什麼是令牌化?
- 給出令牌化的例子?
- 如何使用掃描器類(Scanner Class)令牌化?
- 如何添加小時(hour)到一個日期對象(Date Objects)?
- 如何格式化日期對象?
- Java中日曆類(Calendar Class)的用途?
- 如何在Java中獲取日曆類的實例?
- 解釋一些日曆類中的重要方法?
- 數字格式化類(Number Format Class)的用途?
讀者福利
由於篇幅有限,部分答案就不做全部展示了,這些面試題的答案我已經整理成PDF文檔了,同時也整理了一些問題詳解;雖然說花了一點時間,但是我也願意把它免費分享出來,希望能夠幫助到有需要的Java工程師朋友,也省的大家再去網上花時間找資料。
領取方式:關注我後私信我【資料】即可免費獲取
最後,希望看到朋友動動手指,幫忙轉發一下,這樣會幫助到更多的朋友
祝大家學習愉快!