2022年春招美团二面总结 凉经

注:部分图片来自网络,如侵必删!

美团二面总结

自我介绍:在这次自我介绍中,不仅是心态上,还是语言表达上,都比一面时要进步很多。

你给我介绍一下你的项目吧

这次面试过程中,面试官倒是直接提示:结合你的技术解决了什么问题来说

由于上次一面已经回答过一次这个问题了,所以这次更得心易手,顺便结合了更多遇到的问题

  1. 介绍为什么要做这个项目
  2. 结合遇到的问题,引出使用到的技术、框架:即使用 xxx 框架,解决了 xxx 问题 的形式
  3. 谈谈在项目过程中遇到的问题、bug、以及如何解决的
  4. 回顾项目,对项目提出新的优化解决方案,如何优化现有项目

你说你用到 Redis,你知道 Redis 除了 String 类型以外,还有什么数据结构吗?

面试官问我这个问题,大概是因为上次一面的时候,我没有回答出吧

那天笔者回去之后又仔细研究了一下 Redis,可是 Redis 的五种基本数据结构和一面时回答的没有问题,即string、list、hash、set、zset 这五钟,以及最后额外补充了一下 bitmap

bitmap 是我故意引出来的,因为笔者刚好前几天了解了一下 bitmap 的使用以及应用场景等等,最后也证实引入 bitmap 是一个正确的选择。

请添加图片描述

BitMap了解么?在什么场景下使用?能解决什么问题?

在本次问题中,面试官主要是追着业务场景进行追问

如,BitMap 可以做什么?朋友圈点赞等功能。

​ 在朋友圈点赞数,如何统计热点数据:用该用户 ID 作为 key,把点赞的 ID 作为 offset,最后使用 bitcount 进行统计。

​ 在海量的数据上,你会如何处理:这里回答的不是很好。

​ redis 实现排行榜:由于笔者对 Redis 的理解不够深入,所以,在这道题上我回答不出来。我向面试官重述一遍问题的时间里(就是给自己多一点时间思考其他的解决方案),突然想到了另一种和关系型数据库有关的解决方案,详细细节见下文。

​ 等等

BitMap

​ BitMap 的基本思想就是用一个 bit 位来标记某个元素对应的 value,而 key 即元素。由于采用了 bit 作为单位来存储数据,因此使用 BitMap可以大大节省地节省存储空间。

​ BitMap 并不是一种数据结构,实际上它就是字符串,但是可以对字符串的位进行操作,可以把 BitMap 想像成一个以 bit 为单位的数组,数组的每个单元存储 0 和 1,数组的下标叫做偏移量。

BitMap 的应用场景

统计

​ 通过 bitcount 可以很快速的统计,比传统的关系型数据库效率高很多

  1. 比如统计年活跃用户数量

    用用户 ID 作为 offset,当用户在一年内访问过网站,就将对应的 offset 的 bit 值设置为 “1”

    通过 bitcount 来统计一年内访问过网站的用户数量

  2. 比如统计三天内活跃用户数量

    时间字符串作为 key,比如 ”20220323:active“、”20220324:active“、“20220325:active“;

    用户的 ID 就可以作为 offset,当用户访问过网站,就将对应的 offset 的 bit 值设置为 “1”

  3. 统计三天的活跃用户,可以通过 or(也就是 “或” 运算) 进行计算,bitop or

  4. 连续三天访问的用户数量,可以通过 and (也就是 “且” 运算) 进行计算,bitop and

  5. 三天都没有访问的用户数量,可以通过 not (也就是 “非” 运算) 进行计算,bitop not

  6. BitMap - Redis 布隆过滤器(应对缓存穿透问题)

    什么是缓存穿透?

    1. 一个查询请求过来,先去访问 Redis,发现 Redis 不存在
    2. 查询数据库,而数据库也查询不到数据,则不写入 Redis
    3. 下一次请求继续循环…

    这种情况,由于 Redis无法缓存数据,导致每次请求都会直接到数据库,数据库压力剧增,导致宕机

    处理方案1:保存 key,value 为 null

    处理方案2:布隆过滤器

    通过对目标数据的表示 hash 为位的下标,目标数据存在则 1,不存在则 0

    注意事项:

    布隆过滤器的重复率依靠的是 hash 算法,所以越完善的 hash 算法,分配的数据越均匀,冲突率越低。

Redis 如何实现排行榜?

由于笔者对 Redis 的理解不够深入,所以,在这道题上我回答不出来。我向面试官重述一遍问题的时间里(就是给自己多一点时间思考其他的解决方案),突然想到了另一种和关系型数据库有关的解决方案,就如下回答:因为最后所有的数据都是要保存进数据库里,所以我们可以在数据库中执行 select top … sorted by … asc 进行查询得到排行榜数据。

​ 结果果不其然,面试官直接给我把问题提升到了海量数据,如何处理。遇到这种问题,我直接条件反射的说到了索引、分库分表。但是面试官说如果分库分表之后,ID 重构问题,这个问题把我问懵住了(其实可以用雪花算法,就可以避免 ID 重构问题)

​ 最后我只好回答:这个问题,我不知道解决,可以请教面试官会如何解决这种问题吗?

​ !!!斯,当时我也不知道为什么我要去问这个问题,哈哈哈哈哈哈。但是我说我不会之后,面试官似乎没有听到,要我重说一遍,我想着:没听到就算了吧,当然最后面试确实是给了我思路:用 Sorted Sets。(这个一开始是有想法的,只是当时的问题是围绕着 BitMap 展开的,所以我以为必须要使用 BitMap 去解决这个业务问题)

请添加图片描述

ZSet 的数据结构

​ sorted set 与 set 结构一样,都不允许重复的元素,但是与 set 不同的是 sorted set 除了 member(元素)之外,每个 member 都会关联一个分数 score。sorted set 根据 score 对元素进行升序排列,如果有多个元素的分数相同,那么按照 member 的字典升序排列,sorted set 中元素不允许相同,但 score 允许相同

适用场景

  1. 朋友圈排行榜,以用户 id 为 member,点赞数得分作为 score,那么就可以得到排行榜,但是需要注意的是 sorted set 是生序排列的,所以如果想取得前 10 的话,需要从最后一个元素开始。
  2. 消息延迟返送,将消息体作为 member,发送时间戳以 score 的形式存储,通过定时任务扫描 sorted set,对 score 小于等于当前时间的 score 对应的消息体进行发送

底层实现

​ sorted set 有两种实现方式,一种是 ziplist 压缩表,一种是 zset(dict、skiplist),redis.conf 有两个配置来控制,当 sorted set 中的元素小于 128 时(即元素对 member score 的个数,共 256 个元素),使用 ziplist,若 ziplist 中所有元素的总长度超过 64 字节时使用 zset

请添加图片描述

​ ziplist 是一个双向链表按照 score 升序排列,当插入一个(member score)对时,ziplist 中插入两个数据项,数据在前,score 在后。ziplist 只能顺序(正 逆)查找,每一步前进两个数据项(member score)

请添加图片描述

算法题

该算法题,就是寻找一个无序数组里,第 N 大的数据(含重复数据)

也就是 [7, 6, 9, 10, 10, 3, 6] 3

返回 9

​ 在阅读完题目之后,我就知道这个算法题是很简单的,只需要排序就可以了,当然如果是简单的冒泡排序肯定会给面试官留下一个很差的印象,所以我打算手写 快排

​ 当我把 快排 的整体代码思路写好之后,想着:我想把题目 ac 之后,再考虑用自己的 快排吧,因为在 java.util.Arrays 类中为我们提供了一个 sort 方法。但最后,我 ac 之后,面试官就不要我继续写下去了,我只好给他讲一下快排的思路加点印象分。

public class Solution {
    /**
     * 本题就比较简单,只需要将无序数组排序之后,返回 n - N 下标的数即可
     */
    public int methods(int[] a, int N) {
        int n = a.length;
        // Arrays.sort(a);
        sort(a, 0, n - 1);
        return a[n - N];
    }
    private static void sort(int[] nums, int left, int right) {
        if(left > right){
            return;
        }
        
        int i = left;
        int j = right;
        int value = nums[left]; // 基准

        while (i < j) {
            while (value <= nums[j] && i < j) j--;
            
            while (value >= nums[i] && i < j) i++;
            
            if (i < j) {
                int temp = nums[j];
                nums[j] = nums[i];
                nums[i] = temp;
            }
        }
        
        nums[left] = nums[i];
        nums[i] = value;
        
        sort(nums, left, j-1);
        sort(nums, j+1, right);
    }
}

聊天

总结

​ 本次面试主要分为两大模块:业务模型、算法题

​ 总体上比较轻松,这里要大大地夸一下美团的面试官!!!人太好了,不管是一面的,还是二面的,都尽力包容我的不足,给我充分的自信去展示自己的优点。但这次面试过程中,还是有比较不满意的地方:感觉没有展示出我的优势或者说特长。

​ 为什么这么说呢?

​ 一是在业务处理,这一块呢,我提出的方案不够好,并且犹犹豫豫的,给面试官一个不好的感受;二是,算法题比较简单,唯一可能可以体现出我的算法能力的就是快排,但是也没有机会写出来,虽然面试结束后做了出来,但心里还是比较落空空的,没有实感。

​ 总结这次面试,我是有一定的运气成分在的。原因是,在面试的前一天,我恰好因为一面 Redis 回答的不够好,又认真的学了一下,最后证实确实是有效地。哈哈哈,但这不能成为我技术差、对 Redis 理解不够深入的理由。所以还是要好好继续学习!!希望能够收到三面通知,并这次面试之后,继续进步!!

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值