乐趣区

关于go:金三银四这些Go面试题看看你会答几道

前言

昨天群友问我能不能整顿 Go 支流框架方面的面试题,安顿!

这篇文章整顿了 gRPC、GoFrame、GoZero、GoMicro、GORM、Gin 等支流框架的 30 道面试题。

须要大厂面经的敌人们也能够 关注我 我在思否会继续更新。

gRPC

1.gRPC 是什么,有哪些长处?

gRPC 是一种高性能、开源的近程过程调用(RPC)框架,它能够使不同平台和语言之间的服务互相通信。它的长处包含:高效性、跨平台、异步流解决、反对多种语言、平安、易于应用和开源。

2.gRPC 和 REST 的区别是什么?

REST 是基于 HTTP 协定的一种格调,而 gRPC 是一个独立于协定的 RPC 框架。REST 基于资源的状态转移,应用规范的 HTTP 办法,而 gRPC 应用协定缓冲区(Protocol Buffers)进行序列化和反序列化。gRPC 反对异步流解决和双向流,而 REST 通常只反对申请 / 响应模式。

3.Protocol Buffers 是什么,为什么它被用于 gRPC 中?

Protocol Buffers 是一种语言中立、平台中立、可扩大的序列化格局,它能够用于数据交换和长久化。它被用于 gRPC 中,因为它能够实现高效的序列化和反序列化,从而进步了 gRPC 的性能和效率。

4.gRPC 的流程是什么?

gRPC 流程分为四个步骤:定义服务、生成源代码、实现服务、启动服务。首先,须要定义要实现的服务及其接口,应用 Protocol Buffers 编写接口定义文件。其次,应用编译器生成客户端和服务器端的源代码。而后,实现生成的接口。最初,启动服务器并将其部署在适当的地位。

5.gRPC 反对哪些类型的序列化?

gRPC 反对两种类型的序列化:二进制(应用 Protocol Buffers)和 JSON。其中,二进制序列化在效率和性能方面比 JSON 序列化更优良。然而,JSON 序列化在可读性方面更好,能够不便地进行调试和测试。

GoFrame

1. 什么是 GoFrame?与 Go 规范库有什么区别?

GoFrame 是一个弱小的 Go Web 利用开发框架,它提供了一系列优良的功能模块和常用工具,不便开发者疾速构建高性能、高可用的 Web 应用程序。

相较于 Go 规范库,GoFrame 提供了更多的功能模块,例如:ORM、Cache、Session、WebSocket、邮件发送等等。此外,GoFrame 也提供了更敌对的 API 和更好的性能。

2.goframe 框架中,如何应用中间件?

在 goframe 框架中应用中间件很简略。只须要在路由定义时应用中间件函数,例如:

s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {group.Middleware(MiddlewareFunc)
    group.ALL("/user", UserHandler)
})

3.goframe 框架中,如何实现定时工作?

在 goframe 框架中实现定时工作很容易。能够应用 gcron 插件。该插件提供了简略的 API 用于创立和治理定时工作,例如:

// 创立定时工作
s := gcron.NewScheduler()
s.Every(1).Hour().Do(TaskFunc)

// 开始定时工作
s.Start()

4.goframe 框架中,如何实现文件上传和下载?

在 goframe 框架中实现文件上传和下载很容易。能够应用 ghttp 的相干办法进行操作,例如:

// 文件上传
uploadFile, err := r.UploadFile("file")
if err != nil {return err}
uploadFile.Save("/path/to/save")

// 文件下载
r.Response().Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
r.Response().ServeFile(filepath)

5.GoFrame 中的 gvalid 组件是什么?如何应用?

goframe 框架提供了功能强大、应用便捷、灵便易扩大的数据 / 表单校验组件,由 gvalid 组件实现。

gvalid 组件实现了十分弱小的数据校验性能,内置了数十种罕用的校验规定,反对单数据多规定校验、多数据多规定批量校验、自定义错误信息、自定义正则校验、自定义校验规定注册、反对 i18n 国际化解决、反对 struct tag 规定及提示信息绑定等等个性,是目前性能最弱小的 Go 数据校验模块。

Go-Zero

1.Go-Zero 是什么?它的次要性能是什么?它与其余 Go 框架有什么不同?

Go-Zero 是一个基于 Go 语言的微服务开发框架。它旨在提供简略、高效和牢靠的微服务开发解决方案。Go-Zero 次要性能包含 RPC、缓存、限流、熔断、监控等。相较于其余 Go 框架,如 Gin 或 Beego,Go-Zero 更加专一于微服务开发,并提供了更多的开箱即用的性能。

2.go-zero 中如何实现 JWT 认证受权?

go-zero 中提供了 go-jwt 包来实现 JWT 认证受权。具体步骤如下:

1)定义一个 Claims 构造体,蕴含须要存储到 JWT token 中的信息。

2)通过 jwt.NewHS256([]byte(“your-secret”))创立一个 JWT 签名实例,将 Claims 构造体转换成 token 字符串。

3)通过 jwt.ParseHS256(token, []byte(“your-secret”))验证 token,并返回解析后的 Claims 构造体。

3. 如何应用 go-zero 实现异步工作?

go-zero 中提供了 go-queue 包来实现异步工作。具体步骤如下:

1)创立一个 Redis 连接池。

2)通过 queue.New(queueConfig, redisConfig)创立一个队列实例。

3)通过 producer := queue.NewProducer()创立一个生产者实例。

4)通过 consumer := queue.NewConsumer(queueConfig, redisConfig)创立一个消费者实例。

5)通过 producer.Enqueue(job)将工作放入队列。

6)通过 consumer.Consume(processor)解决队列中的工作。

4. 如何应用 go-zero 实现分布式缓存?

go-zero 中提供了 go-cache 包来实现分布式缓存。具体步骤如下:

1)创立一个 Redis 连接池。

2)通过 cache.New(cacheConfig, redisConfig)创立一个缓存实例。

3)通过 cache.Set(key, value, expireTime)将数据存入缓存中。

4)通过 cache.Get(key)从缓存中获取数据。

5. 如何应用 go-zero 实现限流?

go-zero 中提供了 go-ratelimit 包来实现限流。具体步骤如下:

1)通过 rate.NewLimiter(rate.Every(time.Second), 100)创立一个限流器实例,限度每秒解决 100 个申请。

2)通过 limiter.Allow()办法判断以后申请是否被容许,若被容许则解决申请,否则返回谬误提醒。

GIN

1.Gin 框架有什么特点?

Gin 是一个基于 Go 语言的 Web 框架,它提供了一些轻量级的工具,使得编写高性能的 Web 应用程序变得非常容易。Gin 具备疾速的路由器,中间件反对和谬误治理性能,同时还提供了自动化的 API 文档生成和参数绑定等性能。

2.Gin 框架中的中间件是什么?

中间件是 Gin 框架的一个重要概念,它是一种在解决申请之前或之后执行的函数。中间件通常用于解决申请,如身份验证,日志记录和性能监测等。在 Gin 框架中,中间件能够依照须要在路由器级别或全局级别进行注册和应用。

3. 如何在 Gin 框架中解决跨域申请?并给出代码

Gin 框架提供了一个 cors 中间件,能够用来解决跨域申请。在应用 cors 中间件时,能够指定容许跨域申请的源地址,容许的申请办法,容许的头信息等。例如:

r := gin.Default()
r.Use(cors.New(cors.Config{AllowOrigins: []string{"http://localhost:8080"},
  AllowMethods: []string{"PUT", "PATCH", "GET", "POST", "DELETE"},
  AllowHeaders: []string{"Origin"},
}))

4. 如何在 Gin 框架中实现文件上传?

在 Gin 框架中,能够应用 MultipartForm 函数来解决文件上传。MultipartForm 函数会主动解析 multipart/form-data 格局的表单数据,并将文件保留在指定的目录中。例如:

func UploadFile(c *gin.Context) {file, err := c.FormFile("file")
    if err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    filename := filepath.Base(file.Filename)
    if err := c.SaveUploadedFile(file, filename); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    c.JSON(http.StatusOK, gin.H{"filename": filename})
}

5.GoFrame 中的 gvalid 模块是什么?如何应用?

goframe 框架提供了功能强大、应用便捷、灵便易扩大的数据 / 表单校验组件,由 gvalid 组件实现。

gvalid 组件实现了十分弱小的数据校验性能,内置了数十种罕用的校验规定,反对单数据多规定校验、多数据多规定批量校验、自定义错误信息、自定义正则校验、自定义校验规定注册、反对 i18n 国际化解决、反对 struct tag 规定及提示信息绑定等等个性,是目前性能最弱小的 Go 数据校验模块。

5. 如何在 Gin 框架中实现 JWT 认证?

在 Gin 框架中,能够应用 jwt-go 库来实现 JWT 认证。JWT 认证流程通常包含登录,生成 token,验证 token 等步骤。在 Gin 框架中,能够应用中间件来实现 JWT 认证,例如:

func AuthMiddleware() gin.HandlerFunc {return func(c *gin.Context) {tokenString := c.GetHeader("Authorization")
        if tokenString == "" {c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "Authorization header required"})
            return
        }

        token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
            }          

GORM

1.GORM 如何实现一对多和多对多关系的映射?

对于一对多关系,能够应用 GORM 的 BelongsTo 和 HasMany 办法实现映射。比方:

type User struct {
    ID        uint
    Name      string
    Addresses []Address}

type Address struct {
    ID      uint
    UserID  uint
    Address string
}

// User 模型对应的表应该蕴含一个外键,指向 Address 表中的 UserID 字段
// 应用 BelongsTo 和 HasMany 办法进行关联
func (u *User) Addresses() []Address {var addresses []Address
    DB.Model(&u).Association("Addresses").Find(&addresses)
    return addresses
}

func (a *Address) User() User {
    var user User
    DB.Model(&a).Association("User").Find(&user)
    return user
}

对于多对多关系,能够应用 GORM 的 ManyToMany 办法实现映射。比方:

type User struct {
    ID       uint
    Name     string
    Articles []Article `gorm:"many2many:user_articles"`}

type Article struct {
    ID      uint
    Title   string
    Content string
    Users   []User `gorm:"many2many:user_articles"`}

// User 和 Article 之间的关系通过 user_articles 表进行映射

2. 在应用 GORM 进行数据库查问时,如何防止 N+1 查问的问题?

N+1 查问问题指的是在查问关联表时,如果应用了嵌套循环进行查问,就会产生大量的 SQL 查问。为了防止这个问题,能够应用 GORM 的 Preload 办法事后加载关联数据。比方:

// 查问 Users 以及它们的 Addresses
var users []User
DB.Preload("Addresses").Find(&users)

这个查问会一次性加载所有 User 和 Address 数据,防止了 N+1 查问问题。

3. 如何应用 GORM 进行事务管理?

GORM 的事务管理应用 Begin、Commit 和 Rollback 办法实现。比方:

tx := DB.Begin()
defer func() {if r := recover(); r != nil {tx.Rollback()
    }
}()

// 在事务中执行一系列操作
if err := tx.Create(&user).Error; err != nil {tx.Rollback()
    return err
}

if err := tx.Create(&address).Error; err != nil {tx.Rollback()
    return err
}

// 提交事务
tx.Commit()

4.GORM 的 Preload 办法和 Joins 办法有什么区别?在什么状况下应用哪种办法更好?

Preload 办法是在查问时预加载关联数据,而 Joins 办法是通过 SQL JOIN 语句连贯多个表查问数据。Preload 办法实用于关联表较少、数据量不大的状况;而 Joins 办法实用于关联表较多、数据量较大的状况。

5. 如何在 GORM 中应用原生 SQL 查问?

在 GORM 中,能够应用 Raw 办法来执行原生 SQL 查问。Raw 办法承受一个 SQL 查问字符串和可选的参数列表,并返回一个 *gorm.DB 对象,能够应用该对象进行进一步的查问操作。

上面是一个应用 Raw 办法执行原生 SQL 查问的示例:

import "gorm.io/gorm"

// ...

var users []User
result := db.Raw("SELECT * FROM users WHERE age > ?", 18).Scan(&users)
if result.Error != nil {// 处理错误}

在下面的示例中,咱们应用 Raw 办法执行了一个简略的 SQL 查问,它将返回所有年龄大于 18 岁的用户。Scan 办法用于将查问后果映射到一个 []User 对象中。

还能够应用 Exec 办法来执行不须要返回值的 SQL 查问,如插入、更新或删除数据:

result := db.Exec("DELETE FROM users WHERE age < ?", 18)
if result.Error != nil {// 处理错误}

在下面的示例中,咱们应用 Exec 办法执行一个删除语句,它将删除所有年龄小于 18 岁的用户。因为这个 SQL 不须要返回值,咱们只需查看 result.Error 是否为 nil 来判断查问是否胜利。

请留神,应用原生 SQL 查问可能会使代码更难以保护和调试,因为它们不受 GORM 的主动迁徙和其余便当性能的反对。因而,应该尽可能地应用 GORM 提供的高级查问性能。

Go-Micro

1. 什么是 go-micro?

go-micro 是一个微服务框架,它能够用于构建可伸缩和可保护的微服务应用程序。它反对多种语言和传输协定,并提供了一系列服务发现、负载平衡、消息传递和近程过程调用(RPC)等基础设施性能。

2.go-micro 反对哪些传输协定?

go-micro 反对多种传输协定,包含 HTTP、TCP 和 NATS。其中,HTTP 和 TCP 协定实用于外部服务之间的通信,而 NATS 协定则实用于跨网络边界的通信。

3. 如何应用 go-micro 进行服务发现和负载平衡?

go-micro 内置了服务发现和负载平衡性能,能够通过调用相干 API 实现。例如,能够应用 go-micro 的服务发现 API 来查找已注册的服务,并应用负载平衡 API 来将申请调配到多个实例之间。

4.go-micro 反对哪些消息传递形式?

go-micro 反对多种消息传递形式,包含同步和异步消息传递。同步消息传递应用 RPC 机制,而异步消息传递则应用音讯队列和事件驱动模式。

5. 如何应用 go-micro 进行测试?

go-micro 提供了一系列测试工具和测试框架,能够用于测试微服务应用程序的各个组件。其中,mock 测试工具能够用于模仿服务接口和行为,以及对服务进行单元测试。另外,go-micro 还提供了一些集成测试工具,例如 Docker 和 Kubernetes,能够用于测试多个服务之间的交互。

总结

有志者,事竟成,背水一战,百二秦关终属楚。

苦心人,天不负,发愤图强,三千越甲可吞吴。

就算待业环境再好,也有人找不到工作;即便待业环境不好,也必定有人能找到工作。

进行埋怨和焦虑,要想找到好工作:我的项目 + 算法 + 八股,都要硬,学起来吧!兄弟们加油。

胜利上岸

如果你不晓得如何写好简历,不晓得如何在面试中做好自我介绍和我的项目介绍,也能够在评论区留言。

也欢送大家关注我的思否账号,点赞、留言、转发。你的反对,是我更文的最大能源!

退出移动版