(Go Gin)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
1. 路由
gin 框架中采用的路优酷是基于httprouter做的
HttpRouter 是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
主要特点
- 显式匹配:与其他路由器不同,HttpRouter 只支持显式匹配,即一个请求只能匹配一个或不匹配任何路由。这避免了意外匹配,提高了 SEO 和用户体验。
- 自动处理尾部斜杠:HttpRouter 会自动重定向缺少或多余尾部斜杠的请求,前提是新路径有处理程序。如果不需要这种行为,可以关闭2。
- 路径自动校正:除了处理尾部斜杠,HttpRouter 还可以修正错误的大小写和多余的路径元素(如 …/ 或 //)。
- 路由参数:支持在路由模式中使用命名参数和捕获所有参数,简化了 URL 路径的解析。
- 零垃圾:匹配和分发过程不会产生垃圾,只有在路径包含参数时才会进行堆分配。
- 最佳性能:使用压缩动态 trie(基数树)结构进行高效匹配,性能优异。
1.1 基本路由
package oneimport ("github.com/gin-gonic/gin""net/http"
)func index() {r := gin.Default()r.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "Hello Gin")})r.POST("/", func(c *gin.Context) {})r.DELETE("/", func(c *gin.Context) {})r.PUT("/", func(c *gin.Context) {})r.Run(":8081")
}
- gin支持Restful风格的API
- 即Representational State Transfer的缩写。直接翻译的意思是"表现层状态转化",是一种互联网应用程序的API设计理念:URL定位资源,用HTTP描述操作
1.获取文章:/blog/getXxx Get blog/Xxx
2.添加:/blog/addXxx POST blog/Xxx
3.修改:/blog/updateXxx PUT blog/Xxx
4.删除:/blog/delXxxx DELETE blog/Xxx
另一种方式
package mainimport ("github.com/gin-gonic/gin""net/http"
)func sayHello(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "hello",})
}func main() {r := gin.Default()r.GET("/test1", sayHello)r.Run(":8080")
}
1.2 API 参数
请求方式的方法可以通过函数来接受,从而获得请求传来的参数
package mainimport ("github.com/gin-gonic/gin""net/http"
)func sayHello(c *gin.Context) {name := c.Param("name")age := c.Param("age")c.JSON(http.StatusOK, gin.H{"name": name,"age": age,})
}func main() {r := gin.Default()// 请求:localhost/test1/xxx/ooo// 响应:{"name":xxx,"age":ooo}r.GET("/test1/:name/:age", sayHello)r.Run(":8080")
}
需要注意:gin默认开启restful风格语法,所以可以直接在请求路径上添加名称,属性名是拟定在请求的路径上的
r.GET("/test1/:name/:age", sayHello)
这里请求路径拟定了方法内
c *gin.Context
中的参数名称;这里默认有 name 和 age 属性
请求:http://localhost:8080/test1/张三/18
响应结果:
{"age": "18","name": "张三"
}
1.3 URL 参数
路径参数,就不会使用restful风格语法进行接受请求参数
package mainimport ("fmt""github.com/gin-gonic/gin""net/http"
)func sayHello(c *gin.Context) {// Query方法,若不存在则返回空字符串name := c.Query("name")age := c.Query("age")fmt.Println("========================")fmt.Println("名称", name)fmt.Println("年龄", name)fmt.Println("========================")name1 := c.DefaultQuery("name", "默认名称")fmt.Println("defaultName", name1)c.JSON(http.StatusOK, gin.H{"name": name,"age": age,"name1": name1,})
}func main() {r := gin.Default()// 请求:localhost/test1/?xxx=xxx&ooo=000// 响应:{"name":xxx,"age":ooo}r.GET("/test1", sayHello)r.Run(":8080")
}
- URL参数可以通过DefaultQuery()或Query()方法获取
- DefaultQuery()若参数不存在,返回默认值,Query()若不存在,返回空串
两种请求:
-
请求1:
http://localhost:8080/test1?age=19
-
响应数据1:
{"age": "19","name": "","name1": "默认名称"
}
- 请求2:
http://localhost:8080/test1?name=张三&age=19
- 响应数据2:
{"age": "19","name": "张三","name1": "张三"
}
1.4 表单参数
- 表单传输为post请求,http常见的传输格式为四种:
- application/json
- application/x-www-form-urlencoded
- application/xml
- multipart/form-data
- 表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencoded或from-data格式的参数
测试的html文件
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body>
<form action="http://localhost:8080/form" method="post" action="application/x-www-form-urlencoded">用户名:<input type="text" name="username" placeholder="请输入你的用户名"> <br>密 码:<input type="password" name="user_password" placeholder="请输入你的密码"> <br><input type="submit" value="提交">
</form>
</body>
</html>
- index.go
package mainimport ("github.com/gin-gonic/gin""net/http"
)func sayHello(c *gin.Context) {types := c.DefaultPostForm("type", "post")// 接受参数name := c.PostForm("username") // 对应页面传入的name值或者json的属性password := c.PostForm("user_password")c.JSON(http.StatusOK, gin.H{"types": types,"name": name,"password": password,})
}func main() {r := gin.Default()r.POST("/form", sayHello)r.Run(":8080")
}
返回数据:
{"name": "rx","password": "123","types": "post"
}
1.5 上传单个文件
multipart/form-data
格式用于文件上传- gin文件上传与原生的net/http方法类似,不同在于gin把原生的request封装到c.Request中
demo2.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">上传文件:<input type="file" name="file" ><input type="submit" value="提交">
</form>
</body>
</html>
- index.go
package __single_fileimport ("github.com/gin-gonic/gin""net/http"
)func DefaultFunction(c *gin.Context) {// 上传单个文件file, _ := c.FormFile("file")if file == nil {c.JSON(http.StatusInternalServerError, gin.H{"code": http.StatusInternalServerError,"message": "文件为空",})return}c.SaveUploadedFile(file, file.Filename)c.JSON(http.StatusOK, gin.H{"file": file.Filename,})
}func main() {r := gin.Default()r.POST("/upload", DefaultFunction)r.Run(":8080")
}
数据响应:
{"file":"Picture3.png"}
1.6 上传单个文件——添加限制
package __single_file_restrictimport ("fmt""github.com/gin-gonic/gin""log""net/http"
)func DefaultFunction(c *gin.Context) {// 上传单个文件_携带限制_, file, err := c.Request.FormFile("file")if err != nil {log.Printf("Error when try to get file: %v", err)}//file.Size 获取文件大小if file.Size > 1024*1024*2 {fmt.Println("文件太大了")return}//file.Header.Get("Content-Type")获取上传文件的类型if file.Header.Get("Content-Type") != "image/png" {fmt.Println("只允许上传png图片")return}c.SaveUploadedFile(file, file.Filename)c.JSON(http.StatusOK, gin.H{"file": file.Filename,})
}func main() {r := gin.Default()r.POST("/upload", DefaultFunction)r.Run(":8080")
}
数据响应:
{"file":"Picture3.png"}
1.7 上传多个文件
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><form action="http://localhost:8000/upload" method="post" enctype="multipart/form-data">上传文件:<input type="file" name="files" multiple><input type="submit" value="提交"></form>
</body>
</html>
package mainimport ("github.com/gin-gonic/gin""net/http""fmt"
)// gin的helloWorldfunc main() {// 1.创建路由// 默认使用了2个中间件Logger(), Recovery()r := gin.Default()// 限制表单上传大小 8MB,默认为32MBr.MaxMultipartMemory = 8 << 20r.POST("/upload", func(c *gin.Context) {form, err := c.MultipartForm()if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get err %s", err.Error()))}// 获取所有图片files := form.File["files"]// 遍历所有图片for _, file := range files {// 逐个存if err := c.SaveUploadedFile(file, file.Filename); err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("upload err %s", err.Error()))return}}c.String(200, fmt.Sprintf("upload ok %d files", len(files)))})//默认端口号是8080r.Run(":8000")
}
1.8 路由组-routers group
package mainimport ("github.com/gin-gonic/gin""net/http"
)func cat(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"cat": c.Query("cat"),})
}func dog(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"dog": c.Query("dog"),})
}func main() {r := gin.Default()animal := r.Group("/animal")// http://localhost:8080/animal/cat?cat=tomanimal.GET("/cat", cat)animal.GET("/dog", dog)// 第二种写法// http://localhost:8080/animal2/cat?cat=tomanimal2 := r.Group("/animal2"){animal2.GET("/cat", cat)animal2.GET("/dog", dog)}r.Run(":8080")
}
路由组有两种写法
-
动态配置,将变量声明出来可以在任意位置配置路由
animal := r.Group("/animal") // http://localhost:8080/animal/cat?cat=tom animal.GET("/cat", cat) animal.GET("/dog", dog)
-
对象配置,直接使用对象进行配置
// http://localhost:8080/animal2/cat?cat=tom animal2 := r.Group("/animal2") {animal2.GET("/cat", cat)animal2.GET("/dog", dog) }
注意路由组配置:组路径下的请求配置,必须加上
/
例如: animal2.GET(“/cat”, cat)
1.9 httprotuer路由原理
1.9.1 Radix Tree(压缩前缀树)
基数树(Radix Tree)又称为PAT位树(Patricia Trie or crit bit tree),是一种更节省空间的前缀树(Trie Tree)。对于基数树的每个节点,如果该节点是唯一的子树的话,就和父节点合并
Radix Tree
可以被认为是一棵简洁版的前缀树。其注册路由的过程就是构造前缀树的过程,具有公共前缀的节点也共享一个公共父节点。假设注册以下路由信息:
r := gin.Default()r.GET("/", func1)
r.GET("/search/", func2)
r.GET("/support/", func3)
r.GET("/blog/", func4)
r.GET("/blog/:post/", func5)
r.GET("/about-us/", func6)
r.GET("/about-us/team/", func7)
r.GET("/contact/", func8)
生成的路由树信息如下:
Priority Path Handle
9 \ *<1>
3 ├s nil
2 |├earch\ *<2>
1 |└upport\ *<3>
2 ├blog\ *<4>
1 | └:post nil
1 | └\ *<5>
2 ├about-us\ *<6>
1 | └team\ *<7>
1 └contact\ *<8>
最右列每个***<数字>表示Handle处理函数的内存地址(一个指针)**。
- 从根节点遍历到叶子节点就能得到完整的路由表。
例如:blog/:post其中:post只是实际文章名称的占位符(参数)。
与hash-maps不同,Radix Tree结构还允许使用像:post参数这种动态部分,因为Radix Tree实际上是根据路由模式进行匹配,而不仅仅是比较哈希值。
由于URL路径具有层次结构,并且只使用有限的一组字符(字节值),所以很可能有许多常见的前缀。这使开发者可以很容易地将路由简化为更小的问题。
- 此外,路由器为每种请求方法管理一棵单独的树。
- 一方面,它比在每个节点中都保存一个method-> handle map更加节省空间,而且还使开发者甚至可以在开始在前缀树中查找之前大大减少路由问题。
为了获得更好的可伸缩性,每个树级别上的子节点都按Priority(优先级)排序,其中优先级(最左列)就是在子节点(子节点、子子节点等等)中注册的句柄的数量。
这样做有两个好处:
优先匹配被大多数路由路径包含的节点
。这样可以让尽可能多的路由快速被定位。- 类似于成本补偿。最长的路径可以被优先匹配,补偿体现在最长的路径需要花费更长的时间来定位,如果最长路径的节点能被优先匹配(即每次拿子节点都命中),那么路由匹配所花的时间不一定比短路径的路由长。
下面展示了节点(每个-可以看做一个节点)匹配的路径:从左到右,从上到下。
├------------
├---------
├-----
├----
├--
├--
└-
1.9.2 httproute 特点
路由器支持路由模式中的变量,并与请求方法进行匹配。其伸缩性相较于原生net/http库更好。
明确的路由匹配,一个path对应一个Handler。
不用关心/,例如当请求/foo/时,此path不存在,如果有/foo会自动302转发
path自动修正,例如//foo转化成/foo
httprouter使用的数据结构就是压缩字典树。
典型的压缩字典树结构如下:
1.9 参考文章:https://blog.csdn.net/ygq13572549874/article/details/130281909
2. 💕👉博客专栏
- Golang专栏-包含基础、Gin、Goam等知识
- 云原生专栏-包含k8s、docker等知识
- 从0开始学习云计算-华为HCIP证书
- JUC专栏-带你快速领悟JUC的知识!
- JVM专栏-深入Java虚拟机,理解JVM的原理
- 基于Java研究 数据结构与算法-包含贪心算法、加权图、最短路径算法等知识
- Docker专栏-上手热门容器技术Docker
- SpringBoot专栏-学习SpringBoot快速开发后端
- 项目管理工具的学习-设计技术:Maven、Git、Gradle等相关管理工具
- JavaSE-全面了解Java基础
- JS专栏-使用JS作的一部分实例~
- 使用CSS所作的一部分案例
相关文章:
(Go Gin)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
1. 路由 gin 框架中采用的路优酷是基于httprouter做的 HttpRouter 是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。 主要特点 显式匹配:与其他路由…...
纯HTMLCSS静态网站——元神
《原神》主题网页介绍 以对该网页的详细介绍 网页整体结构 头部(header):包含网站的 logo 和导航栏。logo 部分展示了 “原神” 字样,点击可返回首页。导航栏提供了多个页面链接,包括首页、音乐、视频、壁纸、世界、…...
嵌入式开发:基础知识介绍
一、嵌入式系统 1、介绍 以提高对象体系智能性、控制力和人机交互能力为目的,通过相互作用和内在指标评价的,嵌入到对象体系中的专用计算机系统。 2、分类 按其形态的差异,一般可将嵌入式系统分为:芯片级(MCU、SoC&am…...
华为VRP系统简介配置TELNET远程登录!
1.华为 VRP 系统概述 1.1 什么是 VRP VRP(Versatile Routing Platform 华为数通设备操作系统)是华为公司数据通信产品的通用操作系统平台,从低端到核心的全系列路由器、以太网交换机、业务网关等产品的软件核心引擎。 1.2 VRP 的功能 统一…...
【高频考点精讲】CSS accent-color属性:如何快速自定义表单控件的颜色?
用CSS accent-color属性3分钟搞定表单控件换肤,原来这么简单! 前几天有个学员问我,checkbox和radio这些表单控件默认样式太丑了,有没有什么办法能快速改颜色?" 我一看这问题就乐了——这不正是CSS accent-color属性的拿手好戏吗?今天咱们就来好好聊聊这个被低估的C…...
【Git】连接github时的疑难杂症(DNS解析失败)
大家好,我是jstart千语。最近在将项目推送到github的时候,突然github就拒绝访问了,即使挂了VPN,网页也进不去,通过git也不能把代码推送上去。 即使后面看别人的一些解决方案,比如取消代理啊、更换ssh的方式…...
成熟的前端vue vite websocket,Django后端实现方案包含主动断开websocket连接的实现
可参考实现方式点击进入查看 具体实现方案如下所示: import { useWebsocketMsessageStore } from /stores/websocketMsessageStore.js import {ElMessage} from "element-plus"; import {useUserStore} from "/stores/userStore.js"; // impo…...
广州 3D 展厅开启企业展示新时代
为了突破传统展厅的局限,满足企业日益增长的展示需求,3D 展厅应运而生。3D 展厅是利用虚拟现实(VR)、增强现实(AR)和三维建模等先进技术,构建出的一个高度逼真的数字化展示空间 。它打破了传统展…...
【Django】新增字段后兼容旧接口 This field is required
背景 我在Django模型里新增了两个字段后,旧的接口由于没有同时新增这两个字段的处理,因此旧的接口就报: This field is required 解决 把序列化时的 required 的字段设置为False即可 class ServiceSerializer(DynamicFieldsModelSerializ…...
基于AIGC的3D场景生成实战:从文本描述到虚拟世界构建
一、3D AIGC技术解析 1.1 技术挑战与突破 挑战维度 传统方案局限 AIGC创新方案 建模效率 人工建模耗时数天 文本到3D秒级生成 细节丰富度 重复使用素材库 无限风格化生成 物理合理性 手动调整物理参数 自动符合物理规律 多平台适配 需手动优化模型 自适应LOD生成 1.2 主流技术路…...
手写Java线程池与定时器:彻底掌握多线程任务调度
目录 一、线程池 1.1、什么是线程池 1.2、Java标准库中的线程池 1.3、ThreadPoolExecutor的七大参数 1.4、模拟实现线程池 1.4.1、submit () 1.4.2、构造方法 1.4.3、运行结果 二、定时器 2.1、标准库中的定时器 2.2、模拟实现定时器 2.2.1、MyTimerTask类 2…...
【科研绘图系列】R语言绘制区间点图(dot plot)
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理画图1画图2输出图片系统信息介绍 【科研绘图系列】R语言绘制区间点图(dot plot) 加载R包 library(tidyverse) library(ggtext) library(r…...
【Agent实战】从0到1开发一个Python 解释器 MCP SSE Server
写在前面 想象一个场景:LLM Agent(如 AutoGPT、MetaGPT 或我们自己构建的 Agent)在规划任务后,决定需要运行一段 Python 代码来处理数据或调用某个 API。它不能直接在自己的环境中执行(通常不具备这个能力,也不安全),而是需要将这段代码发送给一个专门的外部服务来执行…...
C语言大写转小写2.0
一、阐述关系 上一次的题目是大写转小写,这一次代码不一样,运行的结果也不一样,这次的代码在此基础之上改动了一下,虽然看起来相似,但实际上运行结果不一样 二、题目展示 下面代码中,运行的结果是多少? 三、分析过程 首先,进入main函数,先声明了一个字符型数组是"012…...
pnpm常见报错解决办法
PS D:\code\gitlab\manus-web> pnpm add -D types/framer-motion --save-exact --config.strict-peer-depsfalse Debugger attached. WARN deprecated eslint8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other op…...
【Linux网络】:套接字之UDP
一、UDP和TCP协议 TCP (Transmission Control Protocol 传输控制协议)的特点: 传输层协议有连接(在正式通信前要先建立连接)可靠传输(在内部帮我们做可靠传输工作)面向字节流 UDP (U…...
量子威胁下的安全革命:后量子密码学技术路线与迁移挑战全解析
引言 量子计算技术的快速发展正在重塑现代密码学的安全版图。随着Shor算法对传统公钥密码体系的根本性威胁[1],全球范围内后量子密码学(Post-Quantum Cryptography, PQC)的研究与标准化进程已进入关键阶段。 本文基于权威文献分析,…...
多模态大语言模型(MLLM)- kimi-vl technical report论文阅读
前言 kimi-vl是月之暗面团队于2025年4月10日发布的多模态大模型。 代码链接:https://github.com/MoonshotAI/Kimi-VL 背景 随着人工智能技术的快速发展,人们对AI助手的需求已从单一文本交互转向多模态理解。新一代多模态模型如GPT-4o和Gemini虽展现…...
ai聊天流式响应,阻塞式和流式响应 nginx遇到的坑
问题 现在做ai的流式请求,在开发环境使用代理访问接口,显示是正常的。上到正式环境,代理通过nginx配置可以访问到流式接口。在本地测试postman请求流式接口,返回的东西是流式返回, 在正式环境里面使用postman请求流式…...
Linux安全模块:SELinux与AppArmor深度解析
引言 在Linux安全领域,SELinux和AppArmor就像两位忠诚的"系统保镖"💂,为你的服务器提供强制访问控制(MAC)保护!本文将深入解析这两大安全模块的工作原理、配置方法和实战技巧。无论你是要加固Web服务器,还是…...
FlinkJobmanager深度解析
1. JobManager 概述 Flink 是一个分布式流处理框架,其核心组件包括 JobManager、TaskManager 和客户端(如 CLI 或 Web UI)。JobManager 是 Flink 集群的“大脑”,负责协调作业的整个生命周期,包括作业调度、资源管理、…...
FlinkSql入门与实践
一、为什么需要 Flink SQL? 传统 SQL 是面向静态数据的查询语言,而现代实时业务要求对动态数据流进行即时分析。Flink SQL 应运而生,它让开发者无需编写复杂的状态管理代码,就能实现实时ETL、复杂事件处理(CEP&#x…...
【物联网】基于LORA组网的远程环境监测系统设计(ThingsCloud云平台版)
演示视频: 基于LORA组网的远程环境监测系统设计(ThingsCloud云平台版) 前言:本设计是基于ThingsCloud云平台版,还有另外一个版本是基于机智云平台版本,两个设计只是云平台和手机APP的区别,其他功能都一样。如下链接: 【物联网】基于LORA组网的远程环境监测系统设计(机…...
C++中指针Ptr(一级指针、二级指针)的基本使用详解(1)
C 中的指针是非常强大的工具,理解一级指针、二级指针以及它们与数组的关系,对于写出高效且安全的程序非常重要。下面我将从基础讲起,详细解释 一级指针、二级指针 的使用,注意事项,以及它们和数组之间的联系与区别&…...
科技赋能建筑新未来:中建海龙模块化建筑产品入选中国建筑首批产业化推广产品
在建筑工业化浪潮中,中国建筑国际集团旗下中建海龙科技有限公司(以下简称“中建海龙”)致力以科技创新赋能传统建造转型升级,大力发展新质生产力,促进科技成果在建筑产业体系化、规模化应用,面向“产品化、…...
示例:Spring JDBC 声明式事务(xml配置形式)
声明式事务是指在不修改源代码的情况下通过配置applicationContext.xml自动实现事务控制,其本质是AOP环绕通知。它的触发时机为:1、当目标方法执行成功时自动提交事务,2、当目标方法抛出运行时异常时,自动事务回滚 核心步骤示例&a…...
java多线程(7.0)
目录 编辑 定时器 定时器的使用 三.定时器的实现 MyTimer 3.1 分析思路 1. 创建执行任务的类。 2. 管理任务 3. 执行任务 3.2 线程安全问题 定时器 定时器是软件开发中的一个重要组件. 类似于一个 "闹钟". 达到一个设定的时间之后, 就执行某个指定好的…...
sgpt在kali应用
Kali Linux 下 sgpt 渗透测试相关案例 1. 扫描目标主机存活 sgpt -s "使用 nmap 扫描 192.168.1.100 是否存活"示例命令: nmap -sn 192.168.1.1002. 扫描目标主机开放端口和服务 sgpt -s "使用 nmap 扫描 192.168.1.100 常见端口和服务"示例…...
小白电路设计-设计11-恒功率充电电路设计
介绍 作为电子信息工程的我,电路学习是一定要学习的,可惜目前作为EMC测试工程师,无法兼顾太多,索性不如直接将所学的知识进行运用,并且也可以作为契机,进行我本人的个人提升。祝大家与我一起进行提升。1.本…...
express的模板handlebars用app.engine()创建配置和用exphbs.create()的区别
在使用 express-handlebars 时,app.engine 和 exphbs.create 都可以用来配置 Handlebars 模板引擎,但它们的使用方式和功能有一些区别。以下是详细的对比和说明 app.engine 方法 app.engine 是 Express 提供的方法,用于注册一个新的模板引擎…...
【Python数据库与后端开发】从ORM到RESTful API
目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1:SQLAlchemy模型定义案例2:FastAPI异步接口案例3:连接池配…...
数据结构(java)二叉树的基本操作
1.二叉树的性质: 1.若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2*-1(i>0)个结点 2.若规定只有根节点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2都k次方-1 3.对于任何一个二叉树,如果其叶结点个数为 n…...
windows编程字符串处理
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、windows常用字符出处理函数?二、测试代码总结 前言 提示:这里可以添加本文要记录的大概内容: Windows编程中主要使用两…...
CentOS系统防火墙服务介绍
CentOS 系统使用的是 firewalld 防火墙服务(从 CentOS 7 开始),它基于 zone(区域) 和 service(服务) 的机制来配置网络访问控制,替代了传统的 iptables。 iptables 是 Linux 系统中…...
59、微服务保姆教程(二)Nacos--- 微服务 注册中心 + 配置中心
Nacos— 微服务 注册中心 + 配置中心 一.什么是Nacos? Nacos是阿里的一个开源产品,是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案。 Nacos核心定位是“一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台”,也就是我们的注册中心和配…...
Git命令行中vim的操作
Git命令行用vim打开文件,或者用其他git命令打开了文件,需要编辑和保存文件等,有些命令表情奇怪,往往容易忘记这些命令。记录下。 下面这篇比较实用和简练: gitvim编辑文件命令 • Worktile社区https://worktile.com/…...
【分布式系统中的“瑞士军刀”_ Zookeeper】一、Zookeeper 快速入门和核心概念
在分布式系统的复杂世界里,协调与同步是确保系统稳定运行的关键所在。Zookeeper 作为分布式协调服务的 “瑞士军刀”,为众多分布式项目提供了高效、可靠的协调解决方案。无论是在分布式锁的实现、配置管理,还是在服务注册与发现等场景中&…...
【昇腾】【训练】800TA2-910B使用LLaMA-Factory训练Qwen
文章目录 1. 使用docker安装1.1 配置docker1. 2 拉取 LLaMA-Factory1.3 修改配置 2. 下载模型3. 准备训练数据3.1 下载数据集3.2 自定义数据集配置 4. 训练4.1 训练配置4.2 启动训练4.3 训练效果测试 5. 合并权重 更好的阅读体验:传送门 服务器:800TA2 芯…...
Python自动化解决滑块验证码的最佳实践
1. 引言:滑块验证码的挑战与自动化需求 滑块验证码(Slider CAPTCHA)是当前互联网广泛使用的反爬机制之一,它要求用户手动拖动滑块到指定位置以完成验证。这种验证方式可以有效阻止简单的自动化脚本,但对爬虫开发者来说…...
知识蒸馏和迁移学习的区别
知识蒸馏和迁移学习虽然都涉及知识的传递,但并不是同一个概念,它们在目的、方法和应用场景上有显著区别: 1. 定义与核心思想 迁移学习(Transfer Learning) 是一种广义的机器学习范式,核心是将从一个任务或领…...
二项分布详解:从基础到应用
二项分布详解:从基础到应用 目录 引言二项分布的定义概率质量函数及其证明期望与方差推导二项分布的重要性质常见应用场景与其他分布的关系知识梳理练习与思考 引言 概率论中,二项分布是最基础也是最常用的离散概率分布之一。它描述了在固定次数的独…...
迁移学习(基础)
迁移学习理论 目标 迁移学习中的有关概念掌握迁移学习的两种方式 概念 预训练模型微调微调脚本 预训练模型(Pretrained model) 一般情况下预训练模型都是大型模型, 具备复杂的网络结构, 众多的参数量, 以及足够大的数据集进行训练而产生的模型, 在NLP领域, 预训练模型往往…...
云服务器和独立服务器的区别在哪
在当今数字化的时代,服务器成为了支撑各种业务和应用的重要基石。而在服务器的领域中,云服务器和独立服务器是两个备受关注的选项。那么,它们到底有何区别呢? 首先,让我们来聊聊成本。云服务器通常采用按需付费的模式…...
大模型时代的深度学习框架
作者:算力魔方创始人/英特尔创新大使刘力 在CNN时代,AI模型的参数规模都在百万级别,仅需在单张消费类显卡上即可完成训练。例如,以业界知名的CNN模型:ResNet50为例,模型参数量是约为 25.63M,在…...
BIOS主板(非UEFI)安装fedora42的方法
BIOS主板(非UEFI)安装fedora42的方法 现实困难:将Fedora-Workstation-Live-42-1.1.x86_64.iso写入U盘制作成可启动U盘启动fedora42,按照向导将fedora42安装到真机的sda7分区中得到报错如下内容: /boot/efi 必需的 /boot/efi必须位于格式化为e…...
C# 综合示例 库存管理系统7 主界面(FormMain)
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的 图99A-22 主界面窗口设计 主界面是多文档界面容器,需要将窗体属性IsMdiContainer设置为True。关于多文档界面编程请参看教程第7.12节《多文档界面》。 主界面并不提…...
1、RabbitMQ的概述笔记
一、什么是RabbitMQ Rabbit是一个公司名.MQ(nessage queue) 消息队列的意思,RabbitMQ 是 Rabbit企业下的一个消息队列产品。 RabbitMQ 是⼀个实现了 AMQP 的 消息队列 服务,是当前主流的消息中间件之⼀. AMQP:即Advanced MessageQueuingProtocol(高级…...
使用spring boot vue 上传mp4转码为dash并播放
1.前端实现 <template><div class"video-upload"><el-uploadclass"upload-demo"action"/api/upload":before-upload"beforeUpload":on-success"handleSuccess":on-error"handleError":show-file-…...
C++智能指针概念理解的面试题
C智能指针概念理解的面试题 第一部分:基础概念 解释std::unique_ptr和std::shared_ptr在以下方面的区别: 所有权语义性能开销自定义删除器的存储方式是否支持数组类型 答案: 所有权语义: unique_ptr:独占所有权&#…...
52.[前端开发-JS实战框架应用]Day03-AJAX-插件开发-备课项目实战-Lodash
常用JavaScript库 1 认识前端工具库 前端工具类库 2 Lodash vs underscore underscore库 VS Lodash库 Lodash库 的安装 Lodash库字符串、数组 Lodash库对象、集合、函数 3 Day.js vs Mement Moment.js库 VS Day.js库 Day.js库安装 Day.js获取、设置、操作时间 Day.js解析、…...