当前位置: 首页 > news >正文

整活 kotlin + springboot3 + sqlite 配置一个 SQLiteCache

要实现一个 SQLiteCache 也是很简单的只需要创建一个 cacheManager Bean 即可

// 如果配置文件中 spring.cache.sqlite.enable = false 则不启用
@Bean("cacheManager")
@ConditionalOnProperty(name = ["spring.cache.sqlite.enable"], havingValue = "true", matchIfMissing = false)
fun cacheManager(sqliteMemoryConnection: Connection): CacheManager {// TODO 返回 CacheManager 
}

同样的还需要 SQLite 这里 SQLite 的 url 设置为 jdbc:sqlite::memory:

@Bean
fun sqliteMemoryConnection(): Connection {val dataSource = SQLiteDataSource()dataSource.url = urllogger.info("SQLite cache 创建连接: $url")return dataSource.connection
}

配置代码

该代码仅仅作为整活使用

package io.github.zimoyin.ra3.configimport io.github.zimoyin.ra3.config.SQLiteCacheConfig.EvictionPolicy.*
import kotlinx.coroutines.*
import org.bouncycastle.asn1.x500.style.RFC4519Style.name
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.cache.Cache
import org.springframework.cache.CacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.validation.annotation.Validated
import org.sqlite.SQLiteDataSource
import java.sql.Connection
import java.util.*
import java.util.concurrent.*
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.locks.ReentrantReadWriteLock
import javax.sql.DataSource
import kotlin.math.log
import kotlin.time.Duration.Companion.minutes@Configuration
@Validated
@ConfigurationProperties(prefix = "spring.cache.sqlite")
class SQLiteCacheConfig(var url: String = "jdbc:sqlite::memory:",var enable: Boolean = false,var tableCacheSize: Int = 100,var expirationMilliseconds: Long = 60000L,var evictionPolicy: EvictionPolicy = FIFO,
) {private val logger = LoggerFactory.getLogger(SQLiteCacheConfig::class.java)@Beanfun sqliteDataSource(): DataSource {val dataSource = SQLiteDataSource()dataSource.url = urllogger.info("初始化 SQLiteCache 数据库地址: $url")return dataSource}@Bean("sqliteCacheManager")@ConditionalOnProperty(name = ["spring.cache.sqlite.enable"], havingValue = "true")fun cacheManager(sqliteDataSource: DataSource): CacheManager = SQLiteCacheManager(dataSource = sqliteDataSource,maxSize = tableCacheSize,expirationMs = expirationMilliseconds,evictionPolicy = evictionPolicy)enum class EvictionPolicy {/*** First In First Out (FIFO)*/FIFO,/*** Least Recently Used (LRU)*/LRU,/*** Least Frequently Used (LFU)*/LFU}class SQLiteCacheManager(private val dataSource: DataSource,private val maxSize: Int,private val expirationMs: Long,private val evictionPolicy: EvictionPolicy,) : CacheManager {private val cacheMap = ConcurrentHashMap<String, SQLiteCache>()private val logger = LoggerFactory.getLogger(SQLiteCacheManager::class.java)private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)init {// 启动定时清理任务(首次延迟1分钟,之后每分钟执行)CoroutineScope(SupervisorJob() + Dispatchers.IO).launch {while (isActive) {delay(1.minutes)cleanupExpiredEntries()}}logger.info("初始化 SQLiteCacheManager: dataSource=$dataSource, maxSize=$maxSize, expirationMs=$expirationMs, evictionPolicy=$evictionPolicy")}override fun getCache(name: String): Cache {return cacheMap.computeIfAbsent(name) {SQLiteCache(name = it,dataSource = dataSource,maxSize = maxSize,expirationMs = expirationMs,evictionPolicy = evictionPolicy).also { cache ->logger.info("创建缓存表 $name")cache.initialize()}}}override fun getCacheNames(): MutableCollection<String> = cacheMap.keysprivate fun cleanupExpiredEntries() {cacheMap.values.forEach { cache ->try {logger.debug("缓存表 ${cache.name} 命中率: ${cache.getHitRate()}")cache.evictExpiredItems()} catch (e: Exception) {logger.error("Error cleaning expired entries in cache ${cache.name}", e)}}}@Synchronizedfun shutdown() {scope.cancel()cacheMap.values.forEach { it.close() }}}class SQLiteCache(private val name: String,val dataSource: DataSource,val maxSize: Int,val expirationMs: Long,val evictionPolicy: EvictionPolicy,) : Cache {private val logger = LoggerFactory.getLogger(SQLiteCache::class.java)private val connection: Connection = dataSource.connection.apply {autoCommit = false}private val lock = ReentrantReadWriteLock()private val hitCount = AtomicLong()private val missCount = AtomicLong()fun initialize() {createTableIfNotExists()createIndexes()}fun close() {connection.close()}override fun getName(): String = nameoverride fun getNativeCache(): Any = connectionoverride fun get(key: Any): Cache.ValueWrapper? {return try {lock.readLock().lock()getInternal(key.toString()).also {if (it != null) hitCount.incrementAndGet() else missCount.incrementAndGet()}} finally {lock.readLock().unlock()}}override fun <T : Any?> get(key: Any, type: Class<T>?): T? {return get(key)?.get() as? T}override fun <T : Any?> get(key: Any, valueLoader: Callable<T>): T {return try {lock.writeLock().lock()get(key)?.get() as? T ?: run {val value = valueLoader.call()put(key, value)value}} finally {lock.writeLock().unlock()}}override fun put(key: Any, value: Any?) {try {lock.writeLock().lock()executeInTransaction {evictIfNecessary()upsertEntry(key.toString(), value)}} finally {lock.writeLock().unlock()}}override fun evict(key: Any) {executeInTransaction {deleteEntry(key.toString())}}override fun clear() {executeInTransaction {connection.createStatement().executeUpdate("DELETE FROM $name")}}fun getHitRate(): Double {val total = hitCount.get() + missCount.get()return if (total == 0L) 0.0 else hitCount.get().toDouble() / total}internal fun evictExpiredItems() {executeInTransaction {val currentTime = System.currentTimeMillis()connection.prepareStatement("DELETE FROM $name WHERE expires_at < ?").use { ps ->ps.setLong(1, currentTime)ps.executeUpdate()}}}private fun getInternal(key: String): Cache.ValueWrapper? {return connection.prepareStatement("SELECT value, expires_at FROM $name WHERE key = ?").use { ps ->ps.setString(1, key)ps.executeQuery().use { rs ->if (rs.next()) {val expiresAt = rs.getLong("expires_at")if (System.currentTimeMillis() > expiresAt) {deleteEntry(key)null} else {updateAccessMetrics(key)Cache.ValueWrapper { rs.getObject("value") }}} else {null}}}}/*** 更新访问指标*/private fun updateAccessMetrics(key: String) {when (evictionPolicy) {LRU -> updateLastAccessed(key)LFU -> incrementAccessCount(key)FIFO -> run { /*不需要更新*/ }}}private fun upsertEntry(key: String, value: Any?) {val now = System.currentTimeMillis()connection.prepareStatement("""INSERT INTO $name (key, value, expires_at, created_at, last_accessed, access_count)VALUES (?, ?, ?, ?, ?, 1)ON CONFLICT(key) DO UPDATE SETvalue = excluded.value,expires_at = excluded.expires_at,last_accessed = excluded.last_accessed,access_count = access_count + 1""").use { ps ->ps.setString(1, key)ps.setObject(2, value)ps.setLong(3, now + expirationMs)ps.setLong(4, now)ps.setLong(5, now)ps.executeUpdate()}}private fun deleteEntry(key: String) {connection.prepareStatement("DELETE FROM $name WHERE key = ?").use { ps ->ps.setString(1, key)ps.executeUpdate()}}private fun evictIfNecessary() {if (currentSize() >= maxSize) {when (evictionPolicy) {FIFO -> evictByCreatedTime()LRU -> evictByLastAccessed()LFU -> evictByAccessCount()}}}private fun currentSize(): Int {return connection.createStatement().use { stmt ->stmt.executeQuery("SELECT COUNT(*) FROM $name ").use { rs ->if (rs.next()) rs.getInt(1) else 0}}}private fun evictByCreatedTime() {evictOldest("created_at")}private fun evictByLastAccessed() {evictOldest("last_accessed")}private fun evictByAccessCount() {connection.createStatement().use { stmt ->stmt.executeQuery("SELECT key FROM $name ORDER BY access_count ASC, created_at ASC LIMIT 1").use { rs ->if (rs.next()) deleteEntry(rs.getString(1))}}}private fun evictOldest(column: String) {connection.createStatement().use { stmt ->stmt.executeQuery("SELECT key FROM $name ORDER BY $column ASC LIMIT 1").use { rs ->if (rs.next()) deleteEntry(rs.getString(1))}}}private fun updateLastAccessed(key: String) {connection.prepareStatement("UPDATE $name SET last_accessed = ? WHERE key = ?").use { ps ->ps.setLong(1, System.currentTimeMillis())ps.setString(2, key)ps.executeUpdate()}}private fun incrementAccessCount(key: String) {connection.createStatement().executeUpdate("UPDATE $name SET access_count = access_count + 1 WHERE key = '$key'")}private fun createTableIfNotExists() {connection.createStatement().execute("""CREATE TABLE IF NOT EXISTS $name (key TEXT PRIMARY KEY,value BLOB,expires_at INTEGER,created_at INTEGER,last_accessed INTEGER,access_count INTEGER DEFAULT 0)""")}/*** 创建索引*/private fun createIndexes() {arrayOf("CREATE INDEX IF NOT EXISTS idx_${name}_expires ON $name (expires_at)","CREATE INDEX IF NOT EXISTS idx_${name}_created ON $name (created_at)","CREATE INDEX IF NOT EXISTS idx_${name}_last_access ON $name (last_accessed)","CREATE INDEX IF NOT EXISTS idx_${name}_access_count ON $name (access_count)").forEach { indexSql ->connection.createStatement().execute(indexSql)}}/*** 执行在事务中运行的代码块,并返回结果。如果代码块执行成功,则提交事务;如果代码块执行失败,则回滚事务。*/private inline fun <T> executeInTransaction(block: () -> T): T {return try {val result = block()connection.commit()result} catch (ex: Exception) {connection.rollback()throw ex}}}
}

配置文件

spring:cache:sqlite:enable: falseexpiration-milliseconds: 60000table-cache-size: 10000eviction-policy: lru

相关文章:

整活 kotlin + springboot3 + sqlite 配置一个 SQLiteCache

要实现一个 SQLiteCache 也是很简单的只需要创建一个 cacheManager Bean 即可 // 如果配置文件中 spring.cache.sqlite.enable false 则不启用 Bean("cacheManager") ConditionalOnProperty(name ["spring.cache.sqlite.enable"], havingValue "t…...

JVM:运行时数据区和线程

一、运行时数据区概述 &#xff08;1&#xff09;整体架构 JVM 启动时&#xff0c;操作系统会为它分配相应的内存空间&#xff0c;接着 JVM 会对分配到的空间进行划分。当 JVM 退出&#xff0c;这些空间会被回收。JVM 将分配到的内存空间主要分成五部分&#xff1a;程序计数器…...

Lucene.NET + Jieba分词:核心词典与停用词配置详解

文章目录 前言一、dict.txt&#xff1a;核心分词词典1. 文件作用2. 文件格式3. 配置方法 二、cn_synonym.txt&#xff1a;同义词扩展库1. 文件作用2. 文件格式3. 在 Lucene 中使用 三、stopwords.txt&#xff1a;停用词表1. 文件作用2. 文件格式3. 配置方法 四、实战&#xff1…...

软件测试之测试数据生成(Excel版)

这是Excel生成测试数据的函数使用 1.时间 1.1.时间 例生成2022-05-01之前一年内任意时间点: =TEXT("2022-05-01"-RAND()-RANDBETWEEN(1,365),"yyyy-mm-dd hh:mm:ss")1.2.年月日 yyyy-mm-dd 以当前时间生成10年的日期 =TEXT(NOW()-RAND()-RANDBETWE…...

局域网内Docker镜像共享方法

在局域网内将Docker镜像构建并传输到另一台电脑&#xff0c;可以通过以下几种方法实现。以下是具体步骤及注意事项&#xff0c;结合不同场景的适用方案&#xff1a; 方法一&#xff1a;使用 docker save 和 docker load 传输镜像文件 步骤说明 在构建机上保存镜像 通过 docker…...

解决WinEdt编辑器出现文字不会适应软件宽度的问题

解决WinEdt编辑器出现文字不会适应软件宽度的问题 问题描述解决 问题描述 在使用WinEdt编辑Latex文本时&#xff0c;发现突然动了下键盘&#xff0c;或者突然就在编辑文本时不能自动换行&#xff0c;而是超出了软件屏幕的宽度。 解决 按住ctrl w &#xff0c;直到界面变成下…...

跨境电商管理转型:日事清通过目标管理、流程自动化助力智优美科技项目管理升级与目标落地复盘

1.客户背景介绍 深圳市智优美科技有限公司是一家专业从事外贸B2C的电子商务公司&#xff0c;公司总部位于深圳市宝安区&#xff0c;旗下拥有三家子公司。目前销售的品类有&#xff1a;家居用品、电子产品、电子配件产品等&#xff0c;在深圳外贸电商行业销售额稳居行业前10名。…...

高防CDN、高防IP vs 高防服务器:核心优势与选型指南

一、高防服务器的核心局限 高防服务器是指通过机房部署硬件防火墙&#xff08;如集群防火墙、流量清洗设备&#xff09;来防御DDoS攻击的物理或虚拟服务器。其核心问题在于&#xff1a; 单点防御风险&#xff1a;依赖单一服务器硬扛攻击&#xff0c;若攻击流量超过防御阈值&am…...

入门-C编程基础部分:5、变量

飞书文档https://x509p6c8to.feishu.cn/wiki/PVnawQn5DiVhHhkMApqcDyDvnWg 变量的作用&#xff1f; 存储程序运行时&#xff0c;需要存储一些可能会变化的数据。 C 中每个变量都有特定的类型&#xff0c;类型决定了变量存储的大小和布局。 变量的名称可以由字母、数字和下划…...

Kafka深度解析与实战应用

Kafka深度解析与实战应用 作者&#xff1a;LedgerX技术团队 发布日期&#xff1a;2025年4月16日 引言 在当今数字时代&#xff0c;数据已成为企业的核心资产&#xff0c;而高效处理大规模数据流的能力则成为现代后端系统的关键挑战之一。Apache Kafka作为一个分布式流处理平台…...

数学教学通讯杂志数学教学通讯杂志社数学教学通讯编辑部2025年第6期目录

课程教材教法 “课程思政”视域下的高中数学教学探索与实践——以“函数概念的发展历程”为例 赵文博; 3-617 PBL教学模式下高中统计教学的探索与实践——以“随机抽样&#xff08;第一课时&#xff09;”为例 陈沛余; 7-10 “三新”背景下的高中数学教学困境与应对…...

【JavaEE初阶】多线程重点知识以及常考的面试题-多线程进阶(二)

本篇博客给大家带来的是多线程中synchronize的实现原理和JUC(java.util.concurrent) 常见类的相关知识点. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的…...

Flutter PIP 插件 ---- iOS Video Call 自定义PIP WINDOW渲染内容

以下是一篇关于在 iOS 中实现画中画(PiP)功能的技术博客: iOS 画中画(PiP)功能实现指南 效果 简介 画中画(Picture in Picture, PiP)是一项允许用户在使用其他应用时继续观看视频内容的功能。本文将详细介绍如何在 iOS 应用中实现 PiP 功能&#xff0c;包括自定义内容渲染和…...

【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——4G模块ME3630测试

1&#xff09;实验平台&#xff1a;正点原子ATK-DLMP257B开发板 2&#xff09;浏览产品&#xff1a;https://www.alientek.com/Product_Details/135.html 3&#xff09;全套实验源码手册视频下载&#xff1a;正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试——4G模…...

高并发内存池(四):内存释放原理与实现

前言&#xff1a;经过前3期的攻坚&#xff0c;我们已完整实现了内存动态申请的核心模块。接下来将进入关键阶段——内存释放机制的理解与实现&#xff0c;这是构建完整 高并发内存池 的最后一块技术拼图。该模块完成后&#xff0c;项目主体架构将基本成型&#xff08;达90%&…...

【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——EEPROM、SPI FLASH测试 #AT24C64 #W25Q128

1&#xff09;实验平台&#xff1a;正点原子ATK-DLMP257B开发板 2&#xff09;浏览产品&#xff1a;https://www.alientek.com/Product_Details/135.html 3&#xff09;全套实验源码手册视频下载&#xff1a;正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试——EEP…...

《突破控件限制:用Qt绘图API解锁高级界面定制能力》

一、基本概念 虽然 Qt 已经内置了很多的控件&#xff0c;但是不能保证现有控件就可以应对所有场景。很多时候我们需要更强的 “自定制” 能力。 Qt 提供了画图相关的 API&#xff0c;允许我们在窗口上绘制任意的图形形状来完成更复杂的界面设计 所谓的 “控件” 本质上也是通…...

MyBatis-Plus 中BaseMapper接口是如何加速微服务内部开发的?

假设我们有一个简单的微服务项目&#xff0c;需要对 User 实体进行基本的数据库操作。 场景一&#xff1a;使用原生 MyBatis 的开发流程 (作为对比) 定义实体类 (Entity): // package com.yourcompany.usermicroservice.entity; public class User {private Long id;private S…...

AIGC-十款数据分析类智能体完整指令直接用(DeepSeek,豆包,千问,Kimi,GPT)

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列AIGC(GPT、DeepSeek、豆包、千问、Kimi)👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资…...

鸿蒙应用(医院陪诊系统)开发篇1·主页面的tabs布局

引言&#xff1a; 首先可在鸿蒙开发者官网找到DevEco Studio的安装教程。 安装好了之后&#xff0c;我们开始开发。 知识点&#xff1a; tabs布局&#xff0c;鸿蒙官方文档地址&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-contai…...

【大模型】DeepSeek + Coze 打造个人专属AI智能体使用详解

目录 一、前言 二、AI智能体介绍 2.1 什么是AI智能体 2.2 AI智能体核心能力 2.3 AI智能应用场景 三、coze 介绍 3.1 coze是什么 3.1.1 平台概述 3.1.2 平台适用人群 3.2 平台核心功能 3.3 coze可以做什么 3.4 为什么选择coze 四、coze 搭建AI智能体操作实践 4.1 搭…...

7.(vue3.x+vite)弹性布局(flex布局)

1:效果截图 2:代码实现 <template><span style="font-size: 20px">右边固定,左边自适应</span><div class=<...

Python基础总结(五)之字典

文章目录 一、字典的格式二、字典的操作2.1 增加项2.1.1 直接增加项2.1.1 formkeys方法 2.2 删除项2.2.1 clear()方法2.2.2 pop()方法 2.3 修改项2.3.1 直接修改2.3.2 update()方法 2.4 查找项2.4.1 get()方法2.4.2 直接查询2.4.3 items()方法2.4.4 keys()方法2.4.5 values()方…...

MCP简介:重构人机交互底层逻辑

在人工智能技术飞速发展的今天&#xff0c;大语言模型&#xff08;LLM&#xff09;的应用场景正不断拓展&#xff0c;但模型与外部系统之间的连接方式却成为制约其潜力发挥的关键瓶颈。为了解决这一难题&#xff0c;由AI领域顶尖公司Anthropic&#xff08;Claude模型背后的开发…...

LangChain缓存嵌入技术完全指南:CacheBackedEmbedding原理与实践(附代码示例)

一、嵌入缓存技术背景与应用场景 1.1 为什么需要嵌入缓存&#xff1f; 算力消耗问题&#xff1a;现代嵌入模型&#xff08;如text-embedding-3-small&#xff09;单次推理需要约0.5-1秒/文本 资源浪费现状&#xff1a;实际业务中约30%-60%的文本存在重复计算 成本压力&#…...

国产DPU芯片+防火墙,能否引领网络安全新跨越?

近日&#xff0c;国内首款搭载国产DPU芯片的800Gbps下一代防火墙——中科网威NSFW - 12000正式发布&#xff0c;引发行业广泛关注。 国产DPU芯片与防火墙的结合&#xff0c;正在推动网络安全领域实现技术突破与体系升级。以下从技术特性、应用场景和产业价值三个维度分析其引领…...

Spark-SQL与Hive的连接及数据处理全解析

Spark-SQL与Hive的连接及数据处理全解析 在大数据处理领域&#xff0c;Spark-SQL和Hive都是重要的工具。今天就来聊聊Spark-SQL如何连接Hive以及相关的数据处理操作。 Spark-SQL连接Hive有多种方式。内嵌Hive虽然使用简单&#xff0c;直接就能用&#xff0c;但在实际生产中…...

ArcGIS Desktop使用入门(四)——9版本与10版本区别

系列文章目录 ArcGIS Desktop使用入门&#xff08;一&#xff09;软件初认识 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——标准工具 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——编辑器 ArcGIS Desktop使用入门&#xff08;二&#x…...

使用 chromedriver 实现网络爬虫【手抄】

1、引用 selenium 包 <dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.29.0</version> </dependency> <dependency><groupId>org.seleniumhq.seleniu…...

ERROR: Unknown host CPU architecture: arm64

1、先检查NDK版本是否支持arm64&#xff0c;NDK版本21.3以上 2、检查gradle中&#xff0c;有关NDK版本是否设置arm64-v8a 例如&#xff1a; ndkVersion "21.4.7075529"ndk {abiFilters "armeabi-v7a","arm64-v8a"} local.properties中&#x…...

从 SQL2API 到 Text2API:开启数据应用开发的新征程

在技术革新浪潮的席卷下&#xff0c;数据应用开发领域正经历着深刻变革。曾经&#xff0c;构建数据 API 需要开发者具备扎实的数据库知识和编程技能&#xff0c;手动编写复杂的 SQL 查询与 API 代码&#xff0c;这一过程不仅耗时费力&#xff0c;还将众多非技术人员阻挡在数据应…...

OpenCv高阶(四)——角点检测

一、角点检测 在计算机视觉中&#xff0c;角点检测是识别图像中局部区域&#xff08;角点&#xff09;的关键技术&#xff0c;这些区域通常是两条或多条边缘的交点&#xff0c;具有丰富的结构信息&#xff0c;常用于图像匹配、跟踪、三维重建等任务。 Harris角点检测算法是一…...

centos8 部署 openstack

在 CentOS 8 上部署 OpenStack 是一个复杂的过程&#xff0c;涉及多个组件的安装和配置。OpenStack 是一个开源的云计算平台&#xff0c;它提供了基础设施即服务&#xff08;IaaS&#xff09;的功能。下面我将指导你通过基本的步骤来部署 OpenStack。 前提条件 系统要求&#…...

智能云图库-8-AI编辑

一、基础图片编辑​ 需求分析​ 在日常的图片管理中&#xff0c;用户经常需要对图片进行简单处理&#xff0c;比如裁剪多余部分、旋转图片、放大缩小尺寸等。 因此&#xff0c;我们首先要引入基础图片编辑功能&#xff0c;帮助用户快速完成以下操作&#xff1a; 裁剪&#…...

libwebsocket建立服务器需要编写LWS_CALLBACK_ADD_HEADERS事件处理

最近在使用libwebsocket&#xff0c;感觉它搭建Http与websocket服务器比较简单&#xff0c;不像poco库那么庞大&#xff0c;但当我使用它建立websocket服务器后&#xff0c;发现websocket客户端连接一直没有连接成功&#xff0c;不知道什么原因&#xff0c;经过一天的调试&…...

L1-002 打印沙漏

L1-002 打印沙漏 - 团体程序设计天梯赛-练习集 (pintia.cn) 本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”&#xff0c;要求按下列格式打印 ************ *****所谓“沙漏形状”&#xff0c;是指每行输出奇数个符号&#xff1b;各行符号中心对齐&#…...

JSP技术入门指南【一】利用IDEA从零开始搭建你的第一个JSP系统

Jsp技术入门指南【一】利用IDEA从零开始搭建你的第一个JSP系统 前言一、什么是JSP1.1 JSP是干什么的&#xff1f;1.2 JSP与Servlet的关系是什么&#xff1f; 二、在Idea中创建第一个JSP系统三、JSP和HTML的差别3.1 格式区别3.2 注释区别 前言 在前面的内容中&#xff0c;我们已…...

NLP高频面试题(四十四)——RLHF过程中的马尔科夫决策过程及对话场景MDP设计

什么是马尔科夫决策过程(MDP)? 马尔科夫决策过程(MDP)是描述序贯决策问题的数学框架,由五元组( (S, A, P, R, \gamma) )组成,其中: (S):状态集合,描述环境的所有可能状态。(A):动作集合,描述智能体可以采取的所有可能动作。(P):状态转移概率函数,表示从一个状态…...

青少年编程与数学 02-016 Python数据结构与算法 24课题、密码学算法

青少年编程与数学 02-016 Python数据结构与算法 24课题、密码学算法 课题摘要:一、对称加密算法AES&#xff08;高级加密标准&#xff09;DES&#xff08;数据加密标准&#xff09;3DES&#xff08;三重数据加密标准&#xff09; 二、非对称加密算法RSAECC&#xff08;椭圆曲线…...

艺术字体AI生成阿里云WordArt锦书、通义万相、SiliconFlow、Pillow+OpenCV本地生成艺术字体

基于您的需求&#xff0c;结合最新API技术和搜索结果&#xff0c;以下是Python调用主流艺术字API的代码案例及对应充值链接方案&#xff1a; 一、大厂API服务&#xff08;付费方案&#xff09; 1. 阿里云WordArt锦书API # 文字纹理生成&#xff08;需安装dashscope&#xff…...

GIS开发笔记(7)结合osg及osgEarth实现不同高度下的三个圆形区域形成的三维覆盖轮廓区域绘制

一、实现效果如下&#xff1a; 二、实现原理 输入四个坐标点&#xff0c;第一个点为中心点&#xff0c;第二三四个点分别以中心点与地面垂线所在线上的各自高度水平面的交点为圆心旋转360进行圆形区域绘制&#xff0c;然后将三个不同高度上的圆形区域进行结合形成三维覆盖区域…...

解决 Kubernetes 调度器启动报错:缺少 Bind 插件

解决 Kubernetes 调度器启动报错&#xff1a;缺少 Bind 插件 问题描述 在启动自定义 Kubernetes 调度器时&#xff0c;出现了以下错误&#xff1a; I0416 17:08:41.420188 68788 configfile.go:57] "KubeSchedulerConfiguration v1beta2 is deprecated in v1.25, wil…...

Spring Batch 专题系列(六):并行处理与性能优化

1. 引言 在上一篇文章中,我们学习了 Spring Batch 的错误处理机制(Skip、Retry、Restart 和 Listener),掌握了如何提升作业的健壮性。随着数据量的增加,批处理任务的性能成为关键挑战。Spring Batch 提供了强大的并行处理功能,包括多线程 Step、分区(Partitioning)和并…...

WPF 从Main()方法启动

1.去掉App.xaml StartupUri“MainWindow.xaml” 只会让App.g.cs 不生成这行代码&#xff0c;但是还是会生成的App.g.cs文件中生成Main方法 this.StartupUri new System.Uri("MainWindow.xaml", System.UriKind.Relative);默认的App.xaml的生成操作是 应用程序定义…...

记录小程序第一次调用Api,基于腾讯云Serverless函数,实现小程序的成功接入api,以及数据调用

目录 创建腾讯云个人账户新建severless应用建立函数URL小程序中调用api示例 创建腾讯云个人账户 百度搜索即可&#xff0c;并注册 新建severless应用 作者以github下载的某Api为例&#xff0c;这里不展示具体Api&#xff0c;只关注操作即可&#xff0c;相信都是互通的 在腾…...

「数据可视化 D3系列」入门第四章:DOM操作与元素管理

DOM操作与元素管理 核心技能&#xff1a;元素选择与操作一、元素选择&#xff1a;精准定位DOM节点基础选择方法对比进阶选择技巧 二、元素插入&#xff1a;动态构建DOM结构append() vs insert()实际应用示例 三、元素删除&#xff1a;优雅移除DOM节点删除操作最佳实践 四、内容…...

突发重磅消息!!!CVE项目将被取消?

突发重磅消息&#xff01;&#xff01;&#xff01;CVE项目将被取消&#xff1f;突发&#xff01;来自可靠消息来源。MITRE 对 CVE 项目的支持将于明天到期。附件信件已发送给 CVE 董事会成员。https://mp.weixin.qq.com/s/N3qkiHaDfzDuBMK3JbBCjw...

基于uniapp的鸿蒙APP大数据量性能优化

文章目录 一、问题诊断与性能瓶颈分析1.1 大数据场景下的典型性能问题1.2 性能监测工具使用1.2.1 HBuilderX内置分析器1.2.2 鸿蒙DevEco工具链1.2.3 自制性能埋点 二、数据加载优化方案2.1 分页加载实现&#xff08;带错误重试机制&#xff09;2.2 数据流优化策略2.2.1 数据压缩…...

【算法】归并排序

算法系列七&#xff1a;归并排序 一、归并排序的递归探寻 1.思路 2.搭建 2.1设计过掉不符情况&#xff08;在最底层时&#xff09; 2.2查验能实现基础排序&#xff08;在最底层往上点时&#xff09; 2.3跳转结果继续往上回搭 3.实质 4.实现 二、递归的调用栈 1.递归的…...

【JavaScript】二十三、M端事件 + 轮播图Swiper插件

文章目录 1、M端事件2、swiper插件2.1 插件2.2 轮播图插件Swiper的使用 3、案例&#xff1a;学生信息表 1、M端事件 移动端有一个独有的事件&#xff1a;触屏事件 touch(也称触摸事件)&#xff0c;Android 和 IOS 都有&#xff0c;touch 对象代表一个触摸点。触摸点可能是一根…...