为什么用golang作为游戏服务端的大型游戏开发语言言,它的并发性如何

走进 Google 的 Go 语言【编程吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:194,023贴子:
走进 Google 的 Go 语言收藏
本文整理自Google首席工程师Rob Pike的演讲Slide,主要讲述的了Go的部分设计原理和初衷,也有提到Go语言在Google内外的应用现状。但本文的目的更多的是关于软件工程而不是编程语言的设计,更准确地说是如何设计编程语言来帮助软件工程。
序言:关于Go Go语言是一个开源、并发、高效、简单、有趣(但对某些人来说可能很无聊)的编程语言,支 持垃圾回收(GC),具有很好的可伸缩性。Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go最初是为了解决Google的问题而开发的,要知道Google面临着很多大问题。Google的中服务器最主要是C++编写的,除此之外还有 很多Java、Python代码。另外,Google还有数千名工程师、无数行代码、庞大的分布式构建系统以及数不清的机器(我们认为相对于一个中等规模 的集群)。Google的开发可能很慢,甚至笨拙,但它总是很有效。所以毫无疑问Go对“大硬件”的支持非常好,也适合“大软件”的开发。CSDN之前也编译了一批Rob Pike的文章——Go语言之父谈Go:大道至简,在这里Rob描述了Go的创作起源和初衷。
为什么应该用Go? Go是为了帮助人们阅读、调试和维护大型软件系统而生的,所以目标是 不再缓慢 不再笨拙 提高效率 保持(甚至提升)扩展性 但是在使用C++或者Java开发中却常常遇到各种问题: 构建缓慢 依赖性难以控制 每个编程语言都使用不同的语言子集 程序难以理解(文档等原因) 重复工作 更新成本高 版本交叉 自动化不方便(工具问题) 跨语言构建 而Go语言则是为了解决这些问题而设计的。另外,C语言的依赖一直是个大问题,包括依赖叠加、编译时引入依赖的情况都很难处理,同时你也没办法查清哪些依赖是可以删除的,那些不可以。在C++中,这一点变得更加明显: 每个类里都有#include文件 #include文件中有代码(而不仅仅是声明) #ifndef的残留 所以一直无法在一台机器上构建大型Google二进制。(To build a large Google binary on a single computer is impractical.)当然,工具确实很有帮助,于是做了如下改进: 新的分布式构建系统 不再需要Makefile(但仍然使用BUILD文件) 多缓存 多复杂度(大程序本身所具有的) 即使在Google的分布式构建系统的的帮助下,大型构建工程依然会花费不少时间(以其中一个二进制文件为例,在2007年花了45分钟,现在是27分钟)。生活质量还是太低。走进Go语言 我们都希望拥有更高质量的生活,所以必须解决这些问题,所以就有了最初的想法: 必须是可扩展的 适合大型程序、大型团队以及拥有大量依赖的应用 必须易于接近,例如接近C语言那样。 现代化 适合多核机器 适合网络机器 适合Web开发 Go语言的设计是以软件工程为目标,所以它有这些优点: 清晰的依赖 清晰的语法 清晰的语义学 简单的模型(垃圾回收和并发性) 便捷的工具(go tool、gofmt、godoc、gofix等) 还有那些问题? Go语言目前所面临的最大问题在于,还没有足够的经验来证明Go是否真的是一个成功的产 品,缺少大型应用实践。但是在Google内部,如golang.org、、都已经开始使用Go语言开 发,除此之外还有一些其它小应用(有的是在GAE上)也选择使用Go;而在Google之外,BBC Worldwide、Canonical、Heroku、Nokia、SoundCloud也都在尝试Go。 总而言之,Go是由软件工程驱动的编程语言,但富有成效并且有趣,这样的设计非常高产。 Rob Pike演讲的Slide可以在这里看到。 本文转载自:
登录百度帐号推荐应用为什么 PHPer 应当学习 Golang
来源:本站原创&
熟悉我的朋友应当知道,近些年的大部分时间我的工作都会多少和 PHP 相关。随着 PHP 有着越来越深入的了解,以及遇到越来越多的不同业务时,使用 PHP 总会让我有一种莫名的无力感。当然,并不是我一个人在使用 PHP 的时候遇到了问题。事实上,每个略微有一些经验,接触过一些需求的人都会有同样的困惑。各种配合 LAMP(或者LNMP?)架构的后端技术也因此被发明或被发现,进而整合到 PHP 的开发的技术体系中。从简单的作为数据中转,cron 后端定时处理;到 、 这些队列神器;最近 @Laruence 甚至封装了利用 libcurl 的异步特性实现并发 RPC 调用的
扩展。几乎整个社区都在寻找 PHP 的摩西之路。
好吧,说了一大堆,回归主题。之前我写了一篇英文练笔《》,获得不少国际友人的关注。排除拼写和语法被他们诟病外,主要是有许多朋友觉得我没把事情说清楚。所以这里我用母语重新聊聊这个事情,只是这些国际友人什么时候能学会阅读中文呢?;)
,是由 Google 支持的快速、一致、稳定的,有活跃的社区支持的开源编程语言。越来越多的应用选择使用 Golang 进行构建。虽然 Rob Pike 说,不过我真得认为:PHPer 应当学习 Golang! 接下来我们就来谈谈原因。
PHP 相当容易学习。Golang 也是!
在这点上,一群大老外对我的观点进行了猛烈的抨击。他们认为我羞辱了 PHPer,说得好像只有简单的东西 PHPer 才能学会一样。但是,这难道不是事实吗?或者换个说法:像我一样的喜欢 PHP 的人,或多或少都会更喜欢简单的东西。
PHP 的语法接近 C 族编程语言(C/C++/Java等等)。如果有这些语言的经验,在第一次遇到 PHP 的时候立刻就能开始上手编写代码。在我看来,编写 PHP 代码或许更加考验程序员的记忆力,而不是智力(当你面对各种不同风格的函数定义、各种扩展的特殊约定时,你一定会相当认同我的观点)。
Golang 同样是一个 C 族编程语言。呃,或者有一些不同吧。例如关键字 ,功能上和 PHP 的接近,但是没有括号。条件语句
同样无需括号。可以阅读
了解更多内容。
Golang 只有 3025 个关键字和 47 个操作符号、分隔符号或其他特殊标记。记住这些标记确实不需要什么特别的努力。精巧的类型系统相当容易使用。实用的,具有方法的结构体类型代替了笨重的对象系统。接口的设计是 Golang 中我最喜欢的部分。当完成了《》的学习之后,利用 PHP 积累的经验,立刻就可以开始使用 Golang 处理一些简单的任务。
PHP 脚本是由 SAPI 组件进行解析执行的,如 Web 服务器模块、PHP-FPM 或者 CLI。部署 PHP 所需要的全部东西就是一个 SAPI 环境。配置这个环境对于新手来说可能是学习 PHP 过程中最为困难的部分。
所有的 Golang 代码会编译和链接为本地码。所以除了编译环境,执行时无需再为其进行任何特别的部署。对比 PHP 环境的配置,这要简单很多。你真得认为配置 PHP 环境很复杂吗?我不觉得,真的!而配置 Golang 编译环境比那还要简单点。
我确信已经有大量的 Golang 相关的书籍、文章介绍过如何进行编译环境的配置了。为了更加清晰,我这里梳理一下思路。
有三个步骤需要处理:
下载 Golang 的源代码;
根据的提示设置环境变量;
运行源代码 src 目录中的 all.bash。
或者一步到位:使用进行安装。
然后就会得到一个叫做“go”的工具集合。使用“go”工具和使用 PHP 的 CLI 工具一样简单。对此进行了详细的解释。
PHP 的迷思
如果一个编程语言容易学习和使用,我们是不是就应当学习它呢?有许多容易学习和使用的编程语言。难道要把它们都学一遍?答案是显然的:NO!
但是为什么 PHPer 应当学习 Golang 呢?只是因为它很酷!是的,我在开玩笑,但是这是真的。无论如何先从 PHP 自身谈起吧。
PHP “原本是为了开发动态的 Web 页面而设计的服务器端通用语言()”。PHP 一个重要的特性就是可以嵌入到 HMTL 中。代码编写在“&?php … ?&”标签内;HTML 写在标签外。它有一个强大的扩展系统。扩展使用 C 调用 Zend API 编写。数据的处理实际上要利用这些扩展完成。在我看来,PHP 是世界上最好的模板语言。
但是当积累了一些 PHP 的经验,并且开始面对一些更加复杂的 Web 应用时,你一定会对 PHP 产生一种无力的感觉。它没有内建的并行机制,没有线程、进程(你真得认为那个简陋的进程控制可以不加改造的用在高并发的生产环境?),或者其他某“程”。一个慢数据源可以阻塞整个页面的处理。消息队列、缓存、代理……系统开始不仅仅是 PHP 这么单纯,还包括了许多服务和系统组件。这时,PHP 只处理很少的业务逻辑,成为真正的模板语言了。
PHPer 们总是在寻找解决这一问题的办法,如“”或者。我很难说哪种会更好一些。不过我肯定你会需要选择一些编程语言用于后端工作的开发。就我自己的经验,我尝试过 C(一直在和 malloc/free 进行搏斗)/Java(陷入到了 jar 地狱中)/Python(从来没能做到 Pythonic 不说,还总是在错误的类型中打转)……如果想要获得性能,就得同内存管理进行搏斗;如果用 GC,就得部署和调优 VM;当获得便利性的时候,同时也是走在刀尖上,一个小错误就引起巨大的灾难……每个都有优势,同样每个都有问题。
好吧!现在回到 Golang!
Golang 有 GC,无需关心内存管理(或者可以用较少的精力去关注它)。代码被编译为本地码,因此“cp”和“mv”就是部署 Golang 编写的应用所需要的全部工具。噢,我刚才已经说过了,Golang 是一个具有静态类型系统的编译语言。所以你没有机会弄乱变量的类型。当然,PHPer 应该学习 Golang 的一个重要原因是“”。《》对此进行了深入的分析。
我可以分享一些我的经验:有一个
的 worker 用于处理后端数据。PHP 通过其
连接到 Gearman 的 Job Server 向 worker 发起请求。最初 worker 是使用 编写的(还有更加原始的版本,PHP 的,但是你能想像它工作起来……唉,不说了……)。这个版本有许多的问题(是我们自己的问题,不关 Python 的事),但是至少它能工作。后来用 Golang 重写了这个 worker。为此我开发了 ,并使用 Zend API 编写了。然后将它们放在一起:一个可以执行 PHP 的 Gearman worker。它已经工作了一段时间了,看起来还不错!哦,受到 Yar 的启发,这里还有一个 Golang 编写的 ,用来合并 PHP 脚本中的 RPC 调用。现在还是个玩具,不过或许日后能用得着。这其实是将 Golang 的 channel 当作消息队列来用。我在《》中对此有一些说明。
世界真美好啊。谢谢 Golang!
无论如何,大多数 PHPer 在进行后端开发的时候都会需要学习一些其他语言。如果你正在寻找,或者已经尝试了一些其他语言。为什么不来试试 Golang?它真得可以让你的生活更加轻松和快乐。让你可以有更多的时间陪伴你的家人和朋友,吃你爱吃的东西,去你想去的地方。
貌似我还是没说清楚啊?好吧,没关系,在下个月的上再跟大家就这个话题做一个探讨吧。
熟悉我的朋友应当知道,近些年的大部分时间我的工作都会多少和 PHP 相关.随着 PHP 有着越来越深入的了解,以及遇到越来越多的不同业务时,使用 PHP 总会让我有一种莫名的无力感.当然,并不是我一个人在使用 PHP 的时候遇到了问题.事实上,每个略微有一些经验,接触过一些需求的人都会有同样的困惑.各种配合 LAMP(或者LNMP?)架构的后端技术也因此被发明或被发现,进而整合到 PHP 的开发的技术体系中.从简单的Memcached作为数据中转,cron 后端定时处理:到 Gearman.Ra
用python开发也有几年了,很喜欢它的简洁.最近在看golang,感觉和python很像,语法简洁,标准类型相识,标准库也是一样的丰富.引用一段文字(http://blog.csdn.net/myan/article/details/2028545): 所谓&魔幻语言&,主要代表作品有C++.Perl.Javascript和Ruby.这些语言拥有丰富的特性,聪明的技 巧和意想不到的奇效,永远有发掘不完的奇技淫巧,总能找到让人匪夷所思的&yet another way&quo
假如你对golang感兴趣, 却尚未开始入门, 这篇文章就是为你准备的. 为什么要学习golang? 游说开发者尝试golang的文章很多. 比如golang主要设计者的演讲, 某个德国人的吐槽, 国内golang布道者所著书籍的前言. 我不想重复一遍大牛们的观点, 只想说一说自己朴素的感受. 在学习golang之前, 我是java的爱好者, 犹如iteye的大多数用户一样. 是的, 我喜欢java, 开源, 跨平台, 强大的IDE支持, 最重要的是--工作机会很多. 但是同时我也讨厌java.
今天开始打算学习golang, 说 并发性很好,非常适合做服务器开发的.初步打算用golang写服务器网关,用python写业务服务器,这样可以减少服务的重启率,提高服务稳定性和效率. IDE使用LiteIDE 配置文件如下: 查看 -- 编辑环境变量 # native compiler windows 386 GOROOT=D:\Software\golang GOBIN=D:\Software\golang\bin GOPATH=C:\golang GOARCH=386 GOOS=windo
我是搞php出身,自然安装lnmp是常规技能.以前的手段还是lnmp安装包,比如军哥的lnmp1.0.随着php和mysql的更新,大多数一键安装都开始版本老化,更新困难的问题.因此,重新研究了一下Ubuntu下lnmp的安装,发现现在简单的多,记录一下. 另外最近在学习golang,Ubuntu下安装自然也是必须的过程.不过golang的安装也有一些奥妙.当然,不是源码安装的啦. Nginx Stable/Development Ubuntu下的包管理器是apt-get或者说dpkg.常规的安
这篇文章主要介绍了Go语言实现简单的一个静态WEB服务器,本文给出了实现代码和运行效果,学习Golang的练手作品,需要的朋友可以参考下 学习Go语言的一些感受,不一定准确. 假如发生战争,JAVA一般都是充当航母战斗群的角色. 一旦出动,就是护卫舰.巡洋舰.航母舰载机.预警机.电子战飞机.潜艇等等 浩浩荡荡,杀将过去. (JVM,数十个JAR包,Tomcat中间件,SSH框架,各种配置文件...天生就是重量级的,专为大规模作战) 而GO语言更像F35战斗轰炸机 单枪匹马,悄无声息,投下炸弹然后
PHPlet是什么? 很简单,它是一个使用PHP编写的Web服务器,可以替代我们常用的Apache或IIS. 为什么要介绍PHPlet? 因为它是PHPer们学习Web服务器原理的捷径. 因为它的程序结构很好,类似Java的面向对象编程,有很好的参考价值. 因为我认为PHP5和PHPlet相继发布稳定版本后,PHP5+PHPlet+SQLite(PPS)将是小型应用.程序演示的另外一种选择. 现在大部分的小型应用或者程序演示都是把Apache+PHP+MySQL(APM结构)做成exe或rpm安
python编程 python学习 - 一簇簇的部落格 小项(肥象) - Powered by BuySz Python PycURL 网络编程 - 真功夫 - 博客园 pycurl模块(第三方)(例子)_python_百度空间 Python3.0 如何抓取网页 - GAE学苑 python 书籍推荐_python 入门书籍-老王python python自由人 最好的python交流学习平台 - Powered by Discuz! Old Nabble - python-chinese @
自己动手写PHP MVC框架 来自: /
代码下载: /yuansir/tiny-php-framework PHP的框架众多,对于哪个框架最好,哪个框架最烂,是否应该用框架,对于这些争论在论坛里面都有人争论,这里不做评价, 个人觉得根据自己需求,选中最佳最适合自己MVC框架,并在开发中能够体现出敏捷开发的效果就OK了,作为一个PHPer要提高自己的对PHP和MVC的框架的认识,所以自己写一个MVC
最近学习golang也有一段时间了,基础差不多学了个大概,因为本人是java程序员,所以对web更感兴趣.根据&go web编程&中的例子改编一个更简单的例子,供新手参考,废话不多说,上菜: 这个例子使用到了beego框架和beedb框架,如果是go新手beego和beedb得自己去google下载安装. 目录结构: index.go package controllers import ( &fmt& &/astaxie/beego&quot
学习golang 记录下 //解析(map[string]interface{})数据格式并打印出数据 func print_json(m map[string]interface{}) { for k, v := range m { switch vv := v.(type) { case string: fmt.Println(k, &is string&, vv) case float64: fmt.Println(k, &is float&, int64(v
本系列&设计模式&博客使用Golang语言实现算法.所谓算法是指解决一个问题的步骤,个人觉得不在于语言.小弟只是最近学习Golang,所以顺带熟练一下语法知识,别无它意. 本系列博客主要介绍常见的23种设计模式,其内容顺序如下: 一.设计模式分类及设计原则 二.工厂方法模式(Factory Method) 三.抽象工厂模式(Abstract Factory) 四.单例模式(Singleton) 五.建造者模式(Builder) 六.原型模式(Prototype) 七.适配器模式(Ada
学习Go语言的过程中,会发现它的指针,地址,还有函数参数跟平常我们理解的不太一样. 上代码: package main //学习指针用法 import ( &fmt& ) func main() { // i 的类型是int型 var p * // p 的类型是[int型的指针] i = 1; // i 的值为 1; p = &i; // p 的值为 [i的地址] fmt.Printf(&i=%d;p=%d;*p=%d\n&,i
网站教程 GO语言编程 and GO语言开发2048 from 实验楼 Go语言后台应用开发 form 优才网 Go语言第一课 form 慕课网 入门书籍 &Go 入门指南&(&The Way to Go&中文版) &Go 编程基础& &学习 Go 语言& &GO 标准库&: Polaris出品,一本有价值的入门书籍. &Go Web 编程& &Go并发编程实战& and &Go命令教程&由@特价萝卜 出品.
1. GOROOT GOPATH 及 PATH 设置 a.添加系统变量GOROOT:安装完Go第一件事就是设置GOROOT.例如我的Go安装在C:\Go目录,则要设置 GOROOT = C:\Go b.修改环境变量PATH:将%GOROOT%\bin加到环境变量PATH里面,这样就可以直接在dos命令模式下任意目录运行%GOROOT%\bin目录下的程序 如:go.exe godoc.exe c.添加系统变量GOPATH:GOPATH是用来设置包加载路径的重要变量.可以设置多个路径,用分号(;)
GO语言吉祥物,很可爱吧. Go语言的hello world!代码: package main import &fmt& func main() { fmt.Println(&Hello, 世界&) } 上一节安装好Go以后,我们就可以搭建开发环境了,这里我用的是 Sublime Text 2 + GoSublime + gocode.对于不了解Sublime Text 2的朋友,可以看看官网:/(总的来说是一个轻
1.设置 Go 环境变量 我们在 Linux 系统下一般通过文件$HOME/.bashrc配置自定义环境变量,根据不同的发行版也可能是文件$HOME/.profile,然后使用 gedit 或 vi 来编辑文件内容.我是安装包安装的,安装在了/usr/local/go export GOROOT=/usr/local/go export GOBIN=$GOROOT/bin export GOARCH=386 export GOOS=linux ( 译者注:目前的 Go 版本一般情况下已不需要设置
如何获得goconfig第三方包 在git shell中使用go /Unknwon/goconfig安装goconfig包 如何使用goconfig package main import ( &fmt& &/Unknwon/goconfig& &log& ) func main() { cfg, err := goconfig.LoadConfigFile(&config.ini&quo
定义一个struct,定义的时候是字段名与其类型一一对应,实际上Go语言支持只提供类型,而不写字段名的方式,也就是匿名字段,或称为嵌入字段. 当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct. 让我们来看一个例子,让上面说的这些更具体化. package main import &fmt& type Human struct { name string age int weight int } type Student
golang并没有在语言层次上提供超时操作,但可以通过一些小技巧实现超时. 原理: 并发一个函数,等待1s后向timeout写入数据,在select中如果1s之内有数据向其他channel写入则会顺利执行,如果没有,这是timeout写入了数据,则我们知道超时了. package main import &fmt& import &time& func main() { ch := make(chan int, 1) timeout := make(chan boo在使用了Rust和Golang以后,我的个人感觉是这两种语言虽然都号称“系统编程语言”,可是他们的目标程序员完全不一样。&br&&ul&&li&Golang的未来应该是慢慢取代Java和Python在&b&分布式&/b&后端的地位的。很多基于Java的通讯密集型分布式框架,现在都在开始用Golang来重写。再加上Golang有个好爹,这个趋势恐怕会越来越明显。对于一个分布式系统而言,通讯的延迟开销往往是性能的瓶颈,所以架构的优势和便捷所带来的性能优势远远大于单机的优化。所以在分布式的环境下,我目前觉得Golang是一个非常好的选择。&/li&&li&Rust的目标用户应该是C/C++用户,未来的&b&单机系统&/b&对于并行,安全和稳定性有着更高的需求,这是Rust应运而生的背景。对于Rust感兴趣的人,应该也会对Pony感兴趣。这是一门新的基于C拓展而来的语言。Pony已经开始在伦敦的金融城有不错的应用和社区了。&a href=&///?target=http%3A//www.ponylang.org& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Pony - High Performance Actor Programming&i class=&icon-external&&&/i&&/a&&/li&&li&Dlang在系统编程领域好像最近已经没有怎么听到了。&/li&&/ul&&br&&br&---- 2016 更新 ----&br&&br&最近一直对Rust和Go很感兴趣,在知乎上浏览大部分关于Rust的讨论,找到这个问题。&br&&br&个人感觉目前的答案缺乏一个完整的分析,大部分都是个人的经验,以及基于很少使用经验得出的总结。然后,我搜了下英文方面的讨论和资料,发现目前美国几个大学已经将操作系统的教学语言换成Rust了。以下是一个教授关于选择Rust作为教学语言,而不使用Java, C++, D, Go以及Python的原因。这个教授具有操作系统,计算机体系,编程语言设计的资深经验和博士学位。这些条应该可以帮助其做出一个最客观的评判。另外,这篇分析的目标读者是系统编程较少的本科生。所以该文中用到的技术词汇极少,很好理解,讨论大多围绕语言的设计目标,适用环境,特性比较,语言潜力等展开。&br&&br&在我看来:操作系统的教学语言,是系统界编程市场趋势的风向标,如果一门语言可以利用最小的成本,并且最大程度地向本科学生传授系统编程的特点,那么这门语言的易学程度是相对较低的,被市场接受的可能性就比较大。&br&&br&&a href=&///?target=http%3A//rust-class.org/0/pages/using-rust-for-an-undergraduate-os-course.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Using Rust for an Undergraduate OS Course&i class=&icon-external&&&/i&&/a&&br&&br&&blockquote&&p&Having eliminated C as an irresponsible choice for teaching an OS course, I had to select another language. (I briefly considered not using a particular language, but since it seemed important to provide starting code to have interesting assignments and to cover some things in class using a particular language, this didn't seem like a viable option to me.)&/p&&p&I considered five possibilities: Java, Python, D, Go, and Rust.&/p&&p&&strong&D.&/strong& D is a programming language designed as a successor to C++ that has been around since 2001. D has some very nice features: it provides reasonable support for functional programming, static types with type inference, and some concurrency constructs. The biggest disadvantage of D compared to Rust is that it does not have the kind of safety perspective that Rust does, and in particular does not provide safe constructs for concurrency. I prefer Rust's memory management options, although D provides a fairly similar combination of garbage collected objects and objects with explicit memory management, it does not provide any of the safey guarantees or lifetime model that Rust does. The other argument against using D is that it has been around more than 10 years now, without much adoption and appears to be more likely &a href=&///?target=http%3A///questions/743319/why-isnt-the-d-language-picking-up& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&on its way out&i class=&icon-external&&&/i&&/a& rather than increasing popularity. This shouldn't be a major factor for an academic course, but I'd much rather be teaching something that is in an early phase of exponential popularity growth rather than something that appears to be declining.&/p&&p&&strong&Go.&/strong& Go is a systems programming language first released in 2007 that was initially designed by a team including Ken Thompson (C co-designer) and Rob Pike at Google. Unlike D, it seems to have a lot of momentum behind it, no doubt partly due to Google's support. There are &a href=&///?target=http%3A//gofy.cat-v.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&some preliminary, although tastelessly named, attempts&i class=&icon-external&&&/i&&/a& to write operating systems in Go, but the intertwining of the runtime with the compiler makes this quite difficult in Go (in comparison to Rust where the runtime can be easily separated). I'm not aware of any undergraduate operating systems courses that have used Go, but MIT's graduate &a href=&///?target=http%3A//pdos.csail.mit.edu/6.824/labs/lab-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&6.824: Distributed Systems&i class=&icon-external&&&/i&&/a&course and CMU's &a href=&///?target=http%3A//www.cs.cmu.edu/%7Edga/15-440/F12/assignments.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&15-440: Distributed Systems&i class=&icon-external&&&/i&&/a& course used Go. Go is a fairly new language, but mature enough to have a stable, industrial-strength compiler with great performance, and good documentation (and mature enough to have an &a href=&///?target=http%3A//golang.org/doc/effective_go.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&idiom guide&i class=&icon-external&&&/i&&/a&). Go is also similar enough to C to be easy for C programmers to learn and has no major learning curve hurdles. &/p&&p&So, Go definitely has a lot of things going for it, and initially I planned to use Go for cs4414 until learning about &a href=&///?target=http%3A///zero-rs-write-rust-without-a-runtime/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&zero.rs&i class=&icon-external&&&/i&&/a&. After looking into Rust more, it seemed like Rust had several key advantages both as a systems programming language in general, and as a primary language for teaching an operating systems course.&/p&&br&&p&&strong&Note Added 4 Jan:&/strong& Some commenters are taking this as being negative on D and Go. That's not my intent at all - its great that people are working on developing these languages. In the larger picture, any progress for any of these languages is a great thing, and I would be very happy to see others developing courses using Go and D. The first step is to realize we don't need to keep using C just because everyone is, but should consider the possible advantages and disadvantages of other languages that solve problems inherent in C's design. I found Rust to be the most exciting and promising option, as discussed below, but that doesn't mean we shouldn't be exploring possibilities with other languages also.&/p&&/blockquote&&br&以下是为什么要选用Rust:&br&&br&&blockquote&Reasons to Use Rust&p&Rust is a new systems programming language being developed at Mozilla. It is primarily driven by the needs of the Mozilla's &a href=&///?target=https%3A///mozilla/servo/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Servo&i class=&icon-external&&&/i&&/a&project to build an experimental multi-core browser engine. Rust adopts a C-like syntax, but is much less tied to C's semantics or being easy for C programmers to learn than Go or D, and its overriding design goal is to support safe concurrency in a practical way. The first public release was in January 2012, so Rust is a very new and immature language, but it has some innovative and very appealing features for use in systems programming and teaching an operating systems course.&/p&&ol&&li&&p&Rust &strong&changes the way you think.&/strong&&/p&&p&At least for &ivory-tower& types, the only reason to learn new languages is for their power to change the way you think.&a class=& wrap external& href=&///?target=http%3A//rust-class.org/0/pages/using-rust-for-an-undergraduate-os-course.html%23fn%3A2& target=&_blank& rel=&nofollow noreferrer&&2&i class=&icon-external&&&/i&&/a& Neither Go nor D really do this (at least for anyone who has previously programmed in C, Java, and Python), but Rust does a great deal. Rust requires programmers to think carefully about how objects are shared and used, and this changes the way you think about programs and algorithms. &/p&&/li&&li&&p&Rust provides &strong&simple and safe concurrency&/strong& mechanisms, and a useful and intellectually interesting &strong&task abstraction&/strong&. &/p&&p&I'm not aware of any other language that has concurrency constructs as elegant and easy to use as Rust's spawn, and I don't know of any language that comes close to the race-free safety guarantees provided by Rust. The alternative with language like C and Go, is to have students get in the habit of writing programs riddled with data race bugs. Such programs tend to work well enough to be satisfactory for course projects (where the occasional crash or corrupted data is acceptable), but are increasingly unacceptable in the real world. The next step is to use available tools to detect races (e.g., &a href=&///?target=http%3A//blog.golang.org/race-detector& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Go's race detector&i class=&icon-external&&&/i&&/a&), but these present another tool to use and learn about, are incomplete (only detect races that occur on executions), and much less satisfying than the static, language-based mechanisms provided by Rust.&/p&&p&Rust's task abstraction is somewhere between a thread and process: it provides the memory isolation safety of a process while allowing safe memory sharing, but with the lightweight costs of a thread requiring no context switching. This is a useful thing for programmers, but also a great thing for students to learn about and understand in an operating systems course. Along with the task abstraction, Rust provides good abstractions for communication between tasks including a simple channel abstraction and &a href=&///?target=http%3A//static.rust-lang.org/doc/0.8/extra/arc/struct.RWArc.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&abstractions for shared mutable state&i class=&icon-external&&&/i&&/a&.&/p&&/li&&li&&p&Rust provides &strong&strong memory safety guarantees&/strong&, but still allows programmers &strong&explicit control over memory management&/strong&.&/p&&p&The main alternatives provide two extremes: C provides no memory safety but fully explicit control ov Go and D provide memory safety but with all objects being automatically managed with a garbage collector (over which languages users have little control). Rust provides a way for programmers to declare objects that are automatically managed or explicitly managed, and statically checks that explicitly managed objects are used safely. This is done using a notion of ownership, and type rules for controlling how ownership is transferred between references (e.g., you can pass an owned object temporarily to a function as a borrowed reference, and can have more complex ownership types to enable controlled sharing). These rules guarantee all memory is safely deallocated, and the sharing restrictions are essential for providing safe concurrency.&/p&&/li&&li&&p&Rust provides good mechanisms for &strong&higher-order procedures&/strong&, and many library types are designed in ways that encourage students to use them.&/p&&p&One of the biggest embarrassments about our department's standard curriculum is that students can reach a 4000-level class without ever encountering a higher-order procedure (as opposed to the sadly rarely-offered &a href=&///?target=http%3A//www.cs.virginia.edu/evans/cs1120-f11/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&alternative intro course&i class=&icon-external&&&/i&&/a& which introduces higher-order procedures in the first assignment), so I thought it was essential to use a language that supports higher-order procedures and provides good opportunities to use them effectively. Rust provides a simple syntax for lambda expressions, and lots of good ways of using them including in the &a href=&///?target=https%3A///cs4414/ps3/blob/master/zhtta.rs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&RWArc abstractions we used in the starting code for PS3&i class=&icon-external&&&/i&&/a&.&/p&&/li&&li&&p&With it strong emphaisis on safety, Rust still provides an &strong&escape hatch&/strong& to allow students to experiment with unsafe code.&/p&&p&The Rust compiler normally disallows any code with implicit data races or unsafe memory use, but the language provides the unsafe construct for surrounding code that may be unsafe. This can certainly be abused (and I regret not providing some guidelines or rules to prevent students from overusing it, which some students did on some assignments), but is also very useful for being able to show simple but unsafe code and for understanding what is necessary to make code safe. For example, we used this in &a href=&///?target=http%3A//rust-class.org/0/pages/ps1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PS1&i class=&icon-external&&&/i&&/a& where students added an unsafe counter to a simple web server, and then in &a href=&///?target=http%3A//rust-class.org/0/pages/ps3.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PS3&i class=&icon-external&&&/i&&/a& there was a problem where students had to implement it in a safe (race-free) way. The unsafe escape hatch also makes it possible to include assembly code in Rust programs, and to easily use libc.&/p&&/li&&li&&p&Rust is &strong&open source&/strong& and has an &strong&open development&/strong& process.&/p&&p&The Rust source code is &a href=&///?target=https%3A///mozilla/rust& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&available&i class=&icon-external&&&/i&&/a& for everyone to read, and the Rust language designers discussions are on an &a href=&///?target=https%3A//mail.mozilla.org/pipermail/rust-dev/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&open mailing list&i class=&icon-external&&&/i&&/a&. (Go is also &a href=&///?target=https%3A///p/go/source/checkout& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&open source&i class=&icon-external&&&/i&&/a& and has an &a href=&///?target=https%3A///forum/%23%21forum/golang-dev& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&open developer discussion&i class=&icon-external&&&/i&&/a&, so this is not a particular advantage of Rust over Go.)&/p&&/li&&li&&p&Rust has a vibrant, helpful, and &strong&friendly community&/strong&. &/p&&p&This is obviously subjective, but the novelty and philosophy of Rust are well-suited to a devoted development team and user base, and I got a good sense that the community would be very helpful in my early interactions on the Rust IRC. For an immature language, having a supportive community is really important, and our class benefitted greatly from help from the Rust community throughout the course.&/p&&/li&&li&&p&The immaturity of Rust means there are &strong&lots of opportunities to make contributions&/strong&.&/p&&p&Rust's immaturity is its biggest drawback (more in the next section), but it also has a good side. Using an immature language means there are lots of opportunities to make substantial contributions, and I tried to encourage students to view anything essential lacking from the Rust ecosystem as an &a href=&///?target=http%3A//www.dorina.org/pubs/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&opportunity for them to create it&i class=&icon-external&&&/i&&/a&. By the end of the course, one of the students had &a href=&///?target=https%3A///mozilla/rust/pull/10477& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&made changes that were accepted into the main Rust compiler&i class=&icon-external&&&/i&&/a&, other group had built a &a href=&///?target=https%3A///ferristseng/regex-rust/tree/master& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&regular expression library&i class=&icon-external&&&/i&&/a&, &a href=&///?target=https%3A///wbkostan/cs4414-ps4& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&true random number generator&i class=&icon-external&&&/i&&/a&, and &a href=&///?target=https%3A///victor-shepardson/rust-audio-experiments& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&real-time audio&i class=&icon-external&&&/i&&/a&, among &a href=&///?target=http%3A//rust-class.org/0/pages/final-projects.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&other projects&i class=&icon-external&&&/i&&/a&; and several students are now working on writing &a href=&///?target=https%3A///rtm9zc/rust-tutorial/wiki& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&tutorials&i class=&icon-external&&&/i&&/a& and documentation that will be useful for students in next semester's class and anyone else who wants to learn Rust. It is hard for me to imagine similar contributions being possible to the extremely mature C ecosystem.&/p&&/li&&/ol&&/blockquote&&br&和为什么不&br&&br&&blockquote&&p&There are lots of great reasons to use Rust in an OS course, but two major (and one minor) ones not to:&/p&&ol&&li&&p&Rust is a &strong&very immature&/strong& language (at version 0.7 at the time we started the class). &/p&&p&The immaturity means there is little documentation, and much of what existed was not consistent with the latest version. It also means the language continues to change in subtantial and non-backwards-compatible ways which mean code we wrote for the class broke when we moved to version 0.8 mid-semester, and many of the libraries available no longer worked. The lack of documentation is a serious problem, and was the main cause of frustration for students in the class. There is a lot of ongoing effort now (including some from students in the class) to improve the available documentation for Rust, so this problem should diminish rapidly. &/p&&p&The more fundamental problem with an immature language is that we lack the experience to have developed idioms and conventions for using the language effectively. Forty years of experience with C has led to the development of lots of idiomatic ways of doing things, and in most cases, evolutionary pressures should lead to good solutions, and these solutions are documented in lots of places that are fairly easy to search (e.g., &a href=&///?target=http%3A///search%3Fq%3D%255Bc%255D%2Bmemory%2Bleaks& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&stackoverflow&i class=&icon-external&&&/i&&/a&). &/p&&/li&&li&&p&Rust has a very &strong&steep learning curve&/strong& and requires programmers to &strong&think differently&/strong&.&/p&&p&As mentioned before, for ivory-tower folks the fact that a language makes you think differently is a great property, but this also makes it a lot harder to learn and is often very frustrating for people used to thinking certain ways and unable to do the things they think should be easy. Good tutorials (which hopefully we'll have ready for next semester) and exercises can help, but the way Rust pointers work is different enough from what people with experience using C and Java expect that it seems necessary to get over some pretty big hurdles before writing any non-trivial programs in Rust.&/p&&/li&&li&&p&Rust is &strong&not widely used&/strong& in industry (yet), so it is disadvantageous to students compared to gaining experience using a commonly used language like C.&/p&&p&I view this as a minor reason, since I don't think its really the mission of a university CS curriculum to prepare students with particular job skills&a class=& wrap external& href=&///?target=http%3A//rust-class.org/0/pages/using-rust-for-an-undergraduate-os-course.html%23fn%3A3& target=&_blank& rel=&nofollow noreferrer&&3&i class=&icon-external&&&/i&&/a&, but many people bring this up so it is worth discussing. One of the problems with this view is it leads to a circle of inertia: industry uses C/Java for programming projects because that's what their current team knows and it is easy to hire C/Java programmers, and universities train C/Java programmers because that's what industry wants. Academia should be &em&leading&/em& industry, not following it, and one way to do that is by producing graduates who know about things that are not yet widely known in industry.&/p&&p&For individuals, however, this larger view is not too helpful (trying to change industry doesn't provide much solace for the poor sap who can't get a job, although our graduates usually have a plethora of interesting job offers, at least for the 4th years, often before finishing this class). More pragmatically, I don't see that a one semester course using C is enough to really increase someone's value as a C programmer. There are thousands of programmers with decades of experience using C, and it takes many years using C to be a top-level C programmer, so a single semester of coursework is unlikely to make someone a particularly valuable C programmer if she wasn't already a valuable employee because of her general knowledge, ability, and talents. On the other hand, if Rust takes-off as an industrial systems programming language, being one of a small number of people who already have significant experience with the language should be a considerable advantage.&/p&&/li&&/ol&&/blockquote&
在使用了Rust和Golang以后,我的个人感觉是这两种语言虽然都号称“系统编程语言”,可是他们的目标程序员完全不一样。 Golang的未来应该是慢慢取代Java和Python在分布式后端的地位的。很多基于Java的通讯密集型分布式框架,现在都在开始用Golang来重写。再…
先从Coding Style上说几点吧:&br&0. 很多 compiling warnings,包括 async/include/async/Shell.h 中 ApplicationInit 的构造函数把 servicesInit 成员和 timerInit 成员的初始化顺序写反了,这种错误不止一处,还有 FastTimer.h。&br&1. space 和 tab 混用&br&2. async/include/async/DataQueue.h 里改了 pack(1) 但没有改回去,基本上谁用谁死。&br&3. 很多class应该禁用copy-ctor和assignment operator,但没有禁用,例如 async/include/async/Mutex.h 中的 ScopedLock,FastTimer.h 中的 FastTimerQueue,socketio/sync.h 中的 SyncSocketFile 等等。基本上C++98/03中需要写destructor的class要么应该自己定义copy-ctor和assignment operator,要么应该禁用 copy-ctor和assignment operator。&br&4. 不该用 explicit 的构造函数:async/include/async/socketio/epoll.h 的 ConnectSocket 。&br&5. 不是 64-bit clean,这从第 0 点的编译器警告能反映出一些来,另外一些混合位宽的整数运算也可能存在风险(int vs. size_t,int vs. pointer 等等)。&br&6. 不该用继承:IoCompletionPort.h 中的 IoCompletionPortST 继承了 std::deque&IoCompletionPort::Message&;sockets.h 中的 SockaddrIn 继承了 C 头文件中的 SOCKADDR_IN struct。&br&7. const member function 不应该返回 non-const reference,例如 Buffered.h 中的 FileT& BufferedReader::get_file() const。&br&8. 命名不地道,async/include/async/Mutex.h 中的 FiberNestableMutex 应该是 FiberReentrantMutex 。&br&9. POD 成员没有初始化,例如 MessageQueue.h 中的 FiberMessageQueue 在构造函数中没有为 WaitingNode* m_waitingL 成员赋初值,只给 BOOL m_fW 赋了值。&br&10. 错误的强制转型,task/ShareFiberTaskPool.h 中 ShareFiberTaskPool::addTask() 把 TaskStub* 强制转型为 MessageQueue::Node*,而 TaskStub 和 Node 两个类型无关,只是 object layout 上有点“关系”,这属于 hacking。&br&11. msgq/condition.h 中的 LimitedMessageQueue 是个 bounded producer consumer queue,其实现也有问题,首先是 push() 只在队列长度 0 -& 1 的时候 notify_one(),这有可能造成多个 consumers 中只唤醒一个,其余饥饿,哪怕队列中有多个可供消费的数据;类似的,pop() 只在队列长度 full -& not full 的时候 notify_one(),这有可能造成 producers 饥饿;最后,clear() 应该 notify producer。MessageQueue::push() 只在队列长度 0 -& 1 的时候 notify_all(),有可能造成不必要的唤醒。&br&&br&too many errors to continue ……&br&&br&我只管中窥豹看了看 async/ 下的代码片段,没有阅读代码整体逻辑,也没有实际运行程序,就目前的感受,说句实话,连 Effective C++ 的条款都没有完全做到啊。不是说C++程序绝对不能打破 Effective C++ 的规则,而是目前的代码打破这些 rule 并没有合理的理由。&br&&br&我只好当这代码是 proof of concept 了。&br&&br&话又说回来,有代码总比空口瞎嚷嚷的强10000倍。
先从Coding Style上说几点吧: 0. 很多 compiling warnings,包括 async/include/async/Shell.h 中 ApplicationInit 的构造函数把 servicesInit 成员和 timerInit 成员的初始化顺序写反了,这种错误不止一处,还有 FastTimer.h。 1. space 和 tab 混用 2. a…
qnlang只是golang版本的tpl(text processing language)库的一个demo,花了7个晚上搞成,没有什么惊人的特性,实在难入大家的法眼,不好意思。有本事就自己撸一个给我涨涨姿势呗,光喷于整个社会进步又有什么鸟用。&br&&br&另外,1月(下个月)22、23号将于北京举行的ecug大会上,我会介绍这门语言是如何构建出来的。整个演讲会围绕如何用qnlang制作一个支持常规四则运算和函数的计算器(大约100行代码)以及qnlang本身(也就是所谓的自举,大约1300行代码)来讲解。这个qnlang版本的计算器和qnlang版本的qnlang会在本次ecug大会后放出。&br&&br&如果你想做为听众参加ecug大会,或者希望做为讲师与大家交流你的技术心得,请访问 &a href=&///?target=http%3A//www.ecug.org& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&ecug.org&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 了解详情(不能访问请自备梯子)。&br&&br&----&br&&br&12.12日更新:今晚抽空写完了qnlang自举的代码,实际代码比golang版本少一些,只有900行。详见:&br&&ul&&li&&a href=&///?target=https%3A///qiniu/qnlang& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&qiniu/qnlang · GitHub&i class=&icon-external&&&/i&&/a&&/li&&/ul&这里可下载 qnlang,并且提供了多个样例。ecug 大会上会讲解背后的工作原理。
qnlang只是golang版本的tpl(text processing language)库的一个demo,花了7个晚上搞成,没有什么惊人的特性,实在难入大家的法眼,不好意思。有本事就自己撸一个给我涨涨姿势呗,光喷于整个社会进步又有什么鸟用。 另外,1月(下个月)22、23号将于北京举…
谢不愿意透露姓名的UC前端号称第二强的 &a data-hash=&1bf51c68cfb2a8c0a849c3c& href=&///people/1bf51c68cfb2a8c0a849c3c& class=&member_mention& data-tip=&p$b$1bf51c68cfb2a8c0a849c3c& data-hovercard=&p$b$1bf51c68cfb2a8c0a849c3c&&@刘洋&/a&人肉邀请……&br&&br&虽然语言只是工具,但是对于做的事而言,正确的“工具”往往会达到事半功倍的效果。在这一点上我一直认为,前后端统一也就是个笑话。&br&&br&即便不说JS语言层面上的天生弊端,比如过于灵活以至于混乱的语法带来的工程上维护成本的巨大,V8本身的稳定性对于后端而言就是个巨大的挑战。Google V8起源于Chome,追求速度,以空间换时间的做法在当前大内存时代并不那么硬伤,稳定性稍差也不是什么很致命的事。但是在服务器上,一寸内存一寸血,谁都不像OOM以至于Crash。速度快慢也没那么重要,服务端追求扩展性,在数百数千甚至数万这个量级上单台服务器极致性能往往没那么重要。在这个基础上,稳定性和可用性最终决定了你服务质量,而这些,都是目前V8或者说node的短板。&br&&br&同时,服务端要求对所用的技术有足够的可控性,node或者说js大量的black magic削弱了系统工程师在这方面对其的信任,出了问题没办法调,找不出bug,downtime上升,谁负责?&br&&br&为何Java被人喷死板依旧占据了那么大的份额?为何C那么老依旧是服务端程序猿的基础?为何Python慢成狗还是有很多公司青睐?无他,只是因为他们经过了大量的考验,证明是可靠的并且可控的罢了。况且即便是Python,最新一系列技术加持之后,对比Node还真不慢……&br&&br&至于为何转向Go?我个人认为Go抓牢了服务端开发的几个大需求,首先是抹平服务器差异,俗称跨平台。然后是标准库做得很相对而言很强大,系统细节屏蔽得很不错。再者是语言层面即满足了脚本小子们所需要的动态性和开发效率,也满足了系统工程师的静态需求来维持项目的有序性和最终输出结果的效率。同时对于未来服务端开发趋势的迎合,比如原生Coroutine并且极力的优化其内存消耗等特性,对于服务端开发而言是极大的提高了生产力的同时也让代码逻辑和可读性大大的提升。基于以上几点,Go确实是当下作为性能型服务端开发语言中比较好的选择。&br&&br&而Node的核心V8,作为一个桌面项目,在这些方面缺陷太过于明显。做demo不错,上到工程级别就WTF了,至少对于我来说,lua/python/go,甚至是未来的rust,都是更好的选择。
谢不愿意透露姓名的UC前端号称第二强的 人肉邀请…… 虽然语言只是工具,但是对于做的事而言,正确的“工具”往往会达到事半功倍的效果。在这一点上我一直认为,前后端统一也就是个笑话。 即便不说JS语言层面上的天生弊端,比如过于灵活以至于混乱的语…
&p&这是个好问题。这句俏皮话具体说来就是,不同的线程不共享内存不用锁,线程之间通讯用channel同步也用channel。&/p&&p&这种并发的范式实际上已经是主流了,不提erlang,即使是C++也有很多高性能的架构是只依赖于高性能的MPSC队列,而从来不在事务逻辑里用锁。在Rust里面,配合所有权概念和Send trait,编译器能够静态的保证没有数据竞争。&/p&&p&用这种范式的主要优点是逻辑简单清楚,系统有高正确性。你的程序能保证每个线程里事件都是sequential consistent的,不会有竞争出现。你不需要在写完程序之后花大笔时间去debug各种诡异的线程竞争问题。在交易系统中,这个对保证交易逻辑的正确性至关重要。&/p&&p&另一方面很多人没有看到的是,这种范式反而会比线程之间单纯的共享内存更快。在我看到的顶尖低延迟领域,这种范式越来越主流。线程之间不用共享内存,共享内存和memory-order的细致优化被完全使用在实现高性能的无锁队列上。由于队列可以无锁,系统延迟完全没有锁的contention的影响,单线程的逻辑同时保证最低延迟。宏观上来讲,由于逻辑能够被更容易的reason about(理清?)。没有数据竞争,人会更容易而且更倾向于写出清楚的责任划分,可以随意并行的系统。大型系统的性能从来都更在乎是否有一个好的架构而通常不是去优化个别函数。&/p&&p&另外,这跟一份内存还是两份内存是没有关系的。很多情况下,数据从channel的一端到另一端其实并没有拷贝,而只是一个move,也就是一个指针的替换。上面所说的对延迟的影响也很容易看到这并不是通过降低速度而换取低复杂性的作法。通常正确实现这类范式的结果是速度变快而不是变慢,无论是延迟还是吞吐。&/p&&p&golang的特色就是它的channel是所谓的first-class citizen(一等公民),使用方便,配套设施完备。加上go-routine,它可以在避免操作系统线程切换的overhead的同时享受channel通信的简单方便。在我看来,这应该是golang的杀手特性。&/p&
这是个好问题。这句俏皮话具体说来就是,不同的线程不共享内存不用锁,线程之间通讯用channel同步也用channel。这种并发的范式实际上已经是主流了,不提erlang,即使是C++也有很多高性能的架构是只依赖于高性能的MPSC队列,而从来不在事务逻辑里用锁。在Rus…
&a href=&///?target=https%3A///funny/link& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&funny/link · GitHub&i class=&icon-external&&&/i&&/a&
长连接网络层的脚手架,因为很简单,所以还算不上框架,就是用来快速搭建自己的网络层用的脚手架,里面的接口设计技巧和编程技巧可以参考下,如果深挖变更日志的话也可以看到这个库的重构过程,之前还有两版内存池的实现,后来都删掉了。&br&&br&&a href=&///?target=https%3A///funny/binary& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&funny/binary · GitHub&i class=&icon-external&&&/i&&/a& 专门用来做二进制数据操作的库,可以用来做二进制文件解析或通讯协议解析,里面的一些接口设计技巧好编程技巧也可以参考一下,里面一些东西是从link包重构过程中分离出来的。&br&&br&&a href=&///?target=https%3A///idada/go-labs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&idada/go-labs · GitHub&i class=&icon-external&&&/i&&/a&
这些是我平时做的一些试验代码,在开发过程中经常会因为一些细节问题影响设计上的判断,所以我会把这些细节问题拆分成一个个小的试验,通过试验数据确认性能或机制,有一些试验比较早了,可能因为Go运行时升级会有变化,所以比较有参考价值的大概是试验方式和拆分问题的思路。&br&&br&有一些试验代码是即兴的,在 &a href=&///?target=http%3A//play.golang.org& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Go Playground&i class=&icon-external&&&/i&&/a& 上直接写直接试了,所以没有留档。&br&&br&因为 &a href=&///?target=http%3A//play.golang.org& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Go Playground&i class=&icon-external&&&/i&&/a& 和 go test 这些工具让试验变得很便捷,所以我在学习Go的过程养成了做小实验的习惯,这个习惯也影响到我做其它的事情,我觉得拆解问题做试验是很好的学习方式,推荐大家尝试。
长连接网络层的脚手架,因为很简单,所以还算不上框架,就是用来快速搭建自己的网络层用的脚手架,里面的接口设计技巧和编程技巧可以参考下,如果深挖变更日志的话也可以看到这个库的重构过程,之前还有两版内存池的实现,后来都删掉…
&p&可以看到,今年谷歌家的 Go 编程语言流行度有着惊人的上升趋势,其发展也是越来越好,因此本文整理了一些优秀的 Go 存储相关开源项目和库,一起分享,一起学习。&/p&&h2&&strong&存储服务器(Storage Server)&/strong&&/h2&&h3&&strong&Go 实现的存储服务器&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A///minio/minio& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&minio&i class=&icon-external&&&/i&&/a& &/strong&- Minio 是一个与 Amazon S3 APIs 兼容的开源对象存储服务器,分布式存储方案&/li&&li&&strong&&a href=&///?target=https%3A///ncw/rclone& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&rclone&i class=&icon-external&&&/i&&/a&&/strong& - “用于云存储的 Rsync” - Google Drive, Amazon Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Cloudfile…&/li&&li&&strong&&a href=&///?target=https%3A///camlistore/camlistore& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&camlistore&i class=&icon-external&&&/i&&/a&&/strong& - Camlistore 是你的个人存储系统:一种存储、同步、共享、建模和备份内容的方式&/li&&li&&strong&&a href=&///?target=https%3A///coreos/torus& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&torus&i class=&icon-external&&&/i&&/a&&/strong& - CoreOS 的现代分布式存储系统&/li&&li&&strong&&a href=&///?target=https%3A///s3git/s3git& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&s3git&i class=&icon-external&&&/i&&/a&&/strong& - 云存储的 Git。用于数据的分布式版本控制系统&/li&&li&&strong&&a href=&///?target=https%3A///rook/rook& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&rook&i class=&icon-external&&&/i&&/a&&/strong& - 开放、云本地和通用的分布式存储&/li&&/ul&&h2&&strong&Key-Value 存储(Key-Value Store)&/strong&&/h2&&h3&&strong&Go 实现的 Key-Value 存储&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A///coreos/etcd& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&etcd&i class=&icon-external&&&/i&&/a&&/strong& - 可靠的分布式 key-value 存储,用于分布式系统的最关键数据&/li&&li&&strong&&a href=&///?target=https%3A///patrickmn/go-cache& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-cache&i class=&icon-external&&&/i&&/a&&/strong& - Go 语言实现的一个内存中的缓存框架,实现 Key-Value 的序列存储,适用于单台机器应用程序&/li&&li&&strong&&a href=&///?target=https%3A///dcoker/biscuit& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&biscuit&i class=&icon-external&&&/i&&/a&&/strong& - Biscuit 用于 AWS 基础架构建设时多区域 HA key-value 存储&/li&&li&&strong&&a href=&///?target=https%3A///peterbourgon/diskv& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&diskv&i class=&icon-external&&&/i&&/a&&/strong& - 支持磁盘的 key-value 存储&/li&&/ul&&h2&&strong&文件系统(File System)&/strong&&/h2&&h3&&strong&Go 实现的文件系统&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A///git-lfs/git-lfs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&git-lfs&i class=&icon-external&&&/i&&/a&&/strong& - 用于大文件版本控制的 Git 扩展&/li&&li&&strong&&a href=&///?target=https%3A///chrislusf/seaweedfs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&seaweedfs&i class=&icon-external&&&/i&&/a&&/strong& - SeaweedFS 是一个用于小文件的简单且高度可扩展的分布式文件系统&/li&&li&&strong&&a href=&///?target=https%3A///fsnotify/fsnotify& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&fsnotify&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的跨平台文件系统监控库&/li&&li&&strong&&a href=&///?target=https%3A///kahing/goofys& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&goofys&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的高性能,POSIX-ish Amazon S3 文件系统&/li&&li&&strong&&a href=&///?target=https%3A///coreos/go-systemd& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-systemd&i class=&icon-external&&&/i&&/a&&/strong& - systemd 的 Go 语言绑定版(包括socket activation, journal, D-Bus, 和 unit files)&/li&&li&&strong&&a href=&///?target=https%3A///GoogleCloudPlatform/gcsfuse& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&gcsfuse&i class=&icon-external&&&/i&&/a&&/strong& - 用于与 Google 云存储交互的用户空间文件系统&/li&&li&&strong&&a href=&///?target=https%3A///ovh/svfs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&svfs&i class=&icon-external&&&/i&&/a&&/strong& - 基于 Openstack 的虚拟文件系统&/li&&/ul&&h2&&strong&数据库(Database)&/strong&&/h2&&h3&&strong&Go 实现的数据库&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A///allegro/bigcache& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&BigCache&i class=&icon-external&&&/i&&/a&&/strong& - 用于千兆字节数据的高效 key/value 缓存&/li&&li&&strong&&a href=&///?target=https%3A///boltdb/bolt& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&bolt&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的低层级的 key/value 数据库&/li&&li&&strong&&a href=&///?target=https%3A///tidwall/buntdb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&buntdb&i class=&icon-external&&&/i&&/a&&/strong& - 一个 Go 实现的快速、可嵌入的 key/value 内存数据库,具有自定义索引和 geospatial 支持的功能&/li&&li&&strong&&a href=&///?target=https%3A///muesli/cache2go& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cache2go&i class=&icon-external&&&/i&&/a&&/strong& - key/value 内存缓存,支持基于超时的自动无效功能&/li&&li&&strong&&a href=&///?target=https%3A///cockroachdb/cockroach& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cockroach&i class=&icon-external&&&/i&&/a&&/strong& - 一个可伸缩的、支持地理位置处理、支持事务处理的数据存储系统&/li&&li&&strong&&a href=&///?target=https%3A///codingsince1985/couchcache& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&couchcache&i class=&icon-external&&&/i&&/a&&/strong& - 由 Couchbase 服务器支持的 RESTful 缓存微服务&/li&&li&&strong&&a href=&///?target=https%3A///dgraph-io/dgraph& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&dgraph&i class=&icon-external&&&/i&&/a&&/strong& - 具有可扩展、分布式、低延迟和高吞吐量功能的图形数据库&/li&&li&&strong&&a href=&///?target=https%3A///krotik/eliasdb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&eliasdb&i class=&icon-external&&&/i&&/a&&/strong& - 使用 REST API,短语搜索和类似 SQL 查询语言的无依赖性,支持事务处理的图形数据库&/li&&li&&strong&&a href=&///?target=https%3A///couchbase/goforestdb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&forestdb&i class=&icon-external&&&/i&&/a&&/strong& - Go bindings for ForestDB.Go 语言绑定版的 ForestDB&/li&&li&&strong&&a href=&///?target=https%3A///bluele/gcache& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GCache&i class=&icon-external&&&/i&&/a&&/strong& - 支持可用缓存、LFU、LRU 和 ARC 的缓存数据库&/li&&li&&strong&&a href=&///?target=https%3A///melihmucuk/geocache& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&geocache&i class=&icon-external&&&/i&&/a&&/strong& - An in-memory cache that is suitable for geolocation based applications.适用于 地理位置处理基于应用程序的内存缓存&/li&&li&&strong&&a href=&///?target=https%3A///syndtr/goleveldb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&goleveldb&i class=&icon-external&&&/i&&/a&&/strong& - An implementation of the &a href=&///?target=https%3A///google/leveldb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LevelDB&i class=&icon-external&&&/i&&/a& key/value database in the Go.Go 实现的 LevelDB key/value 数据库&/li&&li&&strong&&a href=&///?target=https%3A///golang/groupcache& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&groupcache&i class=&icon-external&&&/i&&/a&&/strong& - Groupcache 是一个缓存和缓存填充库,在许多情况下用于替代 memcached&/li&&li&&strong&&a href=&///?target=https%3A///influxdb/influxdb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&influxdb&i class=&icon-external&&&/i&&/a&&/strong& - 开源的分布式指标、事件和实时分析的可扩展数据库&/li&&li&&strong&&a href=&///?target=https%3A///siddontang/ledisdb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ledisdb&i class=&icon-external&&&/i&&/a&&/strong& - 基于 LevelDB 类似 Redis 的高性能 NoSQL 数据库&/li&&li&&strong&&a href=&///?target=https%3A///jmhodges/levigo& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&levigo&i class=&icon-external&&&/i&&/a&&/strong& - 用于 LevelDB 的 Go 封装包&/li&&li&&strong&&a href=&///?target=https%3A///couchbase/moss& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&moss&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的简单 LSM key-value 存储引擎&/li&&li&&strong&&a href=&///?target=https%3A///fern4lvarez/piladb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&piladb&i class=&icon-external&&&/i&&/a&&/strong& - 基于堆栈数据结构的轻量级 RESTful 数据库引擎&/li&&li&&strong&&a href=&///?target=https%3A///nuveo/prest& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pREST&i class=&icon-external&&&/i&&/a&&/strong& - 为任何来自 PostgreSQL 的数据库提供一个 RESTful API&/li&&li&&strong&&a href=&///?target=https%3A///prometheus/prometheus& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&prometheus&i class=&icon-external&&&/i&&/a&&/strong& - 服务监控系统和时间序列数据库&/li&&li&&strong&&a href=&///?target=https%3A///rqlite/rqlite& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&rqlite&i class=&icon-external&&&/i&&/a&&/strong& - 基于 SQLite 构建的轻量级、分布式关系数据库&/li&&li&&strong&&a href=&///?target=https%3A///nanobox-io/golang-scribble& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&scribble&i class=&icon-external&&&/i&&/a&&/strong& - 一个小型的 Flat File JSON 存储&/li&&li&&strong&&a href=&///?target=https%3A//www.oschina.net/p/tidb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&tidb&i class=&icon-external&&&/i&&/a&&/strong& - TiDB 是一个分布式 SQL 数据库,灵感来自于 Google F1 和 Google spanner。TiDB 支持包括传统 RDBMS 和 NoSQL 的特性。&/li&&li&&strong&&a href=&///?target=https%3A///HouzuoGuo/tiedot& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&tiedot&i class=&icon-external&&&/i&&/a&&/strong& - 基于 Go 的 NoSQL 数据库&/li&&li&&strong&&a href=&///?target=https%3A///tidwall/tile38& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Tile38&i class=&icon-external&&&/i&&/a&&/strong& - 具有空间索引和实时地理围栏的地理位置数据库&/li&&/ul&&h3&&strong&数据库&/strong&&strong&迁移&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A///GuiaBolso/darwin& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&darwin&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的数据库 schema 演进库&/li&&li&&strong&&a href=&///?target=https%3A///steinbacher/goose& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&goose&i class=&icon-external&&&/i&&/a&&/strong& - 数据库迁移工具。可通过创建增量 SQL 或 Go 脚本来管理数据库的演变&/li&&li&&strong&&a href=&///?target=https%3A///go-gormigrate/gormigrate& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&gormigrate&i class=&icon-external&&&/i&&/a&&/strong& - Gorm ORM 的数据库迁移助手&/li&&li&&strong&&a href=&///?target=https%3A///mattes/migrate& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&migrate&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的数据库迁移处理,支持 MySQL, PostgreSQL, Cassandra, 和 SQLite&/li&&li&&strong&&a href=&///?target=https%3A///pravasan/pravasan& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pravasan&i class=&icon-external&&&/i&&/a&&/strong& - 简单的迁移工具,目前支持 MySQL,PostgreSQL,但计划很快支持 SQLite, MongoDB 等&/li&&li&&strong&&a href=&///?target=https%3A///markbates/pop/tree/master/soda& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&soda&i class=&icon-external&&&/i&&/a&&/strong& - 具有数据库迁移、创建和 ORM 等功能,适用于 MySQL, PostgreSQL, 和 SQLite&/li&&li&&strong&&a href=&///?target=https%3A//www.oschina.net/p/sql-migrate& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&sql-migrate&i class=&icon-external&&&/i&&/a&&/strong& - 数据库 schema 迁移工具。允许使用 go-bindata 将迁移嵌入到应用程序中&/li&&/ul&&h3&&strong&数据库工具&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A//www.oschina.net/p/go-mysql& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-mysql&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的用于处理 MySQL 协议和复制的工具集&/li&&li&&strong&&a href=&///?target=https%3A///siddontang/go-mysql-elasticsearch& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-mysql-elasticsearch&i class=&icon-external&&&/i&&/a&&/strong& - 将 MySQL 数据自动同步到 Elasticsearch 中&/li&&li&&strong&&a href=&///?target=https%3A//www.oschina.net/p/kingshard& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&kingshard&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的高性能 MySQL Proxy 项目&/li&&li&&strong&&a href=&///?target=https%3A///2tvenom/myreplication& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&myreplication&i class=&icon-external&&&/i&&/a&&/strong& - MySQL 二进制日志复制监听器。支持语句和基于行的复制&/li&&li&&strong&&a href=&///?target=https%3A//www.oschina.net/p/orchestrator& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&orchestrator&i class=&icon-external&&&/i&&/a&&/strong& - MySQL 复制拓扑管理器和可视化工具&/li&&li&&strong&&a href=&///?target=https%3A//www.oschina.net/p/pgweb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pgweb&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的基于 Web 的 PostgreSQL 数据库管理系统&/li&&li&&strong&&a href=&///?target=https%3A//www.oschina.net/p/vitess& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&vitess&i class=&icon-external&&&/i&&/a&&/strong& - 分布式 MySQL 工具集。vitess 提供了服务器和工具,以便于大规模 Web 服务的 MySQL 数据库扩展&/li&&/ul&&h3&&strong&SQL 查询构建器,用于构建和使用 SQL 的库&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A///mgutz/dat& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&dat&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的 Postgres 数据访问工具包&/li&&li&&strong&&a href=&///?target=https%3A///gchaincl/dotsql& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dotsql&i class=&icon-external&&&/i&&/a&&/strong& - Go 语言实现的库,可帮助你将 sql 文件保存至某个地方并轻松使用它&/li&&li&&strong&&a href=&///?target=https%3A///doug-martin/goqu& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&goqu&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的 SQL 构建器和查询库&/li&&li&&strong&&a href=&///?target=https%3A///galeone/igor& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&igor&i class=&icon-external&&&/i&&/a&&/strong& - PostgreSQL 的抽象层,支持高级功能并使用类似 Gorm 的语法&/li&&li&&strong&&a href=&///?target=https%3A///go-ozzo/ozzo-dbx& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ozzo-dbx&i class=&icon-external&&&/i&&/a&&/strong& - 强大的数据检索方法以及 DB-agnostic 查询构建功能&/li&&li&&strong&&a href=&///?target=https%3A///variadico/scaneo& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&scaneo&i class=&icon-external&&&/i&&/a&&/strong& - 生成 Go 代码以将数据库行转换为任意结构&/li&&li&&strong&&a href=&///?target=https%3A///elgris/sqrl& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&sqrl&i class=&icon-external&&&/i&&/a&&/strong& - SQL 查询构建器,Squirrel 的 fork 具有更好的性能&/li&&li&&strong&&a href=&///?target=https%3A///Masterminds/squirrel& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Squirrel&i class=&icon-external&&&/i&&/a&&/strong& - 帮助你构建 SQL 查询的 Go 库&/li&&li&&strong&&a href=&///?target=https%3A///knq/xo& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&xo&i class=&icon-external&&&/i&&/a&&/strong& - 基于现有 schema 定义或支持 PostgreSQL,MySQL,SQLite,Oracle 和 Microsoft SQL Server 的自定义查询生成数据库的惯用 Go 代码&/li&&/ul&&h2&&strong&数据库驱动&/strong&&/h2&&p&&strong&用于连接和操作数据库的库&/strong&&/p&&h3&&strong&关系数据库&/strong&&/h3&&ul&&li&&strong&&a href=&///?target=https%3A///viant/bgc& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&bgc&i class=&icon-external&&&/i&&/a&&/strong& - Go 实现的用于 BigQuery 的数据存储连接&/li&&li&&strong&&a href=&///?target=https%3A///nakagami/firebirdsql& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&firebirdsql&i class=&icon-external&&&/i&&/a&&/strong& - Firebird RDBMS SQL 驱动&/li&&li&&strong&&a href=&///?target=https%3A///mattn/go-adodb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-adodb&i class=&icon-external&&&/i&&/a&&/strong& - Microsoft ActiveX Object 数据库驱动,使用 database/sql&/li&&li&&strong&&a href=&///?target=https%3A///rounds/go-bqstreamer& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-bqstreamer&i class=&icon-external&&&/i&&/a&&/strong& - BigQuery 快速并发流插入&/li&&li&&strong&&a href=&///?target=https%3A///denisenkom/go-mssqldb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-mssqldb&i class=&icon-external&&&/i&&/a&&/strong& - Microsoft MSSQL 驱动&/li&&li&&strong&&a href=&///?target=https%3A///mattn/go-oci8& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-oci8&i class=&icon-external&&&/i&&/a&&/strong& - Oracle 驱动,使用 database/sql&/li&&li&&strong&&a href=&///?target=https%3A///go-sql-driver/mysql& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-sql-driver/mysql&i class=&icon-external&&&/i&&/a&&/strong& - MySQL 驱动&/li&&li&&strong&&a href=&///?target=https%3A///mattn/go-sqlite3& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go-sqlite3&i class=&icon-external&&&/i&&/a&&/strong& - SQLite3 驱动,使用 database/sql&/li&&li&&strong&&a href=&///?target=https%3A///minus}

我要回帖

更多关于 大型游戏开发语言 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信