go语言麻将手机游戏开发需求,如何寻找客户需求懂go语言的技术大牛?

Teamwork团队在去年写了近20万行Go代码,建造了一堆速度奇快的小型HTTP服务,本文列出了他们总结的9条经验教训。为什么选择Go语言?Go语言,又称Golang,是Google开发的一款静态强类型、编译型、并发型,并具有垃圾回收机制的编程语言,它的运行速度非常之快,同时还有如下特性:具有一流的标准库、无继承关系、支持多核;同时它还有着传说级的设计者与极其优秀的社区支持,更别提还有对于我们这些web应用的编写者异常方便、可以避免事件循环与回调地狱的goroutine-per-request设置了(每次请求处理都需要启动一个独立的goroutine)。目前,Go语言已经成为构建系统、服务器,特别是微服务的热门选择。正如使用其它新兴语言或技术一样,我们在早期的实验阶段经历了好一阵子的摸索期。Go语言确实有自己的风格与使用习惯,尤其是对于从面向对象语言(比如Java)或脚本语言(比如Python)转过来的开发者而言更是如此。所以我们很是犯了些错误,在本文中我们希望能与大家分享所得。如果在生产环境中使用Go语言,下面这些问题都有可能碰到,希望本文能为Go语言的初学者提供一些帮助。1. Revel不是好的选择对于初学Go语言、需要构建web服务器的用户来说,他们也许会认为此时需要一个合适的框架。使用MVC框架确有优势,主要是由于惯例优先原则设置了一系列的项目架构与惯例,从而赋予了项目一致性,并降低了跨项目开发的门槛。但我们发现:自行配置比遵循惯例更为强大,尤其是Go语言已经将编写web应用的难度降到了最低,而我们的很多web应用都是小型服务。最重要的是:我们的应用不符合惯例。Revel的设计初衷在于:尝试将Play或Rails之类的框架引入Go语言,而不是运用Go与stdlib的力量,并以其为基础进行构建。根据Go语言编写者的说法:& & 最初这只是一个有趣的项目,我想尝试能否在不那么神奇的Go语言中复制神奇的Play框架体验。公平来讲,那时候在一种新语言中采用MVC框架对我们来说很有意义——无需争论架构,同时新团队也能连贯地构建内容。在使用Go语言之前,我所编写的每个web应用都有着借助MVC框架的痕迹。在C#中使用了ASP.NET MVC,在Java中使用了SpringMVC,在PHP中使用了Symfony,在Python中使用了CherryPy,在Ruby中使用了RoR,但最后我们终于发现,在Go语言中不需要框架。标准库HTTP包已经包含所需的内容了,一般只要加入多路复用器(比如 mux)来选择路由,再加入lib来处理中间件(比如 negroni)的任务(包括身份验证与登录等)就足够了。Go的标准库HTTP包设计让这项工作十分简单,使用者会渐渐发现:Go的强大有一部分原因就在于其工具链与相关的工具——其中包含各种可运行在代码中的强大命令。但在Revel中,由于项目架构的设定,再加上缺乏package main与func main() {}入口(这些都是惯用和必要的Go命令),我们无法使用这些工具。事实上Revel附带自己的命令包,镜像一些类似run与build之类的命令。使用Revel后,我们:& & 无法运行go build;& & 无法运行go install;& & 无法使用 race detector (–race);& & 无法使用go-fuzz或者其它需要可构建Go资源的强大工具;& & 无法使用其它中间件或者路由;& & 热重载虽然简洁,但很缓慢,Revel在源上使用了反射机制(reflection),且从1.4版本来看,编译时间也增加了大约30%。由于并未使用go install,程序包没有缓存;& & 由于在Go 1.5及以上版本中编译速度更慢,因此无法迁移到高版本,为了将内核升级到1.6版,我们去掉了Revel;& & Revel将测试放置在/test dir下面,违反了Go语言中将_test.go文件与测试文件打包在一起的习惯;& & 要想运行Revel测试,需要启动服务器并执行集成测试。我们发现Revel的很多方式与Go语言的构建习惯相去甚远,同时也失去了一些强大go工具集的协助。2. 明智地使用Panics如果你是从Java或C#转到Go语言的开发者,可能会有些不太习惯Go语言中的错误处理方式(error handling)。在Go语言中,函数可返回多个值,因此在返回其他值时一并返回error是很典型的情况,如果一切运行正常的话,resturnsError返回的值为nil(nil是Go语言中引用类型的默认值)。func something() (thing string, err error) { && & s := db.GetSomething()& & if s == && {& & & & return s, errors.New(&Nothing Found&)& & }& & return s, nil}由于我们想要创建一个error,并在调用栈的更高层级中进行处理,因此最终使用了panic。s, err := something() && & if err != nil {& & panic(err)}结果我们完全惊呆了:一个error?天啊,运行它!但在Go中,你会发现error其实也是返回值,在函数调用和响应处理中十分常见,而panic则会拖慢应用的性能,并导致崩溃——类似运行异常时的崩溃。为什么要仅仅因为需要函数返回error就这样做呢?这是我们的教训。在1.6 版本发布前,转储panic的堆栈也负责转储所有运行的Go程序,导致在查找问题起源时非常困难,我们在一大堆不相关的内容上查找了很久,白费力气。就算有一个真正不可恢复的error,或是遇到了运行时的panic,很可能你也并不希望整个web服务器崩溃,因为它也是很多其他服务的中间件(你的数据库也使用事务机制对吧?) 因此我们学到了处理这些panic的方式:在Revel中添加filter能够让这些panic恢复,还能获取日志文件中的堆栈追踪记录并发送到Sentry,然后通过电邮以及Teamwork Chat实时聊天工具给我们发送警告,API向前端返回“500内部服务器错误”。// PanicFilter wraps the action invocation in a protective defer blanket that// recovers panics, logs everything, and returns 500.func PanicFilter(rc *revel.Controller, fc []revel.Filter) { && & defer func() {& & & & if err := recover(); err != nil {& & & & & & handleInvocationPanic(rc, err) // stack trace, logging. alerting & & & & & && & & & }& & }()& & fc[0](rc, fc[1:])}3. 当心不止一次从Request.Body的读取从http.Request.Body读取内容之后,其Body就被抽空了,随后再次读取会返回空body[]byte{} 。这是因为在读取一个http.Request.Body的数据时,读取器会停在数据的末尾,想要再次读取必须先进行重置。然而,http.Request.Body是一个io.ReadWriter,并未提供Peek或Seek之类能解决这个问题的方法。有一个解决办法是先将Body复制到内存中,读取之后再将原本的内容填回去。如果有大量request的话,这种方式的开销很大,只能算权宜之计。下面是一段短小而完整的代码:package mainimport ( && & &bytes&& & &fmt&& & &io/ioutil&& & &net/http&)func main() { && & r := http.Request{}& & // Body is an io.ReadWriter so we wrap it up in a NopCloser to satisfy that interface& & r.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(&test&)))& & s, _ := ioutil.ReadAll(r.Body)& & fmt.Println(string(s)) // prints &test&& & s, _ = ioutil.ReadAll(r.Body)& & fmt.Println(string(s)) // prints empty string!&}这里包括复制及回填的代码:content, _ := ioutil.ReadAll(r.Body) &// Replace the body with a new io.ReadCloser that yields the same bytesr.Body = ioutil.NopCloser(bytes.NewBuffer(content)) &again, _ = ioutil.ReadAll(r.Body) &可以创建一些util函数:func ReadNotDrain(r *http.Request) (content []byte, err error) { && & content, err = ioutil.ReadAll(r.Body)& & r.Body = ioutil.NopCloser(bytes.NewBuffer(content))&& & return}以替代调用类似ioutil.ReadAll的方式:content, err := ReadNotDrain(&r) &当然,现在你已经用no-op替换了r.Body.Close(),在request.Body中调用Close时将不会执行任何操作,这也是httputil.DumpRequest的工作方式。4. 一些持续优化的库有助于SQL的编写在Teamwork Desk,向用户提供web应用服务的核心功能常要涉及MySQL,而我们没有使用存储程序,因此在Go之中的数据层包含一些很复杂的MySQL……而且某些代码所构建的查询复杂程度,足以媲美奥林匹克体操比赛的冠军。一开始,我们用Gorm及其可链API来构建SQL,在Gorm中仍可使用原始的SQL,并让它根据你的结构来生成结果(但在实践中,近来我们发现这类操作越来越频繁,这代表着我们需要重新调整使用Gorm的方式,以确保找到最佳方式,或者需要多看些替代方案——但也没什么好怕的!)对于一些人来说,对象关系映射(ORM)非常糟糕,它会让人失去控制力与理解力,以及优化查询的可能性,这种想法没错,但我们只是用Gorm作为构建查询(能理解其输出的那部分)的封装方式,而不是当作ORM来完全使用。在这种情况下,我们可以像下面这样使用其可链API来构建查询,并根据具体结构来调整结果。它的很多功能方便在代码中手写SQL,还支持Preloading、Limits、Grouping、Associations、Raw SQL、Transactions等操作,如果你要在Go语言中手写SQL代码,那么这种方法值得一试。var customer Customer && &query = db.& &Joins(&inner join tickets on tickets.customersId = customers.id&).& &Where(&tickets.id = ?&, e.Id).& &Where(&tickets.state = ?&, &active&).& &Where(&customers.state = ?&, &Cork&).& &Where(&customers.isPaid = ?&, false).&& &First(&customer)5. 无指向的指针是没有意义的实际上这里特指切片(slice)。你在向函数传值时使用到了切片?在Go语言中,数组(array)也是数值,如果有大量的数组的话,你也不希望每次传值或者分配时都要复制一下吧?没错,让内存传递数组的开销是很大的,但在Go语言中,99%的时间里我们处理的都是切片而不是数组。一般来讲,切片可以当成数组部分片段的描述(经常是全部的片段),包含指向数组开始元素的指针、切片的长度与容量。切片的每个部分只需要8个字节, 因此无论底层是什么,数组有多大都不会超过24个字节。我们经常向函数切片发送指针,以为能节省空间。t := getTickets() // e.g. returns []Tickets, a slice &ft := filterTickets(&t)func filterTickets(t *[]Tickets) []Tickets {} &如果t中有很多数据,我们以为将其发送给filterTicket能阻止在内存中执行大量数据的复制工作。而现在随着对切片的了解,我们知道:可以只发送切片值,不用担心内存的问题。t := getTickets() // []Tickets massive list of tickets, 20MB &ft := filterTickets(t)func filterTickets(t []Tickets) []Tickets {} // 24 bytes passed by value &当然,不通过引用来发送也代表着你不会对指针指向进行错误的更改,因为切片本身就是一个引用类型。6. Naked returns会损失可读性,让代码更难读懂(在较大的函数中)。在Go语言中,“Naked returns”指代从某个函数返回时,没有明确说明返回内容的return。Go语言可以有命名返回值,比如func add(a, b int) (total int) {}, 我可以使用刚返回的那个函数来执行返回,而无需返回全部内容(使用return来代替return all)。在小型函数中,Naked Returns非常有用,也很简洁。func findTickets() (tickets []Ticket, countActive int64, err error) { && & tickets, countActive = db.GetTickets()& & if tickets == 0 {& & & & err = errors.New(&no tickets found!&)& & }& & return}显而易见,如果没找到ticket,则返回0, 0, error;如果找到了ticket,则返回120, 80, nil之类的格式,具体数值取决于ticket的count。关键在于:如果在函数签名中命名了返回值,就可以使用return(naked return),在调用返回时,也会返回每个命名返回值所在的状态。然而,我们有一些大型函数,大到有些笨重的那种。在函数中的,任何长度需要翻页的naked returns都会极大地影响可读性,并容易造成细微不易察觉的bug。特别如果有多个返回点的话,千万不要使用naked returns或者大型函数。下面是一个例子:func findTickets() (tickets []Ticket, countActive int64, err error) { && & tickets, countActive := db.GetTickets()& & if tickets == 0 {& & & & err = errors.New(&no tickets found!&)& & } else {& & & & tickets += addClosed()& & & & // return, hmmm...okay, I might know what this is& & & & return&& & }& & .& & .& & .& & // lots more code& & .& & .& & .& & if countActive & 0 {& & & & countActive - closedToday()& & & & // have to scroll back up now just to be sure...& & & & return& & }& & .& & .& & .& & // Okay, by now I definitely can't remember what I was returning or what values they might have& & return}7. 当心作用域与缩略声明在Go语言中,如果在不同的块区内使用相同的缩略名:=来声明变量时,由于作用域(scope)的存在,会出现一些细微不易察觉的bug,我们称之为shadowing。func findTickets() (tickets []Ticket, countActive int64) { && & tickets, countActive := db.GetTickets() // 10 tickets returned, 3 active& & if countActive & 0 {& & & & // oops, tickets redeclared and used just in this block& & & & tickets, err := removeClosed() // 6 tickets left after removing closed& & & & if err != nil {& & & & & & // Argh! We used the variables here for logging!, if we didn't we would& & & & & & // have received a compile-time error at least for unused variables.& & & & & & log.Printf(&could not remove closed %s, ticket count %d&, err.Error(), len(tickets))& & & & }& & }& & return // this will return 10 tickets o_O}具体在于:=缩略变量的声明与分配问题,一般来说如果在左边使用新变量时,才会编译:=,但如果左边出现其他新变量的话,也是有效的。在上例中,err是新变量,因为在函数返回的参数中已经声明过,你以为ticket会被自动覆盖。但事实并非如此,由于块区作用域的存在,在声明和分配新的ticket变量后,一旦块区闭合,其作用域就会丢失。为了解决这个问题,我们只需声明变量err位于块区之外,再用=来代替:=,优秀的编辑器(比如加入Go插件的Emacs或Sublime就能解决这个shadowing的问题)。func findTickets() (tickets []Ticket, countActive int64) { && & var err error& & tickets, countActive := db.GetTickets() // 10 tickets returned, 3 active& & if countActive & 0 {& & & & tickets, err = removeClosed() // 6 tickets left after removing closed& & & & if err != nil {& & & & & & log.Printf(&could not remove closed %s, ticket count %d&, err.Error(), len(tickets))& & & & }& & }& & return // this will return 6 tickets}8. 映射与随机崩溃在并发访问时,映射并不安全。我们曾出现过这个情况:将映射作为应用整个生命周期的应用级变量,在我们的应用中,这个映射是用来收集每个控制器统计数据的,当然在Go语言中每个http request都是自己的goroutine。你可以猜到下面会发生什么,实际上不同的goroutine会尝试同时访问映射,也可能是读取,也可能是写入,可能会造成panic而导致应用崩溃(我们在Ubuntu中使用了upstart脚本,在进程停止时重启应用,至少保证应用算是“在线”)。有趣的是:这种情况随机出现,在1.6版本之前,想要找出像这样出现panic的原因都有些费劲,因为堆栈转储包含所有运行状态下的goroutine,从而导致我们需要过滤大量的日志。在并发访问时,Go团队的确考虑过映射的安全性问题,但最终放弃了,因为在大多数情况下这种方式会造成非必要开销,在golang.org的FAQ中有这样的解释:& & 在经过长期讨论后,我们决定在使用映射时,一般不需从多个goroutine执行安全访问。在确实需要安全访问时,映射很可能属于已经同步过的较大数据架构或者计算。因此,如果要求所有映射操作需要互斥锁的话,会拖慢大多数程序,但效果寥寥无几。由于不经控制的映射访问会让程序崩溃,作出这个决定并不容易。我们的代码看起来就象这样:package statsvar Requests map[*revel.Controller]*RequestLog &var RequestLogs map[string]*PathLog &我们对其进行了修改,使用stdlib的同步数据包:在封装映射的结构中嵌入读取/写入互斥锁。我们为这个结构添加了一些helper:Add与Get方法:var Requests ConcurrentRequestLogMap// init is run for each package when the app first runsfunc init() { && & Requests = ConcurrentRequestLogMap{items: make(map[interface{}]*RequestLog)}}type ConcurrentRequestLogMap struct { && & sync.RWMutex // We embed the sync primitive, a reader/writer Mutex& & items map[interface{}]*RequestLog}func (m *ConcurrentRequestLogMap) Add(k interface{}, v *RequestLog) { && & m.Lock() // Here we can take a write lock& & m.items[k] = v& & m.Unlock()}func (m *ConcurrentRequestLogMap) Get(k interface{}) (*RequestLog, bool) { && & m.RLock() // And here we can take a read lock& & v, ok := m.items[k]& & m.RUnlock()& & return v, ok}现在再也不会崩溃了。9. Vendor的使用好吧,虽然难以启齿,但我们刚好犯了这个错误,罪责重大——在将代码部署到生产环境时,我们居然没有使用vendor。简单解释一下,在Go语言中,我们通过从项目根目录下运行go get ./...来获得依赖, 每个依赖都需要从主服务器的HEAD上拉取,很显然这种情况非常糟糕,除非在$GOPATH的服务器上保存依赖的准确版本,并且一直不做更新(也不重新构建或运行新的服务器),如果更改无可回避,你会对生产环境中运行的代码失去控制。在Go 1.4版本中,我们使用了Godeps及其GOPATH来执行vendor;在1.5版本中,我们使用了GO15VENDOREXPERIMENT环境变量;到了1.6版本,终于不需要工具了——项目根目录下的/vendor可以自动识别为依赖的存放位置。你可以在不同的vendor工具中选择一个来追踪版本号,让依赖的添加与更新更为简单(移除.git,更新清单等)。所获良多,但学无止境上面仅仅列出了我们初期所犯错误与所获心得的一小部分。我们只是由5名开发者组成的小团队,创建了Teamwork Desk,尽管去年我们在Go语言方面所获良多,但还有大批的优秀功能蜂拥而至。今年我们会出席各种关于Go语言的大会,包括在丹佛举行的GopherCon大会;另外我还在Cork的当地开发者聚会上就Go的使用进行了讨论。我们会继续发布Go语言相关的开源工具,并致力于回馈现有的库。目前我们已经适当提供了一些小型项目(参见列表),所发的Pull Request也被Stripe、Revel以及一些其他的开源Go项目所采纳。CSDN大数据(csdnbigdata) 
 文章为作者独立观点,不代表大不六文章网立场
的最新文章
日-20日,由CSDN重磅打造的SDCC 2016中国软件开发者大会将在北京举行,高吞吐数据库架构专题讲师议题火热发布,先睹为快。从阿里巴巴董事局主席马云提出的电子商务将消失,新五通一平将引领未来,到王坚博士带来的飞天进化,再到让人眼花缭乱的新品发布以及数不尽的战略合作发布,拨开纷繁复杂的表象,我们不难得出,互联网、数据和计算的聚变催生的计算经济时代已经到来。每隔三十秒就会有位置数据返回,包括来自于司机和乘客应用的各类数据,需要实时使用的实时数据非常之多,那么Uber是如何存储这些位置数据的呢?Uber的解决方案非常全面:他们在Mesos顶层构建了自己的系统,运行Cassandra。使用PostgreSQL提供的skip locked 或者advisory lock特性,消除行锁冲突,提高并行度,从而提高更新效率,发挥机器的最大能力。仅在8台虚拟机上,就实现了原本需要100台虚拟机才能实现的工作。卷积神经网络是一种主流的深度学习模型,它可以用神经网络模型来处理序列化的数据,比如文本、音频和视频数据。它能把一个序列浓缩为抽象的理解,以此来表示这个序列,乃至新产生一个序列。PostgreSQL9.6在前些日子发布了, 社区为该版本的重大更新付诸良多, 发布日志一如既往的长,我挑选了6个重要的更新, 这些或许能够帮助你更好的使用PostgreSQL。Hugo是一个制作静态页面的工具,非常灵活,可以以多种形式工作,是制作博客、文档、个人履历等非常合适的工具。Hugo激发了创造力,让建造网页变得充满乐趣。如果我的网络模型效果不好,我该怎么办?
通常我的回答是“具体原因我不清楚,但我有一些想法可以试试”。
然后我会列举一些我认为能够提升性能的方法。Spark 是一个通用,快速,适用于大规模数据的处理引擎。他开发GoChat时就是一个MVP,压根没考虑扩展性的事,因为他从来没想过这么短时间就有这么多用户。日-23日,由CSDN重磅打造的大数据核心技术与实战峰会、互联网应用架构实战峰会将在杭州举行。种种好处让跨平台开发风头无量,数以万计开发者在实践中找寻“最趁手”的跨平台开发解决方案。对于开发者而言,如何做跨平台开发工具选型?如何透过良好的设计实现大部分代码都可复用,并实现服务器端动态更新?如何解决自定义 UI、API 扩展性等问题?如果细细体会如今的 IT 现状,是牵一发而动全身,还是一马平川,发展趋势几何,都是规划 IT 投入时不可回避的话题。我分享的题目是《蘑菇街实时计算平台实践》,分享的内容包括,实时计算技术选型,平台建设和数据治理相关话题的实践经验。计算机视觉是一门研究如何使机器“会看”的科学。在发展了50多年后的今天,本文介绍最近让计算机拥有“无中生有”能力的五个有趣尝试。日-23日,由CSDN重磅打造的大数据&架构实战峰会在杭州隆重举行。在第一天的大数据核心技术与实战峰会上,由来自唯品会、小米、蘑菇街、饿了么、有赞、游族、echo、In、万达的资深专家分享了各自在大数据领域丰富的实战经验。日-20日,由CSDN重磅打造的年终技术盛会,SDCC 2016中国软件开发者大会将在北京举行。Julia编程语言闯入前五十名。9月5日~18日是八折优惠票价阶段,5人以上团购或者购买两场峰会通票更有特惠。中国移动从最初基于OpenNebula研发移动“大云”到2013年开始转而基于OpenStack,对于中国移动这样体量如此巨大的企业来说,背后有着怎样的勇气和壮士断腕的决心?日-23日,由CSDN重磅打造的SDCC 2016大数据技术&架构实战峰会(杭州站)将在杭州举行。大会前夕,网易云计算架构师尧飘海接受了CSDN专访,谈及了对架构的理解、Docker的使用经验和微服务的案例等。我们见过用黏菌、肥皂膜、水滴计算,甚至用10000台Domino服务机来计算。如今,DNA可以在试管内做加减乘除的数学计算了。Docker的火热,催生了人们对于其商业模式的探讨,虽然目前Docker还有很多有待完善之处,但这并不妨碍人们对于Docker的追捧,对其商业模式的探讨,将有力促进Docker的健康发展。每一年都有诸多大大小小的技术峰会,你如何给一场会议评价是一件比较难的事情,每个人看到的都是不同的,而为了让用户有更多的甄选信息,特邀请一些演讲嘉宾、行业的参会大牛分享他们的看法,或许可以管中窥豹看到一些不同。大数据时代,数据已成为公司最有价值的资产之一,因此,设计、实现和维护好数据库,对公司是至关重要的。要想提供适用于酒店行业的软件解决方案,必须建立起与PMS供应商的双向集成系统。其中的挑战在于:我们需要大规模构建与管理这些联网的内容,并应对涉及多家酒店、多个PMS系统的情况。本文将会介绍一个用于集成系统基础构建的简单架构设计方法。大家的月薪是多少?在近一年增长幅度是多少?是否有跳槽计划?会选择什么类型的公司?什么开发语言使用最多?现在哪本文面向程序员,通过Image Caption Generation,一个有意思的具体任务,深入浅出地介绍深度学习的知识,涉及到很多深度学习流行的模型,如CNN,RNN/LSTM,Attention等。为了让报名者以及感兴趣者深入了解SDCC 2016大数据&架构峰会·杭州站,我们特别整理了以往所有的信息和资料,以及近期会放出的大招。为你总结,参加SDCC 2016大数据&架构峰会·杭州站的七大理由。本文是关于Flume成功应用Kafka的研究案例,深入剖析它是如何将RDBMS实时数据流导入到HDFS的Hive表中。人工智能总体还处于初级阶段,作为一个关键的技术,它会影响一个国家的格局甚至国家的国际竞争力,要以推进“互联网+”和“中国制造2025”战略为契机,加快相关规划与政策的落地,释放出能力,最终走出一条具有中国特色的人工智能强国之路。代码审查是指阅读代码来检查源代码与编码标准的符合性以及代码质量的活动。目前,网上有大量的框架供大家选择,本文作者分享了9款各方面都兼具优势的PHP框架,主要用来构建响应式网站,开发人员可以根据自己的需求来选择下面的某一个框架。发现问题,解决问题,是运维永恒不变的两个主题。而如何发现问题,是其中的难点和重点。运维收集的数据可能数以百万计,如何从其中快速、准确的发现问题?身为开发者,你是否曾意识到,只需要对应用做些许改进,就能令超过一亿人的庞大残障群体也能成为新用户?日-23日,由CSDN重磅打造的SDCC 2016大数据技术&架构实战峰会(杭州站)将在杭州举行。大会前夕,京东商城架构师杨超接受了CSDN专访,谈及了对架构的理解、京东现有的电商特点,以及如何支撑高流量和高并发之道。哪些组织机构是Github最具有影响力的,本文使用gh-impact工具评估得出了如下TOP 10名单前三名分别是:Google、Facebook、Apache。每天,全世界几百万的用户都在Twitter上搜索着发生的新鲜事。在重大事件期间,比如刚刚过去不久的2016欧本文将介绍一些在Visual Studio(免费下载)中很实用却被忽略的小技巧。Spark2.0中引入了SparkSession的概念,它为用户提供了一个统一的切入点来使用Spark的各项功能,用户不但可以使用DataFrame和Dataset的各种API,学习Spark的难度也会大大降低。大会前夕,“机器学习的明天”联席主席、滴滴研究院副院长叶杰平接受CSDN记者专访,介绍了机器学习对人们出行的影响——滴滴出行正在借助机器学习和大数据解决其智能调度和供需预测的难题,让司机和用户更加满意。在CCAI 2016大会,Tomaso Poggio的主题报告除了总结智能工程的进展,还将诠释MIT CBMM的智能科学研究——机器学习、计算机科学、神经科学与认知科学的融合。CSDN技术主题月是由CSDN社区主办的线下技术交流活动,旨在和国内技术领先的企业共同围绕行业趋势和话题进行解决方案的探讨、分享和交流。在技术开放的氛围下,希望开发者们能够通过CSDN社区平台结识更多技术达人,交流&分享技术观点。由中国人工智能学会发起主办、中国科学院自动化研究所与CSDN共同承办的2016中国人工智能大会(CCAI 2016)将于8月26-27日在北京召开。目前所有的讲师议题和大会日程均已公布。gRPC是一个高性能、开源、通用的RPC框架,面向移动和HTTP/2设计,是由谷歌发布的首款基于Protoc本文为用户使用Apache NiFi最新版本来监听SMTP邮件,并以编程方式做出反应以及捕捉数据提供了指导。往期50+干货Slides网盘全下载,没谁了。MDCC 2016 移动开发者大会将于 9 月 23 - 24 日在北京 · 国家会议中心隆重举行。主办方携五大技术专场和五大技术峰会出品人,为大会的嘉宾及内容质量进行严格的审核,现正式公布已经确定的演讲人与议题,让我们逐一为各位揭晓。老牌C语言颓势明显,其地位尴尬有多方面原因。csdnbigdataCSDN分享Hadoop、Spark、NoSQL/NewSQL、HBase、Impala、内存计算、流计算、机器学习和智能算法等相关大数据观点,提供云计算和大数据技术、平台、实践和产业信息等服务。热门文章最新文章csdnbigdataCSDN分享Hadoop、Spark、NoSQL/NewSQL、HBase、Impala、内存计算、流计算、机器学习和智能算法等相关大数据观点,提供云计算和大数据技术、平台、实践和产业信息等服务。

我要回帖

更多关于 麻将游戏整体需求书 的文章

 

随机推荐