abcnull
INTP男,好结交志趣相投的朋友,微信:a463279708,希望能共同努力进步!你们的支持将是我写下去的不竭动力......
展开
-
go gorm想要查询数据按照where in中的数据进行排序
遇到一个比较常见的场景,就是因为一般不太建议联合查询,所以在后端代码中进行多张表分别查询,但是最终的结果需要按照第一张表的某个字段去排序该怎么做呢?原创 2023-03-10 18:45:35 · 793 阅读 · 0 评论 -
实际开发中如何存储密码(md5加盐bcrypt)golang
一般前端把用户密码发给服务端,服务端实际业务中如何存储密码呢,如何存储密码才能保证密码不被开发者获取或者被截取呢,保证密码的安全。原创 2023-03-10 10:52:53 · 601 阅读 · 0 评论 -
gin中间件middleware两种声明方式的区别
【代码】gin中间件middleware两种声明方式的区别。转载 2023-03-09 16:07:29 · 213 阅读 · 0 评论 -
接口幂等性的通用解决方案golang版
接口的幂等性是指:用户对同一个操作发起多次请求,系统的设计需要保证其多次请求后结果是一致的。常见的如支付场景,连续快速点击两次支付 10 元,不应该扣费 20,第一次应该扣费成功,第二次则应该失败什么场景要考虑幂等性设计在现在公司里头,都在做分布式划分,一个大型系统会拆成比较多的模块,不同的模块用集群来部署,上游服务调用下游服务的形式,比如 rpc 调用,但是由于网络抖动等原因,可能会造成服务迟迟没有响应,用户端可能多次点击再一个就是支付场景也必须得考虑一下幂等性的问题。原创 2023-02-27 22:59:03 · 993 阅读 · 3 评论 -
golang文件路径判定是否存在以及创建路径创建文件
【代码】golang文件路径判定是否存在以及创建路径创建文件。原创 2022-09-19 20:55:30 · 1760 阅读 · 0 评论 -
golang单例模式
单例模式,一种很常用的设计模式,特点是:类构造器私有化因为不能被外部构造,拥有自己的类属性,对外暴露获取实例的静态函数说白了就是返回一个实例出去,但是这个实例是只能内部构造一次,不允许外部构造非线程安全。当正在创建时,有线程来访问此时ins = nil就会再创建,单例类就会有多个实例了懒汉加锁单例懒汉单例线程不安全,那就加个锁呗,但加锁是要付出一些成本的懒汉加双重锁sync.Once单例(荐)sync.Once 是 golang 提供的方法,一旦执行一次,就不再执行饿汉单例线程安全,但是如果原创 2022-06-13 23:10:06 · 945 阅读 · 0 评论 -
golang单元测试
若有一个需要被单测的函数现在写一个单测单测主函数初始化逻辑可以放在TestMain中,然后测试入口就可以从TestMain中进入单测断言golang的标准库没有断言,那么为什么呢?看看官方解释:即如果想要写单测,可以考虑引用一个第三方库,这个比较常用然后常见的断言手段当然用可以打印出很多信息...原创 2022-06-06 23:18:16 · 585 阅读 · 1 评论 -
golang文件读写操作
文章目录golang 常用输入输出常用:读取文件成 []byte一种是生成 File,再利用 File 读或者写;另一种通过 ioutil 包直接对某路径下文件进行读写// 依据相对路径拿到 *File 类型jsonFile, err := os.Open(path)defer jsonFile.Close()// 将读取的文件读成 []bytejsonData, err := ioutil.ReadAll(jsonFile)// 通过序列化机制,把 []byte 转成特定结构 struc原创 2022-05-29 22:15:12 · 1058 阅读 · 0 评论 -
golang简单随机数生成
文章目录rand 随机数rand 随机数// 设置随机种子rand.Seed(time.Now().UnixNano())// 产生一个 [0, 10) 的随机整数fmt.Println(rand.Intn(10))原创 2022-05-29 21:29:56 · 341 阅读 · 0 评论 -
Golang代码中os系统包使用
文章目录os 包os 包获取/设置环境变量// 获取环境变量,返回 stringfmt.Println(os.Getenv("PATH"))// 设置环境变量os.Setenv("XXX_HOME", "yyy")设置环境变量除了公司平台一般可配置以外,本地 ide golang 中,运行那里的 edit configuration 也可配置运行时可带 string 参数切片// 运行时带参数切片fmt.Println(os.Args)还可通过 golang 执行一些 linu原创 2022-05-29 21:21:07 · 831 阅读 · 0 评论 -
golang中time包时间处理
文章目录time 包time 包UTC or CSTutc 是世界协调时间(标准),cst 是中央标准时间当UTC时间为0点时,中国CST时间要加 8h,即为8点AM当UTC时间为0点时,美国CST时间要减 6h,即为18点PM返回 Time 时间类型// 返回当前时间 Time 类型now := time.Now()fmt.Printf("%v", now)// 输出2022-05-29 19:47:46.435119 +0800 CST m=+0.000401431// 返回指原创 2022-05-29 20:54:19 · 1064 阅读 · 0 评论 -
代码:go研发实际生产中hmac的验签过程
文章目录简介验签代码简介go 开发生产中常用的验签的包是 hmac 包服务端一般验签流程是:发送方和接收方共享一个密钥 secret,然后发送方要发消息给接收方,会把原始信息(明文)和使用 secret 计算的 hmac 值(签名)一起发过去,接收方接收到消息之后,使用自己手中的 secret 把传过来的原始信息重新计算一下 hmac,看自己计算的 hmac 和发送过来的 hmac 如果匹配就认为验签成功为什么不怕数据中途截获呢?因为如果别人中途截获了数据,知道原始信息和签名,但是无法反向解析,比如原创 2022-04-01 12:35:01 · 942 阅读 · 0 评论 -
golang web项目结构
文章目录简介gin http项目结构thrift rpc 项目结构项目结构简介我们知道 java 项目结构是请求达到路由层控制器 controller,然后 controller 会去调用 service 层逻辑代码,然后 service 层会去调用 dao 层的接口方法,其实 dao 层都是以接口的形式提供,然后这些接口里头的都是操作数据库的方法,然后与 dao 层对应着的有一个 mapper,mapper 是以 xml 形式提供的,与 dao 层中的接口相对应,xml 中实际就是实现了 dao 接原创 2022-03-31 13:06:35 · 2947 阅读 · 0 评论 -
加签和验签
文章目录基本概念加签验签举例总结抽象基本概念明文/密文:明文是没有经过加密的数据,密文是加密后的数据公钥/私钥:公钥和私钥是相对来说的,一般公钥用来解密,私钥用来解密对称加密/非对称加密:对称加密公钥和私钥相同,非对称加密公钥和私钥不同,不论公钥私钥都可被称为密钥加密/解密:加密是明文转密文,解密是密文转明文原始报文/摘要/数字签名:原始报文即为经过加密处理的报文,当原始报文经过了一些 hash 算法处理之后就成为了数字摘要,如果经过sha256 或者 RSA 处理之后,当数原创 2022-03-15 14:38:24 · 5148 阅读 · 1 评论 -
gin项目封装errcode和message
文章目录简介指定业务项目的错误码和错误信息考虑让原本注册的路由函数返回指定格式路由函数具体怎么接入使用简介写 gin 的项目其实会有一个感悟就是 gin 通过 Get 和 Post 函数可以注册路由,其中只需要传入路由函数名即可func(*gin.Context)类型,然后路由函数最后一般都是c.JSON()形式来返回要响应的 struct,但是有时候路由函数中的一些出现一些错误需要我们在一些 if 语句中也能返回响应,如果这样的 if 多了之后,一个路由函数就会出现很多c.JSON(),而且其中会写一原创 2022-03-01 23:12:06 · 1252 阅读 · 0 评论 -
gin框架使用JWT鉴定权限
文章目录简介引入源码代码模型router 中写法middlerware 中写法ParseToken 解析 token string => *jwt.TokensecretKey 密钥AuthClaims 结构体GenerateToken 生成 *jwt.Tokenlogin 登录后响应头设置 cookie常规 HandlerFunc 使用用户信息简介目前主流的 gin 的鉴权框架有 github 上的 dgrijalva/jwt-go 和 golang-jwt/jwt,但是 dgrijalva/原创 2022-02-10 23:32:03 · 2339 阅读 · 0 评论 -
gin框架自带的一些的鉴定权限机制 session cookie
文章目录gin.Cookie() 使用gin.BasicAuth() 中间件github.com/gin-contrib/sessions 包实际生产中使用鉴权方式gin.Cookie() 使用下面的小例子可以使用 postman 来请求,只要服务启动了,其实主要就是 Cookie 函数来拿到请求头的 value,用 SetCookie 函数来设置 cookie 的 valuefunc main() { r := gin.Default() r.Get("/cookie", handler.M原创 2022-02-08 23:35:55 · 2761 阅读 · 2 评论 -
gin框架快速入门
文章目录背景安装使用非常简单的例子Restful API 的实现Get/Post配置路由配置路由参数配置分组路由接收 Query 参数[传入]Query/DefaultQuery 接收单个参数[传入]QueryArray 接收多个参数[传入]QueryMap 接收多个参数[传入]请求提 query 转 struct接收表单数据[传入]PostForm 接收表单数据[传入]请求体 form 表单转 struct文件上传[传入]单文件上传[传入]多文件上传JSON 的使用[输出]struct 转 json[输出原创 2022-02-07 11:13:19 · 2821 阅读 · 1 评论 -
初学者go中易错点语法知识
文章目录包相关声明相关数组相关切片相关map 相关chan 相关函数相关struct 相关接口相关错误异常相关条件语句相关线程安全相关fmt 相关builtin 相关其他包相关同一个文件夹下包声明需要一致,可以是和文件夹不同名字匿名引用是为了使用包中初始化的方法 init 方法,比如说使用 mysql 时候,常常会引用 driver,那个 driver 就是匿名引用import _ "github.com/xxx"import 引入的方式import "xxx"import (原创 2022-01-23 23:52:48 · 461 阅读 · 0 评论 -
golang.org/x/sync/errgroup管控多协程生命周期
文章目录errgroup 包结构体 group函数 WithContext函数 Wait函数 Goerrgroup 包errgroup 是 go 官方提供的一个额外的库golang.org/x/sync/errgroup,它可以将一个大的任务拆解成多个任务来并发的执行,并且很容易的管控着并发协程的生命周期底层通过 waitgroup 来控制让所有其他协程运行完主协程 wait 才会被放行底层通过 context 的只读 channel 来管控子协程的生命周期,如果有一个子协程有 error 返回,那原创 2021-11-12 23:20:38 · 839 阅读 · 0 评论 -
golang中context包来管控多协程的生命周期
文章目录context 简介接口 Context接口 canceler整型 emptyCtx & 函数 Background & 函数 TODO结构体 cancelCtx & 函数 WithCancel结构体 timerCtx & 函数 WithDeadline & 函数 WithTimeout结构体 valueCtx & 函数 WithValueContext 使用建议context 简介为什么要用 context 呢?因为在并发编程中,一般我们可以通过原创 2021-11-12 20:59:29 · 1340 阅读 · 0 评论 -
golang并发模型-moving on继续模型
文章目录谁返回结果最快用谁的结果,一旦返回最快的结果被拿到了,函数就直接解除阻塞往下执行,无需关注其他慢的结果场景:比如说发送几个 goroutine 去请求某一个数据库,谁最快返回,ch 就被阻塞,然后走 default 分支直接退出了func Query(conns []Conn, query string) Result { ch := make(cahn Result) for _, conn := range conns { go func(c Conn) {原创 2021-11-08 22:47:59 · 258 阅读 · 0 评论 -
golang模版-使用close关闭chan来规避chan阻塞导致的协程泄漏
文章目录close 解除读取 chan 阻塞深入思考建议扩充close 解除读取 chan 阻塞上方的例子是通过 waitgroup 等待让所有的 goroutine 都运行完毕之后,wait 函数才会被放行(注意加上超时处理)。试想一下存在这样的琴况,如果 wait 函数要等待所有 goroutine 结束才能放行,可是这些 gouroutine 因为从 chan 读取不到数据而造成阻塞,则这些 goroutine 可能一直陷入阻塞,而 wait 函数也一直无法放行,就有可能陷入死锁,所以我们有另一种原创 2021-11-07 19:16:17 · 1474 阅读 · 0 评论 -
golang时间格式化
文章目录简介例子简介时间格式在程序,数据库,日志中都是非常重要的角色,go 中自带有 time 包方便我们来进行时间的格式化操作例子func main() { // now now := time.Now() // year year := now.Year() // month month := now.Month() // day day := now.Day() // hour hour := now.Hour() // minute minute := now.Min原创 2021-10-31 23:34:49 · 3672 阅读 · 0 评论 -
golang使用三方库json_iterator序列化和反序列化
文章目录简介序列化struct->jsonmap->json反序列化json->structjson->map简介golang 中 json 序列化和反序列化除了使用自带的 encoding/json 库之外,还可以使用第三方的 “github.com/json-iterator/go” 库,json_iterator 工具号称是最快的序列化和反序列化 json 工具,Jsoniter Golang 版本的编解码能力比普通 encoding/json 库快 6 倍实际中具体的原创 2021-10-31 23:09:13 · 1215 阅读 · 0 评论 -
golang使用标准库encoding/json序列化和反序列化
文章目录简介序列化struct->jsonmap->json反序列化json->structjson->mapgolang中json序列化与反序列化简介golang 中 json 的序列化可以使用 golang 官方库中自带的 encoding/json 序列化工具,也可以使用第三方库中的 json-iterator,它更加高效encoding/json 中序列化和反序列化的方法中,被序列化的类型和 []byte 类型是需要注意的关键数据类型序列化序列化是将对象的状态信息原创 2021-10-31 22:26:16 · 709 阅读 · 0 评论 -
golang常用的几种格式化输出语句
文章目录format 格式解释%v值的默认格式,输出结构体%+v输出结构体显示字段名%T输出值的类型%%输出值并添加百分号%d输出标准的十进制格式化%f输出标准的十进制小数格式化%s输出字符串%f输出标准的十进制小数格式化举例一:type UserInfo struct { Name string Doing string Book string}func main() { user := UserIn原创 2021-10-30 21:25:30 · 585 阅读 · 0 评论 -
go工程化处理error实践
文章目录简介error 基础sentinel error(哨兵错误)error types(自定义错误类型)opaque errors(非透明错误)wrap error(包装错误)go 1.13 基础库 errors其他 error 处理技巧简介golang 中的 error 机制是很多人吐槽比较多的点,但是其实 golang 的 error 处理机制在我看来有很多好处。golang 函数的多返回值可以很容易的带上 error 信息先说结论:实际工程中建议使用 pkg/errors 中的错误处理机制,原创 2021-10-30 14:55:02 · 547 阅读 · 0 评论 -
golang模版-多协程的安全退出(避免goroutine泄漏)模版
文章目录前置知识多协程安全退出粗糙版多协程安全退出完美版golang 中很容易开启多个协程,那开启的这么多协程如何保证在 main 函数结束前这些协程都是安全退出呢(信道都安全关闭),这里我们使用到了 select,close 关闭信道函数以及 sync.WaitGroup 函数前置知识当信道被 close 掉之后,如果信道中有缓存,那么被关闭后是不能写的但是依然可以读取缓存数据,缓存被读完后读到的就是 0;如果信道中没有缓存,那么信道被关闭后直接读到的就是 0多协程安全退出粗糙版func wor原创 2021-10-24 22:51:30 · 2767 阅读 · 0 评论 -
golang模版-使用sync.WaitGroup把一组协程当作整体来完成的模版
文章目录golang 中对于协程提供了非常多好用的函数,其中 sync.WaitGroup 可以让我们把一批协程当成一组要运行的程序,等这一批程序运行完之后放可以运行后面的程序func function() { // 一些操作 // sync.WaitGroup var wg sync.WaitGroup // 开启一个循环 for i := 0; i < 10; i++ { // wg 加一 wg.Add(1) // 开启一个新协程 go fun() { //原创 2021-10-24 22:19:49 · 2290 阅读 · 0 评论 -
golang并发模型-发布订阅并发模型
文章目录简介发布订阅模型简介发布订阅模型简写为 pub/sub 模型,消息生产者成为了发布者 publisher,消息消费者成为了订阅者 subscriber。传统生产者消费者模型是将消息发送到一个队列中,发布订阅模型是将消息发布给一个主题与其把发布订阅者模式我更喜欢理解成发布订阅器模式,订阅者更像是一个订阅器,发布者中含有多个订阅器,每个订阅器有自己的一种订阅规则,同时订阅器中会存在多个不同的订阅信息,但是这些订阅信息都是满足该订阅器的订阅规则的发布订阅模型发布订阅支持包package pub原创 2021-10-24 21:35:04 · 577 阅读 · 0 评论 -
golang并发模型-生产者消费者并发模型
文章目录简介生产者消费者模型简介并发不是并行,并发更多是关注程序设计层面的,并行是程序运行层面的。另外需要注意的是 golang 中对于无缓冲的 channel 在接收到一个数据时候就会直接陷入阻塞但是对于有缓冲的 channel,在 channel 满载后再有一个数进入才会陷入阻塞并发编程中最常见的例子就是生产者消费者模型了,大致就是生产者生产一批数据,放到结果队列中,消费者从结果队列中取出数据来消费,这样生产者和消费者就是两个异步的流程,当结果队列中没有数据,消费者就陷入了饥饿等待的状态,当结果队原创 2021-10-24 15:11:00 · 2240 阅读 · 0 评论 -
golang通过内置net/rpc实现实现一个简单rpc服务并做优化
文章目录规则原始版的 rpc 服务服务端注册 rpc 服务客户端请求 rpc 服务进一步:更优美的 rpc服务端 rpc 服务优化客户端调用优化进一步:跨语言的 rpcrpc 服务端客户端进一步:http 中访问 rpcrpc 客户端总结规则使用 golang 中的 net/rpc,需要将被注册为 rpc 服务的对象满足以下规则:方法只能有两个可序列化的参数方法中第二个参数是指针类型方法返回一个 error 类型方法是公开的方法type HelloService struct {}fu原创 2021-10-22 01:02:39 · 831 阅读 · 0 评论 -
切片的add和delete等功能实现
文章目录背景切片 Delete切片 Insert背景golang 的切片和 java 的 ArrayList 还是有区别的,不支持随机的增删操作,而 ArrayList 中的方法还是很齐全的,golang 只有最基础的 append 追加操作,所以其他的还需要程序员自己实现切片 Deletefunc Delete(sli []int, index int) []int { sli = append(sli[:index], sli[index+1:]...) return sli}Dele原创 2021-09-27 00:57:01 · 435 阅读 · 0 评论 -
go连接数据库
文章目录原生 sql 连接数据库使用 gorm 连接数据库原生 sql 连接数据库func main() { // 账号 username := "root" // 密码 password := "123456" // mysql 服务地址 host := "127.0.0.1" // 端口 port := 3306 // 数据库名 Dbname := "Dbname" // 拼接 mysql dsn,即拼接数据源,下方 {} 中的替换参数即可 //原创 2021-09-22 18:51:51 · 439 阅读 · 0 评论 -
golang模版-使用time.After超时功能模版
golang 中存在通道 chan,golang 中有一套比较标准的超时重试机制,但是需要借助 time 包中的函数func main() { c := make(chan int) fmt.Println(time.Now()) // 开启协程,往信道传数据 go func() { tīme.Sleep(time.Second * 4) c <- 0 }() for { select { case <-c: // 如果超时 1s 那么久执行这里原创 2021-09-15 06:28:01 · 597 阅读 · 0 评论 -
golang模版-net包进行端口监听模版
简介net 包提供了可移植的网络 I/O 接口,包括 TCP/IP、UDP、域名解析和Unix 域 socket使用监听常用模版关键函数 Dial Listen Accept端口监听// 监听端口listen, err := net.Listen("tcp", "127.0.0.1:8080")if err != nil { // 处理错误}// 不断循环接收for { // 在没有接收到数据前这里是阻塞的 conn, err := listen.Accept() if err原创 2021-09-15 06:00:14 · 1105 阅读 · 0 评论 -
golang中的flag包
背景golang 中有一个好用的 flag 包一个执行文件,我们可以启用不同的参数来控制程序的行为,如果程序希望做到启动参数用户可配启动参数有说明启动参数有默认值我们该怎么做呢?这时候 flag 包就起到作用了示例func main() { // 设置 port = flag.Int("port", 1234, "解释xxx") // 解析 flag.Parse() fmt.Println("端口号:", *port)}这个时候我在终端运行$ go run main.g原创 2021-09-15 02:21:56 · 328 阅读 · 0 评论 -
golang编译原理初识
文章目录关于编译器词法分析语法分析类型检查生成 SSA 中间代码生成机器代码总结关于编译器编译器本质就是一个翻译器,作用是将一个高级语言翻译成计算机可以识别的机器语言,如今的编译器都是分层架构,分层可以增加各层之间的独立性。golang 编译器分为前端和后端编译器种类:本地编译器:可以编译生成所在计算机系统相同平台可执行的目标代码交叉编译器:可生成在其他平台上可执行的目标代码golang 编译器主要编译阶段:1.词法分析 => 2.语法分析 => 3.类型检查 => 4.原创 2021-08-31 00:03:49 · 579 阅读 · 0 评论 -
golang中slice的扩容机制
文章目录简介结论关于 len & cap关于 cap 扩容简介slice 是 golang 中的数组切片,可以理解成是一种动态数组,一般通过 make 声明时候,会指定其 len 和 cap。一般我们常常使用 append 函数时候当 len 超过 cap 时候就会进行扩容处理结论我们先说结论当所需容量 cap 大于原先容量 cap 的 2 倍,则最终申请 cap 容量为当前所需容量当所需要容量 cap 没有大于原先容量 cap 2 倍时,且若原切片长度 len 小于 1024 时候,原创 2021-08-24 14:19:48 · 951 阅读 · 0 评论