本篇内容主要讲解“怎么高效阅读源码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么高效阅读源码”吧!
在 JAVA 领域中包含 JAVA 集合、Java并发(JUC)等, 它们是项目中使用的高频技术,在各种复杂的场景中选用合适的数据结构、线程并发模型,合理控制锁粒度等都能显著提高应用程序的可用性、健壮性,非常容易凸显出自己的技术实力,更容易受到领导的认可,助力职场。
当然通过阅读源码并不是知晓原理的唯一方法,但作为一个名程序员、直面代码,亲自感受代码的魅力或许会显得的更加直接。
我所在公司使用了 Dubbo、RocketMQ,我也有幸参与到这些技术栈的运用与运维,积累了丰富的使用经验,为了突出在这两个领域的优势,我详细阅读了它们的源码,在CSDN和公众号等知识分享平台发布了大量的技术文章,成体系的剖析其实现原理、架构设计理念,理论与实战相结合,让我成为在Dubbo、RocketMQ领域当仁不让的技术专家,团队中的核心骨干。
同时由于文章是成体系的,被出版社相中,邀请出书,《RocketMQ技术内幕》一书应运而生,从而成为我职业技能列表中非常亮眼的名片,形成公认的技术影响力,具备一定的“品牌溢价”能力。
当然, 也可以等到出了问题再看源码,“投入产出比”更高,但这是个被动过程,如果生产环境由于并发不高,那可能一年、两年你都遇不到真正的问题,经验积累非常慢, 工作了4、5年,有可能还比不过工作2、3年的人。
所以如果是你想快速打造亮点的话,还是需要主动阅读源码,成体系掌握其设计理念、实现原理。
学习编程的过程其实就是一个模仿的过程, 优秀的源码都是大师级作品,极具营养,可以看到大师们是如何抽象接口的,如何应用SOLID原则的,还有很多非常有用的编程技巧。
例如JUnit是从模式开始构建系统, 其中你可以看到大量的设计模式的应用,这些都是活生生的案例,比干巴巴地看那些设计模式理论,或者简单的例子不知道好到哪里去了。
2、如何阅读源码
我根据多年的阅读经验,整理了这么一套方法:
了解这款软件的使用场景、以及架构设计中将承担的责任。
寻找官方文档,从整体上把握这款软件的设计理念。
搭建自己的开发调试环境,运行官方提供Demo示例,为后续深入研究打下基础。
先主干流程再分支流程,注意切割,逐个击破。
接下来分享一下我在阅读 RocketMQ 源码时的一些经历,尽量让上述理论具有画面感。
MQ的使用场景是比较清晰的,它的两大基本职责是解耦与削峰填谷。
举一个最简单的场景:新用户注册送积分、送优惠券场景,其原始架构设计通常如下:
可以看出用户注册和发优惠券,送积分是紧耦合的, 随着业务不断发展,活动部门提出在春节期间用户注册不送积分,发优惠券,而是赠送一个新春礼包,如果基于上述架构的话,需要去改动用户注册的主流程,违背了设计模式中的对修改关闭、对扩展开放的设计理念。
MQ的出现,可以很好地解决上面的问题:
通过通读官方文档,不仅可以得出MQ的整体脉络(例如NameServer路由发现、消息发送、消息存储、消息消费、消息过滤),也能对顺序消费,零拷贝、同步刷盘、异步刷盘等“高端大气上档次”的高级特性产生兴趣与好奇,驱动我们去阅读其源码,探究其实现细节,使得我们在阅读源码中进行一定的自我思考成为了可能。
不同的系统搭建方式也不同,我这里有一篇手把手教你安装RocketMQ与IDEA Debug环境搭建。
在搭建好本地开发环境后,切忌直接用Debug去跟踪消息发送的整体流程,因为这个流程实在是太长了,从比较粗粒度来看其流程如下图所示:
经过这样一分解,就能专注理解其某一块的设计原理,所需要的连续时间也能大大减少,一口一口“吃”,最终完成整个体系的理解。
这还带来了一个额外的好处:分批次输出多篇文章,提高了文章产出,提高了成就感。
阅读源码是枯燥的,一个人孤军奋战很容易放弃,尤其是遇到问题的时候, 如何才能坚持下去,把它读完呢?
我的答案是坚持,但允许短暂的休整、停留,然后反复发起冲刺,拼抢,直到攻克这个“山头”。
因为一旦放弃就将前功尽弃,一旦突破,自身能力能得到一个质的飞跃。
我在阅读Netty源码时就遇到了难题,当时刚刚写完Netty的内存泄露检测,准备开始研究内存分配机制, 这一块儿非常抽象,涉及的数据结构复杂,需要掌握二叉树与数组之间如何映射、牵扯到大量的位运算等等,让我在探究其原理时寸步难行,怎么办呢?放弃?
当一周、两周都无法取得突破时,人很容易想到:这样持续投入时间,又没有回报, 是不是在浪费时间?
其实我想过放弃,但转念一想:放弃后,我会做什么呢?玩游戏?看电视?
既然是玩游戏、看电视,不更是浪费时间吗?想清楚这一层后,继续攻关,继续突破就成了唯一的选择。
当然,遇到难题了,偶尔放松一两天,重新调整状态也是非常必要的。短暂的休整可以让我们变得不那么焦躁,有利于我们重新整理思路,重新发起冲刺。
当时遇到难题时,采取哪些措施有利于我们攻克难题呢?
1、向“度娘”求救
在阅读源码时可以将看不懂的代码直接COPY一小段到百度上去搜索,可能会有大牛已经对这些代码做过解读,能起到指点作用。
当时经过我的搜索,发现Netty的内存分配算法并不是首创,而是对 jemalloc 算法的实现,通过查阅相关的技术文档,可以从整体上理解Netty的内存分配算法。
2、Debug
Netty追求极致的性能,采用了大量的位运算,由于平时工作中很少会使用位运算,看起来比较吃力,为了弥补这方面的不足,使用DEBUG模式,结合运行时数据,去理解位运算,更容易开窍。
经过上面的努力,花了10天时间,Netty的内存分配机制慢慢被我解开,经过分解,我写了一系列文章来描述Netty内存分配:
其中192.168.1.3这个机器有一段时间负载过高,响应时间过长,发往它的请求有30%都失败了。
而30%恰恰是Sentinel设置的熔断错误率, 于是Sentinel认为整个“用户信息查找”服务不可用了,熔断了。
这明显是不合理的,因为192.168.1.4和192.168.1.5这两个机器还活着呢!
本质上这是因为熔断错误率被定义到了服务级别 :服务 -> 熔断错误率
在对这个问题进行思考的时候,我认为在配置熔断规则的时候,需要细化,应该把熔断错误率定义到资源组级别:[服务 , 机器] -> 熔断错误率
这样,当一个机器上的服务提供者被熔断后,不影响其他机器,保证了真正的高可用。
通过与官方联系,我这个想法得到了其作者的肯定,反向促进了社区的发展。
到此,相信大家对“怎么高效阅读源码”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。