學習記錄:DAY22

假日尾聲:技術進階與自我反思

前言


于是,假日迎來了它的尾聲,把快樂和焦躁都留存在昨天。
我只覺情感的自相矛盾在加重,學習讓我焦躁,縱欲無法填補空虛,于是我的心被拖入了無止盡的拉扯中。
我還沒有找到必須留存的理由,但反之而言,我也遠沒有到可以決定自己生命自由的時刻。
還是閉上雙眼,向前走吧,明日難測,卻因昨日懊悔。
今天來統計一下剩余的進階要求和已經完成的進階要求,再針對性地完成。


日程


9點半,開始學習吧。

  • 上午:連接池動態擴縮容問題弄了一早上
  • 下午:完成了簡單結果集映射
  • 晚上8點:做完結果集相關的blog
  • 嘻嘻,五一的學科作業還沒寫,我完蛋了。

學習內容


省流

  1. 連接池動態擴縮容
  2. 項目階段性進度檢查
  3. 簡單結果集映射

1. 連接池動態擴縮容

1)動態擴容

在等待線程大于最大等待線程值時,臨時將線程池的大小擴大1.5倍。

if (rawConn == null && waitCount.get() > hakimiConfig.getMaxWaitThreads()) {int temporaryMax = (int) (hakimiConfig.getMaxSize() * 1.5); // 擴容上限:maxSize 的 1.5 倍int current;do {current = createdCount.get();if (current >= temporaryMax) {break; // 已達到擴容上限}} while (!createdCount.compareAndSet(current, current + 1));if (current < temporaryMax) {log.warn("已啟用動態擴容");try {rawConn = createPhysicalConnection();} catch (SQLException e) {createdCount.decrementAndGet(); // 創建失敗時回滾計數器throw e;}}
}
2)動態縮容

這里使用了 ScheduledExecutorService 定時任務調度器,scheduleWithFixedDelay 會周期性地觸發里面的回調函數。

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
// 啟動縮容任務(每5分鐘檢查一次)
public void startShrinkTask() {scheduler.scheduleWithFixedDelay(() -> {try {int currentIdle = idleConnections.size();int minIdle = hakimiConfig.getMinIdle();// 僅當空閑連接 > minIdle 時才嘗試縮容if (currentIdle <= minIdle) {return;}// 計算最多可回收的連接數(避免過度縮容)int maxShrink = currentIdle - minIdle;int shrunk = 0;while (shrunk < maxShrink) {// 非阻塞取出連接(避免長時間鎖住隊列)Connection conn = idleConnections.poll(10, TimeUnit.MILLISECONDS);if (conn == null) {break; // 隊列已空}// 檢查是否超時if (isIdleTimeout(conn, hakimiConfig.getIdleTimeoutMillis())) {closeConnection(conn);createdCount.decrementAndGet();log.warn("關閉空閑連接");shrunk++;} else {// 未超時,放回隊列(避免誤殺)idleConnections.offer(conn);}}} catch (Exception e) {log.error("Shrink task error", e);}}, 300, 300, TimeUnit.SECONDS);
}// 檢查連接是否空閑超時
private boolean isIdleTimeout(Connection conn, long idleTimeoutMillis) {if (conn instanceof Proxy) {InvocationHandler handler = Proxy.getInvocationHandler(conn);if (handler instanceof HakimiConnectionPool.ConnectionInvocationHandler) {long idleTime = System.currentTimeMillis() -((HakimiConnectionPool.ConnectionInvocationHandler) handler).lastUsedTime;return idleTime > idleTimeoutMillis;}}return false;
}

2. 項目階段性進度檢查

已完成進階需求
  • Maven 分模塊化構建項目。
  • 完成數據庫連接池,支持動態擴縮容(c3p0、druid)(并發安全(hard))。
  • 將常量配置轉移到 yml 配置文件。
  • 輸出日志文件。
  • 通過依賴注入(DI)進行控制反轉(IOC),使用全局上下文進行全局對象的對象間依賴注入(使用注解)。
  • 實現 AOP 動態代理。
目前需要完成的進階需求
  • SQL 構建器 + 自定義 SQL,高兼容性的結果映射。
  • DispatcherController 來統一接收數據,并轉發給路徑給對應 Controller 處理。
  • 自定義異常拋出,全局異常處理器,過濾器。
  • 后端以多線程模式運行,保證并發安全。(考慮方法級鎖)
往后的進階需求
  • 統一接收 JSON 格式數據,對數據進行混合加密(RSA + AES)。
  • 判題機制,可以運行 C++ 代碼。
  • Nginx 部署前端 + Docker 容器技術。
  • 將項目部署到公網。

3. 簡單結果集映射

1)關鍵方法:預包裝代理方法
private static <T> BiFunction<ResultSet, Integer, T> createMapper(Class<T> targetClass) {try {// 獲取或創建構造函數句柄Constructor<T> constructor = targetClass.getDeclaredConstructor();constructor.setAccessible(true);MethodHandle constructorHandle = MethodHandles.lookup().unreflectConstructor(constructor); // 使用MethodHandle包裝構造器,比傳統反射調用性能更高// 從緩存獲取或創建字段信息Map<String, MethodHandle> setters = Cache.SETTER_CACHE.computeIfAbsent(targetClass, KatSimpleMapper::createSetters);Map<String, Class<?>> fieldTypes = Cache.FIELD_TYPE_CACHE.computeIfAbsent(targetClass, KatSimpleMapper::getFieldTypes);return (rs, index) -> {try {@SuppressWarnings("unchecked")T instance = (T) constructorHandle.invoke(); // 創建目標對象實例for (Map.Entry<String, MethodHandle> entry : setters.entrySet()) {String fieldName = entry.getKey();String columnName = namingStrategy.convert(fieldName);try {Object value = rs.getObject(columnName);if (value != null) {Class<?> fieldType = fieldTypes.get(fieldName);Object convertedValue = convertType(value, fieldType); // 類型轉換entry.getValue().invoke(instance, convertedValue); // 設置屬性值}} catch (SQLException e) {// 列不存在時跳過}}return instance;} catch (Throwable e) {throw new RuntimeException("Mapping failed for " + targetClass.getName(), e);}};} catch (Exception e) {throw new RuntimeException("Mapper creation failed for " + targetClass.getName(), e);}
}
2)包裝方法:負責將觸發代理方法,將mapper結果映射到結果集中
public static <T> List<T> map(ResultSet rs, Class<T> targetClass) throws SQLException {@SuppressWarnings("unchecked")BiFunction<ResultSet, Integer, T> mapper = (BiFunction<ResultSet, Integer, T>)Cache.MAPPER_CACHE.computeIfAbsent(targetClass, KatSimpleMapper::createMapper);List<T> results = new ArrayList<>();while (rs.next()) {results.add(mapper.apply(rs, 1));}return results;
}
3)輔助方法
  • 數據庫字段類型到java字段類型的轉換
private static Object convertType(Object value, Class<?> targetType) {if (value == null) return null;if (targetType.isInstance(value)) return value;// 數值類型轉換if (value instanceof Number number) {if (targetType == Double.class || targetType == double.class) {return number.doubleValue();}if (targetType == Float.class || targetType == float.class) {return number.floatValue();}if (targetType == Integer.class || targetType == int.class) {return number.intValue();}if (targetType == Long.class || targetType == long.class) {return number.longValue();}if (targetType == Short.class || targetType == short.class) {return number.shortValue();}}// 日期類型轉換if (value instanceof java.sql.Date sqlDate) {if (targetType == LocalDate.class) {return sqlDate.toLocalDate();}if (targetType == LocalDateTime.class) {return sqlDate.toLocalDate().atStartOfDay();}}// 布爾類型轉換if (value instanceof Boolean bool) {if (targetType == Integer.class || targetType == int.class) {return bool ? 1 : 0;}if (targetType == Double.class || targetType == double.class) {return bool ? 1.0 : 0.0;}}// 時間戳轉換if (value instanceof Timestamp timestamp) {if (targetType == LocalDateTime.class) {return timestamp.toLocalDateTime();}if (targetType == LocalDate.class) {return timestamp.toLocalDateTime().toLocalDate();}}return value;
}
  • 創建setter方法并緩存
private static <T> Map<String, MethodHandle> createSetters(Class<T> targetClass) {try {Map<String, MethodHandle> setters = new HashMap<>();MethodHandles.Lookup lookup = MethodHandles.lookup(); // 獲取MethodHandles.Lookup實例,用于方法/字段查找for (Field field : targetClass.getDeclaredFields()) {try {MethodHandle setter = lookup.unreflectSetter(field); // 嘗試通過標準setter方法獲取MethodHandlesetters.put(field.getName(), setter);} catch (IllegalAccessException e) {// 如果字段沒有setter,嘗試直接設置字段值field.setAccessible(true);MethodHandle setter = lookup.unreflectSetter(field);setters.put(field.getName(), setter);}}return Collections.unmodifiableMap(setters); // 返回不可修改的Map} catch (Exception e) {throw new RuntimeException("Failed to create setters for " + targetClass.getName(), e);}
}

結語



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

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

相關文章

Oracle OCP認證考試考點詳解083系列07

題記&#xff1a; 本系列主要講解Oracle OCP認證考試考點&#xff08;題目&#xff09;&#xff0c;適用于19C/21C,跟著學OCP考試必過。 31. 第31題&#xff1a; 題目 解析及答案&#xff1a; 從 Oracle 19c 開始&#xff0c;數據庫配置助手&#xff08;DBCA&#xff09;在克…

專業課復習筆記 4

前言 實際上對于我的考研來說&#xff0c;最重要的兩門就是數學和專業課。所以從今天開始&#xff0c;我盡可能多花時間學習數學和專業課。把里面的知識和邏輯關系理解清楚&#xff0c;把常考的內容練習透徹。就這樣。 尋址方式 立即數尋址 操作數在指令里面直接提供了。 …

Go小技巧易錯點100例(三十)

本期分享&#xff1a; 1.切片共享底層數組 2.獲取Go函數的注釋 切片共享底層數組 在Go語言中&#xff0c;切片和數組是兩種不同的元素&#xff0c;但是切片的底層是數組&#xff0c;并且還有一個比較重要的機制&#xff1a;切片共享底層數組。 下面這段代碼演示了切片&…

反轉字符串2

reverse函數的用法(reverse一般是左閉右開區間)&#xff1a; 1.反轉數組&#xff1a; int arr[] {1, 2, 3, 4, 5}; int n sizeof(arr) / sizeof(arr[0]); // 反轉數組arr的全部元素 reverse(arr, arr n); 2.反轉字符串&#xff1a; string str "he…

企業可用免費軟件 | 7-Zip,壓縮率比 WinZip 高10%!

7-Zip是一款出色的文件壓縮和存檔工具&#xff0c;但實際上許多小伙伴們并不了解。它是一款開源的免費軟件&#xff0c;目前支持87種語言&#xff0c;適用于所有系統&#xff0c;軟件操作界面也十分簡潔&#xff0c;大部分代碼都在GNU LGPL許可下。除了免費無廣告的優點之外&am…

Gradio全解20——Streaming:流式傳輸的多模態應用(1)——Mistral-7B實現流式傳輸音頻:魔力8號球

Gradio全解20——Streaming&#xff1a;流式傳輸的多模態應用&#xff08;1&#xff09;——Mistral-7B實現流式傳輸音頻&#xff1a;魔力8號球 前言本篇摘要20. Streaming&#xff1a;流式傳輸的多模態應用20.1 Mistral-7B實現流式傳輸音頻&#xff1a;魔力8號球20.1.1 工作原…

Qt實現網頁內嵌

文章目錄 一、環境準備 二、代碼實現 三、測試 一、環境準備 首先&#xff0c;確保你的Qt安裝包含了QtWebEngine模塊。我的Qt是5.12.9并且使用MSVC來編譯項目。在項目文件中需要添加以下配置&#xff0c;其中在Qt中配置MSVC&#xff0c;建議去看看這位大佬的博客&#xff1a…

conda管理python環境

其他文章 服務容錯治理框架resilience4j&sentinel基礎應用---微服務的限流/熔斷/降級解決方案-CSDN博客 conda管理python環境-CSDN博客 快速搭建對象存儲服務 - Minio&#xff0c;并解決臨時地址暴露ip、短鏈接請求改變瀏覽器地址等問題-CSDN博客 大模型LLMs的MCP入門-…

Android工廠模式

前言 工廠模式是創建型模式&#xff0c;使我們常用/常見的模式之一。多用于需要生成復雜對象的地方。用new就可以完成創建的對象就無需使用。工廠模式降低了對象之間的耦合度&#xff0c;由于工廠模式依賴抽象的架構&#xff0c;實例化的任務交由子類去完成&#xff0c;所以有…

【AI面試準備】數據驅動測試思維與實踐指南

面試題&#xff1a;數據驅動思維 構建測試數據集&#xff1a;收集代碼覆蓋率、缺陷歷史等數據。 模型訓練優化&#xff1a;使用Jupyter Notebook分析特征重要性。 數據驅動思維是一種以數據為核心、基于數據分析結果進行決策的方法論。它強調通過量化分析、模式識別和預測建模…

內存碎片深度剖析

目錄 什么是內存碎片 內部碎片的解決 malloc STL二級空間配置器 外部碎片的解決 伙伴系統算法 slab分配器 什么是內存碎片 內存碎片是指在內存中存在的一些不連續的、較小的空閑內存塊&#xff0c;這些小塊內存由于太小而無法被有效地分配給程序使用&#xff0c;從而導…

flutter 專題 六十一 支持上拉加載更多的自定義橫向滑動表格

在股票軟件中&#xff0c;經常會看到如下所示的效果&#xff08;ps&#xff1a;由于公司數據敏感&#xff0c;所以使用另一個朋友的一個圖&#xff09;。 分析需要后&#xff0c;我先在網上找了下支持橫向滑動的組件&#xff0c;最后找到了這個&#xff1a;flutter_horizontal…

0-1背包問題基礎概念

一、問題描述 給定一個容量為 W 的背包和 n 個物品。每個物品有一個重量 w[i] 和價值 v[i]。每個物品只能選或不選&#xff08;即“0-1”&#xff09;&#xff0c;求在不超過背包容量的前提下&#xff0c;所能獲得的最大總價值。 輸入&#xff1a; 背包容量 W&#xff08;in…

使用 Semantic Kernel 快速對接國產大模型實戰指南(DeepSeek/Qwen/GLM)

文章目錄 使用 Semantic Kernel 快速對接國產大模型實戰指南&#xff08;DeepSeek/Qwen/GLM&#xff09;一、引言二、環境準備2.1 開發環境2.2 模型服務配置 三、核心代碼實現3.1 會話代碼封裝3.2 CurModelContext封裝3.3 DeepSeek對接示例3.4 Qwen對接示例3.5 GLM對接示例 四、…

Ai時代,運維人如何轉型

在AI時代,傳統運維向智能運維(AIOps)的轉型需要系統性重塑,以下是深度拆解的轉型路線圖和關鍵實施要素: 一、認知升級范式轉變 1. 演進路線模型(三階段) 被動響應階段:人工巡檢(→監控覆蓋率<30%)主動防御階段:規則引擎(→告警準確率70%~85%)預測自治階段:深…

windows鼠標按鍵自定義任意設置

因為用慣了Linux的鼠標中鍵的復制黏貼&#xff0c;發現windows下有完全可以實現類似自定義功能的軟件&#xff0c;推薦一下&#xff1a; X Mouse Button Control。 免費版足夠好用。 軟件簡介&#xff1a; X Mouse Button Control是一款專業的重新映射鼠標按鈕的軟件工具&…

怎么看戶型好不好?

看房型好不好可從以下方面判斷&#xff1a; 空間布局 方正性&#xff1a;戶型方正為佳 &#xff0c;此時進深與開間比例在1:1.5左右。方正戶型空間利用率高&#xff0c;無采光死角。如手槍型、鋸齒型等異形戶型&#xff0c;易有拐角、長過道&#xff0c;空間浪費大。動靜分區…

基于WOA鯨魚優化TCN-BiGRU注意力機制網絡模型的時間序列預測算法matlab仿真

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 5.算法完整程序工程 1.算法運行效果圖預覽 (完整程序運行后無水印) 2.算法運行軟件版本 matlab2022a/matlab2024b 3.部分核心程序 &#xff08;完整版代碼包含詳細中文注釋和操作步驟視頻…

JAVA簡單走進AI世界~Spring AI

1、背景 現代 AI 正以前所未有的速度改變著世界。它是基于復雜算法和強大計算能力的技術體系,涵蓋了機器學習、深度學習、自然語言處理等多個領域。 在日常生活中,AI 廣泛應用于智能語音助手、圖像識別、推薦系統等。比如,智能音箱能理解并回應語音指令,為人們提供信息查…

stm32wb55rg (4) 啟用usart串口

code repo: 訪問gitee 上節課成功點亮了LED&#xff0c;這次來把usart 用起來&#xff0c;畢竟有交互才是系統。 技術準備 首先查看手冊&#xff0c;發現mcu有1個usart和1個 lpuart。 usart 的使用需要兩個pin&#xff0c;一個接收一個發送。繼續查看pin and ball definition…