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

使用 Kotlin 将 Vertx 和 Springboot 整合

本篇文章目的是将 Springboot 和 Vertx 进行简单整合。整合目的仅仅是为了整活,因为两个不同的东西整合在一起提升的性能并没有只使用 Vertx 性能高,因此追求高性能的话这是在我来说不推荐。而且他们不仅没有提高很多性能甚至增加了学习成本

一、整合流程

首先呢目标是将Vertx 最终整合成和使用Springboot web 一样简单的 httpserver。
步骤:

  1. 获取Springboot 所有的Bean
  2. 注册路由: 检查Bean 中是否是存在实现了 Router 的方法,并交给 router
  3. 开启服务器,等待请求

二、扫描 Bean

最终目标呢,是实现和使用Springboot 一样简便,所以就需要注解来对需要的方法进行标注

最终效果预览

@RouterController
class HelloRouter(val test :PlayerUnlockTechService
) {/*** 注册路由* 正则路由以 ^ 开始** 方法参数可以是 routingContext 或者 router 或者 routingContext 内的任何东西。以及其他的任何东西,或者 bean**/@Rout("/hello")fun hello(response: HttpServerResponse, request: HttpServerRequest) {request.bodyHandler {response.end(test.getPlayerUnlockTechsByBuilding("BD12DC34624208045CCA1ECE32071F20").toString())}}
  1. 创建注解

主要注解有:

  • RouterController 标注类中有 Router 需要的路由实现
  • Rout 标注方法是个路由实现
  • AutoClose 标注方法执行完成后自动关闭连接
/**** @author : zimo* @date : 2025/01/03*/
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
annotation class RouterController/**** @author : zimo* @date : 2025/01/03*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Router(val path: String,val method: String = ""
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Rout(val path: String,val method: String = ""
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterGet(val path: String,val method: String = "GET"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterPost(val path: String,val method: String = "POST"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterPut(val path: String,val method: String = "PUT"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterDelete(val path: String,val method: String = "DELETE"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterPatch(val path: String,val method: String = "PATCH"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterHead(val path: String,val method: String = "HEAD"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterOptions(val path: String,val method: String = "OPTIONS"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class AutoClose
  1. 获取 Beans
    在当前类中注入 applicationContext 并通过 applicationContext.beanDefinitionNames 获取所有的 Bean
@Component
class RouterProcessor(val applicationContext: ApplicationContext) {/*** 初始化完成后的 bean 列表*/private val initializedBeanInstances by lazy {applicationContext.beanDefinitionNames.filter {it != this.javaClass.simpleName && it != Connection::class.simpleName}.mapNotNull {applicationContext.getBean(it)}}
}
  1. 检测出所有的Router 方法
    检测出是否被标注为了一个 Router 方法,并注册到 router
for (method in clazz.methods) {if (method.isAnnotationPresent(io.github.zimoyin.ra3.annotations.Router::class.java)) {val path = method.getAnnotation(io.github.zimoyin.ra3.annotations.Router::class.java).pathrouter.let {if (path.startsWith("^")) it.routeWithRegex(path.replaceFirst("^", ""))else it.route(path)// order 可以放到注解里,这样可以动态设置了}.order(0).handler {// 执行方法的封装invoke(method, bean, it)}return}// ... 其他注解处理
}

三、执行Router方法

这里只有两个重点,一个是自动关闭,一个是执行方法传入的参数实例

  • 自动关闭,如果方法上存在 AutoClose 注解就在执行方法结束后尝试关闭连接
  • 方法参数,从Bean、Context 中获取。如果没有则通过上下文创建 Bean
fun invoke(method: Method, bean: Any, routingContext: RoutingContext) {val args = arrayListOf<Any>()val isHasAutoClose = method.isAnnotationPresent(AutoClose::class.java)// 获取方法需要的参数method.parameters.forEach {val bean0 = kotlin.runCatching { applicationContext.getBean(it.name, it.type) }.getOrNull()?: kotlin.runCatching { applicationContext.getBean(it.type) }.getOrNull()if (bean0 != null) {args.add(bean0)} else {args.add(createParameter(it, routingContext))}}//执行方法try {routingContext.request().paramsCharset = "UTF-8"val result = method.invoke(bean, *args.toTypedArray())kotlin.runCatching {// 自动关闭,如果方法上存在 `AutoClose` 注解就在执行方法结束后尝试关闭连接// 获取方法的返回值,并以方法的返回值作为自动关闭的参数if (isHasAutoClose) {val response = routingContext.response()response.putHeader("content-type", "application/json")if (method.returnType == Unit::class.java) {response.end()}if (result == null) {response.end()}if (result is String) {response.end(result)} else if (result is Number || result is Comparable<*>) {response.end(result.toString())} else {kotlin.runCatching {response.end(result.toJsonObject().toString())}.onFailure {response.end()logger.debug("自动关闭连接失败", it)}}}}} catch (e: InvocationTargetException) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败, $method 方法内部存在错误逻辑导致方法执行失败", e)} catch (e: Exception) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败", e)}}

获取 routingContext 中的参数,或者创建一个参数

private fun createParameter(value: Parameter, routingContext: RoutingContext): Any {val name = value.nameval type = value.typewhen (name) {"res", "response", "resp" -> return routingContext.response()"req", "request", "requ" -> return routingContext.request()"body", "reqBody", "requestBody" -> return routingContext.body()"headers", "header", "reqHeader", "requestHeader", "reqHeaders", "requestHeaders" -> return routingContext.request().headers()"query", "reqQuery", "requestQuery", "reqQueries", "requestQueries" -> return routingContext.queryParams()"data", "reqData", "requestData" -> return routingContext.data()"params", "reqParams", "requestParams" -> return routingContext.pathParams()"cookie", "reqCookie", "requestCookie" -> return routingContext.cookieMap()"session", "reqSession", "requestSession" -> return routingContext.session()"user", "reqUser", "requestUser" -> return routingContext.user()"bodyAsString", "reqBodyAsString", "requestBodyAsString" -> return routingContext.bodyAsString"bodyAsJson", "reqBodyAsJson", "requestBodyAsJson" -> return routingContext.bodyAsJson"bodyAsBuffer", "reqBodyAsBuffer", "requestBodyAsBuffer" -> return routingContext.body().buffer()"routingContext", "context", "routerContext", "routContext" -> return routingContext"rout", "router" -> return routingContext.currentRoute()"vertx", "vertxContext" -> return routingContext.vertx()"responseHeaders", "responseHeader" -> return routingContext.response().headers()"uri" -> return routingContext.request().uri()"absoluteURI" -> return routingContext.request().absoluteURI()"authority" -> return routingContext.request().authority()"isSSL", "ssl", "isSsl", "isSSl", "isssl", "SSL", "Ssl" -> return routingContext.request().isSSL}// 如果都不是以上的参数则创建一个kotlin.runCatching {applicationContext.autowireCapableBeanFactory.createBean(type)}.onSuccess {return it}throw IllegalArgumentException("Unable to parse parameters:$name")}

四、全部代码

通过 @EventListener(ApplicationReadyEvent::class) 注解来确保,该初始化方法可以在Springboot 启动完成后执行

注意: 需要提前将 Router 注册到Springboot

@Component
class RouterProcessor(val applicationContext: ApplicationContext) {private lateinit var router: io.vertx.ext.web.Routerprivate val logger = LoggerFactory.getLogger(RouterProcessor::class.java)@EventListener(ApplicationReadyEvent::class)fun init(event: ApplicationReadyEvent) {kotlin.runCatching {router = applicationContext.getBeanByName("router")for (bean in initializedBeanInstances) {registerBean(bean)}}.onFailure {logger.error(" Vertx WebRouter 初始化失败: ${it.message}", it)}}/*** 初始化完成后的 bean 列表*/private val initializedBeanInstances by lazy {applicationContext.beanDefinitionNames.filter {it != this.javaClass.simpleName &&it != Connection::class.simpleName}.mapNotNull {applicationContext.getBean(it)}}fun registerBean(bean: Any) {val clazz = bean.javaClassfor (method in clazz.methods) {runCatch {registerMethod(method, bean)}}}fun registerMethod(method: Method, bean: Any) {if (method.isAnnotationPresent(io.github.zimoyin.ra3.annotations.Router::class.java)) {val path = method.getAnnotation(io.github.zimoyin.ra3.annotations.Router::class.java).pathrouter.let {if (path.startsWith("^")) it.routeWithRegex(path.replaceFirst("^", ""))else it.route(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(Rout::class.java)) {val path = method.getAnnotation(Rout::class.java).pathrouter.let {if (path.startsWith("^")) it.routeWithRegex(path.replaceFirst("^", ""))else it.route(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPost::class.java)) {val path = method.getAnnotation(RouterPost::class.java).pathrouter.let {if (path.startsWith("^")) it.postWithRegex(path.replaceFirst("^", ""))else it.post(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterGet::class.java)) {val path = method.getAnnotation(RouterGet::class.java).pathrouter.let {if (path.startsWith("^")) it.getWithRegex(path.replaceFirst("^", ""))else it.get(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPut::class.java)) {val path = method.getAnnotation(RouterPut::class.java).pathrouter.let {if (path.startsWith("^")) it.putWithRegex(path.replaceFirst("^", ""))else it.put(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPatch::class.java)) {val path = method.getAnnotation(RouterPatch::class.java).pathrouter.let {if (path.startsWith("^")) it.patchWithRegex(path.replaceFirst("^", ""))else it.patch(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPatch::class.java)) {val path = method.getAnnotation(RouterDelete::class.java).pathrouter.let {if (path.startsWith("^")) it.deleteWithRegex(path.replaceFirst("^", ""))else it.delete(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterHead::class.java)) {val path = method.getAnnotation(RouterHead::class.java).pathrouter.let {if (path.startsWith("^")) it.headWithRegex(path.replaceFirst("^", ""))else it.head(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterOptions::class.java)) {val path = method.getAnnotation(RouterOptions::class.java).pathrouter.let {if (path.startsWith("^")) it.optionsWithRegex(path.replaceFirst("^", ""))else it.options(path)}.order(0).handler {invoke(method, bean, it)}return}}fun invoke(method: Method, bean: Any, routingContext: RoutingContext) {val args = arrayListOf<Any>()val isHasAutoClose = method.isAnnotationPresent(AutoClose::class.java)method.parameters.forEach {val bean0 = kotlin.runCatching { applicationContext.getBean(it.name, it.type) }.getOrNull()?: kotlin.runCatching { applicationContext.getBean(it.type) }.getOrNull()if (bean0 != null) {args.add(bean0)} else {args.add(createParameter(it, routingContext))}}//执行方法try {routingContext.request().paramsCharset = "UTF-8"val result = method.invoke(bean, *args.toTypedArray())kotlin.runCatching {if (isHasAutoClose) {val response = routingContext.response()response.putHeader("content-type", "application/json")if (method.returnType == Unit::class.java) {response.end()}if (result == null) {response.end()}if (result is String) {response.end(result)} else if (result is Number || result is Comparable<*>) {response.end(result.toString())} else {kotlin.runCatching {response.end(result.toJsonObject().toString())}.onFailure {response.end()logger.debug("自动关闭连接失败", it)}}}}} catch (e: InvocationTargetException) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败, $method 方法内部存在错误逻辑导致方法执行失败", e)} catch (e: Exception) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败", e)}}private fun createParameter(value: Parameter, routingContext: RoutingContext): Any {val name = value.nameval type = value.typewhen (name) {"res", "response", "resp" -> return routingContext.response()"req", "request", "requ" -> return routingContext.request()"body", "reqBody", "requestBody" -> return routingContext.body()"headers", "header", "reqHeader", "requestHeader", "reqHeaders", "requestHeaders" -> return routingContext.request().headers()"query", "reqQuery", "requestQuery", "reqQueries", "requestQueries" -> return routingContext.queryParams()"data", "reqData", "requestData" -> return routingContext.data()"params", "reqParams", "requestParams" -> return routingContext.pathParams()"cookie", "reqCookie", "requestCookie" -> return routingContext.cookieMap()"session", "reqSession", "requestSession" -> return routingContext.session()"user", "reqUser", "requestUser" -> return routingContext.user()"bodyAsString", "reqBodyAsString", "requestBodyAsString" -> return routingContext.bodyAsString"bodyAsJson", "reqBodyAsJson", "requestBodyAsJson" -> return routingContext.bodyAsJson"bodyAsBuffer", "reqBodyAsBuffer", "requestBodyAsBuffer" -> return routingContext.body().buffer()"routingContext", "context", "routerContext", "routContext" -> return routingContext"rout", "router" -> return routingContext.currentRoute()"vertx", "vertxContext" -> return routingContext.vertx()"responseHeaders", "responseHeader" -> return routingContext.response().headers()"uri" -> return routingContext.request().uri()"absoluteURI" -> return routingContext.request().absoluteURI()"authority" -> return routingContext.request().authority()"isSSL", "ssl", "isSsl", "isSSl", "isssl", "SSL", "Ssl" -> return routingContext.request().isSSL}kotlin.runCatching {applicationContext.autowireCapableBeanFactory.createBean(type)}.onSuccess {return it}throw IllegalArgumentException("Unable to parse parameters:$name")}fun <T : Any> runCatch(block: () -> T): T? {try {return block()} catch (e: Exception) {logger.error("路由捕获到异常", e)}return null}
}

使用示例

/**** @author : zimo* @date : 2025/01/04*/
@RouterController
class HelloRouter(val test :PlayerUnlockTechService
) {/*** 注册路由* 正则路由以 ^ 开始* 请求处理方法: 所有* 方法参数可以是 routingContext 或者 router 或者 routingContext 内的任何东西。以及其他的任何东西,或者 bean**/@Rout("/hello")
//    @RouterGetfun hello(response: HttpServerResponse, request: HttpServerRequest) {request.bodyHandler {response.end(test.getPlayerUnlockTechsByBuilding("BD12DC34624208045CCA1ECE32071F20").toString())}}/*** 注册路由(并自动关闭,将返回值发送会前端)* 正则路由以 ^ 开始* 请求处理方法: GET* 方法参数可以是 routingContext 或者 router 或者 routingContext 内的任何东西。以及其他的任何东西,或者 bean**/@RouterGet("/test/send_message/:message")@AutoClosefun send(response: HttpServerResponse, request: HttpServerRequest):String {return "你好"}}
}

Main 方法

/**** @author : zimo* @date : 2025/01/03*/
@SpringBootApplication
@EnableCaching
@MapperScan(basePackages = ["io.github.zimoyin.ra3.mapper"])
class ApplicationStart2(val vertx: Vertx,val router: Router
) {companion object {@JvmStaticfun main(args: Array<String>) {runApplication<ApplicationStart2>(*args)}}@PostConstructfun onStartVertxWeb() {vertx.createHttpServer().requestHandler(router).listen(8090).onSuccess {println("启动成功")}}
}@Configuration
class VertxConfig {@Bean("vertx")fun vertx(): Vertx {return Vertx.vertx()}@Bean("router")fun router(vertx: Vertx): Router? {return Router.router(vertx)}
}

相关文章:

使用 Kotlin 将 Vertx 和 Springboot 整合

本篇文章目的是将 Springboot 和 Vertx 进行简单整合。整合目的仅仅是为了整活&#xff0c;因为两个不同的东西整合在一起提升的性能并没有只使用 Vertx 性能高&#xff0c;因此追求高性能的话这是在我来说不推荐。而且他们不仅没有提高很多性能甚至增加了学习成本 一、整合流…...

自定义数据集 使用scikit-learn中svm的包实现svm分类

引入必要的库 import numpy as np from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.metrics import accuracy_score, classification_report 生成自定义数据集 X, y ma…...

python:如何播放 .spx 声音文件

.spx 是 Speex音频编解码器的文件扩展名&#xff0c;它是一种开源的、免费的音频编解码器&#xff0c;主要用于语音压缩和语音通信领域。spx 文件通常用于语音记录、VoIP应用、语音信箱等场景。 .mp3 是一种广泛使用的音频格式&#xff0c;它采用了有损压缩算法&#xff0c;可…...

php的使用及 phpstorm环境部署

php语法 环境搭建&#xff1a;在小皮中新建网站&#xff0c;注意先填写域名再点击选择根目录。 成功创建网站后&#xff0c;打开发现forbidden&#xff0c;因为新建的网站里是空的&#xff0c;需要新建index.php文件----> 在Phpstorm中左上角打开文件&#xff0c;打开那个文…...

有用的sql链接

『SQL』常考面试题&#xff08;2——窗口函数&#xff09;_sql的窗口函数面试题-CSDN博客 史上最强sql计算用户次日留存率详解&#xff08;通用版&#xff09;及相关常用函数 -2020.06.10 - 知乎 (zhihu.com) 1280. 学生们参加各科测试的次数 - 力扣&#xff08;LeetCode&…...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.27 NumPy+Pandas:高性能数据处理的黄金组合

2.27 NumPyPandas&#xff1a;高性能数据处理的黄金组合 目录 #mermaid-svg-x3ndEE4hrhO6WR6H {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-x3ndEE4hrhO6WR6H .error-icon{fill:#552222;}#mermaid-svg-x3ndEE4hr…...

第一个3D程序!

运行效果 CPP #include <iostream> #include <fstream> #include <string> #include <cmath>#include <GL/glew.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> #include <glm/gtc/type_ptr.hpp> #include <glm/gtc/…...

NeuralCF 模型:神经网络协同过滤模型

实验和完整代码 完整代码实现和jupyter运行&#xff1a;https://github.com/Myolive-Lin/RecSys--deep-learning-recommendation-system/tree/main 引言 NeuralCF 模型由新加坡国立大学研究人员于 2017 年提出&#xff0c;其核心思想在于将传统协同过滤方法与深度学习技术相结…...

第二十三章 MySQL锁之表锁

目录 一、概述 二、语法 三、特点 一、概述 表级锁&#xff0c;每次操作锁住整张表。锁定粒度大&#xff0c;发生锁冲突的概率最高&#xff0c;并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。 对于表级锁&#xff0c;主要分为以下三类&#xff1a; 1. 表锁 2. 元数…...

【Uniapp-Vue3】获取用户状态栏高度和胶囊按钮高度

在项目目录下创建一个utils文件&#xff0c;并在里面创建一个system.js文件。 在system.js中配置如下代码&#xff1a; const SYSTEM_INFO uni.getSystemInfoAsync();// 返回状态栏高度 export const getStatusBarHeight ()> SYSTEM_INFO.statusBarHeight || 15;// 返回胶…...

04树 + 堆 + 优先队列 + 图(D1_树(D10_决策树))

目录 一、引言 二、算法原理 三、算法实现 四、知识小结 一、引言 决策树算法是一种常用的机器学习算法&#xff0c;可用于分类和回归问题。它基于特征之间的条件判断来构 建一棵树&#xff0c;树的每个节点代表一个特征&#xff0c;每个叶节点代表一个类别或回归值。决策…...

通向AGI之路:人工通用智能的技术演进与人类未来

文章目录 引言:当机器开始思考一、AGI的本质定义与技术演进1.1 从专用到通用:智能形态的范式转移1.2 AGI发展路线图二、突破AGI的五大技术路径2.1 神经符号整合(Neuro-Symbolic AI)2.2 世界模型架构(World Models)2.3 具身认知理论(Embodied Cognition)三、AGI安全:价…...

将ollama迁移到其他盘(eg:F盘)

文章目录 1.迁移ollama的安装目录2.修改环境变量3.验证 背景&#xff1a;在windows操作系统中进行操作 相关阅读 &#xff1a;本地部署deepseek模型步骤 1.迁移ollama的安装目录 因为ollama默认安装在C盘&#xff0c;所以只能安装好之后再进行手动迁移位置。 # 1.迁移Ollama可…...

为AI聊天工具添加一个知识系统 之86 详细设计之27 数据处理:ETL

本文要点 ETL 数据提取 作为 数据项目的起点。数据的整个三部曲--里程碑式的发展进程&#xff1a; ETL : 1分形 Type()-层次Broker / 2完形 Method() - 维度Delegate /3 整形 Class() - 容器 Agent 1变象。变象 脸谱Extractor - 缠度&#xff08;物理 皮肤缠度&#xf…...

Java自定义IO密集型和CPU密集型线程池

文章目录 前言线程池各类场景描述常见场景案例设计思路公共类自定义工厂类-MyThreadFactory自定义拒绝策略-RejectedExecutionHandlerFactory自定义阻塞队列-TaskQueue&#xff08;实现 核心线程->最大线程数->队列&#xff09; 场景1&#xff1a;CPU密集型场景思路&…...

使用开源项目:pdf2docx,让PDF转换为Word

目录 1.安装python 2.安装 pdf2docx 3.使用 pdf2docx 转换 PDF 到 Word pdf2docx&#xff1a;GitCode - 全球开发者的开源社区,开源代码托管平台 环境&#xff1a;windows电脑 1.安装python Download Python | Python.org 最好下载3.8以上的版本 安装时记得选择上&#…...

蓝桥杯思维训练营(四)

文章目录 小红打怪494.目标和 小红打怪 小红打怪 思路分析&#xff1a;可以看到ai的范围较大&#xff0c;如果我们直接一个个进行暴力遍历的话&#xff0c;会超时。当我们的攻击的次数越大的时候&#xff0c;怪物的血量就会越少&#xff0c;这里就有一个单调的规律在里面&…...

尝试把clang-tidy集成到AWTK项目

前言 项目经过一段时间的耕耘终于进入了团队开发阶段&#xff0c;期间出现了很多问题&#xff0c;其中一个就是开会讨论团队的代码风格规范&#xff0c;目前项目代码风格比较混乱&#xff0c;有的模块是驼峰&#xff0c;有的模块是匈牙利&#xff0c;后面经过讨论&#xff0c;…...

【学习笔记】深度学习网络-正则化方法

作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程&#xff0c;深度学习领域研究生必读教材),开始深度学习领域学习&#xff0c;深入全面的理解深度学习的理论知识。 在之前的文章中介绍了深度学习中用…...

介绍一下Mybatis的底层原理(包括一二级缓存)

表面上我们的就是Sql语句和我们的java对象进行映射&#xff0c;然后Mapper代理然后调用方法来操作数据库 底层的话我们就涉及到Sqlsession和Configuration 首先说一下SqlSession&#xff0c; 它可以被视为与数据库交互的一个会话&#xff0c;用于执行 SQL 语句&#xff08;Ex…...

WordPress使用(1)

1. 概述 WordPress是一个开源博客框架&#xff0c;配合不同主题&#xff0c;可以有多种展现方式&#xff0c;博客、企业官网、CMS系统等&#xff0c;都可以很好的实现。 官网&#xff1a;博客工具、发布平台和内容管理系统 – WordPress.org China 简体中文&#xff0c;这里可…...

BUUCTF_[安洵杯 2019]easy_web(preg_match绕过/MD5强碰撞绕过/代码审计)

打开靶场&#xff0c;出现下面的静态html页面&#xff0c;也没有找到什么有价值的信息。 查看页面源代码 在url里发现了img传参还有cmd 求img参数 这里先从img传参入手&#xff0c;这里我发现img传参好像是base64的样子 进行解码&#xff0c;解码之后还像是base64的样子再次进…...

C基础寒假练习(4)

输入带空格的字符串&#xff0c;求单词个数、 #include <stdio.h> // 计算字符串长度的函数 size_t my_strlen(const char *str) {size_t len 0;while (str[len] ! \0) {len;}return len; }int main() {char str[100];printf("请输入一个字符串: ");fgets(…...

git error: invalid path

git clone GitHub - guanpengchn/awesome-books: :books: 开发者推荐阅读的书籍 在windows上想把这个仓库拉取下来&#xff0c;发现本地git仓库创建 但只有一个.git隐藏文件夹&#xff0c;其他文件都处于删除状态。 问题&#xff1a; Cloning into awesome-books... remote:…...

MySQL 事务实现原理( 详解 )

MySQL 主要是通过: 锁、Redo Log、Undo Log、MVCC来实现事务 事务的隔离性利用锁机制实现 原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。 Redo Log(重做日志)&#xff1a;记录事务对数据库的所有修改&#xff0c;在崩溃时恢复未提交的更改&#xff0c;保证事务…...

git基础使用--1--版本控制的基本概念

文章目录 git基础使用--1--版本控制的基本概念1.版本控制的需求背景&#xff0c;即为啥需要版本控制2. 集中式版本控制SVN3. 分布式版本控制 Git4. SVN和Git的比较 git基础使用–1–版本控制的基本概念 1.版本控制的需求背景&#xff0c;即为啥需要版本控制 先说啥叫版本&…...

Spring RESTful API 设计与实现

Spring RESTful API的设计与实现极大地提升了开发效率和系统可维护性,通过遵循RESTful设计原则,使得API结构清晰、行为一致,便于扩展和维护。它在构建微服务架构中扮演着核心角色,支持松耦合的通信,同时通过标准的HTTP协议和数据格式增强了系统的互操作性。结合Spring Sec…...

Unity飞行代码 超仿真 保姆级教程

本文使用Rigidbody控制飞机&#xff0c;基本不会穿模。 效果 飞行效果 这是一条优雅的广告 如果你也在开发飞机大战等类型的飞行游戏&#xff0c;欢迎在主页搜索博文并参考。 搜索词&#xff1a;Unity游戏(Assault空对地打击)开发。 脚本编写 首先是完整代码。 using System.Co…...

【自学笔记】Git的重点知识点-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Git基础知识Git高级操作与概念Git常用命令 总结 Git基础知识 Git简介 Git是一种分布式版本控制系统&#xff0c;用于记录文件内容的改动&#xff0c;便于开发者追踪…...

力扣73矩阵置零

给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 输入&#xff1a;matrix [[0,1,2,0],[3,4,5,2],[…...