同步原语的基石
Go是一门以并发编程见长的语言,它提供了一系列的同步原语方便开发者使用,例如sync
包下的Mutex
、RWMutex
、WaitGroup
、Once
、Cond
,以及抽象层级更高的Channel
。但是,它们的实现基石是原子操作。需要记住的是:软件原子操作离不开硬件指令的支持。本文拟通过探讨原子操作——**比较并交换(compare and swap, CAS)**的实现,来理解Go是如何借助硬件指令来实现这一过程的。
Go是一门以并发编程见长的语言,它提供了一系列的同步原语方便开发者使用,例如sync
包下的Mutex
、RWMutex
、WaitGroup
、Once
、Cond
,以及抽象层级更高的Channel
。但是,它们的实现基石是原子操作。需要记住的是:软件原子操作离不开硬件指令的支持。本文拟通过探讨原子操作——**比较并交换(compare and swap, CAS)**的实现,来理解Go是如何借助硬件指令来实现这一过程的。
在《切片传递的隐藏危机》一文,小菜刀有简单地提及到切片扩容的问题。在读者讨论群,有人举了以下例子,并想得到一个合理的回答。
1package main
2
3func main() {
4 s := []int{1,2}
5 s = append(s, 3,4,5)
6 println(cap(s))
7}
8
9// output: 6
为什么结果不是5,不是8,而是6呢?由于小菜刀在该文中关于扩容的描述不够准确,让读者产生了疑惑。因此本文想借此机会细致分析一下append
函数及其背后的扩容机制。
Go是一门带有垃圾回收的现代语言,它抛弃了传统C/C++的开发者需要手动管理内存的方式,实现了内存的主动申请和释放的管理。Go的垃圾回收,让堆和栈的概念对程序员保持透明,它增加的逃逸分析与GC,使得程序员的双手真正地得到了解放,给了开发者更多的精力去关注软件设计本身。
认识单例
超超:您好,面试官~
面试官:你好,你平时开发是用 windows 还是 linux 居多?
超超: ̄□ ̄||我平时都是用windows开发的。
面试官:那你知道 windows 的资源管理器只能单开,但是cmd命令行可以开很多个,有想过这是为什么吗?
本文是公众号读者上山打老虎的第二篇原创投稿,主要内容是讲解算法技巧之滑动窗口。上山兄一直保持着刷题的习惯,并形成了自己的一套做题心得,当然他也是无情的offer收割机。同时上山兄会持续给本号投稿算法类文章,代码示例均采用Go语言,希望该算法系列文章有助读者更好地备战面试。
在Go的源码库或者其他开源项目中,会发现有些函数在需要用到切片入参时,它采用是指向切片类型的指针,而非切片类型。这里未免会产生疑问:切片底层不就是指针指向底层数组数据吗,为何不直接传递切片,两者有什么区别?
在Go中,要理解channel,首先需要认识goroutine。
为什么会有goroutine
现代操作系统中为我们提供了三种基本的构造并发程序的方法:多进程、I/O多路复用和多线程。其中最简单的构造方式当属多进程,但是多进程的并发程序,由于对进程控制和进程间通信开销巨大,这样的并发方式往往会很慢。
本文旨在探讨Go函数中的一个问题:**为什么Go函数能支持多参数返回,而C/C++、java不行?**这其实牵涉到了一个叫做函数调用惯例的问题。