精华内容
下载资源
问答
  • Java笔试面试-消息队列面试题总结

    万次阅读 多人点赞 2019-09-26 15:10:12
    1.消息队列的应用场景有哪些? 答:消息队列的应用场景如下。 应用解耦,比如,用户下单后,订单系统需要通知库存系统,假如库存系统无法访问,则订单减库存将失败,从而导致订单失败。订单系统与库存系统耦合,这...

    1.消息队列的应用场景有哪些?

    答:消息队列的应用场景如下。

    • 应用解耦,比如,用户下单后,订单系统需要通知库存系统,假如库存系统无法访问,则订单减库存将失败,从而导致订单失败。订单系统与库存系统耦合,这个时候如果使用消息队列,可以返回给用户成功,先把消息持久化,等库存系统恢复后,就可以正常消费减去库存了。
    • 削峰填谷,比如,秒杀活动,一般会因为流量过大,从而导致流量暴增,应用挂掉,这个时候加上消息队列,服务器接收到用户的请求后,首先写入消息队列,假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。
    • 日志系统,比如,客户端负责将日志采集,然后定时写入消息队列,消息队列再统一将日志数据存储和转发。

    2.RabbitMQ 有哪些优点?

    答:RabbitMQ 的优点如下:

    • 可靠性,RabbitMQ 的持久化支持,保证了消息的稳定性;
    • 高并发,RabbitMQ 使用了 Erlang 开发语言,Erlang 是为电话交换机开发的语言,天生自带高并发光环和高可用特性;
    • 集群部署简单,正是因为 Erlang 使得 RabbitMQ 集群部署变的非常简单;
    • 社区活跃度高,因为 RabbitMQ 应用比较广泛,所以社区的活跃度也很高;
    • 解决问题成本低,因为资料比较多,所以解决问题的成本也很低;
    • 支持多种语言,主流的编程语言都支持,如 Java、.NET、PHP、Python、JavaScript、Ruby、Go 等;
    • 插件多方便使用,如网页控制台消息管理插件、消息延迟插件等。

    3.RabbitMQ 有哪些重要的角色?

    答:RabbitMQ 包含以下三个重要的角色:

    • 生产者:消息的创建者,负责创建和推送数据到消息服务器;
    • 消费者:消息的接收方,用于处理数据和确认消息;
    • 代理:就是 RabbitMQ 本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色。

    4.RabbitMQ 有哪些重要的组件?它们有什么作用?

    答:RabbitMQ 包含的重要组件有:ConnectionFactory(连接管理器)、Channel(信道)、Exchange(交换器)、Queue(队列)、RoutingKey(路由键)、BindingKey(绑定键) 等重要的组件,它们的作用如下:

    • ConnectionFactory(连接管理器):应用程序与 RabbitMQ 之间建立连接的管理器,程序代码中使用;
    • Channel(信道):消息推送使用的通道;
    • Exchange(交换器):用于接受、分配消息;
    • Queue(队列):用于存储生产者的消息;
    • RoutingKey(路由键):用于把生成者的数据分配到交换器上;
    • BindingKey(绑定键):用于把交换器的消息绑定到队列上。

    运行流程,如下图所示:
    在这里插入图片描述

    5.什么是消息持久化?

    答:消息持久化是把消息保存到物理介质上,以防止消息的丢失。

    6.RabbitMQ 要实现消息持久化,需要满足哪些条件?

    答:RabbitMQ 要实现消息持久化,必须满足以下 4 个条件:

    • 投递消息的时候 durable 设置为 true,消息持久化,代码:channel.queueDeclare(x, true, false, false, null),参数 2 设置为 true 持久化;
    • 设置投递模式 deliveryMode 设置为 2(持久),代码:channel.basicPublish(x, x, MessageProperties.PERSISTENTTEXTPLAIN,x),参数 3 设置为存储纯文本到磁盘;
    • 消息已经到达持久化交换器上;
    • 消息已经到达持久化的队列。

    7.消息持久化有哪些缺点?如何缓解?

    答:消息持久化的缺点是很消耗性能,因为要写入硬盘要比写入内存性能较低很多,从而降低了服务器的吞吐量。可使用固态硬盘来提高读写速度,以达到缓解消息持久化的缺点。

    8.如何使用 Java 代码连接 RabbitMQ?

    答:使用 Java 代码连接 RabbitMQ 有以下两种方式:

    方式一:

    public static Connection GetRabbitConnection() {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername(Config.UserName);
        factory.setPassword(Config.Password);
        factory.setVirtualHost(Config.VHost);
        factory.setHost(Config.Host);
        factory.setPort(Config.Port);
        Connection conn = null;
        try {
            conn = factory.newConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
    

    方式二:

    public static Connection GetRabbitConnection2() {
        ConnectionFactory factory = new ConnectionFactory();
        // 连接格式:amqp://userName:password@hostName:portNumber/virtualHost
        String uri = String.format("amqp://%s:%s@%s:%d%s", Config.UserName, Config.Password, Config.Host, Config.Port,
                Config.VHost);
        Connection conn = null;
        try {
            factory.setUri(uri);
            factory.setVirtualHost(Config.VHost);
            conn = factory.newConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
    

    9.使用 Java 代码编写一个 RabbitMQ 消费和生产的示例?

    答:代码如下:

    public static void main(String[] args) {
        publisher();     // 生产消息
        consumer();     // 消费消息
    }
    
    /**
     * 推送消息
     */
    public static void publisher() {
        // 创建一个连接
        Connection conn = ConnectionFactoryUtil.GetRabbitConnection();
        if (conn != null) {
            try {
                // 创建通道
                Channel channel = conn.createChannel();
                // 声明队列【参数说明:参数一:队列名称,参数二:是否持久化;参数三:是否独占模式;参数四:消费者断开连接时是否删除队列;参数五:消息其他参数】
                channel.queueDeclare(Config.QueueName, false, false, false, null);
                String content = String.format("当前时间:%s", new Date().getTime());
                // 发送内容【参数说明:参数一:交换机名称;参数二:队列名称,参数三:消息的其他属性-routing headers,此属性为MessageProperties.PERSISTENT_TEXT_PLAIN用于设置纯文本消息存储到硬盘;参数四:消息主体】
                channel.basicPublish("", Config.QueueName, null, content.getBytes("UTF-8"));
                System.out.println("已发送消息:" + content);
                // 关闭连接
                channel.close();
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 消费消息
     */
    public static void consumer() {
        // 创建一个连接
        Connection conn = ConnectionFactoryUtil.GetRabbitConnection();
        if (conn != null) {
            try {
                // 创建通道
                Channel channel = conn.createChannel();
                // 声明队列【参数说明:参数一:队列名称,参数二:是否持久化;参数三:是否独占模式;参数四:消费者断开连接时是否删除队列;参数五:消息其他参数】
                channel.queueDeclare(Config.QueueName, false, false, false, null);
    
                // 创建订阅器,并接受消息
                channel.basicConsume(Config.QueueName, false, "", new DefaultConsumer(channel) {
                    @Override
                    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                            byte[] body) throws IOException {
                        String routingKey = envelope.getRoutingKey(); // 队列名称
                        String contentType = properties.getContentType(); // 内容类型
                        String content = new String(body, "utf-8"); // 消息正文
                        System.out.println("消息正文:" + content);
                        channel.basicAck(envelope.getDeliveryTag(), false); // 手动确认消息【参数说明:参数一:该消息的index;参数二:是否批量应答,true批量确认小于index的消息】
                    }
                });
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    10.RabbitMQ 交换器类型有哪些?

    答:RabbitMQ 消费类型也就是交换器(Exchange)类型有以下四种:

    • direct:轮询方式
    • headers:轮询方式,允许使用 header 而非路由键匹配消息,性能差,几乎不用
    • fanout:广播方式,发送给所有订阅者
    • topic:匹配模式,允许使用正则表达式匹配消息

    RabbitMQ 默认的是 direct 方式。

    11.RabbitMQ 如何确保每个消息能被消费?

    答:RabbitMQ 使用 ack 消息确认的方式保证每个消息都能被消费,开发者可根据自己的实际业务,选择 channel.basicAck() 方法手动确认消息被消费。

    12.RabbitMQ 接收到消息之后必须消费吗?

    答:RabbitMQ 接收到消息之后可以不消费,在消息确认消费之前,可以做以下两件事:

    • 拒绝消息消费,使用 channel.basicReject(消息编号, true) 方法,消息会被分配给其他订阅者;
    • 设置为死信队列,死信队列是用于专门存放被拒绝的消息队列。

    13.topic 模式下发布了一个路由键为“com.mq.rabbit.error”的消息,请问以下不能接收到消息的是?

    A:cn.mq.rabbit.*
    B:#.error
    C:cn.mq.*
    D:cn.mq.#

    答:C

    题目解析:“*”用于匹配一个分段(用“.”分割)的内容,“#”用于匹配 0 和多个字符。

    14.以下可以获取历史消息的是?

    A:topic 交换器
    B:fanout 交换器
    C:direct 交换器
    D:以上都不是

    答:C

    题目解析:fanout 和 topic 都是广播形式的,因此无法获取历史消息,而 direct 可以。

    15.RabbitMQ 包含事务功能吗?如何使用?

    答:RabbitMQ 包含事务功能,主要是对信道(Channel)的设置,主要方法有以下三个:

    • channel.txSelect() 声明启动事务模式;
    • channel.txComment() 提交事务;
    • channel.txRollback() 回滚事务。

    16.RabbitMQ 的事务在什么情况下是无效的?

    答:RabbitMQ 的事务在 autoAck=true 也就是自动消费确认的时候,事务是无效的。因为如果是自动消费确认,RabbitMQ 会直接把消息从队列中移除,即使后面事务回滚也不能起到任何作用。

    17.Kafka 可以脱离 ZooKeeper 单独使用吗?

    答:Kafka 不能脱离 ZooKeeper 单独使用,因为 Kafka 使用 ZooKeeper 管理和协调 Kafka 的节点服务器。

    18.Kafka 有几种数据保留的策略?

    答:Kafka 有两种数据保存策略:按照过期时间保留和按照存储的消息大小保留。

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

    答:这个时候 Kafka 会执行数据清除工作,时间和大小不论哪个满足条件,都会清空数据。

    20.什么情况会导致 Kafka 运行变慢?

    答:以下情况可导致 Kafka 运行变慢:

    • CPU 性能瓶颈
    • 磁盘读写瓶颈
    • 网络瓶颈

    21.使用 Kafka 集群需要注意什么?

    答:Kafka 集群使用需要注意以下事项:

    • 集群的数量不是越多越好,最好不要超过 7 个,因为节点越多,消息复制需要的时间就越长,整个群组的吞吐量就越低;
    • 集群数量最好是单数,因为超过一半故障集群就不能用了,设置为单数容错率更高。
    展开全文
  • 消息队列面试题

    2019-09-07 16:14:12
  • 最新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

    展开全文
  • 消息队列面试题及答案

    万次阅读 多人点赞 2019-11-27 15:48:36
    1、为什么使用消息队列消息队列使用的场景和中间件有很多,但解决的核心问题主要是:异步、解耦、消峰填谷。 2、消息队列的优缺点 异步、解耦、消峰填谷这是消息队列最大的优点,除了这些消息队列还可以会解决...

    1、为什么使用消息队列?

    消息队列使用的场景和中间件有很多,但解决的核心问题主要是:异步、解耦、消峰填谷。

    2、消息队列的优缺点

    异步、解耦、消峰填谷这是消息队列最大的优点,除了这些消息队列还可以会解决一些我们特殊业务场景的问题。但是缺点主要在于系统的可用性、复杂性、一致性问题,引入消息队列后,需要考虑MQ的可用性,万一MQ崩溃了岂不是要爆炸?而且复杂性明显提高了,需要考虑一些消息队列的常见问题和解决方案,还有就是一致性问题,一条消息由多个消费者消费,万一有一个消费者消费失败了,就会导致数据不一致。

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

    由于笔者只使用和实践过RabbitMQ和Kafka,RocketMQ和ActiveMQ了解的不深,所以分析一下RabbitMQ和Kafka的高可用。

    (一)RabbitMQ

    RabbitMQ有三种模式:单机模式,普通集群模式,镜像集群模式

    (1)单机模式

    单机模式平常使用在开发或者本地测试场景,一般就是测试是不是能够正确的处理消息,生产上基本没人去用单机模式,风险很大。

    (2)普通集群模式

    普通集群模式就是启动多个RabbitMQ实例。在你创建的queue,只会放在一个rabbtimq实例上,但是每个实例都同步queue的元数据。在消费的时候完了,上如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。

    这种方式确实很麻烦,也不怎么好,没做到所谓的分布式,就是个普通集群。因为这导致你要么消费者每次随机连接一个实例然后拉取数据,要么固定连接那个queue所在实例消费数据,前者有数据拉取的开销,后者导致单实例性能瓶颈。

    而且如果那个放queue的实例宕机了,会导致接下来其他实例就无法从那个实例拉取,如果你开启了消息持久化,让RabbitMQ落地存储消息的话,消息不一定会丢,得等这个实例恢复了,然后才可以继续从这个queue拉取数据。

    这方案主要是提高吞吐量的,就是说让集群中多个节点来服务某个queue的读写操作。

    (3)镜像集群模式

    镜像集群模式是所谓的RabbitMQ的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。

    优点在于你任何一个实例宕机了,没事儿,别的实例都可以用。缺点在于性能开销太大和扩展性很低,同步所有实例,这会导致网络带宽和压力很重,而且扩展性很低,每增加一个实例都会去包含已有的queue的所有数据,并没有办法线性扩展queue。

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

    (二)Kafka

    Kafka天生就是一个分布式的消息队列,它可以由多个broker组成,每个broker是一个节点;你创建一个topic,这个topic可以划分为多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。

    kafka 0.8以前,是没有HA机制的,就是任何一个broker宕机了,那个broker上的partition就废了,没法写也没法读,没有什么高可用性可言。

    kafka 0.8以后,提供了HA机制,就是replica副本机制。kafka会均匀的将一个partition的所有replica分布在不同的机器上,来提高容错性。每个partition的数据都会同步到吉他机器上,形成自己的多个replica副本。然后所有replica会选举一个leader出来,那么生产和消费都去leader,其他replica就是follower,leader会同步数据给follower。当leader挂了会自动去找replica,然后会再选举一个leader出来,这样就具有高可用性了。

    写数据的时候,生产者就写leader,然后leader将数据落地写本地磁盘,接着其他follower自己主动从leader来pull数据。一旦所有follower同步好数据了,就会发送ack给leader,leader收到所有follower的ack之后,就会返回写成功的消息给生产者。(当然,这只是其中一种模式,还可以适当调整这个行为)

    消费的时候,只会从leader去读,但是只有一个消息已经被所有follower都同步成功返回ack的时候,这个消息才会被消费者读到。

    4、如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

    其实消息重复消费的主要原因在于回馈机制(RabbitMQ是ack,Kafka是offset),在某些场景中我们采用的回馈机制不同,原因也不同,例如消费者消费完消息后回复ack, 但是刚消费完还没来得及提交系统就重启了,这时候上来就pull消息的时候由于没有提交ack或者offset,消费的还是上条消息。

    那么如何怎么来保证消息消费的幂等性呢?实际上我们只要保证多条相同的数据过来的时候只处理一条或者说多条处理和处理一条造成的结果相同即可,但是具体怎么做要根据业务需求来定,例如入库消息,先查一下消息是否已经入库啊或者说搞个唯一约束啊什么的,还有一些是天生保证幂等性就根本不用去管,例如redis就是天然幂等性。

    还有一个问题,消费者消费消息的时候在某些场景下要放过消费不了的消息,遇到消费不了的消息通过日志记录一下或者搞个什么措施以后再来处理,但是一定要放过消息,因为在某些场景下例如spring-rabbitmq的默认回馈策略是出现异常就没有提交ack,导致了一直在重发那条消费异常的消息,而且一直还消费不了,这就尴尬了,后果你会懂的。

    5、如何保证消息的可靠性传输?或者说,如何处理消息丢失的问题?

    参考:https://www.jianshu.com/p/06e7e3b34dd6

    6、如何保证消息的顺序性?

    因为在某些情况下我们扔进MQ中的消息是要严格保证顺序的,尤其涉及到订单什么的业务需求,消费的时候也是要严格保证顺序,不然会出大问题的。

    先看看顺序会错乱的两个场景:

    • rabbitmq:一个queue,多个consumer,这不明显乱了
    • kafka:一个topic,一个partition,一个consumer,内部多线程,这不也明显乱了
       

    7、如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时怎么解决?

    (一)、大量消息在mq里积压了几个小时了还没解决

    几千万条数据在MQ里积压了七八个小时,从下午4点多,积压到了晚上很晚,10点多,11点多
    这个是我们真实遇到过的一个场景,确实是线上故障了,这个时候要不然就是修复consumer的问题,让他恢复消费速度,然后傻傻的等待几个小时消费完毕。这个肯定不能在面试的时候说吧。

    一个消费者一秒是1000条,一秒3个消费者是3000条,一分钟是18万条,1000多万条,所以如果你积压了几百万到上千万的数据,即使消费者恢复了,也需要大概1小时的时间才能恢复过来。

    一般这个时候,只能操作临时紧急扩容了,具体操作步骤和思路如下:

    1. 先修复consumer的问题,确保其恢复消费速度,然后将现有cnosumer都停掉。
    2. 新建一个topic,partition是原来的10倍,临时建立好原先10倍或者20倍的queue数量。
    3. 然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue。
    4. 接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据。
    5. 这种做法相当于是临时将queue资源和consumer资源扩大10倍,以正常的10倍速度来消费数据。
    6. 等快速消费完积压数据之后,得恢复原先部署架构,重新用原先的consumer机器来消费消息。

    (二)、消息队列过期失效问题

    假设你用的是rabbitmq,rabbitmq是可以设置过期时间的,就是TTL,如果消息在queue中积压超过一定的时间就会被rabbitmq给清理掉,这个数据就没了。那这就是第二个坑了。这就不是说数据会大量积压在mq里,而是大量的数据会直接搞丢。

    这个情况下,就不是说要增加consumer消费积压的消息,因为实际上没啥积压,而是丢了大量的消息。我们可以采取一个方案,就是批量重导,这个我们之前线上也有类似的场景干过。就是大量积压的时候,我们当时就直接丢弃数据了,然后等过了高峰期以后,比如大家一起喝咖啡熬夜到晚上12点以后,用户都睡觉了。

    这个时候我们就开始写程序,将丢失的那批数据,写个临时程序,一点一点的查出来,然后重新灌入mq里面去,把白天丢的数据给他补回来。也只能是这样了。

    假设1万个订单积压在mq里面,没有处理,其中1000个订单都丢了,你只能手动写程序把那1000个订单给查出来,手动发到mq里去再补一次。

    (三)、消息队列满了怎么搞?

    如果走的方式是消息积压在mq里,那么如果你很长时间都没处理掉,此时导致mq都快写满了,咋办?这个还有别的办法吗?没有,谁让你第一个方案执行的太慢了,你临时写程序,接入数据来消费,消费一个丢弃一个,都不要了,快速消费掉所有的消息。然后走第二个方案,到了晚上再补数据吧。

    9、RabbitMQ 有哪些重要的角色?

    10、RabbitMQ 有哪些重要的组件?

    11、RabbitMQ 有几种广播类型?

    三种广播模式:

    1. fanout: 所有bind到此exchange的queue都可以接收消息(纯广播,绑定到RabbitMQ的接受者都能收到消息);
    2. direct: 通过routingKey和exchange决定的那个唯一的queue可以接收消息;
    3. topic:  所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息;

    12、Kafka 可以脱离 zookeeper 单独使用吗?为什么?

    kafka 不能脱离 zookeeper 单独使用,因为 kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。

    13、Kafka 有几种数据保留的策略?

    kafka 有两种数据保存策略:

    1. 按照过期时间保留
    2. 按照存储的消息大小保留

    14、Kafka 的分区策略有哪些?

    1. 给定了分区号,直接将数据发送到指定的分区里面去
    2. 没有给定分区号,给定数据的key值,通过key取上hashCode进行分区
    3. 既没有给定分区号,也没有给定key值,直接轮循进行分区
    4. 自定义分区

    我有一个微信公众号,经常会分享一些Java技术相关的干货;如果你喜欢我的分享,可以用微信搜索“Java团长”或者“javatuanzhang”关注。

    展开全文
  • Java 基础高频面试题(2021年最新版)

    万次阅读 多人点赞 2021-03-31 23:39:26
    最新 Java 基础高频面试题
  • Java集合容器面试题(2020最新版)

    万次阅读 多人点赞 2020-03-01 11:08:34
    文章目录集合容器概述什么是集合集合的特点集合和数组的区别使用集合框架的好处常用的集合类有哪些?List,Set,Map三者的区别?...Java集合的快速失败机制 “fail-fast”?怎么确保一个集合不能被修改?Collection...
  • Java消息队列三道面试题详解

    千次阅读 2019-02-18 21:08:00
    文章地址:https://studygolang.com/topics/8246#reply0
  • Java面试题大全(2020版)

    万次阅读 多人点赞 2019-11-26 11:59:06
    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java ...
  • RabbitMQ消息队列常见面试题总结

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

    万次阅读 多人点赞 2019-10-15 18:58:32
    史上最全的java工程师面试题汇总,纯个人总结,精准无误。适合中高级JAVA工程师。
  • Java面试题 MQ消息队列

    千次阅读 2019-07-17 22:09:13
    七:MQ消息队列 1:介绍 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已。其主要用途:不同进程Process/线程Thread之间通信。 2:为什么会...
  • 史上最全面Java面试汇总(面试题+答案)

    万次阅读 多人点赞 2018-07-06 14:09:25
    JAVA面试精选【Java基础第一部分】 JAVA面试精选【Java基础第二部分】 JAVA面试精选【Java基础第三部分】 JAVA面试精选【Java算法与编程一】 JAVA面试精选【Java算法与编程二】 ...Java中高级面试题 数据...
  • Java面试题大全(2021版)

    万次阅读 多人点赞 2020-11-25 11:55:31
    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java基础知识面试题 1、Java概述 ①. 何为编程 ...
  • JAVA消息中间件面试题

    千次阅读 2020-04-17 23:45:57
    前言 文章开始前,我们先了解一下什么是消息中间件? 什么是中间件? 非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的,不能直接给客户带来价值的软件统称为中间件...接下来就是消息中间件面试题...
  • 面试题消息队列面试连环炮

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

    万次阅读 多人点赞 2019-07-10 17:41:50
    这份面试清单是从我 2015 年做了 TeamLeader 之后开始收集的,一方面是给公司招聘用,另一方面是想用它来挖掘在 Java 技术栈中,还有那些知识点是我不知道的,我想找到这些技术盲点,然后修复它,以此来提高自己的...
  • 1. 面试题 2. 面试官心理分析 3. 面试题剖析 3.1. 为什么使用消息队列 3.2. 消息队列有什么优缺点 3.3. Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点? 1. 面试题 为什么使用消息队列消息队列有...
  • 1 面试题 如何保证消息的顺序性? 2 考点分析 MQ必问话题 考察你是否了解顺序性 考察你是否有办法保证消息的顺序性,因为这是生产系统中常见的一个问题. 3 详解 3.0 案例 一个MySQL binlog同步系统,日同步数据达到...
  • 2020最新Java常见面试题及答案

    万次阅读 多人点赞 2019-10-26 15:53:35
    Java最新常见面试题 + 答案汇总 1、面试题模块汇总 面试题包括以下十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、...
  • 客户端是通过列队的pop来获取消息,然后进行处理,处理完再接着获取消息。如此循环。这就是客户端的生命周期。 问题一:队列空了会有什么影响 如果队列空了,客户端会一直pop队列,这就造成了空轮询。空轮询不但提高...
  • Java综合中级面试题

    万次阅读 多人点赞 2019-06-24 22:13:13
    大公司最喜欢问的Java集合类面试题40个Java集合面试问题和答案 java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。 java.util.Collection 是一个集合接口。它提供了对集合对象进行基本...
  • java并发编程面试题

    万次阅读 2020-09-28 23:25:46
    4、JVM对Java的原生锁做了哪些优化?5、为什么说Synchronized是非公平锁?6、什么是锁消除和锁粗化?7、为什么说Synchronized是一个悲观锁?乐观锁的实现原理又是什么?什么是CAS,它有什么特性?8、乐观锁一定就是好...
  • 消息队列面试 - 为什么使用消息队列,消息队列有什么优点和缺点? 面试题 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景? 面试官...
  • Java面试消息队列

    2020-02-27 10:54:25
    消息队列面试题 题目来自于中华石杉,解决方案根据自己的思路来总结而得。题目主要如下:![3duWCT.png](https://imgchr.com/i/3duWCT) 1. 为什么要引入消息队列? 消息队列的引入可以解决3个核心问题: 解耦 异步 削...
  • Java底层知识面试题

    千次阅读 2020-04-21 23:12:46
    面试题 Java集合框架 面试题 Java并发编程 面试题 Redis 面试题 文章目录JVM内存结构class文件格式运行时数据区:堆、栈、方法区、直接内存、运行时常量池堆和栈区别Java中的对象一定在堆上分配吗?Java内存...
  • 1 面试题  写一个消息队列,你如何进行架构设计,说一下你的思路!  2 考点分析  一般面试官要考察两块:  (1)你有没有对某一个消息队列做过较为深入的原理的了解,或者从整体了解把握住一个mq的架构原理  ...
  • 栈和队列面试题Java

    千次阅读 多人点赞 2019-09-26 14:15:59
    两个队列实现一个栈 使用两个队列完成栈的功能, 思路: 如上图,入队顺序为:1 2 3 4 5,如果要模拟栈的功能,那么就要上5先弹出来,因为是队列,所以只能从1开始出,把1 2 3 4存到另外一个队列中,这样就可以把5弹...
  • 面试题剖析 为什么使用消息队列 先说一下消息队列常见的使用场景吧,其实场景有很多,但是比较核心的有 3 个:解耦、异步、削峰。 解耦 看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E ...
  • 消息中间件MQ与RabbitMQ面试题(2020最新版)

    万次阅读 多人点赞 2020-03-01 11:11:21
    MQ的优点消息队列有什么优缺点?RabbitMQ有什么优缺点?你们公司生产环境用的是什么消息中间件?Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?MQ 有哪些常见问题?如何解决这些问题?什么是RabbitMQ?...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 63,370
精华内容 25,348
关键字:

java消息队列面试题

java 订阅