背景
- 公司:百度
- 部门:地图
- 第几面:一面
- 方向:后端开发
- 语言:Go
- 投递渠道:Boss
- 面试时间:2024.10.12 19:30
- 面试方式:线上(如流)
总体情况
面试时长45分钟左右,因为面试官迟到了10分钟。简单听了第一个项目介绍,没追问难/亮点。然后花20分钟问了1道设计题、八股,花20分钟做了1道算法题。
这个面试官说话速度有点快,然后声音有点小,需要注意力十分集中才行。给我的感觉这个面试官就是属于那种专注代码,不善言辞的那种大佬。
第一次碰到场景题,如果不大确认面试官想考察什么,或者没有思路,可以再跟面试官确认下问题。或者一步一步回答到面试官想要听到的答案上。这次的设计题我应该就是属于一步一步回答到面试官想要听到的答案上。
或许是设计题的答案他比较满意,再加上他迟到了,就只问了我一道八股。然后就发生了以下对话:
面试官:你现在的年包应该有超过**了吧?(猜测的是我当前的3倍)
我:哪有
面试官:那**有了吧?(猜测的是我当前的2倍)
我:只有**(我当时脸都红了,都不好意思说出来了)
面试官:啊?你那个城市的薪资这么低的吗?
对话完然后就开始做题了。并且做完题之后他直接就跟我说会明后天约我二面。
我觉得能让面试官留下这么好的印象,主要不是题目回答的有多好多完美(其实我听回录音,有些答案回答的未必是正确的,也未必是最好的方案)。而是在于能和面试官有个交流,让他觉得你在跟他互动,就像真正在职场中跟他实际讨论一个问题的解决方案一样。也可以在互动中抛出一些你在业界借鉴的设计(我下面就是说的TCP分段设计)来解决这个方案,这样也会让人觉得你技术面比较广。
设计题
面试官:现在我有个需求比如说我去街上,然后去拍一组图片,然后这一组图片我拍回来之后,我要给它传到服务端。如果我是采集方,然后你是这个服务端的接收方,你怎么去设计这个接口呢?
我:一开始有点蒙,之前还没有遇到直接问场景题的,所以又跟面试官确认了一下需求。他再详细给我举了一个例子
面试官:比如我采集到了100张,然后服务端要去判断我这100张都收到了,而且是不重复的,怎么去设计这个接口完成这个采集任务?
我:对于这同一批次的图片可以用时间戳拼接图片序号作为图片ID,例如:“上传时间戳_01”,”上传时间戳_02″,”上传时间戳_03″….”上传时间戳_100″
面试官:但是传的时候应该不是一张一张传的话,时间传太久了。一般传图片或者传这种影像数据,它都不会直接传,因为它占的网络带宽比较大,就是怎么去存这个图片这部分不用去考虑,就是说我现在有一组图片,然后我要想给你回传,就是我回传这个过程应该怎么设计?其实就是保证他回传某一个任务的这些包不重不丢吗?就比如说我有 101 张图片,然后我10个一组,10个一组,然后会传11次对吧,然后服务端怎么去判断我这 11个包全收到?
我:前面的回答应该都不算正确,通过和面试官的沟通+引导到这才明白面试官真正想问什么。我这里联想想到的知识点是TCP数据包分段(MSS)的知识点,但是记不大清了,就大概这么答:可以借鉴于 TCP 分段,就是我协议定的时候加一个hander字段,里面记录这一批量包的图片总数101,然后其他字段就是每一组图片。这样每一次的请求都有总数101 + 1组图片,假设中间有一次请求丢包的话,那其实我最后是可以知道最终接收图片数量对不上总数,就代表发生了丢包要重传
面试官:嗯,那我怎么去重呢?就比如说调你的这个服务端的接口,然后去给你传一组图片。这图片正常来讲你们会在还回一个response,但是有可能有时候是网络抖了一下,他没收到,他那样可能设计了一个重传机制,他又给你传过来重复的这个包,针对于这种重复的包你怎么处理的?
我:首先我觉得如果是从速度上考虑的话,我可以用Redis key去存,就是说我这一批图片可以作为一个哈希map。然后他我重传成功之后,会在这个map里面保存图片ID,就表示这个这一批图片里的某一个图片已经收到了。那如果他第二次发起重传的话,这个时候map里面已经存了这个,就表示我已经上传成功了,我就不需要在第二次再保存它这个图片,主要是用 Redis来保证它的幂等性
面试官:这样还要用一层Redis再判断一次,其实把图片ID设为主键好像也可以解决
我:是的,如果设为数据库主键就不需要再用redis判断了
面试官:好,那这个重复的问题解决了。很多任务它拆包的时候应该不是拆成固定的,就比如说刚才提到那个例子是11个包,有可能再下一个任务采集回传的时候它是21个,然后,对于 11 跟 21 ,在服务端你怎么去判断你这组包前面经过去重之后,它是真的收集全了所有的包呢?
我:到这我怀疑面试官没听清楚或者没有理解到我上面那个模拟TCP分段的思想,于是又给他描述了一次上面那个分段思想。然后再补充了:他传过来的时候我会再把这批照片加起来的总数与包里的总数对比,就知道是否有收集全了
面试官:这个总数应该不用存到MySQL吧?如果用Redis标识这个包的完整度时候是不是可以用减法啊?这样就不用二次提取再做一次计算了
八股
为什么Redis是单线程的,然后性能还这么好吗?(我回答完问题之后,面试官就说:“算了,那些八股也没啥好问的”)
算法
手写个归并排序(我理解就是写个快排,每次二分法处理即可。归并其实也是分治思想,把一个大东西拆成小东西解决)