Java开发面试题

昨天面试了一家创业型公司,感觉还是有些挑战的,以下答案是我根据自己的理解写的,有些当时也没答出来,后面查资料了,发出来大家看看,如有问题,欢迎指正。

1、数组扩容机制、HashMap扩容机制,java8的hashmap为何要加红黑树

数组的扩容机制以ArrayList为例,因为ArrayList底层数据结构就是数组,在默认情况下ArrayList的容量是10,当存储的元素达到上限时会启动扩容,扩容的逻辑是在原来容量的基础上加上原容量的一半,比如默认情况下第一次扩容后容量变为10+10/2 = 15,第二次变为15+15/2 = 22,第三次为22+22/2 = 33,以此类推

HashMap默认容量是16,默认扩容的阈值是容量的0.75,也就是当存储的元素到达12就开始扩容,每次扩容是前一次容量的2倍,添加红黑树是因为存储的对象可以重写hashcode函数,可能导致大部分元素以链表形式存储,查找效率低下

2、openfeign异常丢失问题怎么解决

首先服务提供方不能将异常通过try catch吞掉,其次在feign客户端的注解中添加fallbackFactory参数指定专门的Bean来处理异常信息

3、JVM的垃圾回收器有哪些

Serial(串行) :适合于单核处理器,年轻代使用复制算法,老年代使用标记整理算法

ParNew(并行年轻代收集器) :多线程,其他同Serial

CMS(并发标记清除):减少停顿时间,适合对响应时间有较高要求的应用,年轻代使用Parallel GC配置,老年代使用并发标记-清除算法

G1(Garbage First):平衡吞吐量与停顿时间,适合大堆内存应用。使用分区和并行算法将堆划分为多个区域进行管理

ZGC:用于需极低暂停时间的大内存应用,使用分区和并行算法,支持多线程并发标记和并发重定位

4、MySQL如何优化子查询

使用左连接代替子查询,用查询结果数据量较少的表驱动数据量较大的表

物化子查询结果,在子查询返回的结果集较小且多次使用时,考虑使用派生或临时表来存储子查询结果,减少重复计算

优化索引,确保响应的查询字段有合适的索引并且被使用了

使用EXPALIN 分析查询计划帮助理解子查询还可以怎么优化

5、SpringMVC的启动流程

Web容器启动后DispatcherServlet根据web.xml中的监听器加载Spring应用的上下文,然后spring加载配置好的监听器、配置文件、上下文环境、拦截器、视图解析器等信息,然后创建WebApplicationContext,创建IOC容器将Bean创建好,初始化HandlerMapping和HandlerAdapter

6、RBAC权限的理解,新版中为何加入了用户组管理,是为什么

RBAC是基于角色的访问控制,权限与角色相关联,而用户通过成为相应的角色来获得权限,使得管理大量用户的权限变得更加简单高效

加入用户组概念是为了进一步提高权限管理的灵活性和效率,通常指具有相似权限需求的用户集合。简化了权限管理、提高可维护性、实现更细粒度的权限控制、易于审计和合规、支持动态变化

7、APP中加入类似微信的聊天功能如何实现

前端使用uniapp或React实现页面排版,然后与后端交互使用RESTful API和WebSocket通信,使用OAuth2.0进行三方登录/注册,JWT来验证用户身份

后端使用netty nio来构建高效的io通信,使用mongodb存储聊天记录和其他非结构化数据,MySQL存储用户信息等结构化数据,Redis做缓存、Kafka进行消息异步处理

8、如何处理WebSocket的数据丢失和顺序错乱的问题

针对数据丢失:

使用确认机制,发送端将消息发送后等待服务器的确认,如未收到确认或超时则重发数据,可为每个消息分配一个唯一的序列号,接收方通过序列号判断是否收到了所有消息

心跳机制:定期发送心跳包来保存连接活跃,并检测连接是否仍然可用

针对顺序错乱:

消息排序:在发送端为每个消息分配一个唯一且递增的序列号,并在接收到按照序列号排序

消息队列:将消息发送到MQ的同一个分区中,确保接收端按照正确的顺序处理消息

持久化存储:对于关键的消息,可以在发送之前先存储在数据库中,确保即使发生故障也能从存储中恢复

9、说说Http和WebSocket的区别

Http设计目的是用于Web网页浏览,是一种无状态,基于请求/响应模式的协议

WebSocket设计用于实现实时双向通信,是一种持久连接协议,支持双向数据传输

WenSocket的数据传输格式更加轻量级,消息头相较于Http小很多且实时性更好,服务器端可主动给客户端推送消息

10、TCP和UDP的区别

TCP是面向连接的协议,需要经过三次握手才能成功建立通信,提供可靠的数据传输。通过确认机制、重传机制、流量控制和拥塞控制等手段,确保数据能准确无误地从发送端传输到接收端,保证数据有序传输,头部开销为20字节,适用与可靠性要求较高的场景,如文件传输、电子邮件等

UDP是无连接协议,通信双方不需要事先建立连接,直接将数据封装成数据报进行发送,可能会出现乱序、丢失等情况,没有流量和拥塞控制,头部开销仅有8个字节,适用于对实时性要求较高但可靠性要求较低的场景,如实时视频会议,在线游戏和网络语音通话等

11、HTTP和HTTPS的区别

HTTP使用明文传输,容易被窃听、篡改和劫持,连接相对简单,客户端发送请求,服务端响应请求,默认80端口,无需证书,没有加密/解密和证书验证的开销,性能相对较高

HTTPS在HTTP的基础上加入了SSL/TLS安全协议,通过加密、验证服务器身份等方式确保数据传输的安全性,连接需要在HTTP的基础上再加上SSL/TLS握手,协商加密参数、算法和密钥等,默认443端口,需要向证书颁发机构申请数字证书用于验证服务器的身份,含有加密/解密和证书验证的开销,比HTTP稍慢

12、MySQL主从同步不一致如何处理

首先确认主从不一致的原因,如果是数据库版本、表引擎或配置等原因可按照原因进行解决,如果是网络原因则检查主从同步状态、检查网络连接情况、调整网络参数或者控制最近写入的数据从主库读取,如不一致会严重影响业务的运行应及时通知运维和业务人员,提供详细的问题描述和影响范围,以便团队做出决策。

13、缓存穿透如何处理

缓存空对象,从DB查不到的数据通过key缓存一个空对象,设置一个较短的过期时间,实现简单

布隆过滤器,写入数据时将数据的key通过多个哈希函数映射到一个位数组中,可以过滤掉一定不存在的数据,但存在误判,可能会将一些不存在的数据判断为存在。

加锁,在缓存失效时仅允许一个线程读取数据库然后回填缓存,其他线程设置带超时时间的阻塞

14、Redis和MongoDB的异同

Redis是内存型的键值对存储数据库,支持多种数据结构,如字符串、哈希表、列表、集合和有序集合,数据主要存储在内存中,可通过配置持久化到磁盘防止数据丢失,主要用于将经常访问的数据缓存在Redis中,以减少数据库的压力达到提高响应速度的目的。查询操作相对简单。

MongoDB是一种文档型数据库,通过类JSON文档存储,每个文档可以有不同的结构(可嵌套对象和数组)、非常灵活、数据存储在磁盘上,也有内存缓存机制来提高性能。有类似SQL的查询语言,可进行条件查询、排序、分页聚合等,适合大数据存储非结构化或半结构化数据,性能相较于Redis来说稍慢一些。

15、存储/获取1G的电影名称及相关数据是放Redis好还是MongoDB好

存储在MongoDB更好,原因是MongoDB支持较复杂的过滤、聚合等查询,MongoDB将数据存储在磁盘上,提供多种数据备份和恢复机制,而Redis的持久化相对简单,主要为了服务重启时恢复数据,且存在数据丢失风险,而且Redis在读取大Key时其他读写会被阻塞,影响整体的效率

16、JVM有哪几类启动参数

标准选项:

类路径 -classpath

运行jar包 -jar

主类名 <main-class>

代理类 -agentlib

系统属性 -D<name>=<value>

安全策略 -Djava.security.policy=

国际化 -Duser.language

非标准选项:

内存相关:-Xms -Xmx -Xmn XX:MaxMetaspaceSize

垃圾回收相关:-XX:+UseSerialGC  XX:+UseParallelGC -XX:+UseConcMarkSweepGC  -XX:+UseG1GC -XX:+PrintGCDetails

线程相关:-Xss -XX:ThreadStackSize=

诊断和调试:-Xdebug -Xrunjdwp:transport=

其他:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath

17、一个外部的类是否可以被Spring监听到

默认情况下无法监听,但可以将外部类设置为Bean对象,类似线程池或对象存储配置类对象通过使用配置注解就可以进行监听

18、垃圾收集器如何判断是否可以回收对象

通过引用计数和可达性分析算法,主流的JVM版本一般使用可达性分析算法,因为引用计数无法解决循环引用的问题

19、MySQL都有哪些数据类型

根据MySQL版本略有不同,下面列出MySQL8版本支持的

数值型有 tinyint smallint mediuint int bigint

浮点类型 float double real

定点类型 decimal number

日期时间 date time datetime timestamp year

字符串 char varchar text binary varbinary  tinytext tinyblob longtext longblob enum set json

位 bit

地图坐标 point geometry geometrycollection

空置 NULL

20、Redis和Zookeeper实现分布式锁的原理和异同

Redis是利用单线程原子性处理set命令的机制实现分布式锁(根据版本不同使用lua或set nx px,或直接使用包装好的工具redssion),zookeeper是利用临时顺序节点,判断自己是否为最小序号,是则加锁成功否则失败,需监控节点路径,当锁是否时可以收到通知

释放锁:Redis判断key的值是否为当前线程设置的值决定是否可删除,通过lua或redssion实现原子性,zookeeper可以在线程执行完业务逻辑时删除对应临时节点,zookeeper会通知其他线程锁已释放

21、一个对象被标记为垃圾后就一定会被回收吗

不一定,如果对象被标记为垃圾后,在finalize()方法中重新与引用链上的对象建立了关联,那么这个对象就会被移除可回收集合,从而不会被回收。

如当前内存压力不大,当前正在运行其他重要的操作时暂时也不会被回收

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值