玄武云一面二面(附我个人查的答案)
一面问了几个八股,还记得这些:
频繁gc怎么排查?
答:Full GC次数过多在新功能上线时较容易出现。Full GC较多的情况,主要有如下两个特征:
- 线上多个线程的CPU都接近100%,通过jstack命令可以看到这些线程主要是垃圾回收线程
- 通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加
具体操作步骤:
- 在shell使用top命令找到高占用CPU的进程
- 使用top -Hp [pid] 查看该进程的高占用CPU的线程
- 使用jstack命令查看为什么该线程耗费CPU最高
- 如果nid=0xa,而且是VM Thread,则说明这个高占用CPU的线程就是垃圾回收线程
- 到这里基本可以确定,系统卡顿或者CPU占用率高是由于频繁GC引起的。
- 使用jstat -gcutil 可以查看GC情况,其中的FGC指的是Full GC次数,如果次数很高并且还在不断增长,则说明频繁GC的原因可能是发生了内存溢出(在这里,很可能是服务一次加载了很大的对象或者很多的对象,导致内存不够,或者很多没用的死数据或者对象(该对象依然可达)仍然驻留在内存中)。
- 接下来要查看是哪些对象导致的内存溢出,这个可以通过jmat命令,制作当前的堆Dump文件,用eclipse的mat工具或者Java VisualVM进行可视化分析,如图,可以看到最右的Percentage来确定目前占用堆内存最多的对象。这个对象最有可能造成了内存溢出。
8.另外,我们也要排除,有些我们引入的依赖包可能会显式调用System.gc(),导致GC次数上升。这种情况,在上面dump出来的文件中,会有关于GC调用的原因(如果是[Full GC(System.gc())],说明是被显式调用,否则就是[GC(Allocation Failure)],这种是jvm自己调用)所以,在这里可以排除。如果是显式调用,我们添加 -XX:+DisableExplicitGC
来禁用JVM对显式GC的响应。
9.排除了上面的情况之后,基本可以确定是内存溢出导致的频繁GC。在这里,需要检查业务代码,对一些用不到的数据和对象进行手动的清除,另外把同时处理大量数据的逻辑改成分批分页进行。如果实在改不了逻辑,说明该做分布式了,或者加服务器内存。
cpu跑满怎么排查?
- 类似上面,而且CPU跑满经常也是由于频繁GC,不然就是代码中的耗时逻辑。这里先用top命令查看高耗CPU的线程,然后用jstack打印该线程的堆栈信息,如果是VM Thread那说明是频繁GC导致的,如果是普通的业务线程比较耗时,那么你可以看到目前线程卡在业务代码的哪个位置上
OOM,内存不足怎么排查?
- 跟上面一样,内存问题用jmat,其他问题用jstack
二面:
操作系统的调度算法,抢占式和非抢占式的优缺点
操作系统的调度算法(这里我把作业调度和进程调度混起来了)有:
- 先来先服务FCFS算法
- 短作业优先SJF算法,有抢占式和非抢占式两种
- 优先级调度算法(Priority-scheduling algorithm),有抢占式和非抢占式两种
- 高响应比优先调度算法(Highest Response Ratio Next,动态优先级)
- 时间片轮转
- 多级反馈队列调度算法
- ...
抢占式的优点是,能够保证高优先级的,或者说先序的线程充分执行,从而能保证系统的高响应性,更加灵活,实现人机交互或者实时调度。当然缺点就是1.线程切换(进程切换)性能开销,涉及上下文的保存和加载这些的2.低优先级的线程可能一直执行不了,然后饿死3.系统复杂度上升。
非抢占式优点是,保证公平,大家基本都能执行,不会饿死。线程切换少,性能开销少,系统简单。缺点就是响应性不足,人机交互很难受。
TCP可靠传输保障的实现
握手与挥手机制,应答,重传,流量控制,拥塞控制,还有数据包头的设计(用seq规定数据包的顺序)。大概是这几个方面,详细请参考小林。
插播一条顺丰的面经。TCP三次握手的原因是确定客户端和服务端都有发送和接收的能力。
MySQL有哪些存储引擎,他们跟InnoDB有什么不同
- MyISAM(MySQL5.5前的默认引擎)
比InnoDB写效率更高,不支持事务、外键,数据和索引存放在两个不同的文件里(InnoDB的聚簇索引,把主键索引和数据放在一起)
- InnoDB(5.5之后默认引擎)
有事务,有外键约束,比MyISAM占用更多的磁盘空间来存储数据和索引,数据和索引存放在同一个文件里,适用需要在并发条件下保持数据的一致性的环境中。索引结构默认B+树
- MEMORY
数据保存在内存中,掉电即失。默认使用HASH索引,访问极快。默认表数据量最大16MB
- tokuDB
高效插入,压缩特性比InnoDB高近10倍,提供了主从延迟的消除技术。
MySQL各种锁
全局锁,表级锁(表锁,元数据锁,意向锁,AUTO-INC锁),行级锁(Record Lock,Gap Lock,Next-Key Lock)
更多请参考小林
MySQL和ES的缓存,加快查询速度(???)
因为简历上有es所以问了es,但我真不太懂es。
MySQL有一个查询缓存,会缓存之前相同的select语句查出来的数据。只要某个表有一个更新操作,该表的查询缓存就会清空。该功能因为鸡肋所以在MySQL8.0中去除。
ES有三种缓存。节点请求缓存,保存可在filter上下文中使用的查询结果。分片请求缓存,缓存size=0时频繁使用的查询的结果,尤其是聚合的结果。字段请求缓存,用于排序和支持某些字段类型上的聚合。
如何节省带宽,带宽打满可以吗
一个比较离谱的问题,当时答了把报文压缩,用udp代替tcp,还有http2.0让服务器能推数据到客户端而不用消耗一次请求(???怎么想到这个我也是离谱)。以下是gpt4的回答:
在Web应用开发过程中,节省带宽的方法有很多。以下是一些可能有用的技巧:
- 压缩文件:使用gzip或其他压缩算法可以减少文件大小,从而减少传输所需的带宽。
- 缓存静态资源:将静态资源(如图片、CSS和JavaScript文件)缓存在客户端浏览器中,可以减少对服务器的请求次数,从而减少带宽消耗。
- 使用CDN:使用内容分发网络(CDN)可以将静态资源缓存在全球各地的服务器上,从而加快资源加载速度并减少带宽消耗。
- 优化图片:使用适当的图片格式、尺寸和压缩算法可以减少图片大小,从而减少传输所需的带宽。
- 使用字体图标:使用字体图标代替图片可以减少文件大小,从而减少传输所需的带宽。
- 使用CSS Sprites:将多个小图标合并成一个大图标可以减少文件大小,从而减少传输所需的带宽。
这些技巧都可以在不影响Web应用性能和用户体验的情况下有效地节省带宽。
带宽打满当然不可以,我当时回答了可能会造成网络阻塞。
MySQL索引结构
常识,不讲
衡量CPU性能的指标
这个题目也挺离谱的,当时答了时钟频率,还有个浮点数运算速率(用鲁大师的时候看到的,这个应该是反映总体情况)。现在想想,还包括字长,寄存器数量,指令集,集成度,片上Cache,片外Cache(这两个是啥我也不知道),功耗,SPEC分数
JDBC API
MyBatis底层,分页原理结构(玛德这个拦截器问了几次我都没记得,看了一次忘了)
oracle 与mysql 的区别(我简历上有oracle)
当时答了mysql免费,oracle不免费,还有oracle有很方便的递归查询语法(start with connect by),mysql的递归查询语法(with recursive as ... union ...) 比较复杂。后来看到,oracle有物化视图,mysql没有,只有普通视图。更多
问了看过哪些框架源码,挑了个Spring bean的初始化讲了(Spring从扫描类到加载bean到IOC容器中)
问java注解怎么实现的,说不会
我以为是说java注解的实现原理,现在想来应该是问自己怎么写一个java注解。java注解的原理应该是java注解也会进字节码,由JVM处理。
关于如何创建一个注解,以下是一个模板
//4个元注解 @Inherited//如果A注解被该注解修饰,且A注解加在一个父类上,那么子类也会继承这个A注解 @Document//说明该注解被包含在javadoc中 @Target(ElementType.ANNOTATION_TYPE)//定义注解的作用目标 @Retention(RetentionPolicy.RUNTIME)//必须,指Java注解保留到何时,这里是保留到Runtime被JVM运行时读取 public @interface MyTarget { }
注解通过反射被读取,以在运行时决定要对该字段(或类,方法,常量...)需要做什么操作
10.17 offer
#玄武云##后端面经##jvm##场景题##晒一晒我的offer#参考: