导读:Java很难再做出更多的改变了,那么它会被替代吗?它的替代者是谁?
Bruce Eckel为什么最喜欢Python,Python究竟好在哪?
Kotlin是怎样为程序员提高效率的?
大龄程序员应如何规划自己的未来?
在本文中,Bruce Eckel将给你这些问题的答案。
这两天,Bruce Eckel来到中国,这是他的中国首秀。5月22日,Bruce Eckel发表了他的最新演讲,与在场的1000多人分享关于编程语言的一些思考,并讲解了Kotlin的一些优势。本文将送上完整演讲稿,希望能让你开脑洞、涨姿势!
大数据(ID:hzdashuju)小编也追到了这位大神,大神说了一句话,并向你扔了一张二维码!
▲戳视频看会动的大神
Bruce Eckel是MindView公司的总裁,该公司向客户提供软件咨询和培训。他是C++标准委员会拥有表决权的成员之一,拥有应用物理学学士和计算机工程硕士学位。从1984年至今,他已经发表了超过150篇计算机技术文章,出版了6本书。他的《C++编程思想》一本书在1995年被评为“最佳软件开发图书”,《Java编程思想》被评为1999年Java World“最受读者欢迎图书”,并且赢得了编辑首选图书奖。这两本书的英文影印版及中文版均已由机械工业出版社引进出版。
▲大神的签名也是萌翻了
接下来就是演讲全文:
01 Kotlin是怎样为你提高效率和生产力的
大家经常会问我,Java之后的继承人会是哪一门语言?我给出的答案可能是带有偏见的,因为我在写这本关于Kotlin的书《Atomic Kotlin》,所以从我的个人想法来看,Kotlin将会成为Java的下一个继承人。这就是今天为什么我来分享这本书。
这个就是这本书的封面,我和Svetlana Isakova共同写了这本书。
因为Svetlana本身是JetBrain这个组织里面的一个负责人,她负责测试很多的功能,所以她能够保证这本书里面的内容都是非常准确的。这本书最后的出版大概会在今年秋天,和关于Kotlin的一个在阿姆斯特丹的大会同时进行。
今天主要是给大家讲一讲我这个书里面的几个例子,主要是给大家一个整体的对这门语言的感觉。Kotlin这种语言是基于对象和函数混合的这样一种语言,它跟Scala很像,但是Scala更多是一种实验性的语言。Kotlin侧重于可供生产使用,能够让大家编程的整体体验感觉更好。
大家可以发现,Kotlin这种语言它是有修饰函数,然后它的标识符是在fun这个函数后面,后面会紧跟着一个冒号。这个方法首先是从fun这个关键词开始,接下来是这个函数的名称,然后是它的参数、冒号,以及这个参数的类型,冒号之后是这个方法返回值的类型。
大家看第二个函数,我觉得这种风格的编程方法可能是来自于Scala,首先是fun这个关键词,然后是函数名,接下来你用一个等号表达这个函数的具体内容。这是我们第一次看到这种类型推测,和第一个方法进行对比,这个函数没有返回值的具体类型,编译器在看到这个方法具体构造的时候就能够知道这个返回值是一个String的类型。这个地方大家可以注意到,这是和Java很不一样的一点,就是我们不需要一定有一个类,这个地方我们只要确定一个方法,然后把它带的参数全部列出来,然后我们就可以进行运行了,不需要一个类去包裹它。
大家可以观察到,print的方法也会变得简单了很多,大家不用再打“System.out.println()”,这个地方很简单的用println()就可以打印出来。刚才那个PPT里面也提到了Java的泛型,Kotlin泛型,但是它会比Java的更简单,我今天不会给更多具体的细节,但是大家可以自己去学习一下。
接下来是一个for循环的例子,不像Java会写很多的参数和条件在for loop里面,写出1..10 就可以循环从1到10的所有整数,这个让我想起类似Python的这样一个风格。Print这个语句大家可以看到它是冒号里面有一个$,这样会把for loop里面具体的数一个一个写入String里面去,这个让我想到了Python最新的版本3.7是如何处理String这种类型的。
大家不要忘记,今天讲授的例子都来自于这本书,这本书里面我们创造的一个库,是专门负责测试的库,就是atomictest.eq,通过简单的一个命令行就可以对你的代码进行测试。Listof()这个方法创造了一个list,大家看一下,这个地方我们没有对list这个变量的类型做出任何的说明。
在Kotlin里面一共有两种变量,一种叫做val,一种是var。现在我们看到的这个是val,这种是不可变的标识符。另外一种var是可变的标识符,我们可以对它进行重新赋值。在大多数情况下,我们会使用val这种不可变的变量,这也是函数类编程的一个基础思想。这个地方list我们没有给它任何具体的类型,编译器能够推测它的类型是什么,在大多数情况下我们都是可以这样去做的,不用告诉他类型是什么,有一种例外就是在方法带的参数里面我们这个地方是要标示出它的类型的。
lst[1],这是一种创造索引的方法,在这个时候我们对“1”,就是1号这个元素进行了索引,然后通过eq这个测试方法测试它是否等于88.3。这种方法也是Kotlin作为DSL一个非常好的语言的一种展示方法。
接下来大家可以看到也是这种函数类编程的一种自己特有的方式,lst.reversed(),还有lst.sorted()这两种其实并不会对原来的list进行修改,它会创造两个新的list。这也就是为什么函数类编程是比较安全的一种方式,我们尽量的不要去修改原来的数据结构。这个是我们在编程当中经常会遇到的一个问题,就是当一个对象是在被共享的时候它的状态发生改变的时候我们是比较难控制的,所以我们希望尽量不要去修改原来的变量。Reversed(), sorted()这两个方法创造了两个新的list,还想再强调一遍。同时,大家看到的这五种方法,比如,max、main、sum等都是Kotlin的标准库里面给大家提供的方法,大大家不需要自己再重新写了。
类的写法也被大大的简化了,现在看到的class NoBody后面没有跟着大括号,里面也没有具体的内容,这是一种很像Python的写法,这也是Kotlin自己的一个理念,就是说如果你不需要做这样的事情,它不会强制你去做。
大家可能也注意到了,Kotlin不要求大家打分号,这是我不太喜欢Java的一点,就是Java本可以也不用写分号的,我认为这是Java语言的创造者偷懒,所以导致我们现在必须要多打一个分号。我本人是很讨厌让我去做本可以去省略的一些事情的。
这个类SomeBody它的内容就是它的构造器,就是它的构造函数。在这个构造函数当中,创建了一个属性,就是name,在这个地方再一次的就是我们没有去给它一个类型,而是通过类型推测来知道它是一个String。
第三个class EveryBody,这个地方的时候就是我们创建了一个list,里面包含了三个SomeBody这个类,大家可以注意到,这个时候我们在构造一个新的SomeBody的时候没有用像类似Java一样的关键词new。大家就会注意到Kotlin这种语言,它的很多的细节都是从其他的语言中获取灵感的,它其实是集很多语言的优点于一身。
Badger这个类大家可以看到它必须强制的带两个参数,一个是id String类型,一个是age,是一个Int的类型,就是Kotlin你在构造函数里面的时候必须要说明它的类型是怎么样的,因为编译器是无法推测出你这个带的参数的类型是什么样的。所以,这是一个非常特别的一个地方。
这边我们创建了两个属性,一个是name,一个age,它们两个的赋值来自于构造函数的参数。接下来可以看到我们这边有一个是override的方法,叫toString,这个跟Java的toString是一样的,这是Kotlin的一个特点,就是它其实希望能够跟Java非常紧密的结合,非常紧密的能够互通的。在Kotlin的时候如果我们想要去override一个方法的时候,我们是必须要加上这个关键词的,要不然这个编译器会报错。
这是另外一个类,叫Snake,它也有自己的变量和override的一个方法,大家看它和上一个Badger之间的区别就在于Badger的构造函数里面带了两个参数,但是Snake这个构造函数里面用到了var这种变量。
还有一点不同的就是在Badger里面的时候我们是必须要明确的写出来,明确的定义刚才的两个,那个里面的var、val,然后在Snake里面我们不需要把它明确的定义出来,但是在toString的方法里面也可以调用到它,因为它是属于Snake这个类里面自己的变量。
所以说,这边如果大家想做出类似的改变,最关键的是要把刚才构造函数里面的那个参数拿出来,然后做出声明,说这是一个var的类型。这是一个我们在构造函数里面遇到val的一个例子,我希望大家能够知道Kotlin这种语言的魅力就在于它极大的简化了工程师的工作量,并且能够减少工程师阅读其他工程师代码时的痛苦。这边在main方法里面我们创造了三个对象,Badger、Snake和Moose,然后调用eq这个测试方法测试它们的值,在这里面其实toString这个方法也是被默认的调用了。
这是又一个类,叫JetPack,这个例子里面主要想为大家展示Kotlin也是支持Private、public和protected这三种访问符,你默认的情况下,如果你不做任何声明它是一个public的变量,但是你也可以说明它是一个private或者protected。
在这里if被用作一个表达式,这个方法check()通过一个等号来调用这个表达式,最后的结果就是如果是“是”就是warning,如果是“否”,就是OK这样结果。
我想再重申一下,Kotlin从它诞生的那个时候我们就希望它是能够非常紧密的和Java能够结合在一起的。所以,你可以创造这样的一个Kotlin的类,但是从Java的代码当中调用这个类,同样的你也可以在Kotlin的代码中调用Java的类。这样做的原因是,我们希望使用Java的编程人员能够从他们代码的很小的地方开始试一试Kotlin,从一些小的地方进行修改,这样不需要大费周章的把整个代码全部改成Kotlin这种语言。
在这个例子当中,我想说明的是关于泛型这样的一个例子。大家可以看到,numbers、strings之后都有一个冒号,会有一个它们具体的类型,你在做Kotlin编程的时候可能会遇到你不得不,或者你希望去说明它的类型是怎么样的,有时候你不得不去说明,因为你不说明Kotlin,就会给你提示你是错误的。
Kotlin也支持可变参数这种类型,它通过这个关键字vararg来支持。在这个函数里面,“s”是一个string,“ints”它是可能有多个int组成的这样一个变量。在这个例子当中,ints就是一个数组,我们可以用for loop,然后说in这个数组,然后把数组里的每一个进行循环调用,然后把它打印出来。下面这个main函数就是调用了上面的这个vararg这个方法,你可以看到我在后面打了多个质数。
在这个例子当中,我是想给大家看一下这三个引号这种写法,三个引号帮我圈起来文本的区块,在这种写法当中,比如说像换行之类的,或者单引号之类的,都会被这个写法照顾到。我非常确定这种功能,这种写法是来自Python的,因为我只在Python见过这样的写法。
接下来我们调用了split这个方法,然后在里面代入了一个正则表达式,这个regex正则表达式是直接来自于Java的库。大家都很熟,这个正则表达式我们是在寻找一个或多个空格,然后通过一个或多个空格把上面的这个String进行分隔。而这个最后返回的结果可以是一个list,也可能是一个数组,比如这个数组的情况下,接下来我们调用sort的这个方法把它进行排序。
接下来大家可以看到一些Kotlin自带的一些方法,比如说,我们刚才把这个颜色colors这个数组进行排序,排序之后我们可以调用toSet这个方法,把它变成一个集,然后下一个操作是减去所有里面空白的格。
接下来我们可以把两个iSet加在一起,这边应该它已经变成了一个集,所以我们可以这样去做,这个也是很好的去解释Kotlin的一个特性,就是它能够重载一个运算符。这个“+”和上面这个“-”都是重载运算符的一个例子,因为它已经是一个Set,一个集合,所以iSet+iSet最后的结果还是等于iSet,所以这两行打印出来的结果应该是一样的。color.toSet这个方法创造了一个不可变的Set,MutableSet的Set。
接下来我们可以调用ToMutableSet这个方法,重新创造一个新的Mutable可变的一个集。接下来我这边又是有一个运算符的重载,就是“+=”,这个时候我们把color这个数组切割,让它从第3到第5这样序列的三个字符,然后加到mSet这个可变的集合当中。
接下来给大家展示的是如何能够确认一个词语是在一个集合当中,有两种方法,一种是用in,或者是用“.contains”这种方法能够确认。大家可以看出来,第一种方法,in iSet会比第二种读起来更好读,这也是为什么我觉得Kotlin是一种很好的作为DSL的一个语言。
在这边我做了一个例子,创建了一个map,大家可以看到to,这个to不是一个关键字,是一个Kotlin作为DSL这种方式创造的一种方法,这边我把一个string和一个Int的映射关系存入map当中。理所当然,我们也可以看到,我们可以把它的一个key放进去,看它的值是多少,或者把它所有的key全部列出来,或者把它所有的值全部列出来。
接下来我把这一个map里面的每一个Entry对象循环一遍,Entry是作为一个类定义出来的,然后我把每一个打印出来,Entry这个类有两个自带的变量,一个是key,一个是value。我还想再给大家看一下,在这个for循环里面,我们没有说Entry包含的值是什么类型的,编译器在这个时候它能够知道你现在是在每一个的检验map里面的这个值。所以,它会给你自己去推测它的类型。
接下来我给大家看一下这种Data class,Data class是来自于Scala,但是在Python的3.7版本中我也见到了类似的这种表达方法。在Scala里这种表达方法叫做case class,case类。
这个Data class主要的好处是在于它帮你创造了,一般在Java上一个类的时候里面自带的一些比较琐碎的方法,比如,getter、setter这样的方法,它都帮你自动创建了,并且能够帮你把它们都写对。因为我把“i”这个变量声明成var这种方法,所以我可以对它进行重新赋值,我现在把它的Data.i的赋值是20。Data class帮你创建了比如像hashcode、 toString、getter、setter这样的方法,就是避免你忘记写这些方法导致运行错误。
还有一个就是Kotlin做的很好的是关于getter和setter的方法,这个其实是Java被诟病很长时间的,但是一直大家也没有解决的一件事情。Kotlin的做法就是可以先声明一个var这样的类型,紧接着你可以写一个get或者一个set,或者两个都写,当每次你去读写这个变量时,get或者set方法会被自动执行。
Field是Kotlin里面一个特殊的提示符,在这个情况下,如果把“i”这个变量改名字了,叫做“j”或者其他的什么,但是你并不需要改变Field,因为它能够通过Field这个特殊的关键词,能够对这个类的变量,这个“i”进行修改。当大家看到这个方法的时候,我们创建了一个GettersAndSetter这个类,我们现在要调用“gs.i”,这是一个Set的方法,或者我们做一个Println(gs.i), 这是一个get的方法,因为大家可以看到,刚才get() 和set里面都有打印,所以,在我们在做这两行操作的时候,那两个方法都会被调用,然后我们也会看到相应的打印。
今天给大家展示的只是Kotlin的冰山一角,其实还有非常多的内容。我其实是希望大家通过今天的这个展示能够了解Kotlin语言背后的原理,希望大家作为编程人员能够编的更顺、编的更快。
在我这本书《Atomic Kotlin》里面有非常多这样的例子,为什么我叫做Atomic Kotlin(原子Kotlin)呢?就是我们希望把每个章节都编的足够小,不能再被拆分了,里面包含这样的小例子,让大家最快的学习到这种语言。我们管这本书里面的每个章节都叫一个原子。我希望今天的这个演讲以及这本书能够吸引你们去渐渐的尝试使用Kotlin。
02 关于Kotlin的现场问答:为什么Kotlin比Java更好?
Q1:我是一个Android开发者,我平时发现Java需要通过jvm生成Native代码跟底层进行交互,我之前看过Kotlin可以直接编程二进制码,可以绕过JVM这一步,我想知道更多这样的细节。
Bruce Eckel:在Android上编程的同学可能都有了解,Google从去年开始把Kotlin作为Android编程的第二个语言,但其实我个人认为,相对于Java来讲,Google更希望用Kotlin作为他首要的Android的编程的语言。我个人来讲,其实并不是希望对JetBrain这个组织的动态做出发言,我更多希望大家去了解Kotlin的这门语言。
我可能不会把所有细节都讲的很正确,我现在理解,一共有两件事情正在发生,第一件事情就是我觉得Google正在推广关于native code的生成。第二件事情就是希望能够通过单一源的代码能够生成native code,能够给iOS和Android的同事使用。在这个过程中会遇到非常多的困难,因为需要做非常大的抽象才能把这个代码给两个平台都同时使用,有一些可能就无法完成,但大多数的应用都是能够实现这样的一个单一源代码。
同时,我觉得Google那边也是在致力于用单一源代码提供给更多的平台,我不知道这件事情什么时候会发生,或者怎么发生,但是我非常期待这件事情。
Q2:我是读您的书长大的,这本书之前是C++编程思想和Java编程思想,我觉得最重要的不仅是语言的本身,可能还是背后的十多年前的这种面向对象的东西。所以,您的那本书是Kotlin语言的本身,未来您对于设计的这种方面,比如说,现在微服务比较火,关于这方面您有什么样的想法?
Bruce Eckel:我非常感谢这个问题,但是我打算先把这本书好好写好。我现在还不想想的那么远,因为这本书已经完全占据我的头脑。但是,你的这个想法非常好。
Q3:我想问的问题就是刚才您说过您的语言Kotlin,里面涉及到我们写的编程的class类,class类里面涉及到之前Java一直垢病的一个Setter和Getter方法,您这边简化了一个方式,不用考虑是是set还是get,我们直接复制,让编程直接执行set和get获取到我们所需要的结果。我想知道的是,当您决定了您这个编程想法,您怎么会觉得您是否失去了这个效率,而获得了更好的体验,是什么让你觉得您的选择是正确的?
Bruce Eckel:我刚才的这个例子只是非常初步的展示了Kotlin的语法。我认为,这样做的好处主要有两个原因:第一个原因,因为当大家做getter、setter这个方法的时候其实只是想访问类里面的一个值,并不是想调用一个方法。第二,我做这样一个语法设计的时候写起来会简便很多,方便很多,这是最主要的原因,我希望大家自己更多的去探索。
Q4:Kotlin我也看过一些,也写过一些代码,因为我写Java已经写了13年。所以,处理问题的时候也是用这种Java的思维这样去写代码。然后,我会发现自己写出来的代码虽然是用Kotlin来写,但是它的风格仍然是Java style,我想了解的是怎么才能写出具有Kotlin style这样的风格的代码,怎么能够用Kotlin的思维去处理我的问题,去分解我的问题。
Bruce Eckel:当大家刚从C转换到C++这种语言的时候大家也面临过类似的问题,虽然在写C++还是C的风格。我其实会建议你多去学习和了解函数式编程,因为Java强调的是面向对象的编程,我们会非常熟悉面向对象的这种思考方式。但是,函数式的编程如果我们更多的了解它,会以它的这种方式去思考。我在写这本书之前,写了关于Scala的这本书,Scala是一门函数式编程的这样一种语言,同样还有类似像Elm这样的编程语言,我在做这件事情的过程中,通过几年的学习渐渐的理解了函数式编程这样的内涵。如果你认为主要是面向函数式编程这样的风格困扰着你,那就是应该你着重去学习的部分。
Q5:Java是企业级开发比较好的一个选择,我就想知道如果我们选择Kotlin能比Java带来哪些优势?
Bruce Eckel:首先,这是一个非常大的问题。其实我这本书的主要目的也是为了回答你这样的问题,就是为什么Kotlin会比Java更好。我其实建议大家在读书的过程中自己去寻找这个答案,一边读就会灵光一现,突然想到这个原来就是Kotlin比Java更好的原因。比如说你能写出更简洁的代码,或者效率更高,或者你的代码更容易被大家懂,这是我希望大家在学习这个语言当中自己去摸索,自己去体验的。
Q6:考虑到刚才那个问题我延伸一下,Java现在团队开发的话,如果换到Kotlin,看单个的代码会容易理解一些,但是对于从系统设计的这个层面来讲,还会那么简洁吗?
Bruce Eckel:首先Kotlin这个语言的发明就是为了简化工作量,我自己其实并没有真的实际做这样的一个大的工程,所以我无法具有权威性的去说这个东西一定就是好的。但是,我认为,这个语言因为它的来源就是希望帮大家简化工作量,所以我认为应该是没有问题的。很多编程语言我希望最终解决的问题就是如何把你的项目能够越做越大,能有延展性。Kotlin这个语言从其他编程语言当中吸收了很多的精华,其实就是希望能够解决这样的问题。
03 应该如何关爱大龄程序员?Python到底有什么好?
Q1:Java未来的趋势是什么?它会如何演变?会被替代吗?如果会的话,将发生于何时,谁又是它的继承人呢?
Bruce Eckel:在Java 8里面已经发生很多改变,Java 8进行了一些改造,如果你要学习Java 8,还是有很多困难需要面对。Java8、Java9、Java10也都会在后面的几个月中进行一些探讨。我在新书里面对Java9、Java10会做更多的阐述。但是我的理解是,Java是很难再被改变的更多了。当我在写《Atomic Scala》(原子Scala)这本书的时候,我觉得Scala有可能会成为Java的一个继承人,但是我不是特别的确定。但是我在Kotlin出来之后,觉得Kotlin可能会比Scala更有希望去替代Java。我们都知道Java语言有很多的惰性,有很多难以改变的东西,但是Kotlin的出现就可以跟Java进行一个无缝的切换和整合。Kotlin现在正在悄悄的溜进一些Java的工程,会使Java开发变得更快。
Q2:现代技术发展的如此迅速,请问Bruce Eckel是如何保持不断更新自己的技术库呢?
Bruce Eckel:因为我用互联网。我自己去参加很多会议,然后我自己也会举办会议,我也会举办一些开发者的活动,邀请可以容纳到我客厅的一些人数来一起探讨最新的进展。我现在更多的使用线上视频来跟会,因为很多会议的演讲都会被放到网上去,我发现这种方式比我自己亲自到会议现场参加更好。举个例子,我刚从一个Python国际会议上过来,我并没有参加每一个单独的话题讨论,我只是参加了开场仪式。
我觉得在语言方面,我更多关心的议题是:第一,如何让开发者更多产。我自己更关心的是,第一,多产。第二,多线程的问题。第三,错误,如何发现跟错误相关的一些议题。(关于这个主题详细探讨,请戳Bruce Eckel最新演讲:调bug就是浪费生命!放弃吧!)我并不能全面的跟随所有科技,你知道这样做是不实际的。
Q3:请问Bruce Eckel对大龄程序员有什么职业建议?
Bruce Eckel:自己开公司。不管怎么样都是需要不断的去学习,无论是初级还是高级程序员。有一段时间我会特别的痛苦特别的挣扎,我会觉得自己做不了或学不下去,但是我同时脑子里也会不停的告诉自己,一定坚持学习。有时候我觉得可能真的是已经年纪大了,或者可能真的已经不够聪明了。但是,无论如何我脑子里的声音都在支持自己不断的学习,坚持下去。
Q4:请Bruce Eckel介绍一下您在不同场景下选择不同编程语言的动因,比如Java、Scala、Python等。
Bruce Eckel:坦白来讲,我最喜欢的语言是Python。因为基本来说,每当我有问题需要被解决的时候我发现Python是最快可以给我结果的一个语言,所以我很喜欢,很享受Python。当然,现在情况发生了一点改变,我觉得Kotlin是一门非常好的语言,所以现在Kotlin是我的第二喜欢的。我已经可以想像出来一个画面,我用Kotlin写一些我的项目,但是目前只是一个想象的东西。底线就是每当我有问题,我觉得需要被解决的时候,我第一个想到的就是Python。除此之外,从Python社区发展开始,我就在他们的官方会议上有过两次的笔记分享,我觉得我对于Python在方向上的把控上是有一定的影响力的,而且我发现Python的社区是我见过的,我觉得这个世界上最友善的社区。
但是,回到之前说的那个话题,我觉得语言方面我最关注的是多产这一个方向。所以,我觉得我在任何一个语言里都学到了很多东西。每一种语言都有它的优势和劣势。虽然我自己偏好于Python,但是我并不建议每个人都去用Python,我更多的是建议每个开发者都找到合适自己解决问题的那个语言,不要固定或者局限于某一种语言,我发现当我去学其他的语言的时候,我对于编程的能力也是在不断的扩展的。
Q5:我刚才听到Bruce Eckel说您对Python比较喜欢,第二喜欢是Kotlin,Python在机器学习和AI方面有很多的用处,比如说Python Machine Learning比较好,我想知道Kotlin在Machine Learning方面有什么优势,比Python更好一些。
Bruce Eckel:Scala里面有一个关于机器学习的一个库,我觉得Kotlin有可能也会有类似的这样的一些库。我主要解释一下为什么Python会作为机器学习非常好的一种语言,因为Python把其他语言做了一个封装,调用其他语言做的包。很多的数据科学家他们其实是不希望学习过于复杂的编程语言,能够把他们关于数据方面处理的智慧进行封装起来,通过Python来调用这样会方便很多,这也是为什么Python这几年这么流行的原因。
04 《Atomic Kotlin》的中文版哪里有?
5月24日,Bruce Eckel来到机械工业出版社,商讨《Atomic Kotlin》等新书出版事宜。Bruce Eckel最新著作的中文版已经在路上,各位就等待查收吧!
关注“大数据”(ID:hzdashuju)并在后台回复Kotlin,可下载完整版PPT
关注“大数据”(ID:hzdashuju)并在后台回复20,可参与寻找"黑皮书"活动,领取当当购书券
点击阅读原文,可查看&购买Bruce Eckel著作《Java编程思想》
推荐阅读
Bruce Eckel最新演讲:调bug就是浪费生命!放弃吧!(附完整PPT)
最全Python数据工具箱:标准库、第三方库和外部工具都在这里了
用《复联3》的豆瓣评分教会你正确使用条形图、饼图、漏斗模型
大数据没用?!张小龙:我们很少看统计数据!
Q: 你开始用Kotlin了吗?
欢迎留言与大家分享
觉得不错,请把这篇文章分享给你的朋友
转载 / 投稿请联系:[email protected]
更多精彩,请在后台点击“历史文章”查看
点击阅读原文,了解更多