当前位置: 首页 > 科技观察

阿里必选:如何写出牛逼的代码?

时间:2023-03-22 12:10:35 科技观察

图片来自Pexels代码作为程序员的硬实力和名片展示,如何提高写代码的能力一直是重点话题。遗憾的是,这篇文章其实并没有讲具体的步骤、银弹方法、武功秘籍等,本文讲的是自己印象中对自己写代码能力有很大提升的4条经验,或许可以供大家参考。01第一次每天都感受到亿级系统的挑战。2008年,HSF第二版在当时淘宝最重要的交易中心上线。它只能通过使用HSF脱机来恢复。下线后,我开始排查问题。HSF的第二个版本基于jboss-remoting。在当前版本的jboss-remoting中,远程同步调用的超时时间是代码中写的60s。但是调用的服务确实会超过10秒,导致web应用处理web请求的线程池逐渐被这些慢请求占用,请求不断累积,最后页面打开非常慢。查明原因后,当时决定基于Mina重写整个HSF通信。两个月的重写,大大提高了我写代码的能力。不管是深入学习网络IO处理,还是深入学习高并发系统,现在想想学习的方法就是看各种类型的网络IO科普资料。然后阅读Mina和Java网络IO的源码。并发的学习主要靠经典的《Java 并发编程实战》和阅读JavaJ.U.C中的代码。这段时间的学习和过去翻ThinkinJava最大的区别就是学完之后付诸实践。随着HSF新改写版本的上线,我也基本逐渐掌握了这部分的代码能力。除了代码能力的提升,我学到的另一个最大的教训是,对于一个亿级、长时间运行的系统来说,很多看似小概率的问题,肯定会变成大问题。这就是为什么很难写出高并发系统的原因。它要求你必须非常清楚自己写的代码以及代码调用的各种API中的实现,这样才能真正保证最终代码的健壮性。02民间“救火队”的故事第二部大大提高我写代码能力的经历是在民间“救火队”的日子里。2009年淘宝出现了很多故障,但是没有规范的处理故障的制度和组织,导致故障多而无人处理,或者处理效率不高。所以当时运维组的一个同学拉了一些人组了个群。团名是淘宝救火队,用来处理淘宝的各种故障。我也是机缘巧合加入了这个群。还有一个全阿里公认的超级科技大神:多龙。第一次看到各种失败,不知如何下手。处理故障,通常不仅需要编写代码的能力,还需要对系统的全局有一定的把握。比如几年前特别火的一篇文章,点击搜索背后发生的事情,其实是对一个系统的处理流程特别熟悉。这在处理故障时非常重要。知道了故障出在哪个环节之后,控制这个环节的代码运行机制的细节就很重要了。这时候,各种工具通常就很重要了,可以有效的帮助你知道发生了什么。比如系统层面的top-H,java层面的btrace等等,可以让你根据运行情况定位问题点。这段时间,我觉得自己的进步靠的是大量的练习。确实有很多毛病。一开始,我取决于人们如何对待他们。我主要是向多龙学习,然后尝试自己解决一些故障。解决的越来越多,熟练度就会逐渐提高。除了解决故障能力的提升,因为我看到了很多代码层面导致的故障,写代码的时候如何更好的保证健壮性呢?这对避免故障非常有帮助。比如我见过很多因为滥用线程池而创建大量线程,最终导致线程无法创建的案例。我会明白在线程池场景下一定要明确控制最大数量,包括堆叠策略等等。再举个例子,数据结构自增容量导致OOM我见过N多例,就会明白写代码的时候不能假设数据结构不会增长到超大,所以没有保护案例。我这时候才明白,写出一段能够运行并满足要求的代码并不难,但是要写出一段能够在各种情况下长期稳定运行的代码就真的不容易了。我认为这是一个专业的写作业务系统。一个优秀的程序员和只是为了好玩而写程序的最大区别。03重写通信框架2010年离开中间件团队,开始做HBase。当时HBase中的通信是用非常简单的写法实现的。想着把以前的HSF移植到这里用的HBase上。这时候多隆刚好用C写了一个通用的通信框架libeasy,用于各种C应用,于是就有了测试。记得第一次测试的结果,看到HSF中通信框架的高并发能力和libeasy有很大的不同。我和多龙讨论了它是如何实现的。我看看能不能学Java这边。版本也变了,才有了这次重写通信框架的经历。本来以为自己在写HSF的时候,这几年已经很好的掌握了通信框架的代码相关能力。在用多隆改写的过程中,发现还是有很大的差距。多隆教了很多细节。基于NIO的通信框架的核心是使用极少的IO线程来处理IO事件(太多了也没用,因为有些部分只能序列化)。所以如何高效的使用这些IO线程是非常关键的,需要尽量减少这些IO线程去处理一些无关紧要的动作。还有一点就是尽量减少IO线程和业务处理线程之间的切换。例如,一个流中的多个请求一次批量抛给业务处理线程是很常见的。之前写过一篇文章总结这段经历。这段经历对我更深入地把握代码逻辑的整体细节很有帮助。这对于编写要求高的系统非常重要。毕竟对于一个超大规模的系统来说,1%的提升还是很可观的。04在学习JVM之前,因为fault比较多,所以开始和公司同事分享了一段时间如何处理fault。后来,我发现有些问题我解释不清楚,或者不知道如何处理。不得不深入学习JVM,但其实一开始根本想不通,一打开JVM代码就不知道从何入手。幸运的是,我遇到了一个和我有相同爱好,而且实力比我强很多的同学,那就是释迦,圈内通常叫R。我和Sakha约好几个周末一起在公司看JVM代码。在Sakha的指导下,我终于入门了,也知道怎么读了。而且我们两个人一起看代码,互相分享和讨论,效率非常高。高的。有了这段经历,再加上不断处理一些故障,基本上逐渐对JVM代码实现有了更深的理解,在分享故障和解决问题的时候也终于能更好的理解了。知道为什么。同样,这对处理故障的能力和编写代码的能力也很有帮助。比如你会更加理解之前认为的所谓GC-friendly代码的含义。我也会有更深的感受,其实Java代码通常不会写得太烂,因为JVM会在运行时尽可能的做很多优化,把它拉到平均线,但是很难做到写得好。它很大,因为你需要了解JVM和JVM下的OS。05总结其实也没什么好总结的,因为每个人的环境不同,每个人都有提升的方法。看自己的经历,我觉得:①环境不行,给自己一个有挑战性的命题。比如你想学习高阶并发通信,你可以尝试自己写一个pk来和别人做对比,做性能。这通常会改善很多。如果你想学习GC,你可以试着给自己出几个问题来控制GC的行为。如果有环境的话,确实会更加有利。②与优秀的程序员一起工作。从多龙和萨迦那里学到了很多,也从很多优秀的开源代码中学到了很多,比如Netty,OpenJDK。所以,通过参与一些优秀的开源项目,也是一个很好的提升方式。阅读优秀书籍(如并发中的Java并发编程实战、OracleJRockit:JVM权威指南、深入理解Java虚拟机等),也是向优秀程序员学习的好方法。③多尝试去解决问题/故障,这绝对是一个非常好的提高代码综合能力的方法,如果你工作中机会不多,网上有很多,像stackoverflow之类的,都是很好的实践理由。最后还是想说,代码能力作为程序员的硬名片,永远是区分程序员能力最有效的东西。我认为“说话很便宜,给我看代码”这句话总是对的。作者:bluedavy责任编辑:陶家龙来源:转载自公众号HelloJava(ID:hellojavacases)