【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?

这篇具有很好参考价值的文章主要介绍了【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?

  • 博主简介:努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:数据结构、Go,Java等相关知识。
  • 博主主页: @是瑶瑶子啦
  • 所属专栏: Go语言核心编程
  • 近期目标:写好专栏的每一篇文章

【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?

一、Go语言的诞生

【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?
Go 语言从 2009 年 9 月 21 日开始作为谷歌公司 20% 兼职项目,即相关员工利用 20% 的空余时间来参与 Go 语言的研发工作。

谷歌的“20%时间”工作方式,允许工程师拿出20%的时间来研究自己喜欢的项目。语音服务Google Now、谷歌新闻Google News、谷歌地图Google Map上的交通信息等,全都是20%时间的产物。

该项目的三位领导者均是著名的 IT 工程师:

  • Robert Griesemer,参与开发 Java HotSpot 虚拟机;
  • Rob Pike,Go 语言项目总负责人,贝尔实验室 Unix 团队成员,参与的项目包括 Plan 9,Inferno 操作系统和 Limbo 编程语言;
  • Ken Thompson,贝尔实验室 Unix 团队成员,C 语言、Unix 和 Plan 9 的创始人之一,与 Rob Pike 共同开发了 UTF-8 字符集规范。

二、Why?——为什么需要Go

存在即合理,新事物的产生有它的道理

在了解为什么我们需要Go之前,我们先了解现有语言可以大致分为两大类:

2.1:静态类型语言、动态类型语言

首先,语言根据静态和动态类型分为以下两类分为以下两类:

  • 静态类型语言(Statically Typed Language(强类型语言,编译语言)
    • 💡简介 :在程序编译时变量的数据类型就被确定。且大多数静态语言在编写代码时,都要求声明变量的数据类型
    • 💡特性 :将所有代码编译(compile)完成,生成可执行文件,再执行。
    • 💡优点 高效: 运行速度快,便于调试,类型安全,结构规范
    • 💡缺点 :每次改动都需要重新编译,开发和学习效率低
    • 💡代表语言 :C,C++,Java(半编译,半解释),Pascal

👁️‍🗨️总结:静态类型语言,如C++,执行效率高,但编译、学习、开发效率低

  • 动态语言(弱类型语言
    • 💡简介 :程序在运行的时候可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化,判断变量的类型是在程序运行的时候完成的
    • 💡特性 变量声明时无需指定类型,会在该变量第一次将数据赋给该变量时,在内部记下该数据类型。将代码按行解释(launch)并允许。
    • 💡优点: 代码简洁(不需要写非常多的类型相关的代码)、可以把更多精力放在业务逻辑的处理上(完成相同逻辑的程序,使用ruby或者Python类动态语言所需要的代码量只有Java实现版本的1/10,相比C/C++差距更大)、更加灵活易于开发、学习、当有改动时无需重新编译,直接解释运行
    • 💡缺点 :不方便调试,命名不规范导致可读性差、运行速度慢
    • 💡代表语言 :PHP、Python、JavaScript

👁️‍🗨️总结:学习、开发效率高,执行效率低

补充:之前学习Java的时候,有一个概念是多态,其实本质就是一个变量的不同形态(类型),像静态语言,不能给变量赋予不同类型的值,需要采取:继承、接口等方式实现多态。而动态语言采用dynamic typing,就是说变量在运行期间是可变的,意味着对象的多态性是与生俱来的

2.2:Go——平衡语言差别

根据上面分析,

  • 传统语言如静态语言C++,学习和开发效率低(命名规范等等,需要花很多时间取学习,才能上手一个程序来写个程序实现某个功能),同时编译花费时间长,编译效率低编写——>编译——>运行这个完成这个链条的周期较长)
  • 动态语言,比如Python,没有强类型的约束,很多问题在程序运行起来才发现,虽然编写——>运行,节省了静态语言编译效率低的问题,但是这种类型相关的低级错误,应该交给编译器来发现

总之,简单来说,在Go之前,没有语言可以兼顾执行效率、开发效率

当然,这只是Go诞生的其中一点

下面列举Goggle公司创造Go语言的原因:

2.3:为什么Google创造了Go

  • 硬件技术更新快,机器性能大幅提高。目前主流的编程语言落后与硬件,不能合理利用多核多CPU的优势提高软件性能
  • 现有编程语言:风格不统一、技术能力不够、处理大并发不够好。且软件系统复杂度高,数以万计的代码,维护成本高,需要足够简洁高效的编程语言,提高开发效率,降低运维成本
  • c/c++项目,虽然运行速度快,但编译速度慢,且存在内存泄漏的问题
  • 部署平台各式各样,交叉编译难
  • 执行效率、开发效率上达到平衡

🤦🏻‍♀️为了解决以上问题,Goggle公司就自己造了个轮子——GO

三、Go的优点

💡Go的主要优点

  • 编译速度快
  • 执行速度快
  • 内存管理
  • 并发编程(多核CPU

3.1:Go编译快的原因

👉Go的编译器:
最初设计团队的想法是实现Go语言编译的前端,是基于C的gcc的编译器来编译成机器代码。这个前端编译器是目前Go的编译器之一:gccGo

  • 上面一行是“编译器前端”组成部分
  • 下面一行是“优化”+“编译器后端”组成部分
    【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?

在Go的1.5中,Go团队使用Go编写了Go的编译器(叫作自举),对比与gccgo:1,提高了编译速度,虽然执行速度略有下降;3,增加可编译平台

👁️‍🗨️C++为什么慢?
C++是也可以用gcc编译器编译的,所以从编译器角度来说,应该不是编译器使Go更快。很大程度是是Go语言的设计本身

⚠注意:这里我们比较编译速度都是比较的静态编译速度

🫐 Go语言·默认·编译方式是·静态编译·不依赖任何动态链接库,可以避免各种动态链接库依赖的问题;编译好后,只要平台是一致的(linux amd64),就可以任意部署,完全不用考虑链接库依赖问题;

💁🏻‍♂️静态编译&动态编译

  • 💙静态编译

    • 简介: 编译器在编译可执行文件时,会把该文件中使用到的链接库提取出来,链接打包进可执行文件中。编译之后的结果只生成一个可执行文件。

    • 优点:不需要管理不同版本库的兼容问题

  • 🧡动态编译

    • 简介: 可执行文件需要附带独立的库文件,不打包库到可执行文件中,减少可执行文件体积,编译完成,程序执行时,执行到了,再从库里面调用。
    • 优点:减少内存和存储占用(不同程序共享一个库)

将外部代码嵌入到当前生成的可执行文件中的就是静态编译,以跳转的方式引用外部代码的就是动态编译

在说回C++为什么慢?

  • include头文件
  • 模板编译

关于模板编译:首先,C++的模板使用,是为了支持泛型编程(这篇文章说的很清楚,这里就不重复造轮子了)。可以看到。编写不同类型的泛型函数,对于编码者来说,确实很方便,但是从那篇文章中,也有可能给编译器增加不必要的编译负担:1,代码膨胀,导致编译时间变长,2,容易出现模板编译错误,且错误信息不易定位

💁🏻‍♂️优化:

  • 基于C/C++慢的第一个引入头文件的问题,后生的语言大部分采用import module代替include 头文件的方式——Go采用的也是import module方式(下面是基于C的几种引入头文件的对比)

    • #include:  include做的事情其实就是简单的复制粘贴,将目标.h文件中的内容一字不落地拷贝到当前文件中,并替换掉这句include。
    • #import:实质上做的事情和#include是一样的,只不过OC为了避免重复引用可能带来的编译错误(这种情况在引用关系复杂的时候很可能发生,比如B和C都引用了A,D又同时引用了B和C,这样A中定义的东西就在D中被定义了两次,重复了),而加入了#import,从而保证每个头文件只会被引用一次。
      如果想深究,import的实现是通过#ifndef一个标志进行判断,然后在引入后#define这个标志,来避免重复引用的
    • PCH(PreCompiled Header): 实质上import也还是拷贝粘贴,这样就带来一个问题:当引用关系很复杂,或者一个头文件被非常多的实现文件引用时,编译时引用所占的代码量就会大幅上升(因为被引用的头文件在各个地方都被copy了一遍)。
        为了解决这个问题,C系语言引入了预编译头文件(PreCompiled Header),将公用的头文件放入预编译头文件中预先进行编译,然后在真正编译工程时再将预先编译好的产物加入到所有待编译的Source中去,来加快编译速度。
    • import Modules: 理论上说,想要提高编译速度,可以把所有头文件引用都放到pch中。但是这样面临的问题是在工程中随处可用本来不应该能访问的东西,而编译器也无法准确给出错误或者警告,无形中增加了出错的可能性。Modules相当于将框架进行了封装,然后加入在实际编译之时加入了一个用来存放已编译添加过的Modules列表。如果在编译的文件中引用到某个Modules的话,将首先在这个列表内查找,找到的话说明已经被加载过则直接使用已有的,如果没有找到,则把引用的头文件编译后加入到这个表中。这样被引用到的Modules只会被编译一次,但是在开发时又不会被意外使用到,从而同时解决了编译时间引用泛滥两方面的问题。
  • 基于第二个问题,Go根本没有将泛型编程纳入设计框架,根本不存在模板编译带来的开销。(不过Go1.18中已经支持泛型了)

3.1.2👩‍💻总结

Go编译速度快的几个原因

  • 使用import引用管理方式
  • 没有模板编译负担
  • 1.5版本后编译器的优化
  • 语言本身关键字很少

3.2:Go的性能

Go的执行速度,可以参考一个语言性能测试数据网站👉 he Computer Language Benchmarks Game。

  • Go的性能接近C++
  • 算法时间花销和Java接近,但内存花销远低于Java
  • 和python 对比,时间和内存开销都优秀

3.3:并发编程

上面我们提到,硬件技术更新快,机器性能大幅提高(eg:多核CPU)。Go语言设计其实初衷也是为了追平编程语言和硬件之间的差距。Go很多特性都是为了并发而生(一些语言也支持并发,但是是一些后期库支持并发和第三方库支持并发,这和Go天生并发的设计是不同的)

  • Go的并发量可以比大部分语言里普通的线程实现要

    这受益于轻量级的Goroutine,轻量化主要是它所占用的空间要小得多,例如64位环境下的JVM,它会默认固定为每个线程分配1MB的线程栈空间,而Goroutines大概只有4-8KB,之后再按需分配。足够轻量化的线程在相同的内存下也就可以有更高并发量(服务器CPU还没有饱和的情况下),同时也可以减少很多上下文切换的时间开销。但是如果你的每个线程占用空间都非常大时(比如10MB,当然这是非常规需求的情况下),Go的轻量化优势就没有那么明显了。

  • 语言设计上支持了并发

3.3:垃圾回收(GC)

垃圾回收(英语:Garbage Collection,缩写为GC),在计算机科学中是一种自动的存储器管理机制。当一个计算机上的动态存储器不再需要时,就应该予以释放,以让出存储器,这种存储器资源管理,称为垃圾回收。垃圾回收器可以让程序员减轻许多负担,也减少程序员犯错的机会

在使用Go或者其他有垃圾回收机制的语言(如Java),无需像C/C++一样进行手动释放内存空间(free()/delete)

  • 优点:方便
  • 限制:
    • 暗箱操作的不透明性
    • GC处理的性能开销
    • 对于性能要求高的场景,需要进行主动释放和优化(eg:自定义内存池)

如果对你有帮助还请:点赞+关注+收藏

如果文中有不足还请多多指出

关注我,一起学习Golang!
【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?文章来源地址https://www.toymoban.com/news/detail-420063.html

到了这里,关于【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Golang】Golang进阶系列教程--为什么说 Go 语言字符串是不可变的?

    最近有读者留言说,平时在写代码的过程中,是会对字符串进行修改的,但网上都说 Go 语言字符串是不可变的,这是为什么呢? 这个问题本身并不困难,但对于新手来说确实容易产生困惑,今天就来回答一下。 首先来看看它的底层结构: 和切片的结构很像,只不过少了一个

    2024年02月14日
    浏览(63)
  • 【Golang】Golang进阶系列教程--为什么 Go 不支持 []T 转换为 []interface

    在 Go 中,如果 interface{} 作为函数参数的话,是可以传任意参数的,然后通过类型断言来转换。 举个例子: 不管是传 int 还是 string,最终都能输出正确结果。 那么,既然是这样的话,我就有一个疑问了,拿出我举一反三的能力。是否可以将 []T 转换为 []interface 呢? 比如下面

    2024年02月15日
    浏览(68)
  • 【Golang】Golang进阶系列教程--为什么 Go for-range 的 value 值地址每次都一样?

    循环语句是一种常用的控制结构,在 Go 语言中,除了 for 以外,还有一个 range ,可以使用 for-range 循环迭代数组、切片、字符串、map 和 channel 这些数据类型。 但是在使用 for-range 循环迭代数组和切片的时候,是很容易出错的,甚至很多老司机一不小心都会在这里

    2024年02月15日
    浏览(61)
  • 为什么HTTP/3要引入UDP?(快速了解QUIC)

    笔者前段时间参加银行技术面时被问到了这个问题,特来整理资料以供记录分享 HTTP/3是HTTP协议的最新版本,它的诞生是为了解决HTTP/1和HTTP/2在性能和效率上的问题。在HTTP/3之前,HTTP协议使用的是TCP作为传输层协议。然而,随着互联网的发展,TCP的性能瓶颈逐渐显现出来。为

    2024年01月17日
    浏览(53)
  • 五分钟了解GPT 模型背后的原理是什么?为什么 GPT 模型能生成有意义的文本?为什么 GPT 模型不会做简单的数学题?为什么有人担心 GPT 模型可能会危害人类?

    由于 GPT 模型的相关内容非常丰富,所以我计划对它进行更加深入的学习和研究,并把它应用到自己的工作、生活和学习中,用来提高工作效能,改善生活质量,提升学习效果。 按照第一性原理,在开始实战演练之前,我认为有必要先了解一下 GPT 模型背后的原理,这样才能

    2024年02月07日
    浏览(64)
  • Go 语言为什么很少使用数组?

    大家好,我是 frank,「Golang 语言开发栈」公众号作者。 01 介绍 在 Go 语言中,数组是一块连续的内存,数组不可以扩容,数组在作为参数传递时,属于值传递。 数组的长度和类型共同决定数组的类型,不同类型的数组之间不可以比较,否则在编译时会报错。 因为数组的一些

    2024年02月04日
    浏览(55)
  • Go 语言为什么不支持并发读写 map?

    大家好,我是 frank ,「 Golang 语言开发栈」公众号作者。 01 介绍 在 Go 语言项目开发中,我们经常会使用哈希表 map ,它的时间复杂度是 O(1) ,Go 语言中的 map 使用开放寻址法避免哈希碰撞。 Go 语言中的 map 并非原子操作,不支持并发读写操作。 Go 官方认为 map 在大多数情况下

    2024年02月02日
    浏览(59)
  • 为什么选择Go语言编写网络应用程序

    关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力! 作为一名后端开发者,你一定对选择合适的编程语言来编写网络应用程序非常重视。在众多的编程语言中,Go语言(Golang)凭借其独特的特性和

    2024年02月02日
    浏览(89)
  • Go 语言为什么建议多使用切片,少使用数组?

    大家好,我是 frank,「Golang 语言开发栈」公众号作者。 01 介绍 在 Go 语言中,数组固定长度,切片可变长度;数组和切片都是值传递,因为切片传递的是指针,所以切片也被称为“引用传递”。 读者朋友们在使用 Go 语言开发项目时,或者在阅读 Go 开源项目源码时,发现很少

    2024年02月03日
    浏览(74)
  • 为什么说 Go 语言字符串是不可变的?

    原文链接: 为什么说 Go 语言字符串是不可变的? 最近有读者留言说,平时在写代码的过程中,是会对字符串进行修改的,但网上都说 Go 语言字符串是不可变的,这是为什么呢? 这个问题本身并不困难,但对于新手来说确实容易产生困惑,今天就来回答一下。 首先来看看它

    2024年02月07日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包