美文网首页
解析一些java复杂面试题的简单操作

解析一些java复杂面试题的简单操作

作者: 宇哥聊AI | 来源:发表于2018-06-08 21:23 被阅读73次

    java虚拟机

    什么时候会触发full gc

    System.gc()方法的调用

    老年代空间不足

    永生区空间不足(JVM规范中运行时数据区域中的方法区,在HotSpot虚拟机中又被习惯称为永生代或者永生区,Permanet Generation中存放的为一些class的信息、常量、静态变量等数据)

    GC时出现promotion failed和concurrent mode failure

    统计得到的Minor GC晋升到旧生代平均大小大于老年代剩余空间

    堆中分配很大的对象

    可以作为root的对象:

    类中的静态变量,当它持有一个指向一个对象的引用时,它就作为root

    活动着的线程,可以作为root

    一个Java方法的参数或者该方法中的局部变量,这两种对象可以作为root

    JNI方法中的局部变量或者参数,这两种对象可以作为root

    例子:下述的Something和Apple都可以作为root对象。

    Java方法的参数和方法中的局部变量,可以作为root.

    新生代转移到老年代的触发条件

    长期存活的对象

    大对象直接进入老年代

    minor gc后,survivor仍然放不下

    动态年龄判断 ,大于等于某个年龄的对象超过了survivor空间一半 ,大于等于某个年龄的对象直接进入老年代

    redis

    redis单线程问题

    单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程。

    为什么说redis能够快速执行

    绝大部分请求是纯粹的内存操作(非常快速)

    采用单线程,避免了不必要的上下文切换和竞争条件

    非阻塞IO - IO多路复用

    redis的内部实现

    内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间 这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。

    Redis关于线程安全问题

    redis实际上是采用了线程封闭的观念,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁。

    使用redis有哪些好处?

    速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

    支持丰富数据类型,支持string,list,set,sorted set,hash

    支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

    丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

    redis相比memcached有哪些优势?

    memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

    redis的速度比memcached快很多

    redis可以持久化其数据

    如果需要Java工程化、高性能及分布式、微服务、Spring,MyBatis,Netty源码分析资料的朋友可以加Java进阶群:591240817 群里有阿里大牛直播讲解技术,以及大型互联网公司架构技术的视频免费分享给大家。

    数据库

    B树和B+树的区别

    B树,每个节点都存储key和data,所有节点组成这棵树,并且叶子节点指针为nul,叶子结点不包含任何关键字信息。

    B+树,所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接,所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)

    为什么说B+比B树更适合实际应用中操作系统的文件索引和数据库索引?

    B+的磁盘读写代价更低 B+的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。

    B+-tree的查询效率更加稳定 由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

    java高并发

    JAVA 线程状态转换图示

    synchronized 的底层怎么实现

    同步代码块(Synchronization)基于进入和退出管程(Monitor)对象实现。每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:

    如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。

    如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.

    如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。

    被 synchronized 修饰的同步方法并没有通过指令monitorenter和monitorexit来完成(理论上其实也可以通过这两条指令来实现),不过相对于普通方法,其常量池中多了ACC_SYNCHRONIZED标示符。JVM就是根据该标示符来实现方法的同步的:当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象。 其实本质上没有区别,只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成

    相关文章

      网友评论

          本文标题:解析一些java复杂面试题的简单操作

          本文链接:https://www.haomeiwen.com/subject/yuhzsftx.html