9号、10号各一个面试,把自己答得不好或者没答上的题整理了一下
目录
2020年6月9号
一面
一、redis大key的问题
- 大key出现的原因
- 单个简单的key存储的value很大
- hash, set,zset,list 中存储过多的元素(以万为单位)
- 解决方法
对于string类型
可以对大key进行拆分,使用mset key1 value1 key2 value2
mset key1 1 key2 2
OK
mget key1 key2
1) "1"
2) "2"
或者使用hash类型存储.
hset keys key1 1 key2 2
(integer) 2
hget keys key1
"1"
hget keys key2
"2"
对于list,hash,set,zset
可以通过下面方法进行简单的计算进行获取指定的数据
hset key1 field1 1 field2 2 field3 3
(integer) 3
hset key2 field4 4 field5 5 field6 6
(integer) 3
二、HTTPS的流程
总结在这篇博客里了:https://blog.csdn.net/willlu10/article/details/106693783
三、concurrentHashmap存数据的方式
https://blog.csdn.net/willlu10/article/details/106721364
二面
一、代理模式的思想
(面试的时候,没说到点上)
指为其它对象提供一种代理,以控制对这个对象的访问。
代理对象在客户端和目标对象之间起到中介作用,代理模式属于结构性设计模式。使用代理模式主要有两个目的:
一是保护目标对象
二是增强目标对象
参考:https://www.cnblogs.com/yinyj/p/11595173.html
二、NIO
(生疏了,简单复习一下)
非阻塞的IO
1.buffer:缓冲区
2.channel:双向的通道
3.selector:轮询访问通道访问通道的SelectionKey状态,例如 OP_ACCEPT OP_READ
三、Lock
AQS (依赖AQS实现了很多 并发工具,比如 ReentrantLook、ReentrantReadWriteLook、CountDownLatch)
(1).int类型变量 state 表示锁状态
(2).内置的FIFIO双向队列(通过内部类Node来实现的)
Lock (ReentrantLook重入锁,ReentrantReadWriteLook读写锁)
ReentrantLook重入锁
公平锁会判断当前线程是否有前驱节点,如果有不会获取当前的锁(或者叫同步状态),非公平锁不会判断
重入的方式是state+1 release的方式是state-1。state==0的时候,锁释放
ReentrantReadWriteLook读写锁
读写状态通过按位切割来实现,一个32位的变量,前16位表示读状态,后16位表示写状态。
如果存在读锁,写锁不能被获取。重入的话把32位的变量+1
读锁可以被多个线程获取,把那个32位的变量的前16位加+1(1<<16)。如果其他线程已经获取写锁,那么读锁获取就会失败
锁降级:当前拥有写锁,并获取了读锁,然后将写锁释放。(不是或许写锁,释放写锁,获取读锁。)
CountDownLatch
共享锁的思想
如果给一个CountDownLatch变量设置初始值为100 相当于将AQS的state初始值赋值为100
CountDownLatch countDownLatch = new CountDownLatch(1000);
构造函数点进去
CountDownLatch 的await()就是获取共享同步状态的过程,state+1
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
CountDownLatch 的countDown()就是释放同步状态的过程 state-1
public void countDown() {
sync.releaseShared(1);
}
参考:
《Java并发编程的艺术》
四、sleep和wait的区别(只说了前两点)
-
sleep()是Thread的方法,wait()是Object的方法
- sleep()必须有参数,设定一个过期时间,wait()可以没参数
- sleep()不会释放锁,只是让锁暂时休息一段时间.wait()会释放锁,使用notify() notifyAll()唤醒锁。
- sleep()必须捕获异常,wait()不需要
2020年6月10号
一、垃圾回收器
serial 新生代 STW(stop the world) 单线程 复制算法
parNew 新生代 STW 多线程 复制算法
parallel scavenge 新生代 复制算法 关注吞吐量 吞吐量=运行用户代码的时间 /(运行用户代码的时间+GC时间)
serial old serial的老年代版本 STW 单线程 标记-整理算法
parallel old (parallel scavenge的老年代版本)标记-整理
CMS 老年代
四个过程 1.初始标记 2.并发标记 3.重新标记 4.并发清除 其中初始标记,重新标记STW
G1
把堆划分为不同的区域(新生代、老年代等)
四个过程:1、初始标记 2、并发标记 3、最终标记 4、筛选回收 其中初始标记,最终标记STW
参考
《深入理解Java虚拟机》
二、编程题 最短路径和
最短路径和:https://leetcode-cn.com/problems/minimum-path-sum/ 动态规划
public static int minPath(int [][] m){
int arr [] =new int [m[0].length];
arr[0]=m[0][0];
for (int i = 1 ; i<m[0].length;i++){
arr[i]=m[0][i]+arr[i-1];
}
for (int i = 1;i<m.length;i++){
arr[0]=m[i][0]+arr[0];
for (int j = 1;j<m[0].length;j++){
arr[j] = m[i][j]+Math.min(arr[j-1],arr[j]);
}
}
return arr[arr.length-1];
}
三、四种线程池的拒绝策略
AbortPolicy:丢弃任务,直接抛出异常
CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
DiscardPolicy 丢弃任务,但是不抛出异常
还可以实现RejectedExecutionHandler接口自定义策略
参考
1. https://blog.csdn.net/suifeng629/article/details/98884972
2.《Java并发编程的艺术》