【金三銀四】每日一點面試題(Java--JVM篇)

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

JVM(Java虛擬機)是Java程序運行的核心組件,它負責將Java字節碼翻譯成底層操作系統能夠執行的指令。JVM由以下幾個主要組成部分構成:
在這里插入圖片描述

  1. 類加載器(Class Loader):負責將類的字節碼加載到內存中,并進行驗證、準備和解析等操作。類加載器按照一定的搜索規則查找類文件,并將其加載到內存中,使得程序可以使用這些類。類加載器還支持類的動態加載和卸載。

  2. 執行引擎(Execution Engine):負責執行加載到內存中的字節碼指令。執行引擎可以逐行解釋執行字節碼,也可以將字節碼編譯成本地機器碼再執行。常見的執行引擎有解釋器和即時編譯器(Just-In-Time Compiler,JIT)。

  3. 運行時數據區(Runtime Data Area):是JVM在運行過程中管理數據的區域,包括方法區、堆、棧、程序計數器和本地方法棧等。其中:

    • 方法區(Method Area)用于存儲類的結構信息、常量池、靜態變量等。
    • 堆(Heap)用于存儲對象實例和數組等動態分配的內存。
    • 棧(Stack)用于存儲線程執行方法時的局部變量、操作數棧、方法出口等。
    • 程序計數器(Program Counter)用于記錄線程當前執行的字節碼指令位置。
    • 本地方法棧(Native Method Stack)用于支持Java以外的語言調用。
  4. 垃圾收集器(Garbage Collector):負責自動管理和回收堆內存中不再使用的對象。垃圾收集器通過識別不可達對象,并釋放它們的內存空間,從而防止內存泄漏和提高系統性能。

  5. JIT編譯器(Just-In-Time Compiler):JIT編譯器將熱點代碼(經常執行的代碼塊)從解釋器轉換為本地機器碼,以提高程序的執行效率。JIT編譯器可以根據程序的實際執行情況進行優化,使得程序在運行過程中逐漸變得更快。

這些組成部分共同協作,使得Java程序能夠跨平臺運行,并提供了內存管理、安全性、性能優化等功能,使Java成為一種廣泛應用的編程語言。

其實可以一句話來解釋:類的加載指的是將類的.class文件中的二進制數據讀入
到內存中,將其放在運行時數據區的方法區內,然后在堆區創建一個
java.lang.Class對象,用來封裝類在方法區內的數據結構。

2、說一下 JVM 運行時數據區

JVM(Java虛擬機)的運行時數據區是指在JVM運行過程中用來存儲數據的不同區域,每個區域都有特定的作用和存儲內容。以下是JVM主要的運行時數據區及其作用:

  1. 方法區(Method Area):用于存儲類的結構信息、常量池、靜態變量等。每個類對應一個Class對象,Class對象包含了類的結構信息,如字段、方法、父類、接口等。方法區是線程共享的區域。

  2. 堆(Heap):用于存儲對象實例和數組等動態分配的內存。所有線程共享堆內存。堆內存可以通過-Xms和-Xmx參數來指定初始大小和最大大小。

  3. 棧(Stack):每個線程在執行方法時會創建一個棧幀,棧幀包含了局部變量表、操作數棧、方法出口等信息。棧內存用于存儲方法的局部變量、方法參數、中間計算結果等。棧內存大小可以通過-Xss參數來指定。

  4. 程序計數器(Program Counter):記錄當前線程執行的字節碼指令位置,是線程私有的數據區域。當線程執行Java方法時,程序計數器指向下一條將要執行的指令地址。

  5. 本地方法棧(Native Method Stack):用于支持Java調用本地方法(Native Method),即使用JNI(Java Native Interface)調用其他編程語言編寫的庫。本地方法棧與Java虛擬機棧類似,區別在于本地方法棧執行的是本地方法。

這些運行時數據區域共同組成了JVM的內存模型,負責管理程序運行時所需的數據。合理管理這些區域的內存分配和釋放對于程序的性能和穩定性具有重要影響。

3、深拷貝和淺拷貝

深拷貝和淺拷貝是編程中處理對象復制操作時經常遇到的概念,特別是在使用引用數據類型(如對象和數組)時。

淺拷貝(Shallow Copy):

  • 淺拷貝指的是復制一個對象的時候,僅僅復制對象本身及其包含的引用,但不復制引用指向的對象本身。
  • 在淺拷貝操作中,如果對象的屬性是基本數據類型(如字符串、數字、布爾值等),則直接復制這些屬性的值;如果屬性是引用數據類型(如對象、數組等),則復制的是這些引用數據類型的引用,也就是說,原始對象和淺拷貝對象中的引用類型屬性實際上指向同一塊內存區域。
  • 因此,如果原始對象或淺拷貝對象中的一個修改了引用類型的屬性,另一個也會受到影響。

深拷貝(Deep Copy):

  • 深拷貝指的是復制一個對象以及這個對象所有的引用指向的對象的復制。
  • 在深拷貝操作中,無論對象的屬性是基本數據類型還是引用數據類型,都會復制一份新的出來。對于引用數據類型,會遞歸地創建一個新的對象或數組,并將原始對象的引用類型屬性的內容復制到新對象中。
  • 因此,原始對象和深拷貝對象之間完全獨立,一個對象的修改不會影響另一個對象。

使用場景:

  • 淺拷貝通常用于創建一個對象的備份,但不需要復制嵌套對象,或者嵌套對象不會被修改的情況。
  • 深拷貝通常用于需要完全分離原始對象和復制對象的情況,特別是在嵌套對象需要被獨立修改時。

4、說一下堆棧的區別?

堆(Heap)和棧(Stack)是在計算機內存管理中常見的兩種數據結構,它們在用途、分配方式、存儲內容以及管理方式等方面有著明顯的區別。

  1. 用途:

    • 堆:用于存儲動態分配的內存空間,主要用于存儲對象實例和數組等。
    • 棧:用于存儲方法的局部變量、方法參數、中間計算結果以及方法調用的棧幀等。
  2. 分配方式:

    • 堆:由程序員手動申請和釋放內存,通常通過new關鍵字分配堆內存,由Java虛擬機的垃圾回收器自動回收不再使用的對象。
    • 棧:由編譯器自動分配和釋放內存,遵循"先進后出"的原則,方法調用時會在棧上創建一個棧幀,方法執行結束時會彈出棧幀。
  3. 存儲內容:

    • 堆:存儲對象的實例和數組,對象在堆上分配內存,但實際對象本身可能位于堆上或者棧上。
    • 棧:存儲方法的局部變量、方法參數、中間計算結果等,以及方法調用的相關信息。
  4. 管理方式:

    • 堆:由垃圾回收器自動管理內存,負責回收不再使用的對象以及內存碎片整理等操作。
    • 棧:由編譯器和運行時系統自動管理,保證方法的局部變量等數據的正確分配和釋放。

總的來說,堆和棧在內存管理中扮演著不同的角色。堆用于存儲動態分配的內存,主要用于存儲對象實例和數組;而棧用于存儲方法調用的局部變量和方法調用信息。在Java中,對象實例通常存儲在堆上,而方法調用的局部變量等數據則存儲在棧上。

5、隊列和棧是什么?有什么區別?

隊列(Queue)和棧(Stack)是計算機科學中兩種常見的數據結構,它們在元素存儲和訪問方面有著明顯的區別。

  1. 隊列(Queue):

    • 隊列是一種先進先出(First In First Out, FIFO)的數據結構,類似于現實生活中排隊的概念。在隊列中,新的元素被添加到隊尾,而從隊列中移除元素時則是從隊頭開始移除。這樣保證了最先進入隊列的元素會最先被取出。
    • 常見的隊列實現包括普通隊列、雙端隊列和優先級隊列等。
  2. 棧(Stack):

    • 棧是一種后進先出(Last In First Out, LIFO)的數據結構,類似于現實生活中堆放盤子的概念。在棧中,新的元素被壓入棧頂,而從棧中移除元素時也是從棧頂開始移除。這樣保證了最后壓入棧的元素會最先被彈出。
    • 常見的棧實現包括普通棧和雙端棧等。
  3. 區別:

    • 主要區別在于元素的存儲和訪問順序。隊列是先進先出的,而棧是后進先出的。
    • 隊列適用于需要按照先后順序處理元素的場景,例如任務調度、消息傳遞等;棧適用于需要反向處理元素的場景,例如表達式求值、函數調用等。
    • 在實際應用中,隊列和棧都有各自的優點和用途,具體選擇取決于所需的數據操作方式和算法需求。

總的來說,隊列和棧是兩種常見的數據結構,它們在元素存儲和訪問順序上有明顯的區別,分別適用于不同的應用場景和算法需求。

6、HotSpot虛擬機對象探秘

在這里插入圖片描述

在HotSpot虛擬機中,當遇到一條new指令時,會按照以下步驟來處理對象的創建和內存分配過程:

  1. 檢查常量池和類加載:

    • 虛擬機首先檢查常量池中是否已經加載了相應的類。如果沒有加載,就需要執行類加載過程,包括加載、驗證、準備、解析和初始化等步驟。
  2. 內存分配:

    • 根據Java堆中內存的規整性,選擇合適的分配方式:
      • 如果Java堆內存是絕對規整的,可以使用“指針碰撞”方式分配內存,即在堆內存中找到合適大小的內存塊進行分配。
      • 如果Java堆內存不規整,就需要從空閑列表中分配內存,這種方式稱為“空閑列表”方式。
  3. 并發處理:

    • 在內存分配過程中,需要考慮并發情況,HotSpot虛擬機提供了兩種并發處理方式:
      • CAS同步處理:使用Compare and Swap(CAS)等原子操作來保證多線程并發訪問的正確性。
      • Thread Local Allocation Buffer(TLAB):為每個線程在Eden區分配一個本地線程緩沖區,避免多線程競爭分配內存時的同步問題。
  4. 內存空間初始化:

    • 內存空間分配后,需要進行初始化操作,包括對象頭信息、哈希碼等的設置。
  5. 對象設置:

    • 執行必要的對象設置,如設置對象的元信息、哈希碼等。
  6. 執行方法:

    • 最后執行對象的構造方法,完成對象的初始化。

通過以上步驟,HotSpot虛擬機能夠有效地處理對象的創建和內存分配過程,同時考慮到內存的規整性、并發處理以及對象初始化等方面的問題,確保程序的正確性和性能。

7、Java會存在內存泄漏嗎?請簡單描述

Java確實存在內存泄漏的情況。內存泄漏指的是不再被使用的對象或變量一直占據在內存中。盡管Java擁有垃圾回收機制,理論上不再被使用的對象會被自動回收,但在某些情況下,Java程序仍然可能出現內存泄漏。

主要原因包括:

1、長生命周期對象持有短生命周期對象的引用:當一個長生命周期的對象持有一個短生命周期對象的引用時,即使短生命周期對象不再需要,它也無法被垃圾回收器回收。例如,將一個對象放入全局變量中,即使后續不再使用,由于全局變量的生命周期很長,這個對象也無法被回收。

2、內部類與外部類的引用關系:如果一個外部類的實例方法返回了一個內部類的實例對象,并且這個內部類對象被長期引用,即使外部類實例不再被使用,由于內部類持有外部類的實例引用,外部類實例也無法被垃圾回收。

3、集合類未正確清理元素:在使用集合類如ArrayList時,如果僅通過調用remove()方法刪除元素,而沒有將對應的引用設置為null,那么這些元素仍然可被訪問,導致無法被垃圾回收。

4、靜態集合類不當使用:靜態集合類如HashMap、ArrayList等如果被用來存儲與生命周期較長的靜態變量相關的對象,這些對象即使不再需要,也難以被回收。

5、資源未關閉:未正確關閉的資源如數據庫連接、文件流等,它們持有的對象也無法被回收。

6、 finalize方法濫用:過度依賴對象的finalize()方法來釋放資源也可能導致內存泄漏。

總之,盡管Java擁有垃圾回收機制,但不當的編程習慣仍然可能導致內存泄漏。因此,編寫代碼時需要注意避免長生命周期對象持有短生命周期對象的引用,并確保及時清理不再需要的對象。

8、簡述Java垃圾回收機制

Java垃圾回收機制是Java虛擬機提供的一種自動內存管理功能,用于在運行時動態回收不再被使用的對象占用的內存空間。其核心目標是通過自動管理內存,減輕程序員手動管理內存的負擔,并提高程序的健壯性和穩定性。

Java垃圾回收機制主要具有以下特點:

1、自動管理:Java虛擬機會自動執行垃圾回收,程序員無需手動釋放內存。

2、不可預測性:垃圾回收的觸發時間和執行時間是不可預測的,程序員無法精確控制。

3、回收范圍:垃圾回收主要針對Java堆內存中的對象空間,不涉及棧內存、寄存器等。

4、引用計數:垃圾回收器會跟蹤對象的引用數量,當對象引用數量為0時,判定為可回收對象。

5、標記-清除:主流的垃圾回收算法包括標記-清除、復制、標記-整理等,各有優缺點。

6、finalize方法:在對象被回收前,垃圾回收器會調用對象的finalize方法,但該方法并不保證一定會被調用。

7、GC通知:程序員可以通過System.gc()來建議垃圾回收器執行垃圾回收,但具體是否執行由垃圾回收器決定。

8、性能開銷:垃圾回收會占用CPU時間,影響程序性能,因此需要合理配置垃圾回收器參數。

總的來說,Java垃圾回收機制極大地簡化了內存管理,但同時也存在一定的不確定性,程序員需要了解其工作原理,并采取一些措施來提高垃圾回收的效率。

9、GC是什么?為什么要GC

GC是Garbage Collection的縮寫,中文稱為“垃圾回收”。它是編程語言中一種自動內存管理的形式,旨在回收不再使用的內存空間,以便這些空間可以被重新分配給其他對象使用。

為什么要GC?
1、避免內存泄漏:如果沒有垃圾回收機制,程序員需要手動管理內存的分配和釋放。這很容易導致內存泄漏,即不再需要的內存沒有被釋放,隨著程序運行時間的增長,內存占用會越來越高。

2、簡化內存管理:垃圾回收機制使得程序員不必擔心內存的分配和釋放,從而可以將更多的精力集中在業務邏輯的實現上。

3、提高開發效率:手動管理內存是一個繁瑣且容易出錯的過程。垃圾回收機制可以自動完成這一工作,提高開發效率。

4、保證程序穩定性:內存管理不當可能導致程序崩潰或產生不可預知的行為。垃圾回收機制有助于減少這類問題。

5、適應動態內存需求:現代應用程序經常需要動態地創建和銷毀對象,垃圾回收可以有效地管理這種動態內存需求。

6、優化資源使用:垃圾回收器可以根據當前系統的資源使用情況來調整回收策略,從而優化內存使用。

7、減少停頓時間:雖然垃圾回收會占用CPU時間,但現代垃圾回收器設計的目標是盡量減少停頓時間(Stop-The-World),使得垃圾回收對程序運行的影響降到最低。

垃圾回收機制在大多數現代編程語言中都是不可或缺的部分,它使得內存管理更加高效和可靠。然而,垃圾回收也帶來了一些挑戰,比如需要選擇合適的垃圾回收策略、調整垃圾回收器參數以適應不同的應用場景,以及處理垃圾回收可能帶來的性能開銷。

10、垃圾回收的優點和原理。并考慮2種回收機制

垃圾回收的優點和原理:

垃圾回收是自動內存管理的一種形式,它的主要目的是自動釋放程序不再使用的內存。以下是垃圾回收的一些優點:

1、避免內存泄漏:垃圾回收可以自動釋放不再使用的內存,避免手動管理內存時可能出現的內存泄漏問題。

2、簡化內存管理:程序員無需手動管理內存的分配和釋放,可以更專注于業務邏輯的實現。

3、提高程序穩定性:垃圾回收可以減少因內存管理不當導致的程序崩潰或不可預知行為。

4、適應動態內存需求:垃圾回收可以有效地管理程序運行時動態創建和銷毀的對象。

垃圾回收的原理主要是通過跟蹤對象的引用來判定哪些對象是“活”的,哪些是“死”的。當一個對象沒有任何“活”的引用時,它就被認為是“死”的,可以被回收。垃圾回收器會定期執行垃圾回收,釋放“死”對象的內存空間。

考慮兩種常見的垃圾回收機制:

標記-清除(Mark-Sweep)算法:
1、標記階段:垃圾回收器會從一組根對象開始,標記所有從這些根對象可達的對象。
2、清除階段:垃圾回收器會遍歷堆內存,標記那些在標記階段未被標記的對象,這些對象被視為垃圾,可以被回收。
3、回收階段:垃圾回收器會釋放那些被標記為垃圾的對象所占用的內存空間。

復制(Copying)算法:
1、復制階段:垃圾回收器會將活著的對象從當前內存區域復制到一個新的內存區域。
2、清除階段:垃圾回收器會清除當前內存區域,釋放其內存空間。
3、交換階段:垃圾回收器會將新內存區域設置為當前內存區域,并重復使用舊的內存區域。
標記-清除算法的優點是避免了內存的頻繁復制,適合老年代對象;缺點是回收過程中會產生內存碎片。復制算法的優點是可以快速回收,并且回收后內存是連續的,沒有碎片;缺點是需要額外的內存來復制對象,適合新生代對象。

11、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內存嗎?有什么辦法主動通知虛擬機進行垃圾回收?

垃圾回收器的基本原理是通過檢測和識別不再被程序引用的對象,然后釋放它們所占用的內存空間,以便供程序后續使用。這樣可以避免內存泄漏和提高內存利用率。

垃圾回收器不能馬上回收內存。它會周期性地或者在系統空閑時執行垃圾回收操作。具體的回收時機由虛擬機決定,一般會受到當前系統資源的影響和垃圾回收算法的選擇。

主動通知虛擬機進行垃圾回收的方式包括:

  1. System.gc()方法:通過調用System.gc()方法,程序可以建議虛擬機執行垃圾回收操作,但并不能強制要求。
  2. Runtime.getRuntime().gc()方法:同樣地,通過調用Runtime.getRuntime().gc()方法也可以建議虛擬機執行垃圾回收操作。

需要注意的是,虛擬機并不一定會立即響應這些垃圾回收的建議,而是根據自身的策略和當前的系統資源情況來決定是否執行垃圾回收操作。

12、Java 中都有哪些引用類型?

在Java中,主要有四種引用類型,它們分別是:

  1. 強引用(Strong Reference):強引用是最常見的引用類型。當一個對象被強引用關聯時,它不會被垃圾回收器回收,即使系統內存不足時也不會被回收。例如:Object obj = new Object();

  2. 軟引用(Soft Reference):軟引用用來描述一些還有用但非必需的對象。在系統將要發生內存溢出之前,這些對象會被回收。軟引用可以通過java.lang.ref.SoftReference類來實現。

  3. 弱引用(Weak Reference):弱引用是用來描述非必需對象的引用。如果一個對象只被弱引用關聯,那么它在下一次垃圾回收時就會被回收。弱引用可以通過java.lang.ref.WeakReference類來實現。

  4. 虛引用(Phantom Reference):虛引用是最弱的一種引用類型。一個對象如果只被虛引用關聯,那么它在任何時候都可能被垃圾回收器回收。虛引用可以通過java.lang.ref.PhantomReference類來實現。

這些引用類型在Java中提供了靈活的內存管理方式,使得開發人員可以更好地控制對象的生命周期和內存占用。

13、怎么判斷對象是否可以被回收?

在Java中,判斷一個對象是否可以被回收主要依賴于垃圾回收器使用的可達性分析算法。以下是一些常見的可達性分析算法:

1、引用計數算法:

  • 每個對象都有一個引用計數器,用于記錄該對象被引用的次數。
  • 當一個對象被創建并初始化時,其引用計數為1。
  • 當有一個新的引用指向該對象時,引用計數加1。
  • 當一個引用失效時(例如,一個局部變量離開了作用域),引用計數減1。
  • 當對象的引用計數變為0時,表示該對象不再被任何其他對象或變量所引用,因此可以被垃圾回收器回收。

GC Root可達性分析算法:

  • 這是根搜索算法的一種擴展,不僅考慮直接從根對象可達的對象,還考慮那些通過一系列引用鏈可達的對象。
  • 垃圾回收器會定義一系列的“GC Roots”,包括但不限于根對象,并遞歸地遍歷這些GC Roots,標記所有可達的對象。
  • 不可達的對象將被視為垃圾,可以被垃圾回收器回收。
  • 在Java中,垃圾回收器會定期執行這些算法來判斷哪些對象是“活”的,哪些是“死”的。當一個對象被判定為“死”時,它就可以被垃圾回收器回收,從而釋放其占用的內存空間。

14、在Java中,對象什么時候可以被垃圾回收

在Java中,對象可以被垃圾回收的條件是它不再被任何“活”的線程或“活”的GC Roots所引用。以下是一些常見的條件,當滿足這些條件時,對象就可以被垃圾回收:

1、對象引用計數為0:在引用計數算法中,當對象的引用計數變為0時,表示沒有任何“活”的對象或變量引用該對象,因此可以被垃圾回收。

2、對象不可達:在根搜索算法中,當對象從GC Roots不可達時,表示沒有任何“活”的線程或GC Roots引用該對象,因此可以被垃圾回收。

3、對象被顯式設置為null:當對象的最后一個引用被顯式設置為null時,該對象就不再被引用,可以被垃圾回收。

4、對象生命周期結束:當對象的生命周期結束時,例如,一個局部變量離開了作用域,它所引用的對象就不再被引用,可以被垃圾回收。

5、對象所在類被卸載:當一個類被卸載時,該類的所有實例對象都會被垃圾回收。

6、對象所在線程結束:當一個線程結束時,該線程棧中的對象都會被垃圾回收。

7、顯式調用System.gc():雖然這只是一個建議,垃圾回收器可能會在調用System.gc()后執行垃圾回收,但不保證一定會回收對象。

需要注意的是,垃圾回收是Java虛擬機的一項自動管理功能,程序員無法精確控制垃圾回收的時機。垃圾回收器會根據一定的策略和算法,在適當的時機自動執行垃圾回收。

15、JVM中的永久代中會發生垃圾回收嗎

在Java虛擬機(JVM)中,永久代(PermGen)是方法區的一種實現,用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。在Java 8之前,永久代是JVM內存結構的一部分,而在Java 8及以后的版本中,永久代被元數據區(Metaspace)所取代,直接使用本地內存(Native Memory)。

對于Java 8及以后的版本,垃圾回收不會發生在元數據區,因為它是直接使用本地內存的。當元數據區滿了或者超過了臨界值時,會觸發完全垃圾回收(Full GC),但這主要是為了清理堆內存中的對象,而元數據區的清理則由元數據區的內存管理機制來處理。

對于Java 8之前的版本,永久代中的垃圾回收主要回收兩部分內容:

1、常量池中廢棄的常量:如果常量池中的常量沒有被任何地方引用,那么它可以被垃圾回收。

2、不再使用的類型(類):判斷一個類是否不再被使用需要同時滿足以下三個條件:

  • 該類的所有實例都已經被回收,即堆中不存在該類及其任何派生子類的實例。
  • 加載該類的類加載器已經被回收,這個條件通常是很難達到的。
  • 該類對應的java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。

16、說一下 JVM 有哪些垃圾回收算法?

JVM 中主要的垃圾回收算法包括以下幾種:

1、標記-清除(Mark-Sweep)算法:
標記階段:標記所有活動的對象。
清除階段:回收未被標記的對象所占用的空間。
優點:實現簡單,不需要額外的內存空間。
缺點:會產生內存碎片,可能導致后續分配大對象時出現問題。

2、復制(Copying)算法:
將內存分為兩塊,每次只使用其中一塊。
在垃圾回收時,將活動的對象復制到另一塊內存區域,然后清理掉舊的內存區域。
優點:沒有內存碎片,回收速度快。
缺點:內存利用率低,需要額外的內存空間。

3、標記-整理(Mark-Compact)算法:
標記階段:標記所有活動的對象。
整理階段:將所有活動的對象移動到內存的一端,然后清理掉邊界以外的內存。
優點:沒有內存碎片。
缺點:需要移動對象,回收速度較慢。

4、分代收集算法:
根據對象的生命周期將內存劃分為不同的區域,如新生代和老年代。
新生代使用復制算法,老年代使用標記-整理或標記-清除算法。
優點:可以提高垃圾回收的效率。

17、說一下 JVM 有哪些垃圾回收器?

Java虛擬機(JVM)中常見的垃圾回收器包括以下幾種:

1、串行垃圾回收器(Serial GC):
新生代使用標記-復制(mark-copy)算法。
老年代使用標記-清除-整理(mark-sweep-compact)算法。
優點:簡單高效,停頓時間短。
缺點:在垃圾回收時會暫停其他所有工作線程(Stop-The-World)。

2、并行垃圾回收器(Parallel GC):
新生代使用標記-復制(mark-copy)算法。
老年代使用標記-清除-整理(mark-sweep-compact)算法。
優點:在多核CPU環境下,可以充分利用多個CPU并行處理垃圾回收,提高應用程序的吞吐量。
缺點:在垃圾回收時會暫停其他所有工作線程(Stop-The-World)。

3、并發標記清除垃圾回收器(CMS GC):
老年代使用標記-清除(mark-sweep)算法。
優點:在垃圾回收時允許應用程序的線程與垃圾回收線程并發執行,減少應用程序的停頓時間。
缺點:因為并發執行,垃圾回收的總體吞吐量會降低,同時會產生內存碎片。

4、G1(Garbage-First)垃圾回收器:
使用標記-清除-整理(mark-sweep-compact)算法。
優點:可以預測停頓時間,適合要求低延遲的大堆內存應用,同時避免內存碎片。
缺點:因為要跟蹤每個區域的垃圾回收價值,所以其內部數據結構比其他回收器復雜,性能開銷較大。

5、ZGC(Z Garbage Collector):
使用標記-整理(mark-compact)算法。
優點:低延遲,高并發,適合多核心機器,停頓時間不會隨著堆內存的增加而增加。
缺點:目前還在持續優化中,可能會影響應用程序的性能。

18、詳細介紹一下 CMS 垃圾回收器?

CMS(Concurrent Mark Sweep)垃圾回收器是Java虛擬機(JVM)中的一種垃圾回收器,主要用于回收老年代(Tenured Generation)的內存。CMS垃圾回收器的設計目標是減少應用程序的停頓時間,特別是在多線程應用程序中。以下是對CMS垃圾回收器的詳細介紹:

工作原理
CMS垃圾回收器使用標記-清除(Mark-Sweep)算法,該算法包括以下幾個主要階段:

1、初始標記(Initial Mark):
這個階段會暫停所有的用戶線程(Stop-The-World事件)。
CMS垃圾回收器會標記所有從GC Roots直接可達的對象。

2、并發標記(Concurrent Mark):
在這個階段,CMS垃圾回收器與應用程序線程并發執行。
它會標記所有從GC Roots間接可達的對象。

3、預清理(Preclean):
這個階段也是并發執行的,它會嘗試處理在并發標記階段因為應用程序線程運行而發生變化的對象。

4、可終止的預清理(Concurrent Preclean):
這個階段同樣是并發執行的,它會再次嘗試處理在并發標記和預清理階段因為應用程序線程運行而發生變化的對象。
這個階段可能會重復多次,直到滿足某些終止條件。

5、重新標記(Final Remark):
這個階段會再次暫停所有的用戶線程(Stop-The-World事件)。
CMS垃圾回收器會重新掃描應用程序的根集合,并標記在并發標記階段發生變化的對象。

6、并發清除(Concurrent Sweep):
在這個階段,CMS垃圾回收器與應用程序線程并發執行,清除所有未被標記為活動的對象。

優點
1、低停頓時間:CMS垃圾回收器在并發標記和并發清除階段與應用程序線程同時運行,減少了應用程序的停頓時間。

2、適用于多線程應用程序:CMS垃圾回收器適用于對響應時間要求較高的多線程應用程序,如Web服務器。

缺點
1、垃圾回收吞吐量較低:由于CMS垃圾回收器需要與應用程序線程并發執行,這可能會降低應用程序的總體吞吐量。
2、內存碎片:標記-清除算法不移動對象,可能導致內存碎片化,這可能會影響后續的內存分配。
3、浮動垃圾:在并發清除階段,應用程序可能會產生新的垃圾,這些垃圾只能在后續的垃圾回收周期中被清除。

JVM參數
要啟用CMS垃圾回收器,可以使用以下JVM參數:

-XX:+UseConcMarkSweepGC

此外,還可以通過其他參數來調整CMS垃圾回收器的行為,例如設置堆內存大小、觸發垃圾回收的閾值等。

注意事項
CMS垃圾回收器不適用于新生代(Young Generation)的內存回收,它通常與ParNew垃圾回收器(一種新生代垃圾回收器)一起使用。
從Java 9開始,CMS垃圾回收器被標記為“deprecated”,并在Java 14中被完全移除,取而代之的是G1垃圾回收器。
CMS垃圾回收器在Java 8及之前的版本中是一種流行的垃圾回收器選擇,尤其適用于需要低延遲的應用程序。然而,隨著G1和ZGC等更先進的垃圾回收器的出現,CMS垃圾回收器的使用已經逐漸減少。

19、新生代垃圾回收器和老年代垃圾回收器都有哪些?有什么區別?

新生代和老年代垃圾回收器在Java虛擬機中各有不同的實現,它們在對象生命周期、垃圾回收策略等方面存在一些區別:

新生代垃圾回收器:

1、Serial GC:單線程執行,使用復制算法,適用于單核CPU環境,簡單高效但會暫停其他線程。

2、ParNew GC:Serial GC的多線程版本,適用于多核CPU環境,同樣使用復制算法,但暫停時間可能更長。

3、Parallel GC:與ParNew類似,適用于多核CPU環境,使用復制算法,提供更高的吞吐量,但也會暫停其他線程。

老年代垃圾回收器:

1、Serial Old GC:Serial GC的老年代版本,單線程執行,使用標記-整理算法。

2、Parallel Old GC:Parallel GC的老年代版本,多線程執行,使用標記-整理算法,適用于多核CPU環境,提供高吞吐量。

3、Concurrent Mark Sweep (CMS) GC:以最短回收停頓時間為目標,使用標記-清除算法,回收老年代對象,但可能會產生內存碎片。

4、Garbage-First (G1) GC:將堆內存分割為多個大小相等的獨立區域,根據各個區域垃圾回收的價值和成本進行優先級排序,旨在提供可控的停頓時間。

區別:

對象生命周期:新生代中的對象一般存活時間較短,而老年代中的對象存活時間較長。

垃圾回收算法:新生代垃圾回收器通常采用復制算法,而老年代垃圾回收器采用標記-整理或標記-清除算法。

停頓時間:新生代垃圾回收器的停頓時間較短,而老年代垃圾回收器的停頓時間較長。

內存碎片:新生代垃圾回收器由于采用復制算法,不會產生內存碎片,而老年代垃圾回收器可能產生內存碎片。

回收頻率:新生代垃圾回收器通常更頻繁地進行垃圾回收,而老年代垃圾回收器的回收頻率較低。

20、簡述分代垃圾回收器是怎么工作的?

分代垃圾回收器是基于這樣一個觀察:不同的對象有不同的生命周期,因此可以將對象根據其生命周期分成不同的代,然后對每一代使用最合適的垃圾回收策略。以下是對分代垃圾回收器工作原理的簡要概述:

對象分類:在Java堆內存中,對象被分為三個代:新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation,Java 8之前)或元數據區(Metaspace,Java 8及以后)。新生代中的對象生命周期較短,而老年代中的對象生命周期較長。

新生代垃圾回收:新生代垃圾回收器(如Serial GC、ParNew GC、Parallel GC)通常使用復制算法。新生代被進一步劃分為一個或多個Eden區和兩個Survivor區(From和To)。新創建的對象首先在Eden區分配。當Eden區滿時,進行Minor GC,將Eden區和From區中存活的對象復制到To區,然后清空Eden區和From區。To區和From區互換角色。經過多次Minor GC后,仍然存活的對象會被晉升到老年代。

老年代垃圾回收:老年代垃圾回收器(如Serial Old GC、Parallel Old GC、CMS GC、G1 GC)通常使用標記-清除或標記-整理算法。當老年代的空間不足以分配新對象時,進行Major GC(也稱為Full GC),標記所有存活的對象,然后清除未被標記的對象。在某些情況下,為了減少內存碎片,會進行標記-整理,將所有存活的對象移動到老年代的一端。

永久代/元數據區垃圾回收:永久代(Java 8之前)或元數據區(Java 8及以后)用于存儲類信息、常量池等數據。這部分區域的垃圾回收通常與老年代的垃圾回收一起發生,主要是清理不再使用的類信息和常量池。

分代垃圾回收器通過將對象按生命周期分類,并對每一代使用最適合的垃圾回收策略,從而提高了垃圾回收的效率和性能。新生代的Minor GC通常比老年代的Major GC更頻繁,但停頓時間更短。

注意:元數據區的垃圾回收

在Java 8及以后的版本中,永久代(Permanent Generation)被元數據區(Metaspace)所取代。元數據區直接使用本地內存(Native Memory),而不是Java堆內存。它的主要作用是存儲類的元數據,包括類信息、常量池、方法信息等。

關于元數據區的垃圾回收,有以下幾點需要注意:

類卸載:當類的Class對象不再被引用,并且滿足一定的卸載條件時(如類的所有實例都已被回收,類加載器也被回收,且沒有任何地方通過反射訪問該類的方法),該類的元數據可以被卸載,從而釋放元數據區中的內存。

常量池清理:類似于類卸載,當常量池中的常量不再被任何地方引用時,它們也可以被清理掉。

元數據區內存管理:與Java堆內存不同,元數據區不使用傳統的垃圾回收算法(如標記-清除或復制算法)。相反,它依賴于內部的內存管理機制來處理類的卸載和常量池的清理。

Full GC影響:當發生Full GC時,雖然主要是為了清理堆內存中的對象,但也會影響到元數據區。Full GC會觸發元數據區的清理工作,例如卸載不再使用的類。

參數控制:元數據區的最大和最小大小可以通過JVM參數來控制,例如-XX:MaxMetaspaceSize和-XX:CompressedClassSpaceSize。

綜上所述,元數據區確實會發生垃圾回收,但它是通過類卸載和常量池清理的方式來進行的,而不是使用傳統的堆內存垃圾回收算法

21、簡述java內存分配與回收策略以及Minor GC和Major GC

Java內存分配與回收策略主要包括堆內存的劃分、對象的內存分配和垃圾回收算法。Java將內存劃分為堆內存(Heap)和方法區(Method Area),其中堆內存用于存儲對象實例,而方法區用于存儲類的結構信息、靜態變量、常量池等。

在堆內存中,通常將其劃分為年輕代(Young Generation)、老年代(Old Generation)和永久代(在Java 8之前的版本中存在)。對象首先被分配到年輕代的Eden區,經過一段時間的存活后會被移到幸存者區(Survivor Space)。在經過多次垃圾回收后,仍然存活的對象會被晉升到老年代。

Java的垃圾回收主要通過Minor GC和Major GC來完成內存回收。

  • Minor GC:也稱為新生代GC,指的是對年輕代(包括Eden區和幸存者區)的垃圾回收。在Minor GC中,會清理年輕代中的無用對象,發生頻率比較高。通常采用復制算法進行垃圾回收,即將存活對象復制到幸存者區,清理Eden區和幸存者區中的無用對象。

  • Major GC:也稱為老年代GC,指的是對老年代的垃圾回收。在Major GC中,會清理老年代中的無用對象,發生頻率相對較低。通常采用標記-清除或標記-整理算法進行垃圾回收,以清理老年代中較大的對象。

通過這種分代的內存管理和垃圾回收策略,Java可以更高效地管理內存,減少內存碎片化問題,并提高垃圾回收的性能。同時,Java虛擬機還提供了不同的垃圾收集器(如Serial GC、Parallel GC、CMS GC、G1 GC等),可以根據應用場景和需求選擇合適的垃圾收集器來優化性能。

22、簡述java類加載機制?

Java類加載機制是指在程序運行過程中,將類的字節碼文件加載到內存中,并轉換為運行時數據結構的過程。Java類加載機制主要包括以下幾個步驟:

  1. 加載(Loading):加載是指通過類加載器將類的字節碼文件加載到內存中。在加載階段,類加載器會根據類的全限定名(fully qualified name)查找類文件,并讀取其二進制數據流。

  2. 驗證(Verification):驗證階段對加載的類進行驗證,確保其符合Java虛擬機規范和安全規范,以防止惡意代碼的執行。

  3. 準備(Preparation):準備階段是為類的靜態變量分配內存并設置默認初始值(零值),這些變量會在類加載的初始化階段被顯式賦值。

  4. 解析(Resolution):解析階段是將類、接口、字段和方法的符號引用解析為直接引用的過程,以便于后續的訪問和使用。

  5. 初始化(Initialization):初始化階段是類加載過程的最后一步,會執行類構造器()方法,對類的靜態變量進行顯示賦值等操作。

需要注意的是,類加載過程中的驗證、準備和解析并不是必需的,而是根據需要來執行的。此外,Java類加載機制采用雙親委派模型,即除了啟動類加載器(Bootstrap ClassLoader)外,每個類加載器在加載類時都會先委托給其父類加載器進行加載,只有在父類加載器無法加載時才由子類加載器自行加載。

通過類加載機制,Java實現了動態加載和運行時多態性,使得程序可以根據需要動態加載類,并在運行時適應不同的環境和需求。

23、描述一下JVM加載Class文件的原理機制

JVM加載Class文件的原理機制如下:

1、類加載器(ClassLoader):JVM使用類加載器來加載Class文件。類加載器本身也是一個類,它的主要職責是將Class文件從文件系統或網絡等位置加載到JVM內存中。

2、加載過程:當程序首次使用一個類時,類加載器會進行加載。加載過程包括讀取Class文件并解析,將其轉換為JVM能夠識別的數據結構,然后將這些數據結構存放在方法區(Method Area)中。

3、連接過程:連接過程包括驗證、準備和解析(可選)。

驗證:確保Class文件的字節流符合JVM規范,沒有安全方面的問題。
準備:為類變量分配內存,并設置默認初始值。
解析:將類、接口、字段和方法的符號引用轉換為直接引用。

4、初始化:初始化階段是執行類構造器()方法的過程,該方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態代碼塊中的語句合并產生的。這個階段會執行靜態變量賦值和靜態代碼塊。

5、使用:當初始化完成后,Class對象可以被用來創建實例、調用方法等。

6、卸載:當Class對象不再被引用,即無法在任何地方通過反射訪問該類的方法,并且滿足一定的卸載條件時(如類的所有實例都已被回收,類加載器也被回收),該類的Class對象和元數據會被卸載,從而釋放方法區中的內存。

類加載器層次結構:Java中的類加載器有三個,分別是Bootstrap Loader、ExtClassLoader和AppClassLoader。它們各自負責不同類型的類的加載:

Bootstrap Loader:負責加載JDK的核心庫,如rt.jar。
ExtClassLoader:負責加載JDK的擴展庫,如jre/lib/ext目錄下的庫。
AppClassLoader:負責加載應用程序自身的類路徑(Classpath)下的類庫。

委托機制:當類加載器需要加載一個類時,它會首先委托給其父類加載器進行加載。只有當父類加載器無法加載該類時,才由自己來加載。
通過以上機制,JVM能夠動態地加載和卸載類,實現了Java程序的運行時靈活性。

24、什么是類加載器,類加載器有哪些?

類加載器(ClassLoader)是Java虛擬機(JVM)的一個重要組成部分,負責將類的字節碼文件加載到內存中并生成對應的Class對象。類加載器通過將類的字節碼文件轉換為運行時的Java類,并在程序運行時動態加載和鏈接類,實現了Java的動態性和靈活性。

在Java中,類加載器主要分為以下幾種類型:

  1. 啟動類加載器(Bootstrap ClassLoader):負責加載Java核心類庫(如rt.jar),是JVM的一部分,并不繼承自java.lang.ClassLoader類。

  2. 擴展類加載器(Extension ClassLoader):負責加載Java的擴展類庫(如jre/lib/ext目錄下的jar包)。

  3. 應用程序類加載器(Application ClassLoader):也稱為系統類加載器,負責加載應用程序類路徑(Classpath)上指定的類庫。

  4. 自定義類加載器(Custom ClassLoader):開發者可以根據需要自定義類加載器,繼承自java.lang.ClassLoader類,實現自定義的類加載策略。

除了以上常見的類加載器外,還有一些特殊的類加載器,如Web應用程序中的WebAppClassLoader、OSGi中的BundleClassLoader等。

類加載器按照雙親委派模型進行工作,即每個類加載器在加載類時都會先委托給其父類加載器進行加載,只有在父類加載器無法加載時才由子類加載器自行加載。這種層次結構保證了類的唯一性和安全性,避免同一個類被不同的類加載器加載多次,同時也提高了類的可移植性和共享性。

通過合理使用類加載器,可以實現類的動態加載、版本隔離、熱部署等功能,為Java語言的靈活性和擴展性提供了良好的支持。

25、說一下類裝載的執行過程?

類加載的執行過程可以大致分為以下幾個步驟:

  1. 加載(Loading):當程序需要使用某個類時,類加載器會首先檢查該類是否已經被加載。如果尚未加載,則類加載器會根據類的全限定名(包括包路徑)在文件系統或網絡中查找對應的.class文件,然后讀取該文件的字節碼數據。

  2. 鏈接(Linking):鏈接階段包括驗證、準備和解析三個步驟。

    • 驗證(Verification):驗證階段確保類的字節碼符合JVM規范,不會危害虛擬機的安全。
    • 準備(Preparation):在準備階段,為類的靜態字段分配內存并設置初始值(通常為零值,如int類型初始化為0)。
    • 解析(Resolution):解析階段將常量池中的符號引用轉換為直接引用,例如將方法調用轉換為實際的內存地址。
  3. 初始化(Initialization):在初始化階段,JVM負責執行類構造器()方法,該方法主要包括對靜態字段的顯示賦值和靜態代碼塊的執行。這一階段標志著類加載過程的完成,類被正式初始化為可用狀態。

需要注意的是,在鏈接和初始化階段,類加載過程可能會觸發對其他類的加載,從而形成類加載的遞歸調用。此外,類加載過程中還涉及到雙親委派模型的機制,即類加載器在加載類時會先委托給其父類加載器進行加載,只有在父類加載器無法加載時才由子類加載器自行加載。

通過類加載的執行過程,Java實現了動態加載和多態性的特性,使得程序可以按需加載類,并在運行時適應不同的環境和需求。

26、什么是雙親委派模型?

雙親委派模型(又稱雙親委派機制)是Java類加載器的一種工作原則,用于保證類的唯一性和安全性。該模型規定了類加載器在加載類時首先委托給父類加載器進行加載,只有在父類加載器無法加載時才由子類加載器自行加載。

具體來說,當一個類加載器收到加載類的請求時,它會先檢查自身是否已經加載了這個類。如果沒有,則會將加載請求委托給父類加載器。父類加載器也會按照同樣的方式繼續向上委托,直至達到最頂層的啟動類加載器。只有當所有父類加載器都無法加載該類時,當前類加載器才會嘗試自行加載。

雙親委派模型的優勢在于確保每個類被加載且僅被加載一次,避免了類的重復加載,提高了系統的安全性和穩定性。同時,該模型也使得Java核心類庫能夠被啟動類加載器優先加載,確保了核心類庫的一致性和統一性。

通過雙親委派模型,Java類加載器實現了類加載的層次化管理,有效地解決了類加載過程中可能出現的類沖突和安全性問題,為Java語言的可移植性和跨平臺性提供了良好的支持。

27、說一下 JVM 調優的工具?常用的 JVM 調優的參數都有哪些?JVM調優是優化Java應用程序性能和資源利用的重要手段之一。以下是一些常用的JVM調優工具和參數:

JVM調優工具:

  1. VisualVM:VisualVM是JDK自帶的一款圖形化監控和分析工具,可以監控應用程序的性能數據、堆棧信息等,并提供基于JMX的遠程監控功能。

  2. JConsole:JConsole是JDK自帶的一個監控和管理工具,可以實時監控Java應用程序的資源利用情況、線程狀態等,并進行相關操作。

  3. JVisualVM:JVisualVM是VisualVM的前身,提供了更多的插件和擴展功能,可以進行堆內存分析、線程分析等。

  4. Java Mission Control:Java Mission Control是Oracle JDK附帶的一款高級監控工具,提供了更豐富的性能分析和故障診斷功能。

常用的JVM調優參數:

  1. 堆內存設置

    • -Xms<size>:初始堆大小
    • -Xmx<size>:最大堆大小
  2. GC相關參數

    • -XX:+UseG1GC:啟用G1垃圾收集器
    • -XX:MaxGCPauseMillis=<time>:指定最大GC停頓時間
    • -XX:NewSize=<size>:新生代大小
    • -XX:SurvivorRatio=<ratio>:Eden區與Survivor區的比例
  3. 調優日志

    • -XX:+PrintGC:打印GC日志
    • -XX:+PrintGCDetails:打印更詳細的GC日志
    • -Xloggc:<file>:將GC日志輸出到指定文件
  4. 性能監控

    • -Dcom.sun.management.jmxremote:啟用JMX遠程監控
    • -Dcom.sun.management.jmxremote.port=<port>:指定JMX端口
  5. 類加載相關

    • -XX:+TraceClassLoading:跟蹤類加載過程
    • -XX:+TraceClassUnloading:跟蹤類卸載過程
  6. 編譯優化

    • -XX:+AggressiveOpts:啟用更激進的編譯優化

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719713.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719713.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719713.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Modbus協議詳細解析與案例分享

目錄 Modbus協議詳細解析與案例分享1. Modbus協議簡介2. Modbus RTU和Modbus TCP的區別3. Modbus幀結構4. Modbus協議示例5. Modbus應用場景結語 Modbus協議詳細解析與案例分享 1. Modbus協議簡介 Modbus是一種串行通信協議&#xff0c;用于實現工業自動化設備之間的通信。它…

消息中間件|初識消息隊列

文章目錄 消息隊列是什么&#xff1f;消息隊列關鍵概念消息隊列優點消息隊列的應用場景異步處理應用解耦流量削峰消息通訊 常用消息隊列中間件的對比 消息隊列是什么&#xff1f; 消息隊列&#xff08;Message Queue&#xff09;是一種用于在軟件系統之間傳遞消息的通信機制。…

spring boot概述

SpringBoot是由Pivotal團隊提供的全新框架&#xff0c;其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。 該框架使用了特定的方式來進行配置&#xff0c;從而使開發人員不再需要定義樣板化的配置。 通過這種方式&#xff0c;SpringBoot致力于在蓬勃發展的快速應用開發…

實時抓取SKU商品屬性詳細信息API數據接口(淘寶,某音)

item_sku-獲取sku詳細信息 taobao.item_sku詳細信息 API公共參數 請求地址: https://api-gw.onebound.cn/taobao/item_sku 名稱類型必須描述keyString是調用key&#xff08;演示示例&#xff09;secretString是調用密鑰api_nameString是API接口名稱&#xff08;包括在請求地…

設計模式學習筆記 - 設計原則 - 3.里氏替換原則,它和多態的區別是什么?

前言 今天來學習 SOLID 中的 L&#xff1a;里氏替換原則。它的英文翻譯是 Liskov Substitution Principle&#xff0c;縮寫為 LSP。 英文原話是&#xff1a; Functions that use points of references of base classes must be able to use objects of derived classes withou…

python-分享篇-生成仿微信公眾號推廣的個性二維碼(支持動態)

代碼 生成仿微信公眾號推廣的個性二維碼&#xff08;支持動態&#xff09;from MyQR import myqr # 要生成動態二維碼&#xff0c;只需要將piture參數和save_name參數設置gif動圖即可 myqr.run(wordshttps://blog.csdn.net/stqer/article/details/135553200, # 指定二維碼包含…

JVM(內存區域劃分)

JVM JVM - Java虛擬機 我們編寫的 Java 程序, 是不能夠被 OS 直接識別的 JVM 充當翻譯官的角色, 負責把我們寫的的 Java 程序 ,翻譯給 OS “聽”, 讓 OS 能夠識別我們所寫的 Java 代碼 JVM 內存區域劃分 JVM 是一個應用程序, 在啟動的時候, 會從 操作系統 申請到一整塊很大的內…

AI-RAN聯盟在MWC24上正式啟動

AI-RAN聯盟在MWC24上正式啟動。它的logo是這個樣的&#xff1a; 2月26日&#xff0c;AI-RAN聯盟&#xff08;AI-RAN Alliance&#xff09;在2024年世界移動通信大會&#xff08;MWC 2024&#xff09;上成立。創始成員包括亞馬遜云科技、Arm、DeepSig、愛立信、微軟、諾基亞、美…

【dc-dc】AP510X單路低壓差線性恒流芯片

說明 AP510X 是一系列外圍電路簡潔的單路線性 LED 恒 流芯片&#xff0c;適用于 3-60V 電壓范圍的 LED 恒流調光 領域。 AP510X 采用我司專利算法&#xff0c;可以實現高精度的恒 流效果&#xff0c;輸出電流恒流精度≤ 3 &#xff05;&#xff0c;電源供電工作 范…

【LeetCode】升級打怪之路 Day 11:棧的應用、單調棧

今日題目&#xff1a; Problem 1: 棧的應用 155. 最小棧 | LeetCode20. 有效的括號 | LeetCode150. 逆波蘭表達式求值 | LeetCode Problem 2: 單調棧 496. 下一個更大元素 I739. 每日溫度503. 下一個更大元素 II 目錄 Problem 1&#xff1a;棧 - “先進后出”的應用LC 155. 最…

【Java設計模式】五、建造者模式

文章目錄 1、建造者模式2、案例&#xff1a;共享單車的創建3、其他用途 1、建造者模式 某個對象的構建復雜將復雜的對象的創建 和 屬性賦值所分離&#xff0c;使得同樣的構建過程可以創建不同的表示建造的過程和細節調用者不需要知道&#xff0c;只需要通過構建者去進行操作 …

力扣刷題記錄--463. 島嶼的周長

題目鏈接&#xff1a;463. 島嶼的周長 - 力扣&#xff08;LeetCode&#xff09; 題目描述 我的代碼實現 class Solution {public int islandPerimeter(int[][] grid) { int result0; int rowgrid.length; int colgrid[0].length; for(int i0;i<row;i){for(int j0;j<col…

【EI會議征稿通知】2024年圖像處理與人工智能國際學術會議(ICIPAI2024)

2024年圖像處理與人工智能國際學術會議&#xff08;ICIPAI2024&#xff09; 2024 International Conference on Image Processing and Artificial Intelligence&#xff08;ICIPAI2024&#xff09; 2024年圖像處理與人工智能國際學術會議&#xff08;ICIPAI2024&#xff09;將…

返回靜態數據

在Java項目中&#xff0c;往往不會一直返回某某數據&#xff0c;而是會返回一個靜態頁面&#xff0c;那么&#xff0c;如何正確返回一個靜態頁面呢&#xff1f;&#xff1f; 要想成功的返回一個靜態頁面前提是必須要有一個靜態頁面&#xff1a; <!DOCTYPE html> <ht…

如何讓 JOIN 跑得更快?

JOIN 一直是數據庫性能優化的老大難問題&#xff0c;本來挺快的查詢&#xff0c;一旦涉及了幾個 JOIN&#xff0c;性能就會陡降。而且&#xff0c;參與 JOIN 的表越大越多&#xff0c;性能就越難提上來。 其實&#xff0c;讓 JOIN 跑得快的關鍵是要對 JOIN 分類&#xff0c;分…

Effective Programming 學習筆記

1 基本語句 1.1 斷言 在南溪看來&#xff0c;斷言可以用來有效地確定編程中當前代碼運行的前置條件&#xff0c;尤其是以下情況&#xff1a; 第三方工具庫對輸入數據的依賴&#xff0c;例如&#xff1a;minitouch庫對Android版本的要求

第三百八十一回

文章目錄 1. 概念介紹2. 修改方法 015buttonStyle.png2.1 修改形狀2.2 修改顏色2.3 修改位置 3. 示例代碼4. 內容總結 我們在上一章回中介紹了"如何創建以圖片為背景的頁面"相關的內容&#xff0c;本章回中將介紹如何修改按鈕的形狀.閑話休提&#xff0c;讓我們一起T…

2024年華為OD機試真題-文件緩存系統-Python-OD統一考試(C卷)

題目描述: 請設計一個文件緩存系統,該文件緩存系統可以指定緩存的最大值(單位為字節)。 文件緩存系統有兩種操作:存儲文件(put)和讀取文件(get) 操作命令為put fileName fileSize或者get fileName 存儲文件是把文件放入文件緩存系統中;讀取文件是從文件緩存系統中訪問已存…

06. Nginx進階-Nginx代理服務

proxy代理功能 正向代理 什么是正向代理&#xff1f; 正向代理&#xff08;forward proxy&#xff09;&#xff0c;一個位于客戶端和原始服務器之間的服務器。 工作原理 為了從原始服務器獲取內容&#xff0c;客戶端向代理發送一個請求并指定目標&#xff08;即原始服務器…

為不同文章形式選擇不同的WordPress文章模板

在寫文章的時候選擇不同的文章形式&#xff0c;然后打開文章的時候會調用不同文章形式的模板。比如&#xff0c;文章形式為video &#xff0c;就調用single-video.php模板&#xff0c;其它文章形式類似&#xff0c;可以添加多個文章樣式。 //為不同文章形式的內容添加不同的si…