web后端开发需要哪些基础知识?

前言

最近组内招人比较多,可惜一直没有招到令人满意的人选。我们一直在讨论彼此都问了什么问题,是不是问的太难了,是不是要放松一下标准等等问题。周末在家闲来无事,发现不知不觉也已经从事web后端开发5年多时间了,所以现在想从事互联网的后端开发,对于大量的curd工作来说,到底需要哪些技能,这里就总结一下。

以下仅代表个人观点。

web后端和工程研发有什么区别吗?

首先web后端和工程研发的区别是什么?

在我心里是这么定义的:在基于H5技术栈的产品中(无论是PC还是手机端),处在需求第一线,以需求为导向的,提供数据与功能的业务支持。


冰山一角

如果单纯的指后端开发,那么范围太广了,比如有专职处理大数据,有处理基础平台的,有算法服务的等等,如果整个后端是一个冰山,那么web后端就像是冰上露出的一角。因为我们都知道,页面上一个看似很小的数据,看似很小的功能模块,可能都是后台经过多个模块,多次聚合得出来的结果,在这个位置就必须熟悉各种底层依赖,如果有些功能团队没法支撑,可能就要自己上去造轮子了。

这个职位可能没有太多时间去在某一个专业方向做技术沉淀,因为需求每天都在变,而且永远做不完。而对应的工程研发,应该是以不变应万变的存在,有了一个通用的大的需求场景,去研发一些底层通用的东西,比如播放器的技术,地图的技术,队列的技术,数据库的技术等。很多公司在招聘的时候把这两类人混成一类来看待,因为我们自己往往也是这么看自己的,毕竟觉得要给自己留一条技术路线的选择,万一全部精力用来讨论业务,自己岂不是未来要转型称为产品经理了……

很多从事这方面工作的人都有一种感觉,就是我们每天都在ctrl c + ctrl v。curd的操作还需要什么技能?以前我也有这种感觉,但是当自己好好总结一下后,发现东西还是不少的。



语言基础

首先当然是语言基础,不管是什么编程语言,没有一门拿得出手的编程语言,就像是士兵上了战场没带枪一样。刚毕业那段时间我也很重视这方面的能力,在各种群里讨论,总结工作中遇见的各种奇怪的问题,但是越到后面,我反而对这个东西的重视程度没那么高了。在我还没毕业的实习阶段,学习的是前端技术,也自学了一点nodejs,后来转到后端做了java开发,再后来加入创业公司转为php开发,也从事了几个月的爬虫研究,所以又学习了python,目前在公司进行的是go语言的开发工作。

这些经历让我感觉语言终归就是一个工具,很多东西大同小异,各自有自己的适合的场景,根据公司的技术栈和项目的实际情况,做出相对合理的选择就好。正如go语言近两年大火,也许过几年又出现什么其他语言也说不定。

过去在面试别人的时候也喜欢去网上找一些所谓的面试题,比如这个函数的返回值是什么之类的问题。说实话,大部分场景我们的工作中都不会遇见的,这个东西有多少意义我对此表示中立,唯一的作用可能是用来衡量面试者的真实工作时长吧,毕竟类似设计模式,架构分层等思想,真的是没有几年真实项目开发经验是完全无法理解的,书本上的知识和亲身感受回答的内容,过来人一听就知道。

所以现在我面试的时候这方面的问题我一般也会问一些,但是一般就是象征性的问一些比较通用的,以go语言为例,基础变量相关的问一问slice,hashmap,底层设计不同于其他语言的CSP模型,GC实现相关的,三色标记法。当然了,也会问一些“一下程序的输出值是什么”之类的问题,这种知识应该是一个人在入门一门语言的过程中随便读过一本书都会了解到的东西。如果面试者宣称的主要开发语言,连一本像样的入门书籍都没读过,这种人肯定是不考虑的。

网络协议基础

如果是计算机相关专业毕业的人,肯定知道计算机网络,TCP/IP卷一,这类书籍,毕竟是必修课嘛。这类东西有用吗?刚毕业的时候没什么感觉,可是时间长了发现还是非常有用的。

比如几乎说有面试宝典都会提到的TCP/IP三次握手,四次挥手。你知道为什么提问的次数这么高吗?因为在web服务后端的开发过程中,尤其是现今微服务这么火热的背景下,所有的服务间通信都离不开这里的知识。如果你身处大公司,可能好多东西都被运维部或基础架构部之类的部门解决掉了,但是如果你在一家中小型公司,这些东西是你必须面对的。

这里说一个我面试的过程中最喜欢提问的一个问题吧-- 从浏览器输入域名开始,到数据返回并呈现页面,中间经历了哪些过程。

答:(DNS)域名解析 -》TCP连接-》http通信-》负载均衡(nginx)-》应用服务(python,go,php等)

这个是应届生基本能给出的答案。

为什么我最喜欢问这个问题呢?因为这里有太多知识点可以提问,

比如:DNS采用什么协议传输,TCP还是UDP,为什么只有13个根域名服务器?

这个知识点有用吗?有用,虽然我们主流的服务都是TCP的,但是不排除你未来会使用UDP应用,UDP的数据报文长度限制都不知道,相关功能怎么开发?局域网的DNS更不用说,大家都改过hosts文件吧,这个在日常服务中也少不了相关的操作。你看很多我们每天在做的事情,其实就是这么一个普通的知识点。

再比如大家总是问tcp握手,相信很多人都像背诵课文一样背下来了,但是能好好理解的人就不多了,比如DOS攻击,目前使用云服务成了主流,这部分应该都被服务商解决了,但是在过去这都是每个开发者自己要考虑的问题。

其次,做开发的,应该没有不知道wireshark的吧。我记得过去自己使用rabbitmq的时候,有一次因为参数配置问题一直搞不清楚,最终就是靠抓包的方式,再对着文档,一点点分析出来问题的,抓下来的包其实就是书中描写的那些东西。

这里多提问一个问题,抓包过程中WIN这个是干什么的?基本上问这个问题就能知道一个人是否学习过计算机网络了。

以及路由的相关知识,我们曾经遇见过,因为一个路由问题,线上机器同一个集群访问数据库走不同的路由,一个走很长的链路一个走很短,导致线上服务接口忽快忽慢,定位了许久才找到这个问题,最终联系运维相关的同事解决了。虽然我们是后端服务开发,但是过程中很多问题也许并不是代码的问题,有这些知识才能让你定位问题时有更广阔的视野。

作为web后端开发,http状态码都代表什么意思,这个必须会没什么异议吧,比如301和302的区别,或者这样问,登录验证时发现你未登录,把你定向到到登录页用的是哪种?包括我们经常看的http报文体,里面很多字段都可以拿出来分析一下。

再然后就是https,相信只要你的公司有个正经的主页,都会有个https 的访问地址了,那么关于https 的基本知识你了解多少呢?曾经有个面试者连https是对称加密还是非对称加密都没答上,我只能说对此很失望……

这里推荐一个博主总结的非常好的文章HTTPS温故知新(一) 这是一个系列的文章,找时间读一下受益匪浅

操作系统基础

我这里毫无疑问指的是linux环境,如果有大佬是window服务器开发的,请绕行……

在面试的时候这里可以问的点就太多了,简单一些的就是服务器的基本操作,比如文件目录的创建,权限变更,常用配置更改,服务资源占用情况,nginx错误日志快速查询等等。

这里问一个有意思的问题,linux的一个文件夹里的文件上限是多少?如果你只有一台服务器,需要保存大量的文件,那么要怎么设计比较好?

上面这个问题就是我在创业公司的时候面对的问题,毕竟小团队规模小,也没那么多服务器,硬盘虽然可以随便加,但是程序设计上就要注意了。

然后就是进程与线程,这个也不多介绍了,干入这行,这点基础没有就别进来了。目前比如go语言又有了协程的概念,其实本质就是内核态与用户态的转换问题。关于这个其实也有很多可以不是很深却很基础的问题,比如我们如何确保服务进程不死的?有使用crontab的,有使用supervisor的,那么supervisor的实现原理是什么?其实就是父子进程的知识点,但是好多人从来没考虑过这个问题。

IO多路复用,基本上对应的面试题就是Apache与nginx对比,或者select 与 epoll区别。

现如今大部分功能都在云上,或者被基础运维同事解决,尤其容器化技术的应用,让过去很多必须小心翼翼的操作变的不那么重要了。

数据结构与算法

大厂面试的门槛,今天你刷leetcode了吗?

数据结构与算法貌似只有计算机专业的人才学的一门课程吧,其实我觉得这个应该拆开成两个部分去看,首先是数据结构,比如链表,hash表。然后是算法,我觉得应该是在应用开发过程中大部分情况都是一起来使用的,所以有了这么个名字。

首先这些知识的作用是毋庸置疑的,但是大家争论比较大的就是,curd的工作会这个有用吗?传说中某厂面试手撸红黑树是真的吗?

这里说说我的一点微不足道的看法。

首先我之前跳槽找工作的时候也在刷题,但是很少,也就几十道,大部分是简单难度的,基本就停留在背包问题这种简单动态规划的水平。首先要承认一点,能把算法学好,同时有能力现场手撸出来的,编程能力普遍会高很多,学习能力也比较容易鉴别,对于财大气粗的厂,也算是变相的减轻了很多人才筛选的工作压力。但是话又说回来,对于主要偏向业务的工程开发,这些算法知识起到的作用很有限……因为除了一些常用的基础知识,其他的都被封装在各种类库,各种框架中供我们使用,如果你追求极致性能上的优化,当然还是需要过硬的能力的,但是国内有多少业务开发会去做这样的事情呢?

而且还会出现一种情况,就是这类人解决单个问题的能力会偏强,但是在代码规范,整体设计上往往并不比擅长工程开发的人要好,究竟什么是系统架构设计这个我后面在聊。而且由于算法工种的平均薪资较高,所以这类人从事工程业务开发有时候会出现厌烦情绪,如果同一个功能频繁换人开发,那么结果将是毁灭性的,相信有过刚入职接手一个N多人开发过的项目的类似经验的人,一定非常理解。

说了这么多,当我面试别人的时候,我会问相关问题吗?当然会了,不过我一般会挑选一些简答的提问。

首先二叉树相关的我基本就不怎么问,比如二叉树找公共父节点,首先这确实是一道好题目,及考了二叉树的结构,又考了递归和非递归编程,不过二叉树这种东西大家实际使用的确实比较少,大部分都是被各类框架封装好了,所以如果没有准备过的人,一般也很难现场整理出来思路。但是我更喜欢的一个题目是二叉树打印,感兴趣的可以试试。

还有一些涉及到算法知识的问题,一般来说我是不喜欢问的,比如如果用randN随机数创造出一个randM的随机数,这里就用到了Rejection sampling(拒绝采样)的知识。绝大部分候选人都是通过刷题库的方式了解到这种解法,但是这有什么意义呢?如果是算法的面试去问问推导过程不是更好吗?

然后关于链表相关的问题,我一般喜欢问判断单向链表是否存在环结构,并找出那个点。这个问题是那种做过了瞬间给出答案,没做过基本没思路的问题,在我面试众多候选人里,只有一个人在我的提示下靠自己推算出来结果,毫无疑问我们直接录用了他。

链表的思想还是非常重要的,这个在一些应用场景里确实是有意义的,同时哪怕是简单的链表翻转,也可以在面试的时候考研面试者的编码能力。

提完链表,就不得不再提一下hash表,这个的重要性就太高了,比如php用着最爽的部分就是那万能的数组,本质就是hash表,同时在日常开发中,进行一些数据源的合并,匹配,包括配合桶排序的思想进行一些业务的上排序和分类,都是非常常用的场景。这里提一个比较经典的题目:两数之和。

然后是排序,首先这个东西的使用大部分都是被各类语言的类库解决了,但是这个思想很重要,手撸快排我真的不觉得过分,至于使用场景就太多了,首页的topN,charts的时间轴等等。

还有一些堆栈问题的使用,这个还是有些作用的,比如求一个连续输入流的topN或者中位数等,就可以使用堆排序的思想解决。这个还是有一些使用场景的。

bitmap相关,很多场景我们不会轻易就使用大数据服务,那么如果进行数据压缩处理,尤其是纯数字的场景,那就是bitmap的思想,甚至在一些数据库的设计中也可以使用类似的方法,可以帮助我们节省很多关联表。最经典的应用应该就是布隆过滤器了。

数据结构与算法,在我看来本质上就是时间换空间或者空间换时间的问题,但是web后端开发的日常真正会遇到这类问题的场景且需要通过代码层面去优化的有多少呢?往往都是通过缓存,网络链路优化等提升更加简单直接有效。


通用的第三方服务

首先各大公司基本都是在用市面上的第三方工具,或者内部公司造的轮子。有一些及其经典的相信做这行的多少要好好去了解一下吧。

mysql

比如mysql,这个就是太经典了,虽然现在随着数据规模增加,需求场景的更加丰富多彩,存储引擎也是五花八门的,但是依然无法动摇mysql的地位,首先SQL标准,基本是所有主流都会支持的,其次作为免费好用的工具,大学时期的大作业相信大部分人也是用mysql实现的吧,然后事务的使用目前也是非常稳定。对于很多孵化期间的产品,mysql依然是最适合起步的存储引擎。

由于各家公司的技术栈和需求场景不同,有人用mongo,有人用postgresql,所以这个在招聘面试的时候也很难针对某一种去面试。但是面试mysql就没什么太大问题,关系型数据库的设计在对象抽象,数据结构描述上也更直接。比如我们目前的技术栈就是mysql加es的方式,但是面试的时候我一般还是主要面试mysql的知识为主。

那么mysql要怎么面试?

首先是sql基础,比如下面这道题。

假设表如下

name   kecheng   fenshu

张三    语文       81

张三     数学       75

李四     语文       76

李四     数学       90

王五     语文       81

王五     数学       100

王五     英语       90

找出每门课都大于80分的学生

首先这个并不难,但是为什么要面这种问题呢?因为现在ORM架构的盛行,很多单纯写业务的人可能真的快把sql语句的基础忘了吧,我记得之前招聘外包的时候真的有一些写不出来的。

然后稍微上一点难度,就是数据库的设计

学生,班级,课程

我有如下需求:

①查询一班选择高等数学课的学生有多少人

②查询一班选课学分不足10分的学生

③查询上学期足球课报名的女生数

其实就是关于一对多,多对多之类的考虑,这个也不难,但是一般面试的时候如果让他现场设计,你可以看到候选人对于需求的拆解过程,是不是自己有过独立负责功能模块开发的经验。当然这个只是面试刚工作一两年左右的人比较合适。

再然后用的比较多的就是索引相关知识,比如:

select * from tb_test where a = ? and c=?;

idx_abc(a,b,c)

这条语句能命中索引吗?

查询结果我只需要a,select * 和select a 有区别吗?

对于索引基础的重要程度就不需要多做解释了。

最后应该就是事务锁的一些问题,毕竟线上服务锁表的风险还是不言而喻的。再比如,select for update在一些特定场景下可能产生的死锁现象,网上也可以搜到许多。

比如会议室系统:比如我司的会议室预定系统,每天10点开放抢会议室,对于比较抢手的时间,经常出现页面卡死,看着有会议室但是实际已经被别人抢走了等等,类似春运抢票的样子,这里就可能是事务锁或主从同步的问题等,那么要如何优化呢?这个就可以和候选人聊一聊。

队列服务

大公司应该都有专门的团队就行封装或者二次开发。那么队列究竟帮我解决了什么问题,以及需要面对哪些新的问题?

我觉得简单理解就是生产与消费速度之间的缓冲,同时也起到了一些分发的功能。

有一篇文章总结的很好,如何保证消息队列的高可用和幂等性以及数据丢失,顺序一致性

在面试的过程中大部分问题也会几种在这部分,生产者弄丢了数据怎么办?消费者弄丢了数据怎么办?数据的顺序如何保证?线上队列堆积怎么办?

很多都是真实的生产环境中会遇见的场景,真正从事过核心业务开发的人不可能没考虑过这些问题,即使没遇见过,预案肯定是要提前确定好的,所以通过这些问题就能够知道面试者在进行日常开发的时候是否有过自己的思考。

redis

过去可能还会有人问redis和memcached的区别,现在好像也没人问了……

redis在缓存上的地位目前应该是无人撼动了,基于redis的提问一般会问什么呢?大部分喜欢问zset的实现,也就是跳跃表。正经翻过一遍redis相关书籍的人应该都对这个实现的印象非常深刻。

其他基于redis的实际使用场景可能会有不少人喜欢问,比如用redis充当简单的队列,用redis实现分布式锁。

如果是中小公司可能还需要考虑一下一致性hash在redis部署上的应用。

这里推荐一个总结的不错的文章Redis系列文章——合集 如果能把这些理解了相信关于redis的面试就没什么问题了

作为日常web开发中,我一直觉得redis是查询接口性能优化中的“抗生素”,简单直接高效,什么底层查询慢,计算慢等问题,挂个定时任务,数据灌入,速度瞬间雄起。但是我一般还是不太喜欢这么做,首先这东西有依赖性,用了一次就有下一次,渐渐的系统就有了“抗药性”,随着数据量访问量的增加,redis自身的负担在加重,接口中值得优化的点基本被忽略,然后接口的相应速度有一点点降低,这时候怎么办?可能就是提高“用药量”,加资源吧……

nginx

我相信nginx与apache的竞争结果也出来了,在互联网公司现在用apache的应该少之又少了吧。

其实面试的时候关于nginx本身的问题我一般问的不多,毕竟这东西作为一个工具性的东西,业务开发了解的那么多也没有什么太大的帮助,网上关于源码分析的东西一抓一大把,我们小组也组织过帮nginx源码加注释的活动,全部过了一遍之后,好像也快忘的差不多了,但是如果是刚工作没多久的,且有业务时间的,倒是可以看一看实现,很多工程实现确实很有借鉴意义。

基于nginx我可能会问一下负载均衡,反向代理,限速相关的问题,比如让你自己实现一个限速器,或者实现一个加权负载的功能,你有什么想法?了解过nginx的一般当场就能打出来,毕竟都是成熟的解决方案,我觉得作为业务开发了解这些就足够了。如果有大佬说他自己实现了个更好的负载算法或者限速算法,那么我只能说大佬慢走,让您做业务开发真的是暴殄天物了。

其他框架

比如spring,gin,laravel 等代码使用的框架,其实写多了就会发现很多共通的地方,比如反转依赖,中间件,路由层,业务逻辑层等等,这个地方可以根据项目上的实际使用来提问。个人感觉可能值得提问的应该就是服务注册,反转依赖,路由设计这几个部分。同时如果你们同时在使用一个轻量级框架或者某框架的最新beta版,倒是可以一起讨论一下遇到的一些坑。

“改轮子”的能力

没事重复造轮子,这种事情经常有人出来吐槽,后来又搞出了什么业务中台之类的概念。这里我说一下,重复造轮子是不可能避免的事情,为什么?因为很多在别人看来很小的需求,在另一个项目确是个强需求,这个时候人家让你支持一下,加个功能吧,定制化个接口吧,你觉得结果会是如何?所以最终就是谁需要谁去重新造,顺便还能刷一波KPI。

我当然是不支持这样做的,但是实际遇见的问题怎么解决?这就是“改轮子”的能力了。大家都熟悉的主流架构我们基本上没法插手,毕竟代码规范和需求涵盖面等基本能满足绝大部分需求了,但是有很多公司内部相似的东西如果能快速理解源码并在此基础上进行微调,并投入自己的生产线中,这才是web后端该做的事情,毕竟这么多需求,你想自己造一个轮子,pm也不会给你时间啊。

掌握一点儿前端知识

前后端分离的概念貌似是近两年流行出来的吧,PC端过去还是jsp,php的时代,那个时候做web开发要说一点前端技术都不懂肯定是不行的。现如今无论大小公司应该都是前后端分离的方式,后端提供api,前端利用一些框架通过异步请求的方式。

这种工作模式下后端要了解前端的知识有什么用?问题在于前端页面的本质是DOM树的渲染过程,通过异步获取json报文并解析,消耗的是客户端的资源,如果这个页面很大,元素很多,甚至再加上一些炫酷的效果呢?估计用户的电脑就像被点燃了一样,风扇飞速旋转,然后死机。毕竟能有阿里这种前端后级别分配这么清晰的公司还是少数,这个时候其实就要前后端来共同决策如何进行优化。

但是反过来如果问我,面试的时候要问面试者前端的相关知识吗?如果非要找点相关性的话,可能就是用户登录,session管理之类的知识吧。

高并发解决方案

到了这里应该都是招聘高级后端才会提问的问题了,大致应该分为几个吧。

比如zookeeper的相关知识。

剩下的应该就是上面提到的那些知识,不过是把场景复杂化一些。

这里介绍一个最近刚看到的,分布式id生成的知识。方案一就是集中式生成,比如Oracle,Zookeper,Redis等,这类方法的问题在于严重依赖第三方。另一种就是叫做Snowflake方法,简单来说,算法采用41bit毫秒时间戳,加上10bit机器ID,加上12bit序列号,理论上最多支持1024台机器每秒生成4096000个序列号。


web后端开发需要哪些基础知识?_第1张图片
Snowflake


个人感觉,所有的方案都在CAP定理下,目前真正拥有超级大的访问规模处理应用就不多,真正有机会在实际生产环境中不断探索和攻克的人更是少之又少,像我这种甘当咸鱼的选手,并不会在这上面放太多精力,对于面试者,只要他能够有过自己的思考,说出自己在项目中的取舍过程就很好了。

系统规划能力

毫无疑问,我这里说的肯定不是网上那种系统架构设计。

这里我觉得我玩过的一个游戏很符合我心里对此的设定 -- 《异星工厂》,如果有爱玩策略类游戏的小伙伴,我这里推荐一下。

开局一个小人,通过建造工厂,造出宇宙飞船逃离星球。


web后端开发需要哪些基础知识?_第2张图片
开局


这个就好像我们刚学习写业务代码的阶段,砍砍树,搬搬砖(写一些最简单的代码),了解各类矿石(了解各种业务)


web后端开发需要哪些基础知识?_第3张图片
建造机器


然后我们有了原材料(基础知识),我们就可以开始建造机器(编写业务功能)


工厂雏形

很快,我们掌握的建造技术(业务功能)越来越多,功能之间彼此连接依赖(功能模块相互调用),就成了一个完整的业务模块。


矿场

我们需要的基础资源(基础数据)越来越多,我们建造起了矿场(数据库)


电厂,水厂等

随着工厂规模的增加(数据规模增加),我们需要更多类型的资源,水资源,煤炭资源等(多数据源)


web后端开发需要哪些基础知识?_第4张图片
分发器

复杂材料需要一些基础材料按照一定比例合成,这里就需要一些分发器(路由),进行矿石的分发与调度(队列)



铁路系统


随着我们需要的资源越来越多,身边的资源已经不够了,我们建造出了火车帮我们去运输远处的资源(大数据平台)


web后端开发需要哪些基础知识?_第5张图片
数据面板

我们需要时刻关注着我们各类资源的生产和消费情况(运维监控)


虫子来袭

在这个星球上我们也有敌人,那就是这些异星的虫子(黑客),我们在进行科技发展的过程中也需要建造武器来抵御攻击(网络安全)


自动机器人建造

很快随着科技的进步,我们可以提前设计好图纸,让机器人快速部署防御系统(docker容器化部署)



web后端开发需要哪些基础知识?_第6张图片
时钟与计算器


这个游戏甚至还提供了与或,加减运算等组件,通过这些东西的合并组合,可以实现时钟与计算器的功能(数据结构与算法)


复杂的工程设计

在这个过程中免不了一些不合理的设计被拆除重新建造(代码重构)

作为玩家,就是将这些简单的组件,合理的组合分配,实现工厂的正常运转。而这就是我心中web后端架构要有的能力,就是将大量简单的业务模块合理规划分配,让整个工厂(系统)可以快速迭代,稳定运行。


结语

web后端工程开发,简单说就是一个什么都要会一些,但是貌似有不是特别需要精通的这么一个岗位。而我们就是要在这样的工作过程中,在业务与技术领域共同进步。

你可能感兴趣的:(web后端开发需要哪些基础知识?)