大学期间Linux C++后台开发这条线怎么走?

我也经常被咨询Linux C++后台开发的学习路线。然而当谈到Linux C++后台开发时,无论Linux还是C++都是一个很大的话题,聪明的程序员需要学会做减法

1

C++

简单谈一下C++。其实为了毕业找工作,熟练使用常用的C++语法就好了,当然C++11是必须要学习的。然后读几本C++的经典图书,学习一下安全编码、高效编码的规范。接着稍微研究一下C++底层原理就OK了。不要贪恋奇技淫巧,毕竟大学时间有限,语言只是一个解决问题的工具。我们还有更多高维的问题亟待解决。语言本身的高难知识日后慢慢学习就好了,很多时候书读百遍,不如实际工作中解决一个问题、实现一个需求掌握的快。好了,对于学习C++,网络上的学习资料太多了,本公众号之前和以后也都有大量相关文章,本文就不做展开了。

关于Linux,我想好好谈谈。大致分两块:一方面是Linux的使用;另一方面就是Linux的环境编程。

2

Linux的使用

关于Linux的使用。就多使用就好了,从自己装系统开始,多折腾折腾。熟练了以后你不想折腾想稳定的话,可以买个云主机,在上面写写代码,让自己习惯终端,习惯命令行。各种命令眼花缭乱,靠背肯定是不行,一定要多用。书不需要通读,有一本随时能翻阅的工具书就够了。

日常使用Linux其实还是比较蛋疼的,毕竟没有Windows和Mac那么丰富的桌面软件。Ubuntu之类的我大学也经常玩,但不管是GNOME,KDE还是Ubuntu自家那个桌面都经常崩。其他兼容性问题也不少,直到有一次更新完,网卡驱动出问题连不上WiFi,以致于让我折腾了很长时间以后。我逐渐意识到自己脱离了本质。沉浸在解决这种不该解决的问题之中,还自得其乐。后来我就用回了Windows(大学的时候没钱买MacBook),买了一个CentOS的云主机当自己的Linux学习环境(学生有优惠)。

Vim、Git的使用要熟练起来,在日后的工作中你离不开这两个工具。sed/awk也要学习一下,统计数据、定位问题的好帮手。其他各种零碎的小命令自然而然就会了(常见的用法经常忘可以记下来)。

此外呢,要学习Unix/Linux的一些基本概念、系统哲学。比如KISS、万物皆文件等等。不要觉得这些浪费时间,就当睡前读物或者厕所读物就好。这样更能激发你的学习兴趣,给你持久的学习动力。从Unix到Linux的发展历史,理清整个技术发展的脉络,了解那些光辉璀璨的人物和他们的英雄事迹。从里奇、汤普森,再到bill joy,从SMS到Linus。从开源运动的兴起到无处不在的Linux。这些故事不仅可以帮你产生学习的兴趣,也会让你学习到Unix/Linux背后的一些知识与设计哲学。

我推荐看一下这本《Unix & Linux大学教程》虽然名字像大学教材,其实是很经典的一本国外图书。当然你也可以先找本《鸟哥的Linux私房菜》来开开胃。我说的这本书则更像正餐,从英雄事迹到各种命令的用法,这里你都能看到。

3

Linux环境编程

初学者可能会对Linux系统环境编程一词有误解。这好像是介绍如何在Linux系统上写代码?其实不是,这里指的是如何使用系统的API来编程。这些API都是C语言的,但和我们课本里的不太一样。我们通常学的C,都是ANSI C(IOS C)是国际统一标准的,不管Windows还是Linux都适用,但是每个操作系统都有其独有的系统级编程的API。Linux的系统API是来源于(兼容)Unix的。Unix的API在几十年的时间内,逐渐形成了标准:POSIX、SUS。POSIX和SUS的区别这里不谈了,大致可以认为我们要学习的Unix环境编程的API就是POSIX标准。

当然说都是POSIX也不尽然,在Unix的世界里,仍然有一些非标的东西存在。比如在SystemV和BSD分庭抗礼的时期,新生的API就出现过割裂的现象。举个例子,我们经常谈到IO多路复用,select其实是起源自System V的,而poll则出自BSD。很多后来的OS都不严格区分API的起源,默默兼容着两套API,比如Linux,直到后来Linux 2.6推出了自己更高效的API:epoll。当然BSD后面也推出了新的kqueue(这个Linux就不再支持了)。除此之外呢,值得一提的是,我们常说的三大IPC:消息队列、信号量、共享内存(当然IPC不止这几个)对应的API:

消息队列

信号量

共享内存

msgget

semget

shmget

msgctl

semctl

shmctl

msgsnd

semop

shmat

msgrcv

shmdt

这些都是出自System V的。其实POSIX后来对这三大IPC也制定过自己的API标准,但是流行度就远远不如以上这几位老前辈了。这里看好像System V占了上风,但其实我们熟悉的socket那套API都是出自BSD,哈哈。

好了,一谈历史我就收不住,重新谈学习。我不建议一上来就找大部头阅读,从A刷到Z。我建议先随便去学校图书馆找一本薄薄的讲Linux C编程的书(尽量500页以内的),逐个章节建立起知识的框架。对系统编程有一个大体的认识。然后再去找一本大部头读一读。Stevens旷世三部曲其二的《APUE》《UNP》都是经典的图书,但其实我这里更建议的是这本《The Linux Programming Interface》(后面简称TLPI):

这本书直译就是《Linux编程接口》不知道为什么被翻译成了《Linux/Unix系统编程手册》,不过这不重要。《TLPI》行文风格,深入浅出。读起来更适合新手入门,作为长期的案边工具书也不错。我个人感觉是比《APUE》读起来更舒服的,而且也更加侧重Linux。另外这本书要比Stevens的那两本书年代要新,TLPI是2010年后出版,而Stevens 1999年就与世长辞啦,虽然其他人也给他的书修订过新版,不过我还是强烈推荐《TLPI》。

可以这么多API怎么学习啊?具体到我个人学习经历,由于我是一个患有重度笔记强迫症(compulsive note taker)的人,在大学期间,我在学习环境编程的过程中,每学一个API,都会去写一个使用demo,并且在github上写一个简要的wiki,久而久之和man手册类似。不过这个太花时间了,不推荐大家效仿了。不过无论如何多写代码总是没错的。

4

道讲完了,再谈一下术

具体到服务端开发,其实主要就是学习各种IPC、socket、IO多路复用(或者说事件驱动)、pthread(多线程),当然socket也是一种IPC,只是它太特殊了,socket的知识复杂度是超过其他IPC方式的,故而单列出来。一言以蔽之,侧重点就是网络编程啦。从多进程到多线程,再到IO多路复用。学完基础,去学一学网络模型,了解reactor(反应堆)和proactor(前摄器)的区别,学一学半同步/半异步模型(或半同步/半反应堆)、领导者/追随者。半同步/半异步模型的知识可以阅读这篇:

高山仰之可极,谈半同步/半异步网络并发模型

这些其实都是经典模型,当然工作之后遇到了brpc,则又是应用了另外一个稍高级的网络模型了。除了上面这些和C++语言之外就够了吗?不不不,还有TCP/IP和HTTP协议的知识。甚至你需要简单学一下HTML和JS。至少要知道前后端是如何交互的。

除了这些,以MySQL为代表的关系型数据库,以Redis为代表的内存KV数据库,还有MQ等等也是需要学习的。可以每一类找一个开源代表学一学。不一定要深入源码,因为组件层出不穷,学是学不完的,但至少要会用,知道如何使用这些组件去解决各种各样的实际问题(比如做个热门榜单,会想到Redis的zset)。

另外很重要一点就是,大学期间对于专业课不要逃课。很多自学编程的同学们总是看不上大学老师那点东西,不去上课。在寝室里自学点Web框架之类的。我不反对学习,但是因为学这些就不去上专业课,真的是舍本逐末。框架本身只是一个经验性的东西,学的就是一个熟练度。培训机构的学生培训三个月玩的比你熟,人家还带项目……当然你也可以去深入研究一下框架的背后实现原理,但我希望你能明白我的意思:学习框架不能成为逃专业课的理由。不要觉得操作系统、计算机网络、数据结构、计算机组成原理这种东西假大空、不实际。错错错,莫莫莫!

其实你把网络编程弄熟,弄一个小的网络库或者RPC框架都是没问题的。或者自己实现一个简易的HTTP Server、FTP Server,或者小Redis(解析几个命令,实现内存存储)之类的。不需要做到工业级别,主要是把核心的想法实现,剩下的很多其实是重复性的工作,以及性能提升的工作。

慢慢来吧,不要想着一口气学完(不可能的)。『以有涯随无涯,殆已!』先建立知识框架,尽量每个知识领域都有涉及,然后逐步填充细节。大学期间不能眉毛胡子一把抓,要把Linux和C++学的比其他的更熟练,其他技术对于大学生面试而言其实要求不高。并且随着工作的沉淀、经验的增长,很多知识其实会像倒排索引一样,慢慢填充到你的脑袋里,而不需要你对着目录从A到Z逐个学习。

相关文章

linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、...
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别...
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书...
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满...
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的...
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线...