教程

syjc
为什么GO不支持循环引用

为什么GO不支持循环引用

学习 Go 语言的开发者越来越多了,很多小伙伴在使用时,就会遇到种种不理解的问题。 其中一点就是包的循环引用的报错: package command-line-arguments imports github.com/eddycjy/awesome-project/a imports github.com/eddycjy/awesome-project/b imports github.com/eddycjy/awesome-project/a: import cycle not allowed 一下子就很懵逼了,为什么 Go 不支持包之间的循环引用呢,这就很不解了,难道还影响性能了? 如下图:...

golang redigo发布订阅使用的方法

golang redigo发布订阅使用的方法

redigo 对 发布订阅的使用 redigo 对redis 的发布订阅机制放在pubsub.go 中 订阅主题后 通过Receive() 函数接受发布订阅主题的消息 // Receive returns a pushed message as a Subscription, Message, Pong or error. // The return value is intended to be used directly in a type switch as // illustrated in the PubSubConn example. func (c PubSubConn) Receive() interf...

定位并修复 Go 中的内存泄露问题

定位并修复 Go 中的内存泄露问题

Go 是一门带 GC 的语言,因此,大家很容易认为它不会有内存泄露问题。 大部分时候确实不会,但如果有些时候使用不注意,也会导致泄露。 本文案例来自谷歌云的代码,探讨如何找到并修复 Go 中的内存泄露。(确切来说是因为资源泄露导致的内存泄露,除了本文介绍的,还有一些其他泄露的情况) 这篇文章回顾了我如何发现内存泄漏、如何修复它,以及我如何修复 Google 示例 Go 代码中的类似问题,以及我们如何改进我们的库以防止将来发生这种情况。 Google Cloud Go 客户端库 [1] 通常在后台使用 gRPC 来连接 Google Cloud API。创建 API 客户端时,库会初始化与 API 的连接,然后保持该连接处于打开...

Go语言并发编程 互斥锁详情

Go语言并发编程 互斥锁详情

1、互斥锁Mutex 1.1 Mutex介绍 Go 语言的同步工具主要由 sync 包提供,互斥锁 (Mutex) 与读写锁 (RWMutex) 就是sync 包中的方法。 互斥锁可以用来保护一个临界区,保证同一时刻只有一个 goroutine 处于该临界区内。主要包括锁定(Lock方法)和解锁(Unlock方法)两个操作,首先对进入临界区的goroutine进行锁定,离开时进行解锁。 使用互斥锁 (Mutex)时要注意以下几点: 不要重复锁定互斥锁,否则会阻塞,也可能会导致死锁(deadlock); 要对互斥锁进行解锁,这也是为了避免重复锁定; 不要对未锁定或者已解锁的互斥锁解锁; 不要在多个函数之...

浅谈golang 的高效编码细节

浅谈golang 的高效编码细节

xdm,我们都知道 golang 是天生的高并发,高效的编译型语言 可我们也都可知道,工具再好,用法不对,全都白费,我们来举 2 个常用路径来感受一下 struct 和 map 用谁呢? 计算量很小的时候,可能看不出使用 临时 struct 和 map 的耗时差距,但是数量起来了,差距就明显了,且会随着数量越大,差距越发明显 当我们遇到键和值都可以是固定的时候,我们选择 struct 比 选择 map 的方式 高效多了 我们模拟循环计算 1 亿 次,看看使用各自的数据结构会耗时多少 循环前计算一下当前时间 循环后计算一下当前时间 最后计算两个时间的差值,此处我们使用 毫秒为单位 func ma...

Golang开发命令行之flag包的使用方法

Golang开发命令行之flag包的使用方法

1、命令行工具概述 日常命令行操作,相对应的众多命令行工具是提高生产力的必备工具,鼠标能够让用户更容易上手,降低用户学习成本。 而对于开发者,键盘操作模式能显著提升生产力,还有在一些专业工具中, 大量使用快捷键代替繁琐的鼠标操作,能够使开发人员更加专注于工作,提高效率,因为键盘操作模式更容易产生肌肉记忆 举个栗子:我司业务研发,前些年在我们的强力推动下(被迫)转向使用了 git 作为版本控制,开始使用的是图形化“小乌龟”工具。后续出现几次问题解决起来较麻烦后,推荐其使用原生的 git 命令行。如今,使用 git 命令行操作版本控制可谓 “一顿操作猛如虎......” 命令行(键盘)操作在很大程度上可以提高工作效率,与之相...

Golang标准库和外部库的性能比较

Golang标准库和外部库的性能比较

前言: 我已经在生产中使用 Go 一段时间了,因为它的构建规模较小,并且由 goroutines 提供的并发性能以及直接在机器上运行构建的能力,所以我非常喜欢它的快速和可靠。 由于标准包的速度非常快,您可以在不使用任何第三方库或框架的情况下构建生产就绪的微服务。这并不是说 Go 中没有提供更多灵活性或速度的框架,只是它们不那么受欢迎。 官方通常告诉你坚持使用标准库。具有讽刺意味的是, golang 框架 的顶级 Google 搜索结果一般都是关于为什么不应该使用标准库。 我对标准库的替代品进行了一些研究和基准测试,以了解它们的表现。我将它们分为我认为是关键的微服务组件。 所有基准测试都在下面列出的配置上运行。虽然正常的基准...

go语言编程学习实现图的广度与深度优先搜索

go语言编程学习实现图的广度与深度优先搜索

图的实现 所谓图就是节点及其连接关系的集合。所以可以通过一个一维数组表示节点,外加一个二维数组表示节点之间的关系。 //图的矩阵实现 typedef struct MGRAPH{ nodes int[]; //节点 edges int[][]; //边 }mGraph; 然而对于一些实际问题,其邻接矩阵中可能存在大量的0值,此时可以通过邻接链表来表示稀疏图,其数据结构如图所示 其左侧为图的示意图,右侧为图的邻接链表。红字表示节点序号,链表中为与这个节点相连的节点,如1节点与2、5节点相连。由于在go中,可以很方便地使用数组来代替链表,所以其链表结构可以写为 pac...

Go 语言 JSON 标准库的使用

Go 语言 JSON 标准库的使用

Go 语言中的 encoding/json 库提供了复杂的将 Go 中各种类型与JSON格式之间转换的功能, 我们主要使用以下几个功能: 将一个切片、结构体或字典序列化成 JSON 格式的字符串【字节流】。 将一个 JSON 格式的字符串【字节流】反序列化成一个切片、结构体或字典。 序列化 序列化使用 json 库中的Marshal函数: func Marshal(v interface{}) ([]byte, error) 1. 结构体序列化 比如使用以下的结构体表示一部电影: type Movie struct { Title string Year int `json:...

Golang通脉之方法详情

Golang通脉之方法详情

方法和接收者 Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。 Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集 方法只是一个函数,它带有一个特殊的接收器类型,它是在func关键字和方法名之间编写的。接收器可以是struct类型或非struct类型。接收方可以在方法内部访问。 方法能给用户自定义的类型添加新的行为。它和函数的区别在于方法有一个接收者,给一个函数添加一个接收者,那么它就变成了方法。...

Golang通脉之数据类型详情

Golang通脉之数据类型详情

1、标识符与关键字 在了解数据类型之前,先了解一下go的标识符和关键字 1.1 标识符 在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符允许由字母数字和_(下划线)组成,并且只能以字母和_开头:abc , _ , _123, a123。 1.2 关键字 关键字是指语言预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名。 Go语言有25个关键字: break default func interface select case defer go...

Golang通脉之map详情

Golang通脉之map详情

Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现。 map 是一种无序的键值对的集合。map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值 map 是一种集合,所以可以像迭代数组和切片那样迭代它。不过,map 是无序的,无法决定它的返回顺序,这是因为 map 是使用 hash 表来实现的,Go语言中的map是引用类型,必须初始化才能使用。 使用map过程中需要注意的几点: map是无序的,每次打印出来的map都会不一样,它不能通过index获取,而必须通过key获取 map的长度是不固定的,也就是和slice一样,也是一种引用类型 内置的len函数同样适用于m...

Golang中channel的原理解读(推荐)

Golang中channel的原理解读(推荐)

数据结构 channel的数据结构在$GOROOT/src/runtime/chan.go文件下: type hchan struct { qcount uint // 当前队列中剩余元素个数 dataqsiz uint // 环形队列长度,即可以存放的元素个数 buf unsafe.Pointer // 环形队列指针 elemsize uint16 // 每个元素的大小 closed uint32 // 标记是否关闭 elemtype *_type...

Golang通脉之类型定义

Golang通脉之类型定义

1、自定义类型 在Go语言中有一些基本的数据类型,如 string 、 整型 、 浮点型 、 布尔 等数据类型, Go语言中可以使用 type 关键字来定义自定义类型。 type是Go语法里的重要而且常用的关键字,type绝不只是对应于C/C++中的typedef。搞清楚type的使用,就容易理解go语言中的核心概念struct、interface、函数等的使用。 2、类型定义 2.1 定义结构体 使用 type 可以定义结构体类型: //1、定义结构体 //结构体定义 type person struct { name string //注意后面不能有逗号 age int } 2....

Go语言并发编程 sync.Once

Go语言并发编程 sync.Once

sync.Once用于保证某个动作只被执行一次,可用于单例模式中,比如初始化配置。我们知道init()函数也只会执行一次,不过它是在main()函数之前执行,如果想要在代码执行过程中只运行某个动作一次,可以使用sync.Once,下面来介绍一下它的使用方法。 先来看下面的代码: package main import ( "fmt" "sync" ) func main() { var num = 6 var once sync.Once add_one := func() { num = num + 1 } minus_one := func() { num...