java学习过程总结汇总(二)

java面试题总结

牛客网面经链接: 点我点我.
问题总结(二面的问题总结)
1描述java的内存结构
答案:内存结构: 点我点我.
我自己的理解是:java程序经过编译得到.class文件之后交给jvm去执行。那么jvm就会为程序提供空间去存储程序运行要用到的数据和相关信息,所以更进一步的讲就是对这部分空间的管理。JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。
2JNI有多深的了解?JNI所占用的空间是哪部分的空间?

答案:JNI是zhidaoJava Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。回JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨答碍你使用其他语言,只要调用约定受支持就可以了。
个人理解是占用的是java Head空间
3 CAS的底层原理
答案: 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科)
1、Unsafe类
是CAS的核心类,由于java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据。
Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作执行依赖于Unsafe类。
Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务  
2、变量valueOffset,表示该变量在内存中的偏移地址,因为Unsafe就是根据内存偏移地址获取数据的。
总结:getAndIncrement()底层调用unsafe类方法,传入三个参数,unsafe.getAndAddInt() 底层使用CAS思想,如果比较成功加1,如果比较失败重新获得,再比较一次,直至成功。
4 如何判断对象是否存活
答案:java采用的是:可达性分析算法。通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。需要说明的是,即使再可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于

“缓刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:
  1、对象在进行可达性分析后被发现不可达,它将会被第一次标记并进行一次筛选,筛选的条件是此对象是否有必要执行finalise()方法,当对象没有覆盖finalize()方法或者finalize()方法已经被JVM调用过,那么就没必要执行finalize()方法;
  2、如果被判定为有必要执行finalize()方法,那么此对象将会放置在一个叫做F-Quenen的队列之中,并在稍后由一个虚拟机自动建立的、低优先级的Finalize线程去触发这个方法。finalize()方法是对象逃脱死亡的最后一次机会,稍后GC将对F-Quenen中的对象进行第二次小规模的标记,如果对象要在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关系即可,譬如把自己(this关键字)赋值给某个类变量或者对象的成员变量,那么在第二次标记时它将被移出“即将回收”集合;如果对象这时候还么有功逃脱,那他就会真的被回收了。
5 知道哪些垃圾回收器和垃圾回收算法?CMS与G1的区别是什么?CMS和G1的运作流程?
算法:引用计数算法,可达性分析算法等等
垃圾回收器:
(1)Serial收集器(复制算法)
新生代单线程收集器,标记和清理都是单线程,优点是简单高效。是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定。
(2)Serial Old收集器(标记-整理算法)
老年代单线程收集器,Serial收集器的老年代版本。
(3)ParNew收集器(停止-复制算法) 
新生代收集器,可以认为是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。
(4)Parallel Scavenge收集器(停止-复制算法)
并行收集器,追求高吞吐量,高效利用CPU。吞吐量一般为99%, 吞吐量= 用户线程时间/(用户线程时间+GC线程时间)。适合后台应用等对交互相应要求不高的场景。是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数。
(5)Parallel Old收集器(停止-复制算法)
Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先。
CMS(Concurrent Mark Sweep)收集器(标记-清理算法)
高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高,响应时间快,停顿时间短,多核cpu 追求高响应时间的选择。
详细地址: 点我点我.
CMS和G1: 点我点我.
6 手撕LRUMap,不允许使用LinkedHashMap和LinkedList

public class LRUCache{

    private class ListNode {
        int key, val;
        ListNode next;

        public ListNode(int key, int val) {
            this.key = key;
            this.val = val;
            this.next = null;
        }
    }

    private int capacity;
    private Map<Integer, ListNode> map;     //key-> node.pre
    private ListNode head;  //dummy
    private ListNode tail;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        map = new HashMap<>();
        head = new ListNode(-1, -1);
        tail = head;
    }

    public int get(int key) {
        if (!map.containsKey(key)) {
            return -1;
        }
        //map中存放的是要找的节点的前驱
        ListNode pre = map.get(key);
        ListNode cur = pre.next;

        //把当前节点删掉并移到尾部
        if (cur != tail) {
            pre.next = cur.next;
            map.put(cur.next.key, pre); //更新它后面node的前驱
            map.put(cur.key, tail);
            moveToTail(cur);
        }
        return cur.val;
    }

    public void put(int key, int value) {
        if (get(key) != -1) {
            map.get(key).next.val = value;
            return;
        }
        //不存在就new一个
        ListNode node = new ListNode(key, value);
        map.put(key, tail); //当前node的pre是tail
        moveToTail(node);

        if (map.size() > capacity) {
            map.remove(head.next.key);
            map.put(head.next.next.key, head);
            head.next = head.next.next;
        }
    }

    private void moveToTail(ListNode node) {
        node.next = null;
        tail.next = node;
        tail = tail.next;
    }
}

爱墨墨真好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值