如何将AI能力与大数据技术结合,助力数据分析治理等工作的效率大幅提升,优化大数据引擎的性能及成本? 了解详情
写点什么

蔡超:入门 Go 语言必须跨越的五个思维误区

  • 2019-03-22
  • 本文字数:2063 字

    阅读完需:约 7 分钟

蔡超:入门 Go 语言必须跨越的五个思维误区

你好,我是蔡超,现在是 Mobvista 技术副总裁,前亚马逊(中国)首席软件架构师,极客时间《Go 语言从入门到实战》视频课程的作者。


在 2018 年的 QCon 北京全球软件开发大会上,我做了题为《讲给 Java / C++开发者的 Go 高效编程》的主题演讲,会后跟大家交流,发现许多人对 Go 语言的学习有需求和热情。但大家的普遍问题就是:不知道该如何高效的入门 Go 语言,尤其是有编程基础的开发者,一不小心就会陷入思维的误区。


因此,今天我就来梳理一下 Go 语言入门学习的过程中,你容易产生的五个思维误区,帮你掌握在 Go 语言与其他编程语言的不同之处。


一、重新思考面向对象程序的设计和实现

首先,你要先理解 Go 语言面向对象编程是具有特殊性的。当然,“Go 是不是支持面向对象“这本身就是一个值得思考的话题,官方文档给出的答案是“Yes and no” 。虽说 Go 语言中是有类型的存在,也允许面向对象的编程风格,但却没有类型层次结构。


Go 语言中没有对类型继承提供支持,而是通过复合来进行扩展,并通过类型嵌入来简化复合的使用。很多人会把类型嵌入看成是 Go 中的继承机制,但是类型嵌入并不支持最基本的继承特性:


  • 子类替换

  • 方法重载(override)


Go 语言中的接口机制与其他语言截然不同,实现接口的类型完全不依赖于接口定义。接口作为方法签名的集合,任何类型的方法集中只要拥有与之对应的全部方法,就表示它实现了该接口。只有深刻理解这些,才能更好发挥 Go 的生产力特性。


不支持继承,特殊的接口类型,这些都会要求我们重新思考设计和编程实现。


戳此可获取:Go语言官方文档


二、改变传统 GC(垃圾收集器)语言的思维模式

Go 是一个非常特殊的语言,即追求简单性又追求高效率,Go 既内置支持 GC(垃圾收集器),又支持指针对内存的直接访问。其他支持 GC 的语言,比如在 Java 中,由于希望对开发者可以屏蔽内存管理,所以语言中没有提供指针的直接访问。为了提高数据访问和传递的效率,编程语言根据不同的情况,通过约束采用值传递或引用传递,来减少数据复制。


而 Go 比较简单地统一采用值传递,但提供指针机制,因此用户可以自己来选择数据的传递方式,要引用传递时可以通过传递指针来完成。


所以在编码时,你要考虑充分指针,提高数据访问效率,减少内存复制并编写 GC 友好的代码。


三、重新思考程序的错误处理机制

Go 语言的错误处理机制中既不支持现在主流的异常模式,同时也与传统的 C 程序通过返回值返回错误状态不同,Go 语言支持返回多个值,可以同时返回结果和错误状态。


  • 以下是 Java 语言示例:


try{...}catch(XXException e){       //错误处理}
复制代码


  • 以下是 Go 语言示例:


if v, err = callSomeFn(); err!=nil{   //错误处理}
复制代码


Go 的 error 处理方式一直以来都是争论的焦点,很多开发者认为 Go 的错误处理机制似乎回到了 70 年代,使得错误处理代码冗长且重复。而 Go 的设计者则认为 try-catch-finally 的结构导致异常处理与控制流程的耦合,从而使程序结构发生了混乱。


Go 的设计者当初选择返回值这种错误处理机制,而不是 try-catch 这种机制,主要是考虑到前者适用于大型软件,后者更适合小程序。因此,程序变大的时候,try-catch 会让错误处理更加冗长繁琐,也就容易出错。try-catch-finally 会怂恿程序员标注过多普通错误,诸如打开文件失败之类的异常,使得程序更加繁琐。


这就决定了你必须重新思考错误处理的编程模式,因为这样的代码是 Go 语言中非常常见的。


四、思考和学习使用 CSP 并发模型

与主流语言通过共享内存来进行并发控制方式不同,Go 语言采用了 CSP 模式。这是一种用于描述两个独立的并发实体通过共享的通讯 Channel(管道)进行通信的并发模型。很多使用过 Erlang 等基于 Actor 模式的程序员,会误认为 Go 和这些语言的模式是一样的。


而实际上,Go 的 CSP 模式与常见的 Actor 模式(如:Erlang 语言就采用了 Actor 模式)也有不少差异,例如:


  • 和 Actor 的直接通讯不同,CSP 模式则是通过 Channel 进行通讯的,更松耦合一些;

  • Go 中 channel 是有容量限制并且独立于处理 Groutine,而如 Erlang,Actor 模式中的 mailbox 容量是无限的,接收进程也总是被动地处理消息。



Actor 模式和 CSP 模式区别图


所以,要用好 Go 语言,一定要思考和学习使用 CSP 来高效的实现我们常见并发任务。


五、理解 Goroutine 的调度机制

Goroutine 是 Go 语言的招牌特性之一,较之线程是非常轻量级的。但是,如果你不了解其中的机制,仅仅按照线程的套路来使用,就发挥不出来 Goroutine 的优势,甚至还会导致很多性能问题。


Goroutine 有着和 Java 线程完全不同的调度机制,Java 线程模型中线程和 KSE(Kernel space Entity)是 1:1 的关系,一个用户线程对应一个 KSE。而 Groutine 和 KSE 是多对多的对应关系。虽然,Groutine 的调度机制不如,由内核直接调度的线程机制效率那么高,但是由于 Groutine 间的切换可以不涉及内核级切换,所以代价小很多。


CSP 并发模型、Goroutine 的调度机制是 Go 语言入门学习的过程中的重点和难点,我会在《Go语言从入门到实战》进阶篇中进行详细的讲解,敬请期待。


拓展阅读:


5个步骤,编写你的第一个 Go 程序


2019-03-22 17:0410331

评论

发布
暂无评论
发现更多内容

[Day35]-[二叉树]-二叉树的锯齿形层序遍历

方勇(gopher)

LeetCode 二叉树 数据结构算法

2022 之Python操作 Excel,xlrd 与 xlwt 模块一文掌握

梦想橡皮擦

5月月更

《深入理解计算机系统》读书笔记——第二章(一)

如浴春风

5月月更

WebAssembly技术_加载ffmpeg在Web端调用解码

DS小龙哥

5月月更

thinkphp5的消息队列详细教程

CRMEB

在线Excel列提取导出工具

入门小站

工具

网站开发进阶(十九)计划任务功能——信息自动弹出

No Silver Bullet

5月月更 自动弹窗

Python 操作 Excel,从 xlwings 模块开始

梦想橡皮擦

5月月更

全新的经济模型、上线币安NFT市场,PlatoFarm现状一览

石头财经

DevOps系列之 —— 持续规划与设计(一)敏捷项目管理理念与方法实践

若尘

DevOps 5月月更

EasyRecovery2022最新版电脑数据恢复工具

茶色酒

数据恢复软件

《敏捷软件测试》的作者将“Agile Testing”改为“Holistic Testing”

BY林子

软件测试 敏捷测试 持续测试

数字化时代,国内SaaS行业的发展态势

小炮

SaaS

《手写 Mybatis》第7步:SQL执行器的定义和实现

小傅哥

小傅哥 mybatis 面试经验 源码学习 手写Mybatis

HUAWEI永远滴神!华为顶级网络专家总结出了这份网络协议开源手册

Java架构追梦

华为 后端开发 网络协议、

网络安全日常学习之渗透测试思路总结

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 漏洞挖掘

[Day35-02]-[二叉树]-求根节点到叶节点数字之和

方勇(gopher)

LeetCode 二叉树 数据结构算法

Nginx解决跨域问题

乌龟哥哥

5月月更

MongoDB 入门教程系列之一:开发环境搭建以及 Node.js 和 Java 的读写访问

Jerry Wang

数据库 mongodb 分布式 分布式数据库mongodb 5月月更

ONES 收购 SegmentFault 思否,共建高质量开发者社区

万事ONES

项目管理 程序员 研发管理 ONES

AI大咖说-如何评价论文的创新性

AIWeker

人工智能 5月月更 论文写作

从研发效能的视角谈“故障复盘”

博文视点Broadview

Pipy for Next Web:静态内容服务与缓存加速

Flomesh

CDN加速 Pipy Headless CMS

四、应用高可用之容量设计

穿过生命散发芬芳

5月月更 容量设计

《对线面试官》Java简历怎么写?

Java3y

Java 程序员 Java web 5月月更

Redis 内存优化在 vivo 的探索与实践

vivo互联网技术

数据库 redis 性能优化 内存优化

【C语言】计算器

謓泽

5月月更

web前端培训Vite的原理源码解析

@零度

前端开发 vite

架构实战营模块四作业

哈啰–J

springsecurity从当前请求对象中获取用户信息

周杰伦本人

5月月更

springboot线程池的使用和扩展

程序员欣宸

Java 线程池 5月月更

蔡超:入门 Go 语言必须跨越的五个思维误区_编程语言_蔡超_InfoQ精选文章