[golang gin框架] 40.Gin商城项目-微服务实战之Captcha验证码微服务

本次内容需要 gin框架基础知识, golang微服务基础知识才能更好理解

一.Captcha验证码功能引入

在前面,讲解了微服务的架构等,这里,来讲解前面商城项目的 Captcha验证码 微服务 ,captcha验证码功能在前台,后端 都要用到 ,可以把它 抽离出来 ,做成微服务功能

编辑

这个验证码功能封装代码captcha.go如下:

package models//验证码属性: https://captcha.mojotv.cn/
import ("github.com/mojocn/base64Captcha""image/color"
)//创建store,保存验证码的位置,默认为mem(内存中)单机部署,如果要布置多台服务器,则可以设置保存在redis中
//var store = base64Captcha.DefaultMemStore//配置RedisStore, 保存验证码的位置为redis, RedisStore实现base64Captcha.Store接口
var store base64Captcha.Store = RedisStore{}//获取验证码
func MakeCaptcha(height int, width int, length int) (string, string, error) {//定义一个drivervar driver base64Captcha.Driver//创建一个字符串类型的验证码驱动DriverString, DriverChinese :中文驱动driverString := base64Captcha.DriverString{Height:          height,                                     //高度Width:           width,                                    //宽度NoiseCount:      0,                                      //干扰数ShowLineOptions: 2 | 4,                                  //展示个数Length:          length,                                      //长度Source:          "1234567890qwertyuioplkjhgfdsazxcvbnm", //验证码随机字符串来源BgColor: &color.RGBA{ // 背景颜色R: 3,G: 102,B: 214,A: 125,},Fonts: []string{"wqy-microhei.ttc"}, // 字体}driver = driverString.ConvertFonts()//生成验证码c := base64Captcha.NewCaptcha(driver, store)id, b64s, err := c.Generate()return id, b64s, err
}//校验验证码
func VerifyCaptcha(id string, VerifyValue string) bool {// 参数说明: id 验证码id, verifyValue 验证码的值, true: 验证成功后是否删除原来的验证码if store.Verify(id, VerifyValue, true) {return true} else {return false}
}
把这个验证码做成微服务的话,就需要实现上面的两个方法: 获取验证码(MakeCaptcha), 校验验证码(VerifyCaptcha)

二.创建captcha验证码微服务服务端

  1. 创建两个文件夹,client(客户端),server(服务端)

  1. 生成服务端captcha微服务代码

在server目录下运行: go-micro new service captcha,生成captcha服务端代码
运行命令后,生成的服务端目录如下:
  1. 编写proto/captcha.proto文件

在这个文件中编写 获取验证码,验验证码相关代码

syntax = "proto3";package captcha;option go_package = "./proto/captcha";service Captcha {//获取验证码: MakeCaptchaRequest请求, MakeCaptchaRequest返回rpc MakeCaptcha(MakeCaptchaRequest) returns (MakeCaptchaResponse) {}//校验验证码: VerifyCaptchaRequest请求, VerifyCaptchaResponse返回rpc VerifyCaptcha(VerifyCaptchaRequest) returns (VerifyCaptchaResponse) {}
}//以下具体参数类型参考captcha.go中对应的方法//获取验证码请求参数
message MakeCaptchaRequest {//验证码高度int32 height =1;//验证码宽度int32 width = 2;//验证码长度int32 length = 3;
}//获取验证码返回数据
message MakeCaptchaResponse {//验证码idstring id = 1;//验证码base64编码string b64s = 2;
}//校验验证码请求参数
message VerifyCaptchaRequest {//验证码idstring id = 1;//输入的验证码string verifyValue = 2;
}//校验验证码返回数据
message VerifyCaptchaResponse {//校验的结果bool verifyResult = 1;
}
  1. 生成proto相关文件

参考 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,windows下运行 Makefile里面的proto下的代码 :protoc --proto_path=. --micro_out=. --go_out=:. proto/captcha.proto, 当然,如果是初次使用go-micro,则还需运行init下面的代码(@go xxx),引入相关包

  1. 初始化项目

在captcha目录下运行命令: go mod init captcha,初始化项目
删除go.mod后再次执行 go mod init captcha命令:
运行命令 :go mod tidy,加载项目需要的包:
上面表示:下载 "go-micro.dev/v4"这个包失败了,这时则需运行命令 go get go-micro.dev/v4, 具体参考 : [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例
在这里可能会出现 import中始终报红 的情况,解决见 : golang开启mod后import报红解决方案
  1. 启动consul服务发现

在cmd中运行命令: consul agent -dev,具体参考: [golang 微服务] 5. 微服务服务发现介绍,安装以及consul的使用,Consul集群
  1. main.go中实例化consul

具体参考: [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,代码如下:

package mainimport ("captcha/handler"pb "captcha/proto/captcha""go-micro.dev/v4""go-micro.dev/v4/logger""github.com/go-micro/plugins/v4/registry/consul"
)var (service = "captcha"version = "latest"
)func main() {//集成consulconsulReg := consul.NewRegistry()// Create servicesrv := micro.NewService(micro.Address("127.0.0.1:8081"),  //指定微服务的ip:  选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的clientmicro.Name(service),micro.Version(version),//注册consulmicro.Registry(consulReg),)srv.Init(micro.Name(service),micro.Version(version),)// Register handlerif err := pb.RegisterCaptchaHandler(srv.Server(), new(handler.Captcha)); err != nil {logger.Fatal(err)}// Run serviceif err := srv.Run(); err != nil {logger.Fatal(err)}
}
  1. handler/captcha.go封装实现proto/captcha.proto里面的rpc方法

参考 proto/captcha.proto里面的 service Captcha 方法实现,也可以参考生成的 .pb.micro.go里面生成的方法进行实现

(1).pb.micro.go参考代码:



// Client API for Captcha service
type CaptchaService interface {// 获取验证码: MakeCaptchaRequest请求, MakeCaptchaRequest返回MakeCaptcha(ctx context.Context, in *MakeCaptchaRequest, opts ...client.CallOption) (*MakeCaptchaResponse, error)// 校验验证码: VerifyCaptchaRequest请求, VerifyCaptchaResponse返回VerifyCaptcha(ctx context.Context, in *VerifyCaptchaRequest, opts ...client.CallOption) (*VerifyCaptchaResponse, error)
}

(2).handler/captcha.go代码:

一.Captcha验证码功能引入中captcha.go的代码复制到 handler/captcha.go中, 然后修修改改就可以了

1)首先,import "github.com/mojocn/base64Captcha"

把" github.com/mojocn/base64Captcha"放入import中,然后通过 go mod tidy或者 go get
github.com/mojocn/base64Captcha 引入

2).配置RedisStore

var store base64Captcha.Store = RedisStore{}复制进去

//创建store,保存验证码的位置,默认为mem(内存中)单机部署,如果要布置多台服务器,则可以设置保存在redis中
//var store = base64Captcha.DefaultMemStore//配置RedisStore, 保存验证码的位置为redis, RedisStore实现base64Captcha.Store接口
var store base64Captcha.Store = RedisStore{}
这里使用的是 redis的存储方式,故需要 初始化redis,以及实现 设置 captcha 的方法的代码,故需要在captcha下创建 models/redisCore.go, models/redisStore.go文件,具体参考: [golang gin框架] 12.Gin 商城项目-base64Captcha生成图形验证码以及分布式架构中配置Captcha
初始化redis的代码
redisCore.go代码如下:

package models//redis官网: github.com/go-redis
//下载go-redis: go get github.com/redis/go-redis/v9
//连接redis数据库核心代码import ("context""fmt""github.com/redis/go-redis/v9""gopkg.in/ini.v1""os"
)//全局使用,就需要把定义成公有的
var ctxRedis = context.Background()var (RedisDb *redis.Client
)//是否开启redis
var redisEnable bool//自动初始化数据库
func init() {//加载配置文件config, iniErr := ini.Load("./conf/app.ini")if iniErr != nil {fmt.Printf("Fail to read file: %v", iniErr)os.Exit(1)}//获取redis配置ip := config.Section("redis").Key("ip").String()port := config.Section("redis").Key("port").String()redisEnable, _ = config.Section("redis").Key("redisEnable").Bool()//判断是否开启redisif redisEnable {RedisDb = redis.NewClient(&redis.Options{Addr:     ip + ":" + port,Password: "", // no password setDB:       0,  // use default DB})//连接redis_, err := RedisDb.Ping(ctxRedis).Result()//判断连接是否成功if err != nil {println(err)}}
}
设置 captcha 的方法的代码
redisStore.go代码如下:

package models/**
使用redis需实现Store中的三个方法
type Store interface {// Set sets the digits for the captcha id.Set(id string, value string)// Get returns stored digits for the captcha id. Clear indicates// whether the captcha must be deleted from the store.Get(id string, clear bool) string//Verify captcha's answer directlyVerify(id, answer string, clear bool) bool
}*/import ("context""fmt""time"
)var ctx = context.Background()const CAPTCHA = "captcha:"type RedisStore struct {
}//实现设置 captcha 的方法
func (r RedisStore) Set(id string, value string) error {key := CAPTCHA + iderr := RedisDb.Set(ctx, key, value, time.Minute*2).Err()return err
}//实现获取 captcha 的方法
func (r RedisStore) Get(id string, clear bool) string {key := CAPTCHA + id//获取 captchaval, err := RedisDb.Get(ctx, key).Result()if err != nil {fmt.Println(err)return ""}//如果clear == true, 则删除if clear {err := RedisDb.Del(ctx, key).Err()if err != nil {fmt.Println(err)return ""}}return val
}//实现验证 captcha 的方法
func (r RedisStore) Verify(id, answer string, clear bool) bool {v := RedisStore{}.Get(id, clear)return v == answer
}
这里使用了ini.Load加载
参考: [golang gin框架] 9.Gin GORM 中使用事务以及go-ini加载.ini配置文件

3).实现获取验证码方法的业务逻辑代码

一.Captcha验证码功能引入中captcha.go 获取验证码方法代码复制到handler/captcha.go的
MakeCaptcha,然后修修改改就可以了,代码如下

//获取验证码的方法
func (e *Captcha) MakeCaptcha(ctx context.Context, req *pb.MakeCaptchaRequest, rsp *pb.MakeCaptchaResponse) error {//实现业务逻辑代码//定义一个drivervar driver base64Captcha.Driver//创建一个字符串类型的验证码驱动DriverString, DriverChinese :中文驱动driverString := base64Captcha.DriverString{Height:          int(req.Height),                                     //高度Width:           int(req.Width),                                    //宽度NoiseCount:      0,                                      //干扰数ShowLineOptions: 2 | 4,                                  //展示个数Length:          int(req.Length),                                      //长度Source:          "1234567890qwertyuioplkjhgfdsazxcvbnm", //验证码随机字符串来源BgColor: &color.RGBA{ // 背景颜色R: 3,G: 102,B: 214,A: 125,},Fonts: []string{"wqy-microhei.ttc"}, // 字体}driver = driverString.ConvertFonts()//生成验证码c := base64Captcha.NewCaptcha(driver, store)id, b64s, err := c.Generate()//把生成的验证码id,base64编码赋值给返回的rsp参数rsp.Id = idrsp.B64S = b64sreturn err
}

4).实现校验验证码方法的业务逻辑代码

一.Captcha验证码功能引入中captcha.go 校验验证码的方法代码复制到handler/captcha.go的
MakeCaptcha,然后修修改改就可以了,代码如下:

//校验验证码的方法
func (e *Captcha) VerifyCaptcha(ctx context.Context, req *pb.VerifyCaptchaRequest, rsp *pb.VerifyCaptchaResponse) error {// 参数说明: id 验证码id, verifyValue 验证码的值, true: 验证成功后是否删除原来的验证码if store.Verify(req.Id, req.VerifyValue, true) {rsp.VerifyResult = true  //校验成功} else {rsp.VerifyResult = false  //校验失败}return nil
}

4).完整代码如下


package handlerimport ("captcha/models"pb "captcha/proto/captcha""context""github.com/mojocn/base64Captcha""image/color"
)//创建store,保存验证码的位置,默认为mem(内存中)单机部署,如果要布置多台服务器,则可以设置保存在redis中
//var store = base64Captcha.DefaultMemStore//配置RedisStore, 保存验证码的位置为redis, RedisStore实现base64Captcha.Store接口
var store base64Captcha.Store = models.RedisStore{}type Captcha struct{}//获取验证码的方法
func (e *Captcha) MakeCaptcha(ctx context.Context, req *pb.MakeCaptchaRequest, rsp *pb.MakeCaptchaResponse) error {//实现业务逻辑代码//定义一个drivervar driver base64Captcha.Driver//创建一个字符串类型的验证码驱动DriverString, DriverChinese :中文驱动driverString := base64Captcha.DriverString{Height:          int(req.Height),                                     //高度Width:           int(req.Width),                                    //宽度NoiseCount:      0,                                      //干扰数ShowLineOptions: 2 | 4,                                  //展示个数Length:          int(req.Length),                                      //长度Source:          "1234567890qwertyuioplkjhgfdsazxcvbnm", //验证码随机字符串来源BgColor: &color.RGBA{ // 背景颜色R: 3,G: 102,B: 214,A: 125,},Fonts: []string{"wqy-microhei.ttc"}, // 字体}driver = driverString.ConvertFonts()//生成验证码c := base64Captcha.NewCaptcha(driver, store)id, b64s, err := c.Generate()//把生成的验证码id,base64编码赋值给返回的rsp参数rsp.Id = idrsp.B64S = b64sreturn err
}//校验验证码的方法
func (e *Captcha) VerifyCaptcha(ctx context.Context, req *pb.VerifyCaptchaRequest, rsp *pb.VerifyCaptchaResponse) error {// 参数说明: id 验证码id, verifyValue 验证码的值, true: 验证成功后是否删除原来的验证码if store.Verify(req.Id, req.VerifyValue, true) {rsp.VerifyResult = true  //校验成功} else {rsp.VerifyResult = false  //校验失败}return nil
}
  1. 注册验证码微服务服务端到服务发现(consul)

captcha目录下运行go run main.go,然后在consul UI 查看,是否注册成功
注册成功了

三.创建captcha验证码微服务客户端

  1. 在前面商城项目单体架构中生成客户端代码

前面单体架构商城中调用captcha验证码接口代码是通过接口 http://127.0.0.1:8080/admin/captcha这个访问的,具体代码如下:

adminRouters.go


//验证码
adminRouters.GET("/captcha", admin.LoginController{}.Captcha)

LoginController.go


//获取验证码,验证验证码func(con LoginController) Captcha(c *gin.Context) {id, b64s, err := models.MakeCaptcha(50, 100 ,1)if err != nil {fmt.Println(err)}c.JSON(http.StatusOK, gin.H{"captchaId":    id,"captchaImage": b64s,})
}
上面调用models下 captcha.go中的方法 MakeCaptcha()获取验证码,该captcha.go也就是 一.Captcha验证码功能引入 中captcha.go代码,这是 原来单体架构的做法,访问如下:
现在就要交给 captcha验证码微服务来处理
  1. 首先把server/captcha/proto文件夹复制到项目中

  1. 封装captcha.go验证码微服务客户端方法

前面章节对于验证码这块儿, 前端后台都需要进行 验证码逻辑处理,调用的方法都是models/captcha.go下面的方法,故在进行微服务客户端处理时,也在这里面进行修改

(1).配置consul服务发现

首先,在models下创建initCaptchaConsul.go,配置consul服务发现,以便调用,代码如下:
package models//微服务客户端配置: 初始化consul配置,当一个项目中多个微服务时,就很方便了
//建议:一个微服务对应一个客户端,这样好管理import ("github.com/go-micro/plugins/v4/registry/consul""go-micro.dev/v4/client""go-micro.dev/v4/registry"
)//CaptchaClient: 全局变量 在外部的包中可以调用
var CaptchaClient client.Client//init 方法: 当程序运行时就会自动执行
func init() {consulRegistry := consul.NewRegistry(//指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client,建议一个微服务对应一个consul集群的clientregistry.Addrs("127.0.0.1:8500"),)// Create servicesrv := micro.NewService(micro.Registry(consulRegistry),)srv.Init()CaptchaClient = srv.Client()
}
在这里,也许没有引入,执行命令:go mod tidy引入对应的包

(2).完善models/captcha.go中的MakeCaptcha获取验证码方法

在该方法中实现调用获取验证码微服务逻辑功能
//调用获取验证码微服务
func MakeCaptcha(height int, width int, length int) (string, string, error) {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient := pbCaptcha.NewCaptchaService("captcha", CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的MakeCaptcha方法rsp, err := captchaClient.MakeCaptcha(context.Background(), &pbCaptcha.MakeCaptchaRequest{Height:     int32(height),  //验证码高度Width:     int32(width),  //验证码宽度Length:     int32(length),  //验证码长度})//判断是否获取成功if err != nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.Id, rsp.B64S, err
}

(3).完善models/captcha.go中的VerifyCaptcha校验验证码方法

在该方法中实现调用校验验证码微服务逻辑功能
//调用校验验证码微服务
func VerifyCaptcha(id string, VerifyValue string) bool {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient := pbCaptcha.NewCaptchaService("captcha", CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的VerifyCaptcha方法rsp, err := captchaClient.VerifyCaptcha(context.Background(), &pbCaptcha.VerifyCaptchaRequest{Id:     id,  //验证码IdVerifyValue:     VerifyValue,  //验证码})//判断是否获取成功if err != nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.VerifyResult
}

(4).完整代码如下

package models//验证码属性: https://captcha.mojotv.cn/
import ("context""github.com/prometheus/common/log"pbCaptcha "goshop/proto/captcha"
)//调用获取验证码微服务
func MakeCaptcha(height int, width int, length int) (string, string, error) {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient := pbCaptcha.NewCaptchaService("captcha", CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的MakeCaptcha方法rsp, err := captchaClient.MakeCaptcha(context.Background(), &pbCaptcha.MakeCaptchaRequest{Height:     int32(height),  //验证码高度Width:     int32(width),  //验证码宽度Length:     int32(length),  //验证码长度})//判断是否获取成功if err != nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.Id, rsp.B64S, err
}//调用校验验证码微服务
func VerifyCaptcha(id string, VerifyValue string) bool {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient := pbCaptcha.NewCaptchaService("captcha", CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的VerifyCaptcha方法rsp, err := captchaClient.VerifyCaptcha(context.Background(), &pbCaptcha.VerifyCaptchaRequest{Id:     id,  //验证码IdVerifyValue:     VerifyValue,  //验证码})//判断是否获取成功if err != nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.VerifyResult
}
  1. 校验captcha验证码微服务功能

(1).先启动服务端

见前面代码

(2).启动客户端

在项目根目录下运行 :go run main.go,启动项目

(3).访问http://127.0.0.1:8080/admin/captcha

访问 http://127.0.0.1:8080/admin/captcha看看是否显示验证码相关数据
显示了,说明调用了验证码微服务操作

(4).校验验证码微服务操作是否成功

访问后台登录页面,输入用户名,密码,验证码,看看是否成功
好了,captcha验证码微服务客户端操作完成,在这里,上面讲解的是web页面调用captcha验证码微服务功能,下面则讲解Go Web Restfull APi 调用Captcha验证码微服务

四.Go Web Restfull APi 调用Captcha验证码微服务

Go Web Restfull APi 调用Captcha验证码微服务主要是给手机app,微信小程序等提供接口,架构如下
  1. 创建一个api的Gin项目,并配置routers

这里直接以上面项目为案例,在routers下创建 apiRouters.go路由文件
  1. 构建验证码相关接口,代码如下

在controllers/api/ CaptchaController.go下编写获取验证码,校验验证码相关逻辑,代码如下:
package apiimport ("context""github.com/gin-gonic/gin""github.com/prometheus/common/log""goshop/models"pbCaptcha "goshop/proto/captcha""net/http"
)type CatpchaController struct {
}//获取验证码的接口(调用验证码微服务操作)
func (con CatpchaController) MakeCaptcha(c *gin.Context) {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient := pbCaptcha.NewCaptchaService("captcha", models.CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的MakeCaptcha方法rsp, err := captchaClient.MakeCaptcha(context.Background(), &pbCaptcha.MakeCaptchaRequest{Height:     100,  //验证码高度Width:     200,  //验证码宽度Length:     4,  //验证码长度})//判断是否获取成功if err != nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回c.JSON(http.StatusOK, gin.H{"captchaId": rsp.Id,"B64s": rsp.B64S,})
}//校验验证码接口
func (con CatpchaController) VerifyCaptcha(c *gin.Context) {//获取请求参数verifyId := c.PostForm("verifyId")verifyValue := c.PostForm("verifyValue")// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient := pbCaptcha.NewCaptchaService("captcha", models.CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的VerifyCaptcha方法rsp, err := captchaClient.VerifyCaptcha(context.Background(), &pbCaptcha.VerifyCaptchaRequest{Id:     verifyId,  //验证码IdVerifyValue:     verifyValue,  //验证码})//判断是否获取成功if err != nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回if rsp.VerifyResult == true {  // 说明验证通过c.JSON(http.StatusOK, gin.H{"message": "验证验证码成功","success": true,})} else {c.JSON(http.StatusOK, gin.H{"message": "验证验证码失败","success": false,})}
}
  1. 校验api请求是否成功

请求http://127.0.0.1:8080/api/MakeCaptcha,看看是否返回对应的验证码json请求
从上图看得出来,返回了对应验证码的数据的,把 B64s中的数据放入<img src="B64s" />中,就可以了,展示的图片如下:

然后校验验证码,一般通过postman校验

好了,Go Web Restfull APi 调用Captcha验证码微服务 获取验证码,以及校验验证码api接口操作就完成了

[上一节][golang gin框架] 39.Gin商城项目-微服务实战之微服务架构

[下一节][golang gin框架] 41.Gin商城项目-微服务实战之后台Rbac微服务(用户登录 、Gorm数据库配置单独抽离、 Consul配置单独抽离)

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

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

相关文章

《零基础入门学习Python》第063讲:论一只爬虫的自我修养11:Scrapy框架之初窥门径

上一节课我们好不容易装好了 Scrapy&#xff0c;今天我们就来学习如何用好它&#xff0c;有些同学可能会有些疑惑&#xff0c;既然我们懂得了Python编写爬虫的技巧&#xff0c;那要这个所谓的爬虫框架又有什么用呢&#xff1f;其实啊&#xff0c;你懂得Python写爬虫的代码&…

20 QTreeWidget控件

代码&#xff1a; //treeWidget树控件//1&#xff1a;设置头部标签 QStringList()匿名对象创建ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄介绍");//2&#xff1a;设置itemQTreeWidgetItem * liItem new QTreeWidg…

Linux 系统中异常与中断

文章目录 异常与中断的关系中断的处理流程异常向量表Linux 系统对中断的处理ARM 处理器程序运行的过程程序被中断时&#xff0c;怎么保存现场Linux 系统对中断处理的演进Linux 对中断的扩展&#xff1a;硬件中断、软件中断硬件中断软件中断 中断处理原则&#xff1a;耗时中断的…

【面试题】万字总结MYSQL面试题

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 1、三大范式 2、DML 语句和 DDL 语句区别 3、主键和外键的区别 4、drop、delete、truncate 区别 5、基础架构 6、MyISAM 和 InnoDB 有什么区别&#xff1f; 7、推荐自增id作为…

【C++】STL---list基本用法介绍

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…

Kotlin基础(七):数据类和封闭类

前言 本文主要讲解kotlin数据类&#xff08;DataClass&#xff09;和封闭类&#xff08;SealedClasses&#xff09;&#xff0c;包括使用数据类&#xff0c;对象复制&#xff0c;数据类成员的解构&#xff0c;使用封闭类&#xff0c;以及数据类和封闭类在Android开发中的应用。…

el-select和el-checkBox实现下拉菜单全选功能

el-select 和 el-checkbox 实现下拉菜单全选功能 示例代码&#xff1a; <el-selectpopper-class"select-container"v-model"ids"placeholder"请选择目标":multiple-limit"20"multiplefilterablecollapse-tagsclass"wd400&qu…

uniapp 小程序 查看评价

查看评价效果图&#xff1a; 评分组件在上一篇文章&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; <template><view class"view-comments"><view class"evaluate-box"><view class"ti…

使用Gin框架搭配WebSocket完成实时聊天

文章目录 前言实时聊天聊天功能测试发送信息 前言 在写项目的时候&#xff0c;需要完成实时聊天的功能&#xff0c;于是简单的学习下WebSocket&#xff0c;想知道WebSocket是什么的小伙伴可以去网上别的地方学习一下。 要实现实时聊天&#xff0c;网上的大部分内容都是Spring…

Rust操作MySQL

查询 本部分是对 「Rust入门系列」Rust 中使用 MySQL[1]的学习与记录 经常使用的时间处理库&#xff1a; chrono 流式查询使用&#xff1a; query_iter 输出到Vec使用&#xff1a; query 映射到结构体使用&#xff1a; query_map 获取单条数据使用&#xff1a; query_first 命名…

小程序体验版上线注意事项

1.接口域名必须是https&#xff0c;有ssh证书。不能用ip地址。 2.需要在微信公众平台进行配置 微信公众平台->开发-> 开发管理->开发设置 对服务器域名和业务域名进行配置对业务域名进行配置时&#xff0c;需要下载校验文件&#xff0c;放在域名根目录下

【Node.js 安装】Node.js安装与使用教程

Node.js 安装 Node.js 是什么那什么是运行时 如何安装 Node.jsNode 使用教程 Node.js 是什么 先说结论&#xff0c;Node.js 它是一套 JavaScript 运行环境&#xff0c;用来支持 JavaScript 代码的执行 JavaScript 诞生于 1995 年&#xff0c;几乎是和互联网同时出现&#xf…

十分钟掌握 Vim 编辑器核心功能

十分钟掌握 Vim 编辑器核心功能 文章目录 十分钟掌握 Vim 编辑器核心功能&#x1f468;‍&#x1f3eb;内容一&#xff1a;前言【Vim是什么】&#x1f468;‍&#x1f52c;内容二&#xff1a;Vim 常用模式&#x1f468;‍&#x1f680;内容三&#xff1a;基本操作&#x1f468;…

【C语言】表达式求值相关问题汇总—>隐式类型转换(整型提升)、算数转换与操作符优先级汇总(收藏查阅)

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负。 目录 前言&#xff1a; 一、隐式类型转换 &#xff08;一&#xff09;整型提升的意义…

Dubbogo 详解

Dubbogo 详解 简介 dubbo功能很强大的微服务开发框架&#xff0c;支持多种通信协议&#xff0c;并具有流量治理的功能。 dubbo在有了大转变&#xff0c;拥抱了云原生&#xff0c;从哪些方面可以体现呢&#xff1f; 推出了自己的Trip协议修复了服务发现的级别&#xff0c;之…

华为云CodeArts产品体验的心得体会及想法

文章目录 前言CodeArts 的产品优势一站式软件开发生产线研发安全Built-In华为多年研发实践能力及规范外溢高质高效敏捷交付 功能特性说明体验感受问题描述完结 前言 华为云作为一家全球领先的云计算服务提供商&#xff0c;致力于为企业和个人用户提供高效、安全、可靠的云服务。…

算法与数据结构(二十一)前缀和数组差分数组

前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。 1. 一维数组中的前缀和 先看一道例题&#xff0c;力扣第 303 题「区域和检索 - 数组不可变」&#xff0c;让你计算数组区间内元素的和&#xff0c;这是一道标准的前缀和问题&#xff1a; 题目要求你实现这样一个…

【C++初阶】---C++入门篇

文章目录 前言&#x1f31f;一、C历史介绍&#x1f31f;二、命名空间&#x1f30f;2.1.C与C对比&#x1f30f;2.2.命名空间的引入&#x1f30f;2.3.命名空间定义&#x1f30f;2.4.命名空间的使用&#x1f30f;2.5.对上述C与C对比中的第二个不同点的解释&#xff1a; &#x1f3…

TableGPT: Towards Unifying Tables, Nature Language and Commands into One GPT

论文标题&#xff1a;TableGPT: Towards Unifying Tables, Nature Language and Commands into One GPT 论文地址&#xff1a;https://github.com/ZJU-M3/TableGPT-techreport/blob/main/TableGPT_tech_report.pdf 发表机构&#xff1a;浙江大学 发表时间&#xff1a;2023 本文…

使用GGML和LangChain在CPU上运行量化的llama2

Meta AI 在本周二发布了最新一代开源大模型 Llama 2。对比于今年 2 月发布的 Llama 1&#xff0c;训练所用的 token 翻了一倍&#xff0c;已经达到了 2 万亿&#xff0c;对于使用大模型最重要的上下文长度限制&#xff0c;Llama 2 也翻了一倍。 在本文&#xff0c;我们将紧跟趋…