0
点赞
收藏
分享

微信扫一扫

Linux C++开发的学习经验总结


文章目录

  • ​​1.Linux C++ 服务器端这条线怎么走?一年半能做出什么?​​
  • ​​(1)学习任何一门课程都要善于抓住主要矛盾、分清主次、突出重点,关键是掌握知识框架,学会以后真正有用的知识和技能,而不要把精力平均分配在一些琐事上。​​
  • ​​(2)注意分清知识的层次。​​
  • ​​(3)注意识别过时的知识。​​
  • ​​(4)如果你要记住结论,一定要同时记住前提和适用条件。​​
  • ​​2.集中大块的时间来学习那些本来只需要查查手册就可以明白的小技巧,而对于真正重要的、思想性东西放在平时零敲碎打,那么肯定是事倍功半,甚至适得其反。​​
  • ​​3.想做 C++ 方面开发,是基于 Linux 还是基于 Windows 平台?​​
  • ​​(1)应付C++校招面试​​
  • ​​(2)Linux C++与windows C++​​
  • ​​(3)C++语言基础与进阶​​
  • ​​(4)应付C++社招面试​​
  • ​​(5)学生与社会人士学习 C++ 的方式的区别​​
  • ​​4.学好c++至少要编多少个程序?​​
  • ​​5.针对C/Linux/C++方向,后端开发工程师如何发展​​

1.Linux C++ 服务器端这条线怎么走?一年半能做出什么?

划重点:

(1)学习任何一门课程都要善于抓住主要矛盾、分清主次、突出重点,关键是掌握知识框架,学会以后真正有用的知识和技能,而不要把精力平均分配在一些琐事上。

eg:
**学习操作系统的目的,**不是让你去发明自己操作系统内核,打败 Linux;也不是成为内核开发人员;而是理解操作系统为用户态进程提供了怎样的运行环境,作为程序员应该如何才能充分利用好这个环境,哪些做法是有益的,哪些是做无用功,哪些则是帮倒忙。

学习计算机体系结构的目的,不是让你去设计自己的 CPU(新的 ISA 或微架构),打败 Intel 和 ARM;也不是参与到 CPU 设计团队,改进现有的微架构;而是明白现代的处理器的能力与特性(例如流水线、多发射、分支预测、乱序执行等等指令级并行手段,内存局部性与 cache,多处理器的内存模型、能见度、重排序等等),在编程的时候通过适当组织代码和数据来发挥 CPU 的效能,避免 pitfalls。Modern Microprocessors

比如说操作系统, 应该把精力主要放在进程管理与调度、内存管理、并发编程与同步、高效的IO等等,而不要过于投入到初始化(从 BIOS 加载引导扇区、设置 GDT、进入保护模式)这种一次性任务上。我发现国内讲 Linux 内核的书往往把初始化的细节放在前几章,而国外的书通常放附录,你可以体会一下。初始化对操作系统本身而言当然是重要的,但是对于在用户态写服务程序的人来说,弄清楚为什么要打开 PC 上的 A20 地址线真的有用处吗?(这不过是个历史包袱罢了。)

比方说《计算机网络》,关键之一是理解如何在底层有丢包、重包、乱序的条件下设计出可靠的网络协议,这不算难。难一点的是这个可靠协议能达到“既能充分利用带宽,又能做到足够公平(并发连接大致平均分享带宽)”。而不是学会手算 CRC32,这更适合放到信息论或别的课程里去讲。

(2)注意分清知识的层次。

eg:
对于并发编程来说,掌握 mutex、condition variable 的正确用法,避免误用(例如防止 busy-waiting 和 data race)、避免性能 pitfalls,是一般服务端程序员应该掌握的知识。而如何实现高效的 mutex 则是 libc 和 kernel 开发者应该关心的事,随着硬件的发展(CPU 与内存之间互联方式的改变、核数的增加),最优做法也随之改变。如果你不能持续跟进这一领域的发展,那么你深入钻研之后掌握的知识到了几年之后可能反而成为累赘,当年针对当时硬件的最优特殊做法(好比说定制了自己的 mutex 或 lock-free 数据结构)在几年后有可能反而会拖低性能。还不如按最清晰的方式写代码,利用好语言和库的现成同步设施,让编译器和 libc 的作者去操心“与时俱进”的事。

(3)注意识别过时的知识。

eg:
比方说《操作系统》讲磁盘IO调度往往会讲电梯算法,但是现在的磁盘普遍内置了这一功能(NCQ),无需操作系统操心了。如果你在一个比较好的学校,操作系统课程的老师应该能指出这些知识点,避免学生浪费精力;如果你全靠自学,我也没什么好办法,尽量用新版的书吧。类似的例子还有《计算机体系结构》中可能会讲 RISC CPU 流水线中的 delay slot,现在似乎也都废弃了。《计算机网络》中类似的情况也不少,首先是 OSI 七层模型已经被证明是扯淡的,现在国外流行的教材基本都按五层模型来讲(Internet protocol suite),如果你的教材还郑重其事地讲 OSI (还描绘成未来的希望),扔了换一本吧。其次,局域网层面,以太网一家独大(几乎成了局域网的代名词),FDDI/Token ring/ATM 基本没啥公司在用了。就说以太网,现在也用不到 CSMA/CD 机制(因为 10M 的同轴电缆、10M/100M 的 hub 都过时了,交换机也早就普及了),因此碰撞检测算法要求“以太网的最小帧长大于最大传播延迟的二倍”这种知识点了解一下就行了。

eg:
另外一点是 low level 优化的知识非常容易过时,编码时要避免过度拟合(overfitting)。比方说目前国内一些教科书(特别是大一第一门编程语言的教程)还在传授“乘除法比加减法慢、浮点数运算比整数运算慢、位运算最快”这种过时的知识。现代通用 CPU 上的实际情况是整数的加减法和乘法运算几乎一样快,整数除法慢很多;浮点数的加减法和乘法运算几乎和整数一样快,浮点数除法慢很多。因此用加减法代替乘法(或用位运算代替算术运算)不见得能提速,反而让代码难懂。而且现代编译器可以把除数为小整数的整数除法转变为乘法来做,无需程序员操心。另外一点是 low level 优化的知识非常容易过时,编码时要避免过度拟合(overfitting)。比方说目前国内一些教科书(特别是大一第一门编程语言的教程)还在传授“乘除法比加减法慢、浮点数运算比整数运算慢、位运算最快”这种过时的知识。现代通用 CPU 上的实际情况是整数的加减法和乘法运算几乎一样快,整数除法慢很多;浮点数的加减法和乘法运算几乎和整数一样快,浮点数除法慢很多。因此用加减法代替乘法(或用位运算代替算术运算)不见得能提速,反而让代码难懂。而且现代编译器可以把除数为小整数的整数除法转变为乘法来做,无需程序员操心。(目前用浮点数乘法代替浮点数除法似乎还是值得一做的,例如除以10改为乘以0.1,因为浮点运算的特殊性(不满足结合律和分配率),阻止了编译器优化。)

eg:
类似的 low level 优化过时的例子是早年用汇编语言写了某流行图像格式的编解码器,但随着 CPU 微架构的发展,其并不比现代 C 语言(可能用上 SIMD)的版本更快, 反而因为使用了 32-bit 汇编语言,导致往 64-bit 移植时出现麻烦。如果不能派人持续维护更新这个私有库,还不如用第三方的库呢。现在能用汇编语言写出比 C 语言更快的代码几乎只有一种可能:使用 CPU 的面向特定算法的新指令,例如 Intel 的新 CPU (将会)内置了 AES、CRC32、SHA1、SHA256 等算法的指令。不过主流的第三方库(例如 OpenSSL)肯定会用上这些手段,及时跟进即可,基本无需自己操刀。(再举一个例子,假如公司早先用汇编语言写了一个非常高效的大整数运算库,一直运转良好,原来写这个库的高人也升职或另谋高就了。Intel 在 2013 年发布了新微架构 Haswell,新增了 MULX 指令,可以进一步提高大整数乘法的效率 GMP on Intel Haswell ,那么贵公司是否有人持续跟进这些 CPU 的进化,并及时更新这个大整数运算库呢?或者直接用开源的 GMP 库,让 GMP 的作者去操心这些事情?)

(4)如果你要记住结论,一定要同时记住前提和适用条件。

Linux C++开发的学习经验总结_汇编语言

2.集中大块的时间来学习那些本来只需要查查手册就可以明白的小技巧,而对于真正重要的、思想性东西放在平时零敲碎打,那么肯定是事倍功半,甚至适得其反。

Linux C++开发的学习经验总结_位运算_02

3.想做 C++ 方面开发,是基于 Linux 还是基于 Windows 平台?

参考知乎回答:
​​​https://www.zhihu.com/question/23534399/answer/615561123​​

简要提纲如下:

(1)应付C++校招面试

(2)Linux C++与windows C++

(3)C++语言基础与进阶

(4)应付C++社招面试

(5)学生与社会人士学习 C++ 的方式的区别

基础:​​https://mp.weixin.qq.com/s/EjgtX2Wghia7ajn2AugCtw​​

4.学好c++至少要编多少个程序?

参考:​​https://www.zhihu.com/question/318466837/answer/651356400​​ 回到软件开发问题上,真要学好c/c++,除了要学会语言本身,需要往三个方向突破。

5.针对C/Linux/C++方向,后端开发工程师如何发展

参考:​​https://zhuanlan.zhihu.com/p/29148848​​


举报

相关推荐

0 条评论