Java 2023年接地氣的中高級面試題一(附答案)

来源:https://www.cnblogs.com/yajunLi/archive/2023/03/22/17243876.html
-Advertisement-
Play Games

直入主題: Q1:為什麼要用分散式鎖? 在分散式系統中,多個進程或線程可能會同時訪問共用資源,這可能會導致數據不一致、併發性問題、性能下降等問題。為瞭解決這些問題,我們通常會使用分散式鎖來協調多個進程或線程對共用資源的訪問。 分散式鎖是一種協調機制,它通過在共用資源上設置鎖來防止多個進程或線程同時訪 ...


直入主題:

 

Q1:為什麼要用分散式鎖?

  在分散式系統中,多個進程或線程可能會同時訪問共用資源,這可能會導致數據不一致、併發性問題、性能下降等問題。為瞭解決這些問題,我們通常會使用分散式鎖來協調多個進程或線程對共用資源的訪問。

  分散式鎖是一種協調機制,它通過在共用資源上設置鎖來防止多個進程或線程同時訪問它。分散式鎖的主要作用如下:

  1. 保證數據的一致性:通過分散式鎖來控制對共用資源的訪問,可以避免多個進程或線程同時修改同一份數據而導致的數據不一致問題。

  2. 提高併發性:通過使用分散式鎖,可以保證每個進程或線程在訪問共用資源時都是排他的,從而避免了併發訪問的問題,提高了系統的併發性。

  3. 避免死鎖:分散式鎖通常會設置超時時間,當一個進程或線程獲取到鎖後在一定時間內未能完成操作,鎖會自動釋放,避免了死鎖的問題。

  總之,使用分散式鎖可以幫助我們在分散式系統中實現數據的一致性、提高系統的併發性和穩定性,從而保證系統的可靠性和高可用性。

 

Q2:分散式鎖用的redis的哪種結構?

  Redis提供了多種實現分散式鎖的方式,常見的有以下兩種:

  1. 基於SETNX命令的實現方式:該方式利用Redis的SETNX命令實現分散式鎖,具體實現流程如下:

    • 在Redis中創建一個鍵值對,鍵為鎖的名稱,值為任意字元串;
    • 當某個進程需要獲取鎖時,它通過SETNX命令嘗試在Redis中創建該鎖對應的鍵值對,如果創建成功(即返回1),則該進程獲取到鎖,如果創建失敗(即返回0),則該進程獲取鎖失敗;
    • 當某個進程需要釋放鎖時,它通過DEL命令刪除該鎖對應的鍵值對。
  2. 基於Redlock演算法的實現方式:該方式是一種分散式鎖的演算法,由Redis官方提出,基於多個Redis實例之間的協調實現分散式鎖,具體實現流程如下:

    • 在多個Redis實例上創建相同的鎖,即相同的鎖名稱和鎖值;
    • 當某個進程需要獲取鎖時,它依次在多個Redis實例上獲取鎖,每個Redis實例的獲取鎖過程與上述基於SETNX命令的方式類似;
    • 當某個進程需要釋放鎖時,它依次在多個Redis實例上釋放鎖,每個Redis實例的釋放鎖過程與上述基於SETNX命令的方式類似;
    • Redlock演算法規定,只有當大多數(超過半數)的Redis實例上的鎖都被某個進程獲取時,該進程才算獲取到了鎖。

  以上兩種方式都是基於Redis的數據結構實現的分散式鎖,具體實現方式有所不同,但都可以有效地解決分散式系統中的併發問題。

  

Q3:為什麼字元串結構不能用來做分散式?

  Redis中的字元串結構可以用來存儲數據,但不能用來實現分散式鎖。這是因為,在分散式系統中,多個進程或線程可能同時訪問共用資源,為了保證數據的一致性和正確性,需要實現對共用資源的互斥訪問。而字元串結構並不支持互斥訪問,也就無法保證共用資源的正確性和一致性。

  另外,即使是對於單機環境,使用字元串結構來實現鎖也是不可行的。因為在Redis中,字元串是原子操作的,即每次操作都是原子性的,但在分散式系統中,多個進程或線程之間的操作是不可預測的,可能會導致競態條件(race condition)和鎖失效的問題。

  因此,在分散式系統中實現鎖需要使用Redis提供的其他數據結構,如上文提到的基於SETNX命令的實現方式和基於Redlock演算法的實現方式。這些數據結構支持互斥訪問和分散式協作,可以實現分散式系統中的鎖功能,從而保證數據的正確性和一致性。

 

Q4:分散式鎖可能會失效的場景是什麼?

  在分散式系統中,分散式鎖是用來協調多個進程或線程之間對共用資源的訪問的,以保證數據的正確性和一致性。但由於分散式系統的複雜性,分散式鎖可能會出現一些失效的場景,如下:

  1. 網路延遲或丟包:由於網路不可靠,分散式系統中的消息可能會出現延遲或丟失的情況,如果分散式鎖的實現依賴於網路通信,這些問題就可能導致鎖失效。

  2. 節點故障:在分散式系統中,節點故障是常見的情況,如果鎖實現依賴於某個節點或實例,當該節點或實例故障時,鎖也可能會失效。

  3. 時鐘不同步:分散式系統中的時鐘可能不同步,導致各個節點之間無法達成一致,如果鎖實現依賴於時間戳或過期時間等機制,就可能導致鎖失效。

  4. 重入問題:如果一個線程已經獲得了分散式鎖,並且在持有鎖的情況下再次嘗試獲取鎖,就會導致死鎖或者其他異常情況。

  5. 鎖誤釋放:如果持有鎖的進程或線程在釋放鎖時出現異常,比如進程崩潰或者網路故障等,就可能導致鎖沒有正確釋放,其他進程或線程無法獲得鎖,從而導致鎖失效。

  針對上述場景,可以通過一些技術手段來減少分散式鎖失效的風險,比如增加重試機制、使用心跳機制等。但是要註意,分散式鎖的失效場景是很複雜的,需要根據具體的業務場景和系統架構進行綜合分析和解決。

 

Q5:spring聲明式事務失效場景有哪些?

  Spring聲明式事務是通過AOP實現的,它的原理是對被@Transactional註解的方法進行代理,然後在方法執行前後進行一些操作,如開啟和提交事務、回滾等。在以下場景中,聲明式事務可能會失效:

  1. 事務傳播行為設置不當:Spring聲明式事務預設使用Propagation.REQUIRED傳播行為,如果在調用方法的過程中使用了不同的傳播行為,就可能導致事務失效。

  2. 異常被吞掉:在方法中捕獲了異常但沒有將其重新拋出或者沒有將其拋給調用方,則可能會導致事務無法回滾。

  3. 基於介面的代理:如果使用了基於介面的代理,且在實現類中調用了自己的另一個方法,那麼該方法調用將不會被事務管理。

  4. 多線程情況:當使用多線程時,若子線程的事務處理方法沒有被@Transactional註解,則可能會導致事務失效。

  5. 資料庫引擎不支持事務:如果使用的資料庫引擎不支持事務,則聲明式事務將會失效。

  6. 註解放錯位置:如果@Transactional註解放置在類上而不是方法上,則事務將不會生效。

  7. 不同的異常類型:如果使用了不同的異常類型,例如RuntimeException而不是Exception,那麼事務可能不會回滾。

  總之,要確保聲明式事務的有效性,應該在調用方法上正確使用@Transactional註解,設置正確的傳播行為,避免吞掉異常,同時註意多線程和資料庫引擎等因素。

 

Q6:嵌套事務有什麼影響?

  在Spring中,嵌套事務是一種事務傳播行為,它允許一個事務在另一個事務的上下文中開啟,形成一個事務嵌套的結構。

  使用嵌套事務可能會對事務的行為產生一些影響,例如:

  1. 回滾行為:當嵌套事務的回滾行為發生時,會影響到外層事務的狀態。如果內層事務回滾,則會導致外層事務也回滾;而外層事務的回滾不會影響到內層事務。

  2. 性能開銷:每個嵌套的事務都需要開啟和提交或回滾,這會帶來一些性能開銷。

  3. 數據一致性:使用嵌套事務時,需要確保內層事務的提交不會影響到外層事務的數據一致性,否則會導致不一致的結果。

  因此,在使用嵌套事務時,需要考慮以上因素,並確保在需要使用嵌套事務時,合理地設置事務傳播行為和隔離級別,以保證數據一致性和事務性能。

 

Q7:springboot怎麼進行非同步處理?

  在Spring Boot中進行非同步處理有多種方式,其中一些常見的方式包括:

  1. 使用@Async註解:通過在方法上添加@Async註解,使方法在非同步線程中執行,可以使用Spring Boot自帶的線程池來管理線程。需要在啟動類中添加@EnableAsync註解開啟非同步處理。

  示例代碼:

@Service
public class MyService {

    @Async
    public CompletableFuture<String> asyncMethod() {
        // 非同步方法邏輯
        return CompletableFuture.completedFuture("非同步方法執行完成");
    }
}

  

  1. 使用CompletableFuture類:CompletableFuture類提供了方便的非同步處理方式,可以通過supplyAsync或runAsync方法創建一個非同步任務,並指定非同步任務的執行邏輯。通過thenApply等方法可以對非同步任務的執行結果進行處理。

  示例代碼:

@Service
public class MyService {

    public CompletableFuture<String> asyncMethod() {
        return CompletableFuture.supplyAsync(() -> {
            // 非同步方法邏輯
            return "非同步方法執行完成";
        });
    }

}

  

  1. 使用@Scheduled註解:可以使用@Scheduled註解創建定時任務,在任務執行時指定執行邏輯。

  示例代碼:

@Service
public class MyService {

    @Scheduled(fixedDelay = 1000)
    public void scheduledMethod() {
        // 定時任務執行邏輯
    }

}

  需要註意的是,使用非同步處理可能會引發一些併發問題,例如線程安全問題、死鎖問題等,需要根據實際場景進行合理的設計和優化。

 

Q8:spring註解使用預設線程池還是自定義線程池?

  Spring中預設情況下使用的是簡單的線程池(SimpleAsyncTaskExecutor),該線程池沒有隊列容量限制,每次調用都會創建一個新的線程,不適用於大規模的併發請求。因此,在實際應用中,應該使用自定義的線程池來處理非同步任務。

  可以使用ThreadPoolTaskExecutor或者ConcurrentTaskExecutor來創建自定義的線程池,具體選擇哪種線程池取決於具體的應用場景。ThreadPoolTaskExecutor是一種基於Java線程池的實現,可以靈活地配置核心線程數、最大線程數、隊列容量等參數;而ConcurrentTaskExecutor是一種基於Java併發包的實現,可以實現更高的併發性能,但是線程池的配置選項較少。

  在使用自定義線程池時,可以通過配置ThreadPoolTaskExecutor或者ConcurrentTaskExecutor的相關參數來優化線程池的性能,例如配置核心線程數、最大線程數、隊列容量、線程存活時間等參數。同時,在設計應用程式時,還需要根據實際情況合理地使用線程池,避免線程安全問題和線程饑餓等問題的發生。

  以下是一個簡單的自定義線程池的示例代碼:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
@EnableAsync
public class AppConfig {

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5); // 核心線程數
        executor.setMaxPoolSize(10); // 最大線程數
        executor.setQueueCapacity(25); // 隊列容量
        executor.setThreadNamePrefix("MyExecutor-"); // 線程名首碼
        executor.initialize(); // 初始化線程池
        return executor;
    }

}  

  上述代碼中,通過@Bean註解將創建的ThreadPoolTaskExecutor類實例化為Spring的Bean,並使用@EnableAsync註解啟用非同步處理功能。在創建線程池時,可以通過setCorePoolSize、setMaxPoolSize、setQueueCapacity等方法設置線程池的核心線程數、最大線程數和隊列容量等參數,並通過setThreadNamePrefix方法設置線程名首碼。最後通過initialize方法初始化線程池,並將線程池返回為一個Executor類型的Bean。

  使用上述自定義線程池的示例:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

@Service
public class MyService {

    @Autowired
    private Executor asyncExecutor; // 註入自定義線程池

    public CompletableFuture<String> asyncMethod() {
        return CompletableFuture.supplyAsync(() -> {
            // 非同步方法邏輯
            return "非同步方法執行完成";
        }, asyncExecutor); // 指定使用自定義線程池
    }

}

  在上述示例代碼中,通過@Autowired註解將自定義的線程池註入到MyService類中,併在非同步方法中通過supplyAsync方法指定使用自定義線程池來執行非同步任務。

 

Q9:說一下常見的幾個線程池?

  在Java中,線程池是一種重要的併發編程工具,可以避免創建和銷毀線程帶來的性能開銷和資源浪費,提高應用程式的性能和穩定性。Java標準庫中提供了許多不同類型的線程池,常見的幾個線程池包括:

  1. FixedThreadPool:固定線程池,所有任務都在同一個固定大小的線程池中執行,適用於需要保證併發線程數不超過指定數量的場景。

  2. CachedThreadPool:緩存線程池,可以動態調整線程數,適用於需要處理大量短時間任務的場景。

  3. SingleThreadExecutor:單線程池,只有一個線程在執行任務,適用於需要按順序執行任務或保證任務的線程安全性的場景。

  4. ScheduledThreadPool:調度線程池,支持按照指定的時間間隔或者時間點執行任務,適用於需要按照特定時間執行任務的場景。

  5. WorkStealingPool:工作竊取線程池,可以動態調整線程數並支持線程間任務竊取,適用於需要處理大量短時間任務且任務之間存在依賴關係的場景。

  6. ForkJoinPool:分治線程池,支持任務拆分和合併,適用於需要處理大量並行計算任務的場景。

  這些線程池都有各自的優點和適用場景,在實際應用中需要根據具體的需求選擇合適的線程池。同時,在使用線程池時,還需要合理地配置線程池參數,以充分利用電腦的資源,提高線程池的執行效率。

 

Q10:講下核心線程數,最大線程數,超時時間,等待隊列等

  在Java中,線程池是一種重要的併發編程工具,常見的線程池參數包括:

  1. 核心線程數(corePoolSize):指線程池中最少保持的活動線程數,當線程池中的線程數小於該值時,新任務將會創建新的線程來處理。對於FixedThreadPool和SingleThreadExecutor,核心線程數即為線程池的大小;對於其他線程池,核心線程數將會一直保持活動狀態,直到線程池關閉。

  2. 最大線程數(maximumPoolSize):指線程池中最大可創建的線程數。當線程池中的線程數達到該值時,新任務將會被阻塞,直到有空閑線程可用。對於FixedThreadPool,最大線程數即為線程池的大小;對於其他線程池,最大線程數可以根據實際需求進行配置。

  3. 超時時間(keepAliveTime):指線程池中空閑線程的存活時間。當線程池中的線程數超過核心線程數時,空閑線程將會在指定時間內被回收。對於其他線程池,如果空閑線程超過該時間,也會被回收。

  4. 等待隊列(workQueue):指線程池中的任務隊列,用於存放等待執行的任務。線程池中的任務將會依次被放入該隊列中,直到有空閑線程可用。對於FixedThreadPool和SingleThreadExecutor,任務隊列為空;對於其他線程池,任務隊列可以根據實際需求進行配置,常見的隊列類型包括有界隊列(ArrayBlockingQueue、LinkedBlockingQueue)和無界隊列(SynchronousQueue)。

  這些線程池參數都會對線程池的性能和行為產生影響,需要根據實際應用場景進行合理的配置。例如,如果任務的執行時間較長,可以適當增加線程池的最大線程數,以避免任務阻塞;如果任務的數量較多,可以增加等待隊列的大小,以緩解線程池的壓力。同時,還需要註意線程池的可擴展性和性能,以避免線程池成為應用程式的瓶頸。

 

暫未結束,下篇見~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 職位一 社招雲計算測試開發工程師 崗位職責: 1、負責雲計算產品的測試設計和測試開發工作,包括計算,存儲,網路等方向; 2、包括但不限於功能、性能、可靠性、用戶體驗等系統性測試; 3、通過技術手段,建設雲計算質量體系,包括產品的功能、性能、質量過程數據,保證產品的穩定性; 4、負責雲計算產品的質量推 ...
  • 前提 小白一個,啥都不會,歡迎指點。 題目 隨機生成10個整數(1-100的範圍),保存到數組,並倒序列印以及求平均值,求最大值和最大值的下標,並查找裡面知否有8。 思路 隨機生成-->採用random(),註意範圍在( 1-100) 。 求取最大值下標插入索引 在再次建立一個索引,以此判斷隨機生成 ...
  • JavaSE:多線程學習 01 初識進程 1.1 Process & Thread 1、首先簡要介紹程式。程式是指令和數據的有序集合,其本身沒有任何運行的含義,只是一個靜態的概念。 2、進程則是執行程式的一次執行過程,是一個動態的概念。是系統資源分配的單位。 3、通常在一個進程中可以包含若幹線程。線 ...
  • Swift 備忘清單 IT寶庫整理的Swift開發速查清單,該清單提供了使用 Swift 的示例,涵蓋 Swift 基礎知識、控制流、類型、結構/類、運算符、函數方法等。入門,為開發人員分享快速參考備忘單。 開發速查表大綱 入門 變數 類型註釋 算術運算符 字元串插值 多行字元串 代碼註釋 組成一個 ...
  • 本文介紹基於Python中ArcPy模塊,對大量柵格遙感影像文件進行批量掩膜與批量重採樣的操作。 首先,我們來明確一下本文的具體需求。現有一個存儲有大量.tif格式遙感影像的文件夾;且其中除了.tif格式的遙感影像文件外,還具有其它格式的文件。 我們希望,依據一個已知的面要素矢量圖層文件,對上述文件 ...
  • aliases: [] tags : " #QA #Java " summary: [POI生成Excel超出的單元格樣式的最大數量] author : [yaenli] notekey: [20230322-100908] 問題現象 使用Apache POI生成Excel時,如果創建的單元格樣式過 ...
  • Tomcat生命周期管理 各種組件如何統一管理 Tomcat的架構設計是清晰的、模塊化、它擁有很多組件,加入在啟動Tomcat時一個一個組件啟動,很容易遺漏組件,同時還會對後面的動態組件拓展帶來麻煩。如果採用我們傳統的方式的話,組件在啟動過程中如果發生異常,會很難管理,比如你的下一個組件調用了sta ...
  • Tcl語言線上運行編譯,是一款可線上編程編輯器,在編輯器上輸入Tcl語言代碼,點擊運行,可線上編譯運行Tcl語言,Tcl語言代碼線上運行調試,Tcl語言線上編譯,可快速線上測試您的Tcl語言代碼,線上編譯Tcl語言代碼發現是否存在錯誤,如果代碼測試通過,將會輸出編譯後的結果。 該線上工具由IT寶庫提 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...