轻而易举的让人认为你是大牛!
JAVA四道题
1.如何定位线上服务OOM问题
2.JVM的GC ROOTS存在于那些地方
3.mysql innodb怎样做查询优化
4.java cas的概念
刚看到的时候懵逼不懵逼?难不难?其实还好~主要还是看大家在解决问题的时候是否想过原理,答案无标准,注重下思路就好。
1>如何定位线上服务OOM问题
因为面试主要是看思路,答案还是其次,那么要是我回答这个问题。我可能会把整个思路都说出来:Java服务OOM,比较常见的原因是
⭐️ 有可能是内存分配确实过小,而正常业务使用了大量内存
比如jmap -heap命令可以查看新生代老年代的堆内存大小及使用情况,看看是否内存本身分配过小。
⭐️ 某一个对象被频繁申请,却没有释放,内存不断泄漏,导致内存耗尽
比如jmap -histo:live 对象显示存活对象的信息,并按照所占内存大小的排序。因为包含了实例数、所占内存大小、类名,所以很直观。
⭐️ 某一个资源被频繁申请,系统资源耗尽,例如:不断创建线程,不断发起网络连接
可以用pstree、netstat查看进程创建线程数,网络连接数,如果资源耗尽,也会出现OOM。也可以查看/proc/${PID}/fd 和/proc/${PID}/task,查看句柄详情和线程数。
2>JVM的GC ROOTS存在于那些地方
问到这个问题应该是前面一步步引导过来的,如果没有,在直接回答这个问题之前,最好简要描述一下JVM的内存结构和根搜索算法(GC ROOTS Tracing)做可达性分析。
GC Roots的对象包括如下几种(静儿来新美大的时候就被我们架构师问过这个问题):
⭐️ 虚拟机栈(栈桢中的本地变量表)中的引用的对象
⭐️ 方法区中的类静态属性引用的对象
⭐️ 方法区中的常量引用的对象
⭐️ 本地方法栈中JNI的引用的对象
GC管理的主要区域是Java堆,一般情况下只针对堆进行垃圾回收。方法区、栈和本地方法区不被GC所管理,因而选择这些区域作为GC ROOTS。被GC ROOTS引用的对象不会被垃圾回收。
3>mysql innodb怎样做查询优化
这个问题的答案就比较多了,各人的心得都是不一样的。主要考察在工作实践中的总结和思考能力。最好面试者能在总结的通用答案之后加上实际项目中的使用例子。
⭐️ innodb_buffer_pool_size 此参数的作用是缓冲数据和索引,对性能可以产生线性的提高,最大可设置为内存大小的百分之七八十的样子
⭐️ 打开慢查询日志,增加参数:log-queries-not-using-indexes,方便把系统中没有走索引的sql语句全抓出来优化
⭐️ 通过explain做查询分析,看看有没有用索引,访问的行数rows
⭐️ 关闭skip_name_resolve,减少逆向DNS解析的消耗
另外还有一些实际写代码过程中深入骨髓的,比如数据动静分离提高query_cache的命中率啦,减少字段冗余,减少查询次数啦,复杂查询分解啦,分页优化啦啥的。
很多人说面试题和实际开发联系不大,觉得没啥用。其实很多活培训两个月都是能干的。人和人之间的差距确实没有明显到你能干我不能干的程度。但是之前做过一个项目,我和别人一起干,干完之后我要修改很多其他人的各种慢查询问题啦,性能问题啦之类。我看了他们写的sql,我发现这些sql我会理所当然不那么用的。因为我在人人的时候就很注意这些方面,我认为是理所当然的,知道这样影响性能。
还有就是面试评价好的人实际写代码的时候确实出的问题要少,因为他们考虑更全面。很多人不是有意要出bug的,但是确实是不知道啊,不知道要考虑情况A,情况B,不知道JVM底层的实现,所以有可能会产生的意想不到的结果。出了问题了也不知道往哪个方向去想。
4>java cas的概念
cas:compare and swap,比较并交换
java的concurrent包中借助cas实现了区别于synchronized同步锁的一种乐观锁。
CAS利用CPU的CAS指令,同时借助JNI来完成java的非阻塞算法,其他的原子操作都是利用类似的特性完成的。java的concurrent包相对于使用synchronized性能提升也是主要依赖于它。