围棋之美

Gopher -Go的标志性吉祥物

我最近开始为我的一些辅助项目探索Go,并为它的美丽而震惊。

我意识到它在易用性(通常与动态类型的解释语言关联)与性能和安全性(类型安全,内存安全)(通常与静态类型的编译语言关联)之间取得了多么出色的平衡。

除此之外,还有两个功能使其成为现代系统开发的理想语言。 这两个功能将在下面的“优点”部分中进行详细说明。

其中之一是对语言的并发性的一流支持 (通过goroutine和通道,如下所述)。 通过并发设计,并发使您可以有效地利用CPU的功能。 即使您的处理器只有1个内核,并发设计也使您可以有效地使用一个内核。 这就是为什么通常在单台计算机上运行数十万个并发goroutine(轻量级线程)的原因。 通道和goroutines是分布式系统的核心,因为它们抽象了生产者-消费者消息传递范例。

我真正喜欢Go的另一个功能是接口。 接口可为您的系统启用松散耦合或解耦的组件 。 这意味着您的代码的一部分只能依赖于接口类型,而实际上并不在乎谁实现了接口或接口的实际实现方式。 然后,您的控制器可以提供满足该代码的接口(实现接口中的所有功能)的依赖项。 这也为单元测试(通过依赖注入)提供了一个真正干净的体系结构。 现在,您的控制器只需注入代码所需的接口的模拟实现即可测试其是否正确执行了其工作。

牢记所有这些功能,我认为Go确实是一种很棒的语言。 尤其适用于云系统开发(Web服务器,CDN,缓存等),分布式系统,微服务等用例。因此,如果您是工程师或初创企业,试图确定您想要探索或尝试的语言,请务必使用Go一个认真的想法。

在这篇文章中,我将讨论该语言的以下方面:

a)简介
b)为什么需要去
c)目标受众
d)Go的优势
e)Go的弱点
f)走向2
g)Go的设计理念
h)如何开始
i)谁在使用Go

介绍

Go是一种开放源代码语言,由Robert Griesemer,Rob Pike和Ken Thompson在Google创建。 这里的开源意味着每个人都可以通过打开新功能的提案 ,修复错误等为该语言做出贡献。该语言的代码可在GitHub上获得这里提供有关如何为该语言做出贡献的文档。

为什么需要Go

作者提到,设计新语言的主要动机是解决Google的软件工程问题。 他们还提到Go实际上是作为C ++的替代产品而开发的。

Rob Pike提到了Go编程语言的目的:

“因此,Go的目的不是对编程语言设计进行研究; 旨在为其设计师及其同事改善工作环境。 Go不仅是关于软件工程的,还在于编程语言的研究。 或者换句话说,它与软件工程服务中的语言设计有关。”

困扰Google软件工程领域的问题是 (摘自https://talks.golang.org/2012/splash.article ):

a)构建缓慢-构建有时会花费一个小时才能完成
b)不受控制的依赖性
c)每个程序员使用语言的不同子集
d)对程序的理解较差(代码难以阅读,文档记录不佳,等等)
e)重复工作
f)更新费用
g)版本偏斜
h)编写自动工具的难度
i)跨语言版本

为了使Go成功,Go必须解决以下问题 (摘自https://talks.golang.org/2012/splash.article ):

a)对于大型程序员团队,对于具有大量依赖关系的程序,go必须大规模工作。
b)Go必须熟悉,大致类似于C。 Google需要使程序员在Go中快速高效地工作,这意味着该语言不能太激进。
c)围棋必须是现代的。 它应该具有诸如并发之类的功能,以便程序可以有效利用多核计算机。 它应该具有内置的网络和Web服务器库,以便有助于现代开发。

目标观众

Go是一种系统编程语言。 Go对于诸如云系统(Web服务器,缓存),微服务,分布式系统(由于并发支持)之类的东西确实很有帮助。

长处

a)静态类型: Go是静态类型。 这意味着您需要在编译时声明所有变量和函数参数(以及返回变量)的类型。 尽管这听起来可能不方便,但这是一个很大的优势,因为在编译时会发现很多错误。 当您的团队规模增加时,此因素将起非常重要的作用,因为声明的类型使函数和库更易读且更易于理解。

b)编译速度: Go代码的编译速度 非常快 ,因此您无需一直等待代码编译。 :)实际上,“ go run”命令如此之快地启动了Go程序,以至于您甚至没有感觉到代码先被编译了。 感觉就像是一种解释语言。

c)执行速度: Go代码直接编译为机器代码,具体取决于OS(Linux / Windows / Mac)和正在编译代码的机器的CPU指令集体系结构(x86,x86–64,arm等) 。 因此,它运行非常快。

d)可移植:由于代码直接编译为机器代码,因此二进制文件变得可移植。 这里的可移植性意味着您可以从计算机(例如Linux,x86–64)中获取二进制文件,然后直接在服务器上运行该二进制文件(如果您的服务器也在x86–64体系结构上运行Linux)。

由于Go二进制文件是静态链接的,因此这成为可能,这意味着您的程序所需的任何共享操作系统库都将在编译时包含在二进制文件中。 它们在运行程序时不会动态链接。

这对于在数据中心的多台计算机上部署程序具有巨大的好处。 如果您的数据中心中有100台计算机,则只需将程序二进制文件“ scp”到所有计算机中,只要二进制文件是针对与计算机运行相同的OS和指令集架构编译的即可。 您无需关心它们正在运行哪个版本的Linux。 无需检查/管理依赖项。 二进制文件仅运行,您的所有服务都已启动:)

e)并发: Go对并发具有一流的支持。 并发是Go的主要卖点之一。 语言设计师围绕Tony Hoare撰写的“ Communicationing Sequential Processes ”论文设计了并发模型。

Go运行时使您可以在一台机器上运行数十万个并发goroutine 。 Goroutine是轻量级的执行线程。 Go运行时在操作系统线程上多路复用这些goroutine。 这意味着多个goroutine可以在单个OS线程上同时运行。 Go运行时具有一个调度程序,其任务是调度这些goroutine以便执行。

这种方法有两个好处:

i)Goroutine在初始化时有4 KB的堆栈。 与OS线程堆栈(通常为1 MB)相比,这确实很小。 当您需要同时运行数十万个不同的goroutine时,此数字很重要。 如果要并行运行数千个OS线程,则RAM显然将成为瓶颈。

ii)Go可能遵循与Java之类的其他语言相同的模型,Java支持与OS线程相同的线程概念。 但是在那种情况下,OS线程之间的上下文切换的开销比不同的goroutine之间的上下文切换的开销要大得多。

由于我在本文中多次提到“并发”,因此建议您查看Rob Pike关于“ 并发不是并行性 ”的演讲。 在编程中,并发是独立执行进程的组成,而并行性是(可能相关的)计算的同时执行。 除非您拥有具有多个内核的处理器或具有多个处理器,否则您就不会真正具有并行性,因为CPU内核一次只能执行一件事。 在单核计算机上,只是并发在后台进行工作。 OS调度程序为处理器上的不同时间片调度不同的进程(实际上是线程。每个进程至少有一个主线程)。 因此,在某一时刻,您只能在处理器上运行一个线程(进程)。 由于指令的执行速度很高,我们感觉到有很多事情正在运行。 但这实际上只是一次。

并发就是一次处理很多事情。 并行是关于一次做很多事情。

f)接口:接口可实现松散耦合的系统。 Go中的接口类型可以定义为一组函数。 而已。 任何实现这些功能的类型都隐式实现了接口,即,您无需指定一种类型实现该接口。 这是由编译器在编译时自动检查的。

这意味着您的代码的一部分可以仅依赖于接口类型,而实际上并不关心谁实现了接口或接口的实际实现方式。 然后,您的main / controller函数可以提供一个满足该代码接口(在接口中实现所有功能)的依赖项。 这也为单元测试(通过依赖注入)提供了一个真正干净的体系结构。 现在,您的测试代码只需注入代码所需的接口的模拟实现即可测试其是否正确执行了其工作。

尽管这对于解耦非常有用,但另一个好处是您随后开始将架构视为不同的微服务。 即使您的应用程序驻留在单个服务器上(如果您只是刚入门),您也可以将应用程序中所需的不同功能架构为不同的微服务,每个微服务都实现它所承诺的接口。 因此,其他服务/控制器仅在界面中调用方法,而实际上并不关心它们在后台的实现方式。

g)垃圾回收:与C不同,您无需记住释放指针或担心Go中的指针悬空。 垃圾收集器自动执行此工作。

h)没有例外,请自己处理错误:我喜欢Go不具有其他语言所具有的标准例外逻辑的事实。 Go迫使开发人员处理诸如“无法打开文件”等基本错误,而不是让他们将所有代码包装在try catch块中。 这也给开发人员施加压力,使他们必须认真考虑需要采取哪些措施来处理这些故障情况。

i)出色的工具: Go的最佳方面之一是其工具。 它具有以下工具:

i) Gofmt:它会自动格式化和缩进您的代码,以使您的代码看起来像地球上的每个Go开发人员一样。 这对代码的可读性有很大的影响。

ii)开始运行:这将编译您的代码并运行它们,两者都:)。 因此,即使Go需要编译,该工具也让您感觉它是一种解释型语言,因为它编译代码的速度如此之快,以至于您甚至在编译代码时都没有感觉。

iii) Go get:这将从GitHub下载该库并将其复制到您的GoPath中,以便您可以在项目中导入该库

iv) Godoc: Godoc解析您的Go源代码(包括注释),并以HTML或纯文本格式生成其文档。 通过godoc的Web界面,您可以然后看到文档及其所包含的代码。 您可以一键式浏览功能文档到其实现。

您可以在此处检查更多工具

j)强大的内置库: Go具有强大的内置库来辅助现代开发。 他们之中有一些是:

a) net / http-提供HTTP客户端和服务器实现

b) 数据库/ sql —与SQL数据库交互

c) encoding / json — JSON被视为标准语言的一等成员:)

d) html / templates — HTML模板库

e) io / ioutil —实现I / O实用程序功能

Go地平线上正在进行许多开发。 您可以在此处找到所有用于各种工具和用例的Go库和框架。

弱点

1.缺少泛型 -泛型让我们围绕以后要指定的类型设计算法。 假设您需要编写一个函数来对整数列表进行排序。 稍后,您需要编写另一个函数来对字符串列表进行排序。 到那时,您意识到代码看起来几乎相同,但是您不能使用原始函数,因为该函数可以将整数类型的列表或字符串类型的列表作为参数。 这将需要代码重复。 因此,泛型使您可以围绕稍后可以指定的类型设计算法。 您可以设计用于对类型T的列表进行排序的算法。然后,可以使用整数/字符串/任何其他类型调用相同的函数,前提是存在该类型的排序函数。 意味着编译器可以检查该类型的一个值是否大于该类型的另一个值(因为排序需要此值)

通过使用语言的空接口(接口{})功能,可以在Go中实现某种通用机制。 但是,这并不理想。

泛型是一个备受争议的话题。 一些程序员发誓。 尽管其他人不希望它们包含在语言中,因为泛型通常是在编译时间和执行时间之间进行权衡的。

话虽如此,Go的作者已表示愿意在Go中实现某种泛型机制。 但是,这不仅仅是泛型。 如果泛型语言能够与语言中的所有其他功能一起正常工作,则只能将其实现。 让我们拭目以待,Go 2是否为他们提供了某种解决方案。

2.缺乏依赖关系管理 -Go1承诺意味着Go语言及其库在Go 1的生存期内无法更改其API。这意味着您的源代码将继续针对Go 1.5和Go 1.9进行编译。 因此,大多数第三方Go库也遵循相同的承诺。 由于从GitHub获取第三方库的主要方法是通过“获取”工具,因此,当您执行“获取github.com/vendor/library”时,您希望其master分支中的最新代码不会更改库API。 尽管这对于临时项目很酷,因为大多数库都没有兑现承诺,但这对于生产部署而言并不是理想的选择。

理想情况下,应该有某种方式进行依赖性版本控制,以便您可以在依赖性文件中简单地包含第三方库的版本号。 即使他们的API发生了变化,您也不必担心,因为较新的API会随附较新的版本。 稍后您可以返回以检查所做的更改,然后决定是否升级依赖文件中的版本,并根据API接口中的更改来更改客户端代码。

Go的官方实验DEP最好应成为解决这一问题很快。 大概在Go 2 :)

走向2

我真的很喜欢作者对这种语言采取这种开源方法的方式。 如果要在Go 2中实现功能,则需要编写文档,其中需要:

a)描述您的用例或问题
b)说明如何使用Go无法解决用例/问题
c)描述问题的严重程度(一些问题不够大或关注的程度不足以在给定的时间点优先解决)。
d)可选地,提出解决问题的方法

作者将对其进行审查并在此处链接。 有关问题的所有讨论都将在邮件列表和问题跟踪器等公共媒体上进行。

我认为,语言的两个最紧迫的问题是泛型和依赖管理。 依赖性管理更多是发布工程或工具问题。 希望我们将看到dep (官方实验)成为解决问题的官方工具。 鉴于作者已经表达了对通用语言的开放性,我很想知道他们如何实现它们,因为通用是以牺牲编译时间或执行时间为代价的。

Go的设计理念

罗伯·派克(Rob Pike)的《 简单就是复杂》Simplicity is Complicated)谈话确实使我想到了两件事。

具体来说,我喜欢的东西是:

a) 传统上,所有其他语言都希望仅添加新功能 。 这样,所有的语言都只是增加了膨胀性,在其编译器和规范中也变得过于复杂。 如果这种情况继续下去,将来每种语言都将看起来像一样,因为每种语言都会不断添加它没有的功能。 考虑一下,JavaScript添加了面向对象的功能。 Go语言作者故意没有在语言中包含很多功能。 只有那些作者同意的功能才被包括在内,因为那些确实觉得它们确实为语言可以实现的价值带来了价值的功能。

b) 特征就像解空间中的正交向量。 重要的是能够为您的用例选择并组合不同的向量。 这些向量应该自然地互相作用。 意味着该语言的每个功能都应可预测地与其他任何功能协同工作。 这样,这些功能集覆盖了整个解决方案空间。 相互之间非常自然地实现所有这些功能,会给语言实现带来很多复杂性。 但是该语言抽象了复杂性,并为您提供了一个简单易懂的界面。 因此,简单性只是隐藏复杂性的艺术:)

c) 可读性的重要性经常被低估。 可以说,可读性是设计编程语言中最重要的事情之一,因为重要性和维护软件的成本都很高。 太多的功能会损害语言的可读性。

d) 可读性也意味着可靠性。 如果语言很复杂,则您必须了解更多内容,才能阅读和使用代码。 同样,对其进行调试并能够对其进行修复。 这也意味着您团队中的新开发人员将需要更多的扩展时间,以使他们对语言的理解达到可以为您的代码库做出贡献的地步。

摘自: https : //blog.digitalocean.com/get-your-development-team-started-with-go/

如何开始

您可以从此处下载Go并按照安装说明进行操作。

这是Go入门的官方指南以身作则也是不错的选择。

如果您想读一本书,那么Go编程语言就是一本很好的书。 它以与传奇的C编程语言书类似的精神编写,由Alan AA DonovanBrian W. Kernighan撰写。

您可以加入Gophers Slack频道与社区互动并参与有关该语言的讨论。

谁在使用Go

许多公司已经开始对Go进行大量投资。 以下是一些较大的名称:

Google- KubernetesMySQL扩展基础结构dl.google.com (下载服务器)

BaseCamp — 前往BaseCamp

CloudFlare — 博客ArsTechnica文章

CockroachDB — 为什么Go是CockroachDB的正确选择

CoreOS — GitHub博客

DataDog — 转到DataDog

DigitalOcean — 让您的开发团队开始使用Go

Docker — 为什么我们决定在Go中编写Docker

Dropbox — 开放资源我们的Go库

解析- 我们如何将API从Ruby迁移到Go并保存理智

Facebook — GitHub

英特尔— GitHub

Iron.IO- 经过2年的生产/

MalwareBytes — 使用golang /每分钟处理一百万个请求

中度- 中度如何社交

MongoDB — Go代理

Mozilla — GitHub

Netflix — GitHub

Pinterest — GitHub

细分— GitHub

SendGrid — 如何说服您的公司选择Golang

Shopify- Twitter

SoundCloud — 前往SoundCloud

SourceGraph — YouTube

Twitter — 每天实时处理50亿个会话

Uber — 博客GitHub

你走之前…

感谢您的时间。 如果您喜欢这篇文章,非常感谢您通过Twitter / Facebook与您的朋友分享这篇文章。 您可以在Twitter上找到我, 网址https://twitter.com/kanishkdudeja

交叉发布于: https : //kanishkdudeja.in/the-beauty-of-go/

From: https://hackernoon.com/the-beauty-of-go-98057e3f0a7d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值