【9.1】Golang后端开发系列--Gin快速入门指南
文章目录
- 一、引言 🌟
- 二、Gin 框架概述 📖
- (一)什么是 Gin
- (二)为什么选择 Gin
- 三、安装 Gin 框架 📦
- (一)安装 Go 语言环境
- (二)使用 Go Modules 安装 Gin
- 四、路由基础 🌐
- (一)基本路由定义
- (二)路由参数
- (三)查询参数
- 五、请求处理和响应 📨
- (一)处理 JSON 数据
- (二)处理表单数据
- 六、中间件的使用 🛡️
- (一)内置中间件
- (二)中间件的执行顺序
- 七、模板渲染 🎨
- (一)使用 HTML 模板
- (二)模板语法和数据传递
- 八、错误处理 ❌
- (一)自定义错误处理
- (二)全局错误处理
- 九、文件上传和下载 📁
- (一)文件上传
一、引言 🌟
在当今的后端开发领域,Go 语言凭借其高效、简洁和强大的并发特性备受开发者青睐。而 Gin 框架更是 Go 语言中构建 Web 服务的利器,它以轻量级和高性能著称,让开发者能够快速搭建功能强大的后端服务。使用 Gin 框架,就像拥有了一把神奇的魔法棒,能将我们的开发效率提升到一个新的高度,轻松应对各种复杂的 Web 应用需求。让我们开启 Gin 后端开发的奇妙之旅吧 🌈
二、Gin 框架概述 📖
(一)什么是 Gin
Gin 是一个用 Go 语言编写的 HTTP Web 框架,它提供了类似于 Martini 框架的 API,但性能更优。Gin 采用了高效的路由和中间件机制,允许开发者快速构建 RESTful API 和 Web 服务。它的语法简洁明了,能够极大地简化 Web 开发流程,减少样板代码,让我们把更多的精力集中在业务逻辑上。可以将 Gin 看作是一个超级高效的桥梁,连接客户端和服务器端,为我们的 Web 应用提供强大的支撑。用 🚀 图标来代表 Gin 框架的高效性。
(二)为什么选择 Gin
- 性能卓越:Gin 基于 HTTPRouter 构建,具有高性能的路由匹配功能,在处理大量并发请求时表现出色。它使用了高效的路由树算法,能够快速找到对应的处理函数,就像闪电一样快。
- 中间件支持:Gin 提供了强大的中间件支持,方便我们在请求处理的不同阶段添加自定义逻辑,如日志记录、认证、授权等。中间件就像是一个个功能插件,可以灵活地插拔到请求处理的流程中,增强了程序的可扩展性和可维护性。可以用 🛠️ 图标表示中间件的工具属性。
- 简洁易用:Gin 的 API 设计简洁直观,容易上手,对于新手来说非常友好。其代码结构清晰,使得开发过程更加流畅,能够让我们快速构建出功能完善的 Web 服务。
三、安装 Gin 框架 📦
(一)安装 Go 语言环境
首先,确保你已经安装了 Go 语言环境。你可以从 Go 官方网站 下载并安装最新版本的 Go。安装完成后,可以通过以下命令检查 Go 版本:
go version
(二)使用 Go Modules 安装 Gin
在 Go 1.11 及以上版本中,推荐使用 Go Modules 来管理依赖。创建一个新的 Go 项目,并初始化 Go Modules:
mkdir gin-example
cd gin-example
go mod init example.com/gin-example
然后,使用以下命令安装 Gin 框架:
go get -u github.com/gin-gonic/gin
这个命令会将 Gin 及其依赖添加到你的项目中。可以使用 go.mod
文件查看项目的依赖情况。
以下是一个简单的代码示例,用于检查 Gin 是否安装成功:
package mainimport ("github.com/gin-gonic/gin"
)func main() {// 创建一个默认的 Gin 引擎r := gin.Default()// 启动服务,监听在 8080 端口r.Run(":8080")
}
在上述代码中:
gin.Default()
创建了一个默认的 Gin 引擎,这个引擎包含了一些常用的中间件,如日志记录和恢复机制。r.Run(":8080")
启动了一个 HTTP 服务器,监听在 8080 端口。
运行代码:
go run main.go
如果一切正常,你会看到服务器启动的日志信息,并且可以在浏览器中访问 http://localhost:8080
,虽然此时它只会返回 404 错误,因为我们还没有定义路由。
四、路由基础 🌐
(一)基本路由定义
路由是将 HTTP 请求映射到相应处理函数的机制。在 Gin 中,我们可以轻松定义路由。以下是一些基本路由的示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// GET 请求路由r.GET("/hello", func(c *gin.Context) {c.String(http.StatusOK, "Hello, Gin!")})// POST 请求路由r.POST("/create", func(c *gin.Context) {c.String(http.StatusCreated, "Created")})// 启动服务,监听在 8080 端口r.Run(":8080")
}
在这个示例中:
r.GET("/hello", func(c *gin.Context) {...})
定义了一个处理 GET 请求的路由,当访问/hello
路径时,会调用相应的处理函数。c.String(http.StatusOK, "Hello, Gin!")
使用gin.Context
的String
方法发送一个带有状态码和响应内容的响应。- 类似地,
r.POST("/create", func(c *gin.Context) {...})
定义了一个处理 POST 请求的路由。
(二)路由参数
我们可以在路由中定义参数,以便从 URL 中获取动态信息。以下是一个示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// 定义带参数的路由r.GET("/user/:id", func(c *gin.Context) {id := c.Param("id")c.String(http.StatusOK, "User ID: %s", id)})r.Run(":8080")
}
在这个代码中:
r.GET("/user/:id", func(c *gin.Context) {...})
中的:id
是一个路由参数。c.Param("id")
从gin.Context
中获取id
参数的值。
(三)查询参数
除了路由参数,我们还可以使用查询参数,就像在 URL 中添加 ?key=value
的部分。以下是一个示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.GET("/search", func(c *gin.Context) {query := c.Query("q")c.String(http.StatusOK, "Search query: %s", query)})r.Run(":8080")
}
在这个示例中:
c.Query("q")
从查询参数中获取q
的值。
五、请求处理和响应 📨
(一)处理 JSON 数据
在实际开发中,处理 JSON 数据是很常见的。以下是如何接收和发送 JSON 数据的示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)type User struct {Name string `json:"name"`Age int `json:"age"`Email string `json:"email"`
}func main() {r := gin.Default()// 发送 JSON 数据r.GET("/user", func(c *gin.Context) {user := User{Name: "Alice",Age: 25,Email: "alice@example.com",}c.JSON(http.StatusOK, user)})// 接收 JSON 数据r.POST("/user", func(c *gin.Context) {var newUser Userif err := c.ShouldBindJSON(&newUser); err == nil {c.JSON(http.StatusCreated, gin.H{"message": "User created","user": newUser,})} else {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),})}})r.Run(":8080")
}
在这个示例中:
c.JSON(http.StatusOK, user)
发送一个 JSON 格式的响应。c.ShouldBindJSON(&newUser)
从请求中解析 JSON 数据到User
结构体中。
(二)处理表单数据
处理表单数据也是常见的需求,以下是一个示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.POST("/form", func(c *gin.Context) {username := c.PostForm("username")password := c.PostForm("password")c.String(http.StatusOK, "Username: %s, Password: %s", username, password)})r.Run(":8080")
}
在这个代码中:
c.PostForm("username")
和c.PostForm("password")
分别从表单中获取username
和password
的值。
六、中间件的使用 🛡️
(一)内置中间件
Gin 自带了一些内置的中间件,如日志记录和恢复中间件。以下是如何使用自定义中间件的示例:
package mainimport ("github.com/gin-gonic/gin""log""time"
)func Logger() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()// 处理请求c.Next()// 计算处理时间duration := time.Since(start)log.Printf("Request processed in %v", duration)}
}func main() {r := gin.Default()// 使用自定义中间件r.Use(Logger())r.GET("/middleware", func(c *gin.Context) {c.String(200, "This is a middleware example")})r.Run(":8080")
}
在这个示例中:
Logger
是一个自定义中间件函数,它在请求处理前后记录时间并计算处理时长。r.Use(Logger())
将自定义中间件添加到路由组中。
(二)中间件的执行顺序
中间件的执行顺序非常重要。以下是一个示例,展示多个中间件的执行顺序:
package mainimport ("github.com/gin-gonic/gin""log""time"
)func FirstMiddleware() gin.HandlerFunc {return func(c *gin.Context) {log.Println("First middleware: before")c.Next()log.Println("First middleware: after")}
}func SecondMiddleware() gin.HandlerFunc {return func(c *gin.Context) {log.Println("Second middleware: before")c.Next()log.Println("Second middleware: after")}
}func main() {r := gin.Default()r.Use(FirstMiddleware())r.Use(SecondMiddleware())r.GET("/middleware-order", func(c *gin.Context) {c.String(200, "Middleware order example")})r.Run(":8080")
}
在这个示例中:
- 当请求
/middleware-order
时,你会看到中间件的执行顺序是按照添加顺序进行的,同时c.Next()
控制着请求继续向下传递。
七、模板渲染 🎨
(一)使用 HTML 模板
Gin 支持 HTML 模板渲染,以下是一个简单的示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// 加载模板文件r.LoadHTMLGlob("templates/*.html")r.GET("/html", func(c *gin.Context) {c.HTML(http.StatusOK, "index.html", gin.H{"title": "Gin HTML Template",})})r.Run(":8080")
}
在这个示例中:
r.LoadHTMLGlob("templates/*.html")
加载templates
目录下的所有 HTML 模板文件。c.HTML(http.StatusOK, "index.html", gin.H{"title": "Gin HTML Template"})
渲染index.html
模板并传递数据。
你需要在 templates
目录下创建一个 index.html
文件,例如:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>{{.title }}</title>
</head>
<body><h1>{{.title }}</h1><p>Welcome to Gin HTML Template!</p>
</body>
</html>
(二)模板语法和数据传递
在 HTML 模板中,可以使用 Go 的模板语法传递和显示数据。以下是一个更复杂的示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// 加载模板文件r.LoadHTMLGlob("templates/*.html")r.GET("/user", func(c *gin.Context) {users := []string{"Alice", "Bob", "Charlie"}c.HTML(http.StatusOK, "user.html", gin.H{"users": users,})})r.Run(":8080")
}
在 templates
目录下的 user.html
文件可以这样写:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>User List</title>
</head>
<body><h1>User List</h1><ul>{{ range.users }}<li>{{. }}</li>{{ end }}</ul>
</body>
</html>
在这个示例中:
{{ range.users }}...{{ end }}
是 Go 的模板语法,用于遍历users
切片并生成列表项。
八、错误处理 ❌
(一)自定义错误处理
我们可以在 Gin 中自定义错误处理,以下是一个示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// 自定义 404 错误处理r.NoRoute(func(c *gin.Context) {c.JSON(http.StatusNotFound, gin.H{"error": "Page not found",})})// 自定义 500 错误处理r.NoError(func(c *gin.Context, err interface{}) {c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error",})})r.Run(":8080")
}
在这个示例中:
r.NoRoute(func(c *gin.Context) {...})
自定义了 404 错误的处理逻辑。r.NoError(func(c *gin.Context, err interface{}) {...})
自定义了 500 错误的处理逻辑。
(二)全局错误处理
我们也可以设置全局的错误处理中间件,以下是一个示例:
package mainimport ("github.com/gin-gonic/gin""log""net/http"
)func ErrorHandler() gin.HandlerFunc {return func(c *gin.Context) {defer func() {if err := recover(); err!= nil {log.Printf("Error occurred: %v", err)c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error",})}}()c.Next()}
}func main() {r := gin.Default()// 添加全局错误处理中间件r.Use(ErrorHandler())r.GET("/error", func(c *gin.Context) {// 模拟一个错误panic("Something went wrong")})r.Run(":8080")
}
在这个示例中:
ErrorHandler
中间件使用recover
来捕获panic
,并将其转换为一个错误响应。
九、文件上传和下载 📁
(一)文件上传
以下是一个文件上传的示例:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.POST("/upload", func(c *gin.Context) {file, err := c.FormFile("file")if err!= nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}// 保存文件c.SaveUploadedFile(file, "./uploads/"+file.Filename)c.JSON(http.StatusOK, gin.H{"message": "File uploaded successfully"})})r.Run(":8080")
}
在这个示例中:
c.FormFile("file")
从请求中获取上传的文件。c.SaveUploadedFile(file, "./uploads/"+file.Filename)
将文件保存到uploads
目录
相关文章:
【9.1】Golang后端开发系列--Gin快速入门指南
文章目录 一、引言 🌟二、Gin 框架概述 📖(一)什么是 Gin(二)为什么选择 Gin 三、安装 Gin 框架 📦(一)安装 Go 语言环境(二)使用 Go Modules 安装…...
电商系统,核心通用架构案例设计方案浅析
文章目录 一、用户系统案例设计1、用户信息的存储方案2、用户注册确保唯一3、用户数据合并方案4、用户敏感信息加密存储5、数据传输安全性6、多用户数据隔离性7、防止恶意注册8、用户好友关系存储方案9、用户登录token方案10、会员优先处理设计 二、网关系统设计1、网关的功能2…...
易飞ERP 9.2 安装包 百度云盘 下载
易飞9.2是鼎捷数智依托四十多年实践经验,面向中小企业的全面ERP解决方案。 以下是关于易飞9.2的详细介绍: 发布与更新: 发布时间:易飞V9.2新版发布于2023年9月。 核心功能: 便捷高效࿱…...
3D目标检测数据集——Waymo数据集
Waymo数据集簡介 发布首页:https://waymo.com/open/ 论文:https://openaccess.thecvf.com/content_CVPR_2020/papers/Sun_Scalability_in_Perception_for_Autonomous_Driving_Waymo_Open_Dataset_CVPR_2020_paper.pdf github:https://github.…...
LSA更新、撤销
LSA的新旧判断: 1.seq,值越大越优先 2.chksum,值越大越优先 3.age,本地的LSA age和收到的LSA age作比较 如果差值<900s,认为age一致,保留本地的:我本地有一条LSA是100 你给的是400 差值小于…...
Redis复制(replica)
Redis主从复制 [Redis主从复制](replica)是一个多Redis实例进行数据同步的过程,其中一个实例是主实例(Master),其他实例是从实例(Slave)。主实例负责处理命令请求,而从实…...
Ubuntu上,ffmpeg如何使用cuda硬件解码、编码、转码加速
本文使用 Ubuntu 环境。Ubuntu 直接使用 APT 安装的就支持 CUDA 加速。本文使用这样下载的版本进行演示,你自己编译或者其他源的版本可能会不同。 ffmpeg 的一些介绍,以及 macOS 版本的 ffmpeg 硬件加速请见《macOS上如何安装(不需要编译安装…...
磁盘满造成业务异常问题排查
最近遇到一个因为磁盘满导致的问题,分享一下,希望能够帮助到以后遇到同样问题的朋友。 早上突然收到业务老师反馈说:上传文件不能正常上传了。 想想之前都好好的,最近又没有更新,为什么突然不能使用了呢?…...
vim基本命令(vi、工作模式、普通模式、插入模式、可视模式、命令行模式、复制、粘贴、插入、删除、查找、替换)
1. Vim的作用 1.1. 文本编辑 1.1.1. 基础文本编辑功能 Vim是一个功能强大的文本编辑器,它可以用来创建、修改和保存各种文本文件。无论是编写简单的文本笔记,还是复杂的代码文件,Vim都能胜任。例如,我们可以用它来编写Python脚…...
vue的KeepAlive应用(针对全部页面及单一页面进行缓存)
KeepAlive的作用是缓存包裹在其中的动态切换组件 当一个组件在 中被切换时,它的 activated 和 deactivated 生命周期钩子将被调用,用来替代 mounted 和 unmounted。这适用于 的直接子节点及其所有子孙节点。 缓存全部页面 将app.vue中的路由出口改为&am…...
Big Model weekly | 第53期
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 01 CodeRosetta: Pushing the Boundaries of Unsupervised Code Translation for Parallel Programming 近期在大型语言模型(LLMs)的进展重新激发了自动编程语言翻译的兴趣。特别是编码器…...
基于STM32设计的粮食仓库(粮仓)环境监测系统
一、前言 1.1 项目开发背景 随着现代农业的发展和粮食储存规模的扩大,粮仓环境的智能化监控需求日益增长。传统的粮仓管理方式通常依赖人工检测和定期巡查,效率低下且容易出现疏漏,无法及时发现潜在问题,可能导致粮食受潮、霉变…...
大数据技术Kafka详解 ⑤ | Kafka中的CAP机制
目录 1、分布式系统当中的CAP理论 1.1、CAP理论 1.2、Partitiontolerance 1.3、Consistency 1.4、Availability 2、Kafka中的CAP机制 C软件异常排查从入门到精通系列教程(核心精品专栏,订阅量已达600多个,欢迎订阅,持续更新…...
44.ComboBox的数据绑定 C#例子 WPF例子
固定最简步骤,包括 XAML: 题头里引入命名空间 标题下面引入类 combobox绑定资源属性和选择属性,block则绑定和combobox一样的选择属性 C#: 通知的类,及对应固定的任务 引入字段 引入属性 其中资源是只读的 选…...
SOLID原则学习,接口隔离原则(Interface Segregation Principle, ISP)
文章目录 1. 定义2. 为什么要遵循接口隔离原则?3. 违反接口隔离原则的例子4. 遵循接口隔离原则的改进5. 总结 1. 定义 接口隔离原则(Interface Segregation Principle, ISP) 接口隔离原则是面向对象设计中的五大原则(SOLID&#…...
Spring Boot Web技术栈(官网文档解读)
摘要 Spring Boot框架既支持传统的Servlet技术栈,也支持新兴的响应式(Reactive)技术栈。本篇文章将详细讲述Spring Boot 对两种技术栈的详细支持和使用。 Servlet 概述 基于Java Servlet API构建,它依赖于传统的阻塞I/O模型&…...
闲谭SpringBoot--ShardingSphere分布式事务探究
文章目录 0. 背景1. 未分库分表时2. 仅分表时3. 分库分表时3.1 不涉及分库表3.2 涉及分库表,且分库表处于一个库3.3 涉及分库表,且分库表处于多个库3.4 涉及分库表,且运行中某库停机 4. 小结 0. 背景 接上篇文章《闲谭SpringBoot–ShardingS…...
计算机网络之---TCP报文段
TCP报文段 TCP报文段是TCP协议中传输数据的基本单位。TCP协议基于流控制、顺序控制和错误校验等机制,以确保数据的可靠传输。TCP报文段结构由多个字段组成,每个字段在TCP的工作中都有特定的作用 一个典型的TCP报文段由两部分组成: TCP头部&a…...
USB 驱动开发 --- Gadget 驱动框架梳理(一)
本文由 Linux 内核文档翻译与总结而来,个人学习笔记仅供参考。 Gadget 框架 在 USB 协议交互过程中,角色定义: the device driver is the master (or “client driver”) Linux 内核中称为 HCD(Host Controller Driver),负责与 …...
C#读写ini配置文件保存设置参数
本示例使用设备:https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1b5P5rkA&ftt&id22173428704 [DllImport("kernel32", CharSet CharSet.Unicode)] public static extern uint GetPrivateProfileString(string lpAppName, stri…...
Linux---history查看命令历史记录命令
history命令是Linux系统中用于显示和管理用户之前执行过的命令列表的实用工具。以下是history命令的详细教程: 一、基本功能 history命令能够显示用户在当前shell会话或之前会话中执行过的所有命令。这对于回顾之前的操作、复制某个命令进行修改再次执行等场景非常…...
CANopen 学习笔记(2)
PDO通讯参数 异步传输 发送类型设置为0xFE或0xFF 修改映射参数后执行sendPDOevent(&CanFestival_Master_Data); /* 发送PDO事件 */则会触发PDO传输 还有一直就是定时器异步发送,配置发送类型为0xFE,定时器发送时间为0x64,则会以100ms的周期发送P…...
《鸿蒙Next旅游应用:人工智能赋能个性化与智能导览新体验》
随着鸿蒙Next的推出,旅游应用迎来了全新的发展机遇,借助人工智能技术能为用户带来更出色的个性化推荐和智能导览服务。 鸿蒙Next与人工智能融合优势 鸿蒙Next拥有强大的分布式能力和原生智能体验。其能打破设备界限,实现多设备协同…...
计算机网络 (39)TCP的运输连接管理
前言 TCP(传输控制协议)是一种面向连接的、可靠的传输协议,它在计算机网络中扮演着至关重要的角色。TCP的运输连接管理涉及连接建立、数据传送和连接释放三个阶段。 一、TCP的连接建立 TCP的连接建立采用三次握手机制,其过程如下&…...
Level2逐笔成交逐笔委托毫秒记录:今日分享优质股票数据20250114
逐笔成交逐笔委托下载 链接: https://pan.baidu.com/s/18YtQiLnt06cPQP1nRXor0g?pwd4k3h 提取码: 4k3h Level2逐笔成交逐笔委托数据分享下载 基于Level2的逐笔成交和逐笔委托数据,这种毫秒级别的记录能分析出许多关键信息,如庄家意图、虚假动作&#…...
探索Java(适合小白)
探索Java:推动数字世界的语言 Java,这一编程语言在信息技术的海洋中如同明珠般闪耀,吸引着无数程序员的关注与热爱。在今天的博客中,我们将深入了解Java的定义、学习的重要性,并详细探讨Java EE的概念。无论你是编程新…...
Java Web开发高级——Spring Boot与微服务架构
微服务架构(Microservices Architecture)已经成为现代软件开发中的主流架构之一。它通过将单一的、庞大的应用程序拆分成多个小的、独立部署的服务,使得开发、维护和扩展变得更加灵活、可控。Spring Boot 提供了一种简单且高效的方式来构建微…...
IMX6U Qt 开发环境
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、交叉编译 1. 安装通用 ARM 交叉编译工具链 2. 安装 Poky 交叉编译工具链 二、编译出厂源码 1. U-boot 2. 内核和模块 3. 编译出厂 Qt GUI 综合 Demo 前言…...
【计算机网络】lab5 ARP协议
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀计算机网络_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2.…...
基于深度学习的视觉检测小项目(十三) 资源文件的生成和调用
在使用 PySide6 进行开发时,管理应用程序的资源(如图标、图片、字体、样式表、音视频等)是一个常见的任务。PySide6 提供了一个工具 pyside6-rcc,它能够将资源文件(.qrc)编译成 Python 模块,然后…...
【C】初阶数据结构3 -- 单链表
之前在顺序表那一篇文章中,提到顺序表具有的缺点,比如头插,头删时间复杂度为O(n),realloc增容有消耗等。而在链表中,这些问题将得到解决。所以在这一篇文章里,我们将会讲解链表的定义与性质,以及…...
STM32 FreeRTOS 基础知识
多任务处理 内核是操作系统的核心组件。诸如 Linux 这样的操作系统采用的内核, 看似允许用户同时访问计算机。很明显,多个用户可以同时执行多个程序。 每个执行程序都是受操作系统控制的任务(或线程)。如果一个操作系统能够以这…...
初学stm32 --- II2C_AT24C02,向EEPROM中读写数据
目录 IIC总线协议介绍 IIC总线结构图 IIC协议时序 1. ACK(Acknowledge) 2. NACK(Not Acknowledge) IO口模拟II2C协议 发送起始信号: 发送停止信号: 检测应答信号: 发送应答信号&#x…...
探索图像编辑的无限可能——Adobe Photoshop全解析
文章目录 前言一、PS的历史二、PS的应用场景三、PS的功能及工具用法四、图层的概念五、调整与滤镜六、创建蒙版七、绘制形状与路径八、实战练习结语 前言 在当今数字化的世界里,视觉内容无处不在,而创建和编辑这些内容的能力已经成为许多行业的核心技能…...
当comfyui-reactor-node 安装失败urllib.error.HTTPError: HTTP Error 403: Forbidden解决方法
comfyUI 节点comfyui-reactor-node 安装 python install 时 报错 urllib.error.HTTPError: HTTP Error 403: Forbidden 如下: (xxx) xxxxxxx:~/sdb/Q/ComfyUI/custom_nodes/comfyui-reactor-node$ python install.py Traceback (most recent call last): File …...
01基本介绍篇(D2_多线程问题)
目录 一、线程的上下文切换问题 1. 基本介绍 2. 多线程一定比单线程快? 3. 如何减少上下文切换 二、线程安全问题 1. 什么是线程安全? 2. java语言中的线程安全 2.1. 不可变 2.2. 绝对线程安全 2.3. 相对线程安全 2.4. 线程兼容 2.5. 线程对立…...
如何保证光谱相机的稳定性和可靠性
光学系统设计与制造 高质量光学元件:采用高精度研磨和镀膜的透镜、棱镜、光栅等光学元件。优质的透镜可以减少像差和色差,确保光线准确聚焦;高质量的镀膜能够提高光学元件的透光率,降低反射损失,并且增强对不同波段光…...
基于springboot+vue的洪涝灾害应急信息管理系统设计与实现
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
登录、注册、忘记密码、首页HTML模板
<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>登录</title><style>body {display: fl…...
HTML文章翻页功能
效果展示: 效果原理: 1、引入CDN 2、绘制文章翻页样式,以及自动分段 3、获取窗口宽高,计算出当前文章总分段,并实现分页 4、完整代码 <!DOCTYPE html> <html><head><meta charset"utf-8&qu…...
JAVA安全编码规范
1. 数据校验 对外部输入进行校验入参的合法性, 防止内存越界,命令注入,SQL注入,格式化字符串漏洞 校验长度,范围,输入校验采用白名单形式 校验前做归一化处理,使用java.text.Normalizer的n…...
OpenGL —— 基于Qt的视频播放器 - ffmpeg硬解码,QOpenGL渲染yuv420p或nv12视频(附源码)
运行效果 工程说明 源码 vertex.glsl...
爬虫逆向学习(十五):Akamai 3.0反爬分析与sensor-data算法逆向经验
此分享只用于学习用途,不作商业用途,若有冒犯,请联系处理 Akamai 3.0反爬分析与sensor-data算法逆向经验 Akamai开始正题前须知站点信息接口分析反爬点反爬点定位_abck定位结果 逆向前准备工作sensor_data生成位置本地替换文件 请求体sensor…...
java项目启动时,执行某方法
1. J2EE项目 在Servlet类中重写init()方法,这个方法会在Servlet实例化时调用,即项目启动时调用。 import javax.servlet.ServletException; import javax.servlet.http.HttpServlet;public class MyServlet extends HttpServlet {Overridepublic void …...
学会使用开源软件jclasslib 字节码文件的组成 详解
应用场景 1 应用场景 2 学习路线 以正确的姿势打开文件 字节码文件的组成 玩转字节码常用工具 以正确的姿势打开文件 开源软件 jclasslib github 地址 https://github.com/ingokegel/jclasslib 工具使用 字节码文件的组成 基本信息 常量池 字段 方法 属性 详解 魔数 主副版…...
Flask表单处理与验证
Flask是一个轻量级的Python框架,它通过扩展库提供了对表单处理与验证的支持。WTForms是一个流行的Flask扩展库,用于创建和验证Web表单。它提供了一种声明式的方法来定义表单结构和验证逻辑,使得表单处理更为简洁和优雅。下面,我们…...
如何通俗易懂的理解 html js css
HTML、CSS 和 JavaScript 是构建网页的三大核心技术。为了通俗易懂地理解它们,我们可以用一个简单的比喻:**盖房子**。 --- ### 1. **HTML:房子的结构** HTML(HyperText Markup Language)就像房子的**骨架**。它定义…...
信凯科技业绩波动明显:毛利率远弱行业,资产负债率偏高
《港湾商业观察》施子夫 1月8日,深交所官网显示,浙江信凯科技集团股份有限公司(以下简称“信凯科技”)主板IPO提交注册。 自2022年递交上市申请,信凯科技的IPO之路已走过两年光景,尽管提交注册࿰…...
蓝牙BT04-A的使用与相关AT指令
一、AT指令没有返回的问题及解决方案 检查指令格式: 确认指令格式是否正确,包括特定的命令和结尾的回车换行符(n)。 检查TX/RX连接: 确认TX(发送)和RX(接收)线是否连接正…...
新手如何练习SQL?|掌握
对于新手想要练习SQL语句,可以从以下几个方面入手: 1. 建立理论基础 首先深入理解数据库的核心组件,包括数据库本身、其内部的各个表、表中的字段及其对应的数据类型(如字符串、整型、日期等),以及数据库…...