后端科普泛泛而谈 1

写在前面

想写这篇文章的起源是今天在一个算法讨论群里回答了一个群友的问题,然后私聊交流了下,大概半个小时,给他科普了一下,以及提供一些建议,他说这半小时抵得上他看好几天帖子。自认为自己普普通通,所以这一系列大概是做一个科普,不是进阶。在这个寒冷的冬季,希望写下一些东西能对大家有所帮助。

笔者Andy是21年校招生,双非一本毕业,曾经是acmer,一个菜得只有一块铜牌的acmer,不过好在学校在北京有地域优势,加上当年还不是很倦,在百度视觉技术部和字节跳动的头条百科实习过,毕业时在阿里淘特和百度搜索架构部以及Shopee不确定部门之间选了Shopee,被分配到infra(基础架构部门)做时序数据库Victoria Metrics的开发工作,主要用golang语言。

尽可能通俗易懂,尽可能少字。

我说的不一定是对的,但你不一定只听我说。另外你也可以公开纠正我。

一切都是程序

在我真正去实习之前,我在学校没有做过项目,只会写算法题,也就是黑框框程序,完全不知道怎么做开发,因为忙于竞赛也没有去学。但我后来意识到,一切都是程序。程序的官方定义在此不表。我说一下我的理解

程序 = 输入 + 处理 + 输出

算法题的黑框框程序,在acm题目里是用scanf或者cin在命令行接收输入,然后做一定的处理,用命令行输出。在leetcode题目里是通过函数调用的方式输入,然后通过函数返回值来输出。在此简单做个延伸

  • 一个http服务(也是程序)是通过监听TCP端口来获得输入,然后输出也是通过TCP端口。
  • 一个RPC服务和http一样也是通过监听端口来输入输出
  • 一个数据库服务通过监听端口来获得输入,它的输出一方面是写到磁盘,一方面是作为查询结果通过网络返回到查询端。
  • 一个爬虫程序它的输入可以是命令行,也可以是配置文件,也可以没有输入。然后它通过作为一个客户端发送http请求抓取数据,这部分即是输出也是输入。然后抓取到的数据写到磁盘里,这是输出。

以上的这些程序,输入方式还有启动参数、读文件。读文件一般读配置文件,常见的如YAML和JSON。这里先不展开。

广义后端和狭义后端

后端工程师的范围特别广,以至于我的理解可能不太严谨。我理解的狭义上的后端就是web服务器后端开发(也就是各种网站),广义上则五花八门,做机器学习平台 检索系统 音视频架构 基础架构的人一般也归类为后端工程师这个范畴。

所以,你找的大概是后端的工作,但不一定是web后端的工作。

后端考察知识

我这里不会列举知识点,只是试图说一下为什么要考,以及我工作中用到的,以及及其粗略地说怎么准备,毕竟你准备校招肯定知乎牛客github都查一下。

算法和数据结构

考察代码功底,但是面试一般不会有那么多原创题。

参考各种leetcode题单和《剑指offer》

计算机网络

这方面是很有必要去学的,尤其是传输层,尤其是如果你要是写go,go语言封装了很好的TCP库,进行socket编程很简单。

TCP

我在工作中用到的TCP主要有这些用途,那些三次握手、四次挥手、拥塞控制和流量控制,算是常考知识点,读者自己去了解。

我一句话说清楚这个东西是做什么的:传输01数据,通过接收01数据可以解码成字符,或者特殊编码。

RPC

这里浅浅讲一下RPC调用的概念,这是真的简化了,读者一定要再去查资料啊,我本人没有亲自写过RPC框架。

RPC:Remote procedure call,远端程序调用。

RPC = 远程函数调用 = 服务发现 + 数据传输+数据编解码。直观理解就是,一个进程像调用自己内部的函数一样调用另外一个进程。

这里先举一个最简单的例子。有一个RPC服务,它叫add,如同函数

int add(int a, int b) {
    return a + b;
}

客户端:我给你100,200,你帮我算一下他们的和。

服务端:100+200=300

  • 数据编解码:简单来说,上面那个RPC服务,他要接收两个int值,那么实际调用的时候,它的客户端大概是要把这两个值合并在一起发送给远端的。所以这就涉及到了编解码,最容易理解的编码之一JSON,用{"A":100,"B":300}来表示传递的参数。然后服务端接收到之后呢,就把A和B都解出来,返回300。另外还有其他编码格式:protobuf,thrift。
    • 这里也叫序列化和反序列化,序列化就是一个结构体序列化成字节,反序列化就是字节解析成结构体。
  • 数据传输:可以是TCP,也可以是http。刚刚说了,TCP是用来传输01数据的。但是http也可以,只不过传的就不是01,而是编码好的字符。收到01数据就能按8个位一个字节解析出来字节,然后就能用上面说的解码。
  • 服务发现:如果你自己写RPC demo的话,你需要add这个服务监听一个端口,然后一个客户端去访问localhost这个端口。但其实在真实生产环境中是通过IP来访问,但是又不希望大家直接访问IP,而是你知道你要访问一个叫add的东西,然后有一个类似DNS的东西告诉你add在哪个机器上。

http

上面说了tcp是用来传输01数据的,http就理解成依赖于TCP用来传输一些特定编码格式的数据就好了。

在工作中主要要注意的就是TCP长连接复用的问题,我最近就遇到了。。

简单来说,http用TCP来传输特定编码的数据,所以机器A和机器B之间要建立TCP连接,但是发完一个request和一个response之后,这个连接可以先不用关闭。

其他的什么http1.0和1.1的关系这些。。我自己也没背熟,读者有好的资料可以评论区发下。

操作系统

这部分最重要的还是进程和线程,还有通信方式。我本人并发编程也只会golang,所以说得不全面。

你gcc编译一个程序,然后./a.out启动,这就是一个进程A。再./a.out一次,这又是另外一个进程B。(在golang里是go build,这里只是举个例子)

然后很显然,A进程里的全局变量在它的程序内部是可以共享的,A程序内部的如果有一个线程ta打开了文件f,那另外一个线程tb也可以读写这个f。并且ta可以通过管道(在golang里是channel)把数据传给线程b。(go routine并不是普通协程,而是用户级别的协程)

然后A进程和B进程之间要怎么通信呢,看了上面你肯定能想到,他们可以通过RPC通信,当然也可以通过http通信,也可以直接就是TCP通信,另外在业界也常用消息队列来进行异步通信。

容器化

上面大概简单说了进程,那么可以说一下容器化,大概就是把一个程序打包成镜像,然后镜像运行在一个容器里。这样有什么好处呢,一个是虚拟化,就是你的东西不管在linux,windows里的,只要打包成了镜像,就可以在docker上跑。另外一个用处是限制资源,比如你这个服务需要64G 64核,那我最多给你这个数,剩下的资源分配给其他容器。

然后对于这些容器呢,还有容器编排系统,常用的有kubernetes。可以理解为对容器的管理吧。我最近也做了一些k8s相关的工作,这里先不展开。

微服务

前面说了网络,进程,RPC,http,服务发现,在这个基础上大概可以讲一下微服务了。

在那些很古老的项目或者框架里,一个网站就是一个项目,也是一个程序,所有的操作都在这个项目中开发。

微服务 = 一个服务拆成多个服务 + 多个服务之间的通信。

下面是一个即兴创作的案例:

一个百科项目,拆成了很多个微服务。

一个web服务reading用来供用户浏览百科,这是最传统的web,接收前端发送的请求,去数据库里查到百科数据,然后序列化之后返回给前端。前端再将序列化的数据渲染成界面。

还有一个服务compose用于创作百科,提供一个富文本编辑器,用户创作之后传到服务器。但是众所周知用户创作的内容是需要审核的,所以这个服务就会把创作的内容通过消息队列传到审核的服务。

审核服务checking用户审核人员来审核创作内容,简单分为过或者不过两种审核结果,过的送到一个队列pass队列,然后reading消费这个队列,更新线上数据。不过的发给fail队列。

创作中心Creation Center服务用来管理创作者的积分,创作记录等等信息,它消费fail队列,往创作者的消息箱发送某词条审核不过的消息。

把一个服务拆成这么多服务了,前面也说了有容器化和k8s,那是不是可以让这些服务运行在容器里头?

多实例和网关负载均衡

前面讲了微服务是一个大的服务拆分成N多个小服务,然后他们各司其职。这算是一个纵向的拆分,但还有横向的拆分,就是多实例。

先说一下什么叫网关,常见的用于做网关的有Nginx、BFE。这个东西很复杂,很有技术挑战,尤其是对于大厂来说,网关是第一关。

这里简单说就是,比如上文的reading服务,它完全可以部署多台实例,这里假设两台,A和B,然后有一个网关N,N用轮询的方式,一个请求发给A,一个请求发给B,这样的话也就是我们所说的负载均衡。

对于reading服务也是,可以部署多个实例给不同的审核团队使用,只要他们消费的数据不重复就行。

后续

一晚上两个小时随手写的,可能还有很多错误。

后续可能会写一些简单的golang demo,用以解释上文所涉及到的概念,还会补充一些学习资料。欢迎大家关注。

知乎ID: andywu 微信公众号:andystreehole 
#后端开发##go后端开发实习##百度##字节跳动##旷视面经#
全部评论
赞!
1 回复 分享
发布于 2022-11-10 01:34 湖北
知乎上看到过你
点赞 回复 分享
发布于 2022-11-18 19:12 广东
确实科普好文,lz用心了,bd
点赞 回复 分享
发布于 2022-11-25 09:56 北京

相关推荐

不愿透露姓名的神秘牛友
02-12 18:14
RT,这周五就是情人节了,前女友给我发了消息,我该不该回?
Yoswell:原则上来说让她滚,但是本着工作很累下班想吃瓜的心态,我觉得你可以回一下
点赞 评论 收藏
分享
EEbond:给北邮✌️跪了
点赞 评论 收藏
分享
评论
15
49
分享

创作者周榜

更多
牛客网
牛客企业服务