-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
互联网大厂高频重点面试题第2季(上) 课程笔记:思维导图+Demo代码
- Loading branch information
Showing
23 changed files
with
949 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
import java.util.concurrent.atomic.AtomicStampedReference; | ||
|
||
/* | ||
* ABA问题的解决 AtomicStampedReference | ||
* */ | ||
public class ABADemo { | ||
static AtomicReference<Integer> atomicReference = new AtomicReference<>(100); | ||
static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100,1); | ||
|
||
|
||
public static void main(String[] args){ | ||
new Thread(()->{ | ||
atomicReference.compareAndSet(100,101); | ||
atomicReference.compareAndSet(101,100); | ||
},"t1").start(); | ||
|
||
new Thread(()->{ | ||
// 暂停1秒钟线程2,保证上面t1线程完成一次ABA操作 | ||
try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace();} | ||
System.out.println(atomicReference.compareAndSet(100,2019)+"\t"+atomicReference.get()); | ||
},"t2").start(); | ||
|
||
try{TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();} | ||
|
||
System.out.println("======以下是ABA问题的解决====="); | ||
new Thread(()->{ | ||
int stamp = atomicStampedReference.getStamp(); | ||
System.out.println(Thread.currentThread().getName()+"\t第1次版本号:"+stamp); | ||
|
||
// 暂停1秒钟t3线程 | ||
try{TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();} | ||
atomicStampedReference.compareAndSet(100,101,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1); | ||
System.out.println(Thread.currentThread().getName()+"\t第2次版本号:"+atomicStampedReference.getStamp()); | ||
atomicStampedReference.compareAndSet(101,100,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1); | ||
System.out.println(Thread.currentThread().getName()+"\t第3次版本号:"+atomicStampedReference.getStamp()); | ||
},"t3").start(); | ||
|
||
new Thread(()->{ | ||
int stamp = atomicStampedReference.getStamp(); | ||
System.out.println(Thread.currentThread().getName()+"\t第1次版本号:"+stamp); | ||
|
||
// 暂停1秒钟t4线程 | ||
try{TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();} | ||
boolean result = atomicStampedReference.compareAndSet(100,2019,stamp,atomicStampedReference.getStamp()+1); | ||
|
||
System.out.println(Thread.currentThread().getName()+"\t修改成功否: "+result+"\t当前最新实际版本号:"+atomicStampedReference.getStamp()); | ||
|
||
},"t4").start(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import javax.jws.soap.SOAPBinding; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
class User{ | ||
String userName; | ||
int age; | ||
} | ||
public class AtomicReferenceDemo { | ||
public static void main(String[] args){ | ||
AtomicReference<User> atomicReference = new AtomicReference<>(); | ||
|
||
// User z3 = new User("z3",22); | ||
// User li4 = new User("li4",25); | ||
|
||
// atomicReference.set(z3); | ||
// System.out.println(atomicReference.compareAndSet(z3,li4)+"\t"+atomicReference.get().toString()); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import java.util.List; | ||
import java.util.concurrent.ArrayBlockingQueue; | ||
import java.util.concurrent.BlockingQueue; | ||
|
||
/* | ||
* ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 | ||
* LinkedBlockingQueue:是一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量高于ArrayBlockingQueue | ||
* SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移出操作,否则插入操作一直处于 | ||
* 阻塞状态,吞吐量通常要高 | ||
* | ||
* | ||
* | ||
* 2.阻塞队列 | ||
* 2.1阻塞队列有没有好的一面 | ||
* 2.2不得不阻塞,你如何管理 | ||
* */ | ||
public class BlockingQueueDemo { | ||
public static void main(String[] args) throws Exception{ | ||
// List list = null; | ||
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3); | ||
// 往阻塞队列添加元素 | ||
System.out.println(blockingQueue.add("a")); | ||
System.out.println(blockingQueue.add("b")); | ||
System.out.println(blockingQueue.add("c")); | ||
|
||
// 从阻塞队列取元素 | ||
System.out.println(blockingQueue.element()); | ||
|
||
System.out.println(blockingQueue.remove()); | ||
System.out.println(blockingQueue.remove()); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
/* | ||
* 1、CAS是什么? ==>compareAndSet | ||
* 比较并交换 | ||
* */ | ||
public class CASDemo { | ||
public static void main(String[] args){ | ||
AtomicInteger atomicInteger = new AtomicInteger(5); | ||
System.out.println(atomicInteger.compareAndSet(5,2019)+"\t current data: "+atomicInteger.get()); | ||
System.out.println(atomicInteger.compareAndSet(5,1024)+"\t current data: "+atomicInteger.get()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import java.util.concurrent.Callable; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.FutureTask; | ||
|
||
/*class MyThread implements Runnable{ | ||
public void run(){ | ||
} | ||
}*/ | ||
|
||
class MyThread implements Callable<Integer> { | ||
public Integer call() throws Exception{ | ||
System.out.println(".........come in callable"); | ||
return 1024; | ||
} | ||
} | ||
|
||
/* | ||
* | ||
* */ | ||
public class CallableDemo { | ||
public static void main(String[] args) throws InterruptedException, ExecutionException { | ||
FutureTask<Integer> futureTask = new FutureTask<>(new MyThread()); | ||
Thread t1 = new Thread(futureTask,"AA"); | ||
t1.start(); | ||
int r1 = 100; | ||
int r2 = futureTask.get();//要求获得Callable线程的计算结果,如果没有计算完成就要强求,会导致阻塞,知道计算完成,建议放在最后 | ||
|
||
System.out.println(".....result"+r1+r2); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import java.util.*; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
||
/* | ||
* 集合类不安全问题:原因是为了保证并发性,add操作没有加锁 | ||
* ArrayList | ||
* */ | ||
public class ContainerNotSafeDemo { | ||
public static void main(String[] args){ | ||
// List<String> list = new ArrayList<>(); | ||
// List<String> list = Collections.synchronizedList(new ArrayList<>()); | ||
List<String> list = new CopyOnWriteArrayList<>(); | ||
for(int i=1;i<=3;i++){ | ||
new Thread(()->{ | ||
list.add(UUID.randomUUID().toString().substring(0,8)); | ||
System.out.println(list); | ||
},String.valueOf(i)).start(); | ||
} | ||
// java.util.ConcurrentModificationException | ||
/* | ||
* 1 故障现象 | ||
* java.util.ConcurrentModificationException | ||
* | ||
* 2 导致原因 | ||
* 并发争抢修改导致,参考我们的花名册签名情况。 | ||
* 一个人正在写入,另一个同学过来抢夺,导致数据不一致异常。并发修改异常。 | ||
* 3 解决方案 | ||
* 3.1 new Vector<>(); | ||
* 3.2 Collections.synchronizedList(new ArrayList<>()); | ||
* 3.3 new CopyOnWriteArrayList<>() | ||
* 写时复制 | ||
* CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加, | ||
* 而是先将当前object[]进行Copy,复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements | ||
* 里添加元素,添加完元素之后,再将原容器的引用指向新的容器setArray(newElements);这样做的好处是可以对 | ||
* copyonwrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以copyonwrite容器也是一种 | ||
* 读写分离的思想,读和写不同的容器。 | ||
* | ||
* 4 优化建议 | ||
* */ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* | ||
* */ | ||
public class CountDownLatch { | ||
public static void main(String[] args) throws Exception{ | ||
java.util.concurrent.CountDownLatch countDownLatch = new java.util.concurrent.CountDownLatch(6); | ||
|
||
for(int i=1;i<=6;i++){ | ||
new Thread(()->{ | ||
System.out.println(Thread.currentThread().getName()+"\t 上完自习,离开教室"); | ||
countDownLatch.countDown(); | ||
},String.valueOf(i)).start(); | ||
} | ||
|
||
countDownLatch.await(); | ||
System.out.println(Thread.currentThread().getName()+"\t *****班长最后关门走人"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import java.util.concurrent.BrokenBarrierException; | ||
import java.util.concurrent.CyclicBarrier; | ||
|
||
/* | ||
* | ||
* */ | ||
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 tempInt = i; | ||
new Thread(()->{ | ||
System.out.println(Thread.currentThread().getName()+"\t 收集到第:"+tempInt+"龙珠"); | ||
try{ | ||
cyclicBarrier.await(); | ||
} catch (InterruptedException e){ | ||
e.printStackTrace(); | ||
} catch (BrokenBarrierException e){ | ||
e.printStackTrace(); | ||
} | ||
|
||
},String.valueOf(i)).start(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* 死锁是指两个或者两个以上的进程在执行过程中,因抢夺资源而造成的一种互相等待的现象, | ||
* 若无外力干涉它们将都无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足, | ||
* 死锁出现的可能性也就很低,否则就会因争夺有限的资源而陷入死锁。 | ||
* */ | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
class HoldLockThread implements Runnable{ | ||
private String lockA; | ||
private String lockB; | ||
|
||
public HoldLockThread(String lockA,String lockB){ | ||
this.lockA = lockA; | ||
this.lockB = lockB; | ||
} | ||
|
||
public void run(){ | ||
synchronized (lockA){ | ||
System.out.println(Thread.currentThread().getName()+"\t自己持有:"+lockA+"\t尝试获得:"+lockB); | ||
//暂停一下 | ||
try{ TimeUnit.SECONDS.sleep(2); }catch (InterruptedException e){e.printStackTrace();} | ||
|
||
synchronized (lockB){ | ||
System.out.println(Thread.currentThread().getName()+"\t自己持有:"+lockB+"\t尝试获得:"+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(); | ||
|
||
/* | ||
* linux ps -ef|grep xxxx ls -l查看当前进程的命令 | ||
* windows下的java运行程序,也有类似ps的查看进程的命令,但是目前我们需要查看的只是java | ||
* jps = java ps jps -l | ||
* jstack | ||
* */ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* 在java中可作为GC Roots的对象有: | ||
* 1.虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。 | ||
* 2.方法区中的类静态属性引用的对象。 | ||
* 3.方法区中常量引用的对象 | ||
* 4.本地方法栈中JNI(Native方法)引用的对象。 | ||
* */ | ||
public class GCRootDemo { | ||
private byte[] byteArray = new byte[100*1024*1024]; | ||
|
||
public static void m1(){ | ||
GCRootDemo t1 = new GCRootDemo(); | ||
System.gc(); | ||
System.out.println("第一次GC完成"); | ||
} | ||
|
||
public static void main(String[] args){ | ||
m1(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
public class HelloGC { | ||
public static void main(String[] args) throws InterruptedException { | ||
System.out.println("......Hello GC"); | ||
Thread.sleep(Integer.MAX_VALUE); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
*第4种获得/使用java多线程的方式,通过线程池 | ||
* (其他三种是:继承Thread类;实现Runnable接口,但是Runnable没有返回值,不抛异常; | ||
* 实现Callable接口,有返回值,会跑出异常) | ||
* */ | ||
|
||
import java.util.concurrent.*; | ||
|
||
//System.out.println(Runtime.getRuntime().availableProcessors()); | ||
//Array Arrays 辅助工具类 | ||
//Collection Collections | ||
//Executor Executors | ||
public class MyThreadPoolDemo { | ||
public static void main(String[] args){ | ||
ExecutorService threadPool = new ThreadPoolExecutor(2, | ||
5, | ||
1L, | ||
TimeUnit.SECONDS, | ||
new LinkedBlockingQueue<>(3), | ||
Executors.defaultThreadFactory(), | ||
new ThreadPoolExecutor.DiscardPolicy()); | ||
|
||
try{ | ||
for(int i=1;i<=11;i++){ | ||
threadPool.execute(()->{ | ||
System.out.println(Thread.currentThread().getName()+"\t 办理业务"); | ||
}); | ||
} | ||
}catch (Exception e){ | ||
e.printStackTrace(); | ||
}finally { | ||
threadPool.shutdown(); | ||
} | ||
} | ||
|
||
private static void threadPoolInit() { | ||
//ExecutorService threadPool = Executors.newFixedThreadPool(5);//一池5个处理线程 | ||
//ExecutorService threadPool = Executors.newFixedThreadPool(1);//一池1个线程 | ||
ExecutorService threadPool = Executors.newCachedThreadPool();//一池N个线程 | ||
|
||
//模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程 | ||
try{ | ||
for(int i=1;i<=10;i++){ | ||
threadPool.execute(()->{ | ||
System.out.println(Thread.currentThread().getName()+"\t 办理业务"); | ||
}); | ||
} | ||
}catch (Exception e){ | ||
e.printStackTrace(); | ||
}finally { | ||
threadPool.shutdown(); | ||
} | ||
} | ||
} |
Oops, something went wrong.