经典面试题
- 分布式之数据库和缓存双写一致性方案解析
- 先更新DB,再更新CACHE
- 线程A更新DB值=1
- 线程B更新DB值=2
- 线程B更新CACHE值=2
- 线程A更新CACHE值=1
- 最终缓存中是脏数据1
- 先更新CACHE,再更新DB
- 线程A淘汰CACHE=0,更新DB=1
- 线程B获取CAHCE不存在,更新DB=2
- 线程B更新CACHE=2
- 线程A更新CACHE=1
- 如何解决? — 延迟双删政策
- 先淘汰缓存
- 在写数据库
- 休眠1s,再淘汰缓存
- 如果删除缓存再失败?— 异步线程去淘汰:使用MQ或者订阅binlog
- 先更新DB,再更新CACHE
- 高并发的核心技术-幂等的实现方案
- 先查询再检验
- 唯一性索引
- Mysql insert into ….. on duplicate key update xxx = now()
- 悲观锁
- 版本号乐观锁
- 状态机
- 题目:编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。如:ABCABCABC……
使用Lock实现
public static void main(String[] args) {
OrderPrintTestCase1 testCase1 = new OrderPrintTestCase1();
Thread a = new Thread(()-> {testCase1.print(0);},"A");
Thread b = new Thread(()-> {testCase1.print(1);},"B");
Thread c = new Thread(()-> {testCase1.print(2);},"C");
a.start();
b.start();
c.start();
}
private int indexCount = 0;
private int mod = 3;
private int loop = 10;
private static ReentrantLock lock = new ReentrantLock(true);
private void print(int threadIndex) {
for (int i = 0; i < loop; ) {
try {
lock.lock();
if (indexCount % mod == threadIndex) {
System.out.println(Thread.currentThread().getName());
indexCount++;
i++;
}
} finally {
lock.unlock();
}
}
}
使用wait notify实现
public static void main(String[] args) {
OrderPrintTestCase1 testCase1 = new OrderPrintTestCase1();
Thread a = new Thread(()-> {testCase1.print(0);},"A");
Thread b = new Thread(()-> {testCase1.print(1);},"B");
Thread c = new Thread(()-> {testCase1.print(2);},"C");
a.start();
b.start();
c.start();
}
private int indexCount = 0;
private int mod = 3;
private int loop = 10;
private static ReentrantLock lock = new ReentrantLock(true);
private void print(int threadIndex) {
for (int i = 0; i < loop; ) {
try {
lock.lock();
if (indexCount % mod == threadIndex) {
System.out.println(Thread.currentThread().getName());
indexCount++;
i++;
}
} finally {
lock.unlock();
}
}
}
todo: 更好的解法?https://www.yuque.com/huishuohuadeyaba/snpoe3/nasqub
- 让3个线程顺序打印数字,如线程1打印1-5,线程2打印6-10,线程3打印11-15,然后是线程1打印16-20…一直打印到75结束。
//此题为上一题衍生,只要每个线程每次占有资源时,打印5次即可。
public static void main(String[] args) {
OrderPrintTestCase1 testCase1 = new OrderPrintTestCase1();
Thread a = new Thread(()-> {testCase1.print(0);},"A");
Thread b = new Thread(()-> {testCase1.print(1);},"B");
Thread c = new Thread(()-> {testCase1.print(2);},"C");
a.start();
b.start();
c.start();
}
private int indexCount = 0;
private int mod = 3;
private int loop = 10;
private static ReentrantLock lock = new ReentrantLock(true);
private void print(int threadIndex) {
for (int i = 0; i < loop; ) {
try {
lock.lock();
if (indexCount % mod == threadIndex) {
System.out.println(Thread.currentThread().getName());
indexCount++;
i++;
}
} finally {
lock.unlock();
}
}
}
现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?
public static void main(String[] args) {
OrderPrintTestCase1 testCase1 = new OrderPrintTestCase1();
Thread a = new Thread(()-> {testCase1.print(0);},"A");
Thread b = new Thread(()-> {testCase1.print(1);},"B");
Thread c = new Thread(()-> {testCase1.print(2);},"C");
a.start();
b.start();
c.start();
}
private int indexCount = 0;
private int mod = 3;
private int loop = 10;
private static ReentrantLock lock = new ReentrantLock(true);
private void print(int threadIndex) {
for (int i = 0; i < loop; ) {
try {
lock.lock();
if (indexCount % mod == threadIndex) {
System.out.println(Thread.currentThread().getName());
indexCount++;
i++;
}
} finally {
lock.unlock();
}
}
}
「阿里面试系列」面试加分项,从JVM层面了解线程的启动和停止
7. 如何设计一个秒杀系统
面试必会:Cookie和Session的区别? | 区别 | Cookie | Session | | —- | —- | —- | | 存放位置 | 在Client存放 | 在Server存放 | | 数据类型 | 保存的是String类型 | 保存的是Object类型 | | 生命周期 | 可以长期保存在Client | 数据随会话的结束而结束 | | 数据安全 | 保存不重要的数据 | 保存重要的数据 | | 限制 | 浏览器最多能创建300个;每个最大4kb;一个WEB站点最多存20个Cookie |
|
作者
URL | 备注 |
---|---|
https://my.oschina.net/tinyframework/ | 恒生架构师罗果 |
https://mp.weixin.qq.com/s/7F32Ni059ZiDW0YXxk61ng | 面试 |
https://www.cnblogs.com/fangjian0423/p/springMVC-interceptor.html | 阿里-SpringMVC技术博客 |
https://blog.csdn.net/javazejian?t=1 | JUC相关 |
https://blog.csdn.net/quhongwei_zhanqiu | 栈秋 |
https://github.com/doocs/advanced-java | 互联网 Java 工程师进阶知识完全扫盲 |
博客
金三银四跳槽季,Java面试大纲
https://www.toutiao.com/a6658965048179819021/
BAT最全Java面试168题汇总:并发编程+JVM+Spring+分布式+缓存等!
蚂蚁金服的一次面试经历分享!(一面、二面)
回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议
Java 集合框架综述