[编程开发] 坚持每天写代码,真的能提高编程水平吗?

[复制链接]
村痞 发表于 2023-10-9 01:27:23|来自:北京 | 显示全部楼层 |阅读模式
坚持每天写代码,真的能提高编程水平吗?
全部回复5 显示全部楼层
lfz3999 发表于 2023-10-9 01:27:33|来自:北京 | 显示全部楼层
谢邀。
很多同学在做开发工作五六年后,突然感到迷茫和无助了。照理说,写了这么多年代码,编程水平也在不断提高,但是找工作的时候却发现缺少技术竞争力,薪资也谈不上去,高不成低不就。
究其原因是,大多数时候写的是很多熟悉的、重复的业务代码,缺少总结和反思,尤其是对各种技术原理的深入学习、理解和积累,所以高贵的程序员成为代码装配车间的流水线码农。
一言以蔽之,即使坚持天天写代码,如果不注重技术原理的学习,不总结与反思,只能浮于技,而匮于艺。
下面根据我的经验来谈一谈,如何提高编程水平,提高核心竞争力。
一、不要埋头写代码,理解业务

在当前国内大环境下,大多数人学的大多数技术并不能让开发者致富,所以不要埋头写代码,要理解产品、理解业务,计算机是死的,只要逻辑没问题,运行结果一定会正确,但人是多变的,不同时候输入相同,反馈可能不一样,学会与人沟通,提高沟通和表达能力。
二、开发时,先规划框架,再到局部实现

思路未考虑清楚之前,不建议动手,很多同学拿到工作内容后,上来就开始写代码,尤其是在设计一些关键步骤时,最后写出来不是有偏差,就是考虑不全。举个例子,我们可以利用 TODO 标记在开始写代码之前,确定我们代码的逻辑步骤。例如:
//TODO: 1. 处理定时器逻辑
//TODO: 2. 利用IO复用函数检测socket上的读写事件
//TODO: 3. 处理socket读写事件
//TODO: 4. 处理其他任务再比如,我们要设计一个 HttpServer,我们可以先规划一些类,例如 HttpServer 类,HttpSession 类,HttpSessionManager 类,HttpConnection 类以及用于客户端的 HttpClient 类等等。
那从哪里可以学习到这些知识?

  • 学习设计模式
  • 学习面向对象思想
  • 学习常用的一些编程范式或者惯用法,如 C++中的 PIMPL 。
设计模式的书推荐《大话设计模式》和《图解设计模式》:
《大话设计模式》  
链接:https://pan.baidu.com/s/1HA6uVJaYy3W4Ww1SrTg0-g 提取码:u3e2  
《图解设计模式》  
链接:https://pan.baidu.com/s/1RMQJ5OR33asB9sJWx1ogvA  提取码:06yl
关于系统设计的推荐《大规模 C++ 程序设计》《C++ API 设计》《重构 改善既有代码的设计》等经典书籍:
《大规模 C++ 程序设计》  链接:https://pan.baidu.com/s/1UElLtFuZB8kx6TmtKR0COg  提取码:unr8   《C++ API 设计》  链接:https://pan.baidu.com/s/1QD-cLkCBHKsOCm2Axr--mw  提取码:7d4o   《重构 改善既有代码的设计》  链接:https://pan.baidu.com/s/1hB4b_YHURckemVqigSC8ww  提取码:lrkp
三、培养良好的代码风格

代码风格很重要,这个在开始学编程的时候就需要培养,有的同学平时写代码随手命名甚至用汉语拼音命名,这种习惯一旦养成,后面很难改掉”。
变量、类和函数等命名要清晰,例如表示名称的变量一般用名词或者形容词、动词过去式修饰的名词等,函数一般用动词或者动词加宾语的结构等。加减乘除等运算符左右各一个空格,有良好的缩进(将 IDE 的 Tab 设置为插入四个空格而不是一个 \t),变量命名以业务背景描述,而不是无意义的字面意思。注释量不少于代码总量 20%,在关键算法或者关键逻辑出给出详细的注释,对于一些存在意外情况暂时不修复的代码加上 TODO 或者 FIXME 标记,对于一些不直观或者很绕的逻辑,加上详细的注释,以方便他人或者之后自己回顾或者 review 代码。
这里涉及的点很多,最琐碎,如果你觉得自己的代码风格不好,可以看看下面的经典书籍。

  • 《代码整洁之道》
链接:https://pan.baidu.com/s/1empDg_BK25QCLVJvsRo5vg  提取码:dt5y


  • 《程序设计实践》
链接:https://pan.baidu.com/s/1476NnN8hEGH-Lo78fWr-2w  提取码:dsoo
这两本书我强烈推荐一下,尤其是对于应届生和写代码年限不长的同学,这两本书的特点是从基本的变量命名、注释、宏定义到一大段代码的设计,详细地给出了最佳代码风格实践。

  • 《Google C++编程风格指南》
链接:https://pan.baidu.com/s/1DtgxMaLzEgE9JLDZvz5G7g  提取码:1nvh
四、注重代码运行效率

例如,查询时使用效率更高的数据结构和算法,减少遍历;循环之前,将循环累计计数先计算出来,而不是每次都计算;减少内存拷贝,减少对象构造等等,使用池化技术(内存池、对象池、连接池等等)。
这一点的话,需要不断的积累,和对一些原理性的东西的理解,例如学习 C/C++ 可以学习下汇编,知道编译器将 C/C++ 代码编译成什么样的机器指令等等。
推荐 :

  • 《程序员的自我修养—链接、装载与库》
链接:https://pan.baidu.com/s/17BmI5Dh2u11rOz6SW0tpJA  提取码:s63b


  • 王爽《汇编》
链接:https://pan.baidu.com/s/1Jfxk8nFZNuJ6qZFE9vRg1w  提取码:29xx


  • 《老码识途 从机器码到框架的系统观逆向修炼之路》
链接:https://pan.baidu.com/s/13YL8xRIYCwsfgdVANpmmzw  提取码:pn12


  • 《C++反汇编与逆向分析技术揭秘》
链接:https://pan.baidu.com/s/1E-RwP53BAsP6mKtx9zjK-A  提取码:5cia
五、掌握一些编码原则与范式,规避一些出错可能

例如,定义变量时尽量给一个有效的初始值,释放指针对象指向的资源时,尽量将指针设置为 NULL(对于 C/C++ 程序排查一个空指针问题远比排查野指针问题要容易得多),使用 RAII 技术保证资源在每条出口路径上都会被释放,多线程加锁时,尽量减小锁的粒度,加多个锁时,锁的方向一致,避免死锁等等。
六、解决问题时,对于原理性的问题,不要面向搜索引擎编程。

很多同学在遇到问题时,习惯上去百度等搜索引擎上去寻找答案,解决问题后,就直接过去了,下次遇到同样的问题,可能又去搜索引擎继续搜索,这样日复一日,功能做了一个又一个,技术毫无长进。建议当我们通过搜索引擎解决了某个问题,如果是原理性的问题,一定要在之后去搞清楚其背后的原理。要记住,解决业务问题,可以帮老板成长,掌握技术原理,才能帮你成长。
七、注重基础知识的学习,不忙碌跟风新技术

基础知识包括 C 语言、Linux 基本操作、算法和数据结构、操作系统原理、网络编程、数据库原理等,这些知识都是非常重要的基础,需要且有必要熟练掌握。大多数新的技术、新的框架都是在这些基础原理之上构建的。
尤其是对于工作年限比较长的程序员,如果靠着体力和加班和年轻的毕业生竞争肯定是竞争不过的,你的竞争力应该着眼于你的技术积累和工作经验。
1. C 语言

对于 C 语言,要熟悉 C 语言的基本语法,包括:

  • 顺序、条件、循环三大控制语句
  • C 中几大基元数据类型的用法
  • 熟悉掌握数组的用法
  • 熟练掌握指针的用法
  • 熟练掌握结构体、枚举、联合等数据类型的用法
  • 熟练使用常用 C 库函数,如控制台输入输出流、字符串操作、文件操作、时间函数等等
这里给大家推荐《C语言程序设计 现代方法》,这本书的作者和译者都很牛,是非常经典的 C 语言教材。


这本书在国外是作为经典大学教材的,两位译者一位是亚洲理工大学,一位是中科院,书翻译的也很地道。强烈推荐一下,有网友分享了本书的电子版(链接收集于网络,喜欢请购买正版):
链接: https://pan.baidu.com/s/1MEr7kEkoDEmDboEAQhIhzw 提取码: 93k0
当然,如果你熟悉了 C 语言的常用语法后,你想进一步针对 C 语言的一些细节和高级特性进行查漏补缺,推荐看看《C 专家编程》:
链接: https://pan.baidu.com/s/13iF1CvUNo2CX1CyHVfNhOQ 提取码: jm7e
不要偏听偏言说,指针是洪水猛兽,是糟粕。指针是 C 语言乃至计算机操作系统核心和精华,所以指针一定要搞明白。
但是无论是 C 还是 C++,指针一直是很多初学者的老大难,可以把指针作为一个专题彻底搞明白,关于这方面也有一本非常好的书,这本书的语言写的也非常通俗易懂,我当年读完之后,对指针再无疑惑,书名叫《C 和指针》:
链接: https://pan.baidu.com/s/1omTnXnU7X_fJW4Tkm4CfRw 提取码: b4eq
指针是 C 语言乃至整个操作系统的灵魂,一定要理解好。
2. 学好 Linux 常用操作和理解一些 Linux 原理

建议读者多玩一玩 Linux 操作系统,可以在自己电脑上通过虚拟机安装一个 Linux 系统(如 CentOS、Ubuntu)。自己在虚拟机中安装 Linux 系统的好处是你可以任意把玩这个系统,只要愿意可以搞清楚这个系统的方方面面。
如果你的机器配置不行,或者不愿意自己安装 Linux 系统,可以花一点费用去各大云主机上(如阿里云、腾讯云)买一些低配的 Linux 主机空间来玩,然后用 XShell、SecureCRT 这样的工具去远程登录到云主机上去玩。下图就是我使用 SecureCRT 连接到我的阿里云主机上进行操作:


良好的英语水平也能帮助你记忆一些 Linux 命令,如 ls => list,lsof => list opened file。其实 Linux 系统常用的命令并不多。
有一些 Linux 操作你一定要理解其背后的原理,比如经常有一些学生来面试,告诉我熟悉 Linux 系统,我就问他 Linux 下如何判断一个文件是可执行文件,很多同学只知道可以使用 chmod +x 授予执行权限,却不知道这个权限怎么看。
除了系统地阅读一些 Linux 书籍之外,平常可以找一些 Linux 各种小技巧的文章来看一看。比如一些同学可能不知道 vim 中如何复制粘贴、如何撤销一个操作、命令行中如何在从一键跳转到命令行的开始或者结尾处、如何使用命令与 Windows 系统之间传输文件等等。
这些技巧可以自己收集于网络,也可以自己细心观察学习自你的同学、同事等等。
推荐几本学习书籍:
《Linux 就是这个范儿》
链接: https://pan.baidu.com/s/1t5g9zQIrzd67yf6D7FsVHw 提取码: c2gt


《鸟哥的 Linux 私房菜基础篇》
链接: https://pan.baidu.com/s/1Xq8Ib8DxWVXn-_GcLyWgeg 提取码: lvtq
《鸟哥的Linux私房菜服务器架设篇》
链接: https://pan.baidu.com/s/1J5y5eGxwW7Br7lU3it50Xg 提取码: nbga
3. 学好算法和数据结构

很多同学可能觉得算法和数据结构只是用来面试,其实不然。扎实的算法和数据结构功底,能让你胜任一些核心技术或者高性能服务。例如 Redis、Nginx 等常用的服务,我们说这些服务性能高,很大一部分原因是因为它们设计的各类数据结构和算法小巧精悍。
如果你想进大厂工作,算法和数据结构是跳不过去的。学习算法和数据一定不能急功近利,算法和数据结构的知识一定要作为一个长期、持续的学习目标。
对于校招或者工作年限不长的同学,面试大厂,必然有一些算法和数据结构的题目。
而且对于校招,通常这块答的不好,基本就被一票否决了。这也是我建议那些参加校招的同学要好好准备算法和数据结构的题目了。 说到这里,为一些学历不错但是因为在校招前不认真准备这块、最终无缘大厂的同学感到惋惜,懒惰两个月,影响职业生涯一辈子。
我目前人在大厂做开发,有时候也担任面试官。我分享一下我的算法题库 + 整理了一些常见的大厂算法题与面经:
a

链接: https://pan.baidu.com/s/1Igq2ZG06cFE0BRMxM_T6Sg 提取码: tjok
大多数技术岗位算法这块的题目并不难,但是一定要在面试前好好准备一下。
另外,很多算法题其实就是《剑指 offer》上的原题:
链接: https://pan.baidu.com/s/1djzkm5rYDLBuWY8E2TcbWg 提取码: bup7


如果是非科班的同学,由于没有像科班同学那样接受到系统的学习,一定要找一两本经典书籍系统地学习下常见的算法理论、思想和常用的数据结构知识。等熟悉了这块的知识,再适当地刷一些算法题目或者做一些算法练习。
4. 学习并掌握一门重型编程语言

如果你想成为开发高手,必须要学一门重型编程语言傍身,可以是 C/C++/Java,只会 Python 和 php、shell 等脚本语言是远远不够的。
例如对于 C++,我建议这么学:C++ 语言本身涉及到的知识点比较多,需要强调的是,既然是学习,请抛弃各种总结经验技巧的面经,逐个掌握 C++ 语言的各个知识点,包括但不局限于:

  • 指针和引用的概念
  • 指针与内存关系
  • 程序编译过程,静态链接库和动态链接库
  • static、const、#define的用法和区别
  • C和C++区别
  • 内存中的栈和堆分配
  • 面向对象理解
  • 访问限定符 public/protected/private
  • 构造函数/析构函数/拷贝构造
  • 多态
  • 虚函数与纯虚函数、虚函数实现机制、虚函数表
  • 继承原理、虚继承、菱形继承
  • new/delete和malloc/free
  • 重载、重写和覆盖
  • 类型转换方式
  • RAII 与 pimpl 惯用法
  • 内存溢出和内存泄漏
  • STL标准模板库
  • 迭代器、空间配置器理解
  • 常用容器特点、用法以及底层实现vector、list、deque、set、map、unorderedmap
内容有点多,只有理解了,才能记得住,关于 C++ 语言背后的实现原理可以看看侯捷老师翻译的《深度探索 C++ 对象模型》一书。
链接: https://pan.baidu.com/s/1eBBtBYCA2asEJpLiUYQ9uQ  提取码: 959g
想掌握一些常用的 C++ 编码技巧,推荐阅读《提高C++性能的编程技术》,这本书很薄,但是内容都比较实用,看起来比较轻松。
链接: https://pan.baidu.com/s/1XCE9WV53GE8DPQXC2sF8ZQ  提取码: 6bp9
可用于工程实践的 C++ 书(例如如何结合 C++ 语言特性设计出优雅而鲁棒的 C++ API、如何优雅地组织和管理一个大型 C++ 工程等)推荐《C++ API 设计》《大规模 C++ 程序设计》:
链接: https://pan.baidu.com/s/1hkleT0kUgCCPyR9RVH4fMA 提取码: q802  
链接: https://pan.baidu.com/s/1P4iJ3HfJi0EdHJLUPD9bKA 提取码: m3fn
C++11/14/17 新标准也慢慢成为主流,这块也要熟悉,要熟悉新标准常用的语法与新功能,包括:另外,时至今日,你一定要熟悉 C++11/14/17 常用的语言特性和类库,这里简单地列一下:

  • 左值/右值/std::move/std::forward
  • 统一的类成员初始化语法与 std::initializer_list
  • 注解标签(attributes)
  • final/override/=default/=delete 语法
  • auto 关键字
  • Range-based 循环语法
  • 结构化绑定
  • stl 容器新增的实用方法
  • std::thread
  • 线程局部存储 thread_local
  • 线程同步原语 std::mutex、std::condition_variable 等
  • 原子操作类
  • 智能指针类
  • std::bind/std::function
C++11/14 网上的资料已经很多了,C++17 的资料不多,重点掌握的还是 C++11 引入的各种实用特性,这就给读者推荐一些我读过的书(文末有完整的书单及下载方式):

  • 《深入理解 C++11:C++11 新特性解析与应用》
  • 《深入应用 C++11:代码优化与工程级应用》
  • 《C++17 完全指南》
  • 《Cpp 17 in Detail》
链接:https://pan.baidu.com/s/138f_9Bu1-nQsqesu5r-nDw  提取码:54ol
另外,Effective C++ 系列的作者 Scott Meyers 又写了本介绍现代 C++ 各种技巧和避坑指南的书《Effective Modern C++》,这本书也不错,推荐一下:
链接: https://pan.baidu.com/s/1HA1INg5cdHIZoQLUCgDHxQ 提取码: ghl9  链接: https://pan.baidu.com/s/14n2gYKKYCL-qrt2sCPI6tA 提取码: 7kjw
学习 Java 的同学可以看这里:
Java 看什么书比较好?5. 熟悉编程语言相关的开发工具链,熟悉调试方法,掌握技巧

熟悉该语言的相关的 IDE 开发环境,如果是 C++ 开发,Windows 上我推荐 Visual Studio,Mac 上可以使用 Subline 或者 VSCode,如果你最终的程序需要在 Linux 跑,你需要熟悉 cmake/make/gcc/g++/gdb 工具链,vim 的基本操作也要熟悉。
建议掌握:

  • 如何启动和结束调试
  • 如何添加/删除/启用/禁用断点(包括普通断点、条件断点和数据断点)
  • 如何查看当天断点下的调用对战
  • 如何查看程序运行过程中的线程信息(这块可以放到下文再学)
  • 如何查看某个变量的内存值
如果你学习的是 Linux C++ 开发,学会用 GDB 调试 C 和 C++ 程序很重要。熟练掌握 gdb 调试等于拥有了学习优秀 C 和 C++ 开源项目源码的钥匙,只要可以利用 gdb 调试,再复杂的项目,在不断调试和分析过程中总会有搞明白的一天。
网上很多关于 gdb 的教程都是零散的,不成体系,且调试的都是各种玩具型程序,看完后很多读者还是不知道如何调试大型 C/C++ 项目,因此我结合自己的工作经验,写了一套《gdb 高级调试实战教程》,这个教程有如下特点:

  • 以调试开源项目 Redis-Server 为例,项目不是玩具型的,具有实战意义;
  • 按调试流程,从 gdb 附加调试程序,到启动 gdb 调试再到使用 gdb 中断 Redis 查看各种状态,循序渐进地介绍各种 gdb 调试命令;
  • 介绍了实际工作中 gdb 的各种高级调试技巧,例如如何显示超长字符串、如何使用 gdb 调试多进程程序等等;
  • 也介绍了基于 gdb 的一些高级工具,如 cgdb、VisualGDB,这些章节是为不习惯 gdb 显示源码方式的同学量身定制。
以下是电子书目录:






《gdb 高级调试实战教程》电子书下载链接:
链接: https://pan.baidu.com/s/1fS8571m6KYcR4tQ05Lbkgw  提取码: wiw3
相关的配套资源:

  • Redis 4.0.11 源码下载:https://github.com/balloonwj/redis-4.0.11
  • Redis 6.0.6  源码下载:https://github.com/balloonwj/redis-6.0.3
  • cgdb 下载地址:cgdb
  • VisualGDB 破解版下载地址:
链接:https://pan.baidu.com/s/1f4Y275wEhljVK1-ChEdUkw  提取码:snwb
掌握了一门编程语言加其开发的工具链,你的想法就可以通过动手变为现实了。

  • 学习操作系统原理和常用 API 接口
学习操作系统常用 API,操作系统的 API 在相当长的时间内都会保持不变,或者向后兼容,学习一次受用无穷。
对于 Linux 系统,我入门的时候看的是 Robert Love 的《Linux 系统编程》,这本书介绍了 Linux 系统上常用的 API 函数和背后的原理。Robert Love 是 Google 的工程师,他也《Linux 内核设计与实现》一书的作者。
链接:https://pan.baidu.com/s/1HRFbj6P4HNUp-9IWhGRmIw  提取码:477u


Windows 系统 API 学习,我推荐《Windows 程序设计(第五版)》和 《Windows 核心编程》。
《Windows 程序设计(第五版)》 链接:https://pan.baidu.com/s/1E40n3uSeh759GaKtqUUaCw  提取码:97te 《Windows 核心编程》   链接:https://pan.baidu.com/s/1jjPbLULmpxagyOQRIKMU4w  提取码:jg2c




2. 学习操作系统 API 也包括学习多线程编程
这块与上文有一点重叠,我们再次说一下。多线程知识,你需要掌握理解线程与进程的关系、熟练使用常用的线程同步技术。推荐的一种学习方式,就是找一个开源项目,使用调试器跑起来,然后看看这个进程有多少线程,每个线程在何时被创建,每个线程的作用是什么,线程之间如何通信的。这也是上文建议你熟练掌握调试器的原因。
推荐看游双的《Linux 高性能服务器编程》多线程相关章节,了解操作系统提供的常用多线程同步原语。
链接:https://pan.baidu.com/s/17sHLGtEnjBrsO8lYAsslnw  提取码:4fse


3. 学习操作系统 API 也包括熟悉操作系统原理
操作系统原理无论是面试还是自我提高的五大基础之一,我的建议学习操作系统知识时,不一定要看完所有操作系统书籍,但一定将一些基础概念(如进程、线程、内存模式等)看懂、理清。Tanenbaum.A.S《现代操作系统》是一本讲解操作系统理论不错的书,作者 Tanenbaum.A.S 是 Linux 内核创始人 Linus Torvalds 的老师。
你如果还有时间强烈推荐看看俞甲子的《程序员的自我修养:链接、装载与库》。这本书同时涉及到了 Windows 和 Linux 两个操作系统平台,用各种辅助工具剖析了程序从源码到二进制文件再到装载到进程地址空间里面的各个细节,甚至连进程地址空间中的堆结构、栈结构也分析得清清楚楚,同时也分析了 C Runtime(CRT)、glibc 这样的操作系统接口库的原理和执行逻辑,是一本实实在在帮你实战操作系统原理的好书。
当然,学有余力的同学,可以进一步了解一些关于操作系统的模式(如实模式、保护模式)、系统的启动与初始化、虚拟内存与物理内存、内存分表分页机制、进程与线程的调度算法等知识。
想要做好开发必须要学习操作系统的原理。学习操作系统原理不一定要看完所有操作系统书籍,但一定将一些基础概念(如进程、线程、内存模式等)看懂、理清,否则稍微复杂点的 C++ 程序还是会无从下手,这里推荐Tanenbaum.A.S《现代操作系统》。
链接:https://pan.baidu.com/s/1kbSNgcMDgeSHk8D37Nlwyw 提取码:egul
从一个 .cpp 文件到可执行程序,经历了哪些阶段,每个阶段做了什么事,可执行文件里面有什么,可执行文件如何被装载到进程地址空间变成可执行的进程的,这些是 C++ 开发者要搞清楚的。强烈推荐看看俞甲子的《程序员的自我修养:链接、装载与库》,这本书同时涉及到了 Windows 和 Linux 两个操作系统平台,用各种辅助工具剖析了程序从源码到二进制文件再到装载到进程地址空间里面的各个细节,甚至连进程地址空间中的堆结构、栈结构也分析得清清楚楚,同时也分析了 C Runtime(CRT)、glibc 这样的操作系统接口库的原理和执行逻辑,是一本实实在在帮你实战操作系统原理的好书。搞 C++ 开发,不看这本书,学尽 C++ 也枉然。
链接:https://pan.baidu.com/s/1SmakiehZQLReGWVY4TY-uw 提取码:eh2k


6. 学习汇编

如果你熟悉汇编,你就比其他人多很多优势,你会能透彻地知道你写的每一行 C/C++ 代码背后的机器指令的效率。无论是做安全工程还是自己技术提升上都是非常不错的。这里推荐一本王爽老师的《汇编语言(第 3 版)》,这本书不厚,语言通俗易懂,你也不用刻意去记忆,基本上当小说书看一下就能很快看完了。汇编实战类图书还有另外一本《老码识途:从机器码到框架的系统观逆向修炼之路》。我个人是非常喜欢这本书的。当年读这本书的时候,真的有一种“笑看妻子愁何在?漫卷诗书喜欲狂”的感觉。
一个不懂汇编的 C++ 程序不是真的 C++ 程序员,如果你不懂汇编,你很难搞得懂 C++ 的函数调用方式,很难搞的懂栈的结构,很难搞的清楚写 switch-case 语句时,怎样布局 case 分支效率才高等等。
如果你熟练掌握汇编,你就比其他人多很多优势,你会能透彻地知道你写的每一行 C/C++ 代码背后的机器指令的效率。无论是做安全工程还是自己技术提升上都是非常不错的。这里推荐一本王爽老师的《汇编语言(第 3 版)》,这本书不厚,语言通俗易懂,你也不用刻意去记忆,基本上当小说书看一下就能很快看完了。
链接:https://pan.baidu.com/s/1ExoiSE3FXvi2h81_avYPGQ  提取码:xna1
汇编实战类图书还有另外一本《老码识途:从机器码到框架的系统观逆向修炼之路》。我个人是非常喜欢这本书的。我上学的时候发现这本书欣喜之致,连着我在宿舍读了两个星期,将这本书读完。
链接:https://pan.baidu.com/s/1tflJW5K2TS7V8KcgJ2eHPg  提取码:krdh
这本书豆瓣评分 9.1 分:



7. 学习计算机网络和 socket 编程

学习计算机网络要从以下三个方面学习:
1. 学习计算机网络理论知识
计算机网络编程你需要掌握基础的如三次握手和四次挥手的过程以及各个状态值,我建议使用 tcpdump 命令实际抓下包就一目了然了,然后就是网络分层,各层的用途,重点熟悉下 TCP/IP 层相关的知识,还有就是 TCP/UDP 的区别,TCP 的滑动窗口机制、拥塞控制算法、TCP 的保序、重传、确认机制。
学习这些知识的时候,一定不要死记硬背,注重理解。我近来面试了一部分学历学校非常好的同学,然而,在问到这块的知识时却大失所望。例如,有的同学只是单纯把三次握手背下来了,我稍微变通一下他就不知道怎么回答了:

  • 如果连接一个目标主机不存在的 IP 地址握手过程是怎样的?连接一个目标 IP 存在但是端口号不存在的主机又是怎样的握手过程呢?
  • A 机器上的进程与 B 机器上的进程进行网络通信,分别经历了哪些网络层。
2 学习 Socket 编程
Socket 编程你需要先掌握常用的 Socket API,包括但不局限于:



常用 Berkeley Sockets API 一览表

学习这些 Socket API 的时候,不是让你单纯地记忆这些函数的参数,而是掌握每一个函数的重难点。
例如:

  • 如何将一个 socket 设置成非阻塞模式
  • 阻塞模式下,send 和 recv 函数行为是什么样子的?非阻塞模式下 send/recv 的返回值分别是什么?
  • 客户端发起连接时,如何主动指定通过本地某个端口号去连接?bind 函数如果端口号设置为 0 是什么行为?
  • listen 函数的 backlog 参数用途是什么?
  • 如何实现异步的 connect 函数?
  • accept 函数调用时,三次握手是否已经完成?
  • 如何实现半关闭状态?
  • nagle 算法的用途是什么?
  • select 函数的第一个参数怎么设置?select 函数的超时参数如果设置为 NULL 是什么行为?
接着要重点学习下常用的网络模型:

  • Windows 上常用的网络模型有 select、WSAEventSelect、WSAAsyncSelect、完成端口模型;
  • Linux 上常用的网络模型 select、poll、epoll,epoll 需要重点关注的是水平模式和边缘模式。
当然,也建议一定要理解,不要死记硬背。C++ 的同学来面试的时候,我会给他们准备如下面试题:
10. epoll 边缘模式下,某次读取了某个 socket 上的部分数据,下次是否会出发读事件?如果此时又来了一个字节的新数据,是否会触发读事件?
11. epoll 边缘模式建议尽量一次把数据读完,怎样判断当前数据已经读完?
12. epoll 边缘模式下,对于写事件应该如何处理?
接着还要熟悉 TCP 协议的流式特性,如何解决粘包问题;还要掌握常见的网络协议格式,像 HTTP、FTP、POP3/SMTP/WebSocket协议的格式都建议熟练掌握。
以 HTTP 协议为例,HTTP 协议包的格式是什么样的,包头和包体如何分界的,GET 与 POST 请求的数据分别放在 HTTP 包的什么位置,如果放在包体中,如何知道包体的数据有多长。
3. 学习常用网络命令
学习了常用的网络命令,可以用来排查网络故障与定位问题,反过来,也可以加深对网络理论知识的理解,建议掌握以下命令:ifconfig、ping、telnet、netstat、lsof、nc、curl、tcpdump。
相关阅读

  • 利用 telnet 命令发电子邮件
  • 做 Java 或者 C++ 开发都应该知道的 lsof 命令
  • Linux 网络故障排查的瑞士军刀
  • Linux tcpdump 使用介绍
掌握了这些命令要做到学以致用,例如现在某个服务器连接不上,如何使用这些命令判断是自己网络的问题还是目标主机的问题;开发了一个服务器程序,手头上没有可用的客户端,如何使用 nc 命令模拟一个;或者反过来,开发了一个客户端程序,如果用 nc 模拟一个服务器端用于测试。
C++ 网络编程方面的实战书来,我推荐韩国人尹圣雨写的这本《TCP/IP 网络编程》,这本书也适合无任何 Socket API 编程经验的小白,这本书涵盖从基础的 Socket API 到高级的 IO 网络模型,有非常详细和生动的例子。
链接:https://pan.baidu.com/s/1dq2Fkm6-_S2HqUnaNe4m-w  提取码:m778


等你有了一定的 C++ 网络编程以后(熟练使用常见 Socket API),你可以看看游双的《Linux 高性能服务器编程》(没错,还是这本书),这本书能让你写出完整的 C++ 网络项目来。
链接:https://pan.baidu.com/s/17sHLGtEnjBrsO8lYAsslnw  提取码:4fse


8. 学习数据库操作和原理

如果你想系统地掌握数据库常用的知识点,一定不要以网上各种散乱的文章为重点学习材料,理由有二:

  • 网上的资料碎片化比较严重,对于新人来说,可能会造成盲人摸象的感觉,无法形成这块成体系的技术认知;
  • 网上的很多数据库文章都是对诸如《MySQL技术内幕》《高性能 MYSQL》的二次理解和加工,很多文章的内容对原有数据库知识理解不到位、甚至理解出错。
学习 MYSQL 数据库,建议方法:

  • 找几本权威的数据库图书系统地学习一下,当然可以选择你感兴趣的部分,常用的数据库知识并不多;
  • 自己安装一个数据库进行操作、实践。
例如,我在我的主机上安装了 MYSQL,我就可以这么练习:
Last login: Tue Jul  6 10:50:02 2021 from 106.26.160.131

Welcome to Alibaba Cloud Elastic Compute Service !

[root@myaliyun ~]# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3550
Server version: 5.5.60-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show database
    -> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'database' at line 1
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| flamingo           |
| mysql              |
| performance_schema |
| teamtalk           |
| test               |
+--------------------+
6 rows in set (0.01 sec)

MariaDB [(none)]> use flamingo;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [flamingo]> show tables;
+---------------------+
| Tables_in_flamingo  |
+---------------------+
| t_chatmsg           |
| t_user              |
| t_user_relationship |
+---------------------+
3 rows in set (0.00 sec)

MariaDB [flamingo]> desc t_chatmsg;
+---------------+-------------+------+-----+-------------------+-----------------------------+
| Field         | Type        | Null | Key | Default           | Extra                       |
+---------------+-------------+------+-----+-------------------+-----------------------------+
| f_create_time | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| f_id          | bigint(20)  | NO   | PRI | NULL              | auto_increment              |
| f_msgcontent  | blob        | NO   |     | NULL              |                             |
| f_remark      | varchar(64) | YES  |     | NULL              |                             |
| f_senderid    | bigint(20)  | NO   |     | NULL              |                             |
| f_targetid    | bigint(20)  | NO   |     | NULL              |                             |
+---------------+-------------+------+-----+-------------------+-----------------------------+
6 rows in set (0.00 sec)

MariaDB [flamingo]> select * from t_chatmsg limit 5;
Empty set (0.00 sec)

MariaDB [flamingo]> 数据库需要掌握的基础知识有:
(1)熟悉基本 SQL 操作 包括增删改查(insert、delete、update、select语句),排序 order,条件查询(where 子语句),限制查询结果数量(LIMIT语句)等
(2)稍微高级一点的 SQL 操作(如 Group by,in,join,left join,多表联合查询,别名的使用,select 子语句等)
(3)索引的概念、索引的原理、索引的创建技巧
(4)数据库本身的操作,建库建表,数据的导入导出
(5)数据库用户权限控制(权限机制)
(6)MySQL的两种数据库引擎的区别
(7)SQL 优化技巧
以上属于对开发的基本的数据库知识要求,你可以找一本相关入门级的数据库图书阅读,推荐:

  • 《MySQL技术内幕(第5版)》
链接: https://pan.baidu.com/s/1A3rU6pjx91l61qF6w00jgA  密码: km5k


高级开发除了以上要求还要熟悉高可用 MySQL、主从同步、读写分离、分表分库等技术,这些技术的细节一定要清楚,它们是你成为技术专家或者高级架构的必备知识。我们在实际面试时,在讨论高可用服务服务方案时,很多面试者也会和我们讨论到这些技术,但是不少面试者只知道这些技术的大致思想,细节往往说不清楚,细节不会就意味着你的高可用方案无法落地,企业需要可以落地的方案。
这些技术我首推《高性能 MySQL》这本书,想成为高级开发者一定要通读的,另外还有两本非常好的图书也推荐一下:一本是《MySQL 排错指南》,读完这本书以后,你会对整个“数据库世界”充满了清晰的认识;另外一本是《数据库索引设计与优化》,这本书读起来非常舒服,尤其是对于喜欢算法和数据结构的同学来说。

  • 《高性能 MySQL》
  • 《MySQL 排错指南》
  • 《数据库索引设计与优化》
链接: https://pan.baidu.com/s/1RIBwk25SDAJkid6vKVNQ9w  密码: vpgu



八. 养成写技术博客的习惯,多总结技术流程和原理

写博客不仅可以锻炼你的表达能力,同时也是在梳理你的技术思路,如果一个技术问题,你不能清晰地给别人讲明白了,说明你也没掌握好。
另外,写博客不要记流水账,可以写一个自己的见解和试验结果。
我曾面试过一个学 Java 的同学,其博客上的多篇文章流程图画的非常漂亮,我看了之后非常惊讶,一面基本没怎么为难他就让他过了。
最后分享一份我精心整理的书单,书不多,都是经典:


获取链接含下载方式:
计算机必看经典书籍(含下载方式)如果觉得有帮助,请给 @张小方 点个赞吧。
Sue 发表于 2023-10-9 01:28:03|来自:北京 | 显示全部楼层
简单说,能。
反过来说,不写代码,水平一定没提高。写代码是必须要的,还有两个重要的方面经常被忽略:

  • 读代码
  • 刻意练习
读代码

读代码,对于程序员,就好比诗人读别人的诗,作家读别人的文。古人云:巧妇难为无米之炊。不读代码,哪里来的写代码的新的灵感和新的素材?同样、类似的代码写 100 遍只会增加你打字的水平,不会提升编程水平。(如果你发现你每天写同样、类似的代码,那说明你应该去学习如何抽象这部分工作,减少重复,而如何抽象的灵感很可能来自于你读到的其他项目的代码。)
《Code Reading: The Open Source Perspective》这本书说提到:40% - 70% 的软件开发工作是改善、完善已有的项目,而进行这项工作之前,我们需要先*阅读代码*。然而,大部分的计算机教育只交会我们如何写好代码,却没有告诉我们如何读好代码。当然,学好基本功(组成原理、操作系统、数据结构算法、数据库、网络)是读代码和写代码的共同基础。
另外,读写也会相互促进,缺一不可。只读不写,是纸上谈兵;只写不读,是无米之炊。
那么,我们应该如何选择项目来阅读呢?要分类来看。本职领域的代码和非本职领域的代码。比如,我是做量化交易的,本职的代码项目主要是关于:回测框架、交易框架、数值计算、时间序列处理等等方面的项目。而非本质的项目可以是任何感兴趣的项目。对于本职项目,需要认真阅读,分析结构、架构、算法和实现;而非本职项目,可以像是读小说或者新闻一样的阅读,可以其中一些亮点,比如小算法啊,一个语法糖啊,吸引。
另外,有一些项目一定要避免:

  • 编码风格不一致
  • 无意义的复杂且难懂
  • 有明显的逻辑问题
  • 无人维护(或者长期无人维护)
  • 大量使用无法迁移的技术
遇到一个项目,可以如下分析:

  • - 这是我的领域优秀代码吗?
  • - 阅读这段代码、项目的目的事?
  •   - 学习新的设计模式?
  •   - 编码风格?
  •   - 业务实现方法?
  •   - 新奇的数据结构?算法?API设计?
  • - 这个项目的规模适合我吗?
  •   - 新手应该从小项目入手
不过读代码本身是个大话题,比如检索源代码、语言相关的范式、文档、不同版本的演化等等,一个回答无法阐述。
刻意练习

刻意练习容易理解,我们写代码的时候要有明确的目的:这是一个项目还是某个架构或算法的练习?这是项目的什么部分?这部分有什么运行时需求?我应该采用什么方法解决?之前接触过类似的方法吗?
总之,每天写代码的时候应该明确的知道自己在做什么,为什么要写,以及跟其他部分的联系。
其实,就是通过每天的读、写代码,让自己的知识库更新,有意识的纳入新的东西,用新的东西跟自己已有的东西建立联系。这就是刻意练习的意义。
123sdf123sd 发表于 2023-10-9 01:28:57|来自:北京 | 显示全部楼层
老话说的好,和臭棋篓子下棋,越下越臭。
坚持多写代码是提高编程水平的必要条件,而非充分条件。

任何科学训练,最核心的一点就是对自己的不足之处进行专项训练。
比如足球运动员要针对体能、传球、带球、射门、战术意识进行分解训练,每个射门脚法好的球员背后都是成千上万次的练习。
编程也是如此,语法、算法、数据结构、新技术原理、数学基础等等,这些都是有关联但不能互相替代的技能。要进行专门的学习和练习——包括不限于看书、看技术文章、仿写、独立编写等各种学习和练习方法。
当然,最好的方法把自主学习和工作实践结合起来,而且对细节多思考,这样进步最快,最不容易走弯路。

具体到实践中,从读一本书、写书上的例题开始,也可以从解决一道练习题开始。动起手来吧~~
编程不是什么高深的科学,它只是一样技能。只要坚持学习,编程能力的提升会非常快~~~
hellos 发表于 2023-10-9 01:29:56|来自:北京 | 显示全部楼层
代码敲得少,是学不好编程的

我上学的时候在敲了5w行代码后悟出了:觉得编程难?先解决量的问题

我本科期间因为各种原因蹉跎了很多时间,可以说编程并未入门。那是什么感觉呢?就是看起来都好像懂点,自己写起程序来就没底。比如数据结构和算法,我虽然知道很重要,但就是没太学懂,考试过了却不知道实际应用。看相关的书籍,如果没有现成的代码我就总感觉少了点什么,有些困难。
后来我就考研了,当时我也没太想明白为什么要读研,算是还没准备好参加工作,还想在学校待两年。读研期间我在实验室跟着做一些科研项目,编程做得也不算多。
2009 年一次偶然的事情改变了我。那天我大概是看到了一个介绍 PKU JudgeOnline - POJ 的网页,然后想起自己 2006 年注册过账号,我就重新登录了进去,没想到从此的一年多时间里,我基本天天泡在上面写程序。
我不是为了参加比赛,而只是偶然陷入了进去,然后就变得沉迷。我基本从早上九点到实验室,到晚上十一点左右离开实验室。我从一些简单的算法开始写,有时候是按照某些分类去做,实在想不出来就去评论区和别人的博客看解题报告。
现在回想起来那一年算是自己最专注的学习编程的一段时间,我记得有一次神奇的体验,有次我一直在想一个算法问题,然后在梦里还在做,第二天醒来后居然能回忆起梦里的方法,最后实现出来居然是对的。
这种忘我的、愉悦的心流体验非常难得,以至于在十年之后,当我遭遇焦虑时仍用这种办法来解决。
在这一年多的时间里,我基本刷完了 500 道题目。其实每个程序通常都比较短,算 100 行每道题的话我也就写了 5 万行代码。
就是这 5 万行代码彻底提高了我的编程能力,感觉就好像就是突然上道了。我对算法和数据结构没有了恐惧感,变得更有耐心,我看其他技术书籍也没任何困难,学习编程语言,框架类的东西快多了。
关于这一点我后来看到硅谷王川的表述非常好:

所有的我们以为的质量问题,大多本质是数量问题。因为数量不够,差几个数量级而已。
数量就是最重要的质量。大部分质量问题,在微观上看,就是某个地方的数量不够。

最大的误区是,明明是数量不够的问题,因为错误地以为瓶颈在于质量,幻想在不增加数量的前提下,用某种奇技淫巧,偷工减料达到目的。这时候玄学,迷信和各种无病呻吟就出现了。数量不够,底子不够厚时,很多事情时做不到的。即使有时看似有捷径,欠的账迟早是要还的。
有的初学者在量没达到的情况下,怀疑自己的学习方法有问题,然后再怀疑是不是编程语言没选对,试其他的办法又没法长久坚持,最终导致自己好像一直没上道。如果没有写到足够的量,任何方法都是无法阶段性提高自己。
这个量就像是一个门槛。

任何复杂技艺的学习都是有门槛的,通过这个门意味着构建了做这行的韧性和耐心,也可以说是找到了里面的乐趣和成就感,这些是深入下去的基础
那我们怎么刻意练习代码能力呢?

正如我所走的道路,在 POJ 上做编程题和自己学习数据结构、算法有什么区别呢?后来我明白,其实我经过了一年多刻意的有效练习,这种在线编程的练习有几个好处:

  • 可以获得即时反馈,一个程序是否通过都是确定的,到底是 Wrong Answer、Memory Limit Exceeded、还是 Time Limit Exceeded
  • 可以跟踪和量化,我学会了哪些,比如 DFS、BFS、DP、Tree、Graph 等都是可以追踪和量化的
  • 可以和其他人交流
在这种练习中,我通过写获得了编程的“语感”,也提高了阅读源码的能力。写代码和写作差不多,编程无非是通过代码来表述自己的想法,需要不断地练习。
在 LeetCode 上写也很不错,这是很多人第一次接触OJ的地方。
LeetCode题库:(2123题)

题库 - 力扣 (LeetCode)​leetcode-cn.com/problemset/all/​leetcode-cn.com/problemset/all/​leetcode-cn.com/problemset/all/​leetcode-cn.com/problemset/all/
总共两千多道题,而且有些题,非常难,就算每天10题,也至少刷半年。这显然不适合绝大部分同学。
所以,我们要找到最核心、最重要的题集,即可
比如,如果时间紧张,可以先刷《程序员面试宝典》里的题目,总共109题。

《程序员面试宝典》​leetcode-cn.com/problem-list/xb9lfcwi/​leetcode-cn.com/problem-list/xb9lfcwi/​leetcode-cn.com/problem-list/xb9lfcwi/​leetcode-cn.com/problem-list/xb9lfcwi/
刷完以后,有时间,可以再刷《剑指offfer》的题目,共75题。

《剑指offer》​leetcode-cn.com/problem-list/xb9nqhhg/​leetcode-cn.com/problem-list/xb9nqhhg/​leetcode-cn.com/problem-list/xb9nqhhg/​leetcode-cn.com/problem-list/xb9nqhhg/
因为这两本书,都是面向面试的高频题汇总,自然有很多题目是重合的。这也正能说明这两本书的重要性。
书籍我也给大家准备好了,可以自取:【知乎】算法导图及推荐学习资料下载 (qq.com)
或者你可能对算法不感兴趣,那可以去做游戏、Web 应用开发、后台开发等等项目,找到自己感兴趣的方向作为突破口,然后持续积累到一定程度的代码量,比如三万行代码,那编程自然就入门了。
就编程来说,三万行代码这么明确的一个指标,实际上大部分人做不到。这里又要借用知乎的名言了:以大多数人的努力程度之低,根本轮不到拼天赋
不信你可以问问,即使是大学计算机专业的学生,很多人毕业的时候并未完成过 3 万行有效编程的这个量。
所以,觉得编程难?从坚持每天写代码开始吧!
钻石王老五 发表于 2023-10-9 01:30:39|来自:北京 | 显示全部楼层

快速回帖

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则