JAVA面试题18

181.activeMQ 消息队列阻塞

1、这个问题还真没处理过,我的大概思路是,将消息确认机制有自动确认改为手动确认,每次消息消费成功后,需要通过 api 方法,手动发送 ACK 确认信息;

2、同时每个消息发送前,都在数据库中进行备份,当消息由消息消费者确认消费成功后,才更改状态;

3、并每隔一段时间对消息队列的消息进行扫描,因为消息具有时效性,如果一条消息发送后 5 秒还没有反馈,这是查看队列未被消费消息的数量,如果过多,则进行队列消息清空;

4、然后从数据库中,将消息未过期(规则自己定,比如 10 分钟内有效)的消息重新发送一遍;

182.消息的不均匀消费

有时在发送一些消息之后,开启 2 个消费者去处理消息。会发现一个消费者处理了所有的消息,另一个消费者根本 没收到消息。原因在于 ActiveMQ 的 prefetch 机制。当消费者去获取消息时,不会一条一条去获取,而是一次性获 取一批,默认是 1000 条。可以将 prefetch 设为 1,每次处理 1 条消息,处理完再去取,这样也慢不了多少。 

 

183.activeMQ 消息丢失

当网络发送方发送一堆数据,然后调用 close 关闭连接之后。这些发送的数据都在接收者的缓存里,接收者如果调用 read 方法仍旧能从缓存中读取这些数据,尽管对方已经关闭了连接。但是当接收者尝试发送数据时,由于此时连接已关闭,所以会发生异常。当发生 SocketException 后,原本缓存区中数据也作废了,此时接收者再次调用 read 方法去读取缓存中的数据,就会报 Software caused connection abort: recv failed 错误数据丢失。 

解决方案:用持久化消息,或者非持久化消息及时处理不要堆积,或者启动事务,启动事务后,commit()方法会负责任的等待服务器的返回,也就不会关闭连接导致消息丢失了。

补充:消息发送前先存入到 mysql 或者 redis 进行持久化保存,并标明消息的过期时间(消息具有时效性),通过定时器(springTask 或者 quartz)定时扫描数据库表的数据,如果消息消费成功则会通过 ACK 确认消息消费结果,broker 可以从队列中将消息移除,但是超时客户端没有 ACK 确认,则认为消息丢失,重新发送消息,直到收到消费成功的 ACK 确认消息。

RabbitMQ自己找一些资料背一背

184. RabbitMQ 有哪些重要的组件

ConnectionFactory(连接管理器):应用程序与 Rabbit 之间建立连接的管理器,程序代码中使用。

Channel(信道):消息推送使用的通道。

Exchange(交换器):用于接受、分配消息。

Queue(队列):用于存储生产者的消息。

RoutingKey(路由键):用于把生成者的数据分配到交换器上。

BindingKey(绑定键):用于把交换器的消息绑定到队列上。

185. RabbitMQ 的消息是怎么发送的

首先客户端必须连接到 RabbitMQ 服务器才能发布和消费消息,客户端和 rabbit server 之间会创建一个 tcp 连 接,一旦 tcp 打开并通过了认证(认证就是你发送给 rabbit 服务器的用户名和密码),你的客户端和 RabbitMQ 就创建了一条 amqp 信道(channel),信道是创建在“真实” tcp 上的虚拟连接,amqp 命令都是通过信道发送 出去的,每个信道都会有一个唯一的 id,不论是发布消息,订阅队列都是通过这个信道完成的。

186. RBAC 权限管理

我负责系统管理模块,系统管理主要是对用户角色和权限的管理,通过 RBAC 实现。

RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系。 不同角色的人登录应该看到不同的权限和内容,权限通常有 3,5,7 张表甚至更多来完成,我们当时用了五张,包括 员工信息表、角色信息表、权限信息表和两张中间关系表:一张员工角色关系表,一张角色权限关系表。

1、可以对用户赋角色,然后角色赋权限,权限表里存着不同的权限的 url,

2、当用户登录时,从 session 中获取用户 id,通过用户 id 获取用户的所有角色 id,再通过角色 id 获取所有权限 url。

3、把当前用户的权限信息用以树形结构展示,就实现了不同的人登录展示不同的权限树。

4、当然,在这里可能有一些安全问题,就是用户直接在浏览器输入非法权限的 url 执行非法操作的问题,我们采 用 filter 拦截器在用户执行操作时先判断该用户有无该权限的 url,在有权限的情况下才放行,否则提示非法操 作,并且终止该操作。

187. spring Security 介绍

一个能够为基于Spring的企业应用系统提供声明式的安全訪问控制解决方式的安全框架(简单说是对访问权限进行控制嘛),应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。 spring security的主要核心功能为 认证和授权,所有的架构也是基于这两个核心功能去实现的。

188.  spring Security 执行过程

spring security 主要做认证和授权两部分工作。

在我们配置好认证需要的UsernameService(从数据库中获取用户 ) 和 AuthenticationProvider(主要做认证工作) 之后,在用户登陆时,我们会拦截到其http请求,得到用户名和密码然后创建未认证的token 去 认证管理器认证,它会选择我们定义的AuthenticationProvider去进行认证工作,从而返回结果。如果成功则 调用成功处理器 AuthenticationSuccessHandler,失败则调用失败处理器。认证成功之后其认证信息就被框架记录下来,在之后的访问中就需要对其鉴权。

授权权时候 首先得到对应URL 的角色信息,然后调用decisionMannager 来进行鉴权,我们现在有该url需要的角色信息,有框架缓存的认证信息 该认证信息里面有其角色信息,那么只需要一比对,如果认证信息的角色 在 需要的角色里面 则权限验证通过,否则权限验证失败,调用AccessDeniedHandler 进行处理。

 189. 什么是单点登录

单点登录的,官方解释为(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

我们目前的系统存在诸多子系统,而这些子系统是分别部署在不同的服务器中,那么使用传统方式的 session 是无法解决的,我们需要使用相关的单点登录技术来解决【共享 session】。

单点登录的解决方案有很多:

1、拦截器+token+redis 可以每个模块生成 token,将 token 和用户信息存入 redis,然后以一级域名作为 cookie 的域,这样不论访问哪个子系统,都会携带 cookie,每次请求模块中的拦截器获取 cookie 中的 token,进而从 redis 中根据 token 获取对应的用户信息,token 不存在或者用户信息不存在,测跳转到统一的登录页面。

2、CAS,开源的单点登录框架,服务单独部署,有服务端和客户端,每个模块集成配置后都是 CAS Client,所有 的请求都统一重定向至 CAS Server,由 CAS 验证用户名和密码是否合法,如果合法,则 cookie 中发放 ticket,访问其他子系统时,携带 ticket,子系统直接将请求重定向到 CAS Server,如果校验通过,则放行,否则跳转至 CAS的登录页面。

190. 什么是 CAS

CAS 是 耶鲁大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,是比较成熟的单点登录的解决方案 

更多面试题,请打开主页分栏 java面试 进行查看,谢谢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值