前言

这篇文章最早发表于电鸭社区,这里我将原文进行了删改,增加了一些可操作层面的干货。
首先我想谈一谈我个人对国内软件行业从业者的一些现状:
前两年我在国内某一家企业工作的时候,经常看到一些同事去客户那边加班,说是出bug了,有时候还需要通宵,我就问他们,你们有写单元测试和集成测试的习惯么?他们说不写,我说你们怎么不写测试呢?一个和我比较熟悉的同事对我说老板天天催,哪有时间啊!
后来我了解到国内大多数企业都是这样的:

老板不停地催研发 ===> 研发没时间写测试,同时可能也产生了大量的辣鸡代码(包含重复性的代码)而没有重构,也从来不进行code review => 随着代码量的增加代码越容易出bug,=> 出了bug就要没日没夜的加班,可能还被老板吐槽你们这群人水平太辣鸡了 ===> 没时间提升自己 => 程序员年龄大了以后没什么人要了(可能因为加班加不动,也可能自己的知识能力也没增长多少,有很多人一年的工作经验重复了好几年!)

老板为什么要催呢?早点上线早点抢占市场啊!
上面的这个恶性循环可能是造成很多程序员失业或者转行的原因吧;

最后简单说一下这篇文章的主体结构:

  1. 为什么要向开源社区做贡献
  2. 向开源社区所做贡献的途径和方法
  3. 向开源社区做贡献所具备的一些基础
  4. 在社区里面提一个问题的正确姿势?
  5. 参与开源项目协作其他需要注意的

为什么要向开源社区做贡献

最显然的就是对于你个人技能的提升:举个例子:如果你自学,大多学的是理论层面的居多,实践层面如果遇到困难了,一时半会很难有人给予你指导;在开源社区,实践的机会很多,遇到不明白的或者说自己犯错了,会有人指导你或者指出你的错误在哪;在工作中就不一样了,如果犯错可能会被解雇;

在最佳实践层面:由于开源社区里面的很多明星项目比如Spring项目,一直在往前发展和创新,因此许多当前的行业最佳实践很多都源于开源社区,有的已经成为了行业的标杆,包含版本控制,单元测试和集成测试,持续集成和部署(CI/CD),设计模式等等;当你为开源社区做出贡献时,你将掌握许多在其他环境中可能永远也不会学到的概念和最佳实践(据我了解,阿里爸爸,字节的很多团队都没有写单元测试和集成测试的习惯)。更重要的是,由于你掌握了这些概念,因此您、你不仅有机会学习它们的工作原理,而且有机会了解它们为什么很重要,并直接了解它们对成功软件项目的影响。

从求职者的层面来看,你向开源社区的对应项目做贡献,其实就是提升你个人在行业内的影响力,当你深入参与到一个开源项目并且向社区贡献代码或者提供解决bug的能力,那么猎头可能会来勾搭你;只要你有能力做出了相应的贡献,人家一般可以忽略你的年龄,肤色,学校而录用你,当然你的学校越好越好,这里是说这些公司相对应滴不那么看中你的学校出身而不像国内的某些单位必须要求你是xx学校毕业的。

当然还有其他的益处,比如你可能学会git的各种骚操作,认识来自全球各地的行业从业者,这里就不一一叙述了。

向开源社区所做贡献的途径和方法(参与社区的方法)

代码层面:

1.修复typo(个人不是很推荐,最Low的级别,但是可以用于练手)

2.Fix bugs(bug的难易程度参差不齐,bug越难,要求修bug的人的知识储备越高,这种层次已经开始有含金量了)

3.Add new features(这个要求你已经具备相当的基础甚至是更高级别的知识储备,含金量上了一个等级)

4.Add unit tests(这里吐槽一下中国很多大厂的开源项目都缺单元测试,大家可以去练练手,提交一个被合并就是贡献者了哦)

5.Update dependencies(有很多开源项目所依赖的第三方库可能有安全漏洞,存在安全隐患)

6.Review PR‘s (这其实是学习开源项目的一种有效方式,但是往往被很多人所忽略,包括之前的我自己)

非代码层面:

1.help the community (你可以订阅使用者邮件列表回答新人问题)

2.documents
1)add useful info (有的项目文档写的不够详细,你可以进行补充)
2)fix dead links(之前我就发现apache旗下的一个项目的文档里面存在这种问题)

3.Issues

1)report issues:当你在使用的过程中如果遇到问题,可以先查一下之前有没人遇到过类似的情况,如果没有,可以尝试开一个issue,如果是和这个项目相关的一些小白问题可以直接到邮件列表里面找,可能你会找到答案;实在不行,那就直接在社区里面问吧;

2)提问题的时候一定要提供相关信息,最好能让潜在的回答者能够再现你出问题的"案发现场"

向开源社区做贡献所具备的一些技术基础

我这里仅仅从java技术栈的角度来展开(其他技术栈我不是很熟悉,但是逻辑应该类似)
java语言的基础知识(包含这种数据结构和算法)肯定需要懂的,除此之外,可能还需要以下知识储备:

1.git需要非常熟练的掌握
这里推荐两个课程,一个免费的,一个收费的(其实我觉得网上免费的已经够用了)

2.单元测试和集成测试
框架和工具有很多,大家可以自己选择;
单元测试我学习的是Junit5
Java: Junit 4/5, Mockito

JS: enzyme, Chai Mochai, Jest, ReactTestUtils, Mock.js

Python: unittest, pytest

Go: testing, gotests, GoMock

集成测试我学习的是Jenkins
写测试的习惯可让让你的pr更容易被人家合并;
学习单元测试的另外一个好处就是在阅读项目源代码的时候你可以通过查看项目的单元测试来快速掌握项目的相关api;

3.重构和设计模式需要熟悉
如果这两者不熟悉,在阅读源代码的时候可能会不明白源代码为什么会这么写!

4.jvm相关知识需要熟悉
这里推荐《深入理解java虚拟机》一书
其他语言的话,相关底层知识也应该需要熟悉

5.多线程和高并发的知识也需要熟悉
很多项目的源代码里面也包含了多线程的设计模式
推荐书籍:《图解java多线程设计模式》《Java Concurrency in Practice》

我能想到的暂时就这么多吧;不同的项目可能还需要其他的一些特定的专业知识(比如你想为groovy项目做贡献,那得懂groovy,你想为spark项目做贡献,那你得懂分布式的相关知识)
当然并不是说要把以上所有知识全部掌握才可以为开源项目做贡献,因为bug的难度可能是不一样的,有高有低,那么可以先从简单的入手,feature也是同理;

如何更有效地学习开源项目的代码

1.下载完整的项目文档
这里指的是利用类似git这种工具来下载完整的源代码,而不是简单的下载source.jar。这样做的好处是你可以“跳跃”至这个源代码的任何一个版本以及从开始创建到目前为止的任何一个时间点。
2.示例代码与单元测试(集成测试)
示例代码可以帮助你学会使用相关开源项目的API。举个例子,如果你在某个项目里面想要用dubbo组件,可以google一下 dubbo samples;

阅读单元测试的好处:

  • 单元测试本身开发量不大,你很容易就能读懂相关代码

  • 每个单元测试都是可以独立运行的,这样节省你跟踪调试的时间。

  • 单元测试在很大程度上定义了软件的功能,可以帮你快速掌握项目的相关api。

  • 如果你修改了开源项目的源代码可以通过修改单元测试来验证你的修改是否正确。

3.架构文档

阅读架构文档主要是在你对代码的某块内容进行详细研究的时候能很快定位到相对应的地方。

在社区里面提一个问题的正确姿势?

其实不光在开源社区,在微信群里面我就遇到过很多不会提问题的人,就直接截个图,然后说有哪个指导指导,搞的好像人家能在你身上灵魂附体和你有心灵感应一样,殊不知很多情况下一个相同的错误可能是不同的原因所造成的!
在逛开源社区的时候我也发现很多问题无人问津,仔细一看,大多数情况是提问的人没有准确的描述出“案发现场”,导致旁观者相帮也帮不了你。
一般提问题的时候,你最好能够详细描述一下你所遇到的情况,包括版本信息之类的,以及具体的问题是怎么样的,必要时可以附上相应的调用栈信息,详细的信息描述可以减少信息交互的次数,提供信息交流的效率。在寻求帮助的过程中,请仔细阅读README,文档,以及检索以往别人提的相关问题。一旦你对这个问题的相关背景知识有了比较清楚的了解,你所提的问题就会一定深度,也更容易被维护人员关注,
最好有一个可以复现的例子,让潜在的想帮助你的人可以回到“案发现场”。
这里提供两个可以堪称典范的提问题的模板(一个简洁版,一个标准版):

提问题模板-简洁版

提问题模板-标准版

参与开源项目协作其他需要注意的

1.有很多项目的issue没有放在github里面,需要你搜索一下,举个例子:google: groovy issue tracker

2.commit message的格式尤其需要注意一下具体格式参见这里
大概如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JSx9x2A3-1598760329250)(https://imgkr2.cn-bj.ufileos.com/ab9b73ea-6f73-4974-b71e-77830e16bd5d.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=Sz4PVm20RXulvVQRYMhEamnUsck%253D&Expires=1598339079)]

3.如何提pr?
看这里
,现在github的官方文档很多都是以图文并茂的方式手把手教你怎么做,提交pr就是一个例子,或者你也可以看我之前写的一篇文章

4.礼仪相关

Apache社区行为准则

Apache社区礼仪指南

Apache邮件列表礼仪贴士

5.如何找到对新手比较友好的项目或issue

适合初学者问题

新手村-干货聚集

结束语

总体而言,参与开源开发是一个日积月累的过程,速成是速成不了的,但是一旦你的工作被越来越多社区开发人员认可,那你在社区的影响力也就越高,你的贡献被大家接受的可能性也也就越高。由此可见,如果你成为了开源社区的资深老鸟,那么你有极大的可能性将会成为这个世界上“拥有不可替代能力”的群体的一部分,最后祝大家在这场奇妙的开源之旅中有所收获,玩得开心!如果觉得本文写的不错,请点赞和在看吧,如果后期还想关注和开源相关的知识,请关注我吧!

在这里插入图片描述

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐