大家好,我是煎鱼。 自从 Go 语言在国内火热以来,除去泛型,其次最具槽点的就是 Go 对错误的处理方式,一句经典的 if err != nil 暗号就能认出你是一个 Go 语言爱好者。 自然,大家对 Go error 的关注度更是高涨,Go team 也是,因此在 Go 2 Draft Designs 中正式提到了 error handling(错误处理)的相关草案,希望能够在未来正式的解决这个问题。 在今天这篇文章中,我们将一同跟踪 Go2 error,看看他是怎么 “挣扎” 的,能不能破局?
今天在 Gophercon2020 上,Go 1.13 错误提案的作者事后提及他对目前错误格式化的缺失表示遗憾,而且在未来很长的好几年内都不会有任何进一步改进计划。 对此他本人给出的原因之一是:对于错误处理这一领域特定的问题,在他的能力范围内实在是无法给出一个令所有人都满意的方案。 尽管如此,在他演讲的最后,还是给出了一些关于错误嵌套的建议,即实现 fmt.Formatter,图中给出了一个简单的例子,大家可以参考如下代码: type DetailError struct { msg, detail string err error } func (e *DetailError) Unwrap() error { return e.err } func (e *DetailError) Error() string { if e.
大家好,我是煎鱼。前段时间 Go 语言的泛型讨论频频出现在各微信群,且又冲上了国内外各大文章的 “头条”: 信息汇总来看,Go 泛型这几年会出,但大体来讲现在 Go 泛型又又又推迟了,好家伙。我最早了解到时是考虑 Go1.16 释出,后面又推到了 Go1.17,接着现在又延期到了 Go1.18 了(2021 年底)。 看到了信息的表象后,再想想为什么泛型 “这件事情” 突然醒目起来了,其原因之一是由官方 Go,11 岁 的博文所引爆的。 同时近日举办的 GopherCon2020 大会,Robert Griesemer 分享的 Typing [Generic] Go。更正式的让 Go 泛型更面向了大众,也侧面的说明官方认为其已经到达了一个新的阶段了,进入最终实现阶段。
不说不知道,一说下一跳。Go 语言已经开源 11 周年了,感觉是一路高歌,Release History (polarisxu 整理)如下: 2011 年 3 月 16 日,Go 语言的第一个稳定版本 r56 发布; 2012 年 3 月 28 日,Go 语言的第一个正式版本 Go1 发布,并承诺 1.x 的 兼容性; 2013 年 5 月 13 日,Go1.
大家好,我是煎鱼。 在所有的语言中,反射这一功能基本属于必不可少的模块。虽说 “反射” 这个词让人根深蒂固,但更多的还是 WHY。反射到底是什么,反射又是基于什么法则实现的? 今天我们通过这篇文章来一一揭晓,以 Go 语言为例,了解反射到底为何物,其底层又是如何实现的。 反射是什么 在计算机学中,反射是指计算机程序在运行时(runtime)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够 “观察” 并且修改自己的行为(来自维基百科)。 简单来讲就是,应用程序能够在运行时观察到变量的值,并且能够修改他。 一个例子 最常见的 reflect 标准库例子,如下: import ( "fmt" "reflect" ) func main() { rv := []interface{}{"hi", 42, func() {}} for _, v := range rv { switch v := reflect.
”Hello World“ 程序几乎是每个程序员入门和开发环境测试的基本标准。代码如下: #inclue <stdio.h> int main() { printf("Hello Wolrd\n"); return 0; } 编译该程序,再运行,就基本完成了所有新手的第一个程序。表面看起来轻轻松松,毫无悬念。但是实际上单纯这几下操作,就已经包含了不少暗操作。本着追根溯源的目的,我们将进一步对其流程进行分析。 其内部主要包含 4 个步骤,分别是:预处理、编译、汇编以及链接。由于篇幅问题本文主要涉及前三部分,链接部分将会放到下一篇文章来讲解。 预编译 程序编译的第一步是 “预编译” 环境。主要作用是处理源代码文件中以 ”#“ 开始的预编译指令,例如:#include、#define 等。 常见的处理规则是: 将所有 #define 删除,并且展开所有的宏定义。
昨天(20201017)很有幸的参加了 GoCN 的 2020 Gopher Meetup 深圳站,在台下听各位大佬分享各自的知识和案例。恰好也是我第一次参加这类 Meetup。因此希望也能够让没来的小伙伴对本次分享内容有一定的了解。 按过往对其观察的惯例,一般在下周后官方就会陆续释出 Meetup PPT 和推文,在此引个主线。 本次 Meetup 主要的方向是云原生,包含四位讲师分享,分享的主题如下: 华为云的 go 语言云原生实践。 go 云上微服务模式解构。 服务网格在边缘计算领域的实践与探索。 腾讯大规模 etcd 集群治理与优化实践。 华为云的 go 语言云原生实践 讲述华为云在早起使用 Go 语言时,当时 Go 语言的整体生态圈还比较薄弱,因此很多第三方基础/工具库并不全:
最近在翻阅文章时,看到全成推荐的《程序员的自我修养》,这是一本讲链接、装载与库的计算机图书,看了下目录后觉得挺有意思。 因此决定每读一章就将其读书笔记整理记录下来,分享给大家。 目录: 不要让 CPU 打盹 在计算机发展早期,CPU 资源十分昂贵。如果一个 CPU 只能运行一个程序,那么当程序在读写磁盘(进行 I/O 操作)时,CPU 就空闲下来了。这在当时简直就是巨大的浪费。 CPU 只能和一个程序A “聊天“,其他来再多的程序BCD,都没有任何操作的空间。就像早年的手机,打电话和上网(语音/数据)只能二选一,作为 CPU 的你,并不能多线程操作。 因此机智的人们很快就编写了一些监控程序,希望来解决这个问题。 多道程序(Multiprogramming) 多道程序起,操作系统正式具有同时运行多个程序的能力。 其是让 CPU 一次读取多个程序放入内存中。当某个程序暂时无须使用 CPU 时,监控程序就把另外的正在等待 CPU 资源的程序启动,以此使得 CPU 能够充分地利用起来。这种策略的确大大的提高了 CPU 资源的利用率。
自古应用程序均从 Hello World 开始,你我所写的 Go 语言亦然: import "fmt" func main() { fmt.Println("hello world.") } 这段程序的输出结果为 hello world.,就是这么的简单又直接。但这时候又不禁思考了起来,这个 hello world. 是怎么输出来,经历了什么过程。 真是非常的好奇,今天我们就通过这篇文章来一探究竟。 引导阶段 查找入口 开始剖析之路,首先编译上文提到的示例程序: $ GOFLAGS="-ldflags=-compressdwarf=false" go build 在命令中指定了 GOFLAGS 参数,这是因为在 Go1.
在前文 《限流熔断是什么,怎么做,不做行不行?》中针对 “限流” 动作,有提到流量控制其内部对应着两种常用的限流算法,分别是漏桶算法和令牌桶算法。因此会有的读者会好奇,这都是些啥? 为了更进一步的了解 WHY,本文来快速探索一下,看看限流下的一些 “算法” 们到底有何作用,是为何成为流量控制的基石的? 前言 理论上每一个对外/内提供功能的资源点,都需要进行一定的流量控制,否则在业务的持续迭代中,是有可能出现突发性流量的场景(就像年初所带来的一些行业突发转变,导致业务流量突然暴增): 若没有进行限流,就会出现一些奇奇怪怪的问题点,实则就是系统无法承受这波流量,逐渐崩溃,走向系统假死。 现实场景 最常见的现实场景就是日常随处可见的排插、插座,其内置的保险丝,也被称为电流保险丝,其主要是起过载保护作用,保险丝会在电流异常升高到一定的高度和热度的时候,自身熔断切断电流,从而起到保护电路安全运行的作用。 因此真实世界中有许多与软件工程中的限流熔断的场景有异曲同工之处,也是为了控制量,超量就切断。你也可以想想现实生活中是否有遇到其他类似的例子呢? 漏桶算法(Leaky Bucket) 漏桶算法(Leaky Bucket)是网络中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时常用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。 漏桶算法通过其算法调控了流量访问,使得突发流量可以被整形,去毛刺,变成一个相对缓和,以便为网络提供一个稳定的流量。 漏桶算法的存储桶主要由三个参数定义,分别是:桶的容量、水从桶中流出的速率、桶的初始充满度。 其核心理念就如字面意思:一个会漏水的桶。 Bursty Flow 在上图中,水龙头代表着突发流量(Bursty Flow)。当网络中存在突发流量,且无任何调控时,就会出现像 Bursty Data 处类似的场景。主机以 12 Mbps 的速率发送数据,时间持续 2s,总计 24 Mbits 数据。随后主机暂停发送 5s,然后再以 2 Mbps 的速率发送数据 3s,最终总共发送了 6 Mbits 的数据。