104
回答
高手问答第 149 期 — Go 并发编程实战
终于搞明白,存储TCO原来是这样算的>>>   

OSCHINA 本期高手问答(2017 年 4 月 18 日 — 4 月 24 日)我们请来了 @hyper0x(郝林) 为大家解答关于 Go 并发编程相关的问题。

@hyper0x,郝林。从业 12 年有余的软件工匠,国内知名的 Go 语言技术布道者,Go 语言北京用户组和 GoHackers 社群的发起人和组织者,多套免费在线 Go 语言教程的作者,深信 Go 语言在人工智能时代和机器人时代也能大放异彩的科技信徒。

Go 语言被称为云计算时代的 C 语言,它在软件开发效率和运行效率之间做出了绝佳的权衡。这使得它既适应于互联网应用的极速开发,又能在高并发、高性能的开发场景中如鱼得水。正因如此,许多互联网公司,尤其是云计算领域的创业公司都选择 Go 语言作为其技术栈的重要组成部分。由此可见,对于广大的开发者而言,关注和学习 Go 语言就十分有必要了。

对于 Go 并发编程,你会碰到哪些问题?或者还有其他关于 Go 语言的问题,欢迎踊跃来提问。

为了鼓励踊跃提问,@hyper0x 会在问答结束后从提问者中抽取 5 名幸运会员赠予《Go并发编程实战(第2版)》一书。

与上一版相比,本书不仅基于 Go 1.8 对上一版进行了全面更新,而且更深入地描绘了 Go 运行时系统的内部机理,并且大幅改进了示例代码。

购买链接:http://www.ituring.com.cn/book/1950

OSChina 高手问答一贯的风格,不欢迎任何与主题无关的讨论和喷子。

下面欢迎大家就 Go 并发编程方面的问题向 @hyper0x(郝林)提问,请直接回帖提问。

举报
局长
发帖于6个月前 104回/5K+阅
共有104个答案 最后回答: 6个月前

OSC 第 149 期高手问答 — Go 并发编程实战(公布中奖名单)

@MtrS  @程序员贾  @老范的自留地  @elsonwu  @梦朝思夕

恭喜以上五位由郝林老师抽中的中奖朋友,将获得《Go并发编程实战(第2版)》图书一本

请私信@局长告知快递信息(格式:姓名+电话+地址+邮编)

--- 共有 2 条评论 ---
elsonwu书已收到,比第一版浓缩了不少,找个时间细看,谢谢啦🙏 6个月前 回复
程序员贾谢谢 6个月前 回复
@hyper0x 郝老师,您好,go语言相比java php这类时下用的最广的语言在执行速度跟并发编程上优势很明显,除了这两点外,go还有别的别的优势吗?另外go语言的应用场合只是适合服务器后端开发吗?创业团队技术选型适合用go语言吗?
@hyper0x ,郝老师,go语言最近火得一塌糊涂,刚才查了一下拉勾,go语言的职位很多,而且薪资也都比较高,我马上就要毕业了,很想学一下,对于我们这些新手来说有什么推荐跟建议吗?或者可以介绍一下您的学习经历吗?

引用来自“老范的自留地”的评论

@hyper0x 郝老师,go这么火,我也很想学习一下,都说读好的一本书能顶好几年开发经验,我想知道您的这本书里有没有一些实例场景的介绍? 还有这一本书如果作为go语言入门的书籍合适吗?

你好,这本书中也一些中大型的例子。这些例子的来源都是我在实际工作中的实际问题。你可以仔细参考这些例子来学习Go语言中的惯用法和最佳实践。

如果你只想钻研Go语言语法的话,我推荐你直接去读Go官方的语言规范。如果你想了解Go语言基础语法的同时知晓Go编程的真正方法,我认为这本书是非常合适的。

--- 共有 5 条评论 ---
程序员贾谢谢郝大老师分享自学go的经历,那这本书很适合入门的新手啊! 6个月前 回复
hyper0x@老范的自留地 回复@老范的自留地 : 客气了。 6个月前 回复
hyper0x@奋斗努力加油 回复@奋斗努力加油 : 客气了。希望你早日成为高手! 6个月前 回复
奋斗努力加油谢谢,郝老师。向您学习。希望自己能把go学好。早日找到一份go相关的开发工作! 6个月前 回复
老范的自留地好的,那我感觉这本书还挺适合我学习的初衷的。谢谢郝老师。 6个月前 回复

引用来自“奋斗努力加油”的评论

@hyper0x 郝老师,您好,go语言相比java php这类时下用的最广的语言在执行速度跟并发编程上优势很明显,除了这两点外,go还有别的别的优势吗?另外go语言的应用场合只是适合服务器后端开发吗?创业团队技术选型适合用go语言吗?

你好,工程化能力、开发和运行效率上的权衡是Go很突出的两个特色。这两方面初看没什么,但细究起来真正是为软件工程的实施准备的,能起到非常大的作用。当一个团队去做一大坨项目或者很大的工程的时候,优势还是很明显的。我推荐创业团队选用Go语言作为其基础技术栈(之一)。

Go语言目前非常适合Web编程和服务器程序开发。另外IoT方面有gobot框架,移动开发方面也有官方的解决方案(虽然还有待进一步发展)。

引用来自“程序员贾”的评论

@hyper0x ,郝老师,go语言最近火得一塌糊涂,刚才查了一下拉勾,go语言的职位很多,而且薪资也都比较高,我马上就要毕业了,很想学一下,对于我们这些新手来说有什么推荐跟建议吗?或者可以介绍一下您的学习经历吗?

你好,我推荐你好好读读这本书。再者,github是一个大宝藏,这本书的附录中推荐了很多值得学习的go项目,你可以通过这些项目获取到很多知识。另外,多与同行交流也是一个必要条件。

我学习Go语言那会儿,资料(尤其是中文资料)和Go技术交流还非常非常少,我基本完全靠自学,读Go源码、文档和国外资料,自己写例子,勤奋练习。相比之下,现在学Go语言要方便很多了。

--- 共有 2 条评论 ---
程序员贾谢谢郝老师的回答与鼓励。我会努力的。 6个月前 回复
老范的自留地好佩服,自学能力要强,多读Go源码、多看文档和国外资料,多实践写例子并且保持这个学习进取心一组勤奋练习!这样人人都能把自己上升到大神!! 6个月前 回复

@hyper0x

如何设计不同goroutine对同一个struct类型的字段并发读写?

因为为了不用lock,只能是有一个独立的goroutine,专门for+select+channel来读写,但这样要为每一个field的读写都加两个channel,代码看起来很ugly,还是说这种场景只能用lock会比较合适?

 

接着,上面的struct对象如果使用完毕,也要close逐个field的channel,但常规来说,应该是消息生产者做close,可是我有一个应用场景,是有多个消息生产者,要是任意一处close了会引起其他消息生产者panic,当然,另外加一个closed bool的字段做标记本struct已经停止也不是不可以,但有没有更合适的方式?

 

BTW:之前您的书第一版电子书和纸质都买了,作为支持,但第一版要是能分两本书,甚至直接去掉基础部分更为合适,既然冲着并发内容而买的人,基础部分都没问题。

--- 共有 12 条评论 ---
anotyhttps://golang.org/pkg/sync/atomic/#Value 试试atomic.Value 6个月前 回复
elsonwu@梦朝思夕 回复@梦朝思夕 : 因为只是个小网站,同时在线就几百人,所以拿channel练练手试着,后来发现不对 6个月前 回复
梦朝思夕@elsonwu 回复@elsonwu : 你这样的方式能做到分布式多机房跨地域的高可用吗?我觉得使用消息队列比较好一些。 6个月前 回复
hyper0x@梦朝思夕 回复@梦朝思夕 : 嗯,你这么说也对,Goroutine最好无状态,否则做不到“用通讯的方式做数据共享”。 6个月前 回复
elsonwu@梦朝思夕 回复@梦朝思夕 : 确实需要摸索一下,之前是在做一个聊天的消息推送,带群组功能,允许多浏览器同时使用一个账号,但又要允许浏览器刷新页面不显示掉线,超时后不重连才算掉线。 6个月前 回复

@hyper0x Go写的package比较多,也好写,但在应用层,项目开发的代码结构我自己做了一些尝试,没找到最佳实践,希望能指点,具体例如,一个web应用,我需要有model(用struct)映射数据库表,如果说我把所有struct放在model的package下,我对各个model的调用function,因为go的struct没有静态方法(虽然可以用nil的struct模拟,但总感觉容易跟struct其他function混在一起容易坑自己),就定义在另外一个叫service的package,这样导致为了区分对不同model的调用,我必须起前缀,这样下去,因为只有两个package,感觉过于耦合(起码会变得很大)。

如果为每个model新建一个package,也不行,因为总会有交叉调用的时候,虽然可以用一个service package统一调用这些model,但又回到上面的问题。

--- 共有 5 条评论 ---
hyper0x 回复 @elsonwu : 代码包要层次,model包里面可以直接编写公开的函数,也可以分层把它们做成子包。 6个月前 回复
elsonwu@hyper0x 回复@hyper0x : 所以说,得把业务逻辑都放在单独一个包,里面定义全部的函数操作各自的model(数据表)? 6个月前 回复
hyper0x 回复 @elsonwu : 为什么形成了循环引用?为什么不能封装成“集成式”的一站式函数完成某一个步骤的所有数据访问需求? 6个月前 回复
elsonwu@hyper0x 回复@hyper0x : 我明白你的意思,我上面写的service package其实就是把功能代码都写成函数,只不过如果把各自model的操作函数都放在一个包,就都得起函数前缀,不然就乱了。而如果把不同的model分别建包,把操作函数放在各自model的包,由会因为函数间需要互相调用其他model,导致循环引用而被go编译器拒绝。 6个月前 回复
hyper0x你好,静态方法可以用函数来表现,这种不同功能的代码放在同一个包的不同的源码文件里就好了,不要什么都用OO思想来做,Go也不是一个纯OO的语言。 6个月前 回复
顶部