一个普通码农的Linux之路

1.

Hi,大家好,我是奔跑的码仔,是一名长期混迹于Linux江湖,靠Linux吃饭的程序员。生活在一个IT大环境不好的二线城市,大家也知道,这里的程序员本来就很稀少,况且是Linux程序员呢,就更是稀有物种了!可是,不是有那么一句老话嘛,物以稀为贵。你还别说,虽然,这里的Linux岗位较少,但是,薪资总体还是蛮有竞争力的。所以,才会有时间来总结自己的Linux学习之路(不然,早就去加班挣生活费了,哈哈)。
但是,最近,自己总是焦虑一个事。那就是自己虽然一直以Linux为生,这些年,也接触了不少的Linux的技术(这些技术不管是工作上用的着的,还是自己感兴趣利用业余时间自学的)。但是,仔细一想,和Linux接触这么长时间,自己真正可以拿的出手的作品好像没有多少,一些学习心得也没有及时的形成文字记录下来,在自己所从事的领域也没有形成技术影响力。作为一个技术人,每每想到这些,内心都十分的失落。所以,思来想去,为了能够更好的学习Linux,也为了能够接触更多的志同道合的人,我决定,以文字的形式记录下我自己的学习过程。顺便,如果这些文字能够能给大家带来些许收获,那我将感到十分的荣幸。其实,记录自己的学习、成长轨迹是一个很好的学习方法,这些文字日后会形成宝贵的财富,这样当自己回望过往时,就不会因为碌碌无为而悔恨和遗憾了。下面开始述说我自己的一些经历和体验。

2.

记得,第一次接触Linux系统,是从大三的Linux高级程序设计这门课开始的。不知不觉,与Linux相伴已经有将近8个年头了。依稀记得,当初刚开始接触Linux时的那种迷茫、无助的感觉。因为习惯了Windows“友好”的使用界面,常常被Linux命令行的使用模式而弄的狼狈不堪。而且,记得那会儿尝试过很多种Linux桌面发行版本,什么Ubuntu 9.10(时间过得真快,现在都19.10了)啦,Debian啦,CentOS啦,SUSE啦等等。有人可能会问,为啥这么花心,感情也太不专一啦!哈哈,说出来原因,大家可能会笑话,原因大概为两种:一种是系统老是崩溃,所以得重装,重装时就想试试其他的版本是不是好用,其实是因为自己技术太菜;另一种就是不会安装软件,对于初学者编译、安装Linux下软件简直太痛苦了。那时候经常能够遇到的场景就是,系统环境不支持某些应用,所以需要自己手动的配置依赖库啦,安装新的环境啦,但是不会啊(相信,这也是也是很多初学者入门Linux的障碍),又迫于完成作业或者课程设计,只能不断的尝试不同的发行版本,不同的搜索前人的解决方法,有时实在找不到解决办法,最后只能不了了之!这就是我痛苦的Linux自我启蒙阶段。虽然,这个阶段比较痛苦,但是,凭着那股子傻劲,最终没有放弃Linux的学习,坚持了下来。想到这,内心还是有些许安慰的。

3.

后来,参加了工作,结束了之前非专业的学习、开发模式。开始接触一些真正的项目了,真正的开始学习如何基于Linux系统进行开发。这也是我技术能力成长较快的一个阶段。记得,那时开发的第一个项目是一个关于网络数据分发的系统,底层框架是基于ACE的(那时候ACE是Linux系统下网络开发的标准框架吧),我负责的是SNMP客户端的设计、实现工作。也是从那时,我开始了解如何编写Linux网络程序、如何使用GDB调试Core文件以及如何使用Linux系统各种各样的系统调用。也是在那段时间,我买了UNIX界的圣经《UNIX环境高级编程》,并开始研读,这本书十分的系统,几乎涉及到了类UNIX系统开发的方方面面,作者对技术的精准讲解,令人叹为观止。工作中,大部分涉及到Linux系统的开发问题,几乎都能在里面找到答案,可谓是Linux开发者的良师益友。我觉得,如果选择了Linux开发这个领域,这本书是不得不读的,而且要反复的读,因为大量技术细节不是一遍,两遍就能理解的了的。还有,我发现,这本书有一个十分的神奇地方,那就是随着自己工作经历的增加,每次研读,从书中我都会有新的收获。这一方面说明自己对技术的理解力在不断的提高,另一方面也说明,这本书里不仅仅是对技术知识的单纯讲解,最重要的是,他是有思想和灵魂的,而这就是Linux能够长盛不衰的根本原因吧。那段时间的工作经历使我明白了Linux系统是什么,基于它能实现什么功能,以及如何基于它实现自己的想法。我觉得从那之后,自己算是入门了。后来,随着工作的深入,我渐渐开始了解Linux的底层工作原理,像进程是啥,线程是啥,他们如何工作?进程和线程如何相互通信?Linux内存是如何管理的?Linux的TCP/IP协议栈是如何设计实现的等等。虽然,这些东西十分的硬核,学起来十分的痛苦。但是,越是不懂我就越觉得它神秘,也就越想去了解它,慢慢的的也就喜欢上了这种感觉。其实,对未知领域的探索,并最终能够理解它的过程,是能给人带来无尽的成就感的,那是一种美妙的享受。

4.

之后,由于换了工作,开始接触嵌入式Linux的开发。嵌入式Linux开发,需要更为全面的Linux技术,而且是十分底层那种,因为你常常需要解决的是如何从无到有的设计一个系统。例如,给你一个硬件平台,你需要从零搭建BootLoader、Linux内核、根文件系统、系统工具这一整套系统。这就需要你不仅懂得如何基于Linux平台开发应用程序,还需要理解诸如编译器原理,Linux内核移植,文件系统的构造方式和原理,驱动程序的编写,Make构建系统,shell脚本等等基础知识。这个阶段,我从系统层面了解了Linux系统在嵌入式系统上的应用方式和开发模式,进一步增强了对于计算机基础原理的理解、认知。那么,如何能够快速入门嵌入式Linux呢?我的是方法是多看、多学习行业社区的实践,然后将学到的技术及时的应用到工作中去,最终内化自己的技术。嵌入式Linux相关的社区有很多,比如,著名的路由器固件OpenWrt,系统构建系统buildroot、交叉工具链发布者linaro等等。我们可以挑选自己关心的领域,然后积极的参与进去,社区里高手林云,我们可以和他们零距离的接触,学习到很多高阶的技术,这对于自己今后的技术职业道路大有裨益。最后,说一下,对于学习Linux内核的看法。嵌入式Linux开发,会或多或少的接触到Linux内核的东西。但是,常常接触到的都是某一个点的技术,常常有一种身在林中不见林的感觉。**这时候,个人经验就是跳出固定的技术点,去尝试理解这个点所在的”林“,也就是去理解整个子系统,重点搞懂子系统在整个系统的位置、作用,子系统的框架,抽象模型,然后就是如何基于子系统提供的模型进行功能模块的设计、开发等。**例如,某款芯片基于I2C通信的,这时候,我们就需要去了解I2C子系统的框架和编程模式,然后再去实现具体的芯片的驱动程序的设计和开发。而且,Linux内核的各个子系统的设计思想是想通的,只要彻底搞明白几个系统,其他的子系统大都类似,这样,你就可以触类旁通了。

5.

如今的Linux技术遍布各个领域,比如,数据中心的服务器几乎都是基于Linux系统构建的,IoT领域的设备端也有很大一部分是基于嵌入式Linux系统构建的,再比如,时下如火如荼的AI,也有很多的关键部件是基于Linux构建的。可以说,Linux无处不在,Linux已经成为了整个计算机世界的基础核心技术,相信未来的Linux技术必定大放异彩。但是,Linux的学习之路是十分陡峭的,刚开始的时候可能十分的痛苦。那如何才能避免Linux学习之路的”开始即结束“的困境呢?结合自己的亲生经历,谈谈一些感想:

1. 切勿好高骛远,学习还需脚踏实地。

Linux世界的技术,纷繁复杂,其有很多的技术特别有吸引力。有些人一开始,为了追求这些高精尖的技术,就奋不顾身的投入到了Linux内核的学习之中。比如,当前流行的容器技术,在没有上手实践容器应用之前,就开始学习Linux内核关于容器的实现原理,然后,一头扎进浩如烟海的Linux内核代码之中。这类人最后基本都是由于缺乏Linux基本技术认知,而最终“淹死”在Linux内核的海洋中。所以,对于刚开始接触Linux的人来说,还是要脚踏实地的去学习Linux的最为基本的技术。我的建议是,首先是丢掉之前靠鼠标点击操作计算机的习惯,逼自己去习惯Linux命令行的操作模式。就从,最最简单的命令开始学习,通过命令行操作去理解Linux系统的工作方式、运行原理。这里,推荐《鸟哥的Linux私房菜》,这本书可以说是Linux入门的圣经,里面详实的讲解了Linux系统方方面面的命令操作,是Linux命令的百科全书。可以说,这本完全可以帮你打开Linux的这扇大门。还有一点建议就是,对于Linux命令的学习,切记,不能纸上谈兵,任何一个命令都得上机进行实操,只有这样你才能直观、真切的体会到命令的高效和价值。这是第一点建议。

2. 层层递进,步步为营。

在有了一定的Linux系统操作经验之后,可以尝试基于Linux系统做一些开发项目。可是,Linux系统的开发能力实在太强,可以做的事情实在太多太多了,对于新人来说可能感到无从下手。这里,说三点建议:

  1. 第一就是以工作内容为导向,由点及面,步步为营
  2. 第二就是系统性的学习Linux的环境编程,这里推荐通读《UNIX环境高级编程》
  3. 第三就是选择基于Linux的开源项目,分析其使用到了哪些Linux技术,以及如何运用的,而后如何形成一个系统,其系统框架是怎样的等等。

其实,这三点存在层层递进的关系:首先,工作中用的知识比较零散,经常遇到的问题大多只涉及某个技术点,形成不了系统,而通过系统学习Linux环境开发相关的经典书籍可以加快促进将技术点形成技术面,从而最终系统化技术。之后,再通过对于优秀的开源项目的分析、学习,可以进一步的加深对于Linux系统的整体认知,丰富我们对于Linux技术的应用方式。经多几次详尽的开源项目分析,从而,最后逐步的掌握Linux系统开发的精髓。

最后,关于Linux系统API的使用谈一下自己的建议。开发过程中,免不了会经常涉及到各种Linux系统API的使用,这其中包括系统调用和glibc函数。如何正确的使用这些API进行开发呢?我的建议是,拿到一个函数API之后,第一件事就是使用man手册进行查看。为什么呢?因为,man手册的编写者一般都是API的开发者或者维护者,里面详细介绍了该API的功能,基本原理,参数解析,返回值。更关键的是,它会详细的说明API的注意事项,使用限制,存在的bugs等,这些可以让你避免大多数坑,从而一开始就让你写出健壮的程序。所以,坚持man是学好Linux的良好的习惯,也是最有效的开发、学习捷径。

3. 技术无止境,学习要更上一层楼。

在有了较长时间的Linux系统开发经验之后,我们可能会不满于简单的使用linux进行应用开发了。那如何才能在Linux领域更上一层楼呢?其实,目前,我也处于这个阶段,没有太多的发言权。只能说一下自己的一些经验,供大家参考。我的经验有两个:

  1. 第一个:根据自身行业特点,找到工作痛点,然后编程解决该痛点。 或者为了提高开发效率,设计实现开发工具库,甚至开发框架。拿我自己来说,以前拿到一个新项目后,总是需要从头设计、开发各个基础工具库,比如日志系统,线程管理模型,线程同步模型,字符串处理模型等,这样大大降低了开发效率,极大的浪费了开发资源。后来,我整理了各个项目使用到的各种基础构件,对其进行了重构,最终整合形成了一套应用的基础开发库。这样做的好处有(1)极大的提升开发效率。(2)极大的提升系统的稳定性。对基础库的每次使用,其都是一次蜕变,bug越来越少,进而,提升系统稳定性。

  2. **第二个:有效的学习Linux内核。**对于Linux内核学习,我也是一个菜鸟。虽然,之前进行了一些内核移植和驱动的开发工作,但总觉得那些只是基于Linux内核在进行应用开发,没有真正的从操作系统的角度学习到Linux的设计精髓。所以,我开始了对于内核的学习。但,我不建议,内核新人一开始就阅读那些大部头的内核经典,不是说它们的内容不好,相反,它们写的太好了,只是不适合初学者。**我的理解是,这些经典,有一个问题是,对某个技术点诠释的特别到位,但是对与内核的整体框架以及各个子系统之间的关系缺乏解释。这就是十分容易使人陷入具体的细节之中,而不能对系统有一个整体的认识,最终,花了很多的精力还是不能理解内核。**我的做法是,对于某个系统的分析,不急于理解具体细节,首先梳理系统的各个主要流程,找到系统的各个关键点,对系统在脑子里有一个总体的理解。然后,再深入去学习具体的实现方式。由于脑子里,一直有一个总体的概念,不至于在学习的时候迷失方向。**就好像,在一个陌生的地方,手里有一份地图,无论怎么走,都不太容易迷路一样。**所以,内核的学习,我的方法是脑子里先形成内核地图,然后在再按图索骥,各个击破难点,最终理解整个内核。

6.

说了这么多,都是自己这一路走来形成的一些想法。但由于个人技术能力的限制,肯定有很多理解的不恰当的地方,还望大家多多包涵。欢迎志同道合之士,前来切磋指教。最后,我想说的是,技术无止境,没有所谓的万能之法。作为技术人,我们只有不断的奔跑,积极的去面对变化,才能立于不败之地。

你可能感兴趣的:(Linux,Thinking)