作者:NULL
链接:https://www.zhihu.com/question/37247264/answer/2352680534
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
服务器是一种高性能的计算机,相对于普通的个人电脑,它的性能往往更强,但是功能也更加单一。服务器开发,就是在服务器上面开发应用程序。服务器开发包括两部分,一是服务器上基础应用的开发,例如搜索引擎等,二是对业务流程在服务器上的相关应用开发。一般来说,企业里招第二类比较多。从业务的角度来看,服务器中的应用程序会接收来自客户端的业务请求,将其所需的数据处理以后,返回给客户端。后台开发不像前台开发一样,有清晰的可视化界面,它在整个业务中往往处于幕后的位置,所以被称为后台开发。下面这张图可以大致体现后台开发的流程:
这张图是客户端和服务器一种最简单的描述,但是这里面有很多问题如果真的研究起来就会很复杂,涉及很多基础知识。
1. 客户端的请求如何表示?对它的回答又如何表示?
2. 服务器和客户端之间的连接该如何建立呢?
3. 服务器和数据库之间又怎么进行交互?
4. 图中一台服务器只面向一台客户端,可是现实当中服务器通常需要接收多个客户端的请求。那么怎么分配这些请求?如果有非常多的客户端向服务器发送请求,服务器怎么样才能保证性能?
以上是服务器开发的一些基本问题,要解决这些问题,就要学习非常多的基础知识。带着这些问题,可以让我们把知识点串起来,对Linux下的服务器开发有一个更好的理解。
涉及知识点
1 编程语言
既然是C++后台开发,那么首先我们要掌握C++语言。C++的知识浩如烟海,而且包含了很多不同的思想,例如,它即继承了C面向过程的语法,又包含了面向对象的思想,要想精通真的很难。我的想法是将C++分成多个组成部分,然后分别学习。学习C++之后,简单总结了一些要点:
- 基础数据类型和运算符:C++的基础数据类型,如int,double。要机制它们的分别占用的内存大小,以及它们之间的转换规则。其中尤其要掌握指针和引用。
- 基础语法:基础的条件语句,顺序语句,循环语句,是必须要掌握的。
- C++关键字:C++中包含了很多关键字,例如static,const,extern等,学习的时候要注意它们的特点,以及应用场景。
- C++内存管理:内存管理非常重要,要记住C++程序内存有几个区,它们之间存放的数据;另一个关键点是C++的内存泄露的发生原因和避免方法。
- C++函数:函数是面向过程的体现,重点包括函数参数,返回值。如果再深入研究,还要知道函数的调用过程等。
- 面向对象:主要就是面向对象的三大特性,封装,继承和多态,以及实现这三大特性的一系列手段,如类,虚函数等。
- 泛型编程:C++中的泛型编程主要是模板编程,包括函数模板,类模板,模板泛化,模板特化这些知识。
- STL标准库:STL主要要掌握各种容器和泛型算法。最好能对它们的底层实现有所了解。
- C++11新特性:C++11作为C++的经典版本,有一些新特性需要学习者好好掌握,例如智能指针等。
除了C/C++以外,你还需要掌握至少一门脚本语言,例如python/shell。脚本语言可能不会是你开发的主语言,但是它可以作为程序的“粘合剂”,完成一些轻量级的工作。
2 Linux基础
现在大多数服务器都运行的是Linux系统,作为一个后端开发,少不了要和Linux打交道。对于初学者来说,可以先从下载一个带图形界面的发行版本,如Ubuntu,CentOS等,边玩边学。我们首先要具备操作Linux的能力,也就是了解Linux的基本结构,掌握基础的Linux命令,会用一些Linux上的工具。再升入一点,Linux和Windows的开发环境有区别,要熟悉Linux下的开发环境。如果这样还学有余力,可以研究一下Linux的底层原理,例如Linux的进程通信是如何实现的。Linux甚至允许你修改它的源码,当然这是很高的要求。
Linux下的常用基础命令:
- 文件处理命令
- 网络管理命令
- 用户管理命令
Linux下的常用工具
- gdb
- git
- vim
- putty
Linux原理
- Linux进程
- Linux文件系统
- Linux内存系统
3 计算机网络
后台开发少不了要和网络编程打交道,要想成为一个优秀的后端开发,就要打好计算机网络的基础。计算机网络的知识比较抽象,我在本科期间也没有学好,后来我听从网上大佬的建议,从计算机网络数据传输的角度出发,思考数据如何经过计算机网络的多层服务进行传送的,感觉对计算机网络有了更深的了解。传统的OSI七层模型是在比较复杂。现在我们实际上使用更多的是 TCP/IP 四层模型(应用层,传输层,网络层和数据链路层)。后台开发对传输层和应用层的要求非常高,所以对这两层要好好理解。
- TCP和UDP:TCP和UDP是传输层最重要的两个协议,掌握的越详细越好,要了解它们的差异,以及差异形成的原因。
- TCP是如何建立连接的:主要就是三次握手和四次挥手的内容,包括连接过程,各种连接状态等。除了要成功的情况外,还要考虑失败的情况。
- 流量控制和拥塞控制:流量控制是为了防止发送方发送数据过快,接收方来不及接收;拥塞控制是为了防止网络上数据量太大,造成网络阻塞。要了解它们的原理和实现方法。
传输层要点:
- TCP和UDP:TCP和UDP是传输层最重要的两个协议,掌握的越详细越好,要了解它们的差异,以及差异形成的原因。
- TCP是如何建立连接的:主要就是三次握手和四次挥手的内容,包括连接过程,各种连接状态等。除了要成功的情况外,还要考虑失败的情况。
- 流量控制和拥塞控制:流量控制是为了防止发送方发送数据过快,接收方来不及接收;拥塞控制是为了防止网络上数据量太大,造成网络阻塞。要了解它们的原理和实现方法。
应用层要点:
- HTTP:http是应用层最重要的协议,http需要理解的知识很多,如请求报文,请求方法,状态码等。向浏览器的地址栏中输入URL得到相应页面,这里就包含了http请求的过程。
- HTTPs:https是http和ssl(安全套接字)的组合,可以在http的基础上实现加密传输和用户认证。重点应该关注https的流程和实现数据安全的方式。
- DNS协议:DNS是应用层另一个非常重要的协议,用来实现域名和IP地址的转换,这个协议的要点在于它具体的解析过程(即如何通过域名得到IP)。
4 操作系统
除了计算机网络以外,另一门Linux下C++开发需要掌握的基础是操作系统。相比Java等语言,C++本身就是一门更加偏重底层的语言,所以它的效率更高,而且C++不太有Java中SpringBoot这种大而全的框架,这更加要求我们理解操作系统原理,以便于自己实现对应的功能。操作系统的抽象程度比计算机网络更高,学习起来更有难度,总结下来,操作系统主要在管理计算机的四种资源:
- 进程管理:即对CPU资源的管理。主要内容包括进程和线程,进线程调度算法,同步与互斥,死锁等。这部分内容是操作系统的重中之重。
- 内存管理:内存分为物理内存和虚拟内存。其中对虚拟内存是内存管理的中心,要点包括分页存储管理,分段存储管理,页面置换算法。
- 文件管理:文件系统,即文件的属性和组织方式的相关内容。
- 设备管理:计算机系统如何和与外设交互,发生中断和响应。
5 网络编程和系统编程
这一部分是上两个部分的具体实现,也就是我们怎么利用学到的原理知识,去解决实际问题。在这方面,我们可能会自己实现一些高效的数据结构,也可能直接调用现成的库函数。主要内容包括:
Socket编程:Socket是对传输层的抽象,它提供给我们一些具体的API,而不需要关注其中的具体实现
- 相关API:connect(),socket(),bind(),listen()等。
- socket建立连接的过程
I/O多路复用:一个进程复用多路I/O,是实现高并发的利器。三种经典的多路复用方法是select,poll和epoll。对这三种方式的区别和实现方式应该有具体了解。
- select,poll,epoll的实现方式和区别。
- reactor和preactor的实现方式和区别。
- ET和LT触发模式的区别。
多线程/多线程编程:多进程多线程编程是实现高并发服务器的利器,非常重要
- 相关API:fork(),pthread_create()等函数。
- 线程池的实现:通过提前创建线程减小切换开销。
- 进程线程间通信方法:共享变量,消息队列,锁等。
6 数据库
数据库是存储数据的仓库,也是后端必备技能之一。在开源的数据库中,MySQL因为其强大的性能被广泛引用。除了关系型数据库之外,因为现在的业务往往涉及到高并发和分布式,所以在传统的关系型数据库以外,企业还要求掌握非关系型数据库,如Redis。
MySQL数据库要点
- 基础语法:基础的CRUD语法
- 数据库引擎:目前MySQL主要的引擎有InnoDB和MyISAM,要知道它们各自特点的区别。
- 索引:索引的使用方法,还有实现它们的数据结构(hashmap和BTree)。
- 锁:数据库中常见的锁,如行锁,表锁,悲观锁,乐观锁,以及它们各自的使用场景。
- 事务:事务的四大特性(ACID),以及四大隔离级别。
- 数据库优化方法:常见的优化方法又SQL语句优化,分表,读写分离。
Redis数据库
- 基础数据类型:Redis五大基本数据类型包括字符串,链表,字典,集合,排序集合。
- 配置文件:Redis配置文件可以配置内存淘汰策略等一系列设置。
- 缓存:Redis被广泛应用于缓存方向,可能会发生缓存相关的问题,如缓存穿透,缓存雪崩等。
7 数据结构和算法
如果我们不想当一个只会调包,只会简单增删改查的码农,那么我们就需要掌握算法和数据结构,常言道:数据结构+算法=程序,高效的数据结构和精巧的算法能提升程序的效率,对于后台开发来说,效率非常重要。当然我们不需要掌握非常高难度的算法,可是掌握基础的算法和数据结构是必须的,下面是一些基础的数据结构和算法
常用数据结构:
常用算法:
- 分治法
- 动态规划
- 递归和回溯
- 排序
- 快速排序
- 归并排序
- 查找
- 二分查找
- 树算法图算法
- 树的前,中,后序,层次遍历(递归和非递归写法)
- 图的遍历
- 最小生成树
- 迪杰斯特拉
算法和数据结构的就像是武侠小说中的内功,是每一个想成为高手的人必须要修炼的。修炼的过程是数以年记的,这个过程需要我们保持耐心和恒心。
8 设计模式
设计模式是软件工程师们针对软件设计模式总结出的经验,如果说前述的内容还处在’术’的阶段,设计模式已经有了’道’的感觉,好的设计模式能帮助工程师创造出高质量的软件。工程师总结了23种常用的设计模式。在23种设计模式中,有几种设计模式是重中之重,要好好掌握,例如:
- 单例模式:一个类只能有一个对象。
- 工厂模式:封装对象的创建,让子类决定创建的对象。
- 观察者模式:定义对象的一对多关系。
9 其他常用技能
除了上面这些基础内容,还有一些也要掌握,例如
- Makefile的编写
- Linux下常用工具的使用,例如vim,git,gdb等
另外,在社招中,企业可能会提一些更高的要求,例如分布式,容器,中间件什么的,如果学有余力,也可以进一步的去了解。
总结
总的来说,Linux下C++服务器开发的知识还是很多的,如果想要找到一份好的工作,或者对这个领域有深入理解,还是需要投入很多的时间精力的。对于这上面列出的知识,我也有很多没掌握的地方,但我相信通过系统的学习,不断迭代更新自己的知识,一定能取得进步。