1.cap理论:

一致,可用,分区容错

2.web2.0:

以分享为特征的实时网络,用户在互联网上拥有自己的数据,并且在不同的网站上使用

3.分布式事务:

事务:原子,一致,隔离,持久

# 开启事务
begin transaction update Account set balance = balance - money where id = 'A';
update Account set balance = balance + money where id = 'B'
# 提交事务
commit transaction Exception # 回滚事务rollback transaction

脏读:事务二读取到事务一中已经更新但是还没有提交的数据,这就是脏读。

不可重复读:一个事务两次读取同一个行数据结果不同,因为有其它的事务对数据进行了更新。此时的数据即为不可重复读数据。

幻读:同一事务执行两次查询,结果不一致,因为中间有其它的事务对数据进行更改。

事务隔离级别

读未提交(read uncommitted):最低级别,可能会导入脏读。

读已提交(read committed):可以避免脏读,只能查询到已经提交的数据。且具有良好的性能,但是不能避免不可重复读和幻读。

可重复读(repeatable):解决了不可重复读,可能会出现幻读。

串行化(serializable):通过加锁,使同一时间只能执行一个事务,不出现上述问题,但是可能会导致大量的超时现象和锁竞争。

分布式事务解决方案:

1.补偿事务TCC:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:

  1. 首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
  2. 在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
  3. 如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。

2.两阶段提交 2pc

3.本地消息表

4.mq事务消息

4.jvm:

1.堆,

Eden ——》s0 《——》s2 ——》老年代

2.栈(线程):适用于java方法嵌套调用逻辑顺序,

线程每调用一个方法就对应着 JVM Stack 中 Stack Frame 的入栈,方法执行完毕或者异常终止对应着出栈(销毁)

(1)栈帧:

​ 1.局部变量表

​ 2.操作数栈:操作栈调用其它有返回结果的方法时,会把结果 push 到栈上(通过操作数栈来进行参数传递)

​ 3.动态链接

​ 4.方法出口

3.本地方法栈:一个Native Method就是一个java调用非java代码的接口,

4.方法区(元空间),程序计数器

5.volatile关键字

java虚拟机提供的一种轻量级的同步机制,1.保证可见性,2.不保证原子性,3.禁止指令重排

1.jmm(java内存模型):可见,原子,有序

线程A 线程B

工作内存 工作内存

​ jmm来控制

​ 主内存

(线程要对变量进行读写操作必须在工作内存中进行,首先从主内存中拷贝变量到工作空间,读写等操作完成之后再将变量写回主内存)

atomic类

6.cas(compareandswap)
为什么atomicIneger底层要用CAS而不是synchronized?

synchronized悲观锁,导致cpu的频繁的上下文切换效率很低

它是一条CPU并发原语,功能是判断内存中某个位置的值是否为预期值,如果是则更新为新的值,这个过程是原子性的

为CPU原子指令,不会造成所谓的数据不一致的问题

public void main (String[]  args){AtomicInteger a=new AtomicInteger(5);System.out.pringln(a.compareAndSet(5,2020));System.out.pringln(a.compareAndSet(5,2021));a.getAndIncrement();/*源码:return unsafe.getAndAddInt(this,valueoffset,1);this:当前的对象,valueoffset:内存地址偏移量(内存地址),value:使用了volatile关键字保证了可见性public final int getAndAddInt(Object var1,long var2,int var4){int var5;do{/var5先获得当前对象的内存地址所指向的值也就类似于c和c++中的指针指向的值。var5 = this.getIntVolatile(var1, var2);//如果取到当前对象内存所指向的值是var5说明没有其他线程更改就把主内存中的值更改为var5 + var4,其中var4=1;}while(!this.compareAndSwapInt(var1,var2,var5,var5+var4))}用当前对象的值和var5比较如果相同,更新内存地址并返回true如果不同,继续取值再比较,直到更新完成(自旋锁的思想借鉴与之)即保证了一致性和高并发性*/
}

当线程获取主内存数据不是期望的5的时候就没有办法执行操作

2.cas的缺点:

如果cas一直失败,会给CPU带来很大的开销,只可以保证一个共享变量的原子操作,ABA问题

ABA问题:狸猫换太子

经典案例:

经典转账案例

假设小琳银行卡有 100 块钱余额,且假定银行转账操作就是一个单纯的 CAS 命令,对比余额旧值是否与当前值相同,如果相同则发生扣减/增加,我们将这个指令用 CAS(origin,expect) 表示。于是,我们看看接下来发生了什么:

  1. 小琳在 ATM 1 转账 100 块钱给小李;
  2. 由于ATM 1 出现了网络拥塞的原因卡住了,这时候小琳跑到旁边的 ATM 2 再次操作转账;
  3. ATM 2 没让小琳失望,执行了 CAS(100,0),很痛快地完成了转账,此时小琳的账户余额为 0;
  4. 小王这时候又给小琳账上转了 100,此时小琳账上余额为 100;
  5. 这时候 ATM 1 网络恢复,继续执行 CAS(100,0),居然执行成功了,小琳账户上余额又变为了 0;
  6. 这时候小王微信跟小琳说转了 100 过去,是否收到呢?小琳去查了下账,摇了摇头,那么问题来了,钱去了哪呢?

关于钱的去向,有一种可能就是小王给小琳的 100 大洋,因为 ATM 1 网络恢复再次被转给了小李,毕竟小琳尝试了两次转账,出现这种情况虽不合理,但情有可原。假设我们作为银行系统设计者和开发者,不接受这种情况存在,那我们就需要着手处理这种 ABA 问题了。

解决办法:添加一种新的机制,加上版本号(类似时间戳)

t1 100 1 2019 2

t2 100 1 101 2 100 3

7.ArrayList是线程不安全的,请编写一个不安全的案例并给出解决办法?
public class ArrayListTest {public static void main(String[] args) {List<String> test= new CopyOnWriteArrayList<>();for (int i = 0; i < 30; i++) {new Thread(()->{test.add(UUID.randomUUID().toString().substring(0,8));System.out.println(test);},String.valueOf(i)).start();}/** 出现异常:java.util.ConcurrentModificationException 并发修改异常* 导致原因*       并发争抢修改导致,参考花名册案例 一个同学正在写,另外一个同学过来抢夺,导致数据不一致异常,并发修改异常** 解决办法*       1.new Vector*       2.Collections.synchronizedList(new ArrayList<>())相当于外面套了一层锁*       3.new CopyOnWriteArrayList<>() 增删改加了锁(写时复制 案例 每个同学修改名单只有一支笔,修改后指针移到修改后的地址),读没有*       CopyOnWrite并发容器用于读多写少的并发场景,比如白名单,黑名单之类的等等写搜索引擎设置哪些内容不可以搜索(黑名单)*        缺点比较占用内存,数据一致性问题,不能保持数据实时一致性,所以如果你希望写入的的数据,马上能读到,请不要使用CopyOnWrite容器*            CopyOnWriteArrayList为什么并发安全且性能比Vector好我知道Vector是增删改查方法都加了synchronized,保证同步,但是每个方法执行的时候都要去获得锁,
*                       性能就会大大下降,而CopyOnWriteArrayList 只是在增删改上加锁,
*                       但是读不加锁,在读方面的性能就好于Vector,CopyOnWriteArrayList支持读多写少的并发情况。* 优化建议*** */}
}

ArrayList,set (hashset底层是hashmap),map线程不安全

ConcurrentHashMap,Vector,hashtable,stack是线程安全

java中8中基本类型和一种比较特殊的类型String,常量池就是java系统级别提供的缓存

8.(java里面的锁)公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?手写一个自旋锁?
(1)公平锁和非公平锁

公平锁是指:先来后到谁等待的时间长谁获得锁

​ 对于java的来说默认的是非公平锁,非公平锁吞吐量比较大

非公平锁:非公平锁那就随机的获取,谁运气好,cpu时间片轮到哪个线程,哪个线程就能获取锁

(2)可重入锁(递归锁)synchronized ReenTrantLock

该锁支持同一个线程对资源的重复加锁

线程可以进入任意一个已经拥有锁的所同步的代码块

(3)自旋锁(unsafe类和CAS思想)手写自旋锁

尝试获取锁的线程不会立即阻塞,而是采用循环的方式来获取锁,减少线程上下文切换的消耗,但是会消耗CPU的资源

public class SpinLockDemo {AtomicReference<Thread> atomicReference=new AtomicReference<>();public void myLock(){Thread thread=Thread.currentThread();while (!atomicReference.compareAndSet(null,thread)){}System.out.println(thread.getName()+"\t come");}public void myunLock(){Thread thread=Thread.currentThread();atomicReference.compareAndSet(thread,null);System.out.println(thread.getName()+"\t invoked myunlock");}public static void main(String[] args) {SpinLockDemo spinLockDemo=new SpinLockDemo();new Thread(()->{spinLockDemo.myLock();try{TimeUnit.MICROSECONDS.sleep(1);}catch (InterruptedException e){e.printStackTrace();}spinLockDemo.myunLock();},"AA").start();try{TimeUnit.SECONDS.sleep(1);}catch (InterruptedException e){e.printStackTrace();}new Thread(()->{spinLockDemo.myLock();spinLockDemo.myunLock();},"BB").start();}
}
(4)独占锁/共享锁/互斥锁/读写锁

独占锁:该锁一次只可以被一个线程占用

共享锁:该锁可以被多个线程所持有

代码实现读写锁:

 class MyCache{private volatile Map<String,Object> map=new HashMap<>();private ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock(true);public void put(String key,Object value){readWriteLock.writeLock().lock();try {System.out.println(Thread.currentThread().getName()+"正在写入"+key);try{TimeUnit.SECONDS.sleep(3);}catch (InterruptedException e){e.printStackTrace();}map.put(key,value);System.out.println(Thread.currentThread().getName()+"写入完成");} catch (Exception e) {e.printStackTrace();} finally {readWriteLock.writeLock().unlock();}}public void get(String key){readWriteLock.readLock().lock();try {System.out.println(Thread.currentThread().getName()+"正在读取");try{TimeUnit.SECONDS.sleep(3);}catch (InterruptedException e){e.printStackTrace();}Object result=map.get(key);System.out.println(Thread.currentThread().getName()+"读取完成"+result);} catch (Exception e) {e.printStackTrace();} finally {readWriteLock.readLock().unlock();}}
}
public class ReadAndWriteLockDemo {public static void main(String[] args) {MyCache myCache=new MyCache();for (int i = 0; i < 5; i++) {final int temp=i;new Thread(()->{myCache.put(""+temp,""+temp);},String.valueOf(i)).start();}for (int i = 0; i < 5; i++) {final int temp=i;new Thread(()->{myCache.get(""+temp);},String.valueOf(i)).start();}}
}
9.CountDownLatch/CyclicBarrier/Semaphore使用过吗?
(1)CountDownLatch
public static void closeDoor() {try {CountDownLatch countDownLatch=new CountDownLatch(6);for (int i = 0; i < 6; i++) {new Thread(()->{System.out.println(Thread.currentThread().getName()+"------离开教室");countDownLatch.countDown();},String.valueOf(i)).start();}countDownLatch.await();System.out.println(Thread.currentThread().getName()+"*****锁门了");} catch (InterruptedException e) {e.printStackTrace();}
}

相当于一个线程的计数器,列入上面的代码来控制主线程最后执行

让一些线程阻塞知道另外一个线程完成一系列操作之后才会被唤醒

当计数器为0的时候,await()的线程才会被唤醒执行

(2)CyclicBarrier

相比较于CountDownLatch,CyclicBarrier是做加法,集齐七颗龙珠就可以召唤神龙

Cyclic:循环,Barrier:屏障

一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障,屏障才会开门所有被屏障拦截的线程才会继续干活

试例代码

public class CyclicBarrierDemo {public static void main(String[] args) {CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {System.out.println("********召唤神龙");});for (int i = 1; i <= 7; i++) {final int temp = i;new Thread(() -> {System.out.println(Thread.currentThread().getName() + "收集到" + temp + "颗");try{cyclicBarrier.await();}catch (Exception e){e.printStackTrace();}}, String.valueOf(i)).start();}}
}
(3)Semaphore (主要 处理所线程抢占多个资源,也可以充当锁)

信号量的主要作用有两个,一个是用于多个共享资源的互斥使用,另外一个是用于并发线程数的控制

for example 抢车位代码

public class SemaphoreDemo {public static void main(String[] args) {Semaphore semaphore=new Semaphore(3);//三个停车场for (int i = 1; i < 6; i++) {new Thread(()->{try {semaphore.acquire();System.out.println(Thread.currentThread().getName()+"抢到车位");try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"停车3秒后离开");} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}},String.valueOf(i)).start();}}
}
10.阻塞队列知道吗?
(1)阻塞队列有没有好的一面
(2)不得不阻塞,你如何管理

当阻塞队里是空的时候,从队列获取元素将会被阻塞

当阻塞队列是满的时候,往队列添加元素将会被阻塞

(3)BlockingQueue

1.ArrayBlockingQueue:由数组组成的有界阻塞队列

2.LinkedBlockindQueue:由链表结构组成的有界阻塞队列

3.PriorityBlockingQueue:支持优先级排序的无界阻塞队列

4.delayQueue:使用优先级实现延迟无界阻塞队列

5.SynchronousQueue:不存储单个元素的阻塞队列,也即单个元素队列

6.LinkedTransferQueue:由链表结构组成的阻塞队列

7.LinkedBlockingQueue:由链表结构组成的双向阻塞队列

(4)BlockingQueue API

1.返回值是布尔类型

抛出异常 特殊值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
检查 element() peek() 不可用 *不可用 *

2.用在哪里

生产消费者模式

  1. ​ 1.传统版,

    题目:一个初始值为零的变量,两个线程对其交替操作,一个加1,一个减1,来5轮

    public class ProductConsumer_traditionDemo {public static void main(String[] args) {ShareData shareData=new ShareData();new Thread(()->{for (int i = 1; i <=5 ; i++) {try {shareData.increment();} catch (Exception e) {e.printStackTrace();}}},String.valueOf("AA")).start();new Thread(()->{for (int i = 1; i <=5 ; i++) {try {shareData.decrement();} catch (Exception e) {e.printStackTrace();}}},String.valueOf("BB")).start();}
    }
    class ShareData{private int number=0;private Lock lock = new ReentrantLock(true);private Condition condition=lock.newCondition();public void increment(){lock.lock();try {while (number!=0){condition.await();}number++;System.out.println(Thread.currentThread().getName()+"\t"+number);/*唤醒线程*/condition.signalAll();} catch (Exception e) {e.printStackTrace();}finally {lock.unlock();}}public void decrement(){lock.lock();try {while (number==0){condition.await();}number--;System.out.println(Thread.currentThread().getName()+"\t"+number);/*唤醒线程*/condition.signalAll();} catch (Exception e) {e.printStackTrace();}finally {lock.unlock();}}
    }
    

    (注意)java多线程为什么要使用while而不是使用if

    问题的关键点在于wait方法执行之后,notify是从那里开始执行,如果是if的话第一次会执行if判断,第二次唤醒就会执行if下面内容

    补充

  2. ​ 2.阻塞队列版(高并发版本)

  3. class MyResource{private volatile boolean flag=true;private AtomicInteger atomicInteger=new AtomicInteger();BlockingQueue<String> blockingQueue=null;public MyResource(BlockingQueue<String> blockingQueue) {this.blockingQueue = blockingQueue;System.out.println(blockingQueue.getClass().getName());}public void prod() throws Exception{String data=null;boolean resultValue;while (flag){data=atomicInteger.incrementAndGet()+"";resultValue = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);if(resultValue){System.out.println(Thread.currentThread().getName()+"\t"+"插入数据成功"+data);}else{System.out.println(Thread.currentThread().getName()+"\t"+"插入数据失败"+data);}TimeUnit.SECONDS.sleep(1);}System.out.println(Thread.currentThread().getName()+"\t flag=false ,生产动作停止");}public void myconsumer() throws Exception{String data=null;while (flag){data=blockingQueue.poll(2L,TimeUnit.SECONDS);if(data==null||data.equalsIgnoreCase("")){flag=false;System.out.println(Thread.currentThread().getName()+"\t 消费退出");return;}System.out.println(Thread.currentThread().getName()+"\t 消费数据成功"+data);}}public void stop() throws Exception{this.flag=false;}
    }
    public class Product_ConsumerDemo {public static void main(String[] args)  throws Exception{MyResource myResource=new MyResource(new ArrayBlockingQueue<>(10));new Thread(()->{System.out.println(Thread.currentThread().getName()+"\t 生产线程启动");try {myResource.prod();} catch (Exception e) {e.printStackTrace();}},"Prod").start();new Thread(()->{System.out.println(Thread.currentThread().getName()+"\t 消费线程启动");try {myResource.myconsumer();} catch (Exception e) {e.printStackTrace();}},"Consumer").start();try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println("over");myResource.stop();}
    }
    

线程池

消息中间件

11.线程池有使用过吗,ThreadPoolExecutor谈谈你的理解(第四种获得java多线程的方式)
1.为什么要使用线程池
  • 降低资源消耗
  • 提高相应速度
  • 提高线程的可管理
2.线程池如何使用

​ 首先java中的线程池是通过Executor框架实现,该框架中用到了Executor,Executors(辅助工具类),ExecutorService,ThreadPoolExecutor(最主要的)

ExecutorService threadPool= Executors.newCachedThreadPool();
ExecutorService threadPool= Executors.newFixedThreadPool(5);
ExecutorService threadPool= Executors.newSingleThreadExecutor();
3.说说线程池几个重要的参数

ThreadPoolExecutor中7个参数:

  • corePoolSize:线程池中常驻核心线程数

  • maximumPoolSize:线程池可以容纳同时执行的最大线程数,此值必须大于等于1

  • keepAliveTime:多余空闲线程的存活时间(当前线程池线程数量超过corePoolSize,当空闲时间大于keepAliveTime,多余线程会被销毁直至达到corePoolSize)

  • unit:keepAliveTime的时间单位

  • workQueue:任务队列(阻塞队列,类似于银行的候客区)

  • threadFactory:生成线程池工厂

  • handler:拒绝策略(默认四种方法,最大线程数和阻塞队列都满了会执行拒绝策略)

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W239ypVW-1666103904161)(D:\Typora\pic\Snipaste_2021-01-14_08-47-36.png)]

4.说说线程池的底层原理(略)
5.线程资源必须通过线程池提供,不允许在应用中自行显示创建线程
6.你在工作中是如何使用线程池的,是否自定义过线程池的使用
7.在线程池中配置合理的线程数
cpu密集型,io密集型
12.synchronized和Lock有什么区别
1.原始构成

synchronized是关键字属于jvm层面,LOCK是具体类是api层面的锁

2.使用方法

synchronized不需要用户手动的释放锁,lock则需要用户手动的释放锁

3.等待是否可中断

synchronized是不可中断的,除非异常或者正常执行完成,lock 可中断

4.加锁是否公平
5.锁要绑定多个condition

synchronized 没有

ReentrantLock用来实现分组唤醒需要唤醒的线程,可以精确唤醒

for example:

题目:所线程之间按照顺序调用,实现A-》B-》C三个线程启动

public class SyncAndReentrantDemo {public static void main(String[] args) {ShareResource shareResource=new ShareResource();new Thread(()->{for (int i = 1; i <=10 ; i++) {shareResource.print5();}},"AA").start();new Thread(()->{for (int i = 1; i <=10 ; i++) {shareResource.print10();}},"BB").start();new Thread(()->{for (int i = 1; i <=10 ; i++) {shareResource.print15();}},"CC").start();}
}
class ShareResource{private int number =1;//a:1 b:2 c:3private Lock lock=new ReentrantLock();private Condition c1=lock.newCondition();private Condition c2=lock.newCondition();private Condition c3=lock.newCondition();public void print5(){lock.lock();try {while (number!=1){c1.await();}for (int i = 1; i <=5 ; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}number=2;c2.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void print10(){lock.lock();try {while (number!=2){c2.await();}for (int i = 1; i <=10 ; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}number=3;c3.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void print15(){lock.lock();try {while (number!=3){c3.await();}for (int i = 1; i <=15 ; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}number=1;c1.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}
}
13.死锁编码及定位分析
1.定义:两个及两个以上的线程的在执行的过程中,因争夺资源而造成的一种相互等待的现象
class HoldLockThread implements Runnable{private String LockA;    private String LockB;public HoldLockThread(String lockA, String lockB) {LockA = lockA;LockB = lockB;}@Overridepublic void run() {synchronized (LockA){System.out.println(Thread.currentThread().getName()+"持有的"+LockA+"尝试获得的"+LockB);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}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 HoldLockThread(LockA,LockB),"ThreadAAA").start();new Thread(new HoldLockThread(LockB,LockA),"ThreadBBB").start();}
}
2.解决办法

jps定位进程号

jstack找到死锁查看

14.jvm垃圾回收的时候如何确定垃圾? 是否知道GC Roots?

枚举根节点做可达性分析(根搜索路径)

GC Roots的对象作为起始点,从GC Roots对象开始向下搜索,如果一个对象没有任何引用链接的时候,表明该对象不可使用

(1)jvm中可以作为GC Roots的对象有哪些?
  • 1.虚拟机栈中引用的对象
  • 2.方法区中类静态属性引用的对象
  • 3.方法区中常量引用的对象
  • 4.本地方法栈中JNI(即一般说的Native方法)的引用对象
15,你说过你做过jvm调优和参数配置,请问如何盘点查看jvm系统默认值?
(1)jvm参数类型
  • 1.标配参数

    -version

    -help

    java -showversion

  • 2.X参数(了解)

    -Xint 解释执行

    -Xcomp 第一次使用就编译本地代码

    -Xmixed 混合模式

  • 3.XX参数

    boolean类型 :公式: -XX:+或者-某个属性值(+表示开启,-表示关闭)

    ​ 是否打印GC收集细节(PrintGCDetails) 、是否使用串行垃圾回收器(UseSerialGC)

    kv设值类型:公式:-XX:属性key=属性value

    ​ for example:-xx:MetaspaceSize=1024m(元空间的大小) -xx:MaxTenuringThreshold=15(eden区存活15轮)

    jinfo举例

  • 4.两个经典参数

    -Xms (等价于 -XX:InitalHeapSize) -Xmx (等价于 -XX:MaxHeapSize )

(2)如何查看一个正在运行的java程序,它的某个jvm参数是否开启?具体指是多少?
  • (1)第一种:

使用jps和jinfo的命令来查看

jinfo -flag 具体参数 java进程编号

  • (2)第二种方法

-XX:+PrintFlagIntial:主要查看默认的初始值,公式:java -XX:+PrintFlagIntial -version

-XX:+PrintFlagFinal:主要查看修改更新过后的参数值

15.你平时工作中jvm常用基本配置参数有哪些?
  • -Xms:初始内存大小,默认为物理内存的 1/64
  • -Xmx:最大分配内存,默认为物理内存的1/4
  • -Xss:设置单个线程栈的大小,一般为512k~1024k
  • -Xmn:设置年轻代的大小
  • -xx:MetaspaceSize=1024m(元空间的大小)
  • -XX:+PrintGCDetails (-Xmx10m -Xms10m -XX:+PrintGCDetails)
  • -XX:SurvivorRatio:设置新生代中Eden和S0、S1的空间比例,默认是8:1:1
  • -XX:NewRatio:设置年轻代和老年代在堆结构的占比
    -XX:MaxTenuringThreShold:设置垃圾最大的年龄,如果设置为0则年轻代对象不会经过Survivor区,对于老年代对象比较多的应用可以提高效率
16.强引用,软引用,弱引用,虚引用作用分别是什么?
  • 1.强引用:jvm开始垃圾回收的时候,就算出现OOM对于强引用对象也不进行回收,死都不回收,一般new出来的对象都是强引用
  • 2.软引用:内存足够的时候不回收,内存不够的时候回收,软引用通产用在对内存敏感的程序中,比如高速缓存,使用泛型SoftReference;可以通过get方法获得强引用
  • 3.弱引用:只要执行GC就会被回收 需要使用java.lang.WeekReference类来实现,你知道WeekHashMap吗?键值为null时候gc会被回收
  • 4.虚引用:任何时候都可能被垃圾回收器回收,gc后被放到引用队列中
17.请谈谈对OOM的认识?

StackOverFlowError:栈溢出异常,递归调用

OutofMemoryError:(1)java heap space (2)GC overhead limit exceeded :GC时间过长

(3)Direct buffer memory:例子:使用NIO的byteBuffer来读取或者写入数据

(4)unable to create new native thread 不能创建更多的本地线程

导致原因(1)应用创建了太多的线程 (2)服务器不允许创建这么多的线程,linux上默认允许单个进程创建的线程数量是1024个

(5)Metaspace 元空间不足

18.GC垃圾回收算法和垃圾回收器的关系?分别是什么请你谈谈
1.垃圾回收算法:

引用计数、复制、标记、标整、分代收集

2.四种垃圾回收器

1.serial 2.parallel 3.CMS 4.G1

19.如何查看服务器上默认的垃圾回收器是哪个?生产上是如何配置垃圾回收器的?谈谈你对垃圾回收器的理解?
20 jvmGC结合springboot微服务生产部署调优

21.生产环境服务器变慢,诊断思路和性能评估谈谈?
  • (1)整机 top

  • load average: 0.58, 0.41, 0.30 系统负载,即任务队列的平均长度。 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。
    如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了。
  • (2)CPU vmstat

  • vmstat -n 2 3 (2秒时间刷新间隔,刷新3次)

  • (3)内存:free

  • free -m 查看系统内存占用情况

  • pidstat -p 进程号 -r 采样间隔秒数

  • (4)硬盘:df (查看磁盘剩余空间)df -h

  • (5)磁盘 IO iostat

  • (6)网络IO ifstat

22.假如生产环境CPU占用率过高,解决办法
  • (1)使用TOP命令来找出CPU占比最高的进程
  • (2)ps -ef 或者JPS进一步定位,得知是怎样一个后台程序
  • (3)定位到具体的线程或者代码
  • (4)将需要的线程id转化为16进制格式
  • (5)jstack进程ID
23.对于jdk自带的jvm监控和性能分析工具用过哪些?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R8JTJiCt-1666103904162)(D:\Typora\pic\20200925125200430.png)]

24.github
1.常用词含义

(1)watch:会持续收到该项目的动态

(2)fork:赋值某个项目到自己的gitlab仓库中

(3)star:点赞

(4)clone:

(5)follow:

2.github常用命令

一般情况下git命令都是 git [command] [option] [argument]

git config --golobal user.name=“hic” 其中config指的就是配置命令 其中–global指的是对全局配置生效

3.in关键词搜索

xxx in:name 项目名包含XXX的,readme,description

4.star或者fork关键字搜搜

(1)公式:xxx关键词 star 通配符 :>或者:>= 区间范围 数字1…数字2

(2)查找stars数量大于5000的springboot项目 springboot stars:>5000

组合模式:springboot forks:100…200 stars:80…100

(3)awesome:awesome系列一般是用来收集学习,工具,书籍类的项目

(4)高亮显示 地址后面 #L行数-L行数

(5)项目内搜索 键盘英文t

25.字符串常量java内部加载

string::intern()是一个本地的方法,它的作用的是如果字符串常量池中已经包含了一个等于此String对象,则返回该对象的引用;

否则将会把此String对象包含的字符串添加到常量池中,并返回此String对象的引用。

Stirng str=new StringBuffer(“ja”).append(“va”).toString();

sout(str); sout(str.intern());sout(str==str.intern());

why:只有java显示的是false??有个初始化的java字符串然后进入常量池

26.AQS原理
1.可重入锁:是指同一个对象在外层方法获取锁后,再进入内层方法会自动获取锁(前提,锁对象是同一个对象),不会因为没有释放锁而导致阻塞防止发生死锁
2.可重入锁的种类:1.隐式锁 2.显示锁
3.locksupport:线程等待唤醒机制(wait/notify)

locksupport中的park()和unpark()的作用分别是阻塞线程和解除阻塞线程,locksupport类使用了一种命名为permit的概念来做到阻塞和唤醒线程的功能,每一个线程都有一个permit,permit只有两个值 0,1

为什么说AQS是JUC内容中最重要的基石?

27.什么是进程\线程\并发\并行

java面试一些问题汇总相关推荐

  1. 阿里最全Java面试100题汇总:涵盖天猫、蚂蚁金服等面试题!含答案~

    [阿里天猫.蚂蚁.钉钉面试题目] 1.微信红包怎么实现. 2.海量数据分析. 3.测试职位问的线程安全和非线程安全. 4.HTTP2.0.thrift. 5.面试电话沟通可能先让自我介绍. 6.分布式 ...

  2. Java面试通关要点汇总集(基础篇之基本功,非原作者)

    Java面试通关要点汇总集(部分解答) 说明 如果你有幸能看到的话, 1.本文整体框架来自@阿里.梁桂钊的博文,总结的非常不错.值得我们学习,它的博客部分做了解答. 2.由于自己能力有限,没能实现心中 ...

  3. Java面试通关要点汇总集【终极版】

    原文地址:梁桂钊的博客 博客地址:blog.720ui.com 年前,我整理的 Java面试通关要点汇总集 获得了很多读者的肯定,谢谢大家支持.事实上,笔者结合自己过往的面试经验,整理了一些核心的知识 ...

  4. java面试笔试大汇总(一)

    java面试笔试题大汇总5 JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象:2.继承:3.封装:4. 多态性: 2.String是最基本的数据类型吗? 基本数据类型包括byte.int. ...

  5. Java面试题目大汇总(附参考答案)

    足足准备了长达3个月的面试,终于在上周拿到了阿里的offer! 博主汇总整理了一份我面试之前看的一些Java面试题目,可以说是非常详细! 分享给大家,希望对正在面试Java岗位的朋友有帮助哈~~ (文 ...

  6. 史上最全阿里Java面试题目大汇总!强烈建议收藏~

    阿里面试题目目录 技术一面(基础面试题目) 技术二面(技术深度.技术原理) 项目实战(项目模拟面试) JAVA开发技术常问的问题 阿里必会知识 阿里面试范畴 阿里面试总结 一:阿里技术一面(基础掌握牢 ...

  7. java面试高频知识点汇总 2021-02-24

    杂碎知识点1 大四开始找工作后遇到的面试题进行汇总,因为之前记录的都是在有道云中,复制到简书出现格式的问题,大致修补了一下,后续继续上传. 1.Integer缓存池问题 当给Integer赋值在-12 ...

  8. Java开发者跳槽必备:2021阿里Java面试题目大汇总

    5.高并发 6.中间件 7.之前项目经历,运用的技术,遇到的问题,如何解决,个人有什么收获和成长: 8.对于技术的热情(平时是否看些技术书籍,逛论坛,写博客,写源代码或程序等): JAVA开发技术面试 ...

  9. Java面试通关要点汇总集(山东数漫江湖)

    这里,笔者结合自己过往的面试经验,整理了一些核心的知识清单,帮助读者更好地回顾与复习 Java 服务端核心技术.本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进行详细的剖析与解答.敬 ...

  10. Java面试通关要点汇总集之核心篇参考答案

    2019独角兽企业重金招聘Python工程师标准>>> 数据存储 MySQL 索引使用的注意事项 1.索引不会包含有NULL的列 只要列中包含有NULL值,都将不会被包含在索引中,复 ...

最新文章

  1. mapx实现热点效果
  2. C#Winform控件随窗体缩放
  3. httpwatchv11.1.46.0免费版
  4. Webbench网站压力测试
  5. 任务间通信的基本知识
  6. DHCP 服务原理:Snooping和Relay
  7. CentOS7.5下搭建zabbix3.4监控
  8. CF1444C Team-Building(可持久化并查集)(二分图)
  9. java圆形头像上传_Android自定义控件实例,圆形头像(图库 + 裁剪+设置),上传头像显示为圆形,附源码...
  10. python网络编程基础语法_python网络编程
  11. Html前端基础(这些基础标签你必须知道!)
  12. 目标成为Photoshop的轻量级替代软件——Acorn Mac版
  13. Swift基础语法: 21 - Swift的可变形形参, 常量形参, 变量形参, In-Out形参
  14. Proteus仿真Arduino的Proteus Library文件下载
  15. (三)进程各种id:pid、pgid、sid、全局pid、局部pid
  16. 通过PS抠出透明的玻璃瓶
  17. dummy node
  18. 苹果iOS 8.0正式发布啦
  19. 工业机器人组成结构【拆卸 / 组装 KUKA 工业机器人】
  20. 七牛 savekey php,七牛云1:客户端直接上传文件

热门文章

  1. D-U-N-S Number 邓白氏编码申请流程
  2. 传统支付方式不能满足线下支付的需求
  3. 平台经济中国案例研究平台经济、系统性思考结合个人陈述的分析(Platform-Economics)
  4. 利用百度地图查询全国地铁线路
  5. 原链YCC落地应用之仓单金融
  6. 《皮肤的秘密》 读书笔记
  7. ONES Talk | 我们为什么选择最难走的软件之路
  8. 最好用的地图匹配框架——基于HMM的Valhalla
  9. 来一份Android动画全家桶
  10. opencv-双边滤波