关于 Colobu | 鸟窝 晁岳攀

rpcx作者,出版《深入理解Go并发编程》等,中科大,先后在清华同方、Motorola、Comcast、新浪等公司工作。

RSS 地址: https://colobu.com/atom.xml

请复制 RSS 到你的阅读器,或快速订阅到 :

Colobu | 鸟窝 晁岳攀 RSS 预览

在 Rust 中同时支持异步和同步代码

1970-01-01 08:00:00

来,过路人,请坐到我身边来,听老衲讲一讲我对 Rust 过分要求的故事。

四种字符串和bytes互相转换方式的性能比较

1970-01-01 08:00:00

昨天公司群中同事提到 Go 1.22 中 string 和 bytes 的互转不需要再用 unsafe 那个包了,直接转就可以。我翻看了 Go 1.22 的 release notes 没找到相应的介绍,但是大家提到了 kubernetes 的 issue 中有这个说法:

As of go 1.22, for string to bytes conversion, we can replace the usage of unsafe.Slice(unsafe.StringData(s), len(s)) with type casting []bytes(str), without the worry of losing performance.

As of go 1.22, string to bytes conversion []bytes(str) is faster than using the unsafe package. Both methods have 0 memory allocation now.

自 Go 1.22 起,对于 string 到 bytes 的转换,我们可以用类型转换 []bytes(str) 来替换 unsafe.Slice(unsafe.StringData(s), len(s)) 的用法,而不用担心性能损失。
自 Go 1.22 起,string 到 bytes 的转换 []bytes(str) 比使用 unsafe 包更快。现在两种方法都不会有内存分配。

这个说法让我很好奇,但是我还是想验证一下这个说法。

注意,这个说法只谈到了 string 到 bytes 的转换,并没有提到 bytes 到 string 的转换,这篇文章也会关注这两者的互转。

首先,让我们看看几种 string 和 bytes 的转换方式,然后我们再写 benchmark 比较它们之间的性能。

没有什么不可能:修改 Go 结构体的私有字段

1970-01-01 08:00:00

在Go语言中,结构体(struct)中的字段如果是私有的,只能在定义该结构体的同一个包内访问。这是为了实现数据的封装和信息隐藏,提高代码的健壮性和安全性。

但是在某些情况下,我们可能需要在外部包中访问或修改结构体的私有字段。这时,我们可以使用 Go 语言提供的反射(reflect)机制来实现这一功能。

即使我们能够实现访问,这些字段你没有办法修改,如果尝试通过反射设置这些私有字段的值,会 panic。

甚至有时,我们通过反射设置一些变量或者字段的值的时候,会 panic, 报错 panic: reflect: reflect.Value.Set using unaddressable value

在本文中,你将了解到:

  1. 如何通过 hack 的方式访问外部结构体的私有字段
  2. 如何通过 hack 的方式设置外部结构体的私有字段
  3. 如何通过 hack 的方式设置 unaddressable 的值

使用eBPF编写系统调用跟踪器

1970-01-01 08:00:00

先决条件

系统调用、eBPF、C语言、底层编程基础。

简介

eBPF(扩展的伯克利数据包过滤器)是一项允许用户在内核中运行自定义程序的技术。BPF或cBPF(经典BPF)是eBPF的前身,它提供了一种简单高效的方法来基于预定义规则过滤数据包。与内核模块相比,eBPF程序提供了更高的安全性、可移植性和可维护性。现有多种高级方法可用于处理eBPF程序,如Cilium的Go语言库、bpftrace、libbpf等。

Russ Cox 引退以及他的新项目 Oscar

1970-01-01 08:00:00

Go 第一代技术领导人 Rob Pike, 近两年已经隐居澳大利亚。
Go 第二代技术领导人 Russ Cox 2024 年 8 月 2 日宣布卸任,转战 AI 项目,聚焦 Oscar 项目。
Go 第三代技术领导人 Austin Clements, 同样和 Russ Cox 一样毕业于美国的一个计算机技术比较出名的一个学院,算是 Russ Cox 的师弟,Austin是Go语言运行时系统和垃圾收集器的主要贡献者之一,在运行时和内存管理等底层系统方面有深入的专长。

128位整数的原子操作

1970-01-01 08:00:00

我们已经知道,标准库中的 atomic 针对 int32/uint32、int64/uint64 提供了原子操作的方法和函数,但是如果针对 128 bit 的整数呢?

Go 朝着错误的方向发展

1970-01-01 08:00:00

这是 Aliaksandr Valialkin 昨天刚写的一篇文章, 心有戚戚焉,所以特意翻译成中文,个人感觉,自从Rob Pike退休后,Go在大方向迷失了,正如老貘(Go101)所说,目前Go的开发就像完成KPI一样,也许, 大师不会再回来了。

Aliaksandr Valialkin是fasthttp的作者,也是VictoriaMetrics开发者,一位资深的Go程序员。

以下是译文。

Rob Pike 语录

1970-01-01 08:00:00

1. 计算机领域里,没有什么问题是加一层间接寻址解决不了的。

There's nothing in computing that can't be broken by another level of indirection.

这是 Rob Pike 的修改版。

经常 level of insriection 误引用为 abstraction layer

原始版本出自 Butler Lampson
All problems in computer science can be solved by another level of indirection

但是 David Wheeler 完成了下半句:
All problems in computer science can be solved by another level of indirection, except for the problem of too many layers of indirection.

还有 Kevlin Henney 的下半句:
ll problems in computer science can be solved by another level of indirection, except for the problem of too many layers of indirection."

From Beautiful Code: Another Level of Indirection

这句话幽默地指出,在计算机编程中,通过引入额外的抽象层或中间层,几乎可以解决任何复杂的问题。这种思路在软件设计和架构中很常见。

Rust tips #81 ~ #90

1970-01-01 08:00:00

Rust tips #61 ~ #80

1970-01-01 08:00:00

Tip #61

前几天有人问我关于智能指针的事。这里简单介绍一下 Rc<T> 智能指针的基础知识:

Rust tips #41 ~ #60

1970-01-01 08:00:00

Tip #41

类似于 Go 语言中的通道(Go 的 channel),Rust 中的 std::sync::mpsc 提供了一种线程间安全地读写数据的机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
});
let received = rx.recv().unwrap();
println!("Got: {}", received);
}

在这个例子中,我们创建了一个通道,然后在一个线程中发送了一个字符串。在主线程中,我们等待接收这个字符串并打印它。

Rust tips #21 ~ #40

1970-01-01 08:00:00

Tip #21

在 Rust 中,我们经常使用 Clone()Copy()。这两者之间的区别是什么?

如何将图片编码成base64?

1970-01-01 08:00:00

图片的 base64 编码在多种上下文中都很有用。当需要通过旨在处理文本数据的媒体存储或传输图片时,它通常会被使用,比如嵌入到网页或者通过 API 上传图片。这篇文章将介绍如何使用 Go 标准库得到任何图片的 base64 编码的值。

Rust tips #1 ~ #20

1970-01-01 08:00:00

Tip #001

Rust 不支持静态 vec(static vec),但是最接近的是静态数组。例如,如果你想存储三个字符串的数组,可以尝试这样: static STRINGS : [&str;3] = ["a", "b", "c"]

Redka - 父亲是Redis,母亲是SQLite

1970-01-01 08:00:00

Redka旨在使用SQLite重新实现Redis的优秀部分,同时保持与Redis API的兼容性。

有意思的特性:

Redia 并不期望完全达到 Redis 那么高的性能,但是性能上也并不会落后很多。它的主要功能还是 SQL + Redis 的功能,集成了两种优秀产品 SQLite 和 Redis 的盛世美颜。

命令分发模式

1970-01-01 08:00:00

命令分发模式 (command dispatcher pattern)不属于23种经典的设计模式。它是一种不太为人所知的设计模式,它主要用于构建可扩展、可插拔的系统架构,将请求与执行请求的操作对象解耦。它类似于命令模式(Command Pattern),但更加灵活和动态。

虽然Command Dispatch Pattern不属于那23种经典模式,但它确实是一种很有价值的模式,可以应用于需要在运行时动态添加、修改或删除操作的系统中,使系统更加灵活和可扩展。

这种模式通过允许方便的添加、替换或移除任何命令处理器, 非常的灵活,将命令调用和命令处理解耦。而且每个命令可以由单独的命令处理器处理,代码组织和维护也很方便。

实际上,对于 Gopher 来讲,必然已经接触到这个模式了,只不过少有人指出或者梳理这种模式,但是在标准库和一些知名的项目中,其实已经自然的应用了,而且看起来整个架构也非常的清爽。

使用Rust捕获和解析网络包

1970-01-01 08:00:00

前两篇文章介绍了C++和Go中利用TCP Option中的时间戳实现计算网络时延。基于“用Rust重写一切”的哲学,今天我们来看看Rust中如何做这个事情。夜深人静,再肝一篇关于网络编程的文章。

使用Go语言实现 pping

1970-01-01 08:00:00

大家好,我是鸟窝。

在前一篇“pping:被动式ping,计算网络时延”一篇中,我给大家介绍了 pping 这个工具的原理和使用方法。这篇文章中,我将使用 Go 语言实现 pping 工具。

让 Rob Pike 或者字节跳动的同学实现一个红黑树

1970-01-01 08:00:00

红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构。它在1972年由鲁道夫·贝尔发明,被称为“对称二叉B树”,它现代的名字源于利奥尼达斯·J·吉巴斯和罗伯特·塞奇威克于1978年写的一篇论文。红黑树的结构复杂,以至于有些个别公司拿它当做面试题现场实现,但它的操作有着良好的最坏情况运行时间,并且在实践中高效:它可以在O(log^n)时间内完成查找、插入和删除。

sqlx: 一个优秀的rust异步SQL库

1970-01-01 08:00:00

上一篇我介绍了Go生态圈的sqlx库。 Rust生态圈也有一个知名的sqlx库,今天给大家介绍一下。这两个没有什么关联啊,纯粹属于名称相同而已。