「面试」小红书之旅

上一篇给你们分享了B站的面试之旅,你们的反响还不错,竟然催更了,小手不由颤抖。因此决定把剩下的这些公司给安排明白了。这不,今天就看看小红书服务端/后台面了啥,不为别的,就想遇到漂亮的HR小姐姐,开工。面试

831aa9611c96d52608f409baf2cdebbd.png大纲算法

一面


一面面试官看着二十七八岁,温文尔雅,这哪里是写代码的,头发都飘起来了好么。上来就干项目,因为你们的项目都不太同样,因此对于项目部分我就说说我面试的时候常常遇到的问题数据库

  • 描述下项目数组

一口是吃不了胖子的,描述以前先憋着气掂量掂量本身所说的东西能不能唬住本身,而后唬住面试官。服务器

  • 项目中担任的角色网络

对于大多数的咱们而言,就是开发的角色,一样的道理,角色对应相应的职务,阐述本身作的内容能引面试官上钩,拉钩上吊一百年不准变。数据结构

  • 在项目遇到什么困难并发

这三个问题,是否是能够拎着脚趾拇均可以想出来,除非不是你作的,哈哈哈哈哈。不慌,不是咱们作的也不怕,咱们必须知道有个网站叫作Github,大牛这么多,本身不是大牛,难道不会学学人家麦。Clone下来,搭建环境跑起来,开始调试修改,经过将模块拆分,进一步修改,这不就是你的项目吗,固然我不怎么建议你们这么操做啦。异步

项目被问的差很少了,开始怼基础知识,基础知识老四套,计算机网络数据库操做系统数据结构(来吧,时刻准备着,真没吹牛逼)tcp

我看你简历中写着网络流量的还原,你应该对计算机网络比较熟悉?(注意哈,简历上写上去的东西,本身内心必定要有点B数),那咱们说说计算机网络

  • 说说计算机网络中TCP的三次握手吧

首先 Client 给 Server 发送一个SYN包,Server 接收到 SYN 回复SYN+ACK,而后客户端回复 ACK 表示收到。

你这样回答确定是不会让面试官满意的,那就加点配料,不放佐料的菜怎么香?那就详细的安排一下

首先客户端的协议栈向服务端发送SYN包,同时告诉服务端当前发送的序列号是X,此时客户端进入 SYNC_SENT状态

服务端的协议栈收到这个包之后,使用 ACK 应答,此时应答的值为 X+1,表示对SYN 包 J 的确认,同时服务端也发送一个SYN包,告诉客户端当前个人发送序列号是Y,此时服务端进入SYNC_RCVD状态

客户端协议栈收到 ACK 之后,应用程序经过connect调用表示服务端的单向链接成功,此时状态为ESTABLISHED,同时客户端协议栈对服务器端的 SYN 进行应答,此时数据为Y+1

服务端收到客户端的应答包,经过accept阻塞调用返回,此时服务端到客户单的单向链接也创建成功,服务器将进入ESTABLISHED状态

这样是否是稍微有B格一点呢,并且还比较形象,固然为了加深你们对这个过程的印象,我再举个例子

第一次握手:小蓝给某女娃告白,说我喜欢你,而后我傻乎乎的等着回应

第二次握手:女生看我这颜值,秒回,天然就答应我啊,并回复我也喜欢你拉

第三次握手:我收到女生的回应说:“那晚上去吃火锅,看电影,理疗”

就这样在一块儿啦,那么后续是啥样呢?是否是得往下看看什么是四次挥手了(渣男石锤),非也,还在热恋期呢,专注的好吗。面试官会继续问你三次握手

面试官说:“那我问你,若是客户端发送的SYN丢失了或者其余缘由致使Server没法处理,是什么缘由?

这个场景很是常见,没有万无一失。在TCP的可靠传输中,若是SYN包在传输的过程当中丢失,此时Client段会触发重传机制,可是也不是无脑的一直重传过去,重传的次数是受限制的,能够经过 tcp_syn_retries 这个配置项来决定。若是此时 tcp_syn_retries 的配置为3,那么其过程以下

463d597c01116134cc2f8ddedc207754.pngTCP重传

当 Client 发送 SYN 后,若是过了1s尚未收到 Server 的回应,那么进行第一次的重传。若是通过了2s没有收到Sever的响应进行第二次的重传,一直重传tcp_syn_retries次。这里的重传三次,意味着当第一次发送SYN后,须要等待(1 +2 +4 +8)秒,若是仍是没有响应,connect就会经过ETIMEOUT的错误返回。

说说四次挥手吧,哎,卑微的蓝蓝

第一次挥手:女生以为和这个男生不太合适,可是是个好人,决定提出分手,等待男生回应

第二次挥手:这男生吧,也是会玩儿,直接说:”分就分“

第三次挥手:过了一段时间,男生以为好没得面子:"我一个大老爷们,应该是我提出分手啊",因而给女生说:咱们分手吧

第四次挥手:女生看到这个消息,你是「憨批」仍是「神经病」?

TIMEWAIT了解哈,过多的TIMEWAIT怎么办,什么缘由形成的?

回答问题的方法无外乎便是什么,为何会出现以及能够解决的方案

在TCP的四次挥手过程当中,发起链接断开的一方会进入TIME_WAIT的状态。一般一个TCP链接经过对外开发端口的方式提供服务,在高并发的状况下,每一个链接占用一个端口,可是端口是有限的以至于可能致使端口耗尽,因此就会出现'"服务时而好时而坏的状况"。

以下图所示的TCP四次挥手,TCP链接准备终止的时候会发送FIN报文,主机2进入CLOSE_WAIT状态并发送ACK应答。主机1会在TIMEWAIT停留2MSL的时间。

为何不直接进入CLOSE转态,而是须要先等待2MSL,这段时间在干啥?

第一个缘由是为了确保最后的ACK可以正常接收,从而有效的正常关闭。怎么理解,科学家们在设计TCP的时候,假设TCP报文会出错从而开始重传,若是主机1的报文没有传输成功,那么主机2就会重发FIN报文,此时主机1没有维护TIME_WAIT状态,就会失去上下文从而恢复RST,致使服被动关闭一方出现错误。

5d97ce6cbe7f09e4fa73978f442bf023.png四次挥手

第二个缘由是让旧连接的重复分节在网络中天然消失。

一次网络通讯可能通过无数个路由器,交换机,不知道到底会是哪一个环节出问题。咱们为了标识一个链接,经过四元组的方式[源IP,源端口,目的IP,目的端口]。假设此时两个链接A,B。A链接在中途中断了,此时从新建立B链接,这个B链接的四元组和A链接同样,若是A链接通过一段时间到达了目的地,那么B链接颇有可能被认为是A链接的一部分,这样就会形成混乱。因此TCP设置了这样一个机制,让两个方向的分组都被丢弃。

那么TIME_WAIT有哪些危害?

过多的链接势必形成内存资源的浪费

对端口的占用。可开启的端口也就32768~61000

有没有对TCP进行优化过

开玩笑,这东西复习过,尽管问,锤子不怕。优化的点不少,随便提一点,让后比较深的描述下这个过程就行好比调整哪些参数在某些特定的条件下会最优

咱们应该都知道半链接,即收到SYN之后没有回复SYN+ACK的链接,那么Server每收到新的SYN包,都会建立一个半链接,而后将这个半链接加入到半链接的队列(syn queue)中,syn queue的长度又是有限的,能够经过tcp_max_syn_backlog进行配置,当队列中积压的半链接数超过了配置的值,新的SYN包就会被抛弃。对于服务器而言,可能瞬间多了不少新的链接,因此经过调大该值,以防止SYN包被丢弃而致使Client收不到SYN+ACK。

就这样是否是就可让面试官感受,这小伙子有点东西。那怎么配置呢

41570335486ce71d56dfbcc7b73ce4fb.png配置syn queue

你觉得面试官是傻子?固然不是,万一面试官问你:半链接积压较多,还有其余的缘由?

哈哈哈,这说明面试官上钩了哇,来,咱们看看还有啥缘由

还有多是由于恶意的Client在进行SYN Flood***。

SYN Flood***是个啥过程?

首先Client以较高频率发送SYN包,且这个SYN包的源IP不停的更换,对于Server来讲,这是新的连接,就会给它分配一个半链接

Server的SYN+ACK会根据以前的SYN包找IP,发现不是原来的IP,因此没法收到Client的ACK包,从而致使没法正确的创建链接,天然就让Server的半链接队列耗尽,没法响应正常的SYN包

那有没有什么方案解决这个问题?

那必须,毕竟面试嘛,须要让面试官问咱们知道的内容。在Linux内核中引入了SYN Cookies机制,那看看这个机制是啥意思

首先Server收到SYN包,不分配资源保存Client的信息,而是根据SYN计算出Cookie值,而后将Cookie记录到SYN ACK并发送出去

若是是正常的状况,这个Cookies值会伴随着Client的ACK报文带回来

Server会根据这个Cookies检查ACK包的合法性,合法则建立链接

那么开启SYN Cookies的方法?

2f22b32fa2421969e77f987e7567896c.pngSYN Cookies

网络问到这就差很少了,挺好的,彻底按照个人套路出牌。开始怼我操做系统

  • 说下什么是大页内存

我擦,我差点没反应过来,"大爷内存",不过确实牛逼,大页内存,记住了,是大页内存

咱们知道操做系统堆内存的管理采用多级页表和分页进行管理,操做系统给每一个页的默认大小是4KB。假设当前进程使用的内存比较大为1GB,那么此时在页表中会占用1GB/4KB=26211个页表项,可是系统的TLB可容乃的页表项远远小于这个数量。因此当多个内存密集型应用访问内存的时候,就会致使过多的TLB没有命中,所以在特定的状况下会须要减小未命中次数,一个可行的办法便是增大每一个页的尺寸。

操做系统默认支持的大页为2MB,当使用1GB内存的时候,页表将占用512页表项,大大的提升TLB命中率从而提升性能。另外须要注意的是,大页内存分配的是物理内存,因此不会有换出磁盘的操做,因此没有缺页中断,也就不会引入访问磁盘的时延。

行,差很少时间了,写个简单代码吧,实现一个无重复字符的最长子串

思路:使用滑动窗口保证每一个窗口的字母都是惟一的

  • 使用 vectorm 来记录一个字母若是后面出现重复时,i 应该调整到的新位置

  • 因此每次更新的时候都会保存 j + 1 ,即字母后面的位置

  • j 表示子串的最后一个字母,计算子串长度为 j - i + 1

7987081f6dd5e6bcf71460e65fb83c31.png无重复字符的最长子串


二面


一面感受还不错,果不其然二面来了,HR小姐姐打电话通知周三二面,行,对于历来不迟到的暖蓝,确定守时。拿着茶,等到2:30,至于为何拿着茶,这是个人习惯,面试前喝杯茶等待面试官的捧击(面试官其实大部分很温柔的啦)。

可耐,面试官到点了竟然还没来,等不及的我打电话给HR,HR说很差意思,得等几分钟,行,对这甜美的声音我忍了,但是等了十分钟都没音信,我下午还有个笔试,无奈给HR说,我下午还有事儿,要不改天面?

不知道什么状况,直接说,我立刻给你换个面试官,我擦,还有这种事儿,我这乡卡卡的娃儿有这种的待遇?是我一面表现的太太突出?不会吧,反正小红书我爱了。

“staty with me”响起,这正是个人手机铃声。。

"您好”

“你好,请问是XX?”

"嗯嗯,你好面试官"

"我是你的二面面试官,先自我介绍吧"

我叫XX,来自XX大学,本科XX,硕士XXX,期间作了XX,谢谢面试官。自我介绍不用那么花里胡哨,挑重点说,不会在乎你本科谈了几回恋爱,也不会在乎你XXXX,简单明了完事,开始二面

  • 应该学过C的吧,用C实现多态怎么个思路

至于这个题,我仍是比较惊讶的,怎么忽然问到了C,想了想可能仍是考虑对于面向对象中多态,继承等的理解。

多态无外乎就是编译时多态和运行时多态,编译时多态理解为重载,运行时多态理解为重写。那么要实现重载,须要用到c中的宏,V_ARGS

c46e1324008281bef43870a640e13b29.pngc实现重载

理解上面的方法,实现多态就更轻松了

c6600d6345b83b48bf723835431f7efb.pngc实现多态

感受没啥问的,先写个代码,二路归并

哈哈,让我想起了歌词"来左边跟我花个龙,在你右边画一道彩虹"(脑补画面)

停!!这是我以前说过的常考算法之一,中心思想即分治,可经过递归一直拆分,递归的结束条件即不可再分,即分为1个的时候就中止。从第一个开始时将每个模块看成一个已经排序好的数组,有如双指针,在两个数组头设立指针,进行值的比较,而后插入到新数组中,上代码咯

fb0a4031de6091bc8293256b531d7781.png归并排序

倒排索引了解不?

假设我这里有几十本文档,每一个文档题目不同,若是我给你文档的题目,你可能很快就能够找到相应的文档。可是若是我让你找论文中包含"暖"和“蓝”这两个字,你可能直接给我"两儿巴“。由于多半很难很快就找出来。从稍微专业的角度来分,前一种是正排索引,后一个是倒排索引

咱们先看简单的正排索引。此时给每一个文档一个惟一ID,而后使用哈希表将文档的ID做为键,将文档内容做为键对应的值。这样咱们就能够在O(1)的时间代价完成key的检索。这也正是正排索引

3433d6827a8044b9e896837e8fa7d7d7.png正排索引

这里遍历哈希表的时间代价为O(n)。每遍历一个文档都须要遍历每一个字符判断是否包含两字。假设每一个文档的平均长度为k,那么遍历一个文档的时间代价为O(K)。

有没有什么优化的方法?

其实以上就是两种方案,一种是根据题目找到内容,另外一种是根据关键字查找题目。这彻底相反的方案,那咱们反着试试

咱们将关键字当作key,将包含这个关键字的文档的列表当作存储的内容。一样创建一个哈希表,在O(1)的时间我就能够找到包含该关键字的文档列表。这种根据内容或者字段反过来的索引结构即倒排索引。

如何建立倒排索引?

  • 首先给文档编个号表示惟一表示,而后排序遍历文档

  • 解析每一个文档的关键字并生成<关键字,文档ID,关键字位置>。这里的关键字位置主要是为了检索的时候显示关键字先后信息

  • 将关键字key插入哈希表。若是哈希表已存在这个key,就在对应的posting list中追加节点,记录文档ID。若是哈希表没有响应的key则插入该key并建立posting list和对应的节点

  • 重复2 3步处理完因此文档

8ba35f327562e745421d015e3d87c0dc.png建立倒排索引

若是要查询同时包含"暖"“蓝”两个key怎么办?

顺藤摸瓜啦,分别用两个key去倒排索引中检索,这样使用的两个不一样list:A和B。A中的文档都包含了"暖"字,B中的文档都包含了"蓝"字。若是文档即出现"暖"也出现"蓝",是否是就正好包含了两个字?因此只须要找到AB公共元素便可

如何找到AB两个链表的公共元素?但愿小伙伴们思考下,常常在手撕算法中被问到

  • 首先使用两个指针P1 P2分别指向有序链表AB的第一个元素

  • 而后对比两个指针所指节点是否相同,这可能出现三种状况

  • 二者id相同则是公共元素,直接归并便可,而后P1 P2后移

  • p1元素小于p2元素,p1后裔,指向A链表的下一个元素

  • p1元素大于p2元素,p2后裔,指向B链表中下一个元素

  • 重复第二步 直到p1和p2移动到链表尾

0914be0043f1fff6df28bef2cd22529f.png链表公共元素

你说使用过kafka,那么使用消息队列的时候如何保证只消费一次?

首先引入kafka等消息队列是为了对峰值写流量作削峰填谷,对不一样系统作解耦合。

举个例子,咱们开发了一个电商系统,其中一个功能是当用户购买了A产品5份就送一个红包从而鼓励用户消费。可是若是在消息传递的过程当中丢失了,用户极可能会由于没有收到红包而不开心,甚至取消订单,在这里如何保证消息被消费到且一次?

咱们先看看这个消息写入消息队列会有几个阶段,首先有消息从生产者写入消息到队列,消息存储在消息队列,消息被消费者消费这个阶段,任何一个阶段都有可能丢失,咱们分别查看这几个阶段

95484f7420cd5d011e8403e017c81ade.png丢失的三种可能

第一个阶段:消息生产

消息的生产一般会是业务服务器,业务服务器和独立部署的消息队列服务器经过内网通讯,极可能由于网络抖动致使消息的丢失,这样能够采用消息重传的机制保证消息的送达。可是容易出现重复消费的状况,意思收到两个红包,用户开心了,可是。。。

第二个阶段:在队列中丢失

kafka为了减小消息存储对磁盘的随机IO,采用的异步刷盘的方式将消息存储在磁盘中。

我看你简历上打过acm,说说你的策略或者经历吧

哈哈哈,终于到我正儿八经吹水的时候了。低调,才是最牛逼的炫耀

写个验证邮箱的正则

当时没有写出来,确实记不住,每次都是用的时候才去查,谁知道面试的时候碰见谁呢,手撕KMP?这里给你们个答案,后续我详细安排一篇正则的套路

10983b141aa12ad4109a0f702103f156.png实现验证邮箱的正则

了解内存映射?说说,尽可能说

既然是尽可能说,就不客气了。从什么是内存到如何查看服务器内存,最后怎么可以更好地用好内存来答就完事

首先内存做为存储系统和应用程序的指令,数据等。在Linux中,管理内存使用到了内存映射。平时咱们常常说的内存容量,主要指的是物理内存,也叫作主存。只有内核才能直接访问,那么问题来了,进城若是要访问内存怎么办呢?

Linux内核为每一个进程提供了一个虚拟地址空间且空间地址连续,这样的话,进程访问虚拟内存将很是的方便。

虚拟地址又分为内核空间用户空间,不一样字长的处理器地址范围也不一样。咱们下面分别看看32位和64位的虚拟地址空间

bcfe8582aa296f0e0375cbfef0103328.png内核空间与用户空间

从这个图很明显的看出32位系统中内核空间1G,而64位的内核空间与用户空间都是128T。

内存映射即虚拟内存地址映射到物理内存地址,完了顺利完成映射,须要给每一个进程维护一张页表记录二者的关系。

b535d547badf0928b40b4368fb2bd920.png虚拟地址到物理地址的转化

这样,若是进程访问的虚拟地址不在则经过缺页异常进入内核空间分配物理内存,更新进程页表,最终返回用户空间。

说到虚拟内存又不得不说说用户空间的各个段

757d49698e429e2c67ac3ca5bb461052.png用户空间各个段

忍不住悄悄咪咪问了下HR,二面面试官对个人评价,基础和code的能力不错,项目讲述的不清楚

  • 我本身可能没有把项目更本质的东西理解清楚

  • 从事的不一样的方向,有些专业术语的理解的不一样)

三面

三面面试官,真的不能用"秃"来描述了,就感受个人眼睛被闪了一分钟,怎么说,面嘛

线程的锁有哪些,我说到了读写锁打断我了,问我读写锁会有什么些问题,无非就是写锁饥饿问题,我说没看过内核源码,而后若是让我来实现,我怎么来避免

分布式Hash表,当进行扩容的时候(会花费很长的时间),我说P确定必定要保证的,CA只能选其一,可是咱们可使用弱一致性来保证其可用性

多个随机Request请求,而后不一样的请求有不一样的权重,进行随机抽样,要求权重大更可能被抽到

有了解过RPC?

RPC翻译过来为远程过程调用。帮助咱们屏蔽网络细节,实现调用远程方法就跟调用本地同样的体验。举个例子,若是没有桥,咱们要过河只好划船,绕道等方式,若是有桥,咱们就像在路面行走同样自如到目的地。

RPC的通讯流程是怎样的?

刚才说RPC屏蔽了网络细节,也就是意味着它处理好了网络部分,它为了保证可靠性,默认采用TCP传输,网络传输的数据是二进制,可是调用所请求的参数是对象,因此须要将对象转换为二进制,这就须要用到序列化技术

服务提供方接收到数据之后,并不知道哪里是结尾,因此须要一些边界条件来标识请求的数据哪里是开始,哪里是结束,就像高速路上各类指路牌引领咱们前进的方向。这种格式的约定叫作“协议”

根据协议规定的格式,就能够正确的提取出相应的请求,根据请求的类型和序列化的类型,将二进制消息体逆向还原为请求对象,这叫作反序列化

服务提供方经过反序列化的对象找到对应的实现类完成整正的调用,这样就是一次rcp的调用。画个图加深下印象

08de48c10562cf813540c6f6344408ee.pngRPC过程

其余问的一些问题感受在前面的面试问过了就没有写在这部份内容了,还问了几个数据库的问题,很常规的了,以前的文章写过,篇幅太长,看着累,要不先三连,咱们下期再见?么么哒

总结

请记下如下几点:

  • 公司招你去是干活了,不会由于你怎么怎么的而下降对你的要求标准。

  • 工具上面写代码和手撕代码彻底不同。

  • 珍惜每一次面试机会并学会复盘。

  • 对于应届生主要考察的仍是计算机基础知识的掌握,项目要求没有那么高,是本身作的就使劲抠细节,作测试,只有这样,才知道会遇到什么问题,遇到什么难点,如何解决的。从而能够侃侃而谈了。

  • 非科班也不要怕,怕了你就输了!必定要多尝试。

相关文章
相关标签/搜索