面试视频随笔

JMM(Java内存模型)

可见性:

多个线程操作同一个变量时,当其中一个线程改变了变量的值之后马上通知其他线程变量值已经被改变了就叫做可见性

原子性

不可分割

有序性

编译后的指令和源代码一样按照一定顺序排列

指令重排

volatile可以禁止指令重排
在这里插入图片描述

写时复制

在这里插入图片描述

集合

ArrayList的底层结构是Object数组:
在这里插入图片描述
在这里插入图片描述

HashSet的底层结构是HashMap:
在这里插入图片描述
HashSet的add方法为啥只需要放一个值,因为value是固定的。
在这里插入图片描述
在这里插入图片描述

公平锁/非公平锁

在这里插入图片描述
在这里插入图片描述

可重入锁(递归锁)

在这里插入图片描述
在这里插入图片描述

自旋锁

在这里插入图片描述

独占锁(写锁)/共享锁(读锁)/互斥锁

在这里插入图片描述

CountDownLatch

在这里插入图片描述
在这里插入图片描述

CyclicBarrier

在这里插入图片描述
在这里插入图片描述

Semaphore

在这里插入图片描述
在这里插入图片描述

阻塞队列

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

synchronized和lock的区别

在这里插入图片描述

线程池

线程池总共有5种,三种常见,两种不常见
在这里插入图片描述

线程池优势

在这里插入图片描述

线程池示例代码

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池示例代码
 */
public class MyThreadPoolDemo {
    public static void main(String[] args) {
        // ExecutorService threadPool = Executors.newFixedThreadPool(5); // 固定长度的线程池
        // ExecutorService threadPool = Executors.newSingleThreadExecutor(); // 长度为1的线程池
        ExecutorService threadPool = Executors.newCachedThreadPool(); // 动态扩容的线程池
        try {
            for (int i = 0; i < 10; i++) {
                threadPool.submit(() -> {
                    System.out.println(Thread.currentThread().getName() + " 正在办理业务");
                });
                // TimeUnit.MILLISECONDS.sleep(200);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

三种线程池创建方式源码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程池的7大参数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程池底层工作原理

在这里插入图片描述
在这里插入图片描述

线程池的4种拒绝策略

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
DiscardOldestPolicy和DiscardPolicy会直接丢弃任务
在这里插入图片描述
在这里插入图片描述

不使用上面默认的三种线程池的原因

在这里插入图片描述
在这里插入图片描述

如何合理设置线程池的参数

cpu密集型

在这里插入图片描述

IO密集型

在这里插入图片描述
在这里插入图片描述

死锁

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

死锁示例代码

import java.util.concurrent.TimeUnit;

class HoldLock implements Runnable{
    private String lockA;
    private String lockB;

    public HoldLock(String lockA, String lockB) {
        this.lockA = lockA;
        this.lockB = lockB;
    }
    @Override
    public void run() {
        synchronized (lockA) {
            System.out.println(Thread.currentThread().getName() + " 持有锁:" + lockA + " 等待锁:" + lockB);
            try {
                TimeUnit.SECONDS.sleep(2L);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized (lockB) {
                System.out.println(Thread.currentThread().getName() + " 持有锁:" + lockB + " 等待锁:" + lockA);
            }
        }
    }
}

/**
 * 死锁示例代码
 */
public class DeadLockDemo {
    public static void main(String[] args) {
        String lockA = "lockA";
        String lockB = "lockB";
        new Thread(new HoldLock(lockA, lockB), "t1").start();
        new Thread(new HoldLock(lockB, lockA), "t2").start();
    }
}

JVM和GC

JVM体系结构

在这里插入图片描述
在这里插入图片描述

GC的作用域

在这里插入图片描述

常见的垃圾回收算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如何确定GC垃圾

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以作为GC Roots的对象

在这里插入图片描述
在这里插入图片描述
上图中1和4标注的可能有问题

JVM的参数类型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

JVM XX参数

boolean类型

在这里插入图片描述
打印GC收集细节
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
使用串行垃圾回收器
在这里插入图片描述

KV设值类型

在这里插入图片描述

jinfo查看默认JVM参数

macOS下JDK11版本的
在这里插入图片描述
window下JDK8版本的
在这里插入图片描述

-Xms和-Xmx参数

在这里插入图片描述

查看jdk安装后所有的默认参数

命令:java -XX:+PrintFlagsInitial
在这里插入图片描述

查看jdk安装之后调整过的所有参数

命令:java -XX:+PrintFlagsFinal -version
在这里插入图片描述
在这里插入图片描述
运行Java代码的同时并修改参数
在这里插入图片描述
命令:java -XX:+PrintCommandLineFlags -version
在这里插入图片描述
在这里插入图片描述

常用JVM参数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
常用的调参示例(注意:此示例仅仅只是说明该调哪些参数,具体值需要根据实际情况进行调整):
在这里插入图片描述
如下参数一般不进行调整,采用默认即可
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:MaxTenuringThreshold在Java8中只能设置成0-15之间
在这里插入图片描述
Java11中范围为0-16
在这里插入图片描述

-XX:+PrintGCDetails

jvm运行参数:-Xms10m -Xmx10m -XX:+PrintGCDetails
在这里插入图片描述
Java8垃圾回收日志
在这里插入图片描述

Java8之前垃圾回收日志解析

GC类型
在这里插入图片描述FULL GC类型
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

强引用、软引用、弱引用、虚引用

整体架构图

在这里插入图片描述

强引用

在这里插入图片描述
示例代码:

/**
 * 强引用示例
 */
public class StrongReferenceDemo {
    public static void main(String[] args) {
        Object obj1 = new Object(); // 这样定义的默认就是强引用
        Object obj2 = obj1; // obj2引用赋值
        obj1 = null; // 置空
        System.gc();
        System.out.println("obj2 = " + obj2);
    }
}

在这里插入图片描述

软引用

在这里插入图片描述
示例代码:

import java.lang.ref.SoftReference;

/**
 * 软引用示例
 */
public class SoftReferenceDemo {

    public static void enough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println("o1 = " + o1);
        System.out.println("softReference.get() = " + softReference.get());
        o1 = null;
        System.gc();
        System.out.println("o1 = " + o1);
        System.out.println("softReference.get() = " + softReference.get());
    }

    public static void notEnough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println("o1 = " + o1);
        System.out.println("softReference.get() = " + softReference.get());
        o1 = null;
        try {
            byte[] bytes = new byte[30 * 1024 * 1024];
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            System.out.println("o1 = " + o1);
            System.out.println("softReference.get() = " + softReference.get());
        }
    }

    public static void main(String[] args) {
        // enough();
        notEnough();
    }
}

在这里插入图片描述
notEnough方法执行jvm参数为:-Xms5m -Xmx5m -XX:+PrintGCDetails
在这里插入图片描述

弱引用

在这里插入图片描述
示例代码:

import java.lang.ref.WeakReference;

/**
 * 弱引用示例
 */
public class WeakReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        WeakReference<Object> weakReference = new WeakReference<>(o1);
        System.out.println(o1);
        System.out.println(weakReference.get());
        o1 = null;
        System.gc();
        System.out.println("==========================");
        System.out.println(o1);
        System.out.println(weakReference.get());
    }
}

在这里插入图片描述
在这里插入图片描述

软引用和弱引用适用的场景

在这里插入图片描述

WeakHashMap

当key置为null的时候,且垃圾回收器进行垃圾回收,那么WeakHashMap里面存放的值也会变为null
示例代码:

import java.util.HashMap;
import java.util.WeakHashMap;

/**
 * WeakHashMap示例
 */
public class WeakHashMapDemo {
    public static void testHashMap() {
        HashMap<Integer, String> hashMap = new HashMap<>();
        Integer key = new Integer(1);
        String value = "HashMap";
        hashMap.put(key, value);
        System.out.println(hashMap);
        key = null;
        System.out.println(hashMap);
        System.gc();
        System.out.println(hashMap + " size : " + hashMap.size());
    }

    public static void testWeakHashMap() {
        WeakHashMap<Integer, String> map = new WeakHashMap<>();
        Integer key = new Integer(2);
        String value = "WeakHashMap";
        map.put(key, value);
        System.out.println(map);
        key = null;
        System.out.println(map);
        System.gc();
        System.out.println(map + " size : " + map.size());
    }

    public static void main(String[] args) {
        testHashMap();
        System.out.println("==============");
        testWeakHashMap();
    }

}

Java8运行结果
在这里插入图片描述
Java11运行结果
在这里插入图片描述
神奇现象
在这里插入图片描述

虚引用

在这里插入图片描述
示例代码:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

/**
 * 虚引用示例
 */
public class PhantomReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(o1, referenceQueue);
        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());
        System.out.println("====================");
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());
    }
}

在这里插入图片描述

ReferenceQueue

引用被GC回收前会先放入ReferenceQueue中(示例用虚引用比较直观)
示例代码:

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

/**
 * ReferenceQueue示例
 */
public class ReferenceQueueDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        WeakReference<Object> weakReference = new WeakReference<>(o1, referenceQueue);
        System.out.println(o1);
        System.out.println(weakReference.get());
        System.out.println(referenceQueue.poll());
        System.out.println("====================");
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(weakReference.get());
        System.out.println(referenceQueue.poll());
    }
}

在这里插入图片描述

GCRoots和四大引用小总结

在这里插入图片描述

OOM的认识

错误类型
在这里插入图片描述

StackOverflowError

示例代码:

/**
 * StackOverflowError示例
 * 无限递归调用可以引发StackOverflowError
 */
public class StackOverflowErrorDemo {
    public static void main(String[] args) {
        stackOverflowError();
    }

    private static void stackOverflowError() {
        stackOverflowError(); // Exception in thread "main" java.lang.StackOverflowError
    }
}

在这里插入图片描述

Java heap space

示例代码:

/**
 * Java heap space 示例代码
 * 运行JVM参数:-Xms10m -Xmx10m
 */
public class JavaHeapSpaceDemo {
    public static void main(String[] args) {
        String str = "aaa";
        // Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        while (true) {
            str += str + UUID.randomUUID() + new Random().nextInt(111111111);
            str.intern();
        }
        // 或者直接创建一个大对象
        // byte[] bytes = new byte[50 * 1024 * 1024];
    }
}

在这里插入图片描述

GC overhead limit exceeded

在这里插入图片描述
示例代码:

import java.util.ArrayList;
import java.util.List;

/**
 * GC overhead limit exceeded 示例
 * JVM运行时参数:
 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
 * 注意:此程序在Java11上面报的错误为:java.lang.OutOfMemoryError: Java heap space,和垃圾回收器相关
 * G1垃圾回收器(Java9及以后默认)报:java.lang.OutOfMemoryError: Java heap space
 * Parallel垃圾回收器(Java8默认)报:java.lang.OutOfMemoryError: GC overhead limit exceeded
 */
public class GCOverheadLimitDemo {
    public static void main(String[] args) {
        int i = 0;
        List<String> list = new ArrayList<>();
        try {
            while (true) {
                list.add(String.valueOf(++i).intern());
            }
        } catch (Throwable throwable) {
            System.out.println("====================== i  ============ : " + i);
            throwable.printStackTrace();
            throw throwable;
        }
    }
}

在这里插入图片描述

Direct buffer memory

在这里插入图片描述
示例代码:

import java.nio.ByteBuffer;

/**
 * Direct buffer memory示例
 * JVM运行时参数:
 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
 */
public class DirectBufferMemoryDemo {
    public static void main(String[] args) {
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);
    }
}

在这里插入图片描述

unable to create native thread

在这里插入图片描述

示例代码:

import java.util.concurrent.TimeUnit;

/**
 * unable to create native thread 示例
 * 此案例和操作系统有关,Linux最大能创建1024个线程,macOS最大能创建4096个线程。实际情况会略小于理论值。
 */
public class UnableCreateNewThreadDemo {
    // Exception in thread "main" java.lang.OutOfMemoryError: unable to create native thread
    public static void main(String[] args) {
        for (int i = 0; ; i++) {
            System.out.println("i = " + i);
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(5L);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }, String.valueOf(i)).start();
        }
    }
}

在这里插入图片描述
Linux系统查看及调整:
在这里插入图片描述
在这里插入图片描述

Metaspace

在这里插入图片描述
示例代码:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Metaspace示例
 * JVM运行时参数:
 * -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
 */
public class MetaspaceOOMDemo {
    static class OOMTest {

    }

    public static void main(String[] args) {
        int i = 0;
        try {
            while (true) {
                i++;
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(OOMTest.class);
                enhancer.setUseCache(false);
                enhancer.setCallback(new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        return methodProxy.invoke(o, args);
                    }
                });
                enhancer.create();
            }
        } catch (Throwable e) {
            System.out.println("i = " + i);
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

垃圾回收器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

串行垃圾回收器Serial

在这里插入图片描述

并行垃圾回收器Parallel

在这里插入图片描述

并发垃圾回收器CMS

在这里插入图片描述

G1垃圾回收器

在这里插入图片描述

查看默认的垃圾收集器

在这里插入图片描述

默认的垃圾收集器

jdk8中有以下6种,之前有个serial old(已废弃),jdk11增加了ZGC
在这里插入图片描述

垃圾收集器详解(新生代和老年代分别用可以用哪些)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

部分参数预先说明

在这里插入图片描述

jdk server和client模式的区别

在这里插入图片描述

新生代串行Serial收集器

在这里插入图片描述
在这里插入图片描述
Java8垃圾回收日志
在这里插入图片描述

新生代并行ParNew收集器(只是新生代用并行收集器)

在这里插入图片描述
在这里插入图片描述
Java8垃圾回收日志
在这里插入图片描述

新生代并行Parallel/Parallel Scavenge收集器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Java8垃圾回收日志
在这里插入图片描述

老年代并行Parallel Old收集器

在这里插入图片描述
Java8垃圾回收日志
在这里插入图片描述

老年代并发CMS收集器(并发标记清除GC)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

老年代串行Serial Old收集器

在这里插入图片描述
在这里插入图片描述

如何选择垃圾收集器(不包含G1)

在这里插入图片描述
在这里插入图片描述

G1垃圾回收器

以前垃圾回收器的特点

在这里插入图片描述

G1是什么

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
特点

在这里插入图片描述

底层原理

Region区域化垃圾收集器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
回收步骤
在这里插入图片描述
在这里插入图片描述
4步过程
在这里插入图片描述

G1相关的一些参数(了解)

在这里插入图片描述
在这里插入图片描述

G1和CMS比较的优势

在这里插入图片描述

Linux排查系统问题常用命令

在这里插入图片描述

top命令

按 q 退出命令
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

vmstat:查看cpu相关信息

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

free:查看内存相关信息

在这里插入图片描述
在这里插入图片描述

df:查看硬盘相关信息

在这里插入图片描述
在这里插入图片描述

iostat:磁盘IO

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ifstat:网络IO

在这里插入图片描述
下载安装命令集合
在这里插入图片描述
使用命令:ifstat 1 (后面参数是数字1,不是英文字母l)
在这里插入图片描述

CPU占用过高的分析思路和定位

在这里插入图片描述

定位到具体线程或者代码

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
上图(排查问题总览图)中的第四点
在这里插入图片描述

GitHub的骚操作

常用词

在这里插入图片描述

in 限制搜索范围

在这里插入图片描述

star和fork范围搜索

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

awesome加强搜索

在这里插入图片描述

#L : 高亮显示某一行或者某几行代码

在这里插入图片描述
示例:

https://github.com/BurningTomcat/wechatserver/blob/master/src/com/wechat/common/controller/CoreController.java#L29-L61

项目内搜索

在这里插入图片描述
进入项目后直接按 t (GitHub的快捷键)

搜索某个地区内的大佬

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HiTomcat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值