
“有多少观众来参加您的Java演讲?” 这取决于Venkat是否同时在相邻的大厅里表演。”
这真是个笑话,有很多道理:在Java世界中,
Venkat Subramaniam是最著名的演讲者之一,他确实能够在会议中吸引其他观众的注意。 他一直不懈地在地球上移动,最近在50个不同的Java用户组之前的一年里,在他的50岁生日那天,他创造了令人印象深刻的记录。
当您的Java职业不是“坐在办公室”而是“不断搬家”时,感觉如何? Venkat对当前的Java问题有何看法? 在10月,他将到达圣彼得堡,因此,我们(
菲林 ,
olegchir )
对此进行了详细采访,从“飞机上的生活”开始,并介绍了初学者的提示,然后转向技术。
由于Venkat详细回答,因此篇幅很长。 如果您愿意,可以立即转到第二部分:

为了生命
-让我们从游览开始,在此期间,您访问了50个Java用户组,以前几乎没有人做过。 您的印象如何?-对我而言,最有趣的事情是,认识到在世界不同地区的不同文化中,尽管存在所有这些差异,但说不同语言的人通过编程作为一个连接线程而团结在一起。 当我们开始谈论编程时,事实证明我们每天面临的问题是相同的。 对我来说,这是一个了不起的发现-您可以在世界上任何一个机场遇到一位程序员,您肯定会找到共同的话题进行对话。 我可以无休止地列出我参与讨论地球另一端Java的案例。
因此,与这些小组的经验对我非常有用。 管理用户组非常困难……我不想说“工作”,因为它不起作用,但是您必须花费很多精力。 我非常尊敬每个月一次又一次地收集这些活动的所有领导人。 不同的小组有不同的动力-一些会议有20或30个人,其他会议有200或300。尽管如此,人数实际上并不起作用,因为主要是开发人员对参加这些会议的热情以及他们对会议的兴趣。技术及其学习欲望。 因此,我很幸运能有机会与这些小组见面,对此我感到非常感谢。
-和您提到的相似之处,世界不同地区的用户组是否存在明显的本地差异?-这些差异令人惊讶地很少。 我注意到,在某些地区,更偏重于重量级框架,而在另一些地区,则更偏重于轻量级解决方案。 但是,通常,所有这些特征都是肤浅的,而根深蒂固的问题和问题却是普遍的。 我诚挚地想告诉您,在地图上的某些时候,人们所做的事情与我们所做的完全不同,那里的一切都很有趣和意想不到,但我不能这么说。
我们都在为复杂性而努力,它使我们感到困惑,而当它受阻时,我们就开始与之抗争。 这是几乎所有地方的普遍趋势。 另一个没有人逃脱的重要问题是业务的严格要求和缺乏质量工作的时间。 我可以向世界各地的人们讲一些例子,在我讲完故事后,我会被问到:“您碰巧在我们公司工作吗?” 我们的问题是如此之深和普遍,以至于它们显然是全世界共同的问题。 这不由自主地使我们考虑了我们最终遵循的人类共同本质,心理学和哲学。 无论我们如何在极客转向技术时想象自己,我们都不应忘记软件开发中的人为因素。 显然,他是一支统一的普遍力量。
-我想问一下“露营”的生活方式。 当您坐在办公室里时,是否想要自己的生活可能并不明显。 例如,对于许多人来说,时差是一个问题,因此,持续飞行似乎是一场噩梦。 但是也许通过实践,您会适应吗?-要回答您的问题,让我们回顾一下持续集成。 如果一个团队每月执行一次集成,那么您建议他们一直这样做,他们会认为您很疯狂。 在这种情况下,旅行关系就像是持续集成和持续交付:如果您处理很多关系,那么您对待他们的方法就会改变。
不要误会我的意思,我不为自己的生活方式感到骄傲,我认为那样的生活不值得。 我总是说旅行最不喜欢旅行本身。 坐在飞机上很累,身体疲惫,而且随着年龄的增长,这些问题无处不在。 但是,当我到达目的地时,当我与其他开发人员会面时,我看到了他们对技术的热情和热情,我有机会分享这种热情,学习新知识并帮助学习,所有的困难都将得到回报。
如果我们谈论时区的变化,那么它根本不会打扰我。 由于飞行不断,从某种意义上讲,我没有固定的“返乡”时间。 我有一个规则:我总是在当地时间同一时间醒来,大约在晚上3.30,身体很快就会进入一定的节奏。 而且,当然,咖啡总是很受欢迎的。
-许多人希望看到这个世界,但他们通常是在旅游旅行中而不是在商务旅行中。 您是否可以看城市,或者由于时间紧迫而只能在会议室看?-是的,部分时间上有问题。 但是,除此之外,由于飞行不断,我有一些我要坚持的原则。 如果旅途与工作有关,那么我除了工作以外什么都不做。 我尝试将尽可能多的时间花在开发人员身上。 例如,当我在欧洲有免费的星期六或星期日时,通常会在一个用户组中度过。 与开发人员进行交流使我感到非常荣幸,因此在商务旅行中,我几乎从未去过感兴趣的地方。
但是,每年夏天,我都会与家人一起旅行四,六个星期,然后我们去观光。 这是我们共同休息的时间,在接下来的几个月中,我将重点放在工作上。
此外,我的方法使我能够最大程度地关注各种社区活动,这也使我感到非常高兴。 这会花费大量时间,并且是一种折衷方案,但它适合我。 生活有时压力太大,我很高兴有机会有时会分心并倾听可能没有机会参加会议或培训课程的开发人员。 另外,我相信这也是我的职业职责,因为正是这些因素激发了我的青春。 我访问了用户组,听了表演,并梦想自己也表演自己。 反过来,如果我设法以相同的方式激励至少一个人,那么这段时间将是值得的。
-最后的旅行问题。 乔治·克鲁尼(George Clooney)在电影《飞向空中》中不断在城市间飞行,他知道许多提高旅行效率的技巧:如何排队,如何打包行李等等。 也许您还想分享一些非显而易见的知识?“我很ham愧地承认这一点,但有时我会在联邦快递的各城市之间送衣服,因为我根本没有时间下班回家飞衣服。 通常,当我到达酒店时,我的衣服已经在那儿了,而当我离开时,我会将它们送回家。 幸运的是,当我连续三周去旅行时,这种情况不会经常发生,也许每年发生三到四次。 有一个尴尬的时刻,我的妻子不得不去机场把行李交给我,因为我之间只有两个半小时的飞行时间。 但是随着时间的流逝,您真正学会了更有效地做一些事情。 有时候当人们说“我需要打包”时,我会感到惊讶,因为我的东西一直都在收集。
说到效率,我至少有一个优势:我是一个非常专一的人。 我们生活在Facebook,Twitter和各种Messenger的世界中,他们不断分散我们的注意力。 我努力降低这种影响,因为几分钟变成几小时,几小时变成几天,几天变成几周,您迟早会意识到自己无法达到想要的目标。 通常,我有一本日记,其中记录了每次旅行需要做的事情。 因此,我有每天的时间表(例如,11月7日或10月8日),我的手机让我想起了当天的每个任务。 在一个八小时的飞行中,我可以写本书的大部分内容,或者为课程准备一个例子。 因此,对我而言,飞行是一个极为有效的时间。 在飞行过程中,我永远不需要其他娱乐活动,与代码调试相关的充足娱乐活动就足够了。 因此,专业旅行者(如果该术语通常适用)与旅行者在飞行时间上的花费大不相同。
-可能是因为您的名声,所以您收到的信件比普通开发人员多得多。 他们会写多少信给您,处理邮件需要多少时间?-值得补充的是,我在大学任教并收到许多学生的来信。 通常我每天会收到20或30个字母。 大约一年前,我在博客上
写了我的一项原则:“立即回答或在回答时说”。
我非常珍惜自己的时间,这意味着我珍惜他人的时间。 我认为,尊重他人并不是先生的诉求,而是互相欣赏的时间。 因此,如果收到一封信,我总是在24小时内回复。 但是有时无法给出完整的答案-例如,会议的组织者要求发送注释或行业内的同事询问有关解决特定问题的问题,要求重构某些代码或使用某种方法的问题。 有时答案可能需要十分钟,有时需要两个小时,但即使十分钟也不能总是花费。 听起来可能有些奇怪,但是在这种情况下,我仍然会在24小时内回复并写:我收到了您的来信,我将处理这个问题,例如9月2日,并写信给您3日。 同时,在我有飞行时间或下午的那天,我的日历会用相应的条目进行更新。
多亏了这种方法,我的收件箱总是空着的,我每天晚上睡前都要清理它。 因此,我在回答信件方面非常有纪律。 人们常常惊讶于我如此迅速地回复他们的来信,但相反,我不明白该怎么做。 我不想妨碍人们,以防止他们发展。 另外,我认为必须说不。 我想重复一遍,您说的越多,您做的事情就越糟。 在某个时刻,您需要意识到我们无法实现世界上的一切。 因此,有时我答复说,不幸的是,我无济于事。 反过来说,我宁愿不被立即告知,也不要拖延,也不要再说。 我认为,这也表示尊重这个人,不愿意白白浪费时间。 您不必帮助,但至少不必打扰。 因此,重要的是要说不。 生活就是这样安排的,不要假装自己可以做世界上的一切。 对我而言,快速诚实地回应的能力是专业精神的标志。
-您是一位经验丰富的演讲者。 作为会议的组织者,我们遇到了没有公开演讲经验或只有很少演讲经验的人。 也许您对他们有建议? 您在Twitter上有一个有趣的提示,“可以访问将在此提前举行报告的大厅” –还有更多吗?-我的第一个报告属于用户组,这就是为什么我每年继续在其中进行15个报告的原因。 并且我建议其他人从同一件事开始:从您所在区域的用户组开始,然后是相邻的用户组,依此类推。
由于许多原因,这些报告比在大型会议上的风险要小:有一个友好的气氛,人们可以在那里共享知识,在您报告之后,您很容易获得回应。 您可以说您对此事经验不足,并希望了解听众的意见,可以很好地开始演示。 今年我有一份新报告,在编写过程中,我经历了很多。 我在Twitter上写道:似乎可以在两分钟之内说完所有内容,但实际上这些材料不能在一个半小时内放完。 我很高兴第一次在用户组中提出此报告,因为这使我有机会更好地为会议做准备。
在用户组或您工作的公司中,您有很大的机会练习演示文稿。 首先,您会受到同事的批评,这将使您可以改进报告。 其次,即使他们不直接对您说任何话,当您开始讲话时,您仍然会自己了解很多。 我认为,从第三次开始就可以真正改善该报告。 第一次,您只是想将所有想法融合在一起。 这就是有趣的地方:独自练习并没有帮助,只有在与他人交谈时才会意识到问题。 到第三次,叙述的逻辑链对您来说变得更清晰了,它已经完成。 这并不总是很明显,但有时我会第三次在讲话中停顿一下。此刻,我意识到正是我试图在报告中说出某种时刻的到来。 因此,练习很重要,但不是一个人,而是与人一起。 这可以给年轻的开发人员必要的信心。
是的,有些人在会议上首次发表报告。 有时候,一个人的死比在公共场合讲话要容易得多,而且他们很容易理解-这需要很多神经。 两三年前,我在一次会议上讲话。 一个非常感兴趣的人走近我说,很显然,我很担心,对此我回答说确实如此。 他问,“这是您的第一份报告吗?”,我回答:“不,大概一万,这就是我担心的原因。” 即使您有很多经验,在观众面前的每场演出都需要很大的情绪压力,这仅仅是因为您关心报告的进行情况。 如果通过在用户组或公司中提供一些测试报告来缓解这种紧张关系,您将做得很好。 这适用于所有演讲者,包括经验丰富的演讲者。
-但是,在公开场合是否应该避免某些事情发生?“我一生中犯了许多错误,这些错误教会我人们从经验中学到的东西最多。” 与听众交谈时,需要牢记一些注意事项。 首先,您需要保持自信:您在该主题上做了很多工作,并且对此了解很多。 其次,请记住:不可能一无所知,对某事的无知不是你的错。 这只是意味着您没有机会关注此问题,这没有错。 诚实地承认这一点非常重要。 您可以像这样在会议上回答这个问题:抱歉,我什么也不能告诉您,我没有机会研究这个问题。
另一个重要的一点是,听众可以分为三种类型。 有些人想向您学习新东西。 其他人则保持谨慎,他们会听您的话,但他们并不会准备好理解您所说的一切。 最后,幸运的是,还有第三类人:那些充满敌意并试图一直抓住你的人。 迟早,您的报告中肯定会有一位开发人员,他会一直打扰您,并破坏报告的进度。 在这种情况下,保持镇静,让他说出来并使讨论回到您需要的方向非常重要-但是,我必须承认,我也是一个人,而且我并不总是成功。 例如,您可以说:我知道这对您很重要,让我们在报告后进行讨论,这个话题对许多人来说都很重要。 没错,听众中经常有盟友,当一个人确实违反演讲过程时,他就被要求冷静下来。 我说的所有这些事实是,即使我们的天性可以抵制,在这种情况下也不要太矛盾很重要。 作为一个年轻的演讲者,我经常全力参加这样的对抗,但这从来没有给任何人带来任何好处。 有必要表现出情感上的成熟,而不是试图向任何人证明自己,这是一种小冲突。 相反,在这种情况下,应将话题带回到观众感兴趣的地方。
我还想谈谈表演过程中的一些不良习惯,我认为开发商有这种习惯。 对于初学者,人们应该看着他们的眼睛。 我知道这非常困难,需要大量的情感投入,但是您需要练习一下。 演讲者经常看着他们的显示器,或者更糟的是看着屏幕,背对观众。 您始终需要面对观众,并且应该始终看着他们。 此外,必须保持自信。 您与程序员的读者交流,并且可以打赌,其中没有一个程序员的代码可以首次使用。 如果您的演示在演示过程中不起作用,则没有任何问题。 所有在场的人很可能会想:“该死,我的一切都完全一样。” 多年来,我已经学会了在这种情况下向听众寻求调试帮助。 通常,在这种情况下,说话者会开始喃喃自语,尝试自己解决所有困难。 相反,您应该问听众-朋友,您能告诉我我在哪里傻吗?
您将立即收到许多报价,并且很多时候它们会帮助您发现错误。一个人很难同时说和写代码,不要害怕寻求帮助。对于听众来说,这种体验也很有价值。这就是我访问其他人的报告的原因之一:查看他们在做什么,并了解不应做的事情。我认为,这些习惯将帮助您重构说话能力。
关于技术
— Java- , Java «Hello world». «public static void main» , , .
: Java- , , , . , . - - Java?“是的,肯定。”而且,这是用Java吸引我的东西之一-根本不是2000年的语言。在过去的几年中,这种语言的创造者开始意识到,当一种语言变得冗长和夸张时,它不仅使程序员而且不仅使初学者更加复杂。假设您正在与您的同事交谈,有一些新的想法拜访您,但是对您的对话者来说,这并不是立即显而易见的,他要求您证明您的意思。打开编辑器,在最初的几秒钟内,您意识到要实现这个想法,您需要编写70个try-catch块。而且,尽管这个主意不错,但您还是决定将其留待以后再做,因为目前可能没有时间。对我来说,编程是一系列小实验。作为顾问,我与程序员团队合作,每个团队都有自己的代码编写方式,而且我经常向他们推荐与他人见过的想法。发生这种情况时,他们不仅希望听到单词的新想法,而且希望在代码中看到它。在这种情况下,重要的是他们必须迅速证明这一点。在这方面,我喜欢最少幻想的语言,这些语言使您可以用几行代码来实现您的想法。这就是Java 12、13和14朝着这个方向发展的原因:开发人员意识到,尽管Java是一种功能非常强大的语言,但尝试使用它并不是很容易,并且很难学习。当您完全知道要编写的内容时,Java可以完美地工作,但是通常编程看起来会有所不同。您总是学习和尝试,总是有以前似乎不可能的想法。如果我在一家拥有完善的代码库和某种代码结构的公司中工作,并且如果我基于现有模板向应用程序添加新功能,则这些更改不会对我产生重大影响,此处Java以现有形式可以正常工作。但是,如果您是一位架构师,团队负责人或者只是一个以创新的方式编写代码并进行实验的程序员,那么当前形式的Java将在很大程度上限制您的工作。因此,在我看来,语言向少用的方向发展很重要,而且我大力支持Java现在正在朝着这个方向发展。
. Joker «Don't walk away from complexity, run» . , Joker , , .
-在“不太夸张的Java”的背景下,不可能不问您有关Kotlin的信息,这通常被称为。“是的,这是真的。” 而且,问题不仅仅在于自命不凡。 对我来说,生活中最激动人心的事情之一就是了解新语言及其功能。 Kotlin中的一种可能是在对象的上下文中运行lambda,即使它不是类的一部分也是如此。 当我发现时,我变得非常感兴趣,因为JavaScript中也存在相同的可能性。 在那里,您可以在调用中传递上下文对象(Kotlin称为接收者),然后执行此任意全局函数,就好像它是某些对象的函数一样。 JavaScript中具有此功能的事实不足为奇,因为该语言是动态的。 但是Kotlin是一种静态语言,在尊重类型安全的同时,它也是这样做的。 当然,缺乏自负性是该语言的一大优势,因为它会自动生成代码的重要部分,因此我们不能一遍又一遍地编写相同的模板。 但是好处还不止于此,因为此功能允许您创建内部DSL。
科学和数学使我开始编程,但30年后,由于这是艺术,我仍然是一名程序员。 我们的领域将科学与艺术融为一体,无处可逃。 简单地使系统运行的能力不受限制,在这里您可以用写诗作类比:要求两个人写爱情,每个人都用自己的方式写。 可以用许多不同的方式编写任何任务的代码。 这就是吸引我使用Kotlin等许多语言的能力:表达某些想法的能力,使代码具有灵活性和轻便性。 您可以更少地考虑语言的语法,而可以更多地考虑要传达的思想。
-代码的质量对您来说非常重要。 这似乎对每个人都很重要,而且似乎每个人都想写得更好,但是众所周知,现有代码的很大一部分都存在问题。 因此,问题是:这样您的同事就不会因为您的代码而讨厌您,您只需要自律即可,您能提出任何具体建议吗?“我坚信,编写可读代码的唯一方法就是阅读代码。” 当他们告诉我代码是可读的时,我问-谁读了它? 如果作者本人在写作后立即阅读了此内容,则不算在内。 因此,我坚信代码审查。 我想澄清一下:我反对将一个团队带入一个大屏幕的房间,在上面显示代码并批评它。 这不可避免地导致不满,这样的公开场合没人好。
我们必须诚实地承认:我们每个人都编写不好的代码。 我很自豪地承认:我的代码很烂,我不知道如何编写好的代码。 如果您问这与我对代码质量的讨论如何相符,我会回答:编写代码是一个不断创新的过程,当您尝试实现某些想法时,代码质量不会给您带来太多麻烦。 总是有必要返回并进行重构,即使执行此操作,通常也无济于事。 但是多年来,我意识到,即使我自己的代码是基础,但我仍然可以很好地发现其他人的代码中的缺陷。 因此,我不会假装我的代码已经非常出色,而是会尽可能地编写它,并提供给您进行验证,与此同时,我将获取同事的代码并进行检查。 结果,我的代码和我的同事的代码都将具有更高的质量。
放弃虚假的骄傲非常重要。 我总是提醒开发人员,他们是团队的一部分,相互竞争并找出谁更酷是没有道理的。 我愿意诚实地承认我的知识很有限-但我所知道的我很清楚。 我的同事在其他领域也有很深的知识。 当我们准备互相学习时,我们在一起就会变得更强大。 因此,我总是建议检查彼此的代码,而在这里完全没有额外的自豪感。 您需要彼此诚实,这是一支优秀团队最重要的素质之一。 如果一个人承认自己写了一个错误的密码,那么诚实就不应受到惩罚-这是正常的。 我们通过互相提供改进代码的方式来提高标准。
另一个要点:您不必告诉别人他犯了一个错误,必须说出可以完全改善的地方。 不要说:“上帝,这个变量真是个糟糕的名字,”最好这样说:“您可能想说这个变量显示了分布的频率-应该相应地调用它。” 这将帮助您更好地传达您的意图。 这也适用于书籍编辑:不仅讨论需要改进的地方,而且还讨论了做得好的地方。 我们经常忘记这一点。 当我编辑别人的代码并看到一个执行良好的地方时,我在评论中写下我真的很喜欢它,我们需要经常这样做,并解释原因。 这会产生建设性的反馈,使开发人员清楚您对他不抱有敌意,并最终提高了团队代码的质量。
-您写道,使用一种能够使您渴望的工具,就像陷入一种有害的恋爱关系中:在这种情况下,您只需要尽快离开即可。 听起来不错,但通常乐器没有其他选择,然后呢?-一个完全合理的问题。 确实,在某些情况下无处可去。 但是我宁愿谈到那些仍然有选择的可能性,而只有缺乏选择的欲望的情况。 我认为,这是一个重要因素。
当别无选择时,应该找出痛点,而不是抱怨:是什么让该工具让您感到不舒服。 然后您可以用不同的方式来做。 您可以与开发人员联系,并说-感谢您的工作,在我们看来,如果您关注此类方面,您的工具可能会更好。 或者,您也可以举行黑客马拉松-在周末与几个开发人员聚会,组织一个用户组,告诉他们您每天花9个小时使用此工具,这很糟糕,并要求他们尝试向其中添加一些功能。
也许您不能独自解决所有问题,但至少您可以将其他人召集在一起并与他们一起解决此问题,尤其是当他们的利益与您的利益相似时。 最后,如果您的工具确实引起了很多问题,那么您可以尝试自己编写一个新书-如果您在社区中有三个或四个与您持相同态度的朋友。
因此,我认为仍然有其他选择。 您不必忍受有害的关系。 您始终需要找到一种出路-与伙伴达成共识并达成相互理解,或者离开。
-您写了一本关于lambda的书,由于这本书而闻名。 我也阅读了它,并且我相信它写得很漂亮,可以提供应用程序开发人员所需的内容,不会提供任何多余的内容。 作为一名真正的专业人员,我想问你:什么是函数编程? 您能用自己的话来形容吗? 我问这个问题是因为每个人都以自己的方式对其进行了定义,并且每次隐含的含义被揭示出来时,其含义都不同于Wikipedia的标准定义。-这是一个很好的问题。 我对这个概念的理解已经发展了多年,现在对我而言,函数编程中最重要的事情是消除多余的复杂性。 我们正在谈论这样一个事实,在命令式编程中,您不仅指示需要完成的事情,而且详细规定了如何做。 对我而言,函数式编程是声明性编程风格的附加组件,在声明性编程风格中,我们指出了需要完成的工作,但没有说明如何做。
让我给您一个原始的比喻:我最好的朋友喜欢汽车,但他们一点都不感兴趣。 当我们聚在一起时,我们同意不讨论汽车,因为我们想成为朋友。 我永远不会驾驶带有手动变速箱的汽车-不断换档的需求破坏了我的整个旅程,这同样适用于命令式编程风格。 自动变速箱使驾驶更加轻松,但是对我来说,最好的选择是让驾驶员驾驶我。 在这种情况下,我只说出需要去的地方,然后在后座笔记本电脑上编写代码。 对我来说,这就是命令式和函数式编程之间的区别。 使用命令式编程,您自己就在驾驶,您需要知道去哪里,怎么去,在哪里转弯,在哪里可以切割。 通过功能编程,您可以坐在后座,告诉驾驶员将您带到何处,并且您的注意力完全集中在工作上。
如何消除这种多余的复杂性? 通过功能的组合。 编写函数时,您的代码会进行一系列转换,在此期间数据会从一种形式传递到另一种形式。 而且,对我们来说,重要的不是不是每个步骤如何执行,而是确切实现了什么。 对我而言,函数式编程的第一个方面是函数组合。 问题在于,许多实现了功能组合的语言(如Ruby,Python,JavaScript,Groovy等)因此提供了优雅和表现力,但它们的性能却很低。 它们中的功能组合效率低下。 我相信没有效率的优雅是不可行的。 代码不仅应该漂亮,而且还应该可以快速工作。 在这里,我们来谈谈函数式编程的第二个至关重要的方面-我们在谈论延迟计算。 某个功能的结果仅在需要时才计算。 因此,可以在函数式编程中兼顾优雅与效率。 因此,对我来说,函数式编程强调的是做什么,而不是如何做。 使用功能组合作为一系列数据转换; 以及由于采用了惰性计算而有效执行这些转换的能力。
请注意,我没有提到抗扰性和高阶函数。 事实是它们只是获得我描述的结果的成分。 我们使用函数式编程不是为了抗扰性和高阶函数,它们只是实现更高目标的一种方法:摆脱不必要的复杂性。
-很棒的定义。 今天,有一种语言可以作为函数编程的基准:Haskell(可能还有F#)。-是的
“至少很多人是这样认为的。” 但是Java显然不是Haskell,它在很大程度上受到限制。 当应用到Java时,函数式编程作为一门学科是否有意义? 毕竟,我们的语言针对此方法的工具集非常有限。-对我来说,务实的态度比追求卓越更为重要。 我对完美感到好奇,但是对于所有正常工作,我都必须成为一个实用主义者。 我为Haskell感到疯狂,并花了很多时间与他在一起,只是想了解如何在函数式编程中解决特定任务。 但是对于我的客户,我不是在写Haskell。 在这里,您可以与“大教堂和集市”进行类比。 大教堂很漂亮,但是大部分时间我都在集市里度过。 问题是如何在这个世界上生存。 当语言不断发展,当我们试图将几种不同的范例组合在一起时,作为程序员,我们需要非常小心地实现它们。
我认为Java中根本不可能进行函数式编程。 在可以选择的情况下,我将专注于最适合我的语言。 但是我永远不会告诉客户:您应该使用这种语言。 我通常会问他们到底做了什么,并试图找到一种在他们已经拥有的环境框架内以更优化的方式做同样的事情的方法。 我相信,在像Java这样的语言中,命令式和函数式编程的结合是完全可能的,甚至是推荐的,但是这样做时要格外小心。 想象一下,您有一个纯函数的圆,周围会有一圈杂质。 您想要更改的所有内容都必须在圈子之外。 在此圈子内,您可以实现自己的功能链,但所有更改都必须在此范围之外。
这就是我喜欢学习新语言的原因之一。 最近,我熟悉了Elm语言,它是一种F#散布的Haskell语法,可以在JavaScript中进行编译。 这种方法从一开始就引起我的兴趣,因为JavaScript是一个集市。 当您浏览JavaScript时,会不断陷入困境。 得益于Haskell的语法,榆树绝对是一座大教堂。 但是,此辅助代码仍可以在集市中运行。 Elm的体系结构很优雅,它有一个模型(即数据),有一个显示此数据的视图,还有一个转换,更新。 第一个主要原理是数据存储在视图中。 当用户执行一个动作(例如,按下一个键)时,来自视图的数据将发送到更新功能,在此进行转换。 数据是不可变的,并且更新函数返回视图保存的新数据,而不是旧数据。
如果您考虑一下,则Redux的功能完全相同。 其中有数据,并且存在化简器。 将数据发送到减速器后,您会得到一个新的副本,该副本将保存而不是旧的副本。 但是,如果Elm和Redux使用相同的方案,则可以用Java实现相同的方案。 我们可以创建将获取数据,转换数据并返回新副本的纯函数。 通过向Redux和Elm学习,我们可以使Java架构更具功能性。 我之所以这样说是因为Redux会编译为JavaScript,这是一个独特的集市。 我认为,JavaScript与功能纯净性的理想是最遥远的,在这里,您步入困境的每一步。 尽管如此,在这个极其不干净的世界中,Redux仍为您提供了功能纯净。 这种方法对我影响很大,因为它改变了我对函数式编程的看法,并表明我也可以在Java中实现这些原理。
-很好,谢谢。 您认为我们在Java中拥有的完整工具集是否完整且足够? 除了lambda表达式,方法引用,流集合之外,我们还需要其他东西吗?-在我看来,我们还有很多想念的地方。 Java世界正在不断发展。 我最近与一位男士进行了一次对话,他说:“几年前听说您在我们的城市,并对仿制药争论很多,”我回答:“我一直对仿制药争论很多。” 我相信Java中的泛型做得很差。 布莱恩·格茨(Brian Goetz)一直在生我的气:“总会有人抱怨仿制药”,而这个人当然就是我。 我认为在这方面可以做很多改进。 我认为改革非常重要。 在减少肠胃气胀,摆脱样板代码方面可以做很多事情。 可以使代码更加流畅。 在这个方向上的某种运动今天已经可见。 Java现在实现了模式匹配,这让我非常高兴-我非常喜欢Scala和Kotlin中的实现方式。 我认为这非常重要,我想到了与钞票处理机的类比。 如果您通过一捆钞票,它将根据每张钞票的价值对它们进行分类。 同样,编程中的模式匹配也可以。 您通过可以检索数据进行处理的参数传递数据。 我认为这可以摆脱我们用Java编写的大量分支运算符。 该代码将变得更具表现力。 总的来说,我认为Java需要大量添加,但是显然,它已经朝着这个方向发展。
我想再提一个对我真的很好奇的方面。 我在传统编程的世界中长大。 我不害怕公开承认我的第一语言是Visual Basic。 从某种意义上说,这是第一个实验的好语言,因为它不会更糟。 然后,我用C和C ++编写了很长时间,并且大部分时间都是用我在C ++中使用的所有语言编写的。 之后,我开始用Java,C#和Ruby之类的语言进行编写。 在某个时候,我意识到我总是用多线程语言编写的。 所以结识Node是一种洞察力-我花了一段时间才弄清楚了异步编程。
但是,我认为异步是Java语言和生态系统可以发展的最重要领域之一。异步是指协程和延续。我认为Java已经朝这个方向发展,我认为这非常重要。而且我想Java程序员要熟悉异步编程和我一样困难。我的编程方法完全基于并行性;我写了一篇关于并行计算的论文。从并行到异步的过程对我来说需要很多努力。现在,了解了这两种方法之后,我了解到,作为Java程序员,我们需要找到一种将它们组合在一起的方法。鉴于世界正在朝着微服务之类的方向发展,从长远来看,异步变得比并行性重要得多。 Java正朝着这个方向发展,我认为这是正确的。— , ? JVM-, . . ?-这是一个非常受欢迎的问题,但是讨论起来并不容易。我现在很now愧谈论这件事,但是我在调试器中度过了我的青春。我现在为此感到as愧的原因是:早上,当我到达工作地点时,我发现光标位于前一天晚上离开的同一位置,因为我太累了,无法继续调试。多年来,我已经通过测试掌握了开发工作,现在我以一种非常有纪律的方式来做。我举一个例子。在当前正在与客户端一起开发的应用程序中,我们可能有数百万个lambda。这是一个有关大数据的项目。我们运行并行代码,该代码不断触发大量lambda。如您所知,该系统并不总是能按预期运行。但是,当发生这种情况时,我们通常会了解它,因为单元测试不起作用。然后,我的客户端在发生错误的测试中设置一个断点,并调试该测试。因此,我们不是在调试大量代码,而是在调试各个模块。换句话说,无法调试代码通常不是特定技术的质量的结果,而是代码缺乏模块化的结果。模块化程度越高,代码变得越受控制。对于并行计算和lambda以及异步而言都是如此。如果我们有多个线程,并且我们很难调试它们,这是可以预料的,因为多线程本质上是不确定的。本质上,您在动物园中打开了牢房,然后尝试找出要逃离的地方。您的任务是驯服这个动物园,获得对该动物园的控制权,为此,您需要使代码模块化。 Lambda也是如此。当他们问我如何调试lambda时,我回答:没办法。您不需要由30行代码组成的lambda。您需要一个单独的功能,为此,您将调试一个单元测试,然后通过lambda将其作为方法引用进行调用。异步是美丽的,这就是原因。您拨打电话,并指定此通话完成后要做什么。但是,不必从异步调用中调用此下一步。可以分别调用以下方法进行调试和测试。而且,异步方法本身不必执行;相反,您可能有一个存根,可以简单地检查是否进行了调用。我再说一遍:无法调试代码通常不是特定技术属性的结果,而是表明代码缺乏模块化。而且,我同时使用多种技术的能力越强,我对此越有信心,就越能发现主动调试的方法,这些方法使我不会失去理智。— . , ? , , . , Reactive Streams, Spring Reactor, CQRS event sourcing. - , CQRS?-是的,当然,很多人都在使用它。但是,回到您所说的思维方式变化,我完全同意这一点。我一次对Angular 1并不熟悉,后来与我一起工作的客户要求我看一下这个框架。在Angular中,您可以编写“ $”字符并访问全局名称空间。当我发现这一点时,我的第一反应是:“这是胡说。你不能那样做。”我说这并不是要赞美自己,而是要顺带思考的话题。从那时起,我开始使用google,并得知每个人都在做这件事而感到非常惊讶。我坚信我永远不会那样写。几个月或几年后-我不完全记得-Angular 2出现了,开发人员承认这件事确实很愚蠢,需要消除。作为开发人员,我们很高兴学习如何使用新库和新技术。但是,当我们这样做时,仅学习新的语法和新的API是不够的-您需要学习适当的思维方式。什么是好的代码?应避免使用哪种反模式?这些技术是由有才能的人创造的,但请记住,它们仍然是人。人们会犯错误。这就是为什么在Java(以及任何语言)中都有弃用的方法的原因。因此,Angular 1已经过去了-我们找到了解决问题的更高级的方法。通常,当您掌握一项新技术时,应该务实地做到这一点,并且要有一些健康的怀疑态度。— - (event-driven systems), , . , -. , , API , . , . , , 5-10 , . -, , - . , . , , — , . — ++. — . , , , . - , , , . , , , .
— , , .
Java Champions, Microsoft MVP, JavaScript, . : Java ? .NET, JavaScript - ?-Java迈向的大部分时间已经存在于.NET中一段时间了。 C#最初是Java的稍有改进的版本,我们说过C#在它之后重复所有操作。但是今天情况恰恰相反。 Lambdas在Java中出现的时间比在C#中添加LINQ晚了几年,它允许您编写Lambda,并且具有动作和功能(它们称为Func)。同样,异步在C#中出现的时间要比为Java增加异步性的承诺早几年。没错,我必须说,自2014年以来,Java中就有一个CompletableFuture。但是异步早在那之前就出现在C#中。关于Java和JavaScript可以说类似的话。我知道“我们有很多可以从JavaScript学习的东西”这个短语可能令人恐惧,但是JavaScript程序员已经看到了很多东西,并且知道多少钱。它们具有“回调地狱”的概念,当回调彼此之间无法很好地配合时,异常处理变得异常困难,并且在必须执行异步调用的回调函数上构建对象非常困难。最终,在JavaScript世界中找到了一种以Promises形式出现的解决方案,类似于Java中的CompletableFutures。然而,必须承认:我们世界的美丽在于,永远没有唯一正确的方法。 Promises的好处之一是可以在其中组合功能。另一个优点是它们可以处理异常,并且您可以通过Promises传递数据。但是,假设您的代码除其他外,具有多个异常级别。它可能变得非常复杂,并且在某个点上您将意识到,如果以命令式而不是功能性的方式编写它,看起来会更好。这就是为什么async和await被添加到JavaScript的原因。从本质上讲,它们是Promise的当务之急。您可以编写命令式代码,并且在其中调用函数时,该调用将变为异步,并且此函数下的代码不会立即执行,而是在异步函数已完成其工作之后执行。使用CompletableFuture是不可能的,但是将来随着Java的延续,这将成为可能。而这正是科特林的协程所做的。但是,假设您的代码除其他外,具有多个异常级别。它可能变得非常复杂,并且在某个点上您将意识到,如果以命令式而不是功能性的方式编写它,看起来会更好。这就是为什么async和await被添加到JavaScript的原因。从本质上讲,它们是Promise的当务之急。您可以编写命令式代码,并且在其中调用函数时,该调用将变为异步,并且此函数下的代码不会立即执行,而是在异步函数已完成其工作之后执行。使用CompletableFuture是不可能的,但是将来随着Java的延续,这将成为可能。而这正是科特林的协程所做的。但是,假设您的代码除其他外,具有多个异常级别。它可能会变得非常复杂,并且在某个点上您将意识到,如果以命令式而不是功能性的方式编写它,看起来会更好。这就是为什么async和await被添加到JavaScript的原因。从本质上讲,它们是Promise的当务之急。您可以编写命令式代码,并且在其中调用函数时,该调用将变为异步,并且此函数下的代码不会立即执行,而是在异步函数已完成其工作之后执行。使用CompletableFuture是不可能的,但是将来随着Java的延续,这将成为可能。而这正是科特林的协程所做的。它可能会变得非常复杂,并且在某个点上您将意识到,如果以命令式而不是功能性的方式编写它,看起来会更好。这就是为什么async和await被添加到JavaScript的原因。从本质上讲,它们是Promise的当务之急。您可以编写命令式代码,并且在其中调用函数时,该调用将变为异步,并且此函数下的代码不会立即执行,而是在异步函数已完成其工作之后执行。使用CompletableFuture是不可能的,但是将来随着Java的延续,这将成为可能。而这正是科特林的协程所做的。它可能变得非常复杂,并且在某个点上您将意识到,如果以命令式而不是功能性的方式编写它,看起来会更好。这就是为什么async和await被添加到JavaScript的原因。从本质上讲,它们是Promise的当务之急。您可以编写命令式代码,并且在其中调用函数时,该调用将变为异步,并且此函数下的代码不会立即执行,而是在异步函数已完成其工作之后执行。使用CompletableFuture是不可能的,但是将来随着Java的延续,这将成为可能。而这正是科特林的协程所做的。从本质上讲,它们是Promise的当务之急。您可以编写命令式代码,并且在其中调用函数时,该调用将变为异步,并且此函数下的代码不会立即执行,而是在异步函数已完成其工作之后执行。使用CompletableFuture是不可能的,但是将来随着Java的延续,这将成为可能。而这正是科特林的协程所做的。从本质上讲,它们是Promise的当务之急。您可以编写命令式代码,并且在其中调用函数时,该调用将变为异步,并且此函数下的代码不会立即执行,而是在异步函数已完成其工作之后执行。使用CompletableFuture是不可能的,但是将来随着Java的延续,这将成为可能。而这正是科特林的协程所做的。如果我们比较所有这些语言,很明显,我纯粹出于自私的原因而会说多种语言。从某种意义上说,使用不同语言进行编程类似于前往不同国家/地区。我喜欢去俄罗斯,爱沙尼亚,印度,美国的不同地区,因为在这些旅行中,我遇到了不同的文化,看到了不同的习惯,人们解决相同问题的方式也不同。因此,我总是告诉开发人员,一个好的程序员最重要的素质之一就是对以下事实的理解:没有一种独特的方法可以编写代码。当然,某些方法在某些情况下具有优势,而其他方法则具有劣势,我们需要选择最有效的方法。如果我们比较C#中的async,async / await和JavaScript中的Promises以及Kotlin中的协程,我们将看到在某些情况下,最好使用函数样式,而在其他情况下,则势在必行,但是您可以同时使用两种方法来实现异步。对我来说似乎很好奇。这些创新领域的Java落后于其他语言。但是我相信Java正在发生变化,不仅是因为其他语言已经发生了这些变化,而且还因为我们创建这些应用程序的环境正在发生变化。语言必须发展以提供创建现代应用程序的能力。我认为不再满足业务需求的语言将变得过时且无法使用。 Java必须进化才能生存。而且我不太担心Java是否落后于其他一些语言-它仍然有时间。但是可以同时实现一种方法和另一种方法的异步性。对我来说似乎很好奇。这些创新领域的Java落后于其他语言。但是我相信Java正在发生变化,不仅是因为其他语言已经发生了这些变化,而且还因为我们创建这些应用程序的环境正在发生变化。语言必须发展以提供创建现代应用程序的能力。我认为不再满足业务需求的语言将变得过时且无法使用。 Java必须进化才能生存。而且我不太担心Java是否落后于其他一些语言-它仍然有时间。但是可以同时实现一种方法和另一种方法的异步性。对我来说似乎很好奇。这些创新领域的Java落后于其他语言。但是我相信Java正在发生变化,不仅是因为其他语言已经发生了这些变化,而且还因为我们创建这些应用程序的环境正在发生变化。语言必须发展以提供创建现代应用程序的能力。我认为不再满足业务需求的语言将变得过时且无法使用。 Java必须进化才能生存。而且我不太担心Java是否落后于其他一些语言-它仍然有时间。Java的变化不仅是因为其他语言已经发生了这些变化,而且还因为我们创建这些应用程序的环境正在发生变化。语言必须发展以提供创建现代应用程序的能力。我认为不再满足业务需求的语言将变得过时且无法使用。 Java必须进化才能生存。而且我不太担心Java是否落后于其他一些语言-它仍然有时间。Java的变化不仅是因为其他语言已经发生了这些变化,而且还因为我们创建这些应用程序的环境正在发生变化。语言必须发展以提供创建现代应用程序的能力。我认为不再满足业务需求的语言将变得过时且无法使用。 Java必须进化才能生存。而且我不太担心Java是否落后于其他一些语言-它仍然有时间。Java必须进化才能生存。而且我不太担心Java是否落后于其他一些语言-它仍然有时间。Java必须进化才能生存。而且我不太担心Java是否落后于其他一些语言-它仍然有时间。我真的很欣赏Java的另一个方面。让我们看一下lambda。我通常会说Java假期很晚,但是带来了很棒的甜点。 Java lambda出现得很晚,但是我认为它们使用invokedynamic的实现是惊人的。它改进了在JVM上运行的所有语言中对lambda的使用。 Java不是语言领域的创新者,而是寻求更好的实现它的方式的创新者。而且,在我看来,这是非常重要的优势。我认为,将来在提供新功能方面,其他语言将继续领先于Java,但是Java将寻求更好,更实用和高性能的方法来在JVM上实现这些技术。但是我们确实需要它。我们不仅需要美的机会,还需要满足我们要求的代码。从这个角度来看,Java的开发速度并不快是一个优势。— . , , , . , 5 . — . — , Common Lisp, JavaScript Meta Object Protocol, DSL Kotlin JetBrains MPS, GraalVM Java Java . . ?-这是一个非常重要的问题。我总是说您应该避免参与技术。爱好是指您看到新内容时的感觉,并且您似乎肯定应该立即在应用程序中使用它。在这里,作为开发人员,我们需要自己努力。首先,我们不应仅仅因为当前项目需要新技术就学习新技术。第二,我们不应该运用我们学到的一切。我之所以这样说,是因为我学到的许多东西都无法使用六到七年。我没有研究直接使用这些技术,而是想知道它们的存在。需要某种智慧来确定该项目中尚不需要此技术。当我们堆积不同的组件时,就会出现复杂性,没有充分了解他们的美德。例如,当我访问客户的网站时,我总是问:您为什么要使用它?而且-您为什么要解决这个问题?为什么它与您解决的许多其他问题一样重要?因此,我建议开发人员花一些时间,弄清楚为什么创建了他们感兴趣的技术。我经常问他们:您能告诉您什么时候在什么条件下使用Angular,什么时候使用-React?有时人们无法回答,但同时他们在项目中使用React。在这种情况下,我的问题是-您真的需要吗?我并不是说不需要它,但是我们经常不知道为什么要使用它,只是因为有人说应该使用它而这样做。当我们使用技术时,就会出现复杂性,没有完全了解他们的目的。您可以通过研究这些技术并将它们相互比较,评估优缺点来与之抗衡。如果开发人员无法告诉我吸引某项工具的五个方面,以及拒绝他的五个方面,则意味着他对这一工具的研究不够充分。当我们从不同的角度看待每个工具并获得公正的看法时,我们就可以成功使用它。当我们从不同的角度看待每个工具并获得公正的看法时,我们就可以成功使用它。当我们从不同的角度看待每个工具并获得公正的看法时,我们就可以成功使用它。关于复杂性,我想说的最后一件事。当您评估技术时,请摆脱您的情绪和欲望。在我们的讨论中,通常有人说:我喜欢这种技术,我想使用它。我建议团队绘制一张表并列出您的应用程序所需的功能:可测试性,可伸缩性,异步性,安全性等,具体取决于应用程序。然后,在每个数字旁边写一个从1到10的数字,其中10表示“极其重要”,而1表示“不在乎”。之后,为每一个机会编写一个现有技术的列表,并为每个技术输入一个从1到10的数字,其中1表示“不支持”,而10表示“完美执行”。最后,计算点数,看看哪种现有技术将获得最多的点数。现在,您的情绪不以任何方式参与评估,这使您可以更明智地选择必要的技术。您没有在全球范围甚至是公司范围内进行此评估;您是根据当前项目的需求进行评估的。因此,我不喜欢某些公司将Angular,React或Java作为通用标准的说法。在这种情况下,我总是问:为什么?我们甚至不知道我们将要做什么。这就像是在说:我们整个公司将只骑自行车行驶。这是没有意义的。这完全取决于我们在做什么,这是首先要回答的问题。总的来说,我相信,如果我们正确地了解我们在做什么以及为什么使用这种技术,那么复杂度将会大大降低。如果您摆脱了情绪和欲望,并掌握了资源和需求;如果您正确评估我们解决方案的可比性。最后,我要说的最后一件事是极简主义。我总是告诉团队-将项目添加到项目很容易;从项目中删除它们非常困难。搬迁费用是增加费用的十倍。因此,在添加任何东西时,您需要确保不仅在目前,而且从长远来看,确实在削减成本。除其他事项外,您还需要考虑可逆性。这是关于回滚有关应用程序体系结构决策的能力。如果解决方案是可逆的,那么明天您可以拒绝它,在这种情况下,您不应该考虑太久。如果解决方案的可逆性很差,那么您需要花更多的时间在它上面,收集更多的数据。如果我们考虑到决策的可逆性,因此,我们大大降低了应用程序的复杂性。总的来说,我认为在许多方面我们都必须克服对技术的热情,以降低复杂性。“谢谢你,这是一个很好的答案。” 在我们的Joker会议上,您还将讨论复杂性,因此您可以在此处继续进行讨论。-是的,我将非常期待。