假日尾声:技术进阶与自我反思

前言


于是,假日迎来了它的尾声,把快乐和焦躁都留存在昨天。
我只觉情感的自相矛盾在加重,学习让我焦躁,纵欲无法填补空虚,于是我的心被拖入了无止尽的拉扯中。
我还没有找到必须留存的理由,但反之而言,我也远没有到可以决定自己生命自由的时刻。
还是闭上双眼,向前走吧,明日难测,却因昨日懊悔。
今天来统计一下剩余的进阶要求和已经完成的进阶要求,再针对性地完成。


日程


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…