java面试题——中间件&&数据库&&redis

Posted lililiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java面试题——中间件&&数据库&&redis相关的知识,希望对你有一定的参考价值。

六、中间件篇

1.消息中间件如何保证消息的一致性和如何进行消息的重试机制?

2.Spring Cloud熔断机制介绍;

在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand,Hystrix会找有这个注解的方法,并将这类方法关联到和熔断器连在一起的代理上。当前,@HystrixCommand仅当类的注解为@Service或@Component时才会发挥作用。

3.Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?

1.①dubbo由于是二进制的传输,占用带宽会更少
  ②springCloud是http协议传输,带宽会比较多,同时使用http协议一般会使用JSON报文,消耗会更大
  ③dubbo的开发难度较大,原因是dubbo的jar包依赖问题很多大型工程无法解决
  ④springcloud的接口协议约定比较自由且松散,需要有强有力的行政措施来限制接口无序升级
  ⑤dubbo的注册中心可以选择zk,redis等多种,springcloud的注册中心只能用eureka或者自研
2.对于类似于电商等同步调用场景多并且能支撑搭建Dubbo 这套比较复杂环境的成本的产品而言,Dubbo 确实是一个可以考虑的选择。但如果产品业务中由于后台业务逻辑复杂、时间长而导致异步逻辑比较多的话,可能Dubbo 并不合适。同时,对于人手不足的初创产品而言,这么重的架构维护起来也不是很方便

参考链接:https://blog.csdn.net/u010664947/article/details/80007767

七、数据库篇

4.锁机制介绍:行锁、表锁、排他锁、共享锁;

①表锁和行锁锁的粒度不一样,表锁锁住的是一整张表,行锁锁住的是表中的一行数据。InnoDB使用的是行级锁,MyISAM使用的是表级锁。
②共享锁又称读锁(S锁),一个事务获取了共享锁,其他事务可以获取共享锁,不能获取排他锁,其他事务可以进行读操作,不能进行写操作。
③排他锁又称写锁(X锁),如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);

5.乐观锁的业务场景及实现方式;

1.①悲观锁(Pessimistic Lock): 每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待。
  ②乐观锁(Optimistic Lock):每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。
2.适用场景:
①悲观锁:比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量。 ②乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。 总结:两种所各有优缺点,读取频繁使用乐观锁,写入频繁使用悲观锁。

6.事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;

1.事务:事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
2.①分布式事务:用需要操作的资源位于多个资源服务器上,而应用需要保证对于多个资源服务器的数据的操作,要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同资源服务器的数据一致性。
3.解决方案:
①两阶段提交;
②补偿事务:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作;
③本地消息表(异步确保):消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送
4.两阶段提交:①TM通知各个RM准备提交它们的事务分支。如果RM判断自己进行的工作可以被提交,那就就对工作内容进行持久化,再给TM肯定答复;要是发生了其他情况,那给TM的都是否定答复。在发送了否定答复并回滚了已经的工作后,RM就可以丢弃这个事务分支信息。②TM根据阶段1各个RM prepare的结果,决定是提交还是回滚事务。如果所有的RM都prepare成功,那么TM通知所有的RM进行提交;如果有RM prepare失败的话,则TM通知所有RM回滚自己的事务分支。
  三阶段提交:①CanCommit阶段:3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
②PreCommit阶段: 协调者根据参与者的反应情况来决定是否可以记性事务的PreCommit操作。根据响应情况,有以下两种可能。假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。
③doCommit阶段, 该阶段进行真正的事务提交,也可以分为以下两种情况。 Case
1:执行提交 1).发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。        2).事务提交 参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。        3).响应反馈 事务提交完之后,向协调者发送Ack响应。        4).完成事务 协调者接收到所有参与者的ack响应之后,完成事务。        Case 2:中断事务 协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。        1).发送中断请求 协调者向所有参与者发送abort请求        2).事务回滚 参与者接收到abort请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。        3).反馈结果 参与者完成事务回滚之后,向协调者发送ACK消息        4).中断事务 协调者接收到参与者反馈的ACK消息之后,执行事务的中断
参考链接:http://www.tianshouzhi.com/api/tutorials/distributed_transaction

7.mysql记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?

①Row Level行模式:日志中会记录每一行数据被修改的形式,然后在slave端再对相同的数据进行修改
优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题
缺点:row level,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容。
②Statement Level(默认):每一条会修改数据的sql都会记录到master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行
优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能,因为它只需要在Master上锁执行的语句的细节,以及执行语句的上下文的信息。
缺点:由于只记录语句,所以,在statement level下 已经发现了有不少情况会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。
③Mixed 自动模式:在Mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志格式,也就是在Statement和Row之间选择一种。如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。

8.同步异步阻塞非阻塞;

1.同步与异步:获取完成标志的方式。如果是采用轮询的方式监测I/O操作是否完成称为同步,而以通过回调通知的方式获得完成标志则称为异步。
  阻塞与非阻塞:在那段时间差的过程中,CPU有没有处理别的事情,如果处理过别的事情则是非阻塞,如果并没有处理过别的事情则是阻塞。

2.①同步阻塞:即是在B阶段CPU一直采用轮询的方式直到获得完成标志,所以此段时间CPU一直阻塞在此I/O操作上。
  ②同步不阻塞:在B阶段依然采用轮询的方式直至获得完成标志,但是此轮询不同于上面的轮询过程,而是在相邻的轮询中完成了上下文切换去处理别的任务的,所以是同步不阻塞
  ③异步阻塞:也就是所没有上面的①,②过程,当I/O操作完成后回调通知CPU已完成【即是③过程】,但是此阶段CPU处于休眠状态而不处理别的任务。=
  ④异步不阻塞:和上面一样没有①,②过程而是通过回调知道I/O操作已完成,但是并没有休眠,而是在此阶段处理其他任务。

综上所述:异步不阻塞是最高效的。

9.数据库事务隔离级别,MySQL默认的隔离级别;

MySQL数据库提供四种隔离级别:
  ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
  ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
  ③ Read committed (读已提交):可避免脏读的发生。
  ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证

MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。

10.Spring如何实现事务、JDBC如何实现事务、嵌套事务实现;

spring事务:①获取事务属性。
    ②加载配置中配置的TransactionManager。
    ③不同的事务处理使用不同的逻辑,第一点区别在事务属性上,编程式事务是不需要有事务属性的。第二点区别在TransactionManager上,CallbackPreferringPlatformTransactionManager实现了PlatformTransactionManager接口,暴露出一个方法用于执行事务处理中的回调。所以这两种方式都可以 用作事务处理方式的判断。
    ④在目标方法执行前获取事务并收集事务信息。(事务信息和事务属性并不相同)
    ⑤执行目标方法。
    ⑥一旦出现异常,尝试异常处理。并不是所有异常spring都会回滚,默认只对RuntimeException回滚。
    ⑦提交事务前的事务信息清除。
    ⑧提交事务。
jdbc事务:①获取连接 Connection con = DriverManager.getConnection() ②开启事务con.setAutoCommit(true/false); ③执行CRUD ④提交事务/回滚事务 con.commit() / con.rollback(); ⑤关闭连接 conn.close();
嵌套事务:在spring中将事务级别设置为RROPAGATION_REQUIRES_NEW

11.SQL的整个解析、执行过程原理、SQL行转列;

1.①第一步:客户端把语句发给服务器端执行
  ②第二步:语句解析 1)查询高速缓存(library cache)
                  2)语句合法性检查(data dict cache)
           3)语言含义检查(data dict cache)
           4)获得对象解析锁(control structer)
           5)数据访问权限的核对(data dict cache)
           6)确定最佳执行计划 ③第三步:绑定变量赋值④第四步:语句执行⑤第五步:提取数据
2.脚本:

Select st.stuid, st.stunm,
MAX(CASE c.coursenm WHEN ‘大学语文‘ THEN s.scores ELSE 0 END ) ‘大学语文‘,
MAX(CASE c.coursenm WHEN ‘新视野英语‘ THEN ifnull(s.scores,0) ELSE 0 END ) ‘新视野英语‘,
MAX(CASE c.coursenm WHEN ‘离散数学‘ THEN ifnull(s.scores,0) ELSE 0 END ) ‘离散数学‘,
MAX(CASE c.coursenm WHEN ‘概率论与数理统计‘ THEN ifnull(s.scores,0) ELSE 0 END ) ‘概率论与数理统计‘,
MAX(CASE c.coursenm WHEN ‘线性代数‘ THEN ifnull(s.scores,0) ELSE 0 END ) ‘线性代数‘,
MAX(CASE c.coursenm WHEN ‘高等数学(一)‘ THEN ifnull(s.scores,0) ELSE 0 END ) ‘高等数学(一)‘,
MAX(CASE c.coursenm WHEN ‘高等数学(二)‘ THEN ifnull(s.scores,0) ELSE 0 END ) ‘高等数学(二)‘
From student st
Left Join score s On st.stuid = s.stuid
Left Join courses c On c.courseno = s.courseno
Group by st.stuid
参考链接:https://blog.csdn.net/wulantian/article/details/52687640

八、Redis

Redis为什么这么快?redis采用多线程会有哪些问题?

Redis支持哪几种数据结构;

Redis跳跃表的问题;

Redis单进程单线程的Redis如何能够高并发?

Redis如何使用Redis实现分布式锁?

Redis分布式锁操作的原子性,Redis内部是如何实现的?

 

以上是关于java面试题——中间件&&数据库&&redis的主要内容,如果未能解决你的问题,请参考以下文章

Java大厂笔试&&面试集合大全目录

Java集训(算法&&面试题)第四天 (链表 & 树)

Java面试题

Java集训(算法&&面试题)第二天

Java集训(算法&&面试题)第三天 (链表 & 树)

Java集训(算法&&面试题)第三天 (链表 & 树)