美文网首页面试题
java面试之四

java面试之四

作者: lijiaccy | 来源:发表于2017-08-07 16:58 被阅读12次
1、你常用的jvm监控工具或者命令有哪些
  • GC日志 PrintGCDetails 每次GC记录日志
  • jstat -gcutil pid 5s 10//间隔5s,打印10次


    Paste_Image.png

    S0 — Heap上的 Survivor space 0 区已使用空间的百分比
    S1 — Heap上的 Survivor space 1 区已使用空间的百分比
    E — Heap上的 Eden space 区已使用空间的百分比
    O — Heap上的 Old space 区已使用空间的百分比
    M — Metaspace 区已使用空间的百分比
    YGC — 从应用程序启动到采样时发生 Young GC 的次数
    YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
    FGC — 从应用程序启动到采样时发生 Full GC 的次数
    FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
    GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)

  • jstack pid:结合top看看是不是cpu过高,导致死锁
2、java8的lambda表达式了解过吗?

java8之前:

new Thread(new Runnable(){
     public void run() {
         System.out.println(1123);
     }
}).start();

java8:

    new Thread(() -> System.out.println(123)).start();

还有其他的好多东西,下次找个时间专门研究一下这个。

3、A,B两个线程同时启动,但让A结束后B在结束,如何实现。

用join关键字。t.join()方法阻塞调用此方法的线程(calling thread),直到线程t完成,此线程再继续;通常用于在main()主线程内,等待其它线程完成再结束main()主线程。例如:

public class Test implements Runnable{

private String name;

public Test(String name) {
    this.name = name;
}

@Override
public void run() {
    try {
        Thread.sleep(1000);
    System.out.println(new Date()+"  "+name);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(new Test("zhangsan"));
    Thread thread1 = new Thread(new Test("lijia"));
    thread.start();
    thread1.start();
    thread.join();
    thread1.join();
    System.out.println("qqqqqqqqqqqq");
}
}
运行结果

如果把join去掉:

Paste_Image.png
4、java中什么是锁

我认为面试官一般问这种问题都是想问你synchronized。主要是问完这个也会顺带着问Lock。锁里面还有一些概念公平锁、非公平锁、自旋锁、可重入锁、偏向锁、轻量级锁、重量级锁、读写锁、互斥锁等。
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:

  • 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;

  • 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;

  • 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;

  • 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

      public class Test2 {
      public static void main(String[] args) {
      SyncThread syncThread = new SyncThread();
      Thread thread1 = new Thread(syncThread, "SyncThread1");
      Thread thread2 = new Thread(syncThread, "SyncThread2");
      thread1.start();
      thread2.start();
    
      }
      }
     class SyncThread implements Runnable {
       private int count;
       public SyncThread() {
       count = 0;
      }
     public  void run() {
      //        synchronized(this) {
           for (int i = 0; i < 5; i++) {
              try {
                  System.out.println(Thread.currentThread().getName() + ":" + (count++));
                  Thread.sleep(100);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
     //        }
    }
       public int getCount() {
        return count;
       }
    }
    

运行结果为


加上synchronized之后

再没有加锁之前,两个线程相互调用cpu,加锁之后,SyncThread1线程执行完才到SyncThread2,而且保证了正确性。

那么再说说volatile吧

还是用上面的例子说明,其他都不动

 private volatile int count;//在count这加入volatile

运行结果

图片.png 图片.png

用volatile只能保证可见性,但是不保证原子性。如上图,结果就是不正确的。
volatile也能禁止重排序

那么volatile怎么保证可见性和禁止重排序
引入深入理解java虚拟机中一段话: 观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
也会说道Lock和AQS,请看
http://www.jianshu.com/p/d333d5177498
也许会问JUC下的一些其他类,这里不说了。

相关文章

网友评论

    本文标题:java面试之四

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