0%

本篇文章记录 Go 进程的启动和初始化过程,从程序入口开始调试,探索 Go 的各个组件初始化,以最简单的 hello world 为示例。

阅读全文 »

在Go语言中,实现并发编程相当简单,因此存在大量场景需要同步操作限制对临界区的修改,避免出现不可期望的情况。因此,Go 语言在 sync 中提供了大量的基本同步原语,例如,最常见的互斥锁 sync.Mutex,它的名字应该来源于:Mutual Exclusion 的前缀组合,它对外只暴露了两个方法:LockUnlock,本篇文章将详细了解加解锁背后的逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// A Mutex is a mutual exclusion lock.
// The zero value for a Mutex is an unlocked mutex.
//
// A Mutex must not be copied after first use.
type Mutex struct {
state int32
sema uint32
}

// A Locker represents an object that can be locked and unlocked.
type Locker interface {
Lock()
Unlock()
}

// 一些状态
const (
mutexLocked = 1 << iota // 1:表示锁定状态
mutexWoken // 2: 表示当前锁被从正常模式唤醒
mutexStarving // 4: 表示当前锁进入互斥状态
mutexWaiterShift = iota // 3:左移3位存储正在等待获取锁的goroutine的个数
starvationThresholdNs = 1e6 // 正在获取锁的goroutine等待1ms之后,会让当前锁进入饥饿模式
)
阅读全文 »

本文借助 visual studio code 搭建本地的 dapr 应用开发环境,另外讲述本地调试技巧,便于问题定位。

还是来调试 dapr 为我们准备的示例应用,secretstore,我们先将本地的 dapr 按照官方指导运行起来,并且将示例应用克隆到本地打开,另外还需安装好 Dapr Visual Studio Code扩展 ,并且执行 npm install 命令安装将应用的扩展,当所有就绪之后你的工作区应该看起来如下所示:

阅读全文 »

Dapr 在 2021 年发布了 v1.0 生产可用版本,预示着这个号称分布式运行时的框架终于可以进入各种大企业。说是尝鲜那已经是晚了很多,讲内部实现目前还不了解,本文主要是记录自己在本地创建 k8s 集群并且跑起来我第一个基于dapr应用的辛酸过程,辛酸是因为对k8s及dapr都不熟悉,加之国内网络限制,M1 芯片对某些软件不支持导致。

阅读全文 »

sync.Pool 是一组临时对象,可以用来被复用,以减少内存分配次数,降低GC压力,在大量相同临时对象存在的场景下使用,能较好处理因GC导致CPU突增的情况。sync.Pool 使用比较简单,只有三个简单的 API:NewGetPut,并且它是并发安全的,意味着它可以在 goroutine 中安全地使用。

阅读全文 »

每个语言都有自己的依赖管理系统,就像 CargonpmComposerNugetPipMaven 等,Go 语言也不能例外,在 go mod 出来之前,有两种模式:

  • GOPATH 模式,这种模式把问题想象的太过于简单理想化,可以说是Go语言设计的败笔,因为不支持对依赖的版本管理,不同的项目依赖同一个第三方库的不同版本,GOPATH 就无法搞定,只能切来切去。

  • vendor 模式,这种模式将第三方依赖下载到项目的 vendor 目录下,实现了不同项目之间相互隔离,但是也不支持对依赖的版本管理,没有统一的地方进行声明,一更新就会升级到最新版本,不像很多语言中,将项目的依赖固化到一个 *_lock.json 版本中,这样在项目转移到其他地方进行编译,能确保得到一致的功能。当然,也有很多人喜欢将 vendor 目录上传到仓库,保持不同地方编译后二进制一致性,不过这样会导致仓库体积过大,有利有弊。

在这种背景下,诞生了很多第三方的依赖管理工具,如:govendorglidedep等,为了解决这种乱象,Go官方出品了 Go Modules,一统江山,其他第三方管理工具就都成为了历时。

阅读全文 »

Rust 中的每一个引用都有其生命周期(lifetime),也就是引用保持有效的作用域。大部分时候生命周期是隐含并可以推断的,正如大部分时候类型也是可以推断的一样。但有些时候,Rust 需要我们使用泛型生命周期参数来注明他们的关系,这样就能确保运行时实际使用的引用绝对是有效的。

阅读全文 »

Rust 是一门赋予每个人构建可靠且高效软件能力的语言。

Rust 相比其他语言,具有显著的特点,尤其是:

  1. 性能高;Rust 速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成。

  2. 高可靠;Rust 丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误。

  3. 极具生产力;Rust 拥有出色的文档、友好的编译器和清晰的错误提示信息, 还集成了一流的工具——包管理器和构建工具, 智能地自动补全和类型检验的多编辑器支持, 以及自动格式化代码等等。

阅读全文 »