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

GO语言学习(16)Gin后端框架

目录

☀️前言

1.什么是前端?什么是后端?🌀

2.Gin框架介绍 🌷

3.Gin框架的基本使用 -Hello,World例子🌷

 🌿入门示例 - Hello,World

💻补充(一些常用的网络术语): 

3.1 Get请求与Post请求📞

3.2 状态码 🔧

4.Gin的各类返回方式 🌷

✏️返回字符串:

 ✏️返回xml:

✏️返回文件(如Excel,txt,png等文件):

 ✏️页面重定向:

 5.如何处理前端的请求数据🌷

6.Gin框架实战案例 -表单信息提交处理🌷

4.1 前端JS请求 🔅

4.2 后端Gin编写 🔅 


☀️前言

        通过前面的基本学习,终于开始进入项目学习阶段。本文将主要介绍Go语言官方的后端框架Gin如何与前端数据交互,以及实现最基本的表单数据交互案例,而关于后端操作数据库的部分,将留在下一章进行详细讲解。

1.什么是前端?什么是后端?🌀

        前端和后端是软件开发中的两个重要部分,它们共同协作完成一个完整的产品或系统。通俗来说,前端就像餐厅的前台,负责接待顾客、展示菜单、处理顾客的点餐需求,后端就像餐厅的后厨,负责准备食材、烹饪菜肴、确保菜品按时送到前台,前端是用户看到的“表面”,负责展示和交互。后端是用户看不到的“幕后”,负责处理数据和逻辑。

对比维度前端后端
定义前端是用户直接看到和交互的部分,主要负责展示界面和处理用户操作。后端是运行在服务器上的部分,主要负责数据处理、逻辑运算和存储。
主要功能展示页面、交互设计、响应用户操作(如点击按钮、输入内容)。处理业务逻辑、管理数据库、提供 API 接口给前端调用。
技术栈HTML、CSS、JavaScript、框架(如 React、Vue、Angular)。

服务器语言(如 Python、Java、Node.js、PHP)、

数据库(如 MySQL、MongoDB)。

工作内容设计和实现用户界面、优化用户体验、与后端 API 交互。开发服务器端逻辑、管理数据库、处理数据、提供安全性和性能优化。
用户体验直接影响用户对产品的第一印象,注重界面美观和交互流畅性。间接影响用户体验,主要通过提供稳定、快速的服务来支持前端。
安全性前端代码是公开的,容易被用户查看和篡改,安全性较弱。后端代码运行在服务器上,用户无法直接访问,安全性较高。
开发工具浏览器、代码编辑器(如 VS Code)、前端框架工具。服务器环境、数据库管理工具、API 测试工具(如 Postman)。

2.Gin框架介绍 🌷

        Gin 是一个用 Go 语言编写的高性能 HTTP Web 框架,以轻量级、快速路由和中间件支持著称。Gin的设计目标是帮助开发者快速构建Web应用和RESTful API,同时保持高性能和低资源占用。其主要特点如下:

  1. 高性能:基于Radix树的路由实现,内存占用小,无反射,API性能可预测。
  2. 零分配路由器:路由处理过程中不产生内存分配,确保高效。
  3. 中间件支持:支持链式中间件,可以用于日志记录、认证、GZIP压缩等。
  4. 崩溃恢复:能够捕获HTTP请求中的panic并恢复,确保服务器始终可用。
  5. JSON验证:支持对请求中的JSON数据进行验证,确保数据完整性。
  6. 路由分组:支持路由分组,便于组织不同功能的API版本或权限。
  7. 错误管理:提供方便的方式收集和处理HTTP请求中的错误。
  8. 内置渲染:支持JSON、XML和HTML的渲染。
  9. 可扩展性:易于创建自定义中间件,满足特定需求

同样Go语言的后端框架不止Gin一种,还有其它后端框架,如Beggo,比较结果如下:

框架性能路由中间件适用场景学习曲线
Gin极高基于httprouter丰富且灵活API服务、微服务、高性能后端
Echo自定义实现简洁RESTful API、轻量级应用
Fiber极高类似ExpressExpress风格替代Gin,追求极简语法
Beego中等自带MVC路由全功能全栈开发(含ORM、模板引擎)中高

3.Gin框架的基本使用 -Hello,World例子🌷

        首先我们得先导入Gin的包,熟悉python语言的同学都知道,对于 python 我们可以在终端使用 pip install 命令进行下载所需要的包,而go语言,可以在终端使用 go get 命令来获取第三方包,导入到项目中。我们在项目的终端中,输入如下命令,即可将Gin框架导入到项目中,接下来就可以使用Gin框架进行开发了。

$ go get -u github.com/gin-gonic/gin
 🌿入门示例 - Hello,World
package mainimport "github.com/gin-gonic/gin"   // 导入Gin的包func main() {r := gin.Default()r.GET("/", func(c *gin.Context) {c.JSON(200, gin.H{"message": "Hello, World!"})})r.Run(":8080") // 监听 0.0.0.0:8080
}

 🌳解释🌳:

  • r := gin.Default() 使用gin创建了一个默认的路由器实例,它会自动加载一些中间件,比如日志记录和恢复中间件,接下来由它负责处理网页的HTTP请求并调用相应的处理函数。
  • r.get用于定义一个GET请求的路由。这里定义了一个路径为"/"的GET请求处理函数。当客户端访问应用的根路径"/"时,会调用这个处理函数。cgin.Context类型的参数,它包含了请求和响应的所有信息。c.JSON用于向客户端发送JSON格式的响应。200是HTTP状态码,表示请求成功。gin.H是一个快捷方式,用于创建一个map[string]interface{},这里用于构建JSON响应内容。
  • r.Run()启动HTTP服务器并开始监听请求。":8080"指定了服务器监听的端口号为8080

         通过本次简单的例子,我们可以归纳出更为普遍的Gin后端框架处理流程,如下图所示:

💻补充(一些常用的网络术语): 

3.1 Get请求与Post请求📞

        通俗来说,GET请求就像去图书馆借书,你告诉图书馆员你想借的书名(参数),这个书名会显示在借书单上(URL),别人可以看到。POST请求就像去图书馆还书,你把书交给图书馆员(数据放在请求体中),这个过程是相对私密的,别人不会知道你具体还了什么书。

对比维度GET请求POST请求
用途用于从服务器获取数据,比如访问一个网页或查询信息。用于向服务器提交数据,比如提交表单或上传文件。
数据传递方式参数附加在URL后面,比如http://example.com/search?q=keyword数据放在请求体中,不会显示在URL中。
安全性相对不安全,因为参数会显示在浏览器地址栏中,可能会被保存在浏览器历史记录或服务器日志中。相对更安全,因为数据不会显示在浏览器地址栏中,也不容易被缓存或记录在历史中。
限制URL长度有限制,通常不能超过2048个字符,不适合传递大量数据。没有长度限制,可以传递大量数据。
缓存可以被浏览器缓存,多次访问相同的URL时可能不会每次都向服务器发送请求。通常不会被浏览器缓存,每次提交都会向服务器发送请求。
幂等性是幂等的,多次请求相同URL不会产生不同结果。不是幂等的,多次提交相同数据可能会产生不同结果(如多次提交表单)。
书签可以通过书签保存URL,方便后续访问。不能通过书签保存请求体中的数据。
适用场景适合简单的查询和数据获取,比如搜索、查看页面内容。适合复杂操作和敏感数据的提交,比如登录、文件上传、表单提交等。
3.2 状态码 🔧

        HTTP状态码是服务器对客户端请求的响应状态的三位数字代码,用于表示请求的处理结果。状态码分为以下几类:

  • 1xx(信息性状态码):表示请求已接收,正在处理。

  • 2xx(成功状态码):表示请求已成功处理。

  • 3xx(重定向状态码):表示需要进一步操作才能完成请求。

  • 4xx(客户端错误状态码):表示客户端请求有误,服务器无法处理。

  • 5xx(服务器错误状态码):表示服务器处理请求时发生错误。

状态码描述
100继续,表示服务器已收到请求的初始部分,客户端可以继续发送其余请求。
200请求成功,服务器返回了请求的数据。
201资源已成功创建。
301资源的URL已永久更改。
302资源的URL暂时更改。
400请求有误,服务器无法处理。
401请求未授权。
403请求被拒绝。
404请求的资源不存在。
500服务器内部错误,无法完成请求。
502服务器从上游服务器接收到的响应无效。
503服务不可用,通常是服务器过载或维护

        而在Go语言中,可以使用net/http包来处理HTTP请求和响应,如http.StatusOK代表状态码200http.StatusBadRequest代表状态码400http.StatusInternalServerError代表状态码500

4.Gin的各类返回方式 🌷

        上述基本案例中,Gin返回的数据类型为json格式,下面介绍一些别的格式的数据返回。

✏️返回字符串:

router.GET("/str", func(c *gin.Context) {c.String(http.StatusOK, "返回成功")
})

 ✏️返回xml:

router.GET("/xml", func(c *gin.Context) {c.XML(http.StatusOK, gin.H{"user": "FJNU", "message": "hey", "status": http.StatusOK})
})

✏️返回文件(如Excel,txt,png等文件):

 router.GET("/download/:filename", func(c *gin.Context) {filename := c.Param("filename")           // 获取前端传输的文件名filePath := "./files/" + filename        // 获取本地的文件路径c.File(filePath)              // 将对应的文件传回前端})

        上述方法用于返回单个文件,filename必须包含文件的扩展名(如.png),Gin会自动根据文件扩展名设置正确的MIME类型。

        如果希望文件被浏览器作为附件下载而不是直接显示,可以使用c.FileAttachment()方法。

package mainimport "github.com/gin-gonic/gin"func main() {router := gin.Default()router.GET("/download/:filename", func(c *gin.Context) {filename := c.Param("filename")filePath := "./files/" + filenamec.FileAttachment(filePath, filename)})router.Run(":8080")
}

 ✏️页面重定向:

        如果你希望点击某个按钮后,跳转到另一个页面,可以使用以下方法:

router.GET("/redirect", func(c *gin.Context) {//支持内部和外部的重定向c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")
})

 5.如何处理前端的请求数据🌷

        c *gin.Context 是 Gin 框架处理 HTTP 请求的核心对象,封装了请求和响应的所有操作。以下是其核心功能及用法:

功能方法/属性说明
获取请求参数c.Param("key")获取路由参数(如 /user/:id → id
c.Query("key")获取 URL 查询参数(如 ?name=John
c.PostForm("key")获取表单数据(Content-Type: application/x-www-form-urlencoded
c.FormFile("file")获取上传的文件(Content-Type: multipart/form-data
请求头操作c.GetHeader("User-Agent")获取请求头字段
c.Request.Header直接访问原始请求头(http.Header类型)

1.获取路由当中的静态值(Query):

r.GET("/test/:age", func(c *gin.Context) {age := c.Query("age")c.String(200, "I am %s years old", age)})

2.获取动态路由中的值(Param):

r.GET("/hello/:name", func(c *gin.Context) {name := c.Param("name")c.String(200, "hello %s", name)})

 3.保存前端所上传的文件(如word,excel,png图片等):

r := gin.Default()// 设置静态文件目录,方便前端访问上传的文件r.Static("/uploads", "./uploads")// 处理文件上传r.POST("/upload", func(c *gin.Context) {// 获取名为 "file" 的上传文件file, err := c.FormFile("file")if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get form file err: %s", err.Error()))return}// 获取上传文件的原始文件名filename := file.Filename// 指定文件保存路径destination := "./uploads/" + filename// 创建 uploads 目录(如果不存在)err = os.MkdirAll("./uploads", os.ModePerm)if err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("mkdir err: %s", err.Error()))return}// 保存上传的文件到指定位置if err := c.SaveUploadedFile(file, destination); err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("upload file err: %s", err.Error()))return}// 返回成功信息c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", filename))})

当然对于接受到的前端数据c,也可以进行后端变量的数据绑定:

方法说明
c.ShouldBindJSON(&obj)将请求体 JSON 绑定到结构体,自动触发 binding 标签验证
c.ShouldBindQuery(&obj)绑定 URL 查询参数到结构体
c.ShouldBindUri(&obj)绑定路由参数到结构体
c.Bind(&obj)自动根据 Content-Type 选择绑定方式,验证失败直接返回 400 错误

以下为一段示例代码:

type User struct {Name  string `json:"name" binding:"required"`// 必填且必须是邮箱格式Email string `json:"email" binding:"required,email"`// 数值范围限制(18 ≤ Age ≤ 60)Age   int    `json:"age" binding:"gte=18,lte=60"`// 字符串长度限制(6 ≤ 密码长度 ≤ 16)Password string `json:"password" binding:"required,min=6,max=16"`// 枚举值(只能是 "male" 或 "female")Gender string `json:"gender" binding:"oneof=male female"`
}
func CreateUser(c *gin.Context) {var user Userif err := c.ShouldBindJSON(&user); err != nil {// 返回验证错误信息c.JSON(400, gin.H{"error": err.Error()})return}// 验证通过后的业务逻辑c.JSON(200, gin.H{"message": "User created"})
}

         上述代码,会将前端传回的json数据c的值绑定在结构体变量user中,并验证数据是否符合结构体当中的binding要求,若不满足则会产生对应的错误err,否则err为空。

        对于中间件与流程控制,有如下方法: 

方法说明
c.Next()继续执行后续中间件或处理函数(通常在中间件中调用)
c.Abort()终止当前请求的后续处理(如权限校验失败时)
c.AbortWithStatus(code)终止并返回指定 HTTP 状态码
c.Set("key", value)存储数据供后续中间件或处理函数使用
c.Get("key")获取通过 Set 存储的值

中间件示例代码:

func AuthMiddleware() gin.HandlerFunc {return func(c *gin.Context) {token := c.GetHeader("Authorization")if token != "valid-token" {c.AbortWithStatusJSON(401, gin.H{"error": "Unauthorized"})return}c.Set("user", "admin") // 传递用户信息c.Next()}
}// 路由中使用中间件
router.GET("/admin", AuthMiddleware(), func(c *gin.Context) {user := c.MustGet("user").(string)c.String(200, "Welcome %s", user)
})

        关于响应的请求头,以及Cookie,Session会话机制的内容,将在后续章节进一步详细解释。 

6.Gin框架实战案例 -表单信息提交处理🌷

        本次案例地前端是使用VUE3与Vite共同创建,采用的UI组件为ElementPlus-Form,如果你熟悉VUE2或其他UI组件库,当然也可以使用。这里就不过多叙述前端的搭建了,前端页面最终效果如下:

4.1 前端JS请求 🔅

        对Create按键添加绑定函数,使得用户点击该按钮的时候,能够自动提交表单填写的信息。

                         

        接着使用Axios,将前端的表单数据发送到后端,当然熟悉fetch的uu,也可以使用fetch的方法进行数据传递。             

4.2 后端Gin编写 🔅 

        首先先介绍一个概念-跨域请求(CORS):CORS(Cross-Origin Resource Sharing)是一种机制,允许服务器通过设置HTTP头部来指定哪些源(域、协议或端口)可以访问其资源。它用于解决浏览器的同源策略限制,使得不同源之间的资源可以安全地进行交互。 

        为了使得数据可以从前端传递到后端,首先我们得先配置一下Gin的CORS,具体代码如下:

r := gin.Default()// 自定义 CORS 中间件r.Use(func(c *gin.Context) {// 设置允许的请求头c.Writer.Header().Set("Access-Control-Allow-Origin", "*")c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")if c.Request.Method == "OPTIONS" {c.AbortWithStatus(http.StatusNoContent)return}c.Next()})

        配置完CORS之后,开始编写处理函数部分:

r.POST("/submit-form", func(c *gin.Context) {var formData map[string]interface{}if err := c.BindJSON(&formData); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"message": "Form submitted successfully", "data": formData})})

        这里与前端的请求相照应,由于前端发起的是POST方式,所以此处也使用r.POST,而不能使用r.GET,路径对应前端的请求路径,为 /submit-form

        接着声明一个 map[string]interface{} 类型的变量formData,用于存储从请求体中解析出来的JSON数据。map[string]interface{}是一个通用的键值对结构,可以存储任意类型的值。(关于Go语言当中map数据类型的内容,我确实没写过...后续有时间在补上。)

        c.BindJSON(&formData)尝试从请求体中解析JSON数据,并将其绑定到formData变量中。如果解析失败,err会包含错误信息。如果解析失败,使用c.JSON发送一个400状态码(http.StatusBadRequest)和一个包含错误信息的JSON响应。如果JSON解析成功,使用c.JSON发送一个200状态码(http.StatusOK)和一个包含成功消息和解析数据的JSON响应。

        最后依据前端的访问端口,进行对应的配置:

r.Run(":8000")

 至此,后端部分完成,下面开始测试:

1.使用npm run开启前端界面,以及运行对应的后端Go文件。

2.在前端界面的表单中输入信息,并点击Create按钮进行表单数据的提交

3.在后端Gin文件中,可以查看到刚刚的前端请求信息

 4.在前端界面中,使用F12,点击Console,可以在控制台看到,Gin所传回来的后端数据,接着前端接受,使用变量接收数据,便可以将数据渲染显示在网页界面上了。

相关文章:

GO语言学习(16)Gin后端框架

目录 ☀️前言 1.什么是前端?什么是后端?🌀 2.Gin框架介绍 🌷 3.Gin框架的基本使用 -Hello,World例子🌷 🌿入门示例 - Hello,World 💻补充(一些常用的网…...

RAG 在 AI 助手、法律分析、医学 NLP 领域的实战案例

RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合信息检索和生成模型的技术,广泛应用于 AI 助手、法律分析、医学 NLP 等领域。 以下是具体的实战案例和技术实现。 1. AI 助手中的 RAG 应用 案例 1:企业…...

大模型-提示词(Prompt)技巧

1、什么是提示词? 提示词(Prompt)是用户发送给大语言模型的问题、指令或请求,用来明确地告诉模型用户想要解决的问题或完成的任务,是大语言模型理解用户需求并据此生成相关、准确回答或内容的基础。对于大语言模型来说…...

RNN模型与NLP应用——(9/9)Self-Attention(自注意力机制)

声明: 本文基于哔站博主【Shusenwang】的视频课程【RNN模型及NLP应用】,结合自身的理解所作,旨在帮助大家了解学习NLP自然语言处理基础知识。配合着视频课程学习效果更佳。 材料来源:【Shusenwang】的视频课程【RNN模型及NLP应用…...

硬件与软件的边界-从单片机到linux的问答详解

硬件与软件的边界——从单片机到 Linux 设备驱动的问答详解 在嵌入式开发和操作系统领域,经常会有人问: “如果一个设备里没有任何代码,硬件是不是依然会工作?例如,数据收发、寄存器数据存储、甚至中断触发&#xff…...

5.实现 Channel 类,Reactor 模式初步形成

目录 由联合体epoll_data引出类Channel 结构体epoll_data_t Channel类 Channel类的使用 Epoll类的改变 由联合体epoll_data引出类Channel 在之前使用epoll时,有使用到一个结构体epoll_event // 这是联合体,多个变量共用同一块内存 typedef union…...

深度剖析:U盘打不开难题与应对之策

一、引言 在数字化办公与数据存储的浪潮中,U盘凭借其小巧便携、大容量存储等优势,成为了人们日常数据传输与备份的得力助手。然而,当我们急需调用U盘中的关键数据时,却常常遭遇U盘打不开的棘手状况。U盘打不开不仅会影响工作进度&…...

洛谷题单3-P5721 【深基4.例6】数字直角三角形-python-流程图重构

题目描述 给出 n n n,请输出一个直角边长度是 n n n 的数字直角三角形。所有数字都是 2 2 2 位组成的,如果没有 2 2 2 位则加上前导 0 0 0。 输入格式 输入一个正整数 n n n。 输出格式 输出如题目要求的数字直角三角形。 输入输出样例 输入…...

一起学大语言模型-通过ollama搭建本地大语言模型服务

文章目录 Ollama的github地址链接安装下载需求配置更改安装目录安装更改下载的模型存储位置Ollama一些目录说明日志目录 运行一个模型测试下测试下更改服务监听地址和端口号 Ollama的github地址链接 https://github.com/ollama/ollama 安装 下载 mac安装包下载地址&#xff1…...

AllData数据中台商业版发布版本1.2.9相关白皮书发布

文章末尾网盘链接获取白皮书,本资源通过星球社群不定时更新,加入星球后,请联系市场同事获取相关知识星球社群信息。 一、总体介绍 主要介绍了AllData商业版产品的整体情况,包括产品定位、核心优势、灵活性和扩展性等,已有150个客户使用,社区发展良好。同时,详细解析了…...

uni-app 框架 调用蓝牙,获取 iBeacon 定位信标的数据,实现室内定位场景

背景:最近需要对接了一个 叫 iBeacon 定位信标 硬件设备,这个设备主要的作用是,在信号不好的地方,或者室内实现定位,准确的找到某个东西。就比如 地下停车场,商城里,我们想知道这个停车场的某个…...

leetcode-热题100(3)

leetcode-74-搜索二维矩阵 矩阵最后一列升序排序,在最后一列中查找第一个大于等于target的元素 然后在该元素所在行进行二分查找 bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {int n matrixSize;int m matrixColSize[0];in…...

汇编学习结语

一天之内挑战计划太乐观了, 不过还好,这次我总共用了三天完成了系列汇编指令的学习,有的指令也深入进行了验证,输出了系列文章,收获颇多。 接下来我将开启一个专栏,用于记录学习OllyDbg的使用。 OllyDbg使用…...

C++ I/O 流通俗指南

1. std::ostream 是什么? 定义:std::ostream 是 C 标准库中的输出流类,负责将数据输出到各种目标(如屏幕、文件、网络等)。你可以把 std::ostream 想象成一根“数据水管”: 数据从 C 代码流进 std::ostrea…...

基于python的电影数据分析及可视化系统

一、项目背景 随着电影行业的快速发展,电影数据日益丰富,如何有效地分析和可视化这些数据成为行业内的一个重要课题。本系统旨在利用Python编程语言,结合数据分析与可视化技术,为电影行业从业者、研究者及爱好者提供一个便捷的电…...

【NLP 面经 5】

难以承受的东西只会让我在下一次更平静的面对 —— 25.4.2 一、NER任务,CRF模型改进 命名实体识别(NER)任务中,你使用基于条件随机场(CRF)的模型,然而模型在识别嵌套实体和重叠实体时效果不佳&a…...

鸿蒙NEXT小游戏开发:猜小球

1. 引言 “猜小球”是一个经典的益智游戏,通常由一名表演者和多名参与者共同完成。表演者会将一个小球放在一个杯子下面,然后将三个杯子快速地交换位置,参与者则需要猜出最终哪个杯子下面有小球。本文将介绍如何使用HarmonyOS NEXT技术&…...

[NCTF2019]Fake XML cookbook [XXE注入]

题目源代码 function doLogin(){var username $("#username").val();var password $("#password").val();if(username "" || password ""){alert("Please enter the username and password!");return;}var data "…...

Android 防抖和节流

文章目录 Android 防抖和节流概述工具类使用源码下载 Android 防抖和节流 概述 防抖(Debounce): 防抖是指在事件被触发后,等待一段时间,如果在这段时间内没有再触发事件,才执行处理函数。如果在这段时间内…...

安徽京准:NTP时间同步服务器操作使用说明

安徽京准:NTP时间同步服务器操作使用说明 3.1 连接天线 天线连接到“ANT”口。 3.2 连接电源 将220V电源线连到AC220V座上或将电源适配器(7.5V~12V)接到DC口上。也可以同时接上,提高供电可靠性。 3.3 LAN网口 网线连接到NTP…...

【学习记录】pytorch载入模型的部分参数

需要从PointNet网络框架中提取encoder部分的参数,然后赋予自己的模型。因此,需要从一个已有的.pth文件读取部分参数,加载到自定义模型上面。做了一些尝试,记录如下。 关于模型保存与载入 torch.save(): 使用Python的pickle实用程…...

Ubuntu Wayland启动腾讯会议并实现原生屏幕共享

Intro 众所周知,长期以来,由于腾讯会议项目组的尸位素餐、极度不作为,在Wayland成为Ubuntu 24.04 LTS的默认窗口环境下,仍然选择摆烂,甚至还“贴心”地在启动脚本下增加检测Wayland退出的代码;并且即使使用…...

写Prompt的技巧和基本原则

一.基本原则 1.一定要描述清晰你需要大模型做的事情,不要模棱两可 2.告诉大模型需要它做什么,不需要做什么 改写前: 请帮我推荐一些电影 改写后: 请帮我推荐2025年新出的10部评分比较高的喜剧电影,不要问我个人喜好等其他问题&#xff…...

前端Material-UI面试题及参考答案

目录 Material-UI 的设计理念与 Material Design 规范的关系是什么? 如何通过 npm/yarn/pnpm 安装 Material-UI 的核心依赖? Material-UI 的默认主题系统如何实现全局样式管理? 如何在项目中配置自定义字体和颜色方案? 什么是 emotion 和 styled-components,它们在 Ma…...

29、web前端开发之CSS3(六)

13. 多列布局(Multi-column Layout) 多列布局(Multi-column Layout)是一种通过CSS实现的布局方式,允许将内容组织成多列,类似于报纸或杂志的排版方式。这种布局方法能够有效地利用页面空间,提升…...

Go 语言语法精讲:从 Java 开发者的视角全面掌握

《Go 语言语法精讲:从 Java 开发者的视角全面掌握》 一、引言1.1 为什么选择 Go?1.2 适合 Java 开发者的原因1.3 本文目标 二、Go 语言环境搭建2.1 安装 Go2.2 推荐 IDE2.3 第一个 Go 程序 三、Go 语言基础语法3.1 变量与常量3.1.1 声明变量3.1.2 常量定…...

MySQL 复制与主从架构(Master-Slave)

MySQL 复制与主从架构(Master-Slave) MySQL 复制与主从架构是数据库高可用和负载均衡的重要手段。通过复制数据到多个从服务器,既可以实现数据冗余备份,又能分担查询压力,提升系统整体性能与容错能力。本文将详细介绍…...

水下成像机理分析

一般情况下, 水下环境泛指浸入到人工水体 (如水库、人工湖等)或自然水体(如海洋、河流、湖 泊、含水层等)中的区域。在水下环境中所拍摄 的图像由于普遍受到光照、波长、水中悬浮颗粒物 等因素的影响,导致生成的水下图像出现模糊、退 化、偏色等现象,图像…...

腾讯云智测试开发面经

1、投递时间线 2.20投递简历,3.11第一轮面试,3.30第二轮面试,4.4第三轮面试,4.10第四轮面试,4.11offer意向书 2、第一轮面试 第一轮面试技术面,面试官是导师,面试时长40多分钟 1)自我介绍 2)数组和列表的区别 3)了解哪些数据库 4)进程和线程的区别 5)了解哪…...

JVM类加载器详解

文章目录 1.类与类加载器2.类加载器加载规则3.JVM 中内置的三个重要类加载器为什么 获取到 ClassLoader 为null就是 BootstrapClassLoader 加载的呢? 4.自定义类加载器什么时候需要自定义类加载器代码示例 5.双亲委派模式类与类加载器双亲委派模型双亲委派模型的执行…...