【面试进行时】大厂常考面试题一览(二)

2021-04-13 15:58:16 浏览数 (1)

.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:30px;margin-bottom:5px}.markdown-body h2{padding-bottom:12px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}

金三银四,金九银十这两段时间一直是广大技术人的求职高峰期。作为一个技术人员,进入大厂工作是我职业生涯的目标之一,这段时间也参与过不少大厂的面试,在面试完后,不管当时的效果如何,都会把面试题记录下。

因为最近工作比较忙,没有时间深入进行学习,我就把前段时间遇到一些常见的或者是比较有意义的题目整理了一下,在自己学习之余也和大家做一个分享。

之前的文章大家也可以看看【面试进行时】大厂常考面试题一览(一)

基本上次面试遇到的问题这一轮也都遇到过,没事复习一下效果也非常棒~

一、能不能谈一谈SpringBean的生命周期?你知道BeanFactory和FactoryBean的区别吗?

这道题在小米和百度的技术面中都遇到了,主要是我的简历上写了学习过spring的源码,我们都知道,spring的源码代码量非常大,也非常复杂,在面试的过程中,时间是有限的,所以我们主要是要捡比较重要的部分回答。

关于生命周期的问题,我在上一篇讲面试的文章里已经说过,这里就不重复水文章了,主要介绍一下BeanFactory和FactoryBean的区别。

BeanFactory:

FactoryBean:

根据这两个图、还有他们的命名和方法,我们大概就能得出初步的结论了:

  • BeanFactory是接口,提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范,同时也是个Factory,是IOC容器或对象工厂。

在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。同时,因为它只是个接口,并不是IOC容器的具体实现,我们常用的ApplicationContext就是一个BeanFactory。我们通过bean的名称或者类型都可以从BeanFactory来获取bean。

  • FactoryBean是接口,为IOC容器中Bean的实现提供了更加灵活的方式,同时FactoryBean也是一个Bean,一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。

对于FactoryBean而言,在Spring有默认方式创建Bean的方法,但是在我们所需要创建的实例Bean对象比较复杂的情况下,使用传统方式创建bean会比较复杂,例如(使用xml配置),这样就出现了FactoryBean接口,可以让用户通过实现该接口来自定义该Bean接口的实例化过程。即包装一层,将复杂的初始化过程包装,让调用者无需关系具体实现细节。

二、Spring中如何实现三级缓存的?

首先,这个问题的提出通常是提到了SpringBean的循环依赖的问题,我们都知道,Spring中已经帮助我们解决了这个问题,而解决的方法就是问题中所提到的三级缓存。

Spring的循环依赖的理论依据基于Java的引用传递,当获得对象的引用时,对象的属性是可以延后设置的

三级缓存

  • singletonObjects(一级缓存):用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用。
  • earlySingletonObjects(二级缓存):提前曝光的单例对象的cache,存放原始的 bean 对象(尚未填充属性),用于解决循环依赖。
  • singletonFactories(三级缓存):单例对象工厂的cache,存放 bean 工厂对象,用于解决循环依赖。

三级缓存的实施方法

  • 1、先从一级缓存singletonObjects中去获取。(如果获取到就直接返回)
  • 2、如果获取不到或者对象正在创建中(isSingletonCurrentlyInCreation()),那就再从二级缓存earlySingletonObjects中获取。(如果获取到就直接返回)
  • 3、如果还是获取不到,且允许singletonFactories(allowEarlyReference=true)通过getObject()获取。就从三级缓存singletonFactory.getObject()获取。(如果获取到了就从singletonFactories中移除,并且放进earlySingletonObjects。其实也就是从三级缓存移动(剪切)到了二级缓存)

三、Redis是常见的缓存中间件,它的性能很好,那么你知道它的性能为什么这么好吗?

众所周知,Redis是一个单线程应用,它的性能非常高的原因主要有以下几点:

  • 单线程实现:因为是单线程应用,所以避免了多个线程之间线程切换和锁资源争用的开销。
  • 内存存储:Redis是一个内存数据库, 所有数据基本上都存在于内存当中, 会定时以追加或者快照的方式刷新到硬盘,没有磁盘IO上的开销。
  • 非阻塞IO:Redis使用多路复用IO技术,在poll,epool,kqueue选择最优IO实现。
  • 优化的数据结构:Redis有诸多可以直接应用的优化数据结构的实现,应用层可以直接使用原生的数据结构提升性能。

这一块我们的重点在数据结构的优化和多路复用技术上,数据结构的内容可以参考之前的文章【进阶之路】Redis基础知识两篇就满足(一),接下来我简单地描述一下多路复用技术的原理。

IO多路复用简单来说就是一个线程处理多个请求。

IO多路复用程序会同时监听多个socket,当被监听的socket准备好执行后,与这些操作相对应的文件事件就会产生。IO多路复用程序会把所有产生事件的socket压入一个队列中,然后有序地每次仅一个socket的方式传送给文件事件分派器,文件事件分派器接收到socket之后会根据socket产生的事件类型调用对应的事件处理器进行处理。

  • 连接应答处理器:用于处理客户端的连接请求;
  • 命令请求处理器:用于执行客户端传递过来的命令,比如常见的set、lpush等;
  • 命令回复处理器:用于返回客户端命令的执行结果,比如set、get等命令的结果;

四、我看你平时使用了多种消息中间件,那么kafka和rabbitMQ的区别是什么?什么是零拷贝技术(zero-copy)?

这种问题我也经常会遇到,因为自己的很多项目都同时用到了kafka与rabbitMQ。

项目中,通常会使用kafka作为消息传输的数据管道,而rabbitMQ作为数据传输管道。这样做的主要原因则是是否存在丢数据的可能与消息中间件本身的性能因素。

rabbitMQ: 我现在的项目主要是处理金融场景的任务,对消息中间件具有较高的严谨性和实时性要求。而rabbitMQ的健壮、稳定、易用、跨平台、支持多种语言、文档齐全、社区活跃等特点和自带消息确认机制和持久化机制与项目要求匹配。

rabbitMQ的特点

  • 可靠性:提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制;
  • 灵活的路由:消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用;
  • 消息集群:在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用;
  • 队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全;

kafka: 而kafka优势主要体现在吞吐量上,虽然可以通过策略实现数据不丢失,但从严谨性角度来讲,大不如rabbitMQ;而且由于kafka保证每条消息最少送达一次,有较小的概率会出现数据重复发送的情况。所以通常作为日志领域的中间件,毕竟大多数情况日志不害怕丢失。

kafka的特点

  • 快速持久化:可以在O(1)的系统开销下进行消息持久化;
  • 高吞吐:在一台普通的服务器上既可以达到10W/s的吞吐速率;
  • 完全的分布式系统:Broker、Producer和Consumer都原生自动支持分布式,自动实现负载均衡;
  • 支持同步和异步复制两种高可用机制;
  • 支持数据批量发送和拉取;

一般答出kafka的特点后,面试官大概会聊到零拷贝技术(如果做好了准备可以自己引出来)。

传统的拷贝流程,在消费者获取消息时,服务器先从磁盘读取数据到内存,然后把内存中的数据原封不动的通过 socket 的形式发送给消费者。而零拷贝并不是不需要拷贝,而是在IO读写过程减少不必要的拷贝次数。

零拷贝技术则是数据直接在内核完成输入和输出,不需要拷贝到用户空间再写出去。 kafka数据写入磁盘前,数据先写到进程的内存空间。

零拷贝技术经过 DMA(Direct Memory Access)技术将文件内容复制到内核模式下的 Read Buffer 中。不过没有数据被复制到 Socket Buffer,相反只有包含数据的位置和长度的信息的文件描述符被加到 Socket Buffer 中。DMA 引擎直接将数据从内核模式中传递到网卡设备(协议引擎)。这里数据只经历了2次复制就从磁盘中传送出去了,而且上下文切换也变成了2次。零拷贝是针对内核模式而言的,数据在内核模式下实现了零拷贝。高并发。

大家好,我是练习java两年半时间的南橘,下面是我的微信,需要之前的导图或者想互相交流经验的小伙伴可以一起互相交流哦。

0 人点赞