软件开发新秀之Go语言

幸运草
幸运草
幸运草
896
文章
3
评论
2020年4月12日18:12:35 评论 258

欢迎大家来到Gopher_Zone,今天要隆重介绍的是编程界的新秀Go,一个有望成为新时代男主角的男人。实事求是哈,自从出道以来,Go语言备受Google公司内部的重视,在开源社区更是受到广大Gopher爱好者的青睐。

至此,大家会感到有些疑惑,为什么Go语言会有望成为新时代的编程界男主角呢?又是什么让它有如此大的魅力呢?接下来,让我们慢慢的走近它,了解它。

简介:

Go语言是谷歌推出的一种静态强类型、编译型、并发型,并具有垃圾回收功能的全新编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮丧,而Go语言让我体验到了从未有过的开发效率,它是一种抛弃繁杂,重于解决实际问题的实践型编程语言。

优势:

1、学习曲线容易

Go语言语法相对简单,罗布派克(Rob Pike)认为Go与Java类似,对于Java开发者来说,应该能够轻松学会Go。之所以将Go作为一个开源项目发布,目的是让开源社区有机会创建更好的工具来使用该语言,例如 Eclipse IDE中的插件。

2、效率&性能

开发过程中相较于Java和C++呆滞的编译速度,Go的快速编译时间是一个主要的效率优势;Go拥有接近C的运行速率和接近PHP的开发效率。

3、强大的标准库

Go语言是编程语言设计的又一次尝试,是对类C语言的重大改进,Go语言的标准库不但能让你访问底层操作系统进行系统编程,还提供了强大的互联网应用编程、网络编程、和并发编程、分布式编程支持。

4、自由高效

组合的思想,非侵入式接口。Go语言可以说是开发效率和运行效率的完美融合,天生的并发编程支持。Go语言支持几乎当前所有的编程范式:过程式编程、面向对象编程、面向接口编程、函数式编程。Gophers可以各取所需,自由组合,总之就是两个字,优秀。

5、并发性&协程与通道

Go 作为一门语言致力于使事情简单化。它并未引入很多新概念,而是聚焦于打造一门简单的语言,以并发编程为例。Goroutines(协程)是Go 面向线程的轻量级方法,而channel(信道)是 Goroutines(协程)之间通信的优先方式。简单对比一下

(1)内存消耗方面:

每个 Goroutine (协程) 默认占用内存远比 Java 、C 的线程少

goroutine:2KB

线程:8MB

(2)线程和Goroutine(协程)切换调度开销方面

线程/Goroutine 切换开销方面,goroutine 远比线程小

线程:模式切换(从用户态切换到内核态)、16个寄存器、PC、SP...等寄存器的刷新

Goroutine :只有三个寄存器的值修改 - PC / SP / DX

6、支持gRPC和Protocol Buffers

Go 语言对 protocol buffers 和 gRPC 有一流的支持。这两个工具能一起友好地工作以构建需要通过 RPC 进行通信的微服务器(microservices),可以更加高效,更加迅速的实现服务端与客户端的通信。

优势介绍,未完待续,在以后的文章中加以补充。

应用领域:

因为Go语言的强大优势,以及待开发的优秀的潜力,在相当多的领域都有它的身影。

1、服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。

2、网络编程,主要是Web应用、API应用。

3、因优秀的并发编程,适合游戏服务端开发。

4、容器领域,比较知名的开源项目Docker、K8s等就是Go语言实现的。

5、区块链领域,分布式数据库开发、这一领域是目前比较流行的。

6、云平台、云计算领域,2018年7月24日,Go 语言团队发布了一个新的开源项目Go Cloud。Go Cloud 是一个可在开放云平台上进行开发的库和工具集,旨在让Go语言成为开发构建可移植云端应用程序的首选语言。

版本简史:

随着版本的不断迭代与优化,性能更加优越,功能更加强大,在Go1.11最新版本中已实现对Go module的支持,逐渐弱化了工作目录GoPath的强制要求。

时间点 版本介绍
2007年 谷歌工程师Rob Pike, Ken Thompson和Robert Griesemer开始设计一门全新的语言,这是Go语言的最初原型
2009年11月10日 Go语言以开放源代码的方式向全球发布
2011年3月16日 Go语言的第一个稳定(stable)版本r56发布
2013年4月04日 Go语言的第一个Go 1.1beta1测试版发布
2013年5月02日 Go语言的第二个Go 1.1beta2测试版发布
2013年5月07日 Go语言Go 1.1RC2版发布
2013年5月09日 Go语言Go 1.1RC3版发布
2013年5月13日 Go语言Go 1.1正式版发布
2013年9月20日 Go语言Go 1.2RC1版发布
2013年12月1日 Go语言Go 1.2正式版发布
2014年6月18日 Go语言Go 1.3版发布
2014年12月10日 Go语言Go 1.4版发布
2015年8月19日 Go语言Go 1.5版发布,本次更新中移除了”最后残余的C代码”
2016年2月17日 Go语言Go 1.6版发布
2016年8月15日 Go语言Go 1.7版发布
2017年2月17日 Go语言Go 1.8版发布
2017年8月24日 Go语言Go 1.9版发布
2018年2月16日 Go语言Go 1.10版发布
2018年8月25日 Go语言Go1.11 版本正式发布

支持平台:

硬件架构,Go语言设计支持主流的32位的X86平台、同时也支持32位的ARM架构。

操作系统,Go语言在Go1版本上支持Windows, 苹果Mac OS X, Linux等操作系统。

开发工具:

个人推荐GoLand开发IDE,Goland是专门针对Go语言的集成开发环境,目前已成为付费软件,最新版支持Go 1.9,支持类型别名。

优秀编号 优秀特征介绍
1 语法高亮显示
2 片段中内嵌的C语法高亮显示
3 与Go标准一致的项目管理方式
4 gofmt、goimports自动格式化支持
5 代码自动完成、重构
6 大纲显示
7 源代码跳转
8 快速API检索
9 代码表达式信息显示
10 断点调试支持
11 使用Delve进行远程调试
12 支持Docker容器的远程调试
13 参数名称显示
14 编辑器样式风格调整
15 键盘快捷键自定义配置
16 Markdown支持(插件)
17 安装插件实现更多功能
众多优秀功能,自行研究发现

简单示例:

功能:实现两个变量的交换

package main

import "fmt"

func main() {

var (

fNum = 12

sNum = 36

)

fNum,sNum=sNum,fNum

fmt.Println(fNum,sNum)

}

总结:

Go语言实际上是一种改良派,汲取以往语言的精华,摒弃以往语言中的繁杂不使用的糟粕新时代编程语言,它更加着重于解决实际中遇到的问题,更加注重于实践性。相信你在看完本篇文章的介绍后,应该对这位编程界的新秀有了一定程度上的了解。因为篇幅有限,感兴趣的同学,可以在网上冲浪一下,根据需要,汲取自己预期的营养。

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

转载请注明:{{title}}-变化吧
  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 赞助本站
  • 支付宝扫一扫
  • weinxin
幸运草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数列表 (不包括参数名) 以及返回值,该类型也可以有其他方法。 接口赋值 对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针。 package main import "fmt" type User struct {     id   int     name string } func main() {     u := User{18, "oldboy"}     var i interface{} = u     u.id = 20     u.name = "Golang"     fmt.Printf("u : %vn", u)     fmt.Printf("i.(User) : %vn", i.(User)) } 运行结果: u : {20 Golang} i.(User) : {18 oldboy} 接口转型返回临时对象,只有使用指针才能修改其状态。 package main import "fmt" type User struct {     id   int     name string } func main() {     u := User{18, "oldboy"}     var vi, pi interface{} = u, &u     // vi.(User).name = "Golang"     pi.(*User).name = "Golang"     fmt.Printf("vi.(User) : %vn", vi.(User))     fmt.Printf("pi.(*User) : %vn", pi.(*User)) } 空接口 只有当接口存储的类型和对象都为nil时,接口才等于nil。 package main import (     "fmt" ) func main() {     var i interface{}     fmt.Printf("i => %vn", i)     fmt.Printf("(i == nil) => %vn", i == nil)     var p *int = nil     // i 指向 p,指向的对象是个nil,但是存在类型不是nil,是个指针     i = p     fmt.Printf("i => %vn", i)     fmt.Printf("(i == nil) => %vn", i == nil) } 运行结果: i => <nil> (i == nil) => true i => <nil> (i == nil) => false 接口实现 接口只有方法声明,没有数据字段,没有实现,也不需要显示的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。 package main import (     "fmt" ) type Info interface {     GetAge() int     GetName() string } type User struct {     name string     age  int } func (u User) GetAge() int {     return u.age } func (u User) GetName() string {     return u.name } func main() {     var user Info = User{"oldboy", 18}     age := user.GetAge()     name := user.GetName()     fmt.Println(age, name) } 如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个接口。 package main import (     "fmt" ) type Age interface {     GetAge() int } type Name interface {     GetName() int } type User struct {     name string...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" ) func main() {   // 设置 路由   http.HandleFunc("/", IndexAction)   // 开启监听   log.Fatal(http.ListenAndServe(":8888", nil)) } func IndexAction(w http.ResponseWriter, r *http.Request) {  w.Write(byte(`<h1 align="center">来自变化吧的问候</h1>`)) } 运行程序,在浏览器上请求: localhost:8888,你会看到我们的结果 Go语言构建HTTP服务器还是很容易的。深入说明。 2 http.Server 类型 HTTP 服务器在 Go 语言中是由 http.Server 结构体对象实现的。参考 http.ListenAndServe() 的实现: // 文件:src/net/http/server.go // ListenAndServe always returns a non-nil error. func ListenAndServe(addr string, handler Handler) error {   server := &Server{Addr: addr, Handler: handler}   return server.ListenAndServe() } 可见过程是先实例化 Server 对象,再完成 ListenAndServe 。其中 Serve 对象就是表示 HTTP 服务器的对象。其结构如下 : // 文件:src/net/http/server.go type Server struct {   Addr    string  // TCP 监听地址, 留空为:":http"   Handler Handler // 调用的 handler(路由处理器), 设为 nil 表示 http.DefaultServeMux   TLSConfig *tls.Config // TLS 配置对象   ReadTimeout time.Duration // 请求超时时长   ReadHeaderTimeout time.Duration // 请求头超时时长   WriteTimeout time.Duration // 响应超时时长   IdleTimeout time.Duration // 请求空闲时长(keep-alive下两个请求间)   MaxHeaderBytes int // 请求头的最大长度   TLSNextProto mapfunc(*Server, *tls.Conn, Handler) // NPN 型协议升级出现时接管TLS连接的处理器函数映射表   ConnState func(net.Conn, ConnState) // 状态转换事件处理器   ErrorLog *log.Logger // 日志记录对象   disableKeepAlives int32     // accessed atomically.   inShutdown        int32     // accessed atomically (non-zero means we're in Shutdown)   nextProtoOnce     sync.Once // guards setupHTTP2_* init   nextProtoErr      error     // result of http2.ConfigureServer if used   mu         sync.Mutex   listeners  mapstruct{}   activeConn mapstruct{}   doneChan   chan struct{}   onShutdown func() } 可见 Server 定义了服务器需要的信息。 实例化了 Server 对象后,调用其 (srv *Server) ListenAndServe() error 方法。该方法会监听 srv.Addr 指定的 TCP 地址,并通过 (srv *Server) Serve(l net.Listener) error 方法接收浏览器端连接请求。Serve 方法会接收监听器 l 收到的每一个连接,并为每一个连接创建一个新的服务进程。 该 go...
go语言动态库的编译和使用 前端框架

go语言动态库的编译和使用

本文主要介绍go语言动态库的编译和使用方法,以linux平台为例,windows平台步骤一样,具体环境如下: $ echo $GOPATH /media/sf_share/git/go_practice $ echo $GOROOT /usr/lib/golang/ $ tree $GOPATH/src /media/sf_share/git/go_practice/src |-- demo |   `-- demo.go `-- main.go 1 directory, 2 files 在$GOPATH/src目录,有demo包和使用demo包的应用程序main.go,main.go代码如下: package main import "demo" func main() {    demo.Demo() } demo包中的demo.go代码如下: package demo import "fmt" func Demo() {    fmt.Println("call demo ...") } 由于demo.go是$GOPATH/src目录下的一个包,main.go在import该包后,可以直接使用,运行main.go: $ go run main.go call demo ... 现在,需要将demo.go编译成动态库libdemo.so,让main.go以动态库方式编译,详细步骤如下: 1 将go语言标准库编译成动态库 $ go install -buildmode=shared -linkshared  std 在命令行运行go install -buildmode=shared -linkshared  std命令,-buildmode指定编译模式为共享模式,-linkshared表示链接动态库,成功编译后会在$GOROOT目录下生标准库的动态库文件libstd.so,一般位于$GOROOT/pkg/linux_amd64_dynlink目录: $ cd $GOROOT/pkg/linux_amd64_dynlink $ ls libstd.so libstd.so 2 将demo.go编译成动态库 $ go install  -buildmode=shared -linkshared demo $ cd $GOPATH/pkg $ ls linux_amd64_dynlink/ demo.a  demo.shlibname  libdemo.so 成功编译后会在$GOPATH/pkg目录生成相应的动态库libdemo.so。 3 以动态库方式编译main.go $ go...
go语言 - Scheduler原理以及查看Goroutine执行 前端框架

go语言 - Scheduler原理以及查看Goroutine执行

最近看了看go scheduler的基本原理,本文介绍go语言scheduler的基本原理以及如何查看go代码中的go routine的执行情况。 0)Scheduler(调度器) 熟悉go语言的小伙伴应该都使用过goroutine。goroutine就是Go语言提供的一种用户态线程。Scheduler是调度goroutine的调度器。 Go的调度器内部有三个重要概念:M,P,G。 M (machine): 代表真正的内核操作系统里面的线程,和POSIX里的thread差不多,也是真正执行goroutine逻辑的部分。 G (Goroutine): 代表一个goroutine。 P (Processor): 代表调度的上下文,可以理解成一个局部调度器。 Go语言实现了多个Goroutine到多个Processor的映射(调度)。注意的是,针对X个Processor,Scheduler可能创建多于X个M(有些M可能会暂时被block)。还需要理解额外两个概念:GRQ(Global Running Queue)以及 LRQ(Local Running Queue)。未指定Processor的Goroutine会存放在GRQ上,在调度到合适的Processor后,会将一个Goroutine从GRQ移动到LRQ。 Go程序中发生了四类事件,允许调程序做出调度决策。 a. 使用关键字go b. 垃圾收集 c. 系统调用 d. 同步 1)Processor的个数 Processor的个数可以通过GOMAXPROCS环境变量设置。GOMAXPROCS默认值是CPU的核数。Processor的个数可以通过如下的go代码进行查询: package main import ( "fmt" "runtime" ) func main() { // NumCPU returns the number of logical // CPUs usable by the current process. fmt.Println(runtime.NumCPU()) } 也就是通过runtime.NumCPU函数可以获得Processor的个数。查看go语言的源代码(runtime/os_linux.c),NumCPU函数的实现函数如下:  func getproccount() int32 { const maxCPUs = 64 * 1024 var buf byte r := sched_getaffinity(0, unsafe.Sizeof(buf), &buf) if r < 0 { return 1 } n := int32(0) for _, v := range buf { for v != 0 { n += int32(v...