BaseDao 通用查詢方法設計與實現

BaseDao 通用查詢方法設計與實現

一、通用查詢方法設計思路

1. 核心查詢功能矩陣

查詢類型方法名功能說明復雜度
主鍵查詢findById()根據主鍵獲取單個實體?
全量查詢findAll()獲取全部實體?
條件查詢findByCondition()動態條件查詢???
分頁查詢findPage()分頁結果集????
排序查詢findWithOrder()帶排序的結果集??
投影查詢findProjection()返回指定字段???
聚合查詢executeAggregate()執行聚合函數????

2. 類關系設計

?abstract?
BaseDao<T, ID>
# DataSource dataSource
# Class entityClass
# String tableName
# String primaryKey
+BaseDao(DataSource dataSource)
+T findById(ID id)
+List findAll()
+List findByCondition(String condition, Object... params)
+Page findPage(int pageNum, int pageSize)
+Page findPageByCondition(int pageNum, int pageSize, String condition, Object... params)
+List> findProjection(String[] columns, String condition, Object... params)
+R executeAggregate(String function, String column, String condition, Class resultType, Object... params)
#T mapRowToEntity(ResultSet rs)
#String buildSelectSql(String[] columns, String condition)
UserDao
+UserDao(DataSource dataSource)
+List findActiveUsers()
Page<T>
- int pageNum
- int pageSize
- int total
- List content
+getTotalPages()

二、完整實現代碼

1. Page 分頁對象

public class Page<T> {private int pageNum;     // 當前頁碼private int pageSize;    // 每頁大小private int total;       // 總記錄數private List<T> content; // 當前頁數據public Page(int pageNum, int pageSize, int total, List<T> content) {this.pageNum = pageNum;this.pageSize = pageSize;this.total = total;this.content = content;}// 計算總頁數public int getTotalPages() {return (int) Math.ceil((double) total / pageSize);}// 是否第一頁public boolean isFirst() {return pageNum == 1;}// 是否最后一頁public boolean isLast() {return pageNum >= getTotalPages();}// Getters and setters...
}

2. BaseDao 通用查詢實現

import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;
import java.util.stream.Collectors;public abstract class BaseDao<T, ID> {protected final DataSource dataSource;protected final Class<T> entityClass;protected final String tableName;protected final String primaryKey;// 通過構造函數獲取實體類型@SuppressWarnings("unchecked")public BaseDao(DataSource dataSource) {this.dataSource = dataSource;this.entityClass = (Class<T>) ((java.lang.reflect.ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];this.tableName = resolveTableName();this.primaryKey = resolvePrimaryKey();}// ========== 核心查詢方法 ========== ///*** 根據主鍵查詢單個實體*/public T findById(ID id) {String condition = primaryKey + " = ?";List<T> result = findByCondition(condition, id);return result.isEmpty() ? null : result.get(0);}/*** 查詢所有實體*/public List<T> findAll() {return findByCondition(null);}/*** 條件查詢* @param condition SQL條件部分 (不包含WHERE關鍵字)* @param params 條件參數*/public List<T> findByCondition(String condition, Object... params) {String sql = buildSelectSql(null, condition);try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {setParameters(pstmt, params);try (ResultSet rs = pstmt.executeQuery()) {List<T> result = new ArrayList<>();while (rs.next()) {result.add(mapRowToEntity(rs));}return result;}} catch (SQLException e) {throw new RuntimeException("Query by condition failed", e);}}/*** 分頁查詢所有記錄*/public Page<T> findPage(int pageNum, int pageSize) {return findPageByCondition(pageNum, pageSize, null);}/*** 帶條件的分頁查詢*/public Page<T> findPageByCondition(int pageNum, int pageSize, String condition, Object... params) {// 計算偏移量int offset = (pageNum - 1) * pageSize;// 構建分頁SQLString sql = buildSelectSql(null, condition) + " LIMIT " + pageSize + " OFFSET " + offset;// 查詢數據List<T> content;try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {setParameters(pstmt, params);try (ResultSet rs = pstmt.executeQuery()) {content = new ArrayList<>();while (rs.next()) {content.add(mapRowToEntity(rs));}}} catch (SQLException e) {throw new RuntimeException("Paged query failed", e);}// 查詢總數int total = countByCondition(condition, params);return new Page<>(pageNum, pageSize, total, content);}/*** 投影查詢 - 返回指定字段的Map集合* @param columns 要查詢的列名* @param condition 查詢條件* @param params 條件參數*/public List<Map<String, Object>> findProjection(String[] columns, String condition, Object... params) {String sql = buildSelectSql(columns, condition);try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {setParameters(pstmt, params);try (ResultSet rs = pstmt.executeQuery()) {List<Map<String, Object>> result = new ArrayList<>();ResultSetMetaData metaData = rs.getMetaData();int columnCount = metaData.getColumnCount();while (rs.next()) {Map<String, Object> row = new LinkedHashMap<>();for (int i = 1; i <= columnCount; i++) {String columnName = metaData.getColumnLabel(i);row.put(columnName, rs.getObject(i));}result.add(row);}return result;}} catch (SQLException e) {throw new RuntimeException("Projection query failed", e);}}/*** 執行聚合函數查詢* @param function 聚合函數 (COUNT, SUM, AVG, MAX, MIN)* @param column 聚合列* @param condition 查詢條件* @param resultType 返回結果類型* @param params 條件參數*/public <R> R executeAggregate(String function, String column, String condition, Class<R> resultType,Object... params) {String sql = "SELECT " + function + "(" + column + ") FROM " + tableName;if (condition != null && !condition.trim().isEmpty()) {sql += " WHERE " + condition;}try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {setParameters(pstmt, params);try (ResultSet rs = pstmt.executeQuery()) {if (rs.next()) {return resultType.cast(rs.getObject(1));}return null;}} catch (SQLException e) {throw new RuntimeException("Aggregate query failed", e);}}/*** 條件統計*/public int countByCondition(String condition, Object... params) {return executeAggregate("COUNT", primaryKey, condition, Integer.class, params);}// ========== 輔助方法 ========== ///*** 構建SELECT語句*/protected String buildSelectSql(String[] columns, String condition) {String selectedColumns = "*";if (columns != null && columns.length > 0) {selectedColumns = String.join(", ", columns);}StringBuilder sql = new StringBuilder("SELECT ").append(selectedColumns).append(" FROM ").append(tableName);if (condition != null && !condition.trim().isEmpty()) {sql.append(" WHERE ").append(condition);}return sql.toString();}/*** 設置PreparedStatement參數*/protected void setParameters(PreparedStatement pstmt, Object... params) throws SQLException {if (params != null) {for (int i = 0; i < params.length; i++) {pstmt.setObject(i + 1, params[i]);}}}/*** 結果集映射到實體對象*/protected T mapRowToEntity(ResultSet rs) throws SQLException {try {T entity = entityClass.getDeclaredConstructor().newInstance();ResultSetMetaData metaData = rs.getMetaData();int columnCount = metaData.getColumnCount();for (int i = 1; i <= columnCount; i++) {String columnName = metaData.getColumnLabel(i);Object value = rs.getObject(i);// 查找對應字段Field field = findFieldForColumn(columnName);if (field != null) {field.setAccessible(true);// 處理特殊類型轉換if (value instanceof java.sql.Timestamp && field.getType() == java.time.LocalDateTime.class) {value = ((java.sql.Timestamp) value).toLocalDateTime();} else if (value instanceof java.sql.Date && field.getType() == java.time.LocalDate.class) {value = ((java.sql.Date) value).toLocalDate();}field.set(entity, value);}}return entity;} catch (Exception e) {throw new SQLException("Failed to map row to entity", e);}}/*** 根據列名查找實體字段*/protected Field findFieldForColumn(String columnName) {// 嘗試直接匹配字段名try {return entityClass.getDeclaredField(columnName);} catch (NoSuchFieldException e1) {// 嘗試匹配駝峰轉下劃線String camelCaseName = snakeToCamel(columnName);try {return entityClass.getDeclaredField(camelCaseName);} catch (NoSuchFieldException e2) {// 遍歷所有字段查找for (Field field : entityClass.getDeclaredFields()) {if (field.getName().equalsIgnoreCase(columnName) || field.getName().equalsIgnoreCase(camelCaseName)) {return field;}}return null;}}}/*** 解析表名*/protected String resolveTableName() {// 如果有@Table注解,優先使用注解值if (entityClass.isAnnotationPresent(Table.class)) {return entityClass.getAnnotation(Table.class).name();}// 默認:類名駝峰轉下劃線return camelToSnake(entityClass.getSimpleName());}/*** 解析主鍵名*/protected String resolvePrimaryKey() {// 查找帶@Id注解的字段for (Field field : entityClass.getDeclaredFields()) {if (field.isAnnotationPresent(Id.class)) {return field.getName();}}// 默認使用"id"return "id";}/*** 駝峰轉下劃線*/protected String camelToSnake(String str) {return str.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();}/*** 下劃線轉駝峰*/protected String snakeToCamel(String str) {StringBuilder result = new StringBuilder();boolean nextUpper = false;for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (c == '_') {nextUpper = true;} else {if (nextUpper) {result.append(Character.toUpperCase(c));nextUpper = false;} else {result.append(Character.toLowerCase(c));}}}return result.toString();}
}

3. 注解定義

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {String name();
}@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTentionPolicy.RUNTIME)
public @interface Id {}

4. 實體類示例

@Table(name = "user_info")
public class User {@Idprivate Long id;private String userName;private String email;private LocalDateTime createTime;private Integer status;// 構造器、getter、setter...
}

三、使用示例

1. 基礎查詢

// 初始化數據源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("user");
dataSource.setPassword("password");// 創建UserDao
UserDao userDao = new UserDao(dataSource);// 根據ID查詢
User user = userDao.findById(1L);
System.out.println("User: " + user.getUserName());// 查詢所有用戶
List<User> allUsers = userDao.findAll();
System.out.println("Total users: " + allUsers.size());// 條件查詢
List<User> activeUsers = userDao.findByCondition("status = ? AND create_time > ?", 1, LocalDateTime.now().minusMonths(1)
);
System.out.println("Active users: " + activeUsers.size());

2. 分頁查詢

// 分頁查詢(第2頁,每頁10條)
Page<User> userPage = userDao.findPage(2, 10);
System.out.println("Page " + userPage.getPageNum() + " of " + userPage.getTotalPages());
System.out.println("Records: " + userPage.getContent().size());// 帶條件的分頁查詢
Page<User> activeUserPage = userDao.findPageByCondition(1, 20, "status = ?", 1
);
System.out.println("Active users: " + activeUserPage.getTotal());

3. 投影查詢

// 投影查詢(只獲取用戶名和郵箱)
List<Map<String, Object>> userProjections = userDao.findProjection(new String[]{"user_name", "email"}, "status = ?", 1
);userProjections.forEach(projection -> {System.out.println(projection.get("user_name") + ": " + projection.get("email"));
});

4. 聚合查詢

// 統計活躍用戶數量
Integer activeCount = userDao.executeAggregate("COUNT", "id", "status = ?", Integer.class, 1
);
System.out.println("Active users: " + activeCount);// 獲取最新注冊時間
LocalDateTime lastRegistration = userDao.executeAggregate("MAX", "create_time", null, LocalDateTime.class
);
System.out.println("Last registration: " + lastRegistration);

四、高級查詢功能擴展

1. 動態排序支持

/*** 帶排序的條件查詢*/
public List<T> findByConditionWithOrder(String condition, String orderBy, Object... params) {String sql = buildSelectSql(null, condition);if (orderBy != null && !orderBy.trim().isEmpty()) {sql += " ORDER BY " + orderBy;}return executeQuery(sql, params);
}private List<T> executeQuery(String sql, Object... params) {try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {setParameters(pstmt, params);try (ResultSet rs = pstmt.executeQuery()) {List<T> result = new ArrayList<>();while (rs.next()) {result.add(mapRowToEntity(rs));}return result;}} catch (SQLException e) {throw new RuntimeException("Query failed", e);}
}

2. 聯表查詢支持

/*** 自定義SQL查詢*/
public List<T> findBySql(String sql, Object... params) {return executeQuery(sql, params);
}/*** 聯表查詢映射*/
protected T mapRowToEntityWithJoins(ResultSet rs) throws SQLException {// 需要子類覆蓋此方法實現復雜映射return mapRowToEntity(rs);
}

3. 緩存集成

public class CachedBaseDao<T, ID> extends BaseDao<T, ID> {private final Cache<ID, T> cache;public CachedBaseDao(DataSource dataSource, Cache<ID, T> cache) {super(dataSource);this.cache = cache;}@Overridepublic T findById(ID id) {// 先從緩存獲取T cached = cache.get(id);if (cached != null) {return cached;}// 數據庫查詢T entity = super.findById(id);if (entity != null) {cache.put(id, entity);}return entity;}@Overridepublic void update(T entity) {super.update(entity);// 更新緩存ID id = (ID) ReflectionUtils.getFieldValue(entity, primaryKey);cache.put(id, entity);}
}

五、性能優化策略

1. 查詢性能優化矩陣

場景優化策略實現方式
頻繁查詢緩存結果集成Caffeine/Redis
大結果集流式處理使用ResultSet流式讀取
復雜查詢預編譯SQL緩存PreparedStatement
字段映射反射緩存緩存Field元數據
批量查詢IN查詢優化使用JOIN代替多個OR

2. 流式查詢實現

/*** 流式查詢(處理大結果集)*/
public void streamByCondition(String condition, Consumer<T> consumer, Object... params) {String sql = buildSelectSql(null, condition);try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {pstmt.setFetchSize(Integer.MIN_VALUE); // MySQL流式讀取setParameters(pstmt, params);try (ResultSet rs = pstmt.executeQuery()) {while (rs.next()) {consumer.accept(mapRowToEntity(rs));}}} catch (SQLException e) {throw new RuntimeException("Stream query failed", e);}
}

3. 預編譯語句緩存

// 在BaseDao中添加緩存
private final Map<String, PreparedStatement> statementCache = new ConcurrentHashMap<>();protected PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException {return statementCache.computeIfAbsent(sql, key -> {try {return conn.prepareStatement(key);} catch (SQLException e) {throw new RuntimeException("Failed to prepare statement", e);}});
}

六、安全注意事項

1. 查詢安全防護

風險防護措施實現方式
SQL注入參數化查詢使用PreparedStatement
敏感數據字段過濾投影查詢指定字段
批量查詢結果集限制添加MAX_ROWS限制
日志泄露脫敏處理不記錄完整結果集
權限控制行級權限基礎條件自動附加

2. 自動條件附加

/*** 自動附加安全條件*/
protected String applySecurityConditions(String originalCondition) {// 示例:只允許查詢當前用戶的數據String userId = SecurityContext.getCurrentUserId();if (userId == null) {throw new SecurityException("Unauthorized access");}String securityCondition = "user_id = '" + userId + "'";if (originalCondition == null || originalCondition.isEmpty()) {return securityCondition;}return "(" + originalCondition + ") AND " + securityCondition;
}

七、總結與最佳實踐

1. BaseDao查詢方法使用場景

查詢類型適用場景性能建議
findById單條記錄獲取添加緩存
findAll小型表全量查詢避免大表使用
findByCondition動態條件查詢確保條件字段索引
findPage列表展示優化分頁SQL
findProjection報表生成只查詢必要字段
executeAggregate統計分析數據庫聚合優于內存計算

2. 設計原則檢查表

- [ ] 接口與實現分離
- [ ] 支持動態條件查詢
- [ ] 分頁查詢獨立封裝
- [ ] 安全參數綁定
- [ ] 類型安全結果映射
- [ ] 支持投影查詢
- [ ] 提供聚合函數支持
- [ ] 異常統一處理
- [ ] 擴展點開放(如自定義映射)

3. 性能優化檢查表

- [ ] 大結果集使用流式處理
- [ ] 頻繁查詢添加緩存
- [ ] 預編譯語句重用
- [ ] 反射元數據緩存
- [ ] 避免N+1查詢問題
- [ ] 分頁查詢優化(Keyset分頁)
主鍵查詢
條件查詢
分頁查詢
聚合查詢
命中
未命中
查詢請求
查詢類型
findById
findByCondition
findPage
executeAggregate
緩存檢查
返回緩存
數據庫查詢
構建SQL
執行查詢
查詢數據
查詢總數
構建分頁對象
執行聚合函數
結果映射
返回結果

最佳實踐總結:BaseDao的通用查詢方法為數據訪問層提供了強大的基礎能力,但在實際項目中需根據具體需求進行擴展和優化。對于復雜查詢場景,建議結合使用MyBatis等專業ORM框架,同時注意查詢性能和安全防護。

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

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

相關文章

llama.cpp gguf主要量化方法

量化是一種通過降低模型參數的表示精度來減少模型的大小和計算存儲需求的方法&#xff0c;如把單精度fp32轉化為int8來減少存儲和計算成本。 常見的是線性量化&#xff0c;公式 r S(q-Z)&#xff0c;將實數值r映射為量化的整數值q&#xff0c;其中縮放因子S和零點Z根據參數分…

汽車級MCU選型新方向:eVTOL垂槳控制監控芯片的替代選型技術分析

摘要&#xff1a;隨著eVTOL&#xff08;電動垂直起降航空器&#xff09;領域的蓬勃發展&#xff0c;對于高性能、高可靠性的垂槳控制監控芯片的需求日益迫切。本文旨在深入探討汽車級MCU&#xff08;微控制單元&#xff09;在這一新興領域的應用潛力&#xff0c;以國科安芯推出…

Deepoc具身智能大模型:送餐機器人如何學會“讀心術”

Deepoc具身智能大模型&#xff1a;送餐機器人如何學會“讀心術”深夜十點的商場火鍋店&#xff0c;一臺銀色機器人正穿越喧鬧的人群。當它感知到奔跑的兒童突然變向&#xff0c;驅動輪立即反向微調0.3度&#xff1b;托盤上的牛油鍋底因顧客推椅產生晃動&#xff0c;平衡系統瞬間…

學習設計模式《十七》——狀態模式

一、基礎概念 狀態模式的本質是【根據狀態來分離和選擇行為】。 狀態模式的定義&#xff1a;允許一個對象在其內部狀態改變時改變它的行為&#xff1b;對象看起來似乎修改了它的類。 認識狀態模式序號認識狀態模式說明1狀態和行為通常指的是對象實例的屬性的值&#xff1b;而行…

python的婚紗影樓管理系統

前端開發框架:vue.js 數據庫 mysql 版本不限 后端語言框架支持&#xff1a; 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 數據庫工具&#xff1a;Navicat/SQLyog等都可以 隨著婚紗…

濾波電路Multisim電路仿真實驗匯總——硬件工程師筆記

目錄 1 濾波電路基礎知識 1.1 濾波電路的分類 1.1.1 按頻率選擇性分類 1.1.2 按實現方式分類 1.2 濾波電路的設計 1.2.1 確定濾波器類型 1.2.2 計算截止頻率 1.2.3 選擇濾波階數 1.2.4 考慮元件參數 1.2.5 仿真驗證 1.3 濾波電路的應用 1.3.1 電源濾波 1.3.2 音頻…

C++隨機打亂函數:簡化源碼與原理深度剖析

文章目錄一、Fisher-Yates洗牌算法核心原理二、std::random_shuffle簡化實現與缺陷分析簡化源碼&#xff08;核心邏輯&#xff09;原理層面的致命缺陷三、std::shuffle的現代改進與實現簡化源碼&#xff08;核心邏輯&#xff09;原理層面的關鍵改進四、隨機數生成器工作原理URB…

DBeaver連接MySQL8.0報錯Public Key Retrieval is not allowed

DBeaver 鏈接本地mysql8.0服務報錯Public Key Retrieval is not allowed為什么會出現這個錯誤&#xff1f;MySQL 8.0 默認使用新的認證插件&#xff1a;caching_sha2_password某些客戶端&#xff08;比如老版本的 JDBC 驅動或配置不當的 DBeaver&#xff09;在連接時&#xff0…

SpringBoot系列—統一功能處理(攔截器)

上篇文章&#xff1a; SpringBoot系列—MyBatis-plushttps://blog.csdn.net/sniper_fandc/article/details/148979284?fromshareblogdetail&sharetypeblogdetail&sharerId148979284&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目錄 1 攔…

《匯編語言:基于X86處理器》第7章 整數運算(3)

本章將介紹匯編語言最大的優勢之一:基本的二進制移位和循環移位技術。實際上&#xff0c;位操作是計算機圖形學、數據加密和硬件控制的固有部分。實現位操作的指令是功能強大的工具&#xff0c;但是高級語言只能實現其中的一部分&#xff0c;并且由于高級語言要求與平臺無關&am…

應用筆記|數字化儀在醫學SS-OCT中的應用

引言近些年來&#xff0c;OCT&#xff08;光學相干斷層掃描&#xff0c;Optical Coherence Tomography&#xff09;作為一種非破壞性3D光學成像技術逐漸在醫學眼科設備中流行起來。OCT可提供實時一維深度或二維截面或三維立體的圖像&#xff0c;分辨率可達微米&#xff08;μm&…

Ubuntu 22.04與24.04 LTS版本對比分析及2025年使用建議

Ubuntu 22.04與24.04 LTS版本對比分析及2025年使用建議 在2025年的技術環境下&#xff0c;Ubuntu 22.04和24.04 LTS各有優勢&#xff0c;選擇哪一個取決于具體應用場景和用戶需求。經過對系統內核、桌面環境、軟件生態、生命周期支持等多方面因素的綜合分析&#xff0c;本報告將…

Linux進程的生命周期:狀態定義、轉換與特殊場景

前言 在Linux系統中&#xff0c;進程是資源分配和調度的基本單位&#xff0c;而進程狀態則是理解進程行為的關鍵。從運行中的任務&#xff08;TASK_RUNNING&#xff09;到僵尸進程&#xff08;EXIT_ZOMBIE&#xff09;&#xff0c;每個狀態都反映了進程在內核調度、資源等待或父…

神經網絡簡介

大腦的基本計算單位是神經元&#xff08;neuron&#xff09;。人類的神經系統中大約有860億個神經元&#xff0c;它們被大約10^14-10^15個突觸&#xff08;synapses&#xff09;連接起來。下面圖表的左邊展示了一個生物學的神經元&#xff0c;右邊展示了一個常用的數學模型。每…

多路由協議融合與網絡服務配置實驗(電視機實驗)

多路由協議融合與網絡服務配置實驗文檔 一、實驗用途和意義 &#xff08;一&#xff09;用途 本實驗模擬企業復雜網絡環境&#xff0c;整合 OSPF、RIPv2 動態路由協議&#xff0c;結合 DHCP、FTP、Telnet 服務配置及訪問控制策略&#xff0c;實現多區域網絡互聯、服務部署與…

在指定conda 環境里安裝 jupyter 和 python kernel的方法

在 Conda 的指定環境中安裝 Jupyter 和 Python Kernel 是一個常見操作,以下是詳細步驟,確保在指定環境中正確配置 Jupyter 和 Python Kernel: 1. 準備工作 確保已安裝 Anaconda 或 Miniconda,Conda 環境管理工具可用。確認已創建或計劃使用的 Conda 環境。2. 步驟:安裝 J…

【數據結構與算法】數據結構初階:詳解順序表和鏈表(四)——單鏈表(下)

&#x1f525;個人主頁&#xff1a;艾莉絲努力練劍 ?專欄傳送門&#xff1a;《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題 &#x1f349;學習方向&#xff1a;C/C方向 ??人生格言&#xff1a;為天地立心&#xff0c;為生民立命&#xff0c;為…

Java+AI精準廣告革命:實時推送系統實戰指南

? 廣告推送的世紀難題 用戶反感&#xff1a;72%用戶因無關廣告卸載APP 轉化率低&#xff1a;傳統推送轉化率<0.5% 資源浪費&#xff1a;40%廣告預算被無效曝光消耗 &#x1f9e0; 智能廣告系統架構 &#x1f525; 核心模塊實現&#xff08;Java 17&#xff09; 1. 實時…

JVM組成及運行流程 - 面試筆記

JVM整體架構 JVM&#xff08;Java Virtual Machine&#xff09;是Java程序運行的核心環境&#xff0c;主要由以下幾個部分組成&#xff1a;1. 程序計數器&#xff08;Program Counter&#xff09; 特點&#xff1a;線程私有&#xff0c;每個線程都有獨立的程序計數器作用&#…

JavaEE——線程池

目錄前言1. 概念2. 線程池相關參數3. Executors的使用總結前言 線程是為了解決進程太重的問題&#xff0c;操作系統中進程的創建和銷毀需要較多的系統資源&#xff0c;用了輕量級的線程來代替部分線程&#xff0c;但是如果線程創建和銷毀的頻率也開始提升到了一定程度&#xf…