精华内容
下载资源
问答
  • 消息队列常见面试题笔记
  • 消息队列常见面试题

    2020-12-14 22:28:17
    消息队列我们在工作中或多或少的都有使用过,那在面试中,常见的有那些面试题呢,下面一一进行归纳与总结。 1. 为什么要用消息队列?(消息队列的应用场景?) 2. 各种消息队列产品的比较? 3. 消息队列的优点和...

    消息队列我们在工作中或多或少的都有使用过,那在面试中,常见的有那些面试题呢,下面一一进行归纳与总结。

    1. 为什么要用消息队列?(消息队列的应用场景?)

    2. 各种消息队列产品的比较?

    3. 消息队列的优点和缺点?

    4. 如果保证消息队列的高可用?

    5. 如何保证消息不丢失?

    6. 如何保证消息不被重复消费(如何保证消息的幂等性)?

    7. 如何保证消息消费的顺序性?

    8. 大量消息堆积怎么办?

     

    展开全文
  • RabbitMQ消息队列常见面试题总结

    千次阅读 2021-03-22 02:46:39
    RabbitMQ消息队列常见面试题总结; 1、什么是消息队列?消息队列的优缺点? 2、Kafka、ActiveMQ、RabbitMQ、RocketMQ的区别? 3、如何保证消息不被重复消费? 4、如何保证消息不丢失,进行可靠性传输? 5、如何保证...

    1、什么是消息队列:

    1.1、消息队列的优点:

    (1)解耦:将系统按照不同的业务功能拆分出来,消息生产者只管把消息发布到 MQ 中而不用管谁来取,消息消费者只管从 MQ 中取消息而不管是谁发布的。消息生产者和消费者都不知道对方的存在;

    (2)异步:主流程只需要完成业务的核心功能;对于业务非核心功能,将消息放入到消息队列之中进行异步处理,减少请求的等待,提高系统的总体性能;

    (3)削峰/限流:将所有请求都写到消息队列中,消费服务器按照自身能够处理的请求数从队列中拿到请求,防止请求并发过高将系统搞崩溃;

    1.2、消息队列的缺点:

    (1)系统的可用性降低:系统引用的外部依赖越多,越容易挂掉,如果MQ 服务器挂掉,那么可能会导致整套系统崩溃。这时就要考虑如何保证消息队列的高可用了

    (2)系统复杂度提高:加入消息队列之后,需要保证消息没有重复消费、如何处理消息丢失的情况、如何保证消息传递的有序性等问题;

    (3)数据一致性问题:A 系统处理完了直接返回成功了,使用者都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,就会导致数据不一致了

    1.3、Kafka、ActiveMQ、RabbitMQ、RocketMQ 消息队列的选型:

    每种MQ没有绝对的好坏,主要依据使用场景,扬长避短,利用其优势,规避其劣势。

    (1)中小型软件公司,技术实力较为一般,建议选RabbitMQ:一方面,erlang语言天生具备高并发的特性,而且管理界面用起来十分方便。代码是开源的,而且社区十分活跃,可以解决开发过程中遇到的bug,这点对于中小型公司来说十分重要。

    • 不考虑 rocketmq 的原因是,rocketmq是阿里出品,如果阿里放弃维护rocketmq,中小型公司一般抽不出人来进行rocketmq的定制化开发,因此不推荐。
    • 不考虑 kafka 的原因是:中小型软件公司不如互联网公司,数据量没那么大,选消息中间件应首选功能比较完备的,所以kafka排除

    (2)大型软件公司:根据具体使用场景在rocketMq和kafka之间二选一。

    一方面,大型软件公司,具备足够的资金搭建分布式环境,也具备足够大的数据量。针对rocketMQ,大型软件公司有能力对rocketMQ进行定制化开发。至于kafka,如果是大数据领域的实时计算、日志采集功能,肯定是首选kafka了。

     

    2、RabbitMQ的构造:

    RabbitMQ 是 AMQP 协议的一个开源实现,所以其内部实际上也是 AMQP 中的基本概念:

    RabbitMQ 内部结构

    • (1)生产者Publisher:生产消息,就是投递消息的一方。消息一般包含两个部分:消息体(payload)和标签(Label)
    • (2)消费者Consumer:消费消息,也就是接收消息的一方。消费者连接到RabbitMQ服务器,并订阅到队列上。消费消息时只消费消息体,丢弃标签。
    • (3)Broker服务节点:表示消息队列服务器实体。一般情况下一个Broker可以看做一个RabbitMQ服务器。
    • (4)Queue:消息队列,用来存放消息。一个消息可投入一个或多个队列,多个消费者可以订阅同一队列,这时队列中的消息会被平摊(轮询)给多个消费者进行处理。
    • (5)Exchange:交换器,接受生产者发送的消息,根据路由键将消息路由到绑定的队列上。
    • (6)Routing Key: 路由关键字,用于指定这个消息的路由规则,需要与交换器类型和绑定键(Binding Key)联合使用才能最终生效。
    • (7)Binding:绑定,通过绑定将交换器和队列关联起来,一般会指定一个BindingKey,通过BindingKey,交换器就知道将消息路由给哪个队列了。
    • (8)Connection :网络连接,比如一个TCP连接,用于连接到具体broker
    • (9)Channel: 信道,AMQP 命令都是在信道中进行的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接,一个TCP连接可以用多个信道。客户端可以建立多个channel,每个channel表示一个会话任务。
    • (10)Message:消息,由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
    • (11)Virtual host:虚拟主机,用于逻辑隔离,表示一批独立的交换器、消息队列和相关对象。一个Virtual host可以有若干个Exchange和Queue,同一个Virtual host不能有同名的Exchange或Queue。最重要的是,其拥有独立的权限系统,可以做到 vhost 范围的用户控制。当然,从 RabbitMQ 的全局角度,vhost 可以作为不同权限隔离的手段

     

    3、Exchange交换器的类型:

    Exchange分发消息时根据类型的不同分发策略有区别,目前共四种类型:direct、fanout、topic、headers

    (1)direct:消息中的路由键(RoutingKey)如果和 Bingding 中的 bindingKey 完全匹配,交换器就将消息发到对应的队列中。是基于完全匹配、单播的模式。

    (2)fanout:把所有发送到fanout交换器的消息路由到所有绑定该交换器的队列中,fanout 类型转发消息是最快的。

    (3)topic:通过模式匹配的方式对消息进行路由,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。

    匹配规则:

    • ① RoutingKey 和 BindingKey 为一个 点号 '.' 分隔的字符串。 比如: java.xiaoka.show
    • ② BindingKey可使用 * 和 # 用于做模糊匹配:*匹配一个单词,#匹配多个或者0个单词

    (4)headers:不依赖于路由键进行匹配,是根据发送消息内容中的headers属性进行匹配,除此之外 headers 交换器和 direct 交换器完全一致,但性能差很多,目前几乎用不到了

     

    4、生产者消息的过程:

    • (1)Producer 先连接到 Broker,建立连接 Connection,开启一个信道 channel
    • (2)Producer 声明一个交换器并设置好相关属性
    • (3)Producer 声明一个队列并设置好相关属性
    • (4)Producer 通过绑定键将交换器和队列绑定起来
    • (5)Producer 发送消息到 Broker,其中包含路由键、交换器等信息
    • (6)交换器根据接收到的路由键查找匹配的队列
    • (7)如果找到,将消息存入对应的队列,如果没有找到,会根据生产者的配置丢弃或者退回给生产者。
    • (8)关闭信道

     

    5、消费者接收消息过程:

    • (1)Producer 先连接到 Broker,建立连接 Connection,开启一个信道 channel
    • (2)向 Broker 请求消费相应队列中消息,可能会设置响应的回调函数。
    • (3)等待 Broker 回应并投递相应队列中的消息,接收消息。
    • (4)消费者确认收到的消息,ack。
    • (5)RabbitMQ从队列中删除已经确定的消息。
    • (6)关闭信道

     

    6、如何保证消息不被重复消费?

    正常情况下,消费者在消费消息后,会给消息队列发送一个确认,消息队列接收后就知道消息已经被成功消费了,然后就从队列中删除该消息,也就不会将该消息再发送给其他消费者了。不同消息队列发出的确认消息形式不同,RabbitMQ是通过发送一个ACK确认消息。但是因为网络故障,消费者发出的确认并没有传到消息队列,导致消息队列不知道该消息已经被消费,然后就再次消息发送给了其他消费者,从而造成重复消费的情况。

    重复消费问题的解决思路是:保证消息的唯一性,即使多次传输,也不让消息的多次消费带来影响,也就是保证消息等幂性;幂等性指一个操作执行任意多次所产生的影响均与一次执行的影响相同。具体解决方案如下:

    (1)改造业务逻辑,使得在重复消费时也不影响最终的结果。例如对SQL语句: update t1 set money = 150 where id = 1 and money = 100; 做了个前置条件判断,即 money = 100 的情况下才会做更新,更通用的是做个 version 即版本号控制,对比消息中的版本号和数据库中的版本号。

    (2)基于数据库的的唯一主键进行约束。消费完消息之后,到数据库中做一个 insert 操作,如果出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。

    (3)通过记录关键的key,当重复消息过来时,先判断下这个key是否已经被处理过了,如果没处理再进行下一步。

    • ① 通过数据库:比如处理订单时,记录订单ID,在消费前,去数据库中进行查询该记录是否存在,如果存在则直接返回。
    • ② 使用全局唯一ID,再配合第三组主键做消费记录,比如使用 redis 的 set 结构,生产者发送消息时给消息分配一个全局ID,在每次消费者开始消费前,先去redis中查询有没有消费记录,如果消费过则不进行处理,如果没消费过,则进行处理,消费完之后,就将这个ID以k-v的形式存入redis中(过期时间根据具体情况设置)。

     

    7、如何保证消息不丢失,进行可靠性传输?

    对于消息的可靠性传输,每种MQ都要从三个角度来分析:生产者丢数据、消息队列丢数据、消费者丢数据。以RabbitMQ为例:

    7.1、生产者丢数据:

    RabbitMQ提供事务机制(transaction)和确认机制(confirm)两种模式来确保生产者不丢消息。

    (1)事务机制:

    发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事务(channel.txCommit())

    该方式的缺点是生产者发送消息会同步阻塞等待发送结果是成功还是失败,导致生产者发送消息的吞吐量降下降。

        // 开启事务
        channel.txSelect
        try {
            // 发送消息
        } catch(Exception e){
            // 回滚事务
            channel.txRollback;
            //再次重试发送这条消息
            ....
        }      
        //提交事务
        channel.txCommit;

    (2)确认机制:

    生产环境常用的是confirm模式。生产者将信道 channel 设置成 confirm 模式,一旦 channel 进入 confirm 模式,所有在该信道上发布的消息都将会被指派一个唯一的ID,一旦消息被投递到所有匹配的队列之后,rabbitMQ就会发送一个确认给生产者(包含消息的唯一ID),这样生产者就知道消息已经正确到达目的队列了。如果rabbitMQ没能处理该消息,也会发送一个Nack消息给你,这时就可以进行重试操作。

    Confirm模式最大的好处在于它是异步的,一旦发布消息,生产者就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者便可以通过回调方法来处理该确认消息。

    处理Ack和Nack的代码如下所示:

    channel.addConfirmListener(new ConfirmListener() {  
        @Override  
        public void handleNack(long deliveryTag, boolean multiple) throws IOException {  
            System.out.println("nack: deliveryTag = "+deliveryTag+" multiple: "+multiple);  
        }  
        @Override  
        public void handleAck(long deliveryTag, boolean multiple) throws IOException {  
            System.out.println("ack: deliveryTag = "+deliveryTag+" multiple: "+multiple);  
        }  
    }); 

    7.2、消息队列丢数据:

    处理消息队列丢数据的情况,一般是开启持久化磁盘。持久化配置可以和生产者的 confirm 机制配合使用,在消息持久化磁盘后,再给生产者发送一个Ack信号。这样的话,如果消息持久化磁盘之前,即使rabbitMQ挂掉了,生产者也会因为收不到Ack信号而再次重发消息。

    持久化设置如下(必须同时设置以下 2 个配置):

    • (1)创建queue的时候,将queue的持久化标志durable在设置为true,代表是一个持久的队列,这样就可以保证 rabbitmq 持久化 queue 的元数据,但是不会持久化queue里的数据;
    • (2)发送消息的时候将 deliveryMode 设置为 2,将消息设置为持久化的,此时 rabbitmq就会将消息持久化到磁盘上去。

    7.3、消费者丢数据:

    消费者丢数据一般是因为采用了自动确认消息模式。该模式下,虽然消息还在处理中,但是消费中者会自动发送一个确认,通知rabbitmq已经收到消息了,这时rabbitMQ就会立即将消息删除。这种情况下,如果消费者出现异常而未能处理消息,那就会丢失该消息。解决方案就是采用手动确认消息,等到消息被真正消费之后,再手动发送一个确认信号,即使中途消息没处理完,但是服务器宕机了,那rabbitmq就收不到发的ack,然后 rabbitmq 就会将这条消息重新分配给其他的消费者去处理。

    需要注意的是:消息可靠性增强了,性能就下降了,因为写磁盘比写 RAM 慢的多,两者的吞吐量可能有 10 倍的差距。所以,是否要对消息进行持久化,需要综合考虑业务场景、性能需要,以及可能遇到的问题。若想达到单RabbitMQ服务器 10W 条/秒以上的消息吞吐量,则要么使用其他的方式来确保消息的可靠传输,要么使用非常快速的存储系统以支持全持久化,例如使用 SSD。或者仅对关键消息作持久化处理,且应该保证关键消息的量不会导致性能瓶颈。

     

    8、如何保证消息的有序性?

    针对保证消息有序性的问题,解决方法就是保证生产者入队的顺序是有序的,出队后的顺序消费则交给消费者去保证。

    (1)方法一:拆分queue,使得一个queue只对应一个消费者。由于MQ一般都能保证内部队列是先进先出的,所以把需要保持先后顺序的一组消息使用某种算法都分配到同一个消息队列中。然后只用一个消费者单线程去消费该队列,这样就能保证消费者是按照顺序进行消费的了。但是消费者的吞吐量会出现瓶颈。如果多个消费者同时消费一个队列,还是可能会出现顺序错乱的情况,这就相当于是多线程消费了

    (2)方法二:对于多线程的消费同一个队列的情况,可以使用重试机制:比如有一个微博业务场景的操作,发微博、写评论、删除微博,这三个异步操作。如果一个消费者先执行了写评论的操作,但是这时微博都还没发,写评论一定是失败的,等一段时间。等另一个消费者,先执行发微博的操作后,再执行,就可以成功。

     

    9、如何处理消息堆积情况?

    场景题:几千万条数据在MQ里积压了七八个小时。

    9.1、出现该问题的原因:

    消息堆积往往是生产者的生产速度与消费者的消费速度不匹配导致的。有可能就是消费者消费能力弱,渐渐地消息就积压了,也有可能是因为消息消费失败反复复重试造成的,也有可能是消费端出了问题,导致不消费了或者消费极其慢。比如,消费端每次消费之后要写mysql,结果mysql挂了,消费端hang住了不动了,或者消费者本地依赖的一个东西挂了,导致消费者挂了。

    所以如果是 bug 则处理 bug;如果是因为本身消费能力较弱,则优化消费逻辑,比如优化前是一条一条消息消费处理的,那么就可以批量处理进行优化。

    9.2、临时扩容,快速处理积压的消息:

    (1)先修复 consumer 的问题,确保其恢复消费速度,然后将现有的 consumer 都停掉;

    (2)临时创建原先 N 倍数量的 queue ,然后写一个临时分发数据的消费者程序,将该程序部署上去消费队列中积压的数据,消费之后不做任何耗时处理,直接均匀轮询写入临时建立好的 N 倍数量的 queue 中;

    (3)接着,临时征用 N 倍的机器来部署 consumer,每个 consumer 消费一个临时 queue 的数据

    (4)等快速消费完积压数据之后,恢复原先部署架构 ,重新用原先的 consumer 机器消费消息。

    这种做法相当于临时将 queue 资源和 consumer 资源扩大 N 倍,以正常 N 倍速度消费。

    9.3、恢复队列中丢失的数据:

    如果使用的是 rabbitMQ,并且设置了过期时间,消息在 queue 里积压超过一定的时间会被 rabbitmq 清理掉,导致数据丢失。这种情况下,实际上队列中没有什么消息挤压,而是丢了大量的消息。所以就不能说增加 consumer 消费积压的数据了,这种情况可以采取 “批量重导” 的方案来进行解决。在流量低峰期,写一个程序,手动去查询丢失的那部分数据,然后将消息重新发送到mq里面,把丢失的数据重新补回来。

    9.4、MQ长时间未处理导致MQ写满的情况如何处理:

    如果消息积压在MQ里,并且长时间都没处理掉,导致MQ都快写满了,这种情况肯定是临时扩容方案执行太慢,这种时候只好采用 “丢弃+批量重导” 的方式来解决了。首先,临时写个程序,连接到mq里面消费数据,消费一个丢弃一个,快速消费掉积压的消息,降低MQ的压力,然后在流量低峰期时去手动查询重导丢失的这部分数据。

     

    10、如何保证消息队列的高可用?

    RabbitMQ 是基于主从(非分布式)做高可用性的,RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式

    10.1、单机模式:一般没人生产用单机模式

    10.2、普通集群模式:

    就是在多台机器上启动多个 RabbitMQ 实例,每个机器启动一个。我们创建的 queue,只会放在其中一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。消费的时候,如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来。

    (1)优点:普通集群模式主要用于提高系统的吞吐量,可以通过添加更加的节点来线性的扩展消息队列的吞吐量,就是说让集群中多个节点来服务某个 queue 的读写操作

    (2)缺点:无高可用性,queue所在的节点宕机了,其他实例就无法从那个实例拉取数据;RabbitMQ 内部也会产生大量的数据传输。

    10.3、镜像集群模式:

    RabbitMQ 真正的高可用模式。镜像集群模式下,队列的元数据和消息会存在于多个实例上,每次写消息到 queue 时,会自动将消息同步到各个实例的 queue ,也就是说每个 RabbitMQ 节点都有这个 queue 的完整镜像,包含 queue 的全部数据。任何一个机器宕机了,其它机器节点还包含了这个 queue 的完整数据,其他 consumer 都可以到其它节点上去消费数据。

    配置镜像队列的集群都包含一个主节点master和若干个从节点slave,slave会准确地按照master执行命令的顺序进行动作,故slave与master上维护的状态应该是相同的。如果master由于某种原因失效,那么按照slave加入的时间排序,"资历最老"的slave会被提升为新的master。

    除发送消息外的所有动作都只会向master发送,然后再由master将命令执行的结果广播给各个slave。如果消费者与slave建立连接并进行订阅消费,其实质上都是从master上获取消息,只不过看似是从slave上消费而已。比如消费者与slave建立了TCP连接之后执行一个Basic.Get的操作,那么首先是由slave将Basic.Get请求发往master,再由master准备好数据返回给slave,最后由slave投递给消费者。

    (1)缺点:

    ① 性能开销大,消息需要同步到所有机器上,导致网络带宽压力和消耗很重

    ② 非分布式,没有扩展性,如果 queue 的数据量大到这个机器上的容量无法容纳了,此时该方案就会出现问题了

    (2)如何开启镜像集群模式呢?

    在RabbitMQ 的管理控制台Admin页面下,新增一个镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点,再次创建 queue 的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。

     

    11、其他:

    (1)交换器无法根据自身类型和路由键找到符合条件队列时,有哪些处理方式:设置mandatory = true,代表返回消息给生产者;设置mandatory = false,代表直接丢弃

    (2)消费者得到消息队列中的数据的方式:push 和 pull

    (3)消息基于什么传输:由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。所以RabbitMQ 使用信道 channel 的方式来传输数据,信道是建立在真实的 TCP 连接内的虚拟连接,且每条 TCP 连接上的信道数量没有限制。

    (4)死信队列DLX:

    DLX也是一个正常的Exchange,和一般的Exchange没有任何区别。能在任何的队列上被指定,实际上就是设置某个队列的属性。当这个队列出现死信(dead message,就是没有任何消费者消费)的时候,RabbitMQ就会自动将这条消息重新发布到Exchange上去,进而被路由到另一个队列。可以监听这个队列中的消息作相应的处理。消息变为死信的几种情况:

    • 消息被拒绝(basic.reject/basic.nack)同时requeue=false(不重回队列)
    • TTL过期
    • 队列达到最大长度,无法再添加

    (5)延迟队列:存储对应的延迟消息,当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

    (6)优先级队列:优先级高的队列会先被消费,可以通过x-max-priority参数来实现。但是当消费速度大于生产速度且 Broker 没有堆积的情况下,优先级显得没有意义。

    (7)RabbitMQ 要求集群中至少有一个磁盘节点,其他节点可以是内存节点,当节点加入或离开集群时,必须要将该变更通知到至少一个磁盘节点。如果只有一个磁盘节点,刚好又是该节点崩溃了,那么集群可以继续路由消息,但不能创建队列、创建交换器、创建绑定、添加用户、更改权限、添加或删除集群节点。也就是说集群中的唯一磁盘节点崩溃的话,集群仍然可以运行,但直到该节点恢复前,无法更改任何东西。

     


    相关阅读:

    SpringMVC常见面试题总结

    Spring常见面试题总结

    Mybatis常见面试题总结

    MySQL常见面试题总结

    RabbitMQ消息队列常见面试题总结

    ElasticSearch搜索引擎常见面试题总结

    计算机网络常见面试题总结

    操作系统常见面试题总结

    海量数据处理的方法总结

    展开全文
  • 为什么要使用消息队列?2.消息队列推、拉模式区别?3.消息队列有什么缺点?4.消息如何保证幂等性?5.消息队列为什么会出现重复消费?6.消息如何保证可靠性?7.如何保证消息顺序?8.消息队列积压怎么办9.Kafka架构?...

    1.为什么要使用消息队列?

    简单来说就是:解耦、异步、削峰。
    消息队列可以对系统异步功能进行剥离,减少功能耦合,提供开发效率;
    消息队列可以削峰限流,确保下游消费者稳定运行。
    参考:Java架构直通车——MQ应用场景与JMS规范
    在这里插入图片描述

    2.消息队列推、拉模式区别?

    • push模式
      推模式指的是客户端与服务端建立好网络长连接,服务方有相关数据,直接通过长连接通道推送到客户端。其优点是 及时 ,一旦有数据变更,客户端立马能感知到;另外对客户端来说逻辑简单,不需要关心有无数据这些逻辑处理。缺点是不知道客户端的数据消费能力,可能导致数据积压在客户端,来不及处理。另外,服务端保存push状态(哪些客户端发送成功,哪些没有发送成功),push状态是集中保存在服务端的,负载均衡也由服务端进行统一处理。
    • pull模式
      客户端主动从服务端轮询拉取数据,其优点是不存在推模式中数据积压的问题。故缺点是可能不够及时,对客户端来说需要考虑数据拉取相关逻辑,这就需要客户端保存pull状态(以便在故障重启的时候恢复),pull状态是分散保存在客户端的,负载均衡由客户端之间做调配(比如使用zookeeper)。

    kafka是通过一个提交日志记录的方式来存储消息记录,采用拉模式,而RabbitMQ有推模式和拉模式,其中推模式采用socket长连接来做通知。

    3.消息队列有什么缺点?

    系统可靠性降低,解耦后,多个系统通过消息中间件交互,消息中间件挂了整个系统就挂了;
    系统开发复杂度提升,需要考虑消息的处理,包括消息幂等性(重复消费问题),消息保序性(一个订单多条消息问题),以及消息中间件本身的持久化和稳定性可靠性;
    消息一致性问题,如果一个功能发给多个系统,要所有系统都执行成功才算成功时,需要确保一个功能多个消息的完整一致性;

    4.消息如何保证幂等性?

    参考:MQ 生产端可靠性投递和消费端幂等性保障方案
    参考:Java架构直通车——幂等性接口设计

    5.消息队列为什么会出现重复消费?

    1. 客户端宕机

    kafka实际上有个offset的概念,就是每个消息写进去,都有一个offset,代表他的序号,然后consumer消费了数据之后,每隔一段时间,会把自己消费过的消息的offset提交一下,代表我已经消费过了,下次我要是重启啥的,你就让我继续从上次消费到的offset来继续消费吧。

    但是凡事总有意外,比如我们之前生产经常遇到的,就是你有时候重启系统,看你怎么重启了,如果碰到点着急的,直接kill进程了,再重启。这会导致consumer有些消息处理了,但是没来得及提交offset,尴尬了。重启之后,少数消息会再次消费一次。

    1. 网络问题

    另外,只要通过网络交换数据,就无法避免重复消费。AMQP 定义了消费者确认机制(message ack),如果服务端投递消息到消费端,然而消费端虽然收到这个消息,但是消费端发送的ACK消息丢失,那服务端Broker就无法获得 ACK确认,那么消息会被重新放入队列。所以 AMQP 提供的是“至少一次交付”(at-least-once delivery),异常情况下,消息会被重复消费,此时业务要实现幂等性(重复消息处理)。

    6.消息如何保证可靠性?

    参考:MQ 生产端可靠性投递和消费端幂等性保障方案

    7.如何保证消息顺序?

    • 对于activeMQ,可以通过exclusive方式让一个queue始终被一个consumer消费;或者messageGroup方式;
    • 对于rabbitMQ, 一个queue对应一个consumer才行,多个consumer对应一个queue就容易错乱;
    • 对于kafka,partition的消息是保序的。然后它强制要求一个partition只能投递给同组内的一个consume(即partition出只能有一个consumer,不能投递给同组内两个consumer,只是同组内的consumer却可以消费多个partition),所以不存在多个消费者错乱的问题。然后生产者可以设定一个key,同一个key的可以发送到同一个partition中,这样同一个key的消息在partition中是保序;
      如果kafka在消费端开启多线程,也会出现乱序。可以在消费端加队列,按照业务保序增加内存队列,这样队列中的消息与partition中顺序是一致的,然后多线程从队列中取数据,每次取一个完整顺序的消息进行处理即可。

    8.消息队列积压怎么办

    消息发送主要涉及三方:producer/consumer/broker,所以发生消息积压要从这三方来看。

    • 发生消息积压后,producer端服务降级,关闭一些非核心业务,减少消息的产生。
    • 扩容consumer实例,注意扩容后必须同步扩容主题中的分区(也叫队列)数量,确保 Consumer 的实例数和分区数量是相等的,因为在队列中的消费是单线程的,如果只扩容了consumer实例,没有扩容队列数量,则不会有效果的。
    • 其实不用太关注消息队列,因为消息队列本身的处理能力要远远大于业务系统的处理能力。主流消息队列的单个节点,消息收发的性能可以达到每秒钟处理几万至几十万条消息的水平,还可以通过水平扩展 Broker 的实例数成倍地提升处理能力。

    9.简单介绍Kafka?Kafka架构?

    Kafka是一个分布式流式处理平台,提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。一般用于大数据实时计算领域中以及日志采集中。因为Kafka提供了发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。kafka 唯一的一点劣势是有可能消息重复消费,但是如果Kafka应用于大数据、日志采集的话,对数据准确性会造成极其轻微的影响。

    Kafka本身的结构遵从JMS的发布订阅模型,为了提高效率,消息被分批次写入Kafka ,这些消息属于同一个主题(topic)和分区(partition)。不过消息分批需要在时间延迟和吞吐量之前做一个权衡(单位时间内批次越大,单位时间内处理的消息就越多,但是单个消息的传输时间就会越长)。主题可以被分为若干个分区,消息以追加的方式写入分区,然后以先入先出FIFO的顺序读取。
    一个独立的Kafka 服务器被称为broker。broker 接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。broker 为消费者提供服务,对读取分区的请求作出响应,返回已经提交到磁盘上的消息。broker 是集群的组成部分,Kafka 集群为分区(Partition)引入了多副本(Replica)机制来提供冗余。

    参考:Kafka概述

    10.简单介绍RabbitMQ?RabbitMQ架构?

    参考:Java架构直通车——RabbitMQ核心概念和消息流转方式

    参考:Java架构直通车——RabbitMQ集群架构模式

    RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。

    11. JMS是什么?AMPQ又是什么?

    JMS(JAVA Message Service,java消息服务),JMS的客户端之间可以通过JMS服务进行异步的消息传输。

    JMS提供了两种消息模型,peer-2-peer(点对点)以及publish-subscribe(发布订阅)模型。当采用点对点模型时,消息将发送到一个队列(queue),该队列的消息只能被一个消费者消费。而采用发布订阅模型时,消息将发送到一个**主题(topic)**上,消息可以被多个消费者消费。在发布订阅模型中,生产者和消费者完全独立,不需要感知对方的存在。

    • 点到点(P2P)模型
      在这里插入图片描述

    • 发布/订阅(Pub/Sub)模型   
      在这里插入图片描述


    AMQP是一种应用层协议的开放标准,最早用于解决金融领不同平台之间的消息传递交互,这种标准使得实现了AMQP协议天然性就是跨平台的。与JMS本质上不同的是,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。意味着我们可以使用Java的AMQP provider,同时使用一个python的producer加一个rubby的consumer。

    另外,在AMQP中,消息路由(messagerouting)和JMS存在一些差别,在AMQP中增加了Exchange和binding的角色。producer将消息发送给Exchange,binding决定Exchange的消息应该发送到那个queue。

    12. Kafka 如何保证消息的消费顺序?

    1. 很简单的保证消息消费顺序的方法:1 个 Topic 只对应一个 Partition。这样当然可以解决问题,但是破坏了 Kafka 的设计初衷。

    2. Kafka 中发送 1 条消息的时候,可以指定 topic, partition, key,data(数据) 4 个参数。如果你发送消息的时候指定了 Partition 的话,所有消息都会被发送到指定的 Partition。并且,同一个 key 的消息可以保证只发送到同一个 partition,这个我们可以采用表/对象的 id 来作为 key 。

    13. Kafka 如何保证消息不丢失?

    生产者弄丢消息:

    1. Kafka 生产者(Producer) 使用 send 方法发送消息实际上是异步的操作,我们可以通过 get()方法获取调用结果,但是这样也让它变为了同步操作。
    2. 采用为其添加回调函数的形式,如果消息发送失败的话,我们检查失败的原因之后可以设定一个retries次数并重新发送。比如:
    ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, o);
    future.addCallback(result -> logger.info("生产者成功发送消息到topic:{} partition:{}的消息", result.getRecordMetadata().topic(), result.getRecordMetadata().partition()),
                    ex -> logger.error("生产者发送消失败,原因:{}", ex.getMessage()));
    

    消费者弄丢消息:
    我们知道消息在被追加到 Partition(分区)的时候都会分配一个特定的偏移量(offset)。偏移量(offset)表示 Consumer 当前消费到的 Partition(分区)的所在的位置。Kafka 通过偏移量(offset)可以保证消息在分区内的顺序性。
    当消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。自动提交的话会有一个问题,试想一下,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了。
    解决办法也比较粗暴,我们手动关闭闭自动提交 offset,每次在真正消费完消息之后之后再自己手动提交 offset 。 但是,细心的朋友一定会发现,这样会带来消息被重新消费的问题。比如你刚刚消费完消息之后,还没提交 offset,结果自己挂掉了,那么这个消息理论上就会被消费两次。

    Kafka 弄丢了消息:
    Kafka 为分区(Partition)引入了多副本(Replica)机制。假如 leader 副本所在的 broker 突然挂掉,那么就要从 follower 副本重新选出一个 leader ,但是 leader 的数据还有一些没有被 follower 副本的同步的话,就会造成消息丢失。
    解决办法是可以设置消息被多个或者全部副本同步后才算消息被成功接收。

    14. Kafka 存储在文件系统上,会不会很慢?

    不会。
    物理上存储的其实是 Partition,每一个 Partition 最终对应一个目录,里面存储所有的消息和索引文件。任何发布到 Partition 的消息都会被追加到 Partition 数据文件的尾部,这样的顺序写磁盘操作让 Kafka 的效率非常高(经验证,顺序写磁盘效率比随机写内存还要高,这是 Kafka 高吞吐率的一个很重要的保证)。

    展开全文
  • 最新Java面试题,常见面试题及答案汇总

    万次阅读 多人点赞 2019-07-12 08:56:55
    Java最新面试题面试题答案汇总

    Java最新常见面试题 + 答案汇总

    原文地址:https://blog.csdn.net/sufu1065/article/details/88051083

    1、面试题模块汇总

    面试题包括以下十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM 。如下图所示:

    可能对于初学者不需要后面的框架和 JVM 模块的知识,读者朋友们可根据自己的情况,选择对应的模块进行阅读。

    适宜阅读人群

    • 需要面试的初/中/高级 java 程序员
    • 想要查漏补缺的人
    • 想要不断完善和扩充自己 java 技术栈的人
    • java 面试官

    具体面试题

    下面一起来看 208 道面试题,具体的内容。

    一、Java 基础

    1.JDK 和 JRE 有什么区别?

    2.== 和 equals 的区别是什么?

    3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

    4.final 在 java 中有什么作用?

    5.java 中的 Math.round(-1.5) 等于多少?

    6.String 属于基础的数据类型吗?

    7.java 中操作字符串都有哪些类?它们之间有什么区别?

    8.String str="i"与 String str=new String(“i”)一样吗?

    9.如何将字符串反转?

    10.String 类的常用方法都有那些?

    11.抽象类必须要有抽象方法吗?

    12.普通类和抽象类有哪些区别?

    13.抽象类能使用 final 修饰吗?

    14.接口和抽象类有什么区别?

    15.java 中 IO 流分为几种?

    16.BIO、NIO、AIO 有什么区别?

    17.Files的常用方法都有哪些?

    二、容器

    18.java 容器都有哪些?

    19.Collection 和 Collections 有什么区别?

    20.List、Set、Map 之间的区别是什么?

    21.HashMap 和 Hashtable 有什么区别?

    22.如何决定使用 HashMap 还是 TreeMap?

    23.说一下 HashMap 的实现原理?

    24.说一下 HashSet 的实现原理?

    25.ArrayList 和 LinkedList 的区别是什么?

    26.如何实现数组和 List 之间的转换?

    27.ArrayList 和 Vector 的区别是什么?

    28.Array 和 ArrayList 有何区别?

    29.在 Queue 中 poll()和 remove()有什么区别?

    30.哪些集合类是线程安全的?

    31.迭代器 Iterator 是什么?

    32.Iterator 怎么使用?有什么特点?

    33.Iterator 和 ListIterator 有什么区别?

    34.怎么确保一个集合不能被修改?

    三、多线程

    35.并行和并发有什么区别?

    36.线程和进程的区别?

    37.守护线程是什么?

    38.创建线程有哪几种方式?

    39.说一下 runnable 和 callable 有什么区别?

    40.线程有哪些状态?

    41.sleep() 和 wait() 有什么区别?

    42.notify()和 notifyAll()有什么区别?

    43.线程的 run()和 start()有什么区别?

    44.创建线程池有哪几种方式?

    45.线程池都有哪些状态?

    46.线程池中 submit()和 execute()方法有什么区别?

    47.在 java 程序中怎么保证多线程的运行安全?

    48.多线程锁的升级原理是什么?

    49.什么是死锁?

    50.怎么防止死锁?

    51.ThreadLocal 是什么?有哪些使用场景?

    52.说一下 synchronized 底层实现原理?

    53.synchronized 和 volatile 的区别是什么?

    54.synchronized 和 Lock 有什么区别?

    55.synchronized 和 ReentrantLock 区别是什么?

    56.说一下 atomic 的原理?

    四、反射

    57.什么是反射?

    58.什么是 java 序列化?什么情况下需要序列化?

    59.动态代理是什么?有哪些应用?

    60.怎么实现动态代理?

    五、对象拷贝

    61.为什么要使用克隆?

    62.如何实现对象克隆?

    63.深拷贝和浅拷贝区别是什么?

    六、Java Web

    64.jsp 和 servlet 有什么区别?

    65.jsp 有哪些内置对象?作用分别是什么?

    66.说一下 jsp 的 4 种作用域?

    67.session 和 cookie 有什么区别?

    68.说一下 session 的工作原理?

    69.如果客户端禁止 cookie 能实现 session 还能用吗?

    70.spring mvc 和 struts 的区别是什么?

    71.如何避免 sql 注入?

    72.什么是 XSS 攻击,如何避免?

    73.什么是 CSRF 攻击,如何避免?

    七、异常

    74.throw 和 throws 的区别?

    75.final、finally、finalize 有什么区别?

    76.try-catch-finally 中哪个部分可以省略?

    77.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

    78.常见的异常类有哪些?

    八、网络

    79.http 响应码 301 和 302 代表的是什么?有什么区别?

    80.forward 和 redirect 的区别?

    81.简述 tcp 和 udp的区别?

    82.tcp 为什么要三次握手,两次不行吗?为什么?

    83.说一下 tcp 粘包是怎么产生的?

    84.OSI 的七层模型都有哪些?

    85.get 和 post 请求有哪些区别?

    86.如何实现跨域?

    87.说一下 JSONP 实现原理?

    九、设计模式

    88.说一下你熟悉的设计模式?

    89.简单工厂和抽象工厂有什么区别?

    十、Spring/Spring MVC

    90.为什么要使用 spring?

    91.解释一下什么是 aop?

    92.解释一下什么是 ioc?

    93.spring 有哪些主要模块?

    94.spring 常用的注入方式有哪些?

    95.spring 中的 bean 是线程安全的吗?

    96.spring 支持几种 bean 的作用域?

    97.spring 自动装配 bean 有哪些方式?

    98.spring 事务实现方式有哪些?

    99.说一下 spring 的事务隔离?

    100.说一下 spring mvc 运行流程?

    101.spring mvc 有哪些组件?

    102.@RequestMapping 的作用是什么?

    103.@Autowired 的作用是什么?

    十一、Spring Boot/Spring Cloud

    104.什么是 spring boot?

    105.为什么要用 spring boot?

    106.spring boot 核心配置文件是什么?

    107.spring boot 配置文件有哪几种类型?它们有什么区别?

    108.spring boot 有哪些方式可以实现热部署?

    109.jpa 和 hibernate 有什么区别?

    110.什么是 spring cloud?

    111.spring cloud 断路器的作用是什么?

    112.spring cloud 的核心组件有哪些?

    十二、Hibernate

    113.为什么要使用 hibernate?

    114.什么是 ORM 框架?

    115.hibernate 中如何在控制台查看打印的 sql 语句?

    116.hibernate 有几种查询方式?

    117.hibernate 实体类可以被定义为 final 吗?

    118.在 hibernate 中使用 Integer 和 int 做映射有什么区别?

    119.hibernate 是如何工作的?

    120.get()和 load()的区别?

    121.说一下 hibernate 的缓存机制?

    122.hibernate 对象有哪些状态?

    123.在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?

    124.hibernate 实体类必须要有无参构造函数吗?为什么?

    十三、Mybatis

    125.mybatis 中 #{}和 ${}的区别是什么?

    126.mybatis 有几种分页方式?

    127.RowBounds 是一次性查询全部结果吗?为什么?

    128.mybatis 逻辑分页和物理分页的区别是什么?

    129.mybatis 是否支持延迟加载?延迟加载的原理是什么?

    130.说一下 mybatis 的一级缓存和二级缓存?

    131.mybatis 和 hibernate 的区别有哪些?

    132.mybatis 有哪些执行器(Executor)?

    133.mybatis 分页插件的实现原理是什么?

    134.mybatis 如何编写一个自定义插件?

    十四、RabbitMQ

    135.rabbitmq 的使用场景有哪些?

    136.rabbitmq 有哪些重要的角色?

    137.rabbitmq 有哪些重要的组件?

    138.rabbitmq 中 vhost 的作用是什么?

    139.rabbitmq 的消息是怎么发送的?

    140.rabbitmq 怎么保证消息的稳定性?

    141.rabbitmq 怎么避免消息丢失?

    142.要保证消息持久化成功的条件有哪些?

    143.rabbitmq 持久化有什么缺点?

    144.rabbitmq 有几种广播类型?

    145.rabbitmq 怎么实现延迟消息队列?

    146.rabbitmq 集群有什么用?

    147.rabbitmq 节点的类型有哪些?

    148.rabbitmq 集群搭建需要注意哪些问题?

    149.rabbitmq 每个节点是其他节点的完整拷贝吗?为什么?

    150.rabbitmq 集群中唯一一个磁盘节点崩溃了会发生什么情况?

    151.rabbitmq 对集群节点停止顺序有要求吗?

    十五、Kafka

    152.kafka 可以脱离 zookeeper 单独使用吗?为什么?

    153.kafka 有几种数据保留的策略?

    154.kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如何处理?

    155.什么情况会导致 kafka 运行变慢?

    156.使用 kafka 集群需要注意什么?

    十六、Zookeeper

    157.zookeeper 是什么?

    158.zookeeper 都有哪些功能?

    159.zookeeper 有几种部署模式?

    160.zookeeper 怎么保证主从节点的状态同步?

    161.集群中为什么要有主节点?

    162.集群中有 3 台服务器,其中一个节点宕机,这个时候 zookeeper 还可以使用吗?

    163.说一下 zookeeper 的通知机制?

    十七、MySql

    164.数据库的三范式是什么?

    165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

    166.如何获取当前数据库版本?

    167.说一下 ACID 是什么?

    168.char 和 varchar 的区别是什么?

    169.float 和 double 的区别是什么?

    170.mysql 的内连接、左连接、右连接有什么区别?

    171.mysql 索引是怎么实现的?

    172.怎么验证 mysql 的索引是否满足需求?

    173.说一下数据库的事务隔离?

    174.说一下 mysql 常用的引擎?

    175.说一下 mysql 的行锁和表锁?

    176.说一下乐观锁和悲观锁?

    177.mysql 问题排查都有哪些手段?

    178.如何做 mysql 的性能优化?

    十八、Redis

    179.redis 是什么?都有哪些使用场景?

    180.redis 有哪些功能?

    181.redis 和 memecache 有什么区别?

    182.redis 为什么是单线程的?

    183.什么是缓存穿透?怎么解决?

    184.redis 支持的数据类型有哪些?

    185.redis 支持的 java 客户端都有哪些?

    186.jedis 和 redisson 有哪些区别?

    187.怎么保证缓存和数据库数据的一致性?

    188.redis 持久化有几种方式?

    189.redis 怎么实现分布式锁?

    190.redis 分布式锁有什么缺陷?

    191.redis 如何做内存优化?

    192.redis 淘汰策略有哪些?

    193.redis 常见的性能问题有哪些?该如何解决?

    十九、JVM

    194.说一下 jvm 的主要组成部分?及其作用?

    195.说一下 jvm 运行时数据区?

    196.说一下堆栈的区别?

    197.队列和栈是什么?有什么区别?

    198.什么是双亲委派模型?

    199.说一下类加载的执行过程?

    200.怎么判断对象是否可以被回收?

    201.java 中都有哪些引用类型?

    202.说一下 jvm 有哪些垃圾回收算法?

    203.说一下 jvm 有哪些垃圾回收器?

    204.详细介绍一下 CMS 垃圾回收器?

    205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

    206.简述分代垃圾回收器是怎么工作的?

    207.说一下 jvm 调优的工具?

    208.常用的 jvm 调优的参数都有哪些?

    2、面试题答案汇总

    (一)基础模块

    (二)容器

    (三)多线程

    (四)反射

    (五)对象拷贝

    (六)JavaWeb

    (七)异常

    (八)网络

    (九)设计模式

    (十)Spring/SpringMVC

    (十一)Spring Boot / Spring Cloud

    (十二)Hibernate

    (十三)Mybatis

    (十四)RabbitMQ

    (十五)Kafka

    (十六)Zookeeper

    (十七)MySql

    (十八)Redis

    (十九)JVM

    展开全文
  • Mybatis常见面试题总结

    万次阅读 多人点赞 2018-07-09 21:29:01
    12、Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签? 、、、、,加上动态sql的9个标签 trim | where | set | foreach | if | choose | when | otherwise | bind 等,其中 为sql片段...
  • 消息队列面试题5

    2019-01-31 15:48:02
    消息队列面试题5   1、面试题   如何保证消息的顺序性?   2、面试官心里分析   其实这个也是用MQ的时候必问的话题,第一看看你了解不了解顺序这个事儿?第二看看你有没有办法保证消息是有顺序的?这...
  • 消息队列面试题

    2020-06-21 12:57:01
    面试题列表 1.为什么要用消息队列? (消息队列的应用场景?) 2.各种消息队列产品的比较? 3.消息队列的优点和缺点? 4.如何保证消息队列的高可用? 5.如何保证消息不丢失? 6.如何保证消息不被重复消费?(如何保证消息消费...
  • 消息队列面试题及答案

    万次阅读 多人点赞 2019-11-27 15:48:36
    1、为什么使用消息队列消息队列使用的场景和中间件有很多,但解决的核心问题主要是:异步、解耦、消峰填谷。 2、消息队列的优缺点 异步、解耦、消峰填谷...而且复杂性明显提高了,需要考虑一些消息队列常见...
  • 栈和队列常见面试题-栈实现队列-队列实现栈 1) 用栈结构实现队列结构2) 如何用队列结构实现栈结构 ) 1) 用栈结构实现队列结构 解析: 用两个栈:push栈,pop栈 push栈:存储数据 pop  栈:只要本栈数据不为...
  • SpringMVC常见面试题总结(超详细回答)

    万次阅读 多人点赞 2018-07-08 22:51:43
    相关阅读: SpringMVC常见面试题总结 Spring常见面试题总结 Mybatis常见面试题总结 MySQL常见面试题总结 RabbitMQ消息队列常见面试题总结 ElasticSearch搜索引擎常见面试题总结 计算机网络常见面试题总结 操作系统...
  • Spring常见面试题总结(超详细回答)

    万次阅读 多人点赞 2018-07-08 15:36:08
    1、Spring是什么? Spring是一个轻量级的IoC和...常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。 主要由以下几个模块组成: Spring Core:核心类库,提供IOC服务; Spring Context:提...
  • 1.实现猫狗队列#include #include<queue>//宠物类 class Pet { public: Pet(string type) :_type(type) {} string GetPetType() { return _type; } private: string _type; };
  • 栈和队列常见面试题

    千次阅读 2017-05-04 14:06:43
    1、两个队列实现一个栈 两个队列实现一个栈2、两个栈实现一个队列 【算法思想】 1>设计类 成员变量:给两个栈s1和s2来模拟实现一个队列 成员函数:入队Push()和出队Pop() 2>给两个指向栈对象s1、s2的指针input...
  • 一些常见消息队列面试题整理

    千次阅读 2019-03-29 10:24:52
    你们公司生产环境用的是什么消息中间件? RabbitMQ、ActiveMQ、RocketMQ、Kafka优缺点与应用场景 为什么在你们系统架构中要引入消息中间件? 系统解耦、异步调用、流量削峰 说说系统架构引入消息中间件有什么...
  • 栈和队列常见面试题-返回栈最小元素 题目:标题实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能**2 ) 设计的栈类型可以使用现成的栈结构1 ) pop、push、getMin操作的时间复杂度都是O(1)**1. ...
  • 消息队列MQ-面试题

    千次阅读 2019-09-18 10:53:15
    目录 1.什么是消息队列?...6.常见消息中间件比较 7.如何保证消息队列是高可用的? RocketMQ kafka 8.如何保证消息不被重复消费(幂等性) 9.如何保证生产者的发送消息的可靠性? RabbitMQ 1...
  • 2020最新Java常见面试题及答案

    万次阅读 多人点赞 2019-10-26 15:53:35
    Java最新常见面试题 + 答案汇总 1、面试题模块汇总 面试题包括以下十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、...
  • 1. 面试题 2. 面试官心理分析 3. 面试题剖析 3.1. 为什么使用消息队列 3.2. 消息队列有什么优缺点 3.3. Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点? 1. 面试题 为什么使用消息队列消息队列有...
  • Kafka常见面试题

    万次阅读 多人点赞 2019-05-19 19:58:39
    1 什么是kafka Kafka是分布式发布-订阅...2 为什么要使用 kafka,为什么要使用消息队列 缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有足够多的机器来保证冗余,kafka在中间可以起到一个缓...
  • 面试题消息队列面试连环炮

    万次阅读 2019-11-02 23:15:58
    目录:你使用过消息中间件吗?你们为什么使用消息中间件?消息队列有什么好处?什么场景下使用的?用来干了个什么的事情?系统中引入消息队列之后会不会有什么坏处?你们使用哪一个消息中间件?为什么...
  • 消息队列面试常见问题大综合

    千次阅读 2020-02-09 17:17:02
    面试官心理分析面试题剖析为什么使用消息队列解耦异步削峰消息队列有什么优缺点Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?二、如何保证消息队列的高可用?面试官心理分析面试题剖析RabbitMQ 的高可用性...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,914
精华内容 16,365
关键字:

消息队列常见面试题