Go语言
一个用了8年C++开发人员,学习Go语言的笔记
灰子学技术
10年+后端开发工程师,8.5年+C++开发,2年Go开发经验。
公众号: 灰子学技术
架构知识文章 25篇+:
Go语言文章40篇+:
算法篇40篇+:
展开
-
Go语言学习目录
本人原本是C++开发工程师,使用C++已经有8年多的时间,最近在学习Go语言,在学习Go语言的时候,难免会拿Go语言与C++语言做一些比较。这些文章便是笔者,在学习Go语言变量的时候,整理的一些知识,目前位置已经有将近50篇Go语言原创,对于学习go语言的朋友来说,算是一个还不错的参考资料。欢迎大家关注我的公众号“灰子学技术”。——灰子Go语言目录公众号链接:go 语言学习目录...原创 2020-05-15 09:32:36 · 318 阅读 · 0 评论 -
Go语言之GRPC
1.RPC的基本知识介绍:RPC叫做远程调用框架(Remote Procedure Call),远程调用原理如下所示:比如 A (client) 调用 ...原创 2020-03-25 20:00:00 · 504 阅读 · 0 评论 -
内存管理篇(三):Go垃圾回收之三色标记算法
三色标记法介绍:三色标记法(tricolor mark-and-sweep algorithm)是传统 Mark-Sweep 的一个改进,它是一个并发的 GC 算法,在Golang中被用作垃圾回收的算法,但是也会有一个缺陷,可能程序中的垃圾产生的速度会大于垃圾收集的速度,这样会导致程序中的垃圾越来越多无法被收集掉。原理如下所示:step 1: 创建:白、灰、黑三个集合。step 2...原创 2020-01-30 10:42:43 · 2634 阅读 · 0 评论 -
内存管理(二):TCMalloc介绍
TCMalloc作为Go语言内存管理的核心算法,是理解和掌握Go的内存管理非常重要的一步,本章主要介绍TCMalloc的是什么样子的。TCMalloc的概述TCMalloc全称是Thread-Caching Malloc,是Google 开发的内存分配器,在不少项目中都有使用,例如在 Golang 中就使用了类似的算法进行内存分配。它具有现代化内存分配器的基本特征:对抗内存碎片、在多核...原创 2020-01-27 10:56:17 · 1093 阅读 · 0 评论 -
Go语言之init函数
Go语言有一个特殊的函数init,先于main函数执行,实现包级别的一些初始化操作。对于init 函数来说:每个包可以包含任意多个 init 函数,这些函数都会在程序执行开始的时候被调用。所有被编译器发现的 init 函数都会安排在 main 函数之前执行。init 函数用在设置包、初始化变量或其他要在程序运行前优先完成的引导工作。init函数的主要作用:1)初始化不能采用初始化表达式初...原创 2020-01-03 19:34:26 · 5398 阅读 · 0 评论 -
Go语言之mutex
写在前面的话:程序中的并发,是导致临界区竞争的根本原因,而解决这个问题的最常用办法就是锁机制,而mutex是Go语言之中最基本的一种锁机制。这篇文章,笔者主要来介绍下Go语言的这个锁机制mutex,在开始之前,我们需要先介绍下几个概念。1. 基本概念临界区(Critical Section):当程序并发地运行时,多个Go协程不应该同时访问那些修改共享资源的代码,这些修改共享资源的代...原创 2019-12-20 06:27:50 · 1092 阅读 · 0 评论 -
Go语言之Cond
Golang的sync包中的Cond实现了一种条件变量,主要用来解决多个读协程等待共享资源变成ready的场景。在使用Cond的时候,需要特别注意下:每个Cond都会关联一个Lock(*sync.Mutex or *sync.RWMutex),当修改条件或者调用Wait方法时,必须加锁,保护condition。1. Cond的介绍:定义如下所示:Cond相关API介绍, Co...原创 2019-12-25 12:30:00 · 776 阅读 · 0 评论 -
Go语言之Once
sync.Once是sync包中的一个对象,它只有一个方法Do,这个方法很特殊,在程序运行过程中,无论被多少次调用,只会执行一次。1.适用场景:在一个进程之中,如果一个函数里面的一部分代码,希望在很多协程都执行的时候,只被执行一次,那么Once便起到了作用。例如:初始化进程中的共享内存,它只希望被该进程初始化一次,其他协程不需要初始化操作。例子:结果分析:从上面的输出结果...原创 2019-12-23 14:19:25 · 1010 阅读 · 0 评论 -
Go语言之Map非并发安全
一、问题描述:一次使用Go map的过程中,发现一个现象,map里面的元素是数据结构的话,该元素的属性不能直接赋值。会提示编译错误:./prog.go:11:15: cannot assign to struct field testMap[1].x in map例子如下:编译错误:./prog.go:11:15: cannot assign to struct fiel...原创 2019-07-25 17:36:58 · 354 阅读 · 0 评论 -
Go语言之RWMutex
本篇文章,笔者主要来介绍读写锁的一种Go语言的实现方式RWMutex。1.基本概念读写锁:是计算机程序的并发控制的一种同步机制,也称“共享-互斥锁”、多读者-单写者锁。读操作可并发重入,写操作是互斥的。主要适用的场景是:读多写少的业务场景。这种场景下如果每次读写都使用互斥锁那么整个效率就会变得很低。因为只是读的话并不需要互斥锁来锁住数据,只有写操作的时候需要互斥锁,而读写结合的时候,...原创 2019-12-21 08:00:00 · 405 阅读 · 0 评论 -
Go语言之panic和recover
写在前面的话:panic是Go语言中,用于终止程序的一种函数,往往用在下面两种情况:1)程序出现了很大的故障,例如不能在提供服务了。2)程序在运行阶段碰到了内存异常的操作,例如空指针的取值,改写只读内存等。对于panic来说,1)场景往往是主动调用;2)场景则是被动调用,panic一旦产生之后,会将堆栈里面的数据dump出来,这样就方便了开发人员来定位问题。recover是用来截获p...原创 2019-12-19 13:06:26 · 3873 阅读 · 1 评论 -
Go语言之error
写在前面的话:Go语言提供了一个error类型,专门用来表示程序出现异常的错误信息。但是有时候,error本身提供的这些错误信息不能完全满足我们的要求,这种情况下我们就需要自己去改造error,来实现自己希望的error格式以及内容。下面笔者主要来讲下这件事情,不过在讲这之前,我们先看下error的定义吧。1. error介绍error其实就是实现了Error()函数的一个接口,...原创 2019-12-18 19:45:45 · 729 阅读 · 0 评论 -
Go语言之类篇
这篇文章便是笔者,在学习Go语言“类”的时候,整理的一些知识。准确来说,Go语言没有类的概念,不过却有struct和interface,这篇文章主要来讲struct,因为笔者觉得这个和C++中的Class有些相似。在C++中Class有几个东西,一定要谈,它们分别是:public/protected/private属性,构造函数和析构函数,继承,函数重载。一、公私有属性1.C+...原创 2019-07-20 13:50:38 · 332 阅读 · 0 评论 -
Go语言之条件编译
背景介绍:我们在开发的过程中,特别是在重构的过程中,往往会存在新代码和老代码同时都在的情况。这种情况下,我们希望可以编译不同的版本,旧代码编译的版本用来做产品发布,没有改好的新代码用来做测试,等测试通过之后,再把旧代码移除。在C和C++中,我们可以很轻松的完成这件事情,那就是使用“预编译宏”#ifndef XXX #define XXXX #endif,但是Go语言中,我们该如何操作呢...原创 2019-12-03 09:48:07 · 828 阅读 · 0 评论 -
Go语言之装饰器,一种很骚的函数操作方法
Go的装饰器本质上允许您包装现有功能,并添加你自己的自定义功能,它操作的对象是函数,返回的对象也是函数。1.简单的一个装饰器例子:结果分析:从输出的结果能够看出,调用了装饰器之后,函数testFunc已经实现了,“自己的代码 + 原来代码”的效果。2.如果我们希望装饰器装饰的函数类型不是固定的呢,也就是说我们希望装饰器装饰的函数可以是任何函数,这样我们该怎么办?答案:采用空in...原创 2019-12-12 18:51:09 · 627 阅读 · 0 评论 -
Go语言之反射
笔者原本是C++开发人员,之前对于反射没太大概念,学了GO之后,才开始接触,在研究了一段时间之后,有了些认识,便整理一个帖子,希望对大家有所帮助。在学习反射的时候,笔者一直在问自己,反射是什么?为什么要用到反射?它是怎么实现的?笔者觉得,在知道这些问题的答案之后,才算是真正了解反射。下面笔者便从这些问题来着手整理反射。一、反射是什么?维基百科上的定义:在计算机科学中,反射是指计...原创 2019-12-11 13:22:26 · 477 阅读 · 0 评论 -
Go语言之常量
欢迎关注,订阅,评论,共同学习,共同进步!灰子学技术:一、Go语言中const常量Go语言的常量关键字是const,用于存储不会改变的数值,定义的格式为:const valueName type = value或者const valueName = value const a = "abc" const b string = "Hello"...原创 2019-07-16 09:09:05 · 174 阅读 · 0 评论 -
Go语言之性能测试相关(基准测试)
在Go语言中,提供了测试函数性能(CPU和Memory)的测试方法,基准测试。基准测试主要用来测试CPU和内存的效率问题,来评估被测代码的性能。测试人员可以根据这些性能指标的反馈,来优化我们的代码,进而提高性能问题。本篇文章主要来介绍,基准测试的使用方法和性能指标的分析。1. 使用规则如下所示:1.基准测试的代码文件必须以_test.go结尾。2.基准测试的函数必须以Ben...原创 2019-10-12 14:31:35 · 411 阅读 · 0 评论 -
消息队列(三):RabbitMQ基本API介绍
一、RabbitMQ简介:RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。二、go-amqp对于Go语言来说,rabbitMQ的开源实现,往往采用go-amqp,下面章节主要是对go-amqp的...原创 2019-10-28 19:04:50 · 1268 阅读 · 0 评论 -
Go语言之带参数的main函数
本篇文章只用来讲解如何实现,一个带命令行的程序。对于这个功能的实现方法,有两种,一种是通过os包的os.Args来实现;另外一种通过flag包来实现。方法一:os.Args实现下面我们来写一个main函数,里面os.Args是一个[]string类型,在运行main函数的时候,命令行中的参数会被写入到os.Args数据中。不过这样的参数不能够指定是什么类型,也不可以指定tag是什么,...原创 2019-10-31 19:47:48 · 11417 阅读 · 0 评论 -
Go之一步步学习RabbitMQ(一)
写在前面的话:最近笔者在学习RabbitMQ,便尝试着通过下面的学习过程,来尽量还原RabbitMQ为什么如此设计,以及它是如何解决这些问题的。当中如有不对或者理解偏差的地方,还请大家不吝赐教,多多留言。如果你觉得这篇文章真的帮到了你,还请你顺手转发下。背景知识:在学习RabbitMQ之前,我们需要对下面的知识有些概念,生产者(producer):产生并发送消息的程序。队列(...原创 2019-11-03 19:25:00 · 514 阅读 · 0 评论 -
Go之一步步学习RabbitMQ(二)
写在前面的话:本篇文章主要来讲解,RabbitMQ的路由知识,在开始之前,笔者问了自己几个问题。笔者觉得一旦知道了这几个问题的答案,那么关于RabbitMQ的路由这部分知识基本上算是熟悉了,所以还希望大家带着这些问题来阅读本篇文章。1. 为什么RabbitMQ需要路由呢?它们有什么用?2.路由都有哪些分类?各自有什么特点?3.这些路由是如何实现消息转发的?一、RabbitMQ...原创 2019-11-07 20:32:37 · 161 阅读 · 0 评论 -
Go语言之可变参数函数
Go中的函数支持可变参数,这一特性其实只是Go语言的一种语法糖,格式如下所示:func function(values...Type) {} // Type:表示的是具体的参数归属类型,可以是int,string...甚至interface例子1: 可变参数是同一种类型的通过上面的代码可以看出,可变参数的函数,对4中参数的输入方式都支持,它们分别是:1.不输入参数;2...原创 2019-11-12 16:35:13 · 715 阅读 · 0 评论 -
Go接口之nil != nil
一、引出话题:在开始这个话题之前,我们先看一段代码以及其输出结果,代码如下所示:从上面的输出结果来看,GetA()返回的类型为*A就算赋值为nil,也不等于nil。看到这里笔者觉得很奇怪,明明是GetA()返回值是nil,为什么nil的判断条件是false呢?二、原因分析:在研究了interface之后,笔者发现了真相,原来Go语言中的interface是不...原创 2019-11-21 08:24:58 · 668 阅读 · 0 评论 -
Go语言之指针常见问题
在Go语言中,指针其实有下面几种表现形式,第一:指针;第二:接口;第三:slice;第四:map。场景一:指针变量作为参数使用,会被复制一份指针变量对于指针来说,最常见也最容易让人产生混淆的便是,指针作为参数传递的时候,到底是复制了一份指针变量,还是类似于C++的引用一样,使用的是传入之前的指针变量?例子:Output:介绍:通过上面的例子输出结果来看,不管是...原创 2019-11-28 08:58:38 · 771 阅读 · 2 评论 -
Go语言之指针篇(四)
转发自自己的公众号(灰子学技术)一、写在前面的话:在介绍Go的指针之前,我们需要先介绍下,指针是什么?为什么我们需要指针?(备注:这里指的是原始指针。)1.指针是什么?首先指针是一个变量,全名叫做指针变量,只不过这个变量里面存储的值是一个地址而已。所以指针,哪怕是空指针,都是有地址的,因为变量都是有地址的。例子如下:Output:从下面的输出,我们可以看出空指针a的...转载 2019-08-22 19:06:25 · 144 阅读 · 0 评论 -
Go语言之Defer篇
转发自自己的公众号(灰子学技术)。写在前面的话:在接触defer之后,觉得Go的这一特性很好,有点类似于C++的析构函数,不过他们却有很大的不同。主要的区别点是defer实现在函数里面,作用域也是在函数里面,当函数的return语句被调用之后,才会调用到这个defer声明的函数。而析构函数实现在类里面,作用域是在类内部,在该类的实例被销毁的时候,就会被调用到。在谈论defer之...转载 2019-08-22 13:51:14 · 163 阅读 · 0 评论 -
Go 语言之常量(二)
转发自自己的公众号(灰子学技术)一、Go语言中const常量Go语言的常量关键字是const,用于存储不会改变的数值,定义的格式为:const valueName type = value或者const valueName = value const a = "abc" const b string = "Hello"Go里面常量,具有常量的基本特质,不能修改。原因...转载 2019-08-22 19:17:15 · 108 阅读 · 0 评论 -
Go语言之变量(一)
转发自自己的公众号(灰子学技术)这篇文章便是笔者,在学习Go语言变量的时候,整理的一些知识。一、变量定义的格式C++的变量定义表达式如下所示:Type name = expression;,例如 int number = 10; // 表示的是 一个数据类型是int,名字叫做 number 的变量,它的初始值是 10。Go的变量定义表达式如下所示:var name t...转载 2019-08-22 19:10:25 · 262 阅读 · 0 评论 -
Go并发之Context篇
前言介绍:在学习Go并发的时候,我们总是能够看到context,而这个context却只在go语言中存在。笔者在看到context的时候,便问了自己几个问题。context是什么?是用来干什么的?我们为什么需要context? context是如何使用的?它为什么被设计成这个样子?基于上面的这些问题,笔者做了整理,笔者觉得在知道了这些问题的答案之后,context 也算是有一点了解了。...原创 2019-10-03 08:08:09 · 495 阅读 · 0 评论 -
Go单元测试(一):基本用法
一、单元测试的基本规则介绍Go的单元测试比较容易实现,因为Go语言为我们提供了单元测试的框架。而对于单元测试的框架需要遵循下面的几条规定。规则1.单元测试代码的go文件必须以_test.go结尾,Go语言测试工具只会认符合这个规则的文件规则2.单元测试的函数名必须以Test开头,是可导出公开的函数。备注:函数名最好是Test+要测试的方法函数名规则3.测试函数的签名必须接...原创 2019-10-04 08:43:55 · 409 阅读 · 0 评论 -
Go并发之channel篇
转自自己的公众号:灰子学技术 ,欢迎大家关注,评论,相互学习灰子学技术公众号学习channel的时候,笔者问了自己几个问题,个人觉得弄明白了这些问题,至少应该会使用channel了。本文也会从这些问题着手,来讲解channel。问题1: 什么是channel?是用来做什么的?1.channel是Go里面的一种类型,它是Go语言为goroutine提供的一种通讯机制,不...原创 2019-09-07 08:44:21 · 434 阅读 · 0 评论 -
go并发(四):select篇
一、前言介绍:对于Go语言并发通讯,是使用的协程goroutine,而协程之间的通讯采用的是channel。但是channel不管是有缓存的,还是无缓存的都会有阻塞的情况出现,只不过无缓存的阻塞会更加频繁。而协程长时间阻塞了之后,Go语言本身又没有提供这种超时的解决机制,所以开发者需要自己考虑实现这种超时机制。这种超时机制在Go语言中则是使用select来解决的。相关的背景知识:1....原创 2019-09-11 14:07:09 · 626 阅读 · 0 评论 -
Go 语言之switch
转发自自己的公众号(灰子学技术)原文链接:https://mp.weixin.qq.com/s/NpAmTMncDabMHcLwoyYegA一、区别switch语句是语言里面非常常见的语句,但是Go语言和C++对它的使用,却实在是迥异,差距非常之大。1.先从写法上面,C++中,switch之后紧跟括号,Go后面没有括号,甚至可以省略。2.switch后的变量类型,C++中必...原创 2019-09-05 09:31:02 · 208 阅读 · 0 评论 -
Go语言之continue/break label
转发自自己的公众号(灰子学技术)原文链接:https://mp.weixin.qq.com/s/kjGZsMJJdpOJbxlC1gs29w一、写在前面的话:最近碰到了,Go语言一个比较有趣的语法continue label和break label,这种语法C/C++却没有,但是却有与之类似的goto。不过C/C++中一般不喜欢也不推荐使用goto,原因是goto语句跳来跳去,很容...原创 2019-09-05 09:25:43 · 1000 阅读 · 0 评论 -
Go语言之goroutine的调度原理
转自本同步公众号:“灰子学技术”一、关于并发的基础知识再讲goroutine的调度原理之前,有些与操作系统相关的知识,我们需要先知道,例如:1.什么是并发?并发:两个或两个以上的任务在一段时间内被执行。我们并不关心这些任务是否在同一时刻执行,我们只是知道,这些任务在这一段时间能能够都被执行,当然这一段时间可以很长,也可以很短。2.并发的最小并发单位是什么?进程是计算...原创 2019-09-02 09:20:24 · 609 阅读 · 0 评论 -
Go单元测试:为什么stub叫做桩函数,mock叫做模拟接口?
一、前言介绍:对于我们平时开发的业务代码,单个函数往往不是独立的,它需要依赖于其他模块、第三方库、数据库、消息交互的结果等等。对于这种代码做单元测试,就会变得复杂许多,而对于当前要测试的函数来说,这些被依赖的其他函数,无非就是返回不同的数据而已。所以在做单元测试的时候,我们只需要让这些被依赖的其他函数返回我们期望的数据,就可以继续测试我们当前需要测试的函数。对于上面这种外部依赖...原创 2019-10-10 19:40:57 · 3987 阅读 · 0 评论