java基础面试题
Posted lgcgkCQ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基础面试题相关的知识,希望对你有一定的参考价值。
RabbitMQ
1.什么是MQ?为什么使用MQ?MQ的优点
MQ:消息队列;是在消息传输过程中保存消息的容器。
主要是:
解耦:系统间通过消息通信,不用关心其他系统的处理
异步:多个系统写库时,不需同步执行,可以减少响应时间
削峰:减少高峰时期对服务器压力
2.MQ 有哪些常见问题?如何解决这些问题?
1.消息的顺序性问题(可以按照消息的发送顺序来消费)
解决:保证生产者 - MQServer - 消费者是一对一对一的关系
2.消息的重复问题(根本原因是:网络不可达)
解决:消费端处理消息的业务逻辑保持幂等性;利用一张日志表来记录已经处理成功的消息的 ID,如 果新到的消息 ID 已经在日志表中,那么就不再处理这条消息
3.什么是RabbitMQ?使用场景
RabbitMQ是一款开源的,Erlang编写的,基于AMQP协议的消息中间件;
使用场景:定时任务、服务间异步通信、顺序消费、请求削峰
4.RabbitMQ有什么优缺点?
优点:
1.应用解耦(MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合)
2.任务异步处理(将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间)
3.削峰填谷(数据量大时,数据库来不及处理,存入mq中保存,根据消费能力来进行处理)
缺点:
1.系统可用性降低(系统引入的外部依赖越多,系统稳定性越差)
2.系统复杂度提高(大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用)
3.一致性问题(如何保证消息数据处理的一致性)
5.RabbitMQ的工作模式
1.收发模式:产生消息,将消息放入队列,消费者监听 消息队列,如果队列中有消息,就消费掉
2.work模式:产生消息,将消息放入队列,多个消费者同时监听,谁先拿到谁消费
3.发布/订阅模式:消息被路由投递给多个队列,一个消息被多个消费者获取
4.路由模式:消息生产者将消息发送给交换机按照路由判断,交换机根据路由的 key, 只能匹配上路由 key 对应的消息队列,对应的消费者才能消费消息
5.主题模式:消息产生者产生消息,把消息交给交换机,交换机根据key的规则模糊匹配到对应的队列,由队列的监听消费者接收消息消 费
6.如何保证RabbitMQ消息的顺序性?
1.拆分成多个队列,每个队列一个消费者;
2.一个消费者对应一个队列,然后这个消费者内部用内存队列做排队,然后分发给底层不同的worker来处理
7.消息如何分发?
若队列至少有一个消费者订阅,消息将以循环的方式发送给消费者。每条消息只会分发给一个订阅的消费者(前提是消费者能够正常处理消息并进行确认)。通过路由可实现多消费的功能
8.如何保证消息不被重复消费?
解决思路是:保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响
1.在写入消息队列的数据做唯一标示,消费消息时,根据唯一标识判断是否消费过
2.利用一张日志表来记录已经处理成功的消息的 ID,如 果新到的消息 ID 已经在日志表中,那么就不再处理这条消息
9.如何确保消息正确地发送至RabbitMQ? 如何确保消息接收方消费了消息?
发送方确认模式将信道设置成发送方确认模式,则所有在信道上发布的消息都会被指派一个唯一的ID。一旦消息被投递到目的队列后,或者消息被写入磁盘后,信道会发送一个确认给生产者;如果 RabbitMQ 发生内部错误从而导致消息丢失,会发送一条nack消息。
接收方确认机制消费者接收每一条消息后都必须进行确认。只有消费者确认消息,RabbitMQ 才能安全地把消息从队列中删除。
10.如何保证RabbitMQ消息的可靠传输?
消息不可靠的情况可能是消息丢失,劫持等原因;丢失又分为:生产者丢失消息、消息列表丢失消息、消费者丢失消息;
生产者丢失消息:发送消息前,开启事务,然后发送消息,如果发送过程中出现什么异常,事务就会回滚,如果发送成功则提交事务
消息列表丢失消息:消息持久化(开启持久化磁盘的配置)
消费者丢失消息:改为手动确认消息模式;消费者在收到消息之后,处理消息之前,会自动回复RabbitMQ已收到消息;如果这时处理消息失败,就会丢失该消息;解决方案:处理消息成功后,手动回复确认消息
11.为什么不应该对所有的 message 都使用持久化机制?
导致性能的下降;仅对关键消息作持久化处理(根据业务重要程度),且应该保证关键消息的量不会导致性能瓶颈
12.如何保证高可用的?
单机模式、普通集群模式、镜像集群模式
13.如何保证消息的一致性
1.主动方应用先把消息发送给消息中间件,消息状态标记为待确认;
2.消息中间件收到消息之后,把消息持久化到消息存储中,但并不向被动方应用投递消息;
3.消息中间件返回消息持久化结果(成功,或者失效),主动方应用根据返回结果进行判断如何处理业务操作处理;(失败:放弃业务操作处理;成功:执行业务操作处理)
4.业务操作完成后,把业务操作结果(成功/失败)发送给消息中间件;
5.消息中间件收到业务操作结果后,根据结果进行处理;(失败:删除消息存储中的消息;成功:更新消息存储中的消息状态为∙待发送)紧接着执行消息投递;
6.前面的正向流程都成功后,向被动方应用投递消息;
14.如何进行消息的重试机制?
消费者消费消息的时候,发生异常情况,导致消息未确认,该消息会被重复消费(默认没有重复次数,即无限循环消费),可以通过设置重试次数以及达到重试次数之后的消息处理
15.项目中有哪些地方用到了RabbitMQ
聊天室、秒杀、积分
Shiro
1.Shiro是什么?
是一个功能强大且易于使用的 Java 安全(权限)框架。Shiro 可以完成:认证、授权、加密、会话管理、与 Web 集成、缓存 等
2.为什么要用Shiro
易于使用:使用 Shiro 构建系统安全框架非常简单
全面:Shiro 包含系统安全框架需要的功能,满足安全需求的“一站式服“
灵活:Shiro 可以在任何应用程序环境中工作
强力支持 Web:Shiro 具有出色的 Web 应用程序支持
兼容性强:Shiro 的设计模式使其易于与其他框架和应用程序集成
社区支持:Shiro 是 Apache 软件基金会的一个开源项目,有完备的社区支持,文档支持
3.三大核心组件
Subject :当前用户的操作
SecurityManager:用于管理所有的Subject
Realms:用于进行权限信息的验证
4.有哪些基本功能
1.身份认证/登录,验证用户是不是拥有相应的身份
2.授权,即权限验证,验证某个已认证的用户是否拥有某个权限
3.会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有 信息都在会话中
4.加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储
5.Web 支持,可以非常容易的集成到 Web 环境
6.缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查
7.Shiro 支持多线程应用的并发验证
8.提供测试支持
9.允许一个用户假装为另一个用户(如果他们允许)的身份进行访问
10.记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了
5.Shiro 的优点
1.简单的身份认证, 支持多种数据源
2.对角色的简单的授权
3.不跟任何的框架或者容器捆绑, 可以独立运行
6.Shiro的四重权限控制方式
1.url级别权限控制
2.方法注解权限控制
3.代码级别权限控制
4.页面标签权限控制
7.Shiro的登录运行流程
1.首先调用Subject.login(token)进行登录,他会委托给SecurityManager
2.SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
3.Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有就返回认证失败,有的话就继续执行操作。
8.如何实现自实现授权
实际开发中,通常提供AuthorizingRealm的实现类,并提供 doGetAuthorizationInfo(PrincipalCollection principals) 方法的具体实现。
9.Shiro授权过程
1.应用程序或框架代码调用任何 Subject 的方法的变体, 传递任何所需的权限
2.Subject 的实例 调用securityManager 的对应的方法
3.SecurityManager 调用 Authorizer 接口的对应方法
4.每个配置好的 Realm 被检查是否实现了相同的 Authorizer 接口
10.什么是粗颗粒和细颗粒权限?
粗颗粒权限:对资源类型的管理;即只控制到菜单、按钮、方法。粗粒度的例子比如:用户具有用户管理的权限,具有导出订单明细的权限
细颗粒权限:对资源实例的控制;即控制到数据级别的权限,比如:用户只允许修改本部门的员工信息,用户只允许导出自己创建的订单明细
11.粗颗粒和细颗粒如何授权?
粗颗粒权限:可以使用过虑器统一拦截url
细颗粒权限:在service中控制,在程序级别来控制,个性化编程
Java基础面试题有哪些?
参考技术A 1.java异常机制的原理与应用\\x0d\\x0a答:每当程序出现异常之后,如果程序没有进行相应的处理,则程序会出现中断现象。\\x0d\\x0a实际上,产生了异常之后,JVM会抛出一个异常类的实例化对象,如果此时使用了try语句捕获的话,则可以进行异常的处理,否则,交给JVM进行处理。当try语句捕获异常之后,将与catch语句的异常类型进行匹配,如果匹配成功则执行catch内的语句。简单的应用:在所以throws语句的地方加入try-catch。标准应用:try-catch-finally-throw-throws一起使用。 \\x0d\\x0a\\x0d\\x0a2. 垃圾回收机制的优点\\x0d\\x0a答:释放无用的对象所占用的空间。方式:自动回收,手动回收。使用System.gc(),实际上调用Runtime.getRuntime().gc()\\x0d\\x0a\\x0d\\x0a3. Error与Exception区别\\x0d\\x0a答:Error是jvm进行处理,是jvm出错\\x0d\\x0aexception是可以由程序处理的,可以用try-catch捕获的\\x0d\\x0a\\x0d\\x0a4. final,finally,finallize\\x0d\\x0a答:final定义的变量的值不能改变,定义的方法不能被覆盖,定义的类不能被继承\\x0d\\x0afinally是异常的统一出口,finallize是垃圾回收前的收尾工作,是Object类定义的\\x0d\\x0a\\x0d\\x0a5. Anonymous Inner Class是否可以extends,是否可以implements Interface\\x0d\\x0a答:允许继承和实现,因为匿名内部类就是在抽象类和接口的基础上发展起来的\\x0d\\x0a\\x0d\\x0a6. Static Nested Class 与Inner Class的区别\\x0d\\x0a答:使用Static定义的Class就是外部类,可以通过外部类. 内部类直接访问\\x0d\\x0a而Inner Class是不能被外部访问的,只能通过外部类的实例再找到内部类实例。\\x0d\\x0a\\x0d\\x0a7. HashMap and HashTable?\\x0d\\x0a答:HashMap:1) released in jdk 1.2,new Class 2)采用异步处理方式,性能较高,是非线程安全的 3)允许null\\x0d\\x0aHashTable:\\x0d\\x0a1)released in jdk 1.0 ,old Class \\x0d\\x0a2)采用同步处理方式,性能低,是线程安全的\\x0d\\x0a3)不允许null\\x0d\\x0a\\x0d\\x0a8. assert代表什么?\\x0d\\x0a答:asserts是jdk 1.4之后发布的新关键字,表示断言,即程序执行到某个地方肯定是预计的值,一般开发很少使用。要使用assert,必须加上 -ea参数\\x0d\\x0a\\x0d\\x0a9. gc是什么?\\x0d\\x0a答:gc是garbage collection,垃圾回收,使用gc可以进行垃圾空间的释放\\x0d\\x0a\\x0d\\x0a10. String s = new String("xyz")产生了几个对象?\\x0d\\x0a答:一个匿名对象xyz,在栈空间内。一个new实例化的对象,在堆空间内。\\x0d\\x0a\\x0d\\x0a11. sleep() and wait()?\\x0d\\x0a答:sleep()是Thread类定义方法,表示线程的休眠,可以自动唤醒\\x0d\\x0await()方法是Object类定义的方法,需要手动notify()和notifyAll()//sleep()不释放资源,wait()释放资源\\x0d\\x0a\\x0d\\x0a12. Overload与Override的区别\\x0d\\x0a答:Overload:重载\\x0d\\x0a |- 在一个类中定义的若干方法\\x0d\\x0a |- 所有的方法名相同,但参数类型或个数不同\\x0d\\x0a |- 只有参数有关,与返回类型无关\\x0d\\x0aOverride:覆写\\x0d\\x0a |- 在继承的关系中\\x0d\\x0a |- 子类定义了父类同名的方法,参数类型或个数最好完全一样。\\x0d\\x0a |- 访问权限不能更严格\\x0d\\x0a\\x0d\\x0a13. abstract class 和 interface有什么区别?\\x0d\\x0a答:抽象类:\\x0d\\x0a |-由抽象方法和常量、变量、全局常量、构造方法、普通方法组成\\x0d\\x0a |-使用abstract声明\\x0d\\x0a |-子类要通过extends继承抽象类,子类如果不是抽象类,则必须覆写抽象类的全部抽象方法\\x0d\\x0a |-存在单继承的局限\\x0d\\x0a |-抽象类可以实现若干个接口\\x0d\\x0a接口:\\x0d\\x0a |-由抽象方法和全局常量组成\\x0d\\x0a |-使用interface关键字\\x0d\\x0a |-子类要通过implements实现接口,子类如果不是抽象类,则必须覆写抽象类的全部抽象方法\\x0d\\x0a |-一个子类可以实现多个接口\\x0d\\x0a |-接口不能继承一个抽象类,但允许继承多个接口以上是关于java基础面试题的主要内容,如果未能解决你的问题,请参考以下文章