一杯茶,一支烟,出了Bug,冰火两重天;带你领略这份2023年J
HashMap面试题
HashMap与HashTable的区别
1.HashMap线程不安全 HashTable 线程是安全的采用synchronized
2.HashMap允许存放key 为null HashTable 不允许存放key 为null
3.在多线程的情况下,推荐使用ConcurrentHashMap 线程安全 且效率非常高
HashMap底层是如何实现的
在HashMap1.7版本中底层是基于数组+链表实现的,如果发生Hash冲突概率
比较大,会存放到同一个链表中,链表如果过长 会从头查询到尾部 效率非常低。
所以在HashMap1.8版本 (数组容量>=64&链表长度大于8) 就会将该链表转化红黑树。
HashMap根据Key查询时间复杂度?
1.Key没有产生冲突 时间复杂度是为o(1); 只需要查询一次
2.Key产生冲突 采用链表存放则为O(N) 从头查询到尾部
3.key产生冲突采用红黑树存放则为O(LogN)
HashMap底层是有序存放的吗?
是无序的,因为Hash 算法是散列计算的 没有顺序,如果需要顺序
可以使用LinkedHashMap集合采用双向链表存放。
HashMap7扩容产生死循环问题有了解过吗?
其实这个JDK官方不承认这个bug,因为HashMap本身是线程不安全的,不推荐在
多线程的情况下使用,是早期阿里一名员工 发生在多线程 的情况下使用HashMap1.7 扩容会发生死循环问题,因为HashMap1.7 采用头插入法 后来在在HashMap1.8 改为尾插法 。
如果是在多线程的情况下 推荐使用ConcurrentHashMap
HashMap Key 为null 存放在 什么位置
存放在数组 index为0的位置。
ConcurrentHashMap 底层是如何实现?
1.传统方式 使用HashTable保证线程问题,是采用synchronized锁将整个HashTable中的数组锁住,
在多个线程中只允许一个线程访问Put或者Get,效率非常低,但是能够保证线程安全问题。
2.多线程的情况下 JDK官方推荐使用ConcurrentHashMap
ConcurrentHashMap 1.7 采用分段锁设计 底层实现原理:数组+Segments分段锁+HashEntry链表实现
大致原理就是将一个大的HashMap 分成n多个不同的小的HashTable
不同的key 计算index 如果没有发生冲突 则存放到不同的小的HashTable中 ,从而可以实现多线程
同时做put操作,但是如果多个线程同时put操作 key 发生了index冲突落到同一个小的HashTable中
还是会发生竞争锁。
3.ConcurrentHashMap 1.7 采用 Lock锁+CAS乐观锁+UNSAFE类 里面有实现 类似于synchronized
锁的升级过程。
4.ConcurrentHashMap 1.8版本 put操作 取消segment分段设计 直接使用Node数组来保存数据
index没有发生冲突使用cas锁 index 如果发生冲突则 使用 synchronized
分布式解决方案
请问你在生产环境中,如何搜索日志的呢?
回答:
- 传统的方式采用tail 搜索文件日志,如果服务器是集群的
使用tail 指令搜索日志效率是非常低; - 所有我们构建分布式ELK+Kafka采集日志 ,统一将我们的日志输出到
ES中,通过可视化界面查询。
3.或者整合skywalking监控服务报警,直接通过skywalking定位服务追踪链
报错信息。
4.在一些较大的互联网企业中,保证服务器端安全性,生产环境一般是不允许直接连接生产环境
服务器,而是通过日志采集系统查看日志。
生产环境中,你遇到了报错的问题 你是如何定位的?
回答:
- 传统的方式 在生产环境中遇到报错问题,我们是通过搜索日志的方式,排查具体的错误。
2.采用aop形式拦截系统错误日志,在将这些错误日志调用微信公众号接口 主动告诉给我们的开发人员
生产环境发生了故障。 - 我们公司采用apm系统 skywalking ,监控整个微服务 如果服务在一段时间
内发生了故障或者报错 会主动调用微信模板接口通知给开发人员 生产环境发生了故障。在通过skywalking 追踪 链可以直接查看到具体的错误信息内容
调用接口的时候,如果服务器端一直没有及时响应 怎么解决?
im1.如果调用接口发生了响应延迟:是因为我们http请求是采用同步的形式,基于请求与响应模型如果服务器端没有及时响应给客户端,客户端就会认为接口超时,接口发生了超时客户端会不断重试 ,重试的过程中 会导致 幂等性问题
幂等性问题(需要保证业务唯一性。)
2.如果接口响应非常慢,就需要对代码做优化例如 加上缓存减轻db查询压力、减少GC回收频率
2.如果接口代码在怎么优化 就是执行非常耗时时间,因为采用mq异步的形式 不能够使用 同步形式。
举例子:接口代码里面 需要调用非常多接口 在响应客户端
接口代码:
1.调用征信报告接口---15s-30s
生产环境服务器宕机,如何解决呢?
- 我们公司生产环境,会对我们服务器 实现多个节点集群,如果某台服务器
发生了宕机 会自动实现故障转移,保证服务的高可用。
- 如果服务器宕机 我们可以在服务器上安装keepalived 监听java进程,如果该java进程发生了宕机 会自动尝试重启该java进程,这是属于软件层面。如果是物理机器比如关机了,可以使用硬件方式自动重启服务器 例如向日葵
3.如果服务器发生了宕机,尝试重启n多次还是失败,我们可以使用容器快速动态的实现扩容(docker或者k8s)
4.重启该服务,如果重启多次还是失败 则会发送短信模板的形式通知给运维人员。
注意:千万不要回答 直接重启服务器端。
SpringCloud
为什么不选择dubbo?却选择SpringCloud?
- dubbo 属于RPC框架;
- SpringCloud 不属于RPC框架,属于微服务全家桶框架,提供非常多
在分布式微服务架构中遇到难题
2.1服务治理---nacos eureka zk
2.2分布式配置中心 nacos springcloud config 携程阿波罗
3.3分布式事务 lcn(被淘汰)、seata
3.4服务追踪 zipkin /skwalking
3.5服务保护 hystry、sentinel
3.6微服务网关 zuul gateway
....
feign客户端 rpc框架 类似于 dubbo
dubbo rpc框架 底层 netty 封装dubbo 协议
整合分布式解决方案---自己单独整合 单一功能
而springcloud 提供了成熟一套微服务解决方案。
dubbox 属于当当网提供 http协议接口
feign 调用接口 http协议
开放平台(阿里、腾讯) http协议 跨平台
dubbo与feign 都是面向接口 调用 底层思想原理都是相同。
底层采用动态代理技术。
服务正在发布中?如何不影响用户使用?
服务正在发布中,该jar中正在启动...
客户端访问的时候,一直阻塞等待。
1.使用nginx 故障转移即可。
2.灰度发布 先发布一小部分 如果没有问题 在让所有用户都可以访问。
灰度发布 nginx+nacos gateway+nacos(推荐)
对方调用你接口响应比较慢?你会怎么排查?
项目搭建服务追踪监控系统
1.zipkin /skwalking 通过平台形式可以查询该接口响应速度时间。
对方调用你接口响应比较慢 多个维度思考?
带宽→服务处理(cpu)→数据库或者Redis→网络IO操作(例如调用别人接口)
1.走外网传输数据 会有带宽限制呢
2.请求如果达到服务端,服务足够线程处理请求 如果服务器没有足够的线程
处理该请求? 导致客户端会阻塞等待?
解决办法:
1.调整最大线程数
2.调整最大线程数 治标不治本,对接口做限流操作 例如服务器端没有足够
线程处理的时候(策略服务熔断 降级 限流策略。)
3.服务cpu处理性能(多核cpu) 体现多线程同时处理 降低cpu上下文切换的次数。
如果发生了上下文切换会导致其他的线程 会短暂阻塞 有需要从新被cpu调度。
4.判断sql语句查询是否比较慢、做mysql调优 快速响应结果
5.网络IO操作(例如调用别人接口)代码在怎么优化还是比较慢,将耗时的操作
采用异步的形式处理 例如多线程(消耗cpu的资源) 建议使用MQ。
开发者不小心删除了生产环境数据?怎么恢复呢?
1.正常的情况下 在生产环境中 没有delete或者rm -rf 通过update
隐藏的形式, 后期淘汰策略删除。
2.构建mysql主从集群环境 可以通过备份节点恢复数据,一主一从。
3.如果执行delete 我们是可以通过binlog 快速恢复数据。
你在开发过程中,遇到哪些难题?你是怎么解决的呢
如果在面试的过程中被面试官问到:你在开发过程中,遇到哪些难题?
不要答:空指针异常、常见错误异常。
遇到问题→你是如何分析的?→如何排查的?→最终是怎么解决的?
1.分布式事务
2.分布式幂等
例如 我们公司提供了一个接口,被其他公司进行调用。
他的公司在调用我们公司接口的过程中,我们的接口响应超时了,
最终触发了客户端重试了,重试的过程当中请求的参数都是相同的,导致我们接口
会重复执行业务逻辑。
解决办法: 全局id 业务上防重复、 在db层面去重复 例如 创建唯一约束
3.定时任务调度
例如:我们项目在生产环境中做定时任务,如果集群的情况下 定时任务重复执行。
解决该问题
1.在打jar包的时候 加上一个开关 只让一个jar包执行定时任务
2.整合分布式任务调度平台 xxljob 最终分片执行 定时任务集群的执行
定时任务1 【】跑批 1-10万 定时任务2 11-20万
4.数据同步延迟问题
我们公司 使用canal 解决mysql与redis+kafka 数据同步问题
发现就是在并发的情况下同步非常延迟,我们整合kafka分区模型
根据每张表都有自己独立的topic主题,每个topic 主题有自己独立
分区 每个分区有自己独立消费者 ,解决消息顺序一致性问题。
6.安全性问题
7生产环境发生cpu飙高、内存泄漏
.......真实业务场景当中遇到难题