不知道写些什么就想着把这段时间网上看到的一些面试题写下来,供各个找工作的人参考
简述一下RabbitMQ的工作模式
-
simple模式(即最简单的收发模式)
- 消息产生消息,将消息放入队列
- 消息的消费者(
consumer
)监听:消息队列,如果队列中有消息,就消费掉。消息被拿走后,自动从队列中删除。 - (当然这个存在隐患:消息可能没有被消费者正确处理,可能因为程序的报错,或者是网路的不稳定,造成消息的丢失,这里就可以设置成手动的ack,但如果设置成手动的ACK,处理完后要及时发送ACK消息给队列,否则会造成内存溢出)
-
wok工作模式(资源的竞争)
- 消息产生者将消息放入队列,消费者可以有多个。
- 消费者A和消费者B同时监听同一个队列,当消费时两位鱼皮共同争抢当前的消息队列内容,谁先拿到谁负责消费
- (隐患:高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关
synchronize
保证一条消息只能被一个消费者使用)
-
publish/subscribe发布订阅(共享资源)
- 每个消费者监听自己的队列
- 生产者将消息发给broker,由交换机将消息转发到绑定此比交换机的每个队列,每个绑定交换机的队列都将接收到消息
- 一般也叫广播模式
-
routing路由模式
- 消费生产者将消息发送给交换机按照路由判断,路由是字符串当前产生的消息携带的路由字符(对象的方法),交换机根据路由的key,只能匹配上路由key对应的消息队列。这样对应的消费者才能消费消息。
- 根据业务功能定义路由字符串。
- 从系统的代码逻辑中获取对应的功能字符串,将消息任务扔到对应的队列中。
-
主题模式
- 主题模式跟路由模式类似,只不过路由模式是指定固定的路由key,而主题模式是可以模糊匹配路由键,类似于SQL中=和like的关系。
- 举例:如果此时有两个队列, Q1绑定.orange.,Q2绑定两个路由key,分别是.rabbit以及lazy.#
- 那生产者发送.orange.1的话只有Q1可以收到,发送.rabbit.1的的话只有Q2可以收到,发送.orange.rabbit的话,Q1和Q2都可以收到
-
rpc模式
- rpc模式是一种远程调用的模式,需要http请求,因此速度比系统内部调用慢
- 生产者开始生产消息后,创建了匿名的、独一无二的回调队列
- 生产者发送请求时,包含两个属性:reply_to,即回调队列;correlation_id,即用于标记请求的属性
- 请求被发送到rpc_queue队列
- 消费者等待请求,收到时,其处理生产者发送的特定的reply_to的消息
- 生产者等待消息的ack回复,当收到回复后,其校验correlation_id,如果正确则回到应用程序中
下面是网上找的各个工作模式的照片,可以对应看一下
守护线程和用户线程有什么区别
- 用户线程:运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程
- 守护线程:运行在后台,为其他前台线程服务。也可以说守护线程是JVM中非守护线程的佣人,一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作:
- main函数所在的线程就是一个用户线程
- main函数启动的同时在JVM内部同时还启动了好多守护线程,比如垃圾回收线程。比较明显的区别之一是用户线程结束,JVM退出,不管这个时候有没有守护线程运行。而守护线程不会影响JVM的退出。
什么是上下文切换
- 多线程编程中一般线程的个数都大于CPU核心的个数,而一个CPU核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU采取的策略是为每个线程分配时间片轮询的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。
- 用大白话来说:当前的任务在执行完CPU时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。
- 使用Linux当做服务器的有点有一点就是因为它切换上下文和模式切换所需要的时间很短