拼多多一面

拼多多一面

  1. 自我介绍

  2. 根据我分布式项目,怎么并发下安全扣除库存,单机下和分布式下并发安全

单机对service方法进行synchronize同步,分布式下通过redis的setnx实现分布式锁。

  1. 单机下使用同步锁性能太差,可以通过数据库实现吗?(之前实习公司有特意讨论过这个问题,感谢神州优车的良好的企业文化,善于分享技术。)

可以通过将查询库存和更新库存合并到一条sql语句,作为原子性操作,从而实现并发安全。

  1. 可以通过数据库的事务实现并发安全吗?

不可以,我之前在service层试过添加事务,因为spring的默认事务隔离机制是同数据库的隔离机制,mysql默认是可重复读,由于可重复读机制下对select用的是意向锁,只会对update、delete、insert用排它锁,所以高并发下,多个线程访问同一条记录是不冲突的,那么同一时刻获取的库存是一样的,所以会造成并发安全问题。

  1. 看你有用到redis集群,那我有100台机器,怎么实现key的映射关系

使用redis集群的哈希槽映射

  1. 如果我想对每台机器实现加权呢?比如说,有两台机器,机器A,机器B,但因为机器A的cpu处理性能比机器B强很多,所以我希望70%的key映射到A,30%的映射到B?那如果我有50台机器,并且对每台机器都要实现加权映射,怎么设计算法?我说不知道,他说没事我随便问问。
    面试时,我没有任何想法,后面查了一下,发现这不就是负载均衡的加权轮询算法吗?老哥你问的也太深入了吧。。。
    负载均衡之加权轮询算法

  2. 我想用hashmap结构实现缓存的LRU淘汰策略,怎么改造hashmap?

我说用TreeMap,然后用时间戳作value进行排序。
然后他问我TreeMap的查找时间复杂度是多少?
我一想是底层使用红黑树实现,那么查到时间为O(logn)。
他说缓存基本是读多写少,你这个性能太差了,想想还有什么方法能实现get()的时间复杂度是O(1)?
我想LRU是通过队列实现先进先出的,那么可以仿照linkedHashMap,在hashmap中使用链表实现队列。
他又问,缓存要求读速度快、LRU淘汰策略、还有就是高并发安全,那么我们现在怎么实现高并发安全?
我说最简单粗暴就是对put()和get()进行同步,他说不行,这样性能太差了。
我说如果使用无锁的CAS机制呢?当时我的理解时,并发安全只会发生在淘汰的时候,因为并发下链表的长度是变化的,所以只要通过CAS机制,比较链表长度进行。
他说,那get方法呢?如果我从hashmap中get()获取了一个值,那这个链表有什么变化。
我当时一直没理解过来,get()方法为什么会改变链表。他解释说,如果如果链表有10个节点,我获取了第一个节点的值后,链表会发生什么变化?
喔,hashmap是用来做缓存的啊,如果get之后,需要重新将这个key插入到链表末尾,那么get方法也会导致链表一直在变化,所以也是需要同步的。。。我说暂时我只能想到使用同步了get和put方法了。
他说不行,性能太差,你再想想。
。。。。这我真不知道了,老哥。我说我暂时没有想法了,他就说没事,我就随便问问。
(这面试官给我的面试体验真的超级好,而且有实力,对于我的回答,能很快找到切入点深入挖掘知识掌握能力,我不懂得,还知道安慰我的心情,另外不知道实验室那边好像信号不好,电话重新打了几次,他也没任何怨言,点赞。说起这个,多益网络面试体验是在恨得差,面试基本全程是在找题库问,而且还是对于我的回答浅尝辄止的那种,,,)

  1. 看你用过mq,那你用rabbitmq的时候有没有出现消息重复的情况。

我没理解消息重复是什么意思,就说是生产者重复生产还是消费者重复消费。
他说是消费者重复消费,你觉得有这种情况吗?
我说有的,rabbitmq有消息确认机制,如果消费者收到数据时,会给mq发送收到的确认机制。
那一般什么情况出现重复消费呢?
消费者发送的确认信息在网络中延迟或者丢失。
那怎么处理重复消费信息?
我想想,要校验是否重复消费,无非是通过记录消费过的消息,然后我说可以通过redis存储消息,并且设置一定的过期时间,消费者接受mq消息时,先去redis查看是否已经消费过。

好的,有什么要问我的,,,
希望能去拼多多认识认识这位大佬。拼多多是迄今为止,我面试过最具有技术含量的公司,体验很好,求二面!

你可能感兴趣的:(面试面经)