Java面试:2021.06.11

1、Spring 框架中都用到了哪些设计模式?

Spring 框架中使用到了大量的设计模式,下面列举了比较有代表性的:

  1. 代理模式 — 在 AOP 和 remoting 中被用的比较多。 

  2. 单例模式 — 在 Spring 配置文件中定义的 Bean 默认为单例模式。 

  3. 模板方法 — 用来解决代码重复的问题。比如 RestTemplate、JmsTemplate、JdbcTemplate 。 

  4. 前端控制器 — Spring提供了 DispatcherServlet 来对请求进行分发。 

  5. 视图帮助(View Helper) — Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码整合在视图里。 

  6. 依赖注入 — 贯穿于 BeanFactory / ApplicationContext 接口的核心理念。工厂模式 — BeanFactory 用来创建对象的实例。

 

2、可以通过哪些方式完成依赖注入?

接口注入、构造函数注入、setter注入。

目前,在 Spring Framework 中,仅使用构造函数和 setter 注入这两种方式。

图片

实际场景下,setting 注入使用的更多。

 

3、Spring Boot、Spring MVC 和 Spring 有什么区别?

Spring 的完整名字,应该是 Spring Framework 。它提供了多个模块,Spring IoC、Spring AOP、Spring MVC 等 等。所以,Spring MVC 是 Spring Framework 众多模块中的一个。
而 Spring Boot 是构造在 Spring Framework 之上的 Boot 启动器,旨在更容易的配置一个 Spring 项目。
总结说来,如下图所示:

 

4、ZooKeeper 是如何保证事务的顺序一致性的?

ZooKeeper 采用了递增的事务 id 来识别,所有的 proposal(提议)都在被提出的时候加上了 zxid 。zxid 实际上 是一个 64 位数字。

  • 高 32 位是 epoch 用来标识 Leader 是否发生了改变,如果有新的 Leader 产生出来,epoch会自增。 

  • 低 32 位用来递增计数。

当新产生的 peoposal 的时候,会依据数据库的两阶段过程,首先会向其他的 Server 发出事务执行请求,如果超 过半数的机器都能执行并且能够成功,那么就会开始执行。



5、ZooKeeper 集群中个服务器之间是怎样通信的?

Leader 服务器会和每一个 Follower/Observer 服务器都建立 TCP 连接,同时为每个 Follower/Observer 都创建一 个叫做 LearnerHandler 的实体。

  • LearnerHandler 主要负责 Leader 和 Follower/Observer 之间的网络通讯,包括数据同步,请求转发和 Proposal 提议的投票等。 

  • Leader 服务器保存了所有 Follower/Observer 的 LearnerHandler 。

 

6、为什么 Redis 单线程模型也能效率这么高?

1、纯内存操作。
Redis 为了达到快的读写速度,将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以 Redis 具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘 I/O 速度为严重影响 Redis 的性能。

2、核心是基于非阻塞的 IO 多路复用机制。

3、单线程反而避免了多线程的频繁上下文切换问题。

Redis 利用队列技术,将并发访问变为串行访问,消除了传统数据库串行控制的开销
4、Redis 全程使用 hash 结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩 表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。

 

7、Redis 有几种持久化方式?

Redis 提供了两种方式,实现数据的持久化到硬盘。

1、【全量】RDB 持久化,是指在指定的时间间隔内将内存中的数据集快照写入磁盘。实际操作过程是,fork 一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

2、【增量】AOF持久化,以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文 本的方式记录,可以打开文件看到详细的操作记录。

 

8、这两种方式的优缺点是怎样的?

RDB 优缺点
① 优点

  • 灵活设置备份频率和周期。你可能打算每个小时归档一次近 24 小时的数据,同时还要每天归档一次近 30 天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。 

  • 非常适合冷备份,对于灾难恢复而言,RDB 是非常不错的选择。因为我们可以非常轻松的将一个单独的文件 压缩后再转移到其它存储介质上。推荐,可以将这种完整的数据文件发送到一些远程的安全存储上去,比如 说 Amazon 的 S3 云服务上去,在国内可以是阿里云的 OSS 分布式存储上。

  • 性能大化。对于 Redis 的服务进程而言,在开始持久化时,它唯一需要做的只是 fork 出子进程,之后再由 子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行 IO 操作了。也就是说,RDB 对 Redis 对 外提供的读写服务,影响非常小,可以让 Redis 保持高性能。 

  • 恢复更快。相比于 AOF 机制,RDB 的恢复速度更更快,更适合恢复数据,特别是在数据集非常大的情况。 

 

② 缺点

  • 如果你想保证数据的高可用性,即大限度的避免数据丢失,那么 RDB 将不是一个很好的选择。因为系统一 旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
    所以,RDB 实际场景下,需要和 AOF 一起使用。

  • 由于 RDB 是通过 fork 子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服 务器停止服务几百毫秒,甚至是 1 秒钟。

    所以,RDB 建议在业务低估,例如在半夜执行。 

 

AOF 优缺点
① 优点

  • 该机制可以带来更高的 数据安全性 ,即数据持久性。Redis 中提供了 3 种同步策略,即每秒同步、每修改(执行一个命令)同步和不同步。

    1.事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一 秒钟之内修改的数据将会丢失。 

    2.而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以 预见,这种方式在效率上是低的。 

    3.至于无同步,无需多言,我想大家都能正确的理解它。 

  • 由于该机制对日志文件的写入操作采用的是 append 模式,因此在写入过程中即使出现宕机现象,也不会破 坏日志文件中已经存在的内容。 

    1.因为以 append-only 模式写入,所以没有任何磁盘寻址的开销,写入性能非常高。 

    2.另外,如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在 Redis 下一次启动 之前,我们可以通过 redis-check-aof 工具来帮助我们解决数据一致性的问题。 

  • 如果日志过大,Redis可以自动启用 rewrite 机制。即使出现后台重写操作,也不会影响客户端的读写。因为 在 rewrite log 的时候,会对其中的指令进行压缩,创建出一份需要恢复数据的小日志出来。再创建新日志 文件的时候,老的日志文件还是照常写入。当新的 merge 后的日志文件 ready 的时候,再交换新老日志文件 即可。

  • AOF 包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完 成数据的重建。


② 缺点

  • 对于相同数量的数据集而言,AOF 文件通常要大于 RDB 文件。RDB 在恢复大数据集时的速度比 AOF 的恢复 速度要快。 

  • 根据同步策略的不同,AOF 在运行效率上往往会慢于 RDB 。总之,每秒同步策略的效率是比较高的,同步禁 用策略的效率和 RDB 一样高效。 

  • 以前 AOF 发生过 bug ,就是通过 AOF 记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。所以说,类似 AOF 这种较为复杂的基于命令日志/merge/回放的方式,比基于 RDB 每次持久化一份完整的数 据快照文件的方式,更加脆弱一些,容易有 bug 。不过 AOF 就是为了避免 rewrite 过程导致的 bug ,因此每次 rewrite 并不是基于旧的指令日志进行 merge 的,而是基于当时内存中的数据进行指令的重新构建,这样 健壮性会好很多。

 

9、在项目中你们用的是那种持久化方式?

  • 不要仅仅使用 RDB,因为那样会导致你丢失很多数据;

  • 也不要仅仅使用 AOF,因为那样有两个问题,第一,你通过 AOF 做冷备,没有 RDB 做冷备,来的恢复速度 更快; 第二,RDB 每次简单粗暴生成数据快照,更加健壮,可以避免 AOF 这种复杂的备份和恢复机制的 bug 。 

  • Redis 支持同时开启开启两种持久化方式,我们可以综合使用 AOF 和 RDB 两种持久化机制,用 AOF 来保证 数据不丢失,作为数据恢复的第一选择; 用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复。 

    如果同时使用 RDB 和 AOF 两种持久化机制,那么在 Redis 重启的时候,会使用 AOF 来重新构建数据, 因为 AOF 中的数据更加完整。

    1.一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。 如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失,那么你可以只使用 RDB 持久 化。 

    2.有很多用户都只使用 AOF 持久化,但并不推荐这种方式:因为定时生成 RDB 快照(snapshot) 非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug。

    在 Redis4.0 版本开始,允许你使用 RDB-AOF 混合持久化方式。

 

10、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?

这个定期的频率,由配置文件中的 hz 参数决定,代表了一秒钟内,后台任务期望被调用的次数。Redis3.0.0 中的默认值是 10 ,代表每秒钟调用 10 次后台任务。 

hz 调大将会提高 Redis 主动淘汰的频率,如果你的 Redis 存储中包含很多冷数据占用内存过大的话,可以考 虑将这个值调大,但 Redis 作者建议这个值不要超过 100 。我们实际线上将这个值调大到 100 ,观察到 CPU 会增加 2% 左右,但对冷数据的内存释放速度确实有明显的提高(通过观察 keyspace 个数和 used_memory 大小)。

另附资源下载:关注 “Java面试百分百
1,后台回复:面试资料,可获取一份最新的Java面试资料。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值