源码阅读心得---如何从零开始阅读一个框架的源码

news2024/11/25 14:44:01

写在前头,菜鸟作者的一些碎碎念:

回想自己2022年研三第一次去实习的时候,是到了一个数据库小组,是一个做数据库内核的小组,leader分配的目标是先把read/write流程搞明白。第一次出校实习,一来就是直接读内核源码,而自己对数据库只有书本上的知识,可以说是对内核实现完全不了解,一片空白,所以当时真的是焦虑的不行,生怕自己无法完成任务,再加上马上就要毕业了工作无着落(虽然后面延毕了),又是第一次去公司实习,所以真的慌得要死,好在leader特别特别特别特别特别好,让我慢慢来,给了我充分的时间来,读了1个月,懵懵懂懂。后来岳麓区疫情爆发,12月初答辩完拿到offer就回学校了,2月的短暂实习就结束了,源码阅读就暂告一个段落了,后来23年6月后来公司,原先数据库小组打散了,leader带着我来到了云原生这个新部门(留在原小组挂靠到其他部门下面的两个应届生后面都被裁了,真的感叹自己超级幸运),是搞k8s,最开始接的任务是改造一个项目的组件自动部署的任务,刚来新部门,啥也不懂,很慌,对k8s只是以前简单看过两本书,但是都忘光了,也就是说对k8s也是一片空白,还好组里的人特好,各种问,然后各种答疑解惑(蛮幸运的)。因为对k8s不太了解,初期只能靠视频以及资料学习,但是看视频和看资料总是不够,还是不知道怎么写代码,另外,除了k8s之外,要维护修改组件部署项目就必须先了解这个项目的源码,所以开头一个月是一边看视频学k8s一边读项目源码一边尝试开发,逐步摸索前进。大概到了十月份,安排了新的任务:组件部署只是实现了自动化这个功能,但是各种中间件的单机部署、集群部署yaml还是需要自己准备,所以新任务就是完成这些yaml,如redis/pulsar/rocketmq等十多中,10月到12月左右都是一边百度组件原理,一边写yaml,一边测试,这个时期是对各种中间件原理的简单了解,这个时期也暗暗埋下了好奇的种子,等到这个搞完,又安排了一个调度器开发的任务,也是对调度器啥也不了解,也是一边看网上资料,一边debug源码,一边编写调度器插件。差不多23年8月~24年2月都是一边看资料学习k8s一边看各种源码,一边开发,差不多对k8s有了初步了解。从出学校到初入职场,这一段时间真的超级重要,这段时间内,组里给我的感觉就是:这个小组的氛围真的特别特别好,学习氛围也特别特别浓厚,反正遇到什么的不懂的有什么不会开发的,看完资料直接看源码吧,正是这种浓厚的氛围为后来培养自己对源码阅读的习惯打下了基础(自己读源码还有一个十分重要的原因就是:第一次实习,阅读数据库源码,成功大致缕清崩溃恢复、2pc流程的时候,那种云开雾散、豁然开朗的感觉真的超爽,自己对这个不了解,看视频只知道大概,看完源码后突然就理解视频里说的是什么意思,很爽)。新的一年,砍掉了许多开发任务,由于人事变动,我也分到了leader(这个leader和前一个leader一样,真的超级好,连续两次遇到两个非常棒的leader真的超级幸运,一个好leader有时候真的是可遇不可求)手下的另一个小组出口网关和消息平台小组,负责出口网关,出口网关比较成熟,所以比去年要空闲一点,也改了加班政策,可以调休更多,所以自觉加班比以前多了一点,一般加班的时候,一半时间摸鱼,一半时间阅读源码和做笔记,从大概24年3月份到今天(2024/11/03),陆陆续续读了:pulsar、etcd、netty、redis、nginx以及公司的出口网关、消息平台等框架的部分源代码,真的受益颇深,如前面所述,支撑我阅读源码的重要动力之一就是:我对这个不了解,我想要了解(自驱力特别重要因为特别害怕被裁(现在工作真不好找),当然,我也是半吊子水平)。从最开始编译数据库库内核,成功跑起来都要个把星期到如今差不多一周就能大致了解一个框架的read/write等主要流程源码(包括搜集资料1到2天,编译环境1到2天(基本半天搞完,pulsar这种复杂的搭建集群折腾了很久),一个流程差不多1到2天就可以大致明白怎么实现的),虽然还是很菜(有时,真的,自己同龄人焦虑真的好严重,当初的同学,我还在入门,他们都去bat等一线大厂工作好几年了,会有深深的打击感和无力感,不过人各有命,顺其自然吧),但是自己也能感觉到自己和初入职场时是有进步的,职场中(我是在基础平台)阅读源码十分常见,所以我想把我这一年来阅读源码的心得总结下来,分享给大家,这仅仅是一家之言,仅仅是菜鸟之言,当然网上类似的文章一大把,内容和我的也差不多,但不管怎样,我的这些心得都是我这一年自己总结的,有些东西看别人写的,似懂非懂,但是等到自己真的实操一遍,才能真的深刻理解。所以,一起加油,各位。

如何快速理解一个框架源码:

1:了解框架及其使用。我一般去b站找该框架的使用教程和百度,过一遍就行,不用都学会,比如视频我都是2倍速和不断快进。阅读源码之前一定要了解他是怎么用的。一般通过使用,就能对他怎么实现的有一点点自己的猜测。

2:搭建debug环境,以便可以debug源码。工欲善其事必先利其器,我都是用jetbrains全家桶,比如java用idea、c++用clion、go用goland、python用pycharm。(实习以及参加工作,一年半里,go、java、python、c++都用过,真的感觉语言只是工具,重要的是不是能完成任务。。。)。!!!一定要搭建调试环境,因为如果要阅读源码,就必定要debug,否则效率很低而且有些流程会理解出错。当然,搭建环境这一步有时候就把人劝退了。。。。

3:再次上b站找视频和百度找源码资料,以便了解大致实现。这次主要是找源码解析视频和解析文章。在自己尝试阅读之前就要大致了解源码是怎么实现的,这样自己读源码的时候才能事半功倍,才能读的更顺。

4:确定切入点。千万不要从main函数开始看起,如果没有切入点,而是直接从main开始,那么你读源码就是浪费时间,因为你本来就对源码不了解,没有切入点也就是没有带着疑问带着目的去阅读,那么你这样收益是极低。所以一定要找到一个切入点。个人建议一般是:write/read/持久化(写日志)/事务,个人建议第一个切入点一般最好是write,比如etcd就是put命令的实现流程、redis就是set命令的实现,因为写命令会涉及到命令的执行、主从同步、日志记录等各方面,也就是一旦弄明白write流程,那么整个框架差不多理解了,像nginx这种就是read流程。因为各个流程都是息息相关的,所以一旦读懂了一个流程,其他的流程也就会轻松很多,并且先读完流程a,然后读流程b,读b的时候往往又会灵光一下,原来流程a里的某处操作是为了流程b啊,这样前后映照,互相补充,效率就高了

5:打断点。确定切入点之后就是打断点了。怎么找断点?我的心得如下:比如我要etcd write流程,那么我就上网百度etcd write源码流程、etcd write源码入口等,然后复制文章里的函数名字,然后去ide里ctrl+shif+f全局搜索这个函数,然后找到了就打一个断点,一般如此一下就在该流程的主线路径上打下两三个断点,注意,不要求一定是入口点,只要是主线流程上的点就行,因为借助ide我们可以快速找到主线。打下断点后我们就是用工具或者直接自己写代码来触发源码的这段流程,比如ectd write源码流程中我打下了断点,然后我就用etcd-cli来发送put命令,如果源码流程执行到了我们的断点处,那么这一步就大功告成,因为只要找到一个断点,那么借助ide,我们就能一眼找到调用栈,通过单步调试,我们也能一步一步深究下去。总结下来就是在某条主线上打下两三个钉子,然后我们就能一下拎起整条主线

6:就是debug源码然后做笔记了。一定要做笔记,只看不做是不行的。同时我并不是一调试就直接做笔记,而是读三遍。第一步先大致捋一遍该流程主线,这个阶段主要是快速浏览主线经过的函数,抓住主线,也就是靠猜,靠函数名来猜主线会往哪里走,然后打断点;第二遍则是从流程起点,再一步一步的看函数,比之前要详细一点,这一阶段主要是大致了解各个函数的流程,以便能够从中拎出哪些是主线代码,哪些是无关流程(比如错误处理、条件检测等);第三遍就是一边debug,一边记录笔记了,比前两个阶段要详细的多,而且记笔记的时候往往记到某个点,突然就会发现他是和前面某个点互相呼应的,所以一定要记笔记。当然,不是每个细节都要弄懂,只要明白这段代码是干什么的,大致是完成什么功能,这个函数也是大致完成什么功能,就行了,不用去深究数据结构,因为目前我读源码主要是弄明白代码流程而不是数据结构,如果死扣细节和数据结构,很容易就被绕晕,半天不得其解,此时很容易就气馁,所以不要扣细节,只要明白大致是什么意思就行了。不懂得地方一定要学会百度,比如这个函数不明白什么意思,直接百度,因为源码阅读这件事很多人都做过笔记的,不要从零开始,要站在前人的肩膀上。

补充:阅读源码的时候一定要学会融会贯通,就是说要会思考,会总结,会一边猜测,然后一边读源码验证。比如我最开始读的是starrocks数据库的源码,然后就对一致性和持久化有一定了解,然后读redis的时候就会想redis肯定会持久化日志,但是到底是在哪里持久化日志的,按照我读starrocks的经验,应该是先写日志,再执行,然后在返回响应,但是实际却是先执行,后写日志,虽然和猜测的不符,但是在带着疑问验证猜测的过程中,我们就可以很好地缕清主线。

补充:!!!!一定要会用chatgpt、阿里通义千问等ai助手,有时候一段函数我们不太懂,直接复制整个函数然后丢给ai助手,让他解释代码,虽然不一定全对,但ai助手能回答个七七八八,我们从ai助手的回答里就能大致知道这个函数大致怎么个流程,有助于我们猜测主线和抓住主线。再次强调,阅读源码一定要用ai助手,不要怀疑ai助手对于阅读源码的能力。

最后的碎碎念:经常有时候有个地方看了很久看不明白,然后上网搜,然后发现别人怎么讲的那么详细,然后觉得别人好厉害,自己好渣,然后被打击,然后心情低落。。。。这是我自己的亲身经历,我的感悟是:没关系,该打击还是会打击的,因为不管怎么样,时间是自己的,成长是自己的,即使垂头丧气,时间也会过的,所以与其垂头丧气,不如收拾好心态,重拾信心,然后再慢慢看,再次强调:因为时间,是自己的,成长,是自己的,所以即使再灰心再沮丧,等心情恢复,又继续慢慢看吧

下面以debug redis为例:

1:学习redis使用,视频和百度。随便找两个教程过一遍就行了,注意,最好是整套整套的教程,不要两三分钟一个知识点片段的那种。

在这里插入图片描述

2:搭建debug环境,直到我们可以用工具正常访问,我们这里用的是redisinsight

在这里插入图片描述

3:找源码教程或者源码文章

在这里插入图片描述

4:打断点,我们一般第一个流程选择write流程,然后百度源码流程,找到对应函数,然后直接ctrl+shift+f在源码中查找,然后打下断点,然后用工具触发这个流程。

4.1:百度,然后找到断点,比如redis的set命令就是一个write流程,我们百度得知set流程会经过setCommand。

在这里插入图片描述

4.2:在源码里面ctrl+shif+f查找字符串 setCommand(,然后在函数代码中打下断点,这样我们就抓住了主线上的一个点
在这里插入图片描述

4.3:工具触发流程,然后借助ide,查看调用栈,我们一下就可以抓住整个主线流程了。主线程流程正好从main开始,所以说不要一开始就从main函数开始平推,而是要找准某个切入点,抓住某条主线,然后往前往后debug。备注:看什么流程就重点关注什么流程,与当前流程无关的,统统跳过
在这里插入图片描述

4.4:借助ai助手,大致了解函数流程,要与时俱进,不要怀疑ai助手的强大。

在这里插入图片描述

5:debug和记笔记了。记笔记我都是记录整个流程,然后用缩进代表调用关系,一般用两个空格,即a调用b,假设a缩进2个空格,那么b就是缩进四个空格,然后是每行只记录一个函数调用,然后在右侧做笔记,介绍函数用途,以及自己的一些心得。c,我一般用文件名.方法名记录方法,go/c++/java,一般用类名.方法名来记录一个函数

filea.func_a                    #这里就表示func_a
  classb.func_b                  #这里表示func_a调用了func_b,然后func_b做了什么事xxxx
    classc.func_c                #然后这里表示func_b调用了func_a

至此,源码阅读的心得总结完毕

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2232399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java项目实战II基于Java+Spring Boot+MySQL的体育馆使用预约平台的设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着全民健…

创新材料科技:铜冷却壁助力高炉节能降耗

高炉用铜冷却壁是高炉内部的一种构件,通常用于高炉的炉身部分。它的主要功能是在高炉冶炼过程中冷却炉壁,以防止炉壁过热。铜冷却壁通常由铜制成,因为铜具有良好的导热性和耐腐蚀性,能够有效地将热量从高炉内部传导到外部&#xf…

衡石分析平台最佳实践-开发场景之分层级嵌入

分层级嵌入 平台整体嵌入 在这种应用场景中&#xff0c;把所有功能通过 iframe 的方式都开放给登陆用户&#xff0c;嵌入的示例如下&#xff1a; html <iframename""src"https://preview.hengshi.com/app/1"> </iframe> 1 2 3 4 单个模…

Balluff EDI 项目需求分析

电子数据交换&#xff08;EDI&#xff0c;Electronic Data Interchange&#xff09;是一种通过电子方式在不同组织之间交换商业文档的技术和标准。它涉及使用标准格式的电子文档&#xff0c;如订单、发票、运输单据等&#xff0c;以实现自动化的数据传输。这种技术通常依赖于专…

C++ 手写常见的任务定时器

序言 最近在编写 C 的服务器代码时&#xff0c;我遇到了一个需求&#xff0c;服务器很可能会遇到那些长期不活跃的连接&#xff0c;这些连接占用了一定的资源但是并没有进行有效的通信。为了优化资源使用&#xff0c;我决定实现一个定时器&#xff0c;以便定期检查连接的活跃状…

后端Java学习:springboot之文件上传(阿里云OSS存储)

一、什么是阿里云存储&#xff1f; 阿里云对象存储OSS&#xff08;Object Storage Service&#xff09;&#xff0c;是一款海量、安全、低成本、高可靠的云存储服务。使用OSS&#xff0c;您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。 二、阿里云…

2024年前三季度币安、OKX等五大交易所上币表现分析

随着加密市场竞争的加剧&#xff0c;头部交易所逐渐在上币策略、代币选择、交易活跃度等方面采取了不同的应对策略。Animoca Digital Research近期发布的一份报告&#xff0c;通过对币安、OKX、Bitget、KuCoin和Bybit五大交易所2024年前三季度的上币情况进行了详细分析。本文将…

嵌入式linux系统中串口驱动框架分析

大家好,今天主要给大家分享一下,如何使用linux系统中的串口实现。 第一:串口基本简介 串口是很常见的一个外设,在Linux下通常通过串口和其他设备或传感器进行通信。根据电平的不同,串口可以分为TTL和RS232。不管是什么样的电平接口,驱动程序是一样的。 第二:Linux下UAR…

服务器内存不够导致postgresql进程被kill的问题记录

服务器环境&#xff1a;Centos7.9&#xff0c;PGSQL14 故障现象 平均负载飙升至80以上 磁盘 IO 高: 故障期间磁盘 IO 明显增加 同步异常: 主从库的复制出现问题&#xff0c;从库自动提升为主库 排查过程 磁盘 IO&#xff1a;使用 iostat查看磁盘 IO 活动&#xff0c;发现磁盘…

解决方案:e1000e eno1 Detected Hardware Unit Hang

在 Proxmox 6.5.11-8 中&#xff0c;偶发性会出现以下报错&#xff0c;尤其是在进行大文件传输后&#xff1a; [97377.240263] e1000e 0000:00:1f eno1: Detected Hardware Unit Hang:TDH <22>TDT <2f>next_to_use &l…

Nature文章《deep learning》文章翻译

这篇文章是对Nature上《deep learning》文章的翻译。原作者 Yann LeCun, Yoshua Bengio& Geoffrey Hinton。 这篇文章的中心思想是深入探讨深度学习在机器学习中的革命性贡献&#xff0c;重点介绍其在特征学习、监督学习、无监督学习等方面的突破&#xff0c;并阐述其在图…

微服务实战系列之玩转Docker(十六)

导览 前言Q&#xff1a;基于容器云如何实现高可用的配置中心一、etcd入门1. 简介2. 特点 二、etcd实践1. 安装etcd镜像2. 创建etcd集群2.1 etcd-node12.2 etcd-node22.3 etcd-node3 3. 启动etcd集群 结语系列回顾 前言 Docker&#xff0c;一个宠儿&#xff0c;一个云原生领域的…

Rust 力扣 - 1423. 可获得的最大点数

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 题目所求结果存在下述等式 可获得的最大点数 所有卡牌的点数之和 - 长度为&#xff08;卡牌数量 - k&#xff09;的窗口的点数之和的最小值 我们遍历长度为&#xff08;卡牌数量 - k&#xff09;的窗口&#…

flink 内存配置(二):设置TaskManager内存

TaskManager在Flink中运行用户代码。根据需要配置内存使用&#xff0c;可以极大地减少Flink的资源占用&#xff0c;提高作业的稳定性。 注意下面的讲解适用于TaskManager 1.10之后的版本。与JobManager进程的内存模型相比&#xff0c;TaskManager内存组件具有类似但更复杂的结构…

配置DDNS结合光猫路由器实现外网映射

配置ddns结合光猫路由器实现外网映射 一、实现思路 首先需要去获取一个动态域名&#xff08;文章不再赘述&#xff0c;重点去介绍具体实现&#xff09;&#xff0c;用作后面与与公网绑定。然后需要在光猫和路由器上去做配置&#xff0c;同时确保路由器有公网IP&#xff0c;最…

如何在BSV区块链上实现可验证AI

​​发表时间&#xff1a;2024年10月2日 nChain的顶尖专家们已经找到并成功测试了一种方法&#xff1a;通过区块链技术来验证AI&#xff08;人工智能&#xff09;系统的输出结果。这种方法可以确保AI模型既按照规范运行&#xff0c;避免严重错误&#xff0c;遵守诸如公平、透明…

华为HarmonyOS打造开放、合规的广告生态 - 激励广告

场景介绍 激励广告是一种全屏幕的视频广告&#xff0c;用户可以选择点击观看&#xff0c;以换取相应奖励。 接口说明 接口名 描述 loadAd(adParam: AdRequestParams, adOptions: AdOptions, listener: AdLoadListener): void 请求单广告位广告&#xff0c;通过AdRequestPar…

easyui +vue v-slot 注意事项

https://www.jeasyui.com/demo-vue/main/index.php?pluginDataGrid&themematerial-teal&dirltr&pitemCheckBox%20Selection&sortasc 接口说明 <template><div><h2>Checkbox Selection</h2><DataGrid :data"data" style&…

unity搭建场景学习

unity搭建场景学习 创建场景创建gameobject创建材质&#xff0c;用于给gameobject上色拖拽材质球上色上色原理设置多个材质方式设置贴图的方式 效果设置光滑度一些预览设置菜单渲染模型与碰撞模型网格渲染参数1. materials(材质)2. lighting(光照)3. reflection probes(反射探针…

软件加密与授权管理:构建安全高效的软件使用体系

“软件加密与授权管理&#xff1a;构建安全高效的软件使用体系”是一个全面且深入的议题&#xff0c;以下是对该议题的详细探讨&#xff1a; 一、软件加密的概念与重要性 软件加密是指为软件添加保护措施&#xff0c;以防止其被盗版或非法复制。这一技术站在软件开发者的角度&a…