chan读写问题
1.chan读写问题 01.对关闭chan读写 golang面试题:对已经关闭的的chan进行读写,会怎么样?为什么? 读已经关闭的 chan 能一直读到东西,但是读到的内容根据通道内关闭前是否有元素而不同。 1)读取有元素,且关闭的chan 会正确读到 chan 内的值,且返回的第二个 bool 值(是否读成功)为 true。 2)读取无元素,且关闭的chan chan 内无值,接下来所有接收的值都会非阻塞直接成功 返回 channel 元素的零值,但是第二个 bool 值一直为 false。 3)写已经关闭的 chan 会 panic 02.未初始化的的chan读写 对未初始化的的chan进行读写,会怎么样?为什么? 2.1 对于写的情况 未初始化的 chan 此时是等于 nil,当它不能阻塞的情况下,直接返回 false,表示写 chan 失败 当 chan 能阻塞的情况下,则直接阻塞 gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2) 然后调用 throw(s string...
深浅拷贝
1.深浅拷贝 01.深浅拷贝 1.1 深浅拷贝定义 浅拷贝就是只拷贝指针的值,指针指向的内容只有一份。 而深拷贝是把指针指向的值拷贝一份。 golang里面也有浅拷贝和深拷贝。 slice的浅拷贝就是指slice变量的赋值操作。 slice的深拷贝就是指使用内置的copy函数来拷贝两个slice。 1.2 深浅拷贝代码举例 12345678910111213141516171819202122232425package mainimport "fmt"func main() { SliceShallowCopy() SliceDeepCopy()}func SliceShallowCopy() { src := []byte {1,2,3,4,5,6} dst := src fmt.Println("浅拷贝原始数据",src) // [1 2 3 4 5 6] dst[0]=10 // 修改拷贝数据,原始数据会以前跟着改变 fmt.Println("after modify...
垃圾回收
1.垃圾回收 01.三种常见垃圾回收机制 1.0 垃圾回收是什么 传统的系统级编程语言(主要指C/C++)中,程序员必须对内存小心的进行管理操作,控制内存的申请及释放。 稍有不慎,就可能产生内存泄露问题,这种问题不易发现并且难以定位 后来开发出来的几乎所有新语言(java,python,php等等)都引入了语言层面的自动内存管理 也就是语言的使用者只用关注内存的申请而不必关心内存的释放 内存释放由虚拟机(virtual machine)或运行时(runtime)来自动进行管理 而这种对不再使用的内存资源进行自动回收的行为就被称为垃圾回收。 1.1 引计数 原理 当一个对象的引用被创建或者复制时,对象的引用计数加1;当一个对象的引用被销毁时,对象的引用计数减1. 当对象的引用计数减少为0时,就意味着对象已经再没有被使用了,可以将其内存释放掉。 优点 引用计数有一个很大的优点,即实时性,任何内存,一旦没有指向它的引用,就会被立即回收,而其他的垃圾收集技术必须在某种特殊条件下才能进行无效内存的回收。 缺点 引用计数机制所带来的维护引用计数的额外操作与Python运行...
内存泄露
1.内存泄漏 01.内存泄漏概念 1.1 内存泄漏定义 定义:由于疏忽或错误造成程序未能释放已经不再使用的内存。 1.2 go内存泄漏两种情况 情况1:僵尸进程 1234567 - 有goroutine泄漏,goroutine“飞”了,zombie goroutine没有结束 - 这个时候在这个goroutine上分配的内存对象将一直被这个僵尸goroutine引用着 - 进而导致gc无法回收这类对象,内存泄漏- ``` 情况2:全局数据结构挂住了本该释放的对象 - 有一些全局(或者生命周期和程序本身运行周期一样长的)的数据结构意外的挂住了本该释放的对象 - 虽然goroutine已经退出了,但是这些对象并没有从这类数据结构中删除,导致对象一直被引用,无法被回收。 02.内存泄漏排查 2.1 排除掉goroutine泄漏 首先,我利用压测工具对server进行100个websocket连接,模拟用户浏览行为,然后关闭连接。 打开浏览器查看goroutine数量,发现新起的goroutine全部已经销毁,没有观察到有泄漏的goroutine,因此排除此情...
内存逃逸
1.内存逃逸 01.内存逃逸 1.1 其他语言内存回收机制 在C/C++开发中,动态分配内存(new/malloc)需要我们手动释放资源。 这样做的好处是,需要申请多少内存空间可以很好的掌握怎么分配。 但是这有个缺点,如果忘记释放内存,则会导致内存泄漏。 在很多高级语言中(python/Go/java)都加上了垃圾回收机制。 1.2 什么是内存逃逸 函数内部申请的临时变量,正常会分配到栈里,栈中的内存分配非常快,自动回收,无需垃圾回收 但是若果申请的临时变量作为了函数返回值,编译器会认为在退出函数之后还有其他地方在引用 在编译的时候就会将变量存储到堆中,堆中的数据不会自动回收,必须使用垃圾回收机制清楚 我们将这种 由于某些原因,数据没有分配到栈中而是分配到堆中的现象叫做 内存逃逸 1.2 golang的内存分配之堆和栈 1.2.1 内存分片概述 Go的垃圾回收,让堆和栈堆程序员保持透明。 真正解放了程序员的双手,让他们可以专注于业务,“高效”地完成代码编写。 把那些内存管理的复杂机制交给编译器。 栈 可以简单得理解成一次函数调用内部申请到的内存,它们会随着函数的返回把内...