深度思维者

永远年轻,永远热泪盈眶

随笔分类 -  Go进阶

go编程进阶,知其然亦知其所以然
摘要:1.前言 所谓垃圾就是不再需要的内存块,这些垃圾如果不清理就没办法再次被分配使用,在不支持垃圾回收的编程语言里,这些垃圾内存就是泄露的内存。 Golang的垃圾回收(GC)也是内存管理的一部分,了解垃圾回收最好先了解前面介绍的内存分配原理。 2. 垃圾回收算法 业界常见的垃圾回收算法有以下几种: 引 阅读全文
posted @ 2021-07-06 07:31 failymao 阅读(484) 评论(0) 推荐(0) 编辑
摘要:1. 前言 编写过C语言程序的肯定知道通过malloc()方法动态申请内存,其中内存分配器使用的是glibc提供的ptmalloc2。 除了glibc,业界比较出名的内存分配器有Google的tcmalloc和Facebook的jemalloc。二者在避免内存碎片和性能上均比glibc有比较大的优势 阅读全文
posted @ 2021-07-04 23:39 failymao 阅读(254) 评论(0) 推荐(0) 编辑
摘要:前言 Goroutine调度是一个很复杂的机制, 尽管Goy源码中提供了大量的注释,但对起原理没有一个好的理解情况下去读源码收获不是很大。 1. 线程池的缺陷 我们知道,在高并发应用中频繁创建线程会造成不必要的开销,所以有了线程池。线程池中预先保存一定数量的线程,而新任务将不再以创建线程的方式去执行 阅读全文
posted @ 2021-07-02 07:06 failymao 阅读(586) 评论(0) 推荐(0) 编辑
摘要:1.前言 所谓读写锁RWMutex,完整的表述应该是读写互斥锁,可以说是Mutex的一个改进版,在某些场景下可以发挥更加灵活的控制能力,比如:读取数据频率远远大于写数据频率的场景。 比如,程序钟写操作少而读操作多,简单的说,如果执行过程时1次写然后N次读的话,使用Mutex这个过程将是串行的, 因为 阅读全文
posted @ 2021-06-30 08:04 failymao 阅读(383) 评论(0) 推荐(0) 编辑
摘要:前言 互斥锁是在并发编程中对共享资源进行访问控制的主要手段,Go语言对其提供了非常简单的Mutex,Mutex是一种数据结构, 对外暴露了两个方法Lock(),Unlock(),分别用于加锁和释放锁。 Mutex使用起来非常方便,但其内部实现却复杂得多,这包括Mutex的几种状态。 另外,我们也想探 阅读全文
posted @ 2021-06-29 08:13 failymao 阅读(1032) 评论(0) 推荐(1) 编辑
摘要:1.前言 range 是Go语言提供的一种遍历手段,可以操作的类型有Array, Slice, Map, Channel. 2.常见的使用技巧 遍历切片时使用正确的姿势是通过索引取值 BadGood func RangeSlice(slice []int) { // 遍历时,其实index不需要,要 阅读全文
posted @ 2021-06-26 23:36 failymao 阅读(365) 评论(0) 推荐(0) 编辑
摘要:1. 前言 select是Golang在语言层面提供的多路IO复用的机制,可以检测多个channel是否准备就绪(即是否可读或可写)。 本节试图通过源码总结其实现原理,从而发现一些使用误区或解释一些不常见的现象 2. 一些常见使用场景 当程序中使用多个case语句时,会随机选择一个进行执行 pack 阅读全文
posted @ 2021-06-25 22:25 failymao 阅读(498) 评论(0) 推荐(0) 编辑
摘要:1.前言 defer语句用于延迟函数的调用, 每次defer会把所在函数压入栈中, 函数在返回前再把延迟函数取出执行。 defer 函数所在的函数称为主函数, defer语句关联的函数称为延迟函数 延迟函数可能有输入参数,这些参数可能来源于定义defer的函数,延迟函数也可能引用主函数用于返回的变量 阅读全文
posted @ 2021-06-22 23:36 failymao 阅读(456) 评论(0) 推荐(0) 编辑
摘要:1. string概念 Go标准库builtin给出了所有内置类型的定义。 源代码位于src/builtin/builtin.go,其中关于string的描述如下: // string is the set of all strings of 8-bit bytes, conventionally 阅读全文
posted @ 2021-06-22 07:47 failymao 阅读(559) 评论(0) 推荐(0) 编辑
摘要:1. iota 概述 iota 常用于const表达式中,并且其值是从0开始的,const声明块中每增加一行iota值自增1. 使用iota可以简化常量的定义,但其规则需要牢牢记住。 2. 使用 2.1 日志模块中使用如下代码 type Priority int const ( LOG_EMERG 阅读全文
posted @ 2021-06-21 07:39 failymao 阅读(165) 评论(0) 推荐(0) 编辑
摘要:概述 Go的struct声明允许字段附带Tag来对字段做一些标记 该Tag 不仅仅是一个字符,其主要的作用是用于反射场景, reflect包中提供了操作Tag 的方法,所以Tag的写法也要遵循一定的规则 Tag的本质 2.1 Tag规则 Tag本身是一个字符串,但字符串中却是:以空格分隔的 key: 阅读全文
posted @ 2021-06-20 08:38 failymao 阅读(117) 评论(0) 推荐(0) 编辑
摘要:1. map数据结构 Map使用的哈希表作为底层实现,一个哈希表里可以有多个哈希表节点,也叫bucket,而每个bucket就保存了map中的一个或一组键值对。 map的数据结构由 runtime/map.go:hmap定义: type hmap struct { count int // 当前保存 阅读全文
posted @ 2021-06-19 12:25 failymao 阅读(5159) 评论(0) 推荐(1) 编辑
摘要:1. 前言 Slice又称动态数组,依托数组实现,可以方便的进行扩容、传递等,实际使用中比数组更灵活。 正因为灵活,如果不了解其内部实现机制,有可能遭遇莫名的异常现象。Slice的实现原理很简单,本节试图根据真实的使用场景,在源码中总结实现原理。 2 Slice实现原理 Slice依托数组实现,底层 阅读全文
posted @ 2021-06-17 23:04 failymao 阅读(292) 评论(0) 推荐(0) 编辑
摘要:1. chan数据结构 src/runtime/chan.go:hchan定义了channel的数据结构,如下 type hchan struct { qcount uint // 当前队列中剩余元素个数 dataqsiz uint // 环形队列长度,即可以存放的元素个数 buf unsafe.P 阅读全文
posted @ 2021-06-17 07:08 failymao 阅读(549) 评论(0) 推荐(0) 编辑