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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…