Go 语言 Channel 实现原理精要

Go 语言中的管道 Channel 是一个非常有趣的数据结构,作为语言中一种核心的数据类型,多个 Goroutine 在进行通信时就会使用 Channel 作为中间的通信方式,我们在一节中要介绍的就是 Golang 中 Channel 的实现原理。这一节中的内容总共包含两个部分,我们会先介绍 Channel 的设计原理以及它在 Go 语言中的数据结构,接下来我们会分析常见的 Channel 操作,例如创建、发送、接受和关闭的实现原理,由于在 Range 和 Select 两节中我们会提到 Channel 在不同的控制结构中组合使用时的现象,所以这一节还是会将重点放到 Channel 的常见操作上。 »

Go 语言 for 和 range 的实现

循环是几乎所有编程语言都具有的控制结构,也是编程语言中常用的控制结构,Go 语言除了使用经典的『三段式』循环之外,还引入了另一个关键字 range 帮助我们快速遍历数组、哈希表以及 Channel 等元素。在这一节中,我们将介绍 Go 语言中的两种不同循环,也就是经典的 for 循环和 for...range 循环,我们会分析这两种循环在运行时的结构以及它们的实现原理, »

谈 Golang 中的字符串和字节数组

字符串是 Go 语言中最常用的基础数据类型之一,虽然字符串往往都被看做是一个整体,但是实际上字符串是一片连续的内存空间,我们也可以将它理解成一个由字符组成的数组,Go 语言中另外一个与字符串关系非常密切的类型就是字节(Byte)了,相信各位读者也都非常了解,这里也就不展开介绍。我们在这一节中就会详细介绍这两种基本类型的实现原理以及它们的转换关系,但是这里还是会将介绍的重点主要放在字符串上,因为这是我们接触最多的一种基本类型并且后者就是一个简单的 uint8 类型,所以会给予 string 最大的篇幅,需要注意的是这篇文章不会使用大量的篇幅介绍 UTF-8 以及编码等知识,主要关注的还是字符串的结构以及常见操作的实现。 »

理解 Golang 哈希表 Map 的原理

这篇文章会介绍 Golang 中的另一个集合元素 — 哈希,也就是 Map 的实现原理;哈希表是除了数组之外,最常见的数据结构,几乎所有的语言都会有数组和哈希表这两种集合元素,有的语言将数组实现成列表,有的语言将哈希表称作结构体或者字典,但是它们其实就是两种设计集合元素的思路,数组用于表示一个元素的序列,而哈希表示的是键值对之间映射关系,只是不同语言的叫法和实现稍微有些不同。哈希表是一种古老的数据结构,在 1953 年就有人使用拉链法实现了哈希表,它能够根据键(Key)直接访问内存中的存储位置,也就是说我们能够直接通过键找到该键对应的一个值,哈希表名称的来源是因为它使用了哈希函数将一个键映射到一个桶中,这个桶中就可能包含该键对应的值。 »

详解 Kubernetes Job 和 CronJob 的实现原理

Kubernetes 作为一个容器编排引擎,任务和定时任务的支持是一个必须要支持的功能。Kubernetes 中使用 Job 和 CronJob 两个资源分别提供了一次性任务和定时任务的特性,这两种对象也使用控制器模型来实现资源的管理,我们在这篇文章种就会介绍它们的实现原理。Kubernetes 中的 Job 可以创建并且保证一定数量 Pod 的成功停止,当 Job 持有的一个 Pod 对象成功完成任务之后,Job 就会记录这一次 Pod 的成功运行;当一定数量的Pod 的任务执行结束之后,当前的 Job 就会将它自己的状态标记成结束。 »

详解 Kubernetes DaemonSet 的实现原理

Deployment 是 Kubernetes 中用于处理无状态服务的资源,而 StatefulSet 是用于支持有状态服务的资源,这两种不同的资源从状态的角度对服务进行了划分,而 DaemonSet 从不同的维度解决了集群中的问题 — 如何同时在集群中的所有节点上提供基础服务和守护进程。我们在这里将介绍 DaemonSet 如何进行状态的同步、Pod 与节点(Node)之间的调度方式和滚动更新的过程以及实现原理。 »

详解 Kubernetes StatefulSet 实现原理

在 Kubernetes 的世界中,Deployment 和 ReplicaSet 主要用于处理无状态的服务,无状态服务的需求往往非常简单并且轻量,每一个无状态节点存储的数据在重启之后就会被删除,虽然这种服务虽然常见,但是我们仍然需要有状态的服务来实现一些特殊的需求,StatefulSet 就是 Kubernetes 为了运行有状态服务引入的资源,例如 Zookeeper、Kafka 等。这篇文章会介绍 Kubernetes 如何在集群中运行有状态服务,同时会分析这些有状态服务 StatefulSet 的同步过程以及实现原理。 »

详解 Kubernetes Deployment 的实现原理

如果你在生产环境中使用过 Kubernetes,那么相信你对 Deployment 一定不会陌生,Deployment 提供了一种对 Pod 和 ReplicaSet 的管理方式,每一个 Deployment 都对应集群中的一次部署,是非常常见的 Kubernetes 对象。我们在这篇文章中就会介绍 Deployment 的实现原理,包括它是如何处理 Pod 的滚动更新、回滚以及支持副本的水平扩容。 »

Go 语言数组和切片的原理

数组和切片是 Go 语言中常见的数据结构,很多刚刚使用 Go 的开发者往往会混淆这两个概念,数组作为最常见的集合在编程语言中是非常重要的,除了数组之外,Go 语言引入了另一个概念 — 切片,切片与数组有一些类似,但是它们的不同之处导致使用上会产生巨大的差别。这里我们将从 Go 语言编译期间的工作和运行时来介绍数组以及切片的底层实现原理,其中会包括数组的初始化以及访问、切片的结构和常见的基本操作。 »

详解 Kubernetes 垃圾收集器的实现原理

垃圾收集器在 Kubernetes 中的作用就是删除之前有所有者但是现在所有者已经不存在的对象,例如删除 ReplicaSet 时会删除它依赖的 Pod,虽然它的名字是垃圾收集器,但是它在 Kubernetes 中还是以控制器的形式进行设计和实现的。在 Kubernetes 引入垃圾收集器之前,所有的级联删除逻辑都是在客户端完成的,kubectl 会先删除 ReplicaSet 持有的 Pod 再删除 ReplicaSet,但是垃圾收集器的引入就让级联删除的实现移到了服务端,我们在这里就会介绍垃圾收集器的设计和实现原理。 »

详解 Kubernetes ReplicaSet 的实现原理

Kubernetes 中的 ReplicaSet 主要的作用是维持一组 Pod 副本的运行,它的主要作用就是保证一定数量的 Pod 能够在集群中正常运行,它会持续监听这些 Pod 的运行状态,在 Pod 发生故障重启数量减少时重新运行新的 Pod 副本。这篇文章会介绍 ReplicaSet 的工作原理,其中包括在 Kubernetes 中是如何被创建的、如何创建并持有 Pod 并在出现问题时重启它们。 »

Elixir 从入门到放弃

过去将近一年的时间里,作者在日常工作中需要经常与 Elixir 这门编程语言打交道,在使用 Elixir 的过程中,发现这门编程语言有很多非常有趣的概念和设计,但是也遇到了更多很难甚至无法解决的问题,最终种种原因最终选择使用 Golang 替换掉生产环境中全部的 Elixir 项目,随着作者将主要编程语言逐渐迁移到 Go,觉得还是有必要对 Elixir 比较独特的语言谈一谈作者的经历和看法。我们将在这篇文章中为各位读者介绍 Elixir 这门编程语言、作者和它相处的体验和经历、最终为什么选择放弃这门编程语言以及不推荐各位工程师在生产环境中使用的原因。 »

指令集架构、机器码与 Go 语言

Go 语言编译的最后一个阶段就是根据 SSA 中间代码生成机器码了,这里谈的机器码生成就是在目标 CPU 架构上能够运行的代码,中间代码生成一节简单介绍的从抽象语法树到 SSA 中间代码的处理过程,处理 SSA 的将近 50 个步骤中有一些过程严格上来说其实是属于机器码生成阶段的。这一节将介绍 Go 编译器将 SSA 中间代码转换成汇编语言和机器码的过程,除此之外也会介绍指令集架构以及硬件相关的一些知识。 »

详解 Golang 中间代码生成

中间代码是一种应用于抽象机器的编程语言,它设计的目的主要是帮助我们分析计算机程序,在编译的过程中,编译器会在将语言的源代码转换成目标机器上机器码的过程中,先把源代码转换成一种中间的表述形式,这里要介绍的就是 Go 语言如何将抽象语法树转换成 SSA 表示的中间代码。 »

Golang 如何进行类型检查

我们在上一节中介绍了 Golang 的第一个编译阶段 — 通过词法和语法分析器的解析得到了抽象语法树,在这里就会继续介绍编译器执行的下一个过程 — 类型检查。Go 语言的编译器使用静态类型检查来保证程序运行的类型安全,当然它也会在编程期引入类型信息,让工程师能够使用反射来判断参数和变量的类型,在这一节中我们还是会重点介绍编译期间的静态类型检查。 »