適配器模式深度解析:Java設計模式實戰指南與接口兼容性解決方案

適配器模式深度解析:Java設計模式實戰指南與接口兼容性解決方案


🌟 嗨,我是IRpickstars!
🌌 總有一行代碼,能點亮萬千星辰。
🔍 在技術的宇宙中,我愿做永不停歇的探索者。
? 用代碼丈量世界,用算法解碼未來。我是摘星人,也是造夢者。
🚀 每一次編譯都是新的征程,每一個bug都是未解的謎題。讓我們攜手,在0和1的星河中,書寫屬于開發者的浪漫詩篇。


目錄

1. 技術背景

2. 概念定義

2.1 適配器模式定義

2.2 核心組成要素

2.3 適配器類型

3. 原理剖析

3.1 工作機制

3.2 對象適配器vs類適配器

4. 技術實現

4.1 基礎適配器接口實現

4.2 具體被適配者實現

4.3 適配器類實現

4.4 通用適配器框架實現

5. 應用場景

5.1 主要應用場景分析

5.2 典型使用場景

6. 實際案例

6.1 支付系統適配器案例

6.2 數據源適配器案例

7. 優缺點分析

7.1 適配器模式優缺點對比

7.2 詳細分析

8. 縱橫對比

8.1 與其他結構型模式對比

8.2 模式選擇指導

9. 實戰思考

9.1 最佳實踐建議

9.2 性能優化策略

9.3 常見問題與解決方案

10. 總結

10.1 核心價值

10.2 適用邊界

10.3 發展趨勢

10.4 實踐建議


1. 技術背景

在現代軟件開發中,系統集成和接口兼容性問題是開發者經常面臨的挑戰。隨著軟件系統的復雜性不斷增加,我們經常需要將具有不同接口的類或組件進行協作。這些組件可能來自第三方庫、遺留系統或者不同的開發團隊,它們的接口設計往往不能直接兼容。

適配器模式(Adapter Pattern)作為GoF設計模式中的一種重要結構型模式,為解決接口不兼容問題提供了優雅的解決方案。就像現實生活中的電源適配器能夠讓不同規格的插頭與插座配合使用一樣,軟件中的適配器模式能夠讓原本因接口不匹配而無法協作的類能夠一起工作。

在企業級應用開發中,適配器模式被廣泛應用于:

  • 第三方SDK集成
  • 遺留系統現代化改造
  • 數據格式轉換
  • API接口統一
  • 框架間的橋接

2. 概念定義

2.1 適配器模式定義

適配器模式(Adapter Pattern)是一種結構型設計模式,它允許接口不兼容的類協同工作。適配器模式通過將一個類的接口轉換成客戶端所期望的另一個接口,使得原本由于接口不匹配而不能一起工作的類能夠協同工作。

2.2 核心組成要素

適配器模式主要包含以下幾個核心要素:

  1. 目標接口(Target):客戶端所期望的接口
  2. 被適配者(Adaptee):需要被適配的現有類
  3. 適配器(Adapter):實現目標接口并包裝被適配者的類
  4. 客戶端(Client):使用目標接口的代碼

2.3 適配器類型

適配器模式有兩種主要實現方式:

  • 對象適配器:使用組合關系,適配器持有被適配者的實例
  • 類適配器:使用繼承關系,適配器繼承被適配者類(Java中較少使用)

3. 原理剖析

3.1 工作機制

適配器模式的核心思想是通過引入一個適配器類,將被適配者的接口轉換為目標接口。客戶端通過目標接口與適配器交互,適配器內部調用被適配者的方法來完成實際工作。

圖1 適配器模式工作機制圖

3.2 對象適配器vs類適配器

圖2 適配器模式實現方式對比圖

4. 技術實現

4.1 基礎適配器接口實現

/*** 目標接口:媒體播放器* 客戶端期望的統一接口*/
public interface MediaPlayer {/*** 播放媒體文件* @param audioType 音頻類型* @param fileName 文件名*/void play(String audioType, String fileName);
}/*** 被適配者:高級媒體播放器* 現有的第三方播放器接口*/
public interface AdvancedMediaPlayer {void playVlc(String fileName);void playMp4(String fileName);void playMkv(String fileName);
}

4.2 具體被適配者實現

/*** VLC播放器實現* 被適配的具體實現類*/
public class VlcPlayer implements AdvancedMediaPlayer {@Overridepublic void playVlc(String fileName) {System.out.println("正在播放VLC格式文件: " + fileName);}@Overridepublic void playMp4(String fileName) {// VLC播放器不支持MP4格式throw new UnsupportedOperationException("VLC播放器不支持MP4格式");}@Overridepublic void playMkv(String fileName) {// VLC播放器不支持MKV格式throw new UnsupportedOperationException("VLC播放器不支持MKV格式");}
}/*** MP4播放器實現*/
public class Mp4Player implements AdvancedMediaPlayer {@Overridepublic void playVlc(String fileName) {throw new UnsupportedOperationException("MP4播放器不支持VLC格式");}@Overridepublic void playMp4(String fileName) {System.out.println("正在播放MP4格式文件: " + fileName);}@Overridepublic void playMkv(String fileName) {throw new UnsupportedOperationException("MP4播放器不支持MKV格式");}
}

4.3 適配器類實現

/*** 媒體適配器* 將AdvancedMediaPlayer適配為MediaPlayer接口*/
public class MediaAdapter implements MediaPlayer {private AdvancedMediaPlayer advancedMusicPlayer;/*** 構造函數:根據音頻類型創建相應的播放器* @param audioType 音頻類型*/public MediaAdapter(String audioType) {if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer = new VlcPlayer();} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer = new Mp4Player();} else {throw new IllegalArgumentException("不支持的音頻格式: " + audioType);}}@Overridepublic void play(String audioType, String fileName) {// 將統一的play方法適配為具體的播放方法if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer.playVlc(fileName);} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer.playMp4(fileName);} else {System.out.println("不支持的格式: " + audioType);}}
}/*** 音頻播放器:主要的客戶端類* 支持內置格式和通過適配器支持的格式*/
public class AudioPlayer implements MediaPlayer {private MediaAdapter mediaAdapter;@Overridepublic void play(String audioType, String fileName) {// 內置支持mp3格式if (audioType.equalsIgnoreCase("mp3")) {System.out.println("正在播放MP3格式文件: " + fileName);}// 通過適配器支持其他格式else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);} else {System.out.println("不支持的音頻格式: " + audioType + "。僅支持mp3, vlc, mp4格式。");}}
}

4.4 通用適配器框架實現

/*** 通用適配器接口* 提供類型安全的適配器基礎*/
public interface Adapter<T, R> {/*** 適配方法* @param source 源對象* @return 適配后的對象*/R adapt(T source);/*** 檢查是否支持適配* @param source 源對象* @return 是否支持*/boolean supports(T source);
}/*** 抽象適配器基類* 提供通用的適配器實現模板*/
public abstract class AbstractAdapter<T, R> implements Adapter<T, R> {@Overridepublic final R adapt(T source) {if (!supports(source)) {throw new IllegalArgumentException("不支持的源對象類型");}return doAdapt(source);}/*** 具體的適配邏輯由子類實現*/protected abstract R doAdapt(T source);
}

5. 應用場景

5.1 主要應用場景分析

適配器模式在軟件開發中有著廣泛的應用場景:

圖3 適配器模式應用場景分析圖

5.2 典型使用場景

系統集成場景:

  • 整合不同廠商的API接口
  • 微服務架構中的接口適配
  • 數據庫訪問層的統一封裝

接口標準化場景:

  • 多種支付方式的統一接口
  • 不同消息隊列的統一訪問
  • 多種緩存系統的統一操作

遺留系統改造場景:

  • 新舊系統的接口橋接
  • 數據格式的轉換適配
  • 通信協議的轉換

6. 實際案例

6.1 支付系統適配器案例

/*** 統一支付接口* 客戶端期望的支付接口*/
public interface PaymentProcessor {/*** 處理支付* @param amount 金額* @param currency 貨幣類型* @return 支付結果*/PaymentResult processPayment(double amount, String currency);
}/*** 支付結果統一返回格式*/
public class PaymentResult {private boolean success;private String transactionId;private String message;// 構造函數和getter/setter方法省略public PaymentResult(boolean success, String transactionId, String message) {this.success = success;this.transactionId = transactionId;this.message = message;}// getter方法省略public boolean isSuccess() { return success; }public String getTransactionId() { return transactionId; }public String getMessage() { return message; }
}/*** 第三方支付SDK - 支付寶* 被適配的支付寶支付接口*/
public class AlipaySDK {public String alipayQuickPay(String amount, String currency) {// 模擬支付寶支付邏輯System.out.println("支付寶支付: ¥" + amount + " " + currency);return "ALIPAY_" + System.currentTimeMillis();}public boolean checkPaymentStatus(String orderId) {// 模擬狀態檢查return true;}
}/*** 第三方支付SDK - 微信支付* 被適配的微信支付接口*/
public class WechatPaySDK {public Map<String, Object> wechatUnifiedOrder(BigDecimal totalFee, String currencyType) {// 模擬微信支付邏輯System.out.println("微信支付: ¥" + totalFee + " " + currencyType);Map<String, Object> result = new HashMap<>();result.put("return_code", "SUCCESS");result.put("transaction_id", "WX_" + System.currentTimeMillis());return result;}
}/*** 支付寶適配器*/
public class AlipayAdapter implements PaymentProcessor {private AlipaySDK alipaySDK;public AlipayAdapter() {this.alipaySDK = new AlipaySDK();}@Overridepublic PaymentResult processPayment(double amount, String currency) {try {// 調用支付寶SDK進行支付String transactionId = alipaySDK.alipayQuickPay(String.valueOf(amount), currency);// 檢查支付狀態boolean success = alipaySDK.checkPaymentStatus(transactionId);return new PaymentResult(success, transactionId, "支付寶支付完成");} catch (Exception e) {return new PaymentResult(false, null, "支付寶支付失敗: " + e.getMessage());}}
}/*** 微信支付適配器*/
public class WechatPayAdapter implements PaymentProcessor {private WechatPaySDK wechatPaySDK;public WechatPayAdapter() {this.wechatPaySDK = new WechatPaySDK();}@Overridepublic PaymentResult processPayment(double amount, String currency) {try {// 調用微信支付SDKMap<String, Object> result = wechatPaySDK.wechatUnifiedOrder(BigDecimal.valueOf(amount), currency);String returnCode = (String) result.get("return_code");boolean success = "SUCCESS".equals(returnCode);String transactionId = (String) result.get("transaction_id");return new PaymentResult(success, transactionId, "微信支付完成");} catch (Exception e) {return new PaymentResult(false, null, "微信支付失敗: " + e.getMessage());}}
}

6.2 數據源適配器案例

/*** 統一數據源接口*/
public interface DataSource {/*** 獲取數據* @param query 查詢條件* @return 數據列表*/List<Map<String, Object>> getData(String query);/*** 獲取數據源類型* @return 數據源類型*/String getDataSourceType();
}/*** REST API數據源適配器*/
public class RestApiAdapter implements DataSource {private String apiBaseUrl;private HttpClient httpClient;public RestApiAdapter(String apiBaseUrl) {this.apiBaseUrl = apiBaseUrl;this.httpClient = HttpClient.newHttpClient();}@Overridepublic List<Map<String, Object>> getData(String query) {try {// 構建REST API請求String url = apiBaseUrl + "/data?query=" + URLEncoder.encode(query, "UTF-8");HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET().build();// 發送請求并解析響應HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());// 模擬JSON解析System.out.println("從REST API獲取數據: " + query);return parseJsonResponse(response.body());} catch (Exception e) {throw new RuntimeException("REST API數據獲取失敗", e);}}@Overridepublic String getDataSourceType() {return "REST_API";}private List<Map<String, Object>> parseJsonResponse(String jsonResponse) {// 簡化的JSON解析邏輯List<Map<String, Object>> result = new ArrayList<>();Map<String, Object> data = new HashMap<>();data.put("source", "REST_API");data.put("data", jsonResponse);result.add(data);return result;}
}/*** 數據源管理器* 統一管理不同類型的數據源*/
public class DataSourceManager {private List<DataSource> dataSources;public DataSourceManager() {this.dataSources = new ArrayList<>();}public void addDataSource(DataSource dataSource) {dataSources.add(dataSource);}/*** 從所有數據源獲取數據并合并*/public List<Map<String, Object>> aggregateData(String query) {List<Map<String, Object>> aggregatedData = new ArrayList<>();for (DataSource dataSource : dataSources) {try {List<Map<String, Object>> data = dataSource.getData(query);aggregatedData.addAll(data);} catch (Exception e) {System.err.println("數據源 " + dataSource.getDataSourceType() + " 獲取數據失敗: " + e.getMessage());}}return aggregatedData;}
}

7. 優缺點分析

7.1 適配器模式優缺點對比

圖4 適配器模式優缺點分析圖

7.2 詳細分析

主要優點:

  1. 接口兼容性:使得接口不兼容的類能夠協同工作
  2. 代碼復用:可以復用現有類的功能,無需重新開發
  3. 開閉原則:對擴展開放,對修改封閉
  4. 職責分離:將接口轉換邏輯與業務邏輯分離

主要缺點:

  1. 系統復雜性:增加了系統的復雜性,類的數量增加
  2. 性能開銷:增加了額外的方法調用層次
  3. 維護成本:需要維護適配器代碼,接口變更可能影響適配器

8. 縱橫對比

8.1 與其他結構型模式對比

對比維度

適配器模式

裝飾器模式

外觀模式

代理模式

主要目的

接口轉換適配

功能增強擴展

簡化復雜接口

控制訪問代理

結構關系

適配不兼容接口

裝飾原有對象

封裝子系統

代理目標對象

使用時機

接口不匹配時

需要擴展功能時

接口過于復雜時

需要控制訪問時

對象關系

組合或繼承

組合關系

組合關系

組合關系

接口一致性

轉換為目標接口

保持原接口

提供新接口

保持原接口

8.2 模式選擇指導

圖5 結構型模式選擇指導圖

9. 實戰思考

9.1 最佳實踐建議

1. 合理設計適配器接口

/*** 良好的適配器接口設計* 提供清晰的適配邊界和異常處理*/
public abstract class BaseAdapter<Source, Target> {/*** 適配方法模板*/public final Target adapt(Source source) {// 前置檢查validateSource(source);try {// 執行適配return doAdapt(source);} catch (Exception e) {// 統一異常處理handleAdaptException(e, source);throw new AdapterException("適配失敗", e);}}/*** 源對象驗證*/protected void validateSource(Source source) {if (source == null) {throw new IllegalArgumentException("源對象不能為null");}}/*** 具體適配邏輯由子類實現*/protected abstract Target doAdapt(Source source);/*** 異常處理*/protected void handleAdaptException(Exception e, Source source) {// 記錄日志、監控等System.err.println("適配異常: " + e.getMessage());}
}

2. 適配器緩存優化

/*** 帶緩存的適配器管理器* 優化適配器創建和使用性能*/
public class CachedAdapterManager {private final Map<Class<?>, Adapter<?, ?>> adapterCache = new ConcurrentHashMap<>();@SuppressWarnings("unchecked")public <S, T> T adapt(S source, Class<T> targetType) {Class<?> sourceType = source.getClass();String cacheKey = sourceType.getName() + "->" + targetType.getName();Adapter<S, T> adapter = (Adapter<S, T>) adapterCache.computeIfAbsent(sourceType, k -> createAdapter(sourceType, targetType));return adapter.adapt(source);}private <S, T> Adapter<S, T> createAdapter(Class<?> sourceType, Class<T> targetType) {// 根據類型創建相應的適配器// 可以使用工廠模式或反射機制return AdapterFactory.createAdapter(sourceType, targetType);}
}

9.2 性能優化策略

適配器池化技術:

/*** 適配器對象池* 減少適配器對象創建開銷*/
public class AdapterPool<T extends Adapter<?, ?>> {private final Queue<T> pool = new ConcurrentLinkedQueue<>();private final Supplier<T> adapterFactory;private final int maxPoolSize;public AdapterPool(Supplier<T> adapterFactory, int maxPoolSize) {this.adapterFactory = adapterFactory;this.maxPoolSize = maxPoolSize;}public T borrowAdapter() {T adapter = pool.poll();return adapter != null ? adapter : adapterFactory.get();}public void returnAdapter(T adapter) {if (pool.size() < maxPoolSize) {// 重置適配器狀態resetAdapter(adapter);pool.offer(adapter);}}private void resetAdapter(T adapter) {// 重置適配器內部狀態if (adapter instanceof Resettable) {((Resettable) adapter).reset();}}
}

9.3 常見問題與解決方案

1. 適配器鏈問題
當需要多個適配器串聯時,要注意避免過長的適配器鏈,影響性能和可維護性。

2. 雙向適配
如果需要雙向適配,建議創建兩個獨立的適配器而不是一個雙向適配器。

3. 適配器測試
適配器的單元測試應該重點關注接口轉換的正確性和異常處理。

/*** 適配器單元測試示例*/
@Test
public class PaymentAdapterTest {@Testpublic void testAlipayAdapter() {// 準備測試數據AlipayAdapter adapter = new AlipayAdapter();double amount = 100.0;String currency = "CNY";// 執行適配操作PaymentResult result = adapter.processPayment(amount, currency);// 驗證結果assertNotNull(result);assertTrue(result.isSuccess());assertNotNull(result.getTransactionId());assertTrue(result.getTransactionId().startsWith("ALIPAY_"));}@Testpublic void testAdapterException() {// 測試異常情況AlipayAdapter adapter = new AlipayAdapter();// 驗證異常處理assertThrows(IllegalArgumentException.class, () -> {adapter.processPayment(-100, "CNY");});}
}

10. 總結

適配器模式作為一種重要的結構型設計模式,在現代軟件開發中發揮著關鍵作用。通過本文的深度解析,我們可以得出以下關鍵要點:

10.1 核心價值

接口兼容性價值: 適配器模式完美解決了接口不匹配的問題,使得原本無法協作的組件能夠無縫集成,這在系統集成和第三方庫整合中價值巨大。

代碼復用價值: 通過適配器模式,我們可以充分復用現有的代碼資源,避免重復開發,提高開發效率和代碼質量。

系統擴展價值: 適配器模式提供了良好的擴展機制,新的適配器可以在不影響現有代碼的情況下輕松添加,體現了開閉原則的精髓。

10.2 適用邊界

最佳適用場景:

  • 需要整合不同廠商或第三方的API接口
  • 遺留系統的現代化改造和接口升級
  • 多種數據源或服務的統一訪問接口
  • 系統間的協議轉換和數據格式適配

不建議使用場景:

  • 接口本身設計合理且匹配的情況
  • 系統架構簡單,沒有復雜集成需求
  • 性能要求極高,不能容忍額外調用層次的場景

10.3 發展趨勢

隨著微服務架構和云原生技術的普及,適配器模式在API網關、服務網格、以及多云環境中的應用越來越廣泛。未來的適配器模式將更多地與自動化工具、代碼生成技術結合,減少手動編寫適配器代碼的工作量。

10.4 實踐建議

在實際項目中應用適配器模式時,需要注意以下幾點:

  1. 合理設計適配器層次:避免過深的適配器嵌套,保持簡潔的調用鏈
  2. 重視性能優化:在高并發場景下考慮適配器的緩存和池化策略
  3. 完善異常處理:建立統一的異常處理機制,提高系統的健壯性
  4. 加強測試覆蓋:重點測試接口轉換的正確性和邊界情況

適配器模式體現了軟件設計中"適配"的智慧,它教會我們在面對不兼容的接口時,不是強行修改現有代碼,而是通過引入適配層來優雅地解決問題。這種思想在軟件架構設計、系統集成、以及日常開發中都有重要的指導意義。

通過深入理解和合理應用適配器模式,我們能夠構建更加靈活、可擴展、易維護的軟件系統,為企業的數字化轉型和技術架構升級提供有力支撐。


參考資料:

  1. Design Patterns: Elements of Reusable Object-Oriented Software - GoF設計模式經典著作
  2. Oracle Java Documentation - Interface - Java官方接口文檔
  3. Spring Framework Reference - Integration - Spring框架集成文檔
  4. Effective Java Third Edition - Java最佳實踐指南
  5. GitHub - Java Design Patterns - 適配器模式Java實現示例

關鍵詞標簽: #適配器模式 #設計模式 #Java #接口適配 #結構型模式 #系統集成 #軟件架構 #編程實踐

🌟 嗨,我是IRpickstars!如果你覺得這篇技術分享對你有啟發:

🛠? 點擊【點贊】讓更多開發者看到這篇干貨
🔔 【關注】解鎖更多架構設計&性能優化秘籍
💡 【評論】留下你的技術見解或實戰困惑

作為常年奮戰在一線的技術博主,我特別期待與你進行深度技術對話。每一個問題都是新的思考維度,每一次討論都能碰撞出創新的火花。

🌟 點擊這里👉 IRpickstars的主頁 ,獲取最新技術解析與實戰干貨!

?? 我的更新節奏:

  • 每周三晚8點:深度技術長文
  • 每周日早10點:高效開發技巧
  • 突發技術熱點:48小時內專題解析

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

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

相關文章

類復制.省略 class.copy.elision

class類 復制/移動省略class.copy.elision 類復制省略 (copy elision) 當滿足特定條件時&#xff0c;即使所選對象的構造函數和/或析構函數有副作用&#xff0c;實現也被允許省略從相同類型&#xff08;忽略 cv 限定符&#xff09;的源對象創建類對象。 在這種情況下&#…

goreplay

1.github地址 https://github.com/buger/goreplay 2.簡單介紹 GoReplay 是一個開源的網絡監控工具&#xff0c;可以記錄用戶的實時流量并將其用于鏡像、負載測試、監控和詳細分析。 3.出現背景 隨著應用程序的增長&#xff0c;測試它所需的工作量也會呈指數級增長。GoRepl…

TensorZero:開源 LLM 應用優化與可觀測性平臺

TensorZero 是一個開源的 LLM&#xff08;大語言模型&#xff09;應用全鏈路優化平臺&#xff0c;聚焦于“數據—評估—優化—實驗”自動化閉環&#xff0c;極大提升 LLM 產品的可觀測性、可優化性和可擴展性。無論你是 GPT 應用開發者&#xff0c;還是需要管理和提升 LLM 服務…

postgreSql數據遷移到openGauss的方案

從postgresql 導出sql 腳本 工具-備份 選擇格式為Plain 得到腳本用vscode 打開并編輯 首先使用查找替換功能 語法適配修改?&#xff1a; 替換不支持的參數如lock_timeout為lockwait_timeout 移除row_security等openGauss不支持的配置 檢查并修改物化視圖的刷新語法 …

網絡爬蟲學習心得

一、引言? 在大數據時代&#xff0c;數據成為了驅動決策、洞察趨勢的核心資源。出于對數據分析的濃厚興趣&#xff0c;以及希望能更高效獲取網絡信息的目的&#xff0c;我踏上了網絡爬蟲的學習之旅。通過這段時間的學習&#xff0c;我不僅掌握了從網頁中提取數據的技術&#…

計算機視覺與深度學習 | 基于Matlab的低照度圖像增強算法原理,公式及實現

基于Matlab的低照度圖像增強是一個重要的圖像處理領域。這里我們重點介紹一種經典且效果較好的算法:多尺度Retinex算法(Multi-Scale Retinex with Color Restoration, MSRCR),包括其原理、公式及Matlab實現。 一、核心原理:Retinex理論 Retinex理論由Edwin Land提出,其…

【Linux跬步積累】—— 網絡編程套接字(二)

&#x1f30f;博客主頁&#xff1a;PH_modest的博客主頁 &#x1f6a9;當前專欄&#xff1a;Linux跬步積累 &#x1f48c;其他專欄&#xff1a; &#x1f534; 每日一題 &#x1f7e1; C跬步積累 &#x1f7e2; C語言跬步積累 &#x1f308;座右銘&#xff1a;廣積糧&#xff0…

JavaScript基礎-API 和 Web API

在學習JavaScript的過程中&#xff0c;理解API&#xff08;應用程序接口&#xff09;和Web API的概念及其應用是非常重要的。這些工具極大地擴展了JavaScript的功能&#xff0c;使得開發者能夠創建出功能豐富、交互性強的Web應用程序。本文將深入探討JavaScript中的API與Web AP…

pikachu靶場通關筆記24 SQL注入07-http header注入

目錄 一、SQL注入 二、http header注入 1、User - Agent 頭注入 2、Referer 頭注入 3、Cookie 頭注入 4、Host 頭注入 三、extractvalue函數 四、源碼分析 1、代碼審計 2、滲透思路 五、滲透實戰 1、滲透探測 2、獲取數據庫名database 3、獲取表名table 4、獲取列…

LabVIEW振動時效處理系統

LabVIEW 開發大功率振動時效處理系統&#xff0c;實現工件殘余應力檢測與消除。聚焦工業場景中金屬加工件的應力處理需求&#xff0c;展現 LabVIEW 在跨硬件集成、實時數據處理及復雜流程控制中的技術優勢。 ? 應用場景 針對航空航天、軌道交通、重型機械等領域中鋼性焊接件…

數據定義以及數據類型

toc 數據定義以及數據類型 1. 數據創建 數據庫創建除了指定數據庫名字&#xff0c;還可以選擇指定數據庫字符集類型以及校對規則&#xff0c;mysql中utf8mb3就是utf8。 -- 使用指令創建數據庫 CREATE DATABASE hsp_db01; -- 刪除數據庫指令 DROP DATABASE hsp_db01 -- 創建…

中國汽車啟動電池市場深度剖析:現狀、趨勢與展望

一、市場規模與增長前景? QYResearch 調研團隊發布的市場報告顯示&#xff0c;中國汽車啟動電池市場展現出強勁的增長勢頭。預計到 2031 年&#xff0c;市場規模將攀升至 74.6 億美元&#xff0c;在未來幾年內&#xff0c;年復合增長率&#xff08;CAGR&#xff09;將穩定保持…

通過RedisCacheManager自定義緩存序列化(適用通過注解緩存數據)

1.Redis 注解默認序列化機制 1.Spring Boot整合Redis組件提供的緩存自動配置類RedisCacheConfiguration&#xff08;org.springframework.boot.autoconfigure.cache&#xff09;, 其內部是通過Redis連接工廠RedisConnectionFactory定義了一個緩存管理器RedisCacheManager&am…

jupyter中的checkpoints為空/打不開解決辦法

jupyter中的checkpoints為空/打不開不要以為你是代碼有問題或者服務器有問題了&#xff0c;浪費我好幾天時間&#xff0c;我說怎么電腦上跑的好好的服務器上模型不見了 新建文件check 然后把checkpoints里的東西全部移動到check文件中就能看見了 checkpoints是Notebook的關鍵…

基于 Spring AI 的 MCP 客戶端/服務端實現

模型上下文協議&#xff08;MCP&#xff09;由Anthropic開源的開放協議&#xff0c;為AI模型與外部數據/工具提供了“標準化橋梁”&#xff0c;通過統一的接口規范&#xff0c;使模型能夠動態調用本地文件、數據庫、API等資源&#xff0c;實現“上下文感知”的智能交互。MCP的核…

python學習打卡day50

DAY 50 預訓練模型CBAM模塊 知識點回顧&#xff1a; resnet結構解析CBAM放置位置的思考針對預訓練模型的訓練策略 差異化學習率三階段微調 ps&#xff1a;今日的代碼訓練時長較長&#xff0c;3080ti大概需要40min的訓練時長 作業&#xff1a; 好好理解下resnet18的模型結構嘗試…

54、錯誤處理-【源碼流程】異常處理流程

54、錯誤處理-【源碼流程】異常處理流程 #### 異常處理流程概述 1. **執行目標方法**&#xff1a; - 程序執行目標方法&#xff0c;期間若發生異常&#xff0c;會被捕獲并記錄&#xff0c;標志當前請求結束。 - 將異常信息賦值給 dispatchException 變量。 2. **進入視圖解析…

使用 VSCode 開發 FastAPI 項目(1)

一、引言 FastAPI 是一款現代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于構建 API&#xff0c;使用 Python 3.7 及更高版本。它基于標準 Python 類型提示&#xff0c;具有自動生成文檔等出色功能。而 VSCode 憑借其輕量、強大的特性&#xff0c;為開發者…

Bash 腳本中的特殊變量

在 Bash 腳本和命令行中&#xff0c;?特殊變量?&#xff08;Special Variables&#xff09;主要用于獲取腳本或命令的上下文信息&#xff0c;如參數、進程狀態、返回值等。以下是常見的特殊變量及其典型應用場景&#xff1a; ?1. 腳本參數處理? $0、$1、$2 ... $9、${10}.…