【Go】面向萌新的Gin框架知识梳理学习笔记
目录
Gin框架简介
路由&路由组
1. 定义基本路由
2. 参数传递
3. 查询字符串参数
4. 路由组
5. 路由中间件
模板渲染
1. 加载模板
2. 定义模板
3. 渲染模板
4. 自定义模板函数
返回json
1. 导入 Gin 包
2. 创建 Gin 引擎
3. 定义路由和处理器函数
4. 运行服务器
获取参数
1.获取 QueryString 参数
2.获取 Form 参数
3.获取 URL 路径参数
参数绑定
1. 绑定 JSON 数据
2. 绑定 Form 表单数据
3. 绑定 Query 参数
请求重定向
1. 重定向到指定 URL
2. 重定向到命名路由
3. 重定向到相对路径
4. 重定向的状态码
中间件
1. 中间件的基本概念
2. 注册中间件
3. 在特定路由或路由组中使用中间件
4. 中间件链
5. 中间件的顺序
文件上传
1. 单个文件上传
2. 多个文件上传
3. 限制文件大小
Gin框架简介
Gin 是一个用 Go 语言编写的 Web 框架,它提供了一组强大的工具和功能,用于快速构建高性能的 Web 应用程序和 API。
路由&路由组
在 Gin 框架中,路由(Routes)用于定义客户端请求的 URL 和处理器函数之间的映射关系。通过路由,可以将特定的 URL 请求映射到相应的处理器函数,从而实现 Web 应用的功能。Gin 框架提供了灵活而强大的路由功能,同时支持路由组(Route Groups),可以方便地对多个相关的路由进行分组管理。下面详细介绍 Gin 框架的路由和路由组:
1. 定义基本路由
在 Gin 中,通过调用 GET
、POST
、PUT
、DELETE
等方法可以定义不同 HTTP 方法的路由,并指定相应的处理器函数。
import "github.com/gin-gonic/gin"func main() {router := gin.Default()// GET 请求router.GET("/hello", func(c *gin.Context) {c.String(200, "Hello, Gin!")})// POST 请求router.POST("/user", func(c *gin.Context) {// 处理 POST 请求})router.Run(":8080")
}
2. 参数传递
通过路由可以传递 URL 参数,参数可以通过 gin.Context
对象的方法来获取。
router.GET("/hello/:name", func(c *gin.Context) {name := c.Param("name")c.String(200, "Hello, %s!", name)
})
3. 查询字符串参数
可以使用 Query
方法获取查询字符串参数。
router.GET("/user", func(c *gin.Context) {name := c.Query("name")age := c.Query("age")c.String(200, "Name: %s, Age: %s", name, age)
})
4. 路由组
路由组允许将一组相关的路由进行分组管理,提高代码的可读性和维护性。
api := router.Group("/api")
{api.GET("/users", func(c *gin.Context) {// 处理获取用户列表的请求})api.POST("/users", func(c *gin.Context) {// 处理创建用户的请求})
}
5. 路由中间件
可以为路由或路由组添加中间件,以实现对特定路由的预处理或后处理操作。
router.GET("/admin", AuthMiddleware, func(c *gin.Context) {// 处理需要身份验证的请求
})func AuthMiddleware(c *gin.Context) {// 身份验证逻辑
}
模板渲染
Gin 框架提供了强大的模板渲染功能,允许开发者将动态数据嵌入到 HTML 模板中,从而生成响应客户端请求的动态网页。以下是如何在 Gin 中使用模板渲染的详细介绍:
1. 加载模板
在使用 Gin 渲染模板之前,首先需要加载模板文件。Gin 提供了多种加载模板的方法,可以加载单个文件、加载指定目录下的所有文件等。
- 加载单个模板文件:
router.LoadHTMLFiles("templates/index.html")
- 加载指定目录下的所有模板文件:
router.LoadHTMLGlob("templates/*")
2. 定义模板
模板文件通常是 .html
文件,里面可以包含静态的 HTML 标签,也可以包含用于动态数据绑定的模板语法。Gin 使用 Go 标准库的 html/template
包作为模板引擎,支持所有 html/template
的功能。
假设我们有一个模板文件 templates/index.html
,内容如下:
<html>
<body><h1>Hello, {{ .Name }}!</h1>
</body>
</html>
这里 {{ .Name }}
是一个模板动作,它会在模板渲染时被替换成具体的值。
3. 渲染模板
在定义了模板文件之后,就可以在处理器函数中使用 HTML
方法来渲染模板了。这个方法接受 HTTP 状态码、模板文件名和传递给模板的数据作为参数。
router.GET("/", func(c *gin.Context) {c.HTML(200, "index.html", gin.H{"Name": "Gin",})
})
在这个例子中,我们渲染了之前定义的 index.html
模板,并传递了一个包含 Name
字段的数据。在模板中,{{ .Name }}
会被替换成 "Gin"。
4. 自定义模板函数
Gin 允许开发者定义自己的模板函数,以便在模板中执行更复杂的操作。可以通过 FuncMap
类型来定义模板函数,并在加载模板之前使用 SetFuncMap
方法将其注册到模板引擎。
func formatAsDate(t time.Time) string {year, month, day := t.Date()return fmt.Sprintf("%d/%02d/%02d", year, month, day)
}router := gin.Default()
router.SetFuncMap(template.FuncMap{"formatAsDate": formatAsDate,
})
router.LoadHTMLGlob("templates/*")
在模板中使用自定义函数:
<div>Date: {{ .Date | formatAsDate }}</div>
返回json
在 Gin 框架中,返回 JSON 数据非常简单。Gin 提供了方便的方法来渲染和返回 JSON 响应。以下是详细介绍如何在 Gin 中返回 JSON 数据的步骤:
1. 导入 Gin 包
首先,确保你已经安装了 Gin 框架,并导入 Gin 包到你的 Go 项目中:
import "github.com/gin-gonic/gin"
2. 创建 Gin 引擎
接着,创建一个 Gin 引擎,通常可以选择 gin.Default()
来创建一个默认的引擎:
router := gin.Default()
3. 定义路由和处理器函数
在 Gin 中,你可以使用不同的 HTTP 方法来定义路由,并指定处理该路由的函数。对于返回 JSON 数据的处理器函数,通常会使用 c.JSON()
方法来渲染 JSON 数据并发送响应。
router.GET("/user/:id", func(c *gin.Context) {id := c.Param("id")// 从数据库或其他地方获取用户信息user := getUserByID(id)// 返回 JSON 响应c.JSON(http.StatusOK, gin.H{"id": user.ID,"name": user.Name,"age": user.Age,})
})
在这个例子中,我们定义了一个 GET 请求的路由 /user/:id
,并指定了一个处理函数。该处理函数首先从 URL 参数中获取用户的 ID,然后根据该 ID 获取用户信息。最后,使用 c.JSON()
方法将用户信息以 JSON 格式返回给客户端。
4. 运行服务器
最后,使用 router.Run()
方法启动 Gin 服务器,指定监听的端口:
router.Run(":8080")
获取参数
在 Gin 框架中,获取参数可以通过不同的方式,包括获取 QueryString 参数、Form 参数以及 URL 路径参数。
1.获取 QueryString 参数
QueryString 参数是附加在 URL 后面的键值对,形如 ?key1=value1&key2=value2
。在 Gin 中,可以使用 c.Query()
方法来获取 QueryString 参数。
router.GET("/query", func(c *gin.Context) {// 获取名为 "key" 的 QueryString 参数的值key := c.Query("key")c.JSON(http.StatusOK, gin.H{"key": key,})
})
2.获取 Form 参数
Form 参数通常是通过 POST 请求发送的表单数据。在 Gin 中,可以使用 c.PostForm()
方法来获取 Form 参数。
router.POST("/form", func(c *gin.Context) {// 获取名为 "key" 的 Form 参数的值key := c.PostForm("key")c.JSON(http.StatusOK, gin.H{"key": key,})
})
3.获取 URL 路径参数
URL 路径参数是在路由中定义的参数,例如 /user/:id
中的 :id
就是一个 URL 路径参数。在 Gin 中,可以使用 c.Param()
方法来获取 URL 路径参数。
router.GET("/user/:id", func(c *gin.Context) {// 获取名为 "id" 的 URL 路径参数的值id := c.Param("id")c.JSON(http.StatusOK, gin.H{"id": id,})
})
参数绑定
在 Gin 框架中,参数绑定是指将请求中的数据绑定到结构体或其他数据类型的过程。这样可以简化处理请求数据的过程,并提高代码的可读性和可维护性。Gin 框架提供了丰富的参数绑定功能,包括绑定 JSON 数据、Form 表单数据、Query 参数等。
1. 绑定 JSON 数据
在 Gin 中,可以使用 BindJSON
方法将请求中的 JSON 数据绑定到结构体中。
type User struct {Name string `json:"name"`Age int `json:"age"`
}router.POST("/json", func(c *gin.Context) {var user Userif err := c.BindJSON(&user); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, user)
})
2. 绑定 Form 表单数据
可以使用 Bind
或 BindWith
方法将请求中的 Form 表单数据绑定到结构体中。
type LoginForm struct {Username string `form:"username"`Password string `form:"password"`
}router.POST("/form", func(c *gin.Context) {var form LoginFormif err := c.Bind(&form); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"username": form.Username, "password": form.Password})
})
3. 绑定 Query 参数
可以使用 Query
方法将请求中的 Query 参数绑定到结构体中。
type Pagination struct {Page int `form:"page"`Limit int `form:"limit"`
}router.GET("/query", func(c *gin.Context) {var pagination Paginationif err := c.BindQuery(&pagination); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"page": pagination.Page, "limit": pagination.Limit})
})
请求重定向
在 Gin 框架中,可以使用 Redirect
方法进行请求重定向。重定向是指服务器返回一个特定的 HTTP 状态码和一个新的 URL,告诉客户端要重定向到该 URL。下面是在 Gin 框架中进行请求重定向的详细介绍:
1. 重定向到指定 URL
使用 Redirect
方法可以将请求重定向到指定的 URL。例如,将请求重定向到 https://www.example.com/new
:
router.GET("/redirect", func(c *gin.Context) {c.Redirect(http.StatusFound, "https://www.example.com/new")
})
2. 重定向到命名路由
如果你在 Gin 路由中定义了命名路由,你可以使用命名路由来进行重定向。
首先,定义一个命名路由:
router.GET("/hello", func(c *gin.Context) {c.String(http.StatusOK, "Hello, Gin!")
}).Name = "helloRoute"
然后,通过命名路由进行重定向:
router.GET("/redirect", func(c *gin.Context) {// 重定向到名为 "helloRoute" 的路由c.Redirect(http.StatusFound, router.GetRoute("helloRoute").Path)
})
3. 重定向到相对路径
可以将请求重定向到相对于当前路径的另一个路径。例如,将请求重定向到相对路径 /new
:
router.GET("/redirect", func(c *gin.Context) {c.Redirect(http.StatusFound, "/new")
})
4. 重定向的状态码
在调用 Redirect
方法时,需要指定重定向的状态码。常用的状态码包括:
http.StatusMovedPermanently
(301): 永久重定向,客户端应该使用新的 URL 重新发起请求。http.StatusFound
(302): 临时重定向,客户端应该使用新的 URL 重新发起请求。
中间件
在 Gin 框架中,中间件(Middleware)是一种特殊的函数,用于在请求到达处理器之前或之后执行一些预处理或后处理操作。Gin 框架的中间件设计非常灵活,可以用于实现诸如日志记录、身份验证、跨域请求处理等各种功能。下面详细介绍 Gin 框架中的中间件设计:
1. 中间件的基本概念
在 Gin 中,中间件是一个接收 gin.Context
对象作为参数的函数,它可以在处理器函数之前、之后或者两者之间执行一些操作。中间件函数可以调用 c.Next()
方法来将控制权传递给下一个中间件或者处理器函数。
2. 注册中间件
可以通过 Use
方法来注册一个全局中间件,该中间件会对所有的请求生效。
import "github.com/gin-gonic/gin"func main() {router := gin.Default()// 注册全局中间件router.Use(LoggerMiddleware)router.GET("/hello", func(c *gin.Context) {c.String(200, "Hello, Gin!")})router.Run(":8080")
}// 全局中间件函数
func LoggerMiddleware(c *gin.Context) {// 在处理器函数之前执行一些操作,例如记录请求日志fmt.Println("Request received:", c.Request.URL.Path)// 将控制权传递给下一个中间件或者处理器函数c.Next()// 在处理器函数之后执行一些操作fmt.Println("Request handled:", c.Request.URL.Path)
}
3. 在特定路由或路由组中使用中间件
除了注册全局中间件外,还可以在特定的路由或路由组中使用中间件。
func main() {router := gin.Default()// 在特定路由中使用中间件router.GET("/hello", AuthMiddleware, func(c *gin.Context) {c.String(200, "Hello, Gin!")})// 在路由组中使用中间件api := router.Group("/api")api.Use(AuthMiddleware){api.GET("/users", func(c *gin.Context) {c.String(200, "List of users")})}router.Run(":8080")
}// 中间件函数
func AuthMiddleware(c *gin.Context) {// 在这里进行身份验证等操作// 如果验证失败,可以调用 c.Abort() 终止请求处理流程
}
在上述示例中,AuthMiddleware
中间件被应用于 /hello
路由以及 /api
路由组中的所有路由。
4. 中间件链
可以通过多次调用 Use
方法来创建一个中间件链,每个中间件按照注册的顺序依次执行。
func main() {router := gin.Default()// 创建中间件链router.Use(Middleware1, Middleware2, Middleware3)router.GET("/hello", func(c *gin.Context) {c.String(200, "Hello, Gin!")})router.Run(":8080")
}
在这个示例中,Middleware1
、Middleware2
和 Middleware3
将按照注册顺序依次执行。
5. 中间件的顺序
中间件的注册顺序很重要,它决定了中间件的执行顺序。一般情况下,应该将在处理器函数之前执行的操作放在中间件链的前面,而将在处理器函数之后执行的操作放在中间件链的后面。
文件上传
在 Gin 框架中,文件上传是一项常见的任务,通常用于处理用户上传的文件,例如图片、视频、文档等。Gin 框架提供了简单而强大的功能来处理文件上传,下面是 Gin 框架中文件上传的详细介绍:
1. 单个文件上传
单个文件上传是最常见的文件上传方式,可以通过 Gin 框架提供的 SaveUploadedFile
方法来处理单个文件的上传。
router.POST("/upload", func(c *gin.Context) {file, err := c.FormFile("file")if err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}// 保存文件到指定路径err = c.SaveUploadedFile(file, "uploads/"+file.Filename)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"message": "File uploaded successfully"})
})
在这个示例中,我们通过 FormFile
方法从请求中获取上传的文件,然后使用 SaveUploadedFile
方法将文件保存到指定的路径。
2. 多个文件上传
Gin 框架也支持同时上传多个文件,可以通过 MultipartForm
方法来处理多个文件的上传。
router.POST("/upload", func(c *gin.Context) {// 解析多个表单字段err := c.Request.ParseMultipartForm(10 << 20) // 10 MBif err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}// 获取所有上传的文件files := c.Request.MultipartForm.File["files"]for _, file := range files {// 保存文件到指定路径err := c.SaveUploadedFile(file, "uploads/"+file.Filename)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}}c.JSON(http.StatusOK, gin.H{"message": "Files uploaded successfully"})
})
在这个示例中,我们通过 MultipartForm
方法解析多个表单字段,然后使用 Request.MultipartForm.File["files"]
获取所有上传的文件,并循环遍历保存到指定路径。
3. 限制文件大小
为了防止恶意上传或者占用过多服务器资源,可以在处理文件上传之前进行文件大小的限制。
router.POST("/upload", func(c *gin.Context) {file, err := c.FormFile("file")if err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}// 限制文件大小为 10 MBif file.Size > 10<<20 {c.JSON(http.StatusBadRequest, gin.H{"error": "File size exceeds 10 MB"})return}// 保存文件到指定路径err = c.SaveUploadedFile(file, "uploads/"+file.Filename)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"message": "File uploaded successfully"})
})
在这个示例中,我们通过 file.Size
来获取文件的大小,并判断是否超过指定大小限制。
相关文章:
【Go】面向萌新的Gin框架知识梳理学习笔记
目录 Gin框架简介 路由&路由组 1. 定义基本路由 2. 参数传递 3. 查询字符串参数 4. 路由组 5. 路由中间件 模板渲染 1. 加载模板 2. 定义模板 3. 渲染模板 4. 自定义模板函数 返回json 1. 导入 Gin 包 2. 创建 Gin 引擎 3. 定义路由和处理器函数 4. 运行服…...
baseDao增删改查.
这里写目录标题 1、baseDao增删改查介绍2、basDao类3、BasDao类的作用 1、baseDao增删改查介绍 (1)、增加Create)操作: 通过BaseDao的insert方法可以向数据库中插入一条新的记录。 该方法接受一个实体对象作参数,将该对象的属性映射到表的字…...
什么是面向对象【大白话Java面试题】
什么是面向对象 同样是解决一个问题,面向对象的角度是将问题抽象成对象的形式。通过分类的思维方式,将问题分成几个解决方案的对象。给每个对象赋值属性和方法,对每个对象的细节进行面向过程的思维,执行自己的方法来解决问题。 …...
PyTorch 教程-快速上手指南
文章目录 PyTorch Quickstart1.处理数据2.创建模型3.优化模型参数4.保存模型5.加载模型 PyTorch 基础入门1.Tensors1.1初始化张量1.2张量的属性1.3张量运算1.3.1张量的索引和切片1.3.2张量的连接1.3.3算术运算1.3.4单元素张量转变为Python数值 1.4Tensor与NumPy的桥接1.4.1Tens…...
【有芯职说】数字芯片BES工程师
一、 数字芯片BES工程师简介 今天来聊聊数字芯片BES工程师,其中BES是Back End Support的缩写,就是后端支持的意思。其实这个岗位是数字IC前端设计和数字IC后端设计之间的一座桥,完成从寄存器传输级设计到具体工艺的mapping和实现。这个岗位在…...
暴力破解pdf文档密码
首先安装pdfcrack工具包 apt install pdfcrack 默认密码字典存储在/usr/share/wordlists里,是gz文件,将它解压并copy到pdf目录 然后使用pdfcrack破解 密码在最后一行user-password的单引号里...
蓝桥杯刷题第四天
思路: 这道题很容易即可发现就是简单的暴力即可完成题目,我们只需满足所有数的和为偶数即可保证有满足条件的分法,同时也不需要存下每个输入的数据,只需要知道他是偶数还是奇数即可,因为我们只需要偶数个奇数搭配在一块…...
03-数据库的用户管理
一、创建新用户 mysql> create user xjzw10.0.0.% identified by 1; Query OK, 0 rows affected (0.01 sec) 二、查看当前数据库正在登录的用户 mysql> select user(); ---------------- | user() | ---------------- | rootlocalhost | ---------------- 1 row …...
每日一题 --- 三数之和[力扣][Go]
三数之和 题目:15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 **注意&#x…...
vue render 函数详解 (配参数详解)
vue render 函数详解 (配参数详解) 在 Vue 3 中,render 函数被用来代替 Vue 2 中的模板语法。 它接收一个 h 函数(或者是 createElement 函数的别名),并且返回一个虚拟 DOM。 render 函数的语法结构如下: render(h) …...
ubuntu23.10配置RUST开发环境
系统版本: gcc版本 下载rustup安装脚本: curl --proto =https --tlsv1.2 https://sh.rustup.rs -sSf | sh下载完成后会自动执行 选择默认安装选项 添加cargo安装目录到环境变量 vim ~/.bashrc<...
Vue性能优化--gZip
一、gZip简单介绍 1.1 什么是gzip gzip是GNUzip的缩写,最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。目前主流的浏览器,Chro…...
蓝桥杯第七届大学B组详解
目录 1.煤球数量; 2.生日蜡烛; 3.凑算式 4.方格填数 5.四平方和 6.交换瓶子 7.最大比例 1.煤球数量 题目解析:可以根据题目的意思,找到规律。 1 *- 1个 2 *** 3个 3 ****** 6个 4 ********** 10个 不难发现 第…...
荣誉 | 人大金仓连续三年入选“金融信创优秀解决方案”
3月28日,由中国人民银行领导,中国金融电子化集团有限公司牵头组建的金融信创生态实验室发布“第三期金融信创优秀解决方案”,人大金仓新一代手机银行系统解决方案成功入选,这也是人大金仓金融行业解决方案连续第三年获得用户认可。…...
【关于jupyter notebook】一打开就闪退的问题
在Anaconda Prompt中输入jupyter notebook发现是有个错误。 里面多了一个__init__.py的文件导致报错。删除之后,就可以使用了...
若依 3.8.7版本springboot前后端分离 整合mabatis plus
1.去掉mybatis 这一步我没有操作,看别人的博客有说不去掉可能冲突,也可能不冲突,我试下来就没去掉如需要去除,到总的pom.xml中properties标签下的<mybatis-spring-boot.version>x.x.x</mybatis-spring-boot.version>…...
vue做移动端自适应插件实现rem
1.实现方式 postcss-pxtorem:将px转换为rem amfe-flexible:为html、body提那家font-size,窗口调整的时候重新设置font-size 2.安装与使用 npm install amfe-flexible --save npm install postcss-pxtorem --save-dev 1.再main.js入口文件…...
android 快速实现 图片获取并裁剪(更换头像)
1.获取图片框架:https://github.com/LuckSiege/PictureSelector 2.图片裁剪框架:https://github.com/jdamcd/android-crop 3.Glide图片加载框架:https://github.com/bumptech/glide 2.build.gradle依赖: dependencies {// Pic…...
垃圾回收机制--GC 垃圾收集器--JVM调优-面试题
1.触发垃圾回收的条件 新生代 Eden区域满了,触发young gc (ygc)老年代区域满了,触发full gc (fgc)通过ygc后进入老年代的平均大小大于老年代的可用内存,触发full gc(fgc).程序中主动调用的System.gc()强制执行gc,是full gc,但是不必然执行。…...
Java基础知识总结(29)
Java虚拟机 运行时数据区 程序计数器 方法区:Java 8以后没有方法区,改为了元空间(MetaSpace) 虚拟机栈 堆 本地方法栈 程序计数器 它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里,…...
vue js金额转中文
在Vue.js项目中,实现金额转中文的功能通常涉及编写一个JavaScript方法来处理数字转换逻辑,并在Vue组件中调用该方法。下面是一个基本的示例,展示如何在Vue组件中定义一个计算属性或方法来实现这一功能: /*** 思路: …...
《QT实用小工具·二》图片文字转base64编码
1、概述 源码放在文章末尾 base64编码转换类 图片转base64字符串。base64字符串转图片。字符转base64字符串。base64字符串转字符。后期增加数据压缩。Qt6对base64编码转换进行了重写效率提升至少200%。 下面是demo演示: 项目部分代码如下所示: #ifn…...
Django安装及第一个项目
1、安装python C:\Users\leell>py --version Python 3.10.6 可以看出我的环境python的版本3.10.6,比较新 2、 Python 虚拟环境创建 2.1 官网教程 目前,有两种常用工具可用于创建 Python 虚拟环境: venv 在 Python 3.3 及更高版本中默…...
专升本-物联网
物联网(IOT,Internet of things) 体系结构: 感知层(感知执行层) 网络层 应用层 基本特征: 全面感知 可靠传输 智能处理 作用: 信息采集、转换、收集 信息传递和处理 数据…...
二叉树的遍历C语言
二叉树作为FDS课程最核心的数据结构之一,要求每个人都掌握! 这是一道简单的二叉树问题! 我们将给出一颗二叉树,请你输出它的三种遍历,分别是先序遍历,中序遍历,后序遍历! 输入格式…...
PostgreSQL到Doris的迁移技巧:实时数据同步新选择!
PostgreSQL可以说是目前比较抢手的关系型数据库了,除了兼具多样功能和强大性能之外,还具备非常优秀的可扩展性,更重要的是它还开源,能火不是没有理由的。 虽然PostgreSQL很强大,但是它也有短板,相对于专业…...
【三维】关于万向节锁的直白解释
1. 分析理解 万向节长什么样子,请参考这篇文章中的图片:https://zhuanlan.zhihu.com/p/42519819。 看了很多篇解释性的文章,没怎么看懂。因为我个人最关注的问题点在于: 现实物体旋转为什么没有所谓的万向节锁的bug,…...
程序员的修养 - 变量
变量几乎代码程序程序 中最基础的组成单元,程序员几乎无时无刻都在接触变量。但你对变量的理解真的足够吗? 首先,什么是变量?! 第一层理解:一个可以改变的量,区别于常量,用户可以修…...
判断一个元素是否在可视区域中
文章目录 一、用途二、实现方式offsetTop、scrollTop注意 getBoundingClientRectIntersection Observer创建观察者传入被观察者 三、案例分析 参考文献 一、用途 可视区域即我们浏览网页的设备肉眼可见的区域,如下图 在日常开发中,我们经常需要判断目标…...
【Monero】Wallet RPC | Wallet CLI | 门罗币命令行查询余额、种子、地址等命令方法教程
ubuntu22.04 首先在运行daemon,详细安装运行教程可参考:The Monero daemon (monerod) ./monerodWallet CLI run ./monero-wallet-cli如果还没有钱包就根据提示创建钱包即可 输入密码 查询余额 balance查询种子 seed其他可执行命令操作࿱…...
网站架设 数据库选用/大一html网页制作作业
阿里高级专家手推最新版Spring源码深度解析(第2版)笔记总结 特点: 全面剖析Spring源码,方便读者根据业务需求进行更改或扩展所有知识点秉承由浅入深、由易到难的讲解架构采用抽丝剥茧的方式来阐述复杂的逻辑,降低理解…...
建网站需要什么技术/中国国家培训网官网入口
个人用户字体文件在~/.local/share/fonts系统字体文件在/usr/share/fonts字体配置文件在/etc/fonts/...
辽宁网站建设/详情页设计
主要软件包, 1. httpd-2.2.6.tar.gz 2. mysql-5.0.45-linux-i686-glibc23.tar.gz ( 这个版本是已编译好的压缩包,解压后稍做配置即可使用 ) 3. php-5.2.5.tar.gz 安装 php 所需的软件包(其中 libxml2 是安装 php5 必须的 . ) 1. l…...
linux wordpress 下载/湖南长沙最新疫情
1.JS基本语法: 1.js引入方式 js是脚本语言,可以在浏览器中执行。js文件是以.js为结尾的,引入html文件中时使用script标签,这时script需要添加一个属性src,src中写js文件的路径;但是js还可以直接写在html当中…...
四川省第十五公司/上海seo网站推广
最初了解 NMock 是从 《程序员》2004.12上的 董洵 所写的 《将单元测试进行到底—Mock Object 浅析》,那真是一片不错的文章! 在文章末尾的参考资料中,有一篇 MSDN杂志的文章Mock Objects to the Rescue! Test Your .NET Code with NMock &a…...
如何用服务器代替空间做网站/百度手机app
该文章转载自 http://fann.im/blog/2012/04/12/difference-between-objectforkey-and-valueforkey-in-nsdictionary/ 感谢原作者 从 NSDictionary 取值的时候有两个方法,objectForKey: 和 valueForKey:,这两个方法具体有什么不同呢? 先从 NS…...