有了实习之后,都会问哪些通用问题?

推荐各位有精力的同学可以搞个文档,提前就把相关问题的答案写好。通过书面表达来整理自己的逻辑。我也会在每个问题的后面都附上我一般是怎么回答的。

所有内容不一定正确,仅供参考。如果你有更好的回答方式,也可以评论区留言。

优先使用STAR法则来回答面试官的问题:

STAR 法则是由 Situation(情境)、Task(任务)、Action(行动)、Result(结果)四个英文单词首字母组成的框架,能帮助使用者逻辑清晰、重点突出地描述具体经历。

各维度关键要点

  1. Situation:明确事件发生的背景,包括时间、地点、所处环境等,简要说明 “当时处于什么情况”。
  2. Task:阐述在该情境下需要完成的任务、目标或面临的挑战,明确 “要做什么”。
  3. Action:重点描述自己为达成目标采取的具体行动、措施和方法,突出 “我做了什么”。
  4. Result:说明行动带来的最终结果、成果或影响,最好用数据量化,体现 “达成了什么效果”。

1.介绍一下你的实习吧?

我的回答架构一般是 大部门业务+我们服务在大部门中的作用+举一个我们服务的作用例子+我具体做了什么事情(有收益可以讲收益,这一部分不要关注技术细节)

比如:

大部门业务:面试官你好,我所在的部门是字节跳动的tik tok shop,内聚在tiktok应用中。其实就是海外版的抖音商城。

我们服务在大部门的作用:我所在的组主要负责的是营销业务,一整个营销的闭环,包括B段的商家活动搭建到C段的用户命中活动都在我们组实现。而我主要参与的服务主要是营销命中服务,为算价服务提供命中活动,支撑算价服务透出价格给前端。

我们服务的作用例子:比如当用户在商城浏览商品的,如果当前用户是新客,我们的营销命中服务就会为当前用户命中属于他的活动,使得他在商城中看到的价格是新客满减价。并且会显示他所命中的Tag,比如新客满减,比如包邮,比如秒杀。

做了什么事情:我在实习期间主要负责了两部分需求,一个是BC段的对账,提高了C段的数据一致性,降低了20%DB压力,一个是活动召回命中服务的架构升级,降低了接口耗时30ms,降低了30%Redis查询压力。

这里有一个需要注意的是:在讲自己做了什么事的时候,不要过于关注代码细节,而是快速的讲清楚自己做了什么需求。

2.你能介绍一下你们服务的业务架构吗?

这一部分其实最大的问题在于很多同学在职期间就没关注过这玩意,所以我在这里教你一个方式,说出来的也不一定就全是业务架构。但这个大致是能应付过面试官的问题的。

我的回答架构一般是我们服务的上下游+上下游和你们服务的依赖关系+服务内部的不同part

这一部分不能举例子的哈,涉及到内部各种流程细节了。但这个也不是很复杂,相信你可以理解。

3.你举一个你实习中的难点吧?

这一部分要注意的点还是我前面说的:不要过度的陷入到代码细节中,快速讲清楚一整个代码逻辑,越快进入难点的讲解越好,废话不要太多。

我的回答架构一般是:讲清需求背景+快速讲清链路+表明难点+都想出了哪些解决方案+最后用了哪一个+为什么选择了这个解决方案,

在这里我用之前美团实习一个难点来举个例子:

快速讲清楚需求:这个需求是要做一个统计接口调用量的需求。他想要统计不同调用方下不同应用调用不同接口的调用次数。主要的作用是方便RD在做接口更改的时候,确定最大的调用方是谁,方便进行周知。

快速讲清链路:他的整体链路是我们会在线上服务器中通过AOP的方式搞一个切面来在接口调用之前通过一个Map做计数操作。并且内部会有一个定时任务,每隔一个小时将当前服务器中的Map数据进行上报。

表明难点:他的难点主要在于统计Map的数据丢失问题。这个Map会向外暴露两个方法:addCount 和 repotr。而report的逻辑是先上报,再clear map。而在上报数据到Clear 这段时间窗口内的接口调用量就会被删除。

而且一整个接口及接口调用量都比较大,一天总计有三四亿的接口调用总量。所以虽然这个时间窗口短,但还是会丢失比较多的调用量。

解决方案:当时我想出了两个解决方案:

第一个是给Map加锁。让在进行上报的时候,不进行Addcount的操作,先阻塞住。其实就是新创建一个类,这个类有两个元素:map和lock。向外暴露两个方法:getMap和releaseMap。本质上就是先尝试获取/释放这个锁,只有获取/释放了这个锁,才能获取/释放Map。

第二个方案是双CouncurrentHashMap。他的逻辑就是我们让执行上报操作的时候,切换到另外一个map做计数操作。ABMap轮流使用。这样就避免了Clear的操作。双ConcurrentHashMap中有一个比较难的点是当你MapA进行上报操作的时候,我们需要把计数Map设置为MapB,那如何保证这个切换对于所有线程来讲是立即可见的呢?

最后我想到了Volatile关键字。因为它可以保证变量的可见性嘛。

使用Volatile关键字修饰activityMap,引用MapA或MapB来进行计数操作。这样当我们切换MapA OR MapB的时候,本质上就是修改activityMap的引用关系。

伪代码如下:


class MethodCount{

     // 调用量计数器 key:调用方Code value:<bizId-iFaceId, 调用量>
    // 双缓冲区Map A和B
    private static volatile ConcurrentHashMap<String, ConcurrentHashMap<String, Long>> mapA = new ConcurrentHashMap<>();
    private static volatile ConcurrentHashMap<String, ConcurrentHashMap<String, Long>> mapB = new ConcurrentHashMap<>();
    
    // 当前激活的Map的引用
    private static volatile ConcurrentHashMap<String, ConcurrentHashMap<String, Long>> activeMap = mapA;

    
     public update(接口){
        1.更新activemap的对应kv
     }

    //这个方法会被内部的定时任务调用,定期上报
    public repoort(){
        
        1.切换激活的Map
        activeMap = (activeMap == mapA) ? mapB : mapA;

        1.从旧ConcurretnHashMap中取出数据,构造msg

        2.向MQ发送消息

        3.Clear Map 中的旧数据
        
    }
    
}

选择了哪一个以及为什么:

最后我和我mt讨论之后,选择了双Map的设计,因为这个代码更加简洁好写。本质上就是再搞一个Map就好了,对原有架构改动小。而那个LockMap的设计,会对Map本身大改,而且还要阻塞现有的方法调用,升高接口耗时。

我自认为上述讲的还算比较清楚。这也是各位同学要注意的,讲难点的时候不要过分沉浸在代码细节中。快速的讲清楚整体逻辑之后就直接开始讲难点。不要又臭又长。

总结:

其实基本上也就这三个问题了。从介绍完难点开始面试官就会根据你的实习以及你自己的描述来延申的问更多关于实习的内容。所以剩下的路就得靠你自己走了。

但无论怎么样,我仍然建议你做好录音,提前将一部分逻辑以文字的形式整理出来。个人的表达能力其实在面试过程中的影响是很大的。

最后:

我是程序员牛肉,目前就职于字节跳动。文章来自我的学习笔记《小牛八股》。目前正在完善中,估计今年八九月份会写完。提前放出来一些文章引引流。

关注我,带你了解更多代码之外的生存之道。欢迎订阅我的专栏(目前免费),后续也会持续更新。如果这篇文章帮到了你的话,就送我朵花花吧。

代码之外的生存之道 文章被收录于专栏

从双非到美团实习,再到字节跳动。 一路踩过多少坑无需多言。我的目标是把我曾经踩过的坑分享给大家。 我们的生活不止有代码。代码之外,亦是更加广阔的天空

全部评论
点赞 回复 分享
发布于 今天 16:38 江苏
👍🏻
点赞 回复 分享
发布于 今天 16:21 上海
点赞 回复 分享
发布于 今天 16:02 湖北

相关推荐

11-07 11:05
已编辑
西安电子科技大学 golang
点赞 评论 收藏
分享
迷茫的大四🐶:那你问他上班之后老实了没
点赞 评论 收藏
分享
评论
6
9
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务