共计 3864 个字符,预计需要花费 10 分钟才能阅读完成。
“我能纯熟应用这个框架 / 软件 / 技术就行了,为什么要看源码?”
“平时不必看源码,看源码太费时间,还容易遗记,工作中呈现问题再针对性地浏览,效率更高。”
“为了面试才须要看源码!”
。。。。。。
如果你也有相似的疑难,无妨接着往下看
1、为什么要浏览源码?
1.1 在通用型根底技术中进步技术能力
在 JAVA 畛域中蕴含 JAVA 汇合、Java 并发 (JUC) 等,它们是我的项目中应用的高频技术,在各种简单的场景中选用适合的数据结构、线程并发模型,正当管制锁粒度等都能显著进步应用程序的可用性、健壮性,非常容易凸显出本人的技术实力,更容易受到领导的认可,助力职场。
当然通过浏览源码并不是通晓原理的惟一办法,但作为一个名程序员、直面代码,亲自感触代码的魅力或者会显得的更加间接。
1.2 在重点畛域打造本人的亮点
我所在公司应用了 Dubbo、RocketMQ,我也有幸参加到这些技术栈的使用与运维,积攒了丰盛的应用教训,为了突出在这两个畛域的劣势,我具体浏览了它们的源码,在 CSDN 和公众号等常识分享平台公布了大量的技术文章,成体系的分析其实现原理、架构设计理念,实践与实战相结合,让我成为在 Dubbo、RocketMQ 畛域当仁不让的技术专家,团队中的外围骨干。
同时因为文章是成体系的,被出版社相中,邀请出书,《RocketMQ 技术底细》一书应运而生,从而成为我职业技能列表中十分亮眼的名片,造成公认的技术影响力,具备肯定的“品牌溢价”能力。
当然,也能够等到出了问题再看源码,“投入产出比”更高,但这是个被动过程,如果生产环境因为并发不高,那可能一年、两年你都遇不到真正的问题,教训积攒十分慢,工作了 4、5 年,有可能还比不过工作 2、3 年的人。
所以如果是你想疾速打造亮点的话,还是须要被动浏览源码,成体系把握其设计理念、实现原理。
1.3 从优良的源码中学习设计和编码
学习编程的过程其实就是一个模拟的过程,优良的源码都是大师级作品,极具养分,能够看到巨匠们是如何形象接口的,如何利用 SOLID 准则的,还有很多十分有用的编程技巧。
例如 JUnit 是从模式开始构建零碎,其中你能够看到大量的设计模式的利用,这些都是活生生的案例,比水灵灵地看那些设计模式实践,或者简略的例子不晓得好到哪里去了。
2、如何浏览源码
我依据多年的浏览教训,整顿了这么一套办法:
- 理解这款软件的应用场景、以及架构设计中将承当的责任。
- 寻找官网文档,从整体上把握这款软件的设计理念。
- 搭建本人的开发调试环境,运行官网提供 Demo 示例,为后续深入研究打下基础。
- 先骨干流程再分支流程,留神切割,一一击破。
接下来分享一下我在浏览 RocketMQ 源码时的一些经验,尽量让上述实践具备画面感。
2.1 理解 RocketMQ 的利用场景
MQ 的应用场景是比拟清晰的,它的两大根本职责是解耦与削峰填谷。
举一个最简略的场景:新用户注册送积分、送优惠券场景,其原始架构设计通常如下:
能够看出用户注册和发优惠券,送积分是紧耦合的,随着业务一直倒退,流动部门提出在春节期间用户注册不送积分,发优惠券,而是赠送一个新春礼包,如果基于上述架构的话,须要去改变用户注册的主流程,违反了设计模式中的对批改敞开、对扩大凋谢的设计理念。
MQ 的呈现,能够很好地解决下面的问题:
通过引入 MQ,用户注册主流程只须要实现注册逻辑,并向 MQ 发送一条音讯,而后流动模块(送积分、送优惠券、送礼包)只须要订阅 MQ 中的音讯,进行对应的解决。
这样音讯注册主流程会十分的简略,不论流动品种如何变动,注册流程无需更改,这样就实现理解耦。
2.2 通读官网文档,从全局把握其设计理念
理解应用场景当前,接下咱们能够去查阅官网文档,次要包含用户设计文档(架构设计),用户使用手册等,从全局理解其设计理念。
通过通读官网文档,不仅能够得出 MQ 的整体脉络(例如 NameServer 路由发现、音讯发送、音讯存储、音讯生产、音讯过滤),也能对程序生产,零拷贝、同步刷盘、异步刷盘等“高端大气上档次”的高级个性产生趣味与好奇,驱动咱们去浏览其源码,探索其实现细节,使得咱们在浏览源码中进行肯定的自我思考成为了可能。
2.3 搭建开发调试环境
不同的零碎搭建形式也不同,我这里有一篇手把手教你装置 RocketMQ 与 IDEA Debug 环境搭建。
2.4 先骨干,再分支
在搭建好本地开发环境后,切忌间接用 Debug 去跟踪音讯发送的整体流程,因为这个流程切实是太长了,从比拟粗粒度来看其流程如下图所示:
如果大家想一次性将上述流程的源码全副看一遍,简直是不可能的。因为音讯发送高可用设计、音讯存储、刷盘、同步等机制,每个点具体开展的工作都是海量的,咱们没有这么多间断的工夫,所以适当的拆分十分有必要。
通过这样一合成,就能专一了解其某一块的设计原理,所须要的间断工夫也能大大减少,一口一口“吃”,最终实现整个体系的了解。
这还带来了一个额定的益处:分批次输入多篇文章,进步了文章产出,进步了成就感。
3、浏览源码很容易放弃,怎么办?
浏览源码是干燥的,一个人孤军奋战很容易放弃,尤其是遇到问题的时候,如何能力坚持下去,把它读完呢?
我的答案是保持,但容许短暂的休整、停留,而后重复发动冲刺,拼抢,直到攻克这个“山头”。
因为一旦放弃就将半途而废,一旦冲破,本身能力能失去一个质的飞跃。
我在浏览 Netty 源码时就遇到了难题,过后刚刚写完 Netty 的内存泄露检测,筹备开始钻研内存分配机制,这一块儿十分形象,波及的数据结构简单,须要把握二叉树与数组之间如何映射、牵扯到大量的位运算等等,让我在探索其原理时举步维艰,怎么办呢?放弃?
当一周、两周都无奈获得冲破时,人很容易想到:这样继续投入工夫,又没有回报,是不是在浪费时间?
其实我想过放弃,但转念一想:放弃后,我会做什么呢?玩游戏?看电视?
既然是玩游戏、看电视,不更是浪费时间吗?想分明这一层后,持续攻关,持续冲破就成了惟一的抉择。
当然,遇到难题了,偶然放松一两天,从新调整状态也是十分必要的。短暂的休整能够让咱们变得不那么烦躁,有利于咱们重新整理思路,从新发动冲刺。
过后遇到难题时,采取哪些措施有利于咱们攻克难题呢?
1、向“度娘”求救
在浏览源码时能够将看不懂的代码间接 COPY 一小段到百度下来搜寻,可能会有大牛曾经对这些代码做过解读,能起到指导作用。
过后通过我的搜寻,发现 Netty 的内存调配算法并不是独创,而是对 jemalloc 算法的实现,通过查阅相干的技术文档,能够从整体上了解 Netty 的内存调配算法。
2、Debug
Netty 谋求极致的性能,采纳了大量的位运算,因为平时工作中很少会应用位运算,看起来比拟吃力,为了补救这方面的有余,应用 DEBUG 模式,联合运行时数据,去了解位运算,更容易开窍。
通过下面的致力,花了 10 天工夫,Netty 的内存分配机制缓缓被我解开,通过合成,我写了一系列文章来形容 Netty 内存调配:
迈过了这道坎,前面的源码浏览效率变得十分高效。
通过攻克一个个难题,最终从质变引发量变,逐步造成一条本人的源码浏览实践,后续的源码剖析 RocketMQ、Dubbo、ElasticJob、Sentinel、Kafka 等专栏就变得非常简单了。
4、源码浏览的三层境界
4.1 高级:记流水账
我初期的源码阅读文章基本上是记流水账,例如对源码一样一行加正文,只关注底层实现细节,但并未造成更高层次认知,对其设计理念没有提炼与深度领悟。
4.2 中级:能发问、思考、提炼
随着技术类文章的继续分享,我意识了很多大牛,发现和他们交换的时候,发现他们一开始并不会说细节,而是讲设计理念。
这就要求咱们在浏览源码的时候多思考,并反诘本人如果本人实现的话该如何着手,如何设计,带着疑难去钻研源码。通过比照,思考,会对其背地的理念有了更粗浅的了解。
4.3 高级:思考、质疑、验证
不论是哪个开源框架,都会存在 BUG 或者实现并不合理的中央,如果大家在浏览源码的时候可能深刻思考,正当质疑,并能通过验证证实本人的观点,而后与官网取得联系,交换,独特促成社区的倒退,阐明咱们的能力、思考失去了极大的晋升。
思考与质疑是源码浏览的一个升华,比方我在看 Sentinel 熔断时对其提出的质疑。
一个“用户信息查找”服务,被部署到了三个机器上。
其中 192.168.1.3 这个机器有一段时间负载过高,响应工夫过长,发往它的申请有 30% 都失败了。
而 30% 恰好是 Sentinel 设置的熔断错误率,于是 Sentinel 认为整个“用户信息查找”服务不可用了,熔断了。
这显著是不合理的,因为 192.168.1.4 和 192.168.1.5 这两个机器还活着呢!
实质上这是因为熔断错误率被定义到了服务级别:服务 -> 熔断错误率
在对这个问题进行思考的时候,我认为在配置熔断规定的时候,须要细化,应该把熔断错误率定义到资源组级别:[服务 , 机器] -> 熔断错误率
这样,当一个机器上的服务提供者被熔断后,不影响其余机器,保障了真正的高可用。
通过与官网分割,我这个想法失去了其作者的必定,反向促成了社区的倒退。
举荐浏览
15 年教学教训的 Java 架构师用 140 个实战案例完满演示微服务 + 丰盛架构图,轻松把握微架构设计与开发
** 为什么阿里巴巴的程序员成长速度这么快?
**
**【手撕 Spring 源码合集】带你从入门到精通;
**
看完三件事❤️
如果你感觉这篇内容对你还蛮有帮忙,我想邀请你帮我三个小忙:
点赞,转发,有你们的『点赞和评论』,才是我发明的能源。
关注公众号『Java 斗帝』,不定期分享原创常识。
同时能够期待后续文章 ing????