请选择 进入手机版 | 继续访问电脑版

不容错过的Java高级面试题

[复制链接]
小小海 发表于 2021-1-1 17:46:56 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
  又到跨年之际,想必在这一年技能发展颇多的猿友们为备战金三银四而摩拳擦掌了吧。工欲善其事必先利其器。停止无病呻吟和眼高手低,实事求是地狂刷口试题,offer拿到手软不再是空谈。帝都的雁为各人汇总本人在今次找工作中遇到的口试题,希望可以帮到猿友。
  (PS:博主本次找工作到场口试的知名企业有:有快手/字节/阿里/滴滴/boss直聘/携程/猎聘/好未来/京东/美团/当当,最终也如愿进入此中一家大厂;口试题基于Java全栈,参照个人简历的技能栈由浅至深询问。故发起猿友们在简历上写自己hold得住的技能,切莫画蛇添足。以本人技能栈为例,答案均为本人的明确,仅供参考。)


一、设计模式

  枚举常被问到的设计模式。
计谋(阿里/快手/京东/猎聘)

  问:在项目哪些地方使用到了计谋设计模式。
  答:重构订单状态变动逻辑。系统中订单的状态有许多多少个,每一个状态对应一种业务逻辑,以前的代码按照if() else if()分支去处置惩罚,代码臃肿且冗余。我界说订单计谋的抽象类抽取共同行为和属性,再将每个订单状态的业务逻辑封装为订单计谋实现类,并放入spring的IOC中;界说一个枚举,将订单的状态和订单计谋实现类的beanID进行映射。最后界说计谋上下文对象,用于交互即可。
 
单例(快手/boss直聘/滴滴)

  问:手写一个单例。
  答:我一般为了简朴,会直接写饿汉式。但会向口试官叙述单例的一些实现方式和注意事项。
  单例是指一个类在一个JVM中仅有一个实例对象。常见的实现方式有饿汉式、懒汉式、线程安全的懒汉式、双重查验锁+volatile、静态内部类、枚举等方式。反射和反序列化可以粉碎单例,所以需要在单例的构造中再次判定实例对象是否已创建,进而抛出异常进行规避。
 
代理(猎聘/字节/阿里)

  问:动态代理的实现方式。
  答:继续目的类或实现目的类接口。
  JDK动态代理基于实现目的类接口,写一个方法增强器实现invocationHandler接口,重写其invoke方法,然后通过Proxy.newInstance的方式传入目的类的类加载器、目的类实现的接口,以及自界说的方法增强器,然后创建代理对象。本质上是动态拼接了一个实现了目的类接口的代理类的字符串,将这个字符串输出至当地的一个Java文件中,再通过Java编译器编译,变为class文件,类加载器将其加载至JVM内存,以反射的方式进行实例化使用。
  CGLIB动态代理基于继续目的类。写一个MethodIntercepter的实现类,重写其invokeSuper方法,然后通过Enhancer的方式进行创建使用。底层通过ASM字节码技能生成了三个文件:代理类字节码、目的类索引文件、代理类索引文件。索引文件中将当前类中方法名称和参数列表范例组成签名,按照hash生成一个下标,然后通过switch case的方式枚举,故而访问起来会比反射的方式更快。
 
观察者(boss直聘/携程/滴滴/美团/当当)

  问:观察者的使用场景。
  答:订单发货后需要给商家发短信和邮件。由于我们系统前期没有引入MQ,所以接纳异步线程去进行解耦。发货可以看作一个事件,短信和邮件可以看作两个观察者。接纳spring的Event事件通知去实现此功能。
 
模板方法(阿里/快手/京东)

  问:项目中怎么使用的模板方法。
  答:系统中许多批量导入的业务代码冗余,且其大抵操纵流程相似,为了便于维护,故而将批量导入的流程抽取至抽象类中,具体的行为抽象交给不同的业务代码实现即可。
 
题外话(京东/猎聘/好未来/滴滴/当当)

  问:现在对于设计模式的使用分为截然不同的两个派系,鼎力大肆拥护和强烈反对。如何对待设计模式?
  答:设计模式有时可能不直观,非本人编写的代码,阅读起来有可能有些绕,倒霉于新手修改。但它方便扩展,且可以使业务代码之间很好的解耦,对于源码的阅读也有很大资助。

二、JAVA基础

  Java基础包罗JDK和spring体系、mybatis。
线程池(快手/字节/阿里/滴滴/boss直聘/携程/猎聘/好未来/京东/美团/当当)

  问:线程池的焦点组件有哪些?为什么不推荐使用JDK自带线程池?如何手写一个线程池。
  答:线程池焦点参数有焦点线程数(线程池启动后,一直处于活跃状态的线程)、队列长度(焦点线程都在处置惩罚任务时,新来的任务会放入此队列中)、最大线程数(队列满了后,会再开启一定命量的线程,即线程池最多创建的线程数量)、拒绝计谋(队列满了,最大线程数的线程均在处置惩罚任务,此时尚有任务投递,则进行的动作)。
  JDK自带的线程池有四种:固定长度(队列无界)、可缓存(最大线程数无界)、可定时(最大线程数无界)、单例(队列无界)。由于其无界(队列或最大线程数),可能会造成线程太多或任务太多带来的OOM(out of memory)问题。我研究过定时线程池,内部维护了一个延时工作队列(底层接纳小堆顶的方式实现),任务携带时间隔断的参数,每当任务要执行时,会把当前系统时间+时间隔断后,把这个任务再次投递至延时工作队列中。
  手写线程池思路:界说阻塞队列。创建焦点线程数的线程,使其一直处于活跃状态(死循环即可),当有任务需要执行时,从队列中获取任务执行。
 
并发包(快手/字节/阿里/滴滴/boss直聘/携程/猎聘/好未来/京东/美团/当当)

  问:sync和lock的区别。公平锁与非公平锁的区别。CAS有什么问题?如何办理?
  答:我个人认为lock就是仿照sync的底层原理以Java代码的方式实现了一次。
  Sync内部维护了一个monitor对象,用于管理锁的开销。其内部有锁池(抢锁失败的线程)、期待池(调用锁wait方法的线程)、锁持有线程、重入次数、竞争逻辑。
  Sync存在锁的膨胀(粗化)。偏向锁:即一把锁在一段时间内只被同一个线程持有,那么当这个线程来访问锁时,不会对其进行加锁操纵,而是在锁对象的对象头markword中存放偏向锁的信息,记载当前线程ID,用于比力。轻量级锁:一个线程持有一把锁的时间非常短,那么抢锁失败的线程不会直接阻塞,而是自旋期待(将锁对象头中偏向锁信息拷贝至自己线程的工作内存中,以CAS的方式自旋)。重量级锁:如果多次自旋失败,则不会继续这种消耗CPU资源的行为,而是直接将其阻塞,期待锁的释放。
  Lock锁本质上是AQS的一层封装。其内存也有状态(记载锁重入次数)、阻塞双向链表(抢锁失败的线程)、锁持有线程、condition的单向期待链表(调用condtion.await方法的线程)。
  AQS默认创建为非公平锁,当线程获取锁失败时,会短暂自旋一次,然后将当前线程通过LockSupport的方式进行阻塞,然后封装为NODE节点,放入阻塞链表的末了。当锁释放后,从阻塞链表的头部取出一个节点,将线程唤醒,继续抢夺锁资源。由于期间可能出现非阻塞链表的线程到场锁资源的争夺,对列队的线程不公平,所以为非公平锁。
  公平锁在非公平锁的基础上进行判定,抢到锁的线程如果不是阻塞链表头部的线程,则将其阻塞,放入阻塞链表末了列队期待。
  CAS自旋消耗CPU资源,且存在ABA问题,可以通过版本号去办理。
参考:Synchronized的花花肠子AQS的傀儡之Lock锁
 
聚集源码(快手/字节/阿里/boss直聘/携程/猎聘/京东)

  问:arrayList底层实现。HashMap1.7和1.8有什么区别。ConcurrentHashMap1.7和1.8有什么区别。
  答:arrayList底层接纳数组实现,默认长度10,1.5倍扩容。扩容需要数组的拷贝,删除需要移位,由于共享全局的数组,且其对数组的维护没有加锁,故非线程安全。存在fail-fast机制。
  HashMap1.7接纳数组+单向链表实现,初始容量16,负载因子0.75,允许存放key为空的数据(放在下标为0处),将key的hashcode值通过hash算法得出hash值,再将hash值与数组的长度按位与,得出下标,在下标处以头插法存放数据。由于没有对共享的数组加锁,非线程安全。2倍扩容,高并发下,由于头插法和非线程安全,可能导致链表死循环。HashTable是在HashMap的基础上,对其所有方法加sync包管线程安全,但HashTable不允许出现空值。
  HashMap1.8接纳数组+单向链表+红黑树实现。当单条链表的长度大于8且聚集元素超过64,会将这条链表转为红黑树,提升查询效率(链表时间复杂度为O(n),红黑树时间复杂度为O(log(n))。链表的插入方式改为尾插法。
  ConcurrentHashMap1.7底层接纳16个segment对象,segment和hashTable雷同,所以ConcurrentHashMap1.7包管线程安全的方式接纳分段锁,从而提升效率。
  ConcurrentHashMap1.8是在HashMap1.8基础上优化,对其所有非线程安全的操纵加锁处置惩罚。比如数组初始化和扩容,接纳CAS方式包管线程安全,对于单个下标下数据的存放,接纳sync锁起来,粒度更细。且当某个线程访问ConcurrentHashMap时,如果发现正在扩容,不会阻塞这个线程,而是资助ConcurrentHashMap完成扩容。
 
Java内存结构(快手/阿里/猎聘/好未来/京东/当当)

  问:类加载过程。双亲委派如何冲破。Java内存如何分别。常用的垃圾接纳器和垃圾接纳算法有哪些。
  答:类加载器通过编译、链接(验证、准备、分析)、初始化的操纵将class文件加载至Java内存中。
  双亲委派是指Java查找类的方式自上而下(启动类加载器、扩展类加载器、应用类加载器、自界说类加载器)。类加载器中有个findClass方法,递归向上查找上级类加载器,我们只需要绕过这个方法即可。
  Java内存机构分为:
  线程独占:栈(由栈帧组成,每一个栈帧就是一个方法。栈帧由局部变量表、操纵数栈、动态链接、返回地点组成)、步伐计数器(记载当前线程运行的位置)和当地方法栈(被native修饰,与C通讯)。
  线程共享:元空间(存放静态信息,类的字节码信息)、堆(创建的对象、字符串常量池)。
  堆内存:以分代算法分别为新生代和老年代。新生代又分为eden区(刚创建的对象)、from和to区(复制算法,用于年龄累加)。
  常用垃圾接纳算法有:标志清除、标志整理、复制、GCROOT。
  常用垃圾接纳器有:CMS、G1、Servier New/Servier Old
参考:被解刨的JVM
 
Java内存模子和volatile(快手/阿里/滴滴/携程/猎聘/京东/当当)

  问:先容下Java内存模子。Volatile如何包管内存可见的。
  答:Java内存模子分为主内存和工作内存(当地内存)。主内存存放全局共享变量数据,而工作内存存放这些共享变量的副本数据。每一个线程都会开发自己的工作内存。而Volatile修饰的变量通过MESI缓存一致性协议去包管一致性,即当变量修改,CPU总线嗅探机制会捕捉到它的变动,将其内容刷新至主内存,然后将别的工作内存的变量值置为无效,使得别的工作内存变量的值重新从主内存获取此变量值,包管一致。
参考:volatile与JMM的那些恩怨情仇
 
mybatis组件(快手/阿里)

  问:先容下Mybatis的原理。
  答:详情参考通俗易懂的Mybatis工作原理
 
spring组件(快手/字节/阿里/猎聘/好未来/京东/当当)

  问:先容下bean的生命周期。AOP如何实现的。如何办理循环依赖问题。声明式事务嵌套会发生什么问题。
  答:spring容器启动时,会初始化spring的各种组件:beanFactory、后置处置惩罚器、event与listener的绑定、初始化单例对象等。初始化单例对象时,反射其无参构造创建对象,然后进行属性赋值,查抄aware的依赖信息,执行后置处置惩罚器的前置操纵,执行自界说init方法,执行后置处置惩罚器后置处置惩罚。
  Spring通过三级缓存来办理单例的循环依赖,多例需要我们通过@primy或@qualify手动声明。
  AOP也是后置处置惩罚器的一种特殊实现。在后置处置惩罚中判定当前类是否实现接口,进而判定使用JDK动态代理照旧CGLIB动态代理,在对应的invoke中,通过责任链+递归的方式去依次执行切面的通知,最后执行目的方法。
  事务是一种特殊的通知,通过手动try catch来提交或回滚事务。
  当同类的事务嵌套时,this会使其失效。不同类事务嵌套,按照事务传播机制进行判定是否回滚。
 
springMVC组件(快手/阿里)

  问:拦截器的原理。
  答:springMVC的焦点类DispatherServlet的doDispath方法中为springMVC的执行原理,通过模版方法获取所有的拦截器,循环调用执行其三个抽象方法的实现。

三、主流技能

  以简历为例。
Redis(快手/字节/阿里/滴滴/boss直聘/携程/猎聘/好未来/京东/美团/当当)

  问:redis的数据结构。淘汰计谋。恒久化机制。集群方式。分布式锁。分片原理。缓存击穿/穿透/雪崩的原因息争决方案。
  答:参考步伐猿必备的Redis常见功能知识点,这些你都会吗?
 
Zookeeper(滴滴/京东/当当)

  问:ZK节点的范例。分布式锁原理。集群原理。Base和CAP的理论。
  答:节点范例分为有序暂时、无序暂时、有序恒久和无序恒久。支持权限认证,有着强大的事件通知功能。
  分布式锁分为暂时节点和有序暂时节点。前者存在羊群效应,后者雷同于Java的lock公平锁。
  集群要包管过半机制,通过MVCC和myid来选取事务ID最大、性能最好的节点当选leader,其数据同步遵循最终一致性(BASE),包管CAP中的CP,通过过半机制包管脑裂现象。
 
消息队列(快手/阿里/滴滴/猎聘/好未来/京东/美团/当当)

  问:MQ的工作方式有哪些。如何确保消息不丢失。如何办理重复消费。如何办理顺序消费。基于mq办理分布式事务。
  答:工作方式有点对点、能者多劳(消费者手动ACK)、发布订阅fanout、路由direct、含糊路由topic。
  消息不丢失:生产者投递消息乐成后,接纳confirm确保投递乐成;消费者消费消息后,手动ACK包管消费乐成;mq通过恒久化机制将消息恒久化至磁盘。
  重复消费:记载消息ID(雪花算法生成),消费消息前主动查询比对。
  顺序消费:多个消息通过key包管其落在同一台broker节点,然后使其被一个消费者消费。消费者在自己当地可接纳内存队列的方式提升消费效率。
  分布式事务:阿里的rocketMQ支持事务消息,通过两端提交协议去包管事务到场者的事务提交或回滚的一致性。
 
微服务(快手/字节/阿里/滴滴/携程/好未来/京东/美团)

  问:什么是服务治理。服务注册和发现的过程。网关的工作原理。如何做到当地负载平衡。服务熔断器的原理。
  答:服务治理就是管理服务之间调用杂乱的现象。注册中心统一管理服务地点,其他服务启动时将自身的信息以服务名称的键值对投递注册至注册中心,若想要获取别的服务地点,也是通过别的服务名称去注册中心查找到集群地点,然后当地通过负载平衡算法进行轮询。
  熔断器可以实现服务降级、熔断和线程隔离等功能。当此接口被熔断器掩护时,只要请求时长超过预设时间,就会走指定的方法进行响应,实现降级处置惩罚。熔断是指如果请求此接口的线程数太多,则会走服务降级处置惩罚。我们也可以对热点接口实现线程池隔离的方式提升性能,不同的接口接纳不同的线程池处置惩罚。
 
Netty(字节/阿里/boss直聘/携程/猎聘/好未来/京东/美团)

  问:netty的作用。什么是NIO多路复用。为什么NIO在LINUX比WINDOWS性能要好。
  答:netty本质上就是对NIO的多路复用做了一层包装。IO模子中分为BIO(获取不到就阻塞),NIO(获取不到不阻塞)和AIO(异步)。为了提升性能和低落CPU使用,接纳一个线程统一管理这些socket的IO,Windows中才selector去不绝的循环这些IO,但IO不一定每次循环都有数据,故会出现空轮询的情况;而linux接纳epoll的事件驱动回调,当socket的IO有数据时主动通知机制去获取数据,故效率更高。

四、数据库

  主要是mysql。
数据结构(快手/字节/阿里/滴滴/boss直聘/携程/猎聘/好未来/京东/美团)

  问:MySQL的索引使用什么数据结构。为什么使用B+树。
  答:mysql索引支持B树、B+树、Hash。默认接纳B+树,hash查询快,但对范围查询不友好,B树的非叶子节点存放了索引值和数据(或数据地点),导致其单个节点存放的索引值变少,树的高度提升,增加IO次数。B+树非叶子节点只存放索引值,故而树的高度小,IO次数少,且叶子节点是一条有序的链表,对范围查询友好。
参考:mysql定位和优化慢查询的方案
 
底层原理(滴滴/携程)

  问:mysql的redolog、undolog和binlog分别有什么作用。
  答:mysql默认接纳innodb作为存储引擎,innodb维护了一个buffer pool的缓冲池来缓存数据。当更新数据时,会先将数据通过随机IO的方式从磁盘读取至缓冲池,在更新缓冲池数据前,会将缓冲池的数据写入至undolog中,用于事务回滚;更新完缓冲池数据后,将缓冲池的数据写入redolog中,用于灾备的规复;然后将缓冲池的数据同步至物理磁盘,并记载在binlog日志,用于做主从复制或与mq同步。
参考:mysql查询和修改的底层原理
 
索引(快手/字节/阿里/滴滴/猎聘/好未来/京东/美团/当当)

  问:为什么索引可以提高查询效率。聚簇索引和非聚簇索引的区别。团结索引的使用方式。
  答:数据是按照索引的方式有序存放,如同我们的新华字典存放汉字一样。聚餐索引即主键索引,数据和索引存放在一个文件中,而非聚簇索引的叶子节点存放的是主键的ID。团结索引遵循最左原则。
参考:mysql定位和优化慢查询的方案
 
事务隔离级别(快手/阿里)

  问:事务隔离级别有哪些。
  答:读未提交(一个事务读到另一个事务未提交的数据,有脏读现象)、读已提交(一个事务读到另一个事务已经提交的数据,有不可重复度现象)、可重复读(事务之间通过MVCC隔离,但有幻读现象)、串行化(单线程)。
参考:mysql事务隔离级别以及MVCC的底层原理
 
sql优化(快手/字节/阿里/滴滴/猎聘/好未来/京东/美团/当当)

  问:项目中如何优化sql,以什么为标准,需要注意什么。
  答:以阿里开发手册为准,通过explain去输出sql的执行计划,将其type优化为range级别以上(至少为range),同时避免filesort的内存排序情况。
参考:mysql定位和优化慢查询的方案
 
欢迎各人和帝都的雁积极互动,头脑交换会比个人笃志苦学更有效!共勉!
公众号:帝都的雁

 
 

来源:https://blog.csdn.net/yxh13521338301/article/details/111991627
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )