每天認識一個設計模式-橋接模式:在抽象與實現的平行宇宙架起彩虹橋

一、前言:虛擬機橋接的啟示

使用過VMware或者Docker的同學們應該都接觸過網絡橋接,在虛擬機網絡配置里,橋接模式是常用的網絡連接方式。選擇橋接模式時,虛擬機會通過虛擬交換機與物理網卡相連,獲取同網段 IP 地址,如同直接連在同一網絡交換機上的兩臺主機,能直接通信。它可讓虛擬機像真實主機一樣訪問局域網設備,接收 DHCP 分配的 IP,或手動配置網絡參數進行通信。?

而在軟件開發中也有這么一個設計模式,從軟件設計角度,虛擬機橋接模式與橋接模式思想一致,橋接模式核心是分離抽象與實現使其獨立變化。虛擬機橋接模式中,物理和虛擬機網絡相對獨立,借虛擬交換機實現連接通信。

軟件系統也有類似情況,多種實現方式與抽象層次下,可借鑒橋接模式分離抽象和實現,降低耦合度,讓系統更靈活可擴展,今天咱們就來了解一下軟件設計中的橋接模式。希望感興趣的同學能對這一設計模式有所感悟~

二、橋接模式的基礎介紹

橋接(Bridge)是用于把抽象化與實現化解耦,使得二者可以獨立變化。這種類型的設計模式屬于結構型模式,它通過提供抽象化和實現化之間的橋接結構,來實現二者的解耦。

這種模式涉及到一個作為橋接的接口,使得實體類的功能獨立于接口實現類,這兩種類型的類可被結構化改變而互不影響。

橋接模式的目的是將抽象與實現分離,使它們可以獨立地變化,該模式通過將一個對象的抽象部分與它的實現部分分離,使它們可以獨立地改變。它通過組合或者聚合的方式,而不是繼承的方式,將抽象和實現的部分連接起來。通過引入一個橋接接口,實現抽象類和實現類之間的關聯,從而避免了抽象類和實現類之間的緊耦合關系。?

在橋接模式的 UML 結構中,主要包含以下幾個關鍵角色:?

  • 抽象(Abstraction):定義抽象接口,通常包含對實現接口的引用。
  • 擴展抽象(Refined Abstraction):對抽象的擴展,可以是抽象類的子類或具體實現類。
  • 實現(Implementor):定義實現接口,提供基本操作的接口。
  • 具體實現(Concrete Implementor):實現實現接口的具體類。

根據這個邏輯我們可以通過簡單的代碼來實現一個基礎的橋接模式的基礎使用案例:

// 實現接口
interface MessageTransport {void send(String message, String target);
}// 具體實現類A
class EmailTransport implements MessageTransport {@Overridepublic void send(String message, String target) {System.out.println("通過電子郵件發送消息:" + message + " 到 " + target);}
}// 具體實現類B
class SmsTransport implements MessageTransport {@Overridepublic void send(String message, String target) {System.out.println("通過短信發送消息:" + message + " 到 " + target);}
}// 抽象類
abstract class MessageSender {protected MessageTransport messageTransport;public MessageSender(MessageTransport messageTransport) {this.messageTransport = messageTransport;}public abstract void sendMessage(String message, String target);
}// 修正抽象類
class TextMessageSender extends MessageSender {public TextMessageSender(MessageTransport messageTransport) {super(messageTransport);}@Overridepublic void sendMessage(String message, String target) {messageTransport.send(message, target);}
}// 客戶端代碼
public class Client {public static void main(String[] args) {MessageTransport emailTransport = new EmailTransport();MessageSender textMessageSenderByEmail = new TextMessageSender(emailTransport);textMessageSenderByEmail.sendMessage("這是一封測試郵件", "test@example.com");MessageTransport smsTransport = new SmsTransport();MessageSender textMessageSenderBySms = new TextMessageSender(smsTransport);textMessageSenderBySms.sendMessage("這是一條測試短信", "12345678900");}
}
  1. MessageTransport 接口:定義了發送消息的方法send,這是實現類需要實現的接口。?
  2. EmailTransport 類和 SmsTransport 類:分別實現了MessageTransport接口,提供了使用電子郵件和短信發送消息的具體實現。?
  3. MessageSender 抽象類:持有一個MessageTransport的引用,通過構造函數進行初始化,并定義了抽象方法sendMessage。?
  4. TextMessageSender 類:繼承自MessageSender抽象類,實現了sendMessage方法,在sendMessage方法中調用MessageTransport的send方法來發送消息。?
  5. Client 類:作為客戶端,創建了EmailTransport和SmsTransport的實例,然后分別創建了使用這兩種傳輸方式的文本消息發送對象,并調用sendMessage方法進行消息發送。

這樣如果我們要新增即時通訊傳輸技術,只需要新增一個實現MessageTransport接口的ImTransport類,而不需要修改抽象類MessageSender及其子類TextMessageSender等,從而實現了抽象和實現分離。

三、框架設計中的橋接智慧

3.1 JDBC 驅動架構:動態適配數據庫

在 Java 數據庫編程中,JDBC(Java Database Connectivity)扮演著至關重要的角色,其驅動架構是橋接模式的典型應用。java.sql.Driver接口定義了數據庫操作的規范,它是整個 JDBC 驅動架構的核心抽象。這個接口規定了一系列方法,如connect方法用于建立與數據庫的連接,acceptsURL方法用于判斷驅動是否能夠處理指定的 URL 等。

package java.sql;import java.util.Properties;public interface Driver {public interface Driver {/*** Attempts to make a database connection to the given URL.* The driver should return "null" if it realizes it is the wrong kind* of driver to connect to the given URL.  This will be common, as when* the JDBC driver manager is asked to connect to a given URL it passes* the URL to each loaded driver in turn.** <P>The driver should throw an {@code SQLException} if it is the right* driver to connect to the given URL but has trouble connecting to* the database.** <P>The {@code Properties} argument can be used to pass* arbitrary string tag/value pairs as connection arguments.* Normally at least "user" and "password" properties should be* included in the {@code Properties} object.* <p>* <B>Note:</B> If a property is specified as part of the {@code url} and* is also specified in the {@code Properties} object, it is* implementation-defined as to which value will take precedence. For* maximum portability, an application should only specify a property once.** @param url the URL of the database to which to connect* @param info a list of arbitrary string tag/value pairs as* connection arguments. Normally at least a "user" and* "password" property should be included.* @return a {@code Connection} object that represents a*         connection to the URL* @throws SQLException if a database access error occurs or the url is* {@code null}*/Connection connect(String url, java.util.Properties info)throws SQLException;/*** Retrieves whether the driver thinks that it can open a connection* to the given URL.  Typically drivers will return {@code true} if they* understand the sub-protocol specified in the URL and {@code false} if* they do not.** @param url the URL of the database* @return {@code true} if this driver understands the given URL;*         {@code false} otherwise* @throws SQLException if a database access error occurs or the url is* {@code null}*/boolean acceptsURL(String url) throws SQLException;// 其他方法省略
}

通過這些方法,JDBC 為各種數據庫操作提供了統一的抽象接口,使得上層應用程序可以以一致的方式與不同的數據庫進行交互,而無需關心具體的數據庫實現細節。?

在實現層,不同的數據庫廠商提供了各自的具體驅動實現。例如,MySQL 數據庫的驅動實現類是com.mysql.cj.jdbc.Driver,Oracle 數據庫的驅動實現類是oracle.jdbc.driver.OracleDriver。以 MySQL 驅動實現類com.mysql.cj.jdbc.Driver為例:

package com.mysql.cj.jdbc;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;public class Driver extends NonRegisteringDriver implements java.sql.Driver {static {try {DriverManager.registerDriver(new Driver());} catch (SQLException E) {throw new RuntimeException("Can't register driver!");}}public Driver() throws SQLException {}@Overridepublic Connection connect(String url, Properties info) throws SQLException {// 根據 MySQL 數據庫的連接協議和規范,創建相應的網絡連接,并進行身份驗證和初始化等操作// 這里是簡化示意,實際代碼更復雜return new ConnectionImpl(url, info);}@Overridepublic boolean acceptsURL(String url) throws SQLException {// 判斷是否是 MySQL 數據庫的 URLreturn url != null && url.startsWith("jdbc:mysql:");}// 其他方法省略
}

這些具體實現類實現了Driver接口中定義的方法,針對各自數據庫的特性和協議,提供了與數據庫進行交互的具體邏輯。?

在 JDBC 驅動架構中,DriverManager充當了橋接器的角色,負責管理和加載驅動程序。DriverManager通過反射機制加載具體的驅動實現類。

package java.sql;import java.util.Enumeration;
import java.util.Vector;public class DriverManager {private final static Vector<DriverInfo> registeredDrivers = new Vector<>();public static Connection getConnection(String url, String user, String password) throws SQLException {java.util.Properties info = new java.util.Properties();if (user != null) {info.put("user", user);}if (password != null) {info.put("password", password);}return getConnection(url, info, Reflection.getCallerClass());}private static Connection getConnection(String url, java.util.Properties info, Class<?> caller) throws SQLException {for (DriverInfo aDriver : registeredDrivers) {Driver driver = aDriver.driver;if (driver.acceptsURL(url)) {return driver.connect(url, info);}}throw new SQLException("No suitable driver found for " + url);}// 其他方法省略
}

當應用程序調用DriverManager.getConnection方法時,DriverManager會遍歷已注冊的驅動程序列表,調用每個驅動的acceptsURL方法,判斷哪個驅動能夠處理指定的 URL。如果找到合適的驅動,就會調用該驅動的connect方法,建立與數據庫的連接。

這種機制使得應用程序可以在運行時動態地選擇和切換不同的數據庫驅動,實現了抽象與實現的分離和動態綁定。

此時如果我們在開發階段可能使用 MySQL 數據庫進行開發和測試,而在生產環境中,為了滿足高并發和高可靠性的需求,可能會切換到 Oracle 數據庫。通過 JDBC 的橋接模式,只需要在配置文件中修改數據庫的 URL 和驅動類名,應用程序的其他部分無需修改,就可以輕松地切換到不同的數據庫。

3.2?JUnit 框架中橋接模式的應用?

在 JUnit 框架里,橋接模式的運用體現在測試運行器與測試用例的關系上。測試運行器負責執行測試用例,橋接模式則實現了二者的解耦,進而提升框架的靈活性與可擴展性。?

JUnit 的測試運行器是一個抽象概念,定義了執行測試用例的基本流程與規范,但不涉及具體的測試用例實現。比如 JUnit4 中的JUnitCore,它是一個測試運行器,承擔著加載和運行測試用例的職責。

import org.junit.runner.JUnitCore;import org.junit.runner.Result;import org.junit.runner.notification.Failure;public class TestRunner {public static void main(String[] args) {// 使用JUnitCore運行MyTest類的測試用例Result result = JUnitCore.runClasses(MyTest.class);// 遍歷測試結果中的失敗項for (Failure failure : result.getFailures()) {System.out.println(failure.toString());}// 根據測試結果輸出相應信息System.out.println(result.wasSuccessful()? "所有測試通過" : "有測試失敗");}
}

而測試用例是具體測試邏輯的實現,通過編寫測試類和測試方法來定義。

import org.junit.Test;import static org.junit.Assert.*;public class MyTest {@Testpublic void testAddition() {int result = 2 + 3;assertEquals(5, result);}
}

在 JUnit 中,橋接模式借助Runner類及其子類,實現測試運行器和測試用例之間的動態綁定。Runner類是抽象類,定義了獲取測試用例、運行測試用例等方法。不同的測試運行器通過繼承Runner類,實現其抽象方法,從而提供具體的測試執行邏輯。?

以BlockJUnit4ClassRunner為例,它是Runner的子類,用于運行 JUnit4 風格的測試類。當JUnitCore運行測試類時,會依據測試類的類型,選擇合適的Runner子類來運行測試用例。

在運行期,JUnit 的測試運行器會根據測試類的元數據,比如注解等,創建相應的Runner實例,然后通過這個實例執行測試用例。這種方式實現了測試運行器和測試用例之間的解耦,使得更換測試運行器或測試用例變得輕松,無需大量修改代碼。?

除了上述 JUnit4 風格的測試類,JUnit 還支持 JUnit 5 的測試風格。JUnit 5 引入了全新的編程模型,在 JUnit 5 中,測試類和測試方法使用@Test、@BeforeEach、@AfterEach等注解進行定義,并且支持使用斷言庫進行斷言操作。例如:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;public class JUnit5Test {@Testpublic void testMultiplication() {int result = 3 * 4;assertEquals(12, result);}
}

JUnit 5 中測試運行器也發生了變化,JUnitPlatform作為測試運行器的核心。JUnitPlatform通過發現機制找到所有的測試類,并委托給相應的測試引擎執行測試。

不同的測試引擎可以看作是Runner的變體,針對 JUnit 5 的測試風格進行適配。例如JUnit Jupiter引擎專門用于運行 JUnit 5 風格的測試類,它會解析 JUnit 5 的注解,構建測試執行上下文,然后執行測試方法。

當項目中需要運行 JUnit 5 風格的測試用例時,只需要將JUnit Jupiter引擎集成到項目中,JUnitPlatform會自動識別并使用該引擎來運行 JUnit 5 風格的測試類,而無需對其他部分代碼進行大規模修改,這進一步體現了橋接模式在 JUnit 框架中對不同類型測試用例和測試運行器的靈活支持。?

從使用結果來看,借助橋接模式,JUnit 框架能靈活支持不同類型的測試用例和測試運行器。在項目中,我們可根據需求選擇合適的測試運行器,也能方便地編寫和擴展測試用例。

同時,橋接模式讓 JUnit 框架的代碼結構更清晰,易于維護和擴展。比如,要添加新的測試運行器或者新的測試用例類型,只需繼承Runner類并實現相應邏輯,不會對其他部分代碼造成影響。

四、 橋接模式業務場景的基本應用

在供應鏈管理中,物流配送是一個關鍵環節。這里我們以一個大型電商企業的供應鏈物流配送系統為例,來理解橋接模式的應用。

假設電商企業需要與多家物流供應商(如順豐、中通、韻達)合作,同時支持不同的配送方式(如標準快遞、加急快遞、同城當日達)。如果不使用橋接模式,傳統的實現方式會導致代碼的高度耦合和難以維護。

比如,為每種物流供應商和配送方式的組合創建單獨的類,隨著物流供應商和配送方式的增加,類的數量會呈指數級增長,代碼復雜度也會急劇上升。?

而使用橋接模式,我們可以將物流供應商和配送方式進行分離,使它們能夠獨立變化。

首先,我們可以定義物流供應商接口LogisticsProvider,并創建順豐、中通、韻達等物流供應商的實現類。然后,定義配送方式接口DeliveryMethod,并創建標準快遞、加急快遞、同城當日達的實現類。最后,通過一個配送抽象類Delivery,將物流供應商和配送方式進行關聯,實現兩者的解耦。

// 物流供應商接口
public interface LogisticsProvider {void deliver(String orderId);
}// 順豐物流供應商實現
@Component
public class SFExpressProvider implements LogisticsProvider {@Overridepublic void deliver(String orderId) {System.out.println("順豐正在配送訂單:" + orderId);}
}// 中通物流供應商實現
@Component
public class ZTOExpressProvider implements LogisticsProvider {@Overridepublic void deliver(String orderId) {System.out.println("中通正在配送訂單:" + orderId);}
}// 韻達物流供應商實現
@Component
public class YundaExpressProvider implements LogisticsProvider {@Overridepublic void deliver(String orderId) {System.out.println("韻達正在配送訂單:" + orderId);}
}// 配送方式接口
public interface DeliveryMethod {void executeDelivery(LogisticsProvider provider, String orderId);
}// 標準快遞配送方式實現
@Component
public class StandardDeliveryMethod implements DeliveryMethod {@Overridepublic void executeDelivery(LogisticsProvider provider, String orderId) {System.out.println("使用標準快遞配送");provider.deliver(orderId);}
}// 加急快遞配送方式實現
@Component
public class ExpressDeliveryMethod implements DeliveryMethod {@Overridepublic void executeDelivery(LogisticsProvider provider, String orderId) {System.out.println("使用加急快遞配送");provider.deliver(orderId);}
}// 同城當日達配送方式實現
@Component
public class SameDayDeliveryMethod implements DeliveryMethod {@Overridepublic void executeDelivery(LogisticsProvider provider, String orderId) {System.out.println("使用同城當日達配送");provider.deliver(orderId);}
}// 配送抽象類
public abstract class Delivery {protected LogisticsProvider logisticsProvider;protected DeliveryMethod deliveryMethod;public Delivery(LogisticsProvider logisticsProvider, DeliveryMethod deliveryMethod) {this.logisticsProvider = logisticsProvider;this.deliveryMethod = deliveryMethod;}public void processDelivery(String orderId) {deliveryMethod.executeDelivery(logisticsProvider, orderId);}
}// 具體配送實現類
@Component
public class OnlineDelivery extends Delivery {public OnlineDelivery(LogisticsProvider logisticsProvider, DeliveryMethod deliveryMethod) {super(logisticsProvider, deliveryMethod);}
}

當我們需要新增一種物流供應商,比如圓通時,只需要創建一個實現LogisticsProvider接口的YTOExpressProvider類,實現其中的deliver方法,即可完成新供應商的添加,而無需修改現有的配送方式和配送邏輯。

// 圓通物流供應商實現
@Component
public class YTOExpressProvider implements LogisticsProvider {@Overridepublic void deliver(String orderId) {System.out.println("圓通正在配送訂單:" + orderId);}
}

如果要新增一種配送方式,比如定時配送,只需創建一個實現DeliveryMethod接口的ScheduledDeliveryMethod類,實現executeDelivery方法,并在需要使用定時配送的地方,將ScheduledDeliveryMethod實例注入到相應的Delivery對象中,就可以輕松實現新配送方式的集成,不會影響到已有的物流供應商和其他配送方式。

// 定時配送方式實現
@Component
public class ScheduledDeliveryMethod implements DeliveryMethod {@Overridepublic void executeDelivery(LogisticsProvider provider, String orderId) {System.out.println("使用定時配送");provider.deliver(orderId);}
}

五、模式總結

雖然一定程度上橋接模式賦予系統極高的靈活性,由于抽象與實現分離,在面對業務需求變更時,我們能夠獨立地對抽象層或實現層進行擴展,而不會對整體架構造成大規模影響。這種分離機制極大地提升了代碼的復用性,底層實現可以被多個不同的抽象所共享,減少了重復代碼的編寫。

比如當我們在一個大型項目中,日志組件可能需要根據不同的環境或需求動態更換,從簡單的控制臺日志記錄切換到文件日志記錄,甚至是分布式日志系統。通過橋接模式,抽象的日志記錄接口與具體的日志實現類分離,在運行時可以輕松切換不同的日志實現,而無需修改大量的業務代碼。

但是橋接模式并非完美無缺。引入多層抽象無疑增加了系統的復雜度,開發人員需要花費更多精力去理解和設計抽象與實現之間的關系。

同時,這種分層設計也帶來了一定的學習成本,對于新手而言,理解橋接模式的運作機制需要一定的時間和實踐。所以各位一定要量力而行,根據業務場景和架構情況選擇合適的設計模式是至關重要的。

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

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

相關文章

java筆記02

運算符 1.隱式轉換和強制轉換 類型轉換的分類 1.隱式轉換&#xff1a; 取值范圍小的數值 轉換為 取值范圍大的數值 2.強制轉換&#xff1a; 取值范圍大的數值 轉換為 取值范圍小的數值隱式轉換的兩種提升規則 取值范圍小的&#xff0c;和取值范圍大的進行運算&#xff0c;小的…

Redis-07.Redis常用命令-集合操作命令

一.集合操作命令 SADD key member1 [member2]&#xff1a; sadd set1 a b c d sadd set1 a 0表示沒有添加成功&#xff0c;因為集合中已經有了這個元素了&#xff0c;因此無法重復添加。 SMEMBERS key: smembers set1 SCARD key&#xff1a; scard set1 SADD key member1 …

李飛飛、吳佳俊團隊新作:FlowMo如何以零卷積、零對抗損失實現ImageNet重構新巔峰

目錄 一、摘要 二、引言 三、相關工作 四、方法 基于擴散先前的離散標記化器利用廣告 架構 階段 1A&#xff1a;模式匹配預訓練 階段 1B&#xff1a;模式搜索后訓練 采樣 第二階段&#xff1a;潛在生成建模 五、Coovally AI模型訓練與應用平臺 六、實驗 主要結果 …

CSS3:現代Web設計的魔法卷軸

一、布局革命&#xff1a;從平面到多維空間 1.1 Grid布局的次元突破 星際戰艦布局系統 .galaxy {display: grid;grid-template-areas: "nav nav nav""sidebar content ads""footer footer footer";grid-template-rows: 80px 1fr 120p…

美觀快速的react 的admin框架

系統特色&#xff1a; - &#x1f3a8; 精心設計的UI主題系統&#xff0c;提供優雅的配色方案和視覺體驗 - &#x1f4e6; 豐富完整的組件庫&#xff0c;包含大量開箱即用的高質量組件 - &#x1f528; 詳盡的組件使用示例&#xff0c;降低開發者的學習成本 - &#x1f680…

【C++】 string底層封裝的模擬實現

目錄 前情提要Member functions —— 成員函數構造函數拷貝構造函數賦值運算符重載析構函數 Element access —— 元素訪問Iterator —— 迭代器Capacity —— 容量sizecapacityclearemptyreserveresize Modifiers —— 修改器push_backappendoperator(char ch)operator(const …

計算機網絡相關知識小結

計算機網絡 1.計算機網絡&#xff1a;獨立計算機&#xff0c;通信線路連接&#xff0c;實現資源共享 2.組成&#xff1a;資源子網和通信子網 3.拓撲分類 4.范圍&#xff1a;LAN, MAN. WAN 5、有線和無線 6.按照方向&#xff1a;單工、雙工&#xff0c;全雙工 7.傳輸對象方式&a…

16-CSS3新增選擇器

知識目標 掌握屬性選擇器的使用掌握關系選擇器的使用掌握結構化偽類選擇器的使用掌握偽元素選擇器的使用 如何減少文檔內class屬性和id屬性的定義&#xff0c;使文檔變得更加簡潔&#xff1f; 可以通過屬性選擇器、關系選擇器、結構化偽類選擇器、偽元素選擇器。 1. 屬性選擇…

【彈性計算】異構計算云服務和 AI 加速器(四):FPGA 虛擬化技術

《異構計算云服務和 AI 加速器》系列&#xff0c;共包含以下文章&#xff1a; 異構計算云服務和 AI 加速器&#xff08;一&#xff09;&#xff1a;功能特點異構計算云服務和 AI 加速器&#xff08;二&#xff09;&#xff1a;適用場景異構計算云服務和 AI 加速器&#xff08;…

Java進階——位運算

位運算直接操作二進制位&#xff0c;在處理底層數據、加密算法、圖像處理等領域具有高效性能和效率。本文將深入探討Java中的位運算。 本文目錄 一、位運算簡介1. 與運算2. 或運算異或運算取反運算左移運算右移運算無符號右移運算 二、位運算的實際應用1. 權限管理2. 交換兩個變…

OpenAI深夜直播「偷襲」谷歌!GPT-4o原生圖像生成:奧特曼帶梗圖,AGI戰場再燃戰火

引言&#xff1a;AI戰場的「閃電戰」 當谷歌剛剛發布「地表最強」Gemini 2.5 Pro時&#xff0c;OpenAI立即以一場深夜直播「閃電反擊」——GPT-4o的原生圖像生成功能正式上線&#xff01;從自拍變梗圖到相對論漫畫&#xff0c;奧特曼&#xff08;OpenAI團隊&#xff09;用一連…

鴻蒙harmonyOS:筆記 正則表達式

從給出的文本中&#xff0c;按照既定的相關規則&#xff0c;匹配出符合的數據&#xff0c;其中的規則就是正則表達式&#xff0c;使用正則表達式&#xff0c;可以使得我們用簡潔的代碼就能實現一定復雜的邏輯&#xff0c;比如判斷一個郵箱賬號是否符合正常的郵箱賬號&#xff0…

[首發]烽火HG680-KD-海思MV320芯片-2+8G-安卓9.0-強刷卡刷固件包

烽火HG680-KD-海思MV320芯片-28G-安卓9.0-強刷卡刷固件包 U盤強刷刷機步驟&#xff1a; 1、強刷刷機&#xff0c;用一個usb2.0的8G以下U盤&#xff0c;fat32&#xff0c;2048塊單分區格式化&#xff08;強刷對&#xff35;盤非常非常挑剔&#xff0c;usb2.0的4G U盤兼容的多&a…

Python-數據處理

第十五章 生成數據 安裝Matplotlib&#xff1a;通過pip install matplotlib命令安裝庫。繪制折線圖的核心語法為&#xff1a; import matplotlib.pyplot as plt x_values [1, 2, 3] y_values [1, 4, 9] plt.plot(x_values, y_values, linewidth2) plt.title(&quo…

Java基礎-23-靜態變量與靜態方法的使用場景

在Java中&#xff0c;static關鍵字用于定義靜態變量和靜態方法。它們屬于類本身&#xff0c;而不是類的某個實例。因此&#xff0c;靜態成員可以通過類名直接訪問&#xff0c;而無需創建對象。以下是靜態變量與靜態方法的常見使用場景&#xff1a; 一、靜態變量的使用場景 靜態…

大模型架構記錄12【Agent實例-tool】

運行根目錄下幾個ipynb文件- Learn-Agent.ipynb- 學習《Custom agent 自定義代理》部分- v1-Create-Custom-Agent.ipynb- v2-Create-Custom-Agent.ipynb- 基于v1&#xff0c;新增一些職位描述&#xff08;JD&#xff09;信息- v3-Create-Custom-Agent.ipynb- 基于v2&#xff0c…

在MCU工程中優化CPU工作效率的幾種方法

在嵌入式系統開發中&#xff0c;優化 CPU 工作效率對于提升系統性能、降低功耗、提高實時性至關重要。Keil 作為主流的嵌入式開發工具&#xff0c;提供了多種優化策略&#xff0c;包括 關鍵字使用、內存管理、字節對齊、算法優化 等。本文將從多個方面介紹如何在 Keil 工程中優…

Linux系統下C語言fork函數使用案例

一、fork函數的作用 生成一個子進程&#xff0c;異步執行某個任務&#xff1b; 二、子進程的作用 1、子進程能復制一份父進程的變量、函數&#xff1b; 2、子進程可以和父進程同時并發執行&#xff1b; 函數語法&#xff1a; pid_t fork() 說明&#xff1a;調用后返回一個進程…

MySQL中的CREATE TABLE LIKE和CREATE TABLE SELECT

MySQL中的CREATE TABLE LIKE和CREATE TABLE SELECT CREATE TABLE LIKECREATE TABLE SELECT CREATE TABLE LIKE CREATE TABLE ... LIKE可以用來復制表結構&#xff0c;源表上的索引和約束也會復制。CREATE TABLE ... LIKE不能復制表數據。CREATE TABLE ... LIKE只能復制基表&…

Java開發者指南:深入理解HotStuff新型共識算法

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、全棧領域優質創作者、高級開發工程師、高級信息系統項目管理師、系統架構師&#xff0c;數學與應用數學專業&#xff0c;10年以上多種混合語言開發經驗&#xff0c;從事DICOM醫學影像開發領域多年&#xff0c;熟悉DICOM協議及…