GIN与Echo:选择正确Go框架的指南

news2024/12/25 4:29:04

您是否在Go中构建Web应用?选择正确的框架至关重要!GIN和Echo是两个热门选择,每个都有其优势和特点。本指南将详细介绍每个框架的特性、速度、社区热度以及它们各自擅长的项目类型。最后,您将能够为您的下一个Web项目选择完美的框架!

在这里插入图片描述

对于Go Web开发项目选择正确的框架对项目成功至关重要。GIN和Echo是两个流行的选择,每个都具有独特的优势。GIN优先考虑性能和简单性,使其成为API和微服务的理想选择。Echo提供了广泛的自定义和灵活性,适用于需要复杂路由的复杂Web应用。在决定使用两者之间时,考虑项目要求、开发者熟悉度和特定用例。GIN在高性能应用中表现出色,而Echo适用于需要定制化的项目。两个框架都有活跃的社区、详尽的文档和不同级别的性能和功能集。根据项目的需要明智选择。

快速对比

Gin和Echo框架的比较:

特性GinEcho
性能高性能,为速度优化快速轻量级框架
路由强大的路由引擎,支持动态路由和中间件强大的路由能力,支持中间件链
中间件支持中间件链并包含多种内置中间件以处理常见任务以中间件为中心的设计,提供广泛的中间件支持
文档文档齐全,有全面的指南和示例详细的文档,有清晰的解释和示例
社区大型活跃社区,频繁更新和贡献不断增长的社区,增加采用率和社区支持
学习曲线对熟悉Web框架的开发者来说学习曲线相对较低对已经熟悉Web开发概念的开发者易于学习
灵活性提供定制化和扩展的灵活性高度灵活,支持自定义中间件和配置选项
流行度在生产环境中广泛使用,受到许多开发者的青睐由于其简单性和性能正变得越来越流行
生态系统丰富的生态系统,有众多第三方库和插件可用生态系统不断发展,支持各种集成和扩展
Websocket支持对Websockets的支持有限,可能需要额外的库或中间件开箱即用的全面Websockets支持,包括内置中间件
JSON处理内置支持JSON处理和序列化原生支持JSON处理,易于使用的API
模板渲染支持使用HTML和文本模板的模板渲染内置支持模板渲染,支持HTML模板和各种模板引擎
许可MIT许可证MIT许可证

引言:

为您的Go Web开发项目选择正确的框架就像

为工匠选择完美的工具一样。它为整个开发过程奠定了基础,影响着从代码结构到项目可扩展性的一切。在这个速度、效率和适应性至关重要的数字时代,这一决定变得更加重要。

选择正确框架的重要性

框架的选择显著影响开发体验和项目的最终成果。一个合适的框架可以简化开发,提高生产力,并确保应用的可扩展性和可维护性。相反,不合适的框架可能导致不必要的复杂性,性能受阻和开发时间增加。

在Go Web开发的背景下,简单性、性能和并发性是核心原则,选择过程变得更加细腻。框架必须在提供强大功能和保持语言固有效率和优雅之间找到微妙的平衡。

介绍GIN和Echo:两个框架的故事

在众多Go Web框架中,GIN和Echo已经成为突出的竞争者,每个都有自己独特的优势和特性。

GIN:

作为一个极简主义但功能强大的框架,GIN优先考虑性能和简单性。基于net/http构建,它拥有极快的路由和最小的开销,使其成为构建高性能API和微服务的理想选择。GIN的轻量级设计和直观API使开发人员能够用最少的样板代码创建健壮的Web应用,确保快速开发而不牺牲性能。

Echo:

相比之下,Echo以其灵活性和可定制性脱颖而出。凭借其优雅和富有表现力的API,Echo使开发人员能够轻松构建复杂的Web应用。提供广泛的中间件支持、动态路由生成和内置验证,Echo为构建RESTful API和复杂Web应用提供了全面的工具包。它对开发者生产力和灵活性的强调使其成为需要广泛定制和高级功能的项目的首选。

导航决策过程

在GIN和Echo之间的决定取决于众多因素,包括项目要求、性能考虑和开发偏好。为了做出明智的选择,开发人员必须仔细评估每个框架的特性、性能指标和社区支持,权衡利弊,并将它们与项目的目标和目的对齐。

在本指南的后续部分中,我们将深入探讨GIN和Echo的特性、用例和性能基准,提供宝贵的洞察,帮助您导航决策过程,并选择最适合您需求的框架。

随着对框架选择重要性的清晰理解以及对GIN和Echo独特特性的介绍,让我们开始探索这两个框架的细节,并发现哪一个在Go Web开发领域占据主导地位。

比较特性

路由

GIN的路由简洁直观,使用最小化的语法定义路由变得简单。Echo提供了类似的功能,具有灵活的路由API,允许动态路由模式和参数解析。两个框架都支持中间件,使开发人员能够高效地向路由添加预处理和后处理逻

辑。

// GIN路由示例
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
    c.String(http.StatusOK, "pong")
})

// Echo路由示例
e := echo.New()
e.GET("/ping", func(c echo.Context) error {
    return c.String(http.StatusOK, "pong")
})

模板

GIN对服务器端模板的支持有限,主要通过HTML渲染引擎。相比之下,Echo通过允许开发人员与多种模板引擎集成,包括HTML、Markdown和JSON,提供了更大的灵活性。

Gin框架:

Gin框架通过使用Go标准库中的html/template包提供内置支持模板渲染。以下是如何在Gin中使用模板渲染的方法:

  1. 模板解析: Gin提供了一个LoadHTMLGlob函数来从目录加载HTML模板。您可以使用此函数来解析和加载模板:
// 加载HTML模板
router := gin.Default()
router.LoadHTMLGlob("templates/*")
  1. 渲染模板: 一旦模板被加载,您可以在路由处理器中使用HTML方法渲染它们:
// 渲染HTML模板
router.GET("/", func(c *gin.Context) {
    // 渲染"index.html"模板
    c.HTML(http.StatusOK, "index.html", gin.H{
        "title": "欢迎来到我的网站",
    })
})
  1. 向模板传递数据: 您可以使用gin.H映射或通过传递结构体来向模板传递数据:
type User struct {
    Name  string
    Email string
}

router.GET("/user", func(c *gin.Context) {
    // 向"user.html"模板传递数据
    user := User{Name: "John Doe", Email: "john@example.com"}
    c.HTML(http.StatusOK, "user.html", gin.H{
        "user": user,
    })
})
Echo框架:

Echo框架同样支持模板渲染,允许使用各种模板引擎,如HTML、Markdown等。以下是在Echo中使用模板渲染的方法:

  1. 模板渲染设置: Echo提供了一个Render方法来设置模板渲染:
// 设置模板渲染
e := echo.New()
e.Renderer = renderer.NewRenderer("templates")
  1. 渲染模板: 设置模板渲染后,您可以在路由处理器中使用Render方法渲染模板:
// 渲染HTML模板
e.GET("/", func(c echo.Context) error {
    // 渲染"index.html"模板
    return c.Render(http.StatusOK, "index.html", map[string]interface{}{
        "title": "欢迎来到我的网站",
    })
})
  1. 向模板传递数据: 类似于Gin,您可以使用映射或结构体向模板传递数据:
type User struct {
    Name  string
    Email string
}

e.GET("/user", func(c echo.Context) error {
    // 向"user.html"模板传递数据
    user := User{Name: "John Doe", Email: "john@example.com"}
    return c.Render(http.StatusOK, "user.html", map[string]interface{}{
        "user": user,
    })
})
对比:

Gin和Echo在模板渲染功能上提供了类似的功能,允许开发人员轻松渲染HTML模板并向它们传递数据。主要区别在于设置和配置语法,Gin使用自己的HTML方法,而Echo使用Render方法。然而,最终结果是相同的,两个框架都提供了在Go Web应用中模板渲染的强大支持。开发人员可以根据个人偏好和项目要求在Gin和Echo之间进行选择。

验证

GIN和Echo都提供了内置验证功能,用于处理用户输入。然而,Echo通过与流行的验证库如Go Validator和go-playground/validator的集成,提供了更广泛的支持。

Gin中的验证:

Gin没有内置的验证功能。然而,开发人员可以轻松集成第三方验证库,如go-playground/validatorasaskevich/govalidator,在Gin应用中处理输入验证。

这是使用go-playground/validator库与Gin进行输入验证的示例:

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/go-playground/validator/v10"
)

type User struct {
    Username string `json:"username" validate:"required"`
    Email    string `json:"email" validate:"required,email"`
}

func main() {
    r := gin.Default()

    // 初始化验证器
    validate := validator.New()

    r.POST("/register", func(c *gin.Context) {
        var user User
        if err := c.ShouldBindJSON(&user); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }

        // 验证用户输入
        if err := validate.Struct(user); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }

        // 处理有效的用户数据
        c.JSON(200, gin.H{"message": "用户注册成功"})
    })

    r.Run(":8080")
}
Echo中的验证:

Echo通过其echo.Validator接口提供内置的验证功能,允许开发人员定义自定义验证规则和错误消息。

这是使用Echo内置验证中间件进行输入验证的示例:

package main

import (
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
    "gopkg.in/go-playground/validator.v9"
)

type User struct {
    Username string `json:"username" validate:"required"`
    Email    string `json:"email" validate:"required,email"`
}

func main() {
    e := echo.New()

    // 初始化验证器
    e.Validator = &CustomValidator{validator: validator.New()}

    e.POST("/register", func(c echo.Context) error {
        var user User
        if err := c.Bind(&user); err != nil {
            return err
        }

        // 验证用户输入
        if err := c.Validate(&user); err != nil {
            return err
        }

        // 处理有效的用户数据
        return c.JSON(200, map[string]string{"message": "用户注册成功"})
    })

    e.Logger.Fatal(e.Start(":8080"))
}

// CustomValidator实现了echo.Validator接口
type CustomValidator struct {
    validator *validator.Validate
}

// Validate验证一个结构体
func (cv *CustomValidator) Validate(i interface{}) error {
    if err := cv.validator.Struct(i); err != nil {
        return echo.NewHTTPError(400, err.Error())
    }
    return nil
}

在这个示例中,CustomValidator结构体实现了echo.Validator接口,允许使用go-playground/validator库定义自定义验证规则。

总的来说,Gin和Echo都提供了输入验证的选项,Gin依赖于第三方库,而Echo提供了内置的验证功能。开发人员可以根据项目要求和偏好选择适合他们的方法。

数据库交互

GIN和Echo都提供了与数据库无缝集成的功能,允许开发人员轻松地与SQL和NoSQL数据库进行交互。虽然GIN提供基本的数据库功能,Echo的灵活性使其能够执行更高级的数据库操作和ORM集成。

让我们比较一下Gin和Echo框架中的数据库交互:

Gin中的数据库交互:

Gin没有内置的数据库交互支持,但它为开发人员提供了选择他们喜欢的数据库库和ORM框架的灵活性。开发人员通常使用流行的库,如gormsqlxdatabase/sql,在Gin应用中与数据库进行交互。

这是在Gin应

用中使用gorm库进行CRUD操作的示例:

package main

import (
    "github.com/gin-gonic/gin"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

type User struct {
    ID       uint   `gorm:"primaryKey"`
    Username string `gorm:"unique"`
    Email    string
}

func main() {
    // 连接到MySQL数据库
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("连接数据库失败")
    }

    // 自动迁移模式
    db.AutoMigrate(&User{})

    // 初始化Gin路由器
    r := gin.Default()

    // 创建新用户的处理器
    r.POST("/users", func(c *gin.Context) {
        var user User
        if err := c.BindJSON(&user); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        db.Create(&user)
        c.JSON(200, user)
    })

    // 获取所有用户的处理器
    r.GET("/users", func(c *gin.Context) {
        var users []User
        db.Find(&users)
        c.JSON(200, users)
    })

    // 运行Gin服务器
    r.Run(":8080")
}
Echo中的数据库交互:

与Gin类似,Echo没有提供内置的数据库交互功能,但它允许开发人员集成他们喜欢的数据库库或ORM。常见的选择包括gormsqlxdatabase/sql

这是在Echo应用中使用gorm库与MySQL数据库交互的示例:

package main

import (
    "github.com/labstack/echo/v4"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

type User struct {
    ID       uint   `gorm:"primaryKey"`
    Username string `gorm:"unique"`
    Email    string
}

func main() {
    // 连接到MySQL数据库
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("连接数据库失败")
    }

    // 自动迁移模式
    db.AutoMigrate(&User{})

    // 初始化Echo实例
    e := echo.New()

    // 创建新用户的处理器
    e.POST("/users", func(c echo.Context) error {
        var user User
        if err := c.Bind(&user); err != nil {
            return err
        }
        db.Create(&user)
        return c.JSON(200, user)
    })

    // 获取所有用户的处理器
    e.GET("/users", func(c echo.Context) error {
        var users []User
        db.Find(&users)
        return c.JSON(200, users)
    })

    // 启动Echo服务器
    e.Logger.Fatal(e.Start(":8080"))
}

在这两个示例中,我们都使用gorm库与MySQL数据库进行交互,在Gin和Echo应用中执行CRUD操作。开发人员可以根据因素,如性能、易用性和与他们应用要求的兼容性,选择他们喜欢的数据库库或ORM框架。

性能

比较Gin和Echo框架的性能可能很复杂,这取决于特定用例、服务器配置和应用实现等多种因素。然而,我可以提供一些关于它们性能特性的一般性见解。

Gin性能:

Gin以其高性能和低开销而闻名。它通过最小化不必要的功能和专注于基本功能来实现这一点。Gin的性能受益于其高效的路由引擎和轻量级设计,使其非常适合构建高性能的Web应用、API和微服务。

Gin通过使用httprouter作为其默认路由器来实现其速度,这是一个高性能的HTTP请求路由器。此外,Gin强调使用较少的反射操作,这可以有助于提高性能。

Echo性能:

Echo也设计用于高性能,旨在成为Go中最快的HTTP框架之一。它通过其简约设计、高效路由和中间件实现来实现这一点。Echo的性能受益于其使用的基于radix树的路由器,该路由器针对快速路由匹配进行了高度优化。

Echo优先考虑速度和简单性,避免不必要的开销,并为开发人员提供了一个轻量级框架,能够高效地处理高负载。

基准测试:

比较Gin和Echo的性能时,开发人员通常使用工具如Apache Bench (ab)、wrk或hey进行基准测试。这些测试通常测量各种负载条件下的吞吐量、响应时间和资源利用率等指标。

基准测试结果可能因服务器硬件、网络配置和应用复杂性等因素而异。在真实世界场景中进行彻底的基准测试是确定哪个框架对特定用例表现更好的关键。

社区和支持

GIN和Echo都拥有活跃和支持性的社区,提供广泛的文档、教程和社区贡献的资源。然而,GIN更大的用户基础和更长的历史可能导致更容易获得的资源和插件。

3. 用例

GIN

GIN非常适合性能至关重要的应用,如API和微服务,其中速度和效率是最重要的。其极简主义设计和低开销使其成为优先考虑原始性能的简单Web应用的绝佳选择。

Echo

Echo在需要广泛定制和灵活性的场景中表现出色,如构建RESTful API或具有复杂路由要求的复杂Web应用。其丰富的功能集和强大的中间件支持使其成为定制性是首要考虑因素的项目的理想选择。

决定

决定是否使用Gin或Echo取决于各种因素,包括项目要求、开发者熟悉度和特定用例。以下是何时使用每个框架的一些考虑因素:

何时使用Gin:

  1. 高性能Web应用: Gin非常适合构建需要快速响应时间和高效路由的高性能Web应用。其极简设计和对速度的专注使其成为性能至关重要的应用的流行选择。
  2. API开发: Gin的轻量级和快速特性使其成为构建API的绝佳选择。其高效的路由引擎和中间件支持使开发人员能够用最小的开销创建RESTful API。
  3. 微服务架构: Gin的低开销和快速路由引擎使其非常适合构建微服务。其简单性和性能使其成为需要多个小服务相互通信的项目的有力选择。
  4. 开发者熟悉度: 如果开发人员已经熟悉Gin框架或更喜欢其语法和特性,它可能是新项目或迁移现有应用的自然选择。

何时使用Echo:

  1. 快速原型制作: Echo的简单性和易用性使其成为快速原型制作和构建概念验证应用的绝佳选择。其简约设计和直观API使开发人员能够快速开始新项目。

  2. 中间件为中心的应用: Echo的中间件为中心的设计使其非常适合需要广泛中间件支持的应用。开发人员可以轻松插入用于身份验证、日志记录和错误处理等任务的中间件,使其灵活适用于广泛的用例。

  3. 社区和生态系统: Echo拥有不断增长的社区和第三方库及插件的生态系统。如果开发人员需要Echo生态系统中可用的特定功能或集成,它可能是他们项目的首选。

  4. 实时应用: Echo的内置对WebSockets的支持和高效的路由引擎使其成为实时应用如聊天应用、实时更新和协作工具的好选择。

对两个框架的考虑:

  1. 项目要求: 在选择Gin和Echo之间时,考虑您项目的具体要求,包括性能、可扩展性和功能集。
  2. 开发者经验: 考虑您的开发团队对每个框架的经验和熟悉度。选择开发人员舒适的框架可以带来更快的开发和更少的实施问题。
  3. 社区支持: 考虑每个框架周围的社区大小和活跃度,以及文档、教程和支持资源的可用性。
  4. 可扩展性: 虽然Gin和Echo都被设计为可扩展的,但考虑您项目的可扩展性要求,以及是否有一个框架可能更适合您的可扩展性目标。

最终,GIN与Echo之间的选择取决于您项目的具体需求和目标,以及您的开发团队的偏好和专业知识。两个框架都提供了出色的性能和灵活性,因此评估它们基于您项目的要求和限制是至关重要的。

4. 结论

总之,GIN与Echo都是强大的框架,具有不同的优势和劣势。在选择它们之间时,考虑您项目的要求、性能考虑和开发偏好。通过评估每个框架的特性、性能和社区支持,您可以选择最符合您项目目标和开发理念的框架。

记住,没有一劳永逸的解决方案,最佳框架可能会根据您项目的具体情况而变化。探索文档,尝试代码示例,并利用社区资源来做出明智的决定。

祝编码愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1489755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot + Disruptor 实现特快高并发处理

使用Disruptor做消息队列,解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级) 【基于 Disruptor 开发的系统单线程能支撑每秒 600 万订单】 核心概念: Ring Buffer 环形的缓冲区,从3.0版本开始…

SQL 查询一张卡的最新使用记录

SQL 查询一张卡的最新使用记录 1. 问题描述 1. 问题描述 一张卡,有一个底表记录这个卡的基本信息,还有一个使用卡的记录表,记录着,这张卡的使用记录,但我们要获取这张卡的最新使用记录,该如何写SQL呢&…

【Linux命令】fuser

fuser 使用文件或文件结构识别进程。 详细 fuser命令用于报告进程使用的文件和网络套接字。fuser命令列出了本地进程的进程号,哪些本地进程使用file,参数指定的本地或远程文件。 每个进程号后面都跟随一个字母,该字母指示进程如何使用该文…

Python实现CCI工具判断信号:股票技术分析的工具系列(5)

Python实现CCI工具判断信号:股票技术分析的工具系列(5) 介绍算法解释 代码rolling函数介绍完整代码data代码CCI.py 介绍 在股票技术分析中,CCI (商品路径指标)是一种常用的技术指标,用于衡量股价是否处于超…

MATLAB知识点:使用for循环时需要注意的事项

​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 节选自​第4章:MATLAB程序流程控制 在使用for循环…

HarmonyOS—HAP唯一性校验逻辑

HAP是应用安装的基本单位,在DevEco Studio工程目录中,一个HAP对应一个Module。应用打包时,每个Module生成一个.hap文件。 应用如果包含多个Module,在应用市场上架时,会将多个.hap文件打包成一个.app文件(称…

第 125 场 LeetCode 双周赛题解

A 超过阈值的最少操作数 I 排序然后查找第一个大于等于 k 的元素所在的位置 class Solution { public:int minOperations(vector<int> &nums, int k) {sort(nums.begin(), nums.end());return lower_bound(nums.begin(), nums.end(), k) - nums.begin();} };B 超过阈…

数据结构(一)综述

一、常见的数据结构 数据结构优点缺点数组查找快增删慢链表增删快查找慢哈希表增删、查找都快数据散列&#xff0c;对存储空间有浪费栈顶部元素插入和取出快除顶部元素外&#xff0c;存取其他元素都很慢队列顶部元素取出和尾部元素插入快存取其他元素都很慢二叉树增删、查找都快…

自学高效备考2025年AMC8数学竞赛:2000-2024年AMC8真题解析

今天继续来随机看五道AMC8的真题和解析&#xff0c;根据实践经验&#xff0c;对于想了解或者加AMC8美国数学竞赛的孩子来说&#xff0c;吃透AMC8历年真题是备考最科学、最有效的方法之一。即使不参加AMC8竞赛&#xff0c;吃透了历年真题600道和背后的知识体系&#xff0c;那么小…

深入理解Tomcat

目录&#xff1a; TomcatTomcat简介如何下载tomcatTomcat工作原理Tomcat架构图Tomcat组件Server组件Service组件Connector组件Engine组件Host组件Context组件 配置虚拟主机(Host)配置Context Tomcat Tomcat简介 Tomcat服务器是Apache的一个开源免费的Web容器。它实现了JavaEE…

计算机网络-物理层-传输媒体

传输媒体的分类 导向型-同轴电缆 导向型-双绞线 导向型-光纤 非导向型

卡密交易系统 卡密社区SUP系统源码 分销系统平台 分销商城系统开发

卡密社区SUP系统总控源码主站分销系统功能源码 跟以前的卡盟那种控制端差不多总控可以给别人开通&#xff0c;分销&#xff0c;主站&#xff0c;类似自己做系统商一样&#xff0c;自助发卡&#xff0c;卡密交易系统。 搭建环境Nginx1.22 mysql 5.7 php8.1 rids 7.2 安装方法…

避坑——Matlab c# 联合编程——Native

相同的库&#xff0c;Matlab生成供.net调用的库时会有两套&#xff0c;也就是Native&#xff08;本地&#xff09;&#xff0c;两套库各有优缺点&#xff0c;这这里就不说了&#xff0c;可以翻看网上其他博文 主要是MWStructArray&#xff0c;MWArray等数据交换对象有两套&…

C语言:qsort的使用方法

目录 1. qsort是什么&#xff1f; 2. 为什么要使用qsort 3. qsort的使用 3.1 qsort的返回值和参数 3.2 qsort的compare函数参数 3.3 int类型数组的qsort完整代码 4. qsort完整代码 1. qsort是什么&#xff1f; qsort中的q在英语中是quick&#xff0c;快速的意思了&#…

Platformview在iOS与Android上的实现方式对比

Android中早期版本Platformview的实现基于Virtual Display。VirtualDisplay方案的原理是&#xff0c;先将Native View绘制到虚显&#xff0c;然后Flutter通过从虚显输出中获取纹理并将其与自己内部的widget树进行合成&#xff0c;最后作为Flutter在 Android 上更大的纹理输出的…

【经验】f-string 的一些点

【经验】f-string 的一些点 省几个字别数错了对齐它现在几点 省几个字 让 f-string 给你写表达式&#xff0c;在 f-string 中使用 来自动打印表达式 a 10 b 25 print(f"{a b }") >>> a b 35别数错了 对于过大的数字难以一眼看出来它的数量级&#xf…

Access AR Foundation 5.1 in Unity 2022

如果已经下载安装了ARF但版本是5.0.7 可以通过下面的方式修改 修改后面的数字会自动更新 更新完成后查看版本 官方文档 Access AR Foundation 5.1 in Unity 2021 | AR Foundation | 5.1.2

93. 通用防重幂等设计

文章目录 一、防重与幂等的区别二、幂等性的应用场景三、幂等性与防重关系四、处理流程 一、防重与幂等的区别 防重与幂等是在 Web 应用程序和分布式系统中重要而又非常常见的问题。 防重 防重是指在多次提交同样的请求过程中&#xff0c;系统会检测和消除重复的数据&#xf…

网络安全: Kali Linux 使用 docker-compose 部署 openvas

目录 一、实验 1.环境 2.Kali Linux 安装docker与docker-compose 3.Kali Linux 使用docker-compose方式部署 openvas 4. KaliLinux 使用openvas 二、问题 1. 信息安全漏洞库 2.信息安全漏洞共享平台 3.Windows 更新指南与查询 4.CVE 查询 5.docker-compose 如何修改o…

适配Ollama的前端界面Open WebUI

在前文 本地大模型运行框架Ollama 中&#xff0c;老苏留了个尾巴&#xff0c;限于篇幅只是提了一下 Open WebUI&#xff0c;有网友留言说自己安装没搞定&#xff0c;今天我们来补上 文章传送门&#xff1a;本地大模型运行框架Ollama 什么是 Open WebUI &#xff1f; Open WebUI…