我对"看源代码"这一行为的看法

随着互联网的发展,分工是越来越细,过去的那种"孤胆英雄"式的程序员成为了历史,现在分工越来越细, 各种编程语言、开源软件变成越来越成熟便利,然而这种趋势对于公司来说无疑是利好,因为可以减少成本,快速上线运行。但是对于广大的程序员来说,无疑是利空的。尤其对于数量众多的业务部门来说,他们不仅有年龄焦虑,还有技术焦虑。

解决焦虑的办法无疑是学习,是成长,是疯狂的内卷。光靠铺天盖地的各种卖课活动就能感知一二。现在在知乎,csdn,sg等技术网站上,很多文章都会夹带私活卖课。而在各个公司内部,各种早读会,技术分享活动都如火如荼的开展起来。就我所待过的公司,基本是每周都有一两次技术分享,隔壁部门甚至每天早上早到一个小时进行早读会。在这些活动里面源码阅读占了大头,因为我们日常使用的软件和编程语言都是开源的,而且基本都已经存在很多源码解读相关的书。只要按章节组织PPT讲解就好了。

虽然我觉着那些活动都太过浮躁,主要是个噱头,学不到啥。但不可否认,阅读源码的好处多多,包括但不限于:

  • 熟悉日常使用的软件的运行原理,扬长避短,提高程序的效率和稳定性
  • 了解先进的架构思想和编程技巧
  • 提高基本的计算机素养,构建知识体系

实际上,在我的技术生涯,我也看过源代码,包括tornado, muduo, nginx, lucene, redis等。它们让我收益良多。

但是当我参与了一些分享会,看了一些网上免费的知识付费课程后,感觉一切似乎有些变味儿了。甚至某一天,组里一个小伙伴私下跟我说,他参加了很多分享会,学习了很多源码,看了很多技术文章,但是仍然还是稀里糊涂的,除了知道了很多概念和名词。在面试的时候,一些专业术语张嘴就能说出来。但是这些知识并不能让其安心,心里依然空荡荡的,搞不清楚跟实际工作有什么联系,焦虑感一丝也没有减少。

鉴于此,我就对阅读源代码谈谈自己的看法。

看源代码对基本功要求较高

这一点似乎跟我前面说的看源代码的好处矛盾,其实,读源代码肯定是大有好处的。但是如果功底不够,就会硬生生的把源代码学习搞成了背诵八股文,多是名词讲解和科普。

在我参与的大多数技术分享,以及知识付费里,知识都很分散,大部分是原理讲解,配合具体代码示例。如果只是记住了基本模型和名词,自然就成了八股文背诵。在阅读源代码之前,起码对操作系统,数据结构与算法,计算机网络有一定的了解,对c/c++无障碍阅读。更重要的一点是,对常见的一些常见的高效的写法熟悉,比如字符串优化, 内存复用, xx池, 异步io,很多你惊叹的奇技淫巧,其实都只是很常见的套路。

看源码其实是为了求证

当你在使用某软件的时候,你有没有想过它是怎么运行的?它有哪些主要模块?它高效的秘诀是什么?

我想如果是个有心人,这些问题肯定想过,甚至在网上看过相关资料。

所以你在看源代码之前必须先把核心架构逻辑弄清楚,想一想,假如你是作者,你该如何去实现这个软件。

在你心中已有完整的脉络,这个时候你去看源码,自然就豁然开朗。

比如我听过不同部门两次go的map源码解读,可惜的时候,讲的人脑子没有清晰的脉络,听的人就更是一脸雾水了,

你在看go的map之前,起码要知道常见的map的两种模式sorted_map和unsorted_map,它们分别是如何实现的,然后你再去go里去验证,看看go的作者有哪些独到的设计,这些设计又有啥优缺点,它们如何管理内存的分配的,又是如何在性能和资源占用方面进行取舍的。如果是你,你又会如何去设计。

这有这样,你才能真正看明白go map的源码,才能有所收获。

只有创造才能学到技术

不少人花了不少钱订阅了一些付费课程,知道了很多高大上的术语,队列,缓存,分布式,容器,熔断,高可用…….都能说得头头是道,然而却什么事都没做成。

我之前也是这样,一些专业术语张嘴就能说出来,以为自己很牛逼,但是后来发现知道这些东西并不能给我带来帮助。

因为我们都进入了一个误区,以为知道了名词就等于拥有了知识。尤其很多人没有机会进入大厂核心岗位,所以对所谓“高并发大数据”非常崇拜,于是找各种大牛写的关于架构方面的文章,三句话不离高并发大数据,但是稍微追问一下,就会发现很多都停留在概念阶段。

没有实践作为支撑的知识都是在扯淡,就如同你知道了反冲原理,但是离造火箭,还差着十万八千里。

只有尝试寻思用所学的技能去做点小东西,一步步的把理论变成实际,一个个去造轮子,才能将知识固化下来。

所谓的造轮子,即把已经有的技术成品重新实现一遍,这件事对工程项目无价值,但对学习却有着不可估量的价值。每次造轮子的时候,你就会很自然地明白,这个轮子解决了什么需求点;甚至同时搞明白,这个轮子的制作思路是如何的,是如何一步一步做出来的。

如此一来,你就把心中技术海洋地图的一小块绘制了出来,并且知道了其在整个海洋中的坐标。下次,相关问题你的思路就会更加清晰。

我相信很多人或多或少都看过 mysql,redis,NGINX源代码,很多人都会在简历里写上精通 xxx。但这种只能唬唬不懂行的面试官,遇到水平高的面试官很容易就卡壳了,毕竟写过和了解过还是有很大区别的。

比如很多人都看过redis源码,你问他redis的细节,他可能张口就来,还能抢答,举一反三,尽可能地jiang他知道的和盘托出。

但你问他如果要将redis改成多线程,需要做哪些工作?他一下子就答不出来了,因为他根本就没实际写过多线程编程,更不会知道在实际中的各种坑。

我也一直都坚信,

熟悉mysql,就必须写出一个mysql,

熟悉 NGINX, 就必须写出一个 nginx,

熟悉 redis,就必须写出一个 redis。

这里写出并不是说要写得跟原软件一摸一样,而是能实际跑起来,实现其最核心的 20%的功能。

只有这样,你才算真正掌握了。