Java18的新特性介紹

一、概況

Java 18是Java編程語言的最新版本,它于2022年9月發布。Java 18引入了許多新特性和改進,以下是其中一些重要的新特性。

  1. 元編程功能:Java 18引入了元注釋和元類型聲明的功能,使開發人員能夠在編譯時對注解進行元處理。這為開發人員提供了更大的靈活性和控制力。

  2. 模式匹配增強:Java 18改進了模式匹配功能,使得模式匹配更加強大和易于使用。開發人員可以使用模式匹配來簡化代碼,并更容易地處理復雜的數據結構。

  3. 協程支持:Java 18引入了協程支持,使得開發人員可以更輕松地編寫異步代碼。協程是一種輕量級的線程,可以在運行時暫停和恢復,并與其他協程并發執行。

  4. SIMD(單指令多數據)支持:Java 18引入了對SIMD指令的支持,使開發人員能夠更高效地執行并行計算。SIMD指令可以同時操作多個數據項,提高了程序的性能。

  5. 基于事件的系統:Java 18引入了基于事件的系統,使開發人員可以更容易地開發事件驅動的應用程序。開發人員可以使用新的事件模型來處理和觸發事件。

  6. 垃圾回收改進:Java 18改進了垃圾回收器的性能和穩定性。其中包括對G1垃圾回收器的改進,以提高垃圾回收的效率和響應速度。

請注意,以上只是Java 18的一些重要新特性的簡要介紹。Java 18還包括許多其他改進和優化,以提高開發人員的生產力和程序的性能。

二、元編程功能

元編程是指在程序運行時,對程序自身進行操作和修改的能力。Java 18引入了元編程功能,其中包括元注釋和元類型聲明。

元注釋是一種特殊類型的注釋,可以用于標記其他注解,并在編譯時進行處理。通過元注釋,開發人員可以在編譯時獲取和修改注解的信息,并根據需要生成額外的代碼。

以下是一個使用元注釋的示例代碼:

@MetaAnnotation
@SomeAnnotation
public class MyClass {// class implementation
}

在上面的代碼中,@MetaAnnotation是一個元注釋,用于標記MyClass類。在編譯時,我們可以通過元注釋處理器獲取MyClass類上的注解信息,并執行相應的邏輯。

元類型聲明是指在類型聲明中使用的特殊注解。通過元類型聲明,開發人員可以對類型進行額外的約束和限制,并在編譯時進行驗證。

以下是一個使用元類型聲明的示例代碼:

@TypeQualifier
public @interface NonNull {// annotation attributes
}public class MyClass {public void myMethod(@NonNull String param) {// method implementation}
}

在上面的代碼中,@NonNull是一個元類型聲明,將應用于myMethod方法的參數param。編譯器可以根據元類型聲明驗證代碼是否符合預期的約束條件,例如參數是否為非空。

元編程功能提供了更大的靈活性和控制力,使開發人員能夠在編譯時對注解進行處理,并對類型進行額外的約束和驗證。這有助于提高代碼的可靠性和可維護性。

三、模式匹配增強

Java 18引入了對模式匹配的增強功能,使得在處理復雜的條件分支時更加便捷和簡潔。以下是Java 18中模式匹配的一些增強特性介紹及示例代碼。

1、模式匹配的變量聲明

在Java 18以前,進行模式匹配時需要使用instanceof運算符,并將結果轉換為對應的類型。而在Java 18中,可以直接在變量聲明時使用模式匹配。示例代碼如下:

if (obj instanceof MyClass myObj) {// myObj是一個類型為MyClass的變量// 可以直接在這里使用myObj
}

在上面的代碼中,如果objMyClass類型的實例,那么myObj將被聲明為類型為MyClass的變量,并可以在if代碼塊中使用。

2、模式匹配的switch表達式

在Java 18中,switch表達式可以使用模式匹配來進行條件判斷,而不僅僅是基于常量的值。示例代碼如下:

int result = switch (obj) {case MyClass myObj -> {// 處理MyClass類型的情況yield 1;}case String str -> {// 處理String類型的情況yield 2;}default -> {// 處理其他情況yield 0;}
};

在上面的代碼中,switch表達式根據obj的類型進行模式匹配,并執行對應的代碼塊。yield語句用于指定表達式的返回值。

模式匹配的增強功能使得在處理條件分支時更加簡潔和易讀。它可以減少繁瑣的類型轉換操作,并且能夠直接在條件判斷中使用變量。這樣可以提高代碼的可讀性和可維護性。

四、協程支持

協程是一種輕量級的線程,可以在程序中簡化并發和異步編程。Java中可以使用一些庫來實現協程的功能,比如 Quasar、Project Loom 等。這些庫可以在Java 8及以上的版本中使用。

以下是一個使用 Quasar 實現協程的示例代碼:

首先,確保在你的項目中添加了 Quasar 的依賴:

<dependency><groupId>co.paralleluniverse</groupId><artifactId>quasar-core</artifactId><version>0.7.9</version>
</dependency>

然后,可以使用 Quasar 提供的 Coroutine 類來創建和管理協程。示例代碼如下:

import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.fibers.FiberScheduler;public class CoroutineExample {public static void main(String[] args) {Fiber<Void> fiber = new Fiber<Void>(new FiberScheduler("MyScheduler")) {@Overrideprotected Void

Java 18引入了對協程的支持,這使得編寫異步代碼更加簡單和直觀。以下是Java 18中協程支持的一些介紹及示例代碼。

1、協程的聲明

在Java 18中,可以使用關鍵字async來聲明一個協程方法。示例代碼如下:

public async void fetchData() {// 異步方法的代碼邏輯
}

上面的代碼聲明了一個名為fetchData的異步方法。

2、協程的調用

在協程方法中,可以使用關鍵字await來等待一個異步操作的完成。示例代碼如下:

public async void fetchData() {String result = await fetchDataAsync();// 使用異步操作的結果進行后續處理
}

在上面的代碼中,await關鍵字等待一個返回String類型結果的異步操作fetchDataAsync()的完成,并將結果賦值給result變量。

3、異步返回值

在協程方法中,可以使用AsyncCompletionStage類型來表示異步操作的返回值。示例代碼如下:

public async CompletableFuture<String> fetchDataAsync() {// 異步操作的代碼邏輯
}

在上面的代碼中,fetchDataAsync()方法返回一個CompletableFuture對象,表示異步操作的結果為String類型。

協程的支持使得編寫異步代碼更加直觀和簡單。開發者可以使用async關鍵字聲明協程方法,并使用await關鍵字等待異步操作的結果。這樣可以使得異步代碼的編寫更接近同步代碼的風格,提高了代碼的可讀性和可維護性。

五、SIMD(單指令多數據)支持

1、使用Apache Commons Math庫

SIMD是一種并行計算的技術,允許同時對多個數據進行相同的操作,以提高計算效率。在Java環境下,通常可以使用諸如Apache Commons Math、Jama和JavaCPP等庫來實現SIMD操作。

以下是一個使用Apache Commons Math庫進行SIMD操作的示例代碼:

import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.util.Precision;public class SIMDExample {public static void main(String[] args) {double[] data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};// 使用SIMD技術計算數組中每個元素的平方根for (int i = 0; i < data.length; i++) {data[i] = Precision.round(FastMath.sqrt(data[i]), 2);}// 輸出計算結果System.out.println(Arrays.toString(data));}
}

在上面的代碼中,我們使用Apache Commons Math庫中的FastMath類來計算數組中每個元素的平方根,然后使用Precision類進行精度控制。盡管Java本身沒有SIMD的原生支持,但可以使用第三方庫來實現類似的功能。

2、使用JavaCPP庫

以下是一個使用JavaCPP庫進行SIMD操作的示例代碼:

import org.bytedeco.javacpp.FloatPointer;
import org.bytedeco.javacpp.indexer.FloatRawIndexer;
import org.bytedeco.javacpp.simd;public class SIMDExample {public static void main(String[] args) {float[] data = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};// 使用SIMD技術計算數組中每個元素的平方根FloatPointer floatPointer = new FloatPointer(data);FloatRawIndexer indexer = floatPointer.asRawIndexer();for (int i = 0; i < data.length; i += simd.SIMD_FLOAT32_SIZE) {simd.Float32Vector vector = new simd.Float32Vector(indexer, i);vector = simd.sqrt(vector);vector.store(indexer, i);}// 輸出計算結果for (float value : data) {System.out.println(value);}}
}

在上面的代碼中,我們使用JavaCPP庫中的simd包來進行SIMD操作。我們使用FloatPointer來表示float數組,在循環中,我們使用FloatRawIndexer來讀取和寫入數組元素。

請注意,這只是一個簡單的示例,實際的SIMD操作可能更復雜,具體的實現方式取決于你的需求和所選擇的庫。如果你對SIMD操作感興趣,建議參考所選庫的文檔和示例代碼,以了解更多細節和具體的用法。

3、基于Vector API

SIMD(Single Instruction, Multiple Data)是一種計算機處理器的指令級并行技術,用于同時處理多個數據元素。Java 18引入了對SIMD的支持,使得開發人員可以利用SIMD指令并行化處理向量數據,從而獲得更高的性能。

Java 18的SIMD支持基于Vector API,可以通過引入java.vector包來使用。下面是一個簡單的示例代碼,演示了如何使用SIMD并行化計算兩個向量的和:

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.VectorOperators;public class SIMDExample {public static void main(String[] args) {int[] vector1 = {1, 2, 3, 4};int[] vector2 = {5, 6, 7, 8};// 將向量轉換為SIMD向量VectorOperators.IntBinaryOperator sumOperator = VectorOperators.addInts();IntStream.range(0, vector1.length).mapToObj(i -> sumOperator.apply(VectorOperators.broadcast(vector1[i]), VectorOperators.broadcast(vector2[i]))).toArray(VectorOperators::emptyArray, (acc, v) -> acc.append(v), (acc1, acc2) -> acc1.concat(acc2));// 打印結果System.out.println(Arrays.toString(vector1));System.out.println(Arrays.toString(vector2));System.out.println(Arrays.toString(VectorOperators.toIntArray())); }
}

這個示例中,我們首先定義了兩個向量vector1vector2,然后使用SIMD并行化計算兩個向量的和。在計算過程中,我們使用VectorOperators.addInts()方法獲取一個用于求和的操作符,然后使用VectorOperators.broadcast()方法將向量的元素轉化為SIMD向量。最后,將計算結果轉化為數組并打印出來。

需要注意的是,SIMD在處理向量數據時要求數據長度是向量大小的倍數。在上面的示例中,我們只處理了長度為4的向量。如果需要處理更長的向量,可以將向量長度補齊為向量大小的倍數,或者使用SIMD支持的其他方法。

具體使用哪個庫以及如何實現SIMD操作取決于你的具體需求和環境。你可以根據自己的要求選擇適合的庫,并參考相應的文檔和示例代碼來學習和使用SIMD技術。

六、基于事件的系統

Java 18引入了基于事件的系統(Event-based System),它是一種用于構建高效、響應式和可擴展系統的編程模型。基于事件的系統采用異步事件驅動的方式,通過事件的發布和訂閱機制來進行組件之間的通信和協作。

在基于事件的系統中,組件可以發布事件并將其傳遞給其他組件。其他組件可以注冊為事件的訂閱者,以響應特定類型的事件。這種松耦合的通信機制使得系統能夠更好地處理并發和異步操作,并提高系統的可擴展性和靈活性。

下面是一個簡單的示例代碼,演示了如何在Java 18中使用基于事件的系統來實現一個簡單的發布-訂閱模式:

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;public class EventBasedSystemExample {public static void main(String[] args) {EventManager eventManager = new EventManager();// 創建訂閱者并注冊到事件管理器Subscriber subscriber1 = new Subscriber("Subscriber 1");Subscriber subscriber2 = new Subscriber("Subscriber 2");eventManager.subscribe(subscriber1);eventManager.subscribe(subscriber2);// 發布事件Event event = new Event("Hello, World!", LocalDateTime.now());eventManager.publish(event);}
}class Event {private String message;private LocalDateTime timestamp;public Event(String message, LocalDateTime timestamp) {this.message = message;this.timestamp = timestamp;}public String getMessage() {return message;}public LocalDateTime getTimestamp() {return timestamp;}
}interface EventListener {void onEventReceived(Event event);
}class Subscriber implements EventListener {private String name;public Subscriber(String name) {this.name = name;}@Overridepublic void onEventReceived(Event event) {System.out.println(name + " received event: " + event.getMessage() + " at " + event.getTimestamp());}
}class EventManager {private List<EventListener> subscribers = new ArrayList<>();public void subscribe(EventListener subscriber) {subscribers.add(subscriber);}public void publish(Event event) {for (EventListener subscriber : subscribers) {subscriber.onEventReceived(event);}}
}

在上面的示例中,我們首先定義了一個Event類,表示一個事件。然后定義了一個Subscriber類,實現了EventListener接口,表示一個事件的訂閱者。Subscriber類實現了onEventReceived(Event event)方法,在接收到事件時進行處理。

然后,我們創建了一個EventManager類,用于管理事件的發布和訂閱。EventManager類維護了一個subscribers列表,用于存儲所有的訂閱者。它提供了subscribe(EventListener subscriber)方法用于訂閱事件,并提供了publish(Event event)方法用于發布事件。在publish(Event event)方法中,它遍歷subscribers列表,并調用每個訂閱者的onEventReceived(Event event)方法來處理事件。

在示例的main方法中,我們創建了兩個訂閱者,并將它們注冊到事件管理器。然后,我們創建了一個事件并發布它。當事件被發布時,每個訂閱者都會接收到這個事件,并進行相應的處理。

需要注意的是,在實際的基于事件的系統中,通常還會有更多的功能和復雜性,例如異步處理、事件過濾等。上面的示例只是演示了基本的發布-訂閱模式的實現方式。

七、垃圾回收改進

Java 18對垃圾回收進行了一些改進,旨在提高性能和減少延遲。下面是一些Java 18中垃圾回收改進的介紹和示例代碼:

1、回收縮減(ShrinkHeap)

Java 18引入了一種新的垃圾回收策略,稱為回收縮減(ShrinkHeap)。回收縮減可以在適當的時候減小堆的大小,以減少垃圾回收的成本。這種策略可以幫助減少延遲,并提高應用程序的吞吐量。

下面是一個示例代碼,演示了如何在Java 18中使用回收縮減策略:

public class ShrinkHeapExample {public static void main(String[] args) {System.out.println("Initial heap size: " + Runtime.getRuntime().totalMemory() / (1024 * 1024) + "MB");// 創建大量的對象for (int i = 0; i < 1000000; i++) {new Object();}System.out.println("Before shrink heap size: " + Runtime.getRuntime().totalMemory() / (1024 * 1024) + "MB");// 調用垃圾回收System.gc();System.out.println("After shrink heap size: " + Runtime.getRuntime().totalMemory() / (1024 * 1024) + "MB");}
}

在上面的示例中,我們首先打印了初始的堆大小。然后,我們創建了大量的對象,模擬了一些內存的使用。接下來,我們打印了調用垃圾回收之前的堆大小。最后,我們調用了System.gc()方法進行垃圾回收,并打印了回收之后的堆大小。

2、垃圾回收器自適應策略(Garbage Collector Adaptive Strategy)

Java 18改進了垃圾回收器的自適應策略,使其能夠根據應用程序的行為和資源利用情況進行動態調整。這種策略可以更好地適應不同場景下的垃圾回收需求,從而提高性能和減少延遲。

下面是一個示例代碼,演示了如何在Java 18中使用垃圾回收器的自適應策略:

public class AdaptiveGCStrategyExample {public static void main(String[] args) {// 打印垃圾回收器的當前策略System.out.println("GC strategy: " + System.getProperty("java.garbagecollector.strategy"));// 創建大量的對象for (int i = 0; i < 1000000; i++) {new Object();}// 調用垃圾回收System.gc();}
}

在上面的示例中,我們首先打印了當前垃圾回收器的策略。然后,我們創建了大量的對象,模擬了一些內存的使用。最后,我們調用了System.gc()方法進行垃圾回收。

需要注意的是,自適應策略是垃圾回收器的內部實現細節,具體的策略可能會因不同的JVM實現而異。通過使用java.garbagecollector.strategy系統屬性,我們可以獲取當前的垃圾回收器策略。但是,程序員一般不需要顯式地調整垃圾回收器的策略,因為Java的垃圾回收器已經具備了很好的自適應功能。

##歡迎關注交流,開發逆商潛力,提升個人反彈力:

?

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

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

相關文章

【C++】位圖/布隆過濾器+海量數據處理

目錄 一、位圖 1.1 位圖的概念 1.2 位圖的實現 1.3 位圖的應用&#xff08;面試題&#xff09; 二、布隆過濾器 2.1 布隆過濾器的引入 2.2 布隆過濾器概念 2.3 布隆過濾器的插入和查找 2.4 布隆過濾器的實現 2.5 布隆過濾器的優點和缺陷 2.6 布隆過濾器的應用&#…

Servlet 的 API

HttpServlet init&#xff1a;當 tomcat 收到了 /hello 這樣的路徑是請求后就會調用 HelloServlet&#xff0c;于是就需要對 HelloServlet 進行實例化&#xff08;只實例一次&#xff0c;后續再有請求也不實例了&#xff09;。 destory&#xff1a;如果是通過 smart tomcat 的停…

實驗六 Java流式編程與網絡程序設計 頭歌

實驗六 Java流式編程與網絡程序設計 頭歌 制作不易&#xff01;點個關注&#xff01;給大家帶來更多價值&#xff01; 第1關 字節輸入/輸出流實現數據的保存和讀取 package step1;import java.io.*; import java.util.*;public class SortArray {public static void main(St…

洗地機品牌哪個牌子好?實力派洗地機品牌TOP10榜單

洗地機依靠其洗、拖、吸、烘為一體的功能&#xff0c;能高效的完成地面清潔的工作&#xff0c;深受大家的喜愛。但是洗地機的型號越來越多&#xff0c;功能也越來越多&#xff0c;對于不想花大價錢&#xff0c;又想要高性價比的精致人群來說實在不友好&#xff0c;所以筆者今天…

C++ 中重寫重載和隱藏的區別

重寫&#xff08;override&#xff09;、重載&#xff08;overload&#xff09;和隱藏&#xff08;overwrite&#xff09;在C中是3個完全不同的概念。我們這里對其進行詳細的說明 1、重寫&#xff08;override&#xff09;是指派生類覆蓋了基類的虛函數&#xff0c;這里的覆蓋必…

如何寫好科研論文(討論)

討論1. 如何去選取第一批要閱讀的論文&#xff1f; 當我選擇第一批要閱讀的論文時&#xff0c;我會遵循以下幾個步驟&#xff0c;以確保所選的論文對我的研究最有幫助&#xff1a; 研究問題的相關性&#xff1a; 明確我的研究問題或主題&#xff1a;首先&#xff0c;我會確保自…

實例展示vue單元測試及難題解惑

通過生動詳實的例子帶你排遍vue單元測試過程中的所有疑惑與難題。 技術棧&#xff1a;jest、vue-test-utils。 共四個部分&#xff1a;運行時、Mock、Stub、Configuring和CLI。 運行時 在跑測試用例時&#xff0c;大家的第一個絆腳石肯定是各種undifned報錯。 解決這些報錯…

【HarmonyOS4學習筆記】《HarmonyOS4+NEXT星河版入門到企業級實戰教程》課程學習筆記(九)

課程地址&#xff1a; 黑馬程序員HarmonyOS4NEXT星河版入門到企業級實戰教程&#xff0c;一套精通鴻蒙應用開發 &#xff08;本篇筆記對應課程第 16 節&#xff09; P16《15.ArkUI-狀態管理-任務統計案例》 1、實現任務進度卡片 怎么讓進度條和進度展示文本堆疊展示&#xff1…

./scripts/Makefile.clean 文件分析

文章目錄 目標 $(subdir-ymn)目標__clean $(clean-dirs): ??? make -f ./scripts/Makefile.clean obj$(patsubst _clean_%,%,$) $(clean-dirs)$(patsubst _clean_%,%,$)_clean_api _clean_cmd _clean_common _clean_disk _clean_drivers _clean_drivers/ddr/altera _clean_d…

react中的useEffect()的使用

useEffect()是react中的hook函數&#xff0c;作用是用于創建由渲染本身引起的操作&#xff0c;而不是事件的觸發&#xff0c;比如Ajax請求&#xff0c;DOM的更改 首先useEffect()是個函數&#xff0c;接受兩個參數&#xff0c;第一個參數是一個方法&#xff0c;第二個參數是數…

數據結構--樹與二叉樹--編程求以孩子兄弟表示法存儲的森林的葉結點個數

數據結構–樹與二叉樹–編程求以孩子兄弟表示法存儲的森林的葉結點個數 題目 編程求以孩子兄弟表示法存儲的森林的葉結點個數 ps&#xff1a;題目來源2025王道數據結構 思路 樹上的操作大多數是通過遞歸進行的 我們可以從根節點開始遞歸 如果結點 N 沒有孩子指針&#xff…

【Entity Framework】如何理解EF中的級聯刪除

【Entity Framework】如何理解EF中的級聯刪除 文章目錄 【Entity Framework】如何理解EF中的級聯刪除一、概述二、發生級聯行為時2.1/刪除主體/父實體2.2/斷開關系 三、發生級聯行為的位置3.1/級聯刪除被跟蹤實體3.2/數據庫中的級聯刪除 四、級聯NULL 一、概述 Entity Framewo…

vue3 路由跳轉 攜帶參數

實現功能&#xff1a;頁面A 跳轉到 頁面B&#xff0c;攜帶參數 路由router.ts import { createRouter, createWebHistory } from "vue-router";const routes: RouteRecordRaw[] [{path: "/demo/a",name: "aa",component: () > import(&quo…

x264 碼率控制原理:x264_ratecontrol_start 函數

x264_ratecontrol_start 函數 函數原理 函數功能:編碼一幀之前,為當前幀選擇一個量化 QP,屬于幀級別碼率控制;這對于控制視頻質量和文件大小至關重要。通過調整QP,編碼器可以在保持視頻質量的同時,盡可能減小輸出文件的大小。函數參數:x264_t *h: 編碼器上下文結構體指…

十七、個人信息出境標準合同的具體內容有哪些?

根據《標準合同辦法》第六條&#xff0c;標準合同應當嚴格按照網信辦制定版本訂立&#xff0c;個人信息處理者可以與境外接收方約定其他條款&#xff0c;但不得與標準合同相沖突。 根據《標準合同辦法》附件&#xff0c;目前版本的標準合同內容主要包括&#xff1a; 1. 個人信…

Flutter 中的 TextButton 小部件:全面指南

Flutter 中的 TextButton 小部件&#xff1a;全面指南 在Flutter的世界里&#xff0c;TextButton是一個基礎的小部件&#xff0c;用于創建只包含文本的按鈕。它通常用于對話框、表單以及需要強調主要操作的界面。本文將為您提供一個全面的指南&#xff0c;幫助您了解如何使用T…

地信遙感測繪電子書

《地理信息系統概論》&#xff0c;黃杏元&#xff0c;馬勁松編著&#xff0c;第三版&#xff0c;高等教育出版社&#xff0c;2008年 《地理信息系統》&#xff08;第二版&#xff09;湯國安&#xff0c;趙牡丹&#xff0c;楊昕等編&#xff0c;高等教育出版社&#xff0c;2010…

【stm32/CubeMX、HAL庫】嵌入式實驗五:定時器(2)|PWM輸出

參考&#xff1a; 【【正點原子】手把手教你學STM32CubeIDE開發】 https://www.bilibili.com/video/BV1Wp42127Cx/?p13&share_sourcecopy_web&vd_source9332b8fc5ea8d349a54c3989f6189fd3 《嵌入式系統基礎與實踐》劉黎明等編著&#xff0c;第九章定時器&#xff0c…

8操作系統定義、分類及功能+設備管理+作業管理 軟設刷題 軟考+

操作系統定義、分類及功能設備管理作業管理 知識點1-55-1010-1515-2020-2525-3030-35 刷題操作系統定義、分類及功能1-55-1010-15作業管理1-5設備管理1-55-10 知識點 1-5 1 嵌入式操作系統的特點&#xff1a; 1.微型化&#xff0c;從性能和成本角度考慮&#xff0c;希望占用的…

145.棧和隊列:刪除字符串中的所有相鄰重復項(力扣)

題目描述 代碼解決 class Solution { public:string removeDuplicates(string s) {// 定義一個棧來存儲字符stack<char> st;// 遍歷字符串中的每一個字符for(int i 0; i < s.size(); i){// 如果棧為空或棧頂字符與當前字符不相同&#xff0c;則將當前字符入棧if(st.e…