【求职面试】大厂必问面试题(JAVA)

知识既要又深度,又要有广度,更重要的是平时的积累和能够运用到实际工作中去!总结了一些java高级程序员面试过程中常见面试,温故而知新。回答有详有略,如有问题,欢迎指正改进。
1,请描述一下Spring的Bean的加载过程?
答:
Spring的bean的加载过程主要分为如下几个阶段:获取beanname,合并bean,实例化,属性填充,初始化,获取最终的bean
2,如何预防redis雪崩(缓存挂掉了如何保证系统可用)
①redis自身高可用,redis主从,哨兵,redis cluster
②应用自身设置二级缓存,缓解redis压力
③设置网关程序,进行限流,熔断处理
3,如何预防redis穿透(恶意请求越过缓存直击数据库)
①从应用机制上变更,例如如果从数据库中没有查到,就将请求作为临时值写到缓存中,这样下次同样的恶意请求进来,就可以直接读缓存,不会读数据库
4,如何预防redis击穿(热点数据失效瞬间请求,直击数据库)
①同上,从应用机制上变更,例如如果从数据库中没有查到,就将请求作为临时值写到缓存中,这样下次同样的恶意请求进来,就可以直接读缓存,不会读数据库
②若热点数据不会发生更新,则设置其为永不过期
③若缓存的数据更新频繁或者缓存刷新的流程耗时较长的情况下,可以利用定时线程在缓存过期前主动的重新构建缓存或者延后缓存的过期时间,以保证所有的请求能一直访问到对应的缓存。
5,Java集合:HashMap和ConcurrentHashMap,平时最好有读一些源码,最好知道每个参数为什么设置成这么大?有什么好处?
答:
HashMap是一种key-value的数据结构,在jdk1.8以前是数组+链表实现,在jdk1.8之后引入了红黑树(自平衡二叉树)
HashMap的数组初始默认长度是16,我们也称该数组为hash桶,数组允许一个key是null,允许多个value是null
Haspmap的put方法,put一个数据时,先根据其hash值取模算出其在数组中的下标,然后将其放到对应下标的数组节点中,如果该节点已经有值了,则连接到数组节点上的链表节点中,插入方式(1.7头插,1.8尾插)
Get方法和put方法类似,也是通过hash值取模得到下标,然后再遍历链表去找对应的值
值得注意的是,如果数组链表的节点长度大于8了,链表则会转为红黑树
6,JUC包相关内容
答:
JUC包包含了许多java并发编程的常用工具类
Volatile关键字:
当多个线程共享数据资源时,为了保证内存中的数据是可见的,可以使用volatile关键字,是一种轻量级的同步策略
不具备“互斥性”,不能保障变量的“原子性”
CAS算法:
CAS(比较并交换)就是一种非阻塞算法实现,也是一种乐观锁技术,他能在不使用锁的情况下实现多线程安全,所以CAS也是一种无锁算法
ConcurrentHashMap:
多线程下HashMap是不安全的(死循环),concurrentHashMap采用分段锁技术,1.8采用CAS+Synchronized
同步锁:
Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的。
读写锁:
读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。
线程池:
创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时 候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。
7,死锁,阻塞,自旋的了解
答:
死锁是在两个对象拥有一份资源的情况下申请另一份资源,而另一份资源恰好又是这两个对象分别持有的,导致两个对象无法完成操作,且所持资源无法释放。
阻塞是由于资源不足引起的排队等待现象。
自旋锁(spinlock)是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环
8,描述一下JVM内存模型以及各个区域的用途
答:
线程共享:
堆(heap space),堆内存是JVM中最大的一块,有年轻代和老年代组成,而年轻代又分为三分部分,Eden区,From Survivor,To Survivor,默认情况下按照8:1:1来分配
方法区(Method area),存储类信息、常量、静态变量等数据,是线程共享的区域
线程私有:
程序计数器(Program counter Register),是一块较小的内存空间,是当前线程所执行的字节码的行号指示器
JVM栈(JVM stacks),也是线程私有的,生命周期与线程相同,每个方法被执行时都会创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息
本地方法栈(Native Mthod Stacks),为虚拟机使用的native方法服务
9,描述一下类的加载过程
答:
类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。
其中类加载过程包括加载、验证、准备、解析和初始化五个阶段,实例化
类加载器又有
启动类加载器
扩展类加载器
系统类加载器等等
10,说一说双亲委派模式
答:
类加载器收到加载请求,会把请求委托给父加载器加载,一直到启动类加载器
如果父加载器能处理,则通过父加载器加载,如果不能加载则抛出异常,并发送给子加载器加载
循环往复
11,常见的垃圾回收算法有哪些,垃圾收集器有哪些
答:
标记整理算法,标记清除算法,复制算法,分代收集算法
Serial收集器,G1收集器
(老年代)标记-清除:将内存中需要的对象进行标记,将标记可清除的对象清除掉缺点内存碎片
(新生代)复制算法:将内存等分,每次只使用一块儿,等这块儿用完了,将其存活的对象复制到另一块儿上去,保证了内存的连续,但是内存利用率太低了
(老年代)标记整理算法:跟标记清除类似,只是对象不直接清除,而是让所有存活对象都向一端移动,然后清理掉端边界以外的区域,缺点是效率低下
12,查看部署在linux主机上的应用的jvm内存情况命令
答:
1,打印dump栈(准确定位内存泄漏点)

jmap -dump:format=b,file=dump1 14614
2,观察jvm内存情况

jps
jstat -class xxxxx
3,看jstack锁(线程快照)

jstack pid > stack.log
13,描述一下Spring中bean的生命周期
答:
实例化,属性赋值,初始化,销毁
14,如何解决循环依赖
答:
在实例化一个bean的时候,是首先递归的实例化其所依赖的所有bean,直到某个bean没有依赖其他bean,此时就会将该实例返回,然后反递归的将获取到的bean设置为各个上层bean的属性
15,Spring是如何实现事务的
答:spring主要有两种控制事务的方式,编程式事务控制,声明式事务控制
编程式事务使用事务管理器,用的比较少
声明式事务一、基于TransactionProxyFactoryBean代理的声明式事务控制;二、使用AOP的声明式事务控制;三、基于@Transactional注解的声明式事务控制。
16,Spring的动态代理原理是什么
答:一种就是jdk动态代理, 另一种就是第三方的CGLIB的代理机制
17,Redis的常见集群模式请分别描述一下
答:
主从
集群分为主服务器和从服务器,从服务向主服务发起同步请求,主服务收到请求后开始生成快照文件,从服务器收到快照文件后丢弃原有文件,主服务器从生成快照文件开始,就开始记录写操作,完成快照传输后,将写操作也全部发送给从服务器,后续主服务器每次新增一笔写操作,就同步给从服务器一次。
哨兵
哨兵模式是主从模式的一种升级版,同时监听主从服务器,当主服务器挂掉,就推举从节点为主节点
Redis cluster
Redis cluster集群模式实现了redis集群高可用也实现了数据的分布式存储,集群中每个节点都拥有hash槽,根据节点个数,平分0-16383中的一段,当写入一个数据时,先根据crc16算法得到一个hash值,然后除以16384取余,得到的值落在那一段hash槽上,就将数据存放在哪一个节点上。Redis cluster集群如果主节点挂掉,会拉起从节点,如果同一个节点的主从节点都挂掉,则集群不可用,如果集群中超过半数的主节点ping不通一个节点,则认为该节点挂掉了。
18,Redis的常用数据类型
答:
String,List,hashmap,set,Zset
19,Redis的单线程模型
答:
Redis是单线程的,不止是出于性能上的考虑,而且内部使用了文件事件处理器,这个处理器是单线程的。
文件事件处理器分为:
①多个socket②IO多路复用程序③socket队列④文件事件分派器⑤事件处理器
而事件处理器又分为3个部分为:连接应答处理器、命令请求处理器、命令回复处理器。
20,Redis集群是如何保证数据一致性的
答:
从服务向主服务发起同步请求,主服务收到请求后开始生成快照文件,从服务器收到快照文件后丢弃原有文件,主服务器从生成快照文件开始,就开始记录写操作,完成快照传输后,将写操作也全部发送给从服务器,后续主服务器每次新增一笔写操作,就同步给从服务器一次。
21,Mysql是如何实现事务的
答:
事务的原子性是通过 undo log 来实现的
事务的持久性性是通过 redo log 来实现的
事务的隔离性是通过 (读写锁+MVCC)来实现的
而事务的一致性是通过原子性,持久性,隔离性联合起来实现的
22,Mysql集群模式(主从)你了解多少
答:
先说优点吧,优点可以进行读写分离,可以进行数据备份,保障数据安全
再说同步过程吧
①master在每个事务更新数据完成之前,会将这个操作 串行的写入binlog
②salve节点开启一个I/O线程,该线程在master开一个普通连接,进行binlog dump process,如果进度已经跟上了master,就进入休眠,等待master产生新的事件,I/O线程的最终目的是将这些事件写入到中继日志中
③sql thread会读取中继日志,并顺序执行日志中的sql事件,从而与主数据库中的数据保持一致
23,关于mongodb集群模式你了解多少
答:
分片模式:集群搭建在3台主机上,集群分为路由层,配置层和数据层,数据层进行了分片,能开分为了3个shard,每个shard有3个节点,主-从-仲裁,每个分片的节点交叉分布在3台主机上,单个节点挂掉了,不会影响整个集群
副本集模式:副本集模式是主从模式的一个升级,包括一个主节点和多个从节点,并且进行了读写分离,主节点负责写,从节点负责读,从节点从主节点进行同步,如果主节点挂掉,从节点就采用霸道选举的方式,选举一个从节点作为主节点,检测方式是用的心跳检测
24,描述一下kafka相关
答:
Kafka是一个高吞吐量的分布式发布订阅消息系统
重要的设定有consumer,producer,topic,partition,group,offset
Kafka的broker会记录消息消费的offset
Push-and-pull,推送消息和消费消息是异步的
一个topic可以有多个分区,具体消息进入哪一个分区是producer决定的
一条消息只会被订阅该topic的group中的一个consumer所消费
一个partion只会被一个consumer所消费,一个consumer可以消费多个partion,所以partion的数量要>=consumer
25,关于Netty,以及Netty的零拷贝是什么东西
答:
CPU不需要为数据在内存之间的拷贝消耗资源。而它通常是指计算机在网络上发送文件时,不需要将文件内容拷贝到用户空间(User Space)而直接在内核空间(Kernel Space)中传输到网络的方式
26,Netty的bio,nio,aio,架构设计怎么样子的?
答:
BIO 同步阻塞式IO
AIO 异步非阻塞IO
NIO 基于事件机制的IO
Netty是建立在NIO的基础上,netty在nio基础上又进行了更高层次的抽象,在netty里面,accept操作可以是单独的线程池来处理,读写操作又是其他的线程池来处理,而请求处理逻辑可以单独的线程池来处理,也可以是用和读写相同的线程池来处理。线程池中的每一个线程都是nio线程
27,算法:快排算法
答:
算法思想:
取待排序列中随机的一个元素,将元素左右分为两个部分,将小于这个元素的值放一边,大于元素的放另一边,循环往复,直至排序完成,指导思想,分而治之
算法实现:
先从数组右边找到一个比枢轴元素小的元素,将数组的第一个位置赋值为该元素;
再从数组的左边找到一个比枢轴元素大的元素,将从上面取元素的位置赋值为该值;
依次进行,直到左右相遇,把枢轴元素赋值到相遇位置
28,算法:二分法
答:
算法思想:
基于有序序列的查找
算法实现:
(1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
(2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。
(3)如果某一步数组为空,则表示找不到目标元素。
29,算法:堆排算法
答:
将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将它移走,然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次最大值。如此反复执行,就能得到一个有序序列了
30,算法:红黑树,二叉树,平衡二叉树
答:
二叉树:由根节点和左子树和右子树组成,可以有很多细分
满二叉树:叶子节点都在最底层,且除了叶子节点外,其他节点都有左右两个子节点
完全二叉树:叶子节点都在最低下两层,最后一层的叶子节点都靠左排列,且除了最后一层,其他层的节点都要达到最大
二叉查找树:要求对于任意节点,其左子树的节点都要小于这个节点,其右子树的节点都要大于这个节点
平衡二叉树:要求任何节点的左右子树的相差高度不能大于1,平衡二叉树必定是二叉查找树
红黑树(自平衡二叉树):
是一种特殊的平衡二叉树
根节点为黑色
每个叶子节点是黑色
如果一个节点是红色,那么他的子节点必须是黑色
如果一个节点是黑色,呢么从这个节点出发的所有路径上的黑色节点数量相同
31,算法:链表翻转
答:
创建一个新的链表,每次从待反转的单向链表上摘下来一个节点,放到新链表的头节点后面。
32,关于网络http,tcp,https,udp,7层网络协议等的相关知识
答:
网络7层协议:应用层,表达层,会话层,传输层,网络层,数据链路层,物理层
在tcp五层模型中,前三层又统称应用层
TCP和UDP区别:
①基于连接与无连接;
②对系统资源的要求(TCP较多,UDP少);
③UDP程序结构较简单;
④流模式与数据报模式 ;
⑤TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
HTTP、HTTPS:
http:建立在TCP协议之上的一种应用。最显著的特点是:客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
HTTPS:是以安全为目标的HTTP通道,是HTTP的安全版。https协议需要到ca申请证书;https 则是具有安全性的ssl加密传输协议;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议。
33,场景实现:抢红包
答:
准备工作:生成可抢红包,入队redis的list结构,命令为RPUSH
用户发出抢的请求:用户标识写入redis的Set中,命令SADD,返回1标识插入成功,可继续获取红包,返回0则为已抢,直接返回
获取红包:list出队一条红包数据,命令为LPOP,如果返回不为nil时,代表获取成功,继续下一步,反之则说明已抢完,返回
建立红包与用户的关系:构建红包与用户的关系对象,入队Redis的list,使用单独线程每秒尝试出队1000个(举例),批量存储到数据库中
34,简单描述一下AHAS
答:
应用高可用服务是一款专注于提高应用高可用能力的 SaaS 产品,包含架构感知、流量防护、故障演练和功能开关四大独立的功能模块
35,简单描述一下sentinel
答:
Sentinel是轻量级流量控制框架,面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性
36,如何在java中实现线程
答:
①继承java.lang.Thread类,重写run()方法来实现
②实现runnable接口,重写run()方法来实现
③实现Callable<>接口,重写call()方法
37,谈一谈你对kubernetes(k8s)的理解
答:
k8s是做容器编排的工具,由master和node组成,master包括kubeapi-service,ETCD,controller-mannager和scheduler几个部分,node包括docker,kube-proxy,kubelet组成;

由master的kube-api-service控制node,apiservice也负责对外交互,交互方式包括kubectl,
Webui,rest接口

Pod,包括docker容器和pause容器组成一个pod,是kubenetes调度的最小单位
Deployment,负责维持pod的数量
Service,多个pod抽象为一个service,负责请求的负载均衡,通常会通过服务名进行service之间的交互
38,RPC的理解
答:远程过程调用
· 首先客户端需要告诉服务器,需要调用的函数,这里函数和进程ID存在一个映射,客户端远程调用时,需要查一下函数,找到对应的ID,然后执行函数的代码。
· 客户端需要把本地参数传给远程函数,本地调用的过程中,直接压栈即可,但是在远程调用过程中不再同一个内存里,无法直接传递函数的参数,因此需要客户端把参数转换成字节流,传给服务端,然后服务端将字节流转换成自身能读取的格式,是一个序列化和反序列化的过程。
· 在微服务的设计中,一个服务A如果访问另一个Module下的服务B,可以采用HTTP REST传输数据,并在两个服务之间进行序列化和反序列化操作,服务B把执行结果返回过来。
· 由于HTTP在应用层中完成,整个通信的代价较高,远程过程调用中直接基于TCP进行远程调用,数据传输在传输层TCP层完成,更适合对效率要求比较高的场景,RPC主要依赖于客户端和服务端之间建立Socket链接进行,底层实现比REST更复杂。
39,定位线上问题的总体思路和方式
答:
①通过现有系统的监控和告警信息分析,如果有可视化的监控平台大盘及链路信息分析,也可以进行参考
②登录到线上主机上,分析主机系统情况,包括主机cpu,内存,磁盘空间,网络等系统参数情况,常见命令为top,free,df,vmstat等等
③通过jstatk命令,查看线程快照
④通过jmap命令查看dump日志,查看内存使用情况,并且可以通过GCeasy工具进行dump日志分析
⑤通过jstat名称查看内存使用,gc情况
⑥通过arthas进行java应用诊断,arthas是阿里开源的java应用问题诊断工具,对常见的线上问题进行方便快捷的定位,支持jdk1.6+并且通过命令行工具进行操作,通过java -jar+程序包名+pid启动,然后进行问题诊断,还可以输出火力图
40,Docker为什么比虚拟机更快
答:
①docker有比虚拟机更少的抽象层
②docker利用的是宿主机的内核
41,分布式锁方案zk和redis哪个更好
答:
分布式锁方案包括三种方式
①基于数据库 ②基于redis ③基于zookeeper
基于数据库的,是基于排它锁(悲观锁)和CAS乐观锁的,可能会存在锁表的情况发生
基于redis的,是基于命令关键字的锁表和添加失效时间
基于zookeeper的,是基于创建目录和删除目录的
在性能方面,redis>zk>mysql
在可靠性一致性方面,zk>redis>mysql
42,Spring IOC和AOP原理
答:
IOC 控制反转,工厂模式,建立对象不用new,用IOC容器进行创建
AOP面向切面,将重复的程序形成切面,基于注解调用,基于jdk动态代理和cglib动态代理实现。
43,服务发现的业内方式横向对比
答:
服务发现方式包括ERUEKA和CONSUL以及zk
Erueka是AP模式的,zk是CP模式的
服务发现分为客户端模式和服务端模式
Erueka是客户端模式

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值