快手一面
08.07 快手一面
自我介绍
研究生期间学了哪些课程?
介绍一下项目,说一下你负责的部分
项目怎么识别用户登录的状态的呢?
项目用到了微服务,微服务有什么好处?
项目里Redis做什么用?
向Redis中存短信验证码的命令是什么?设置过期时间的命令是什么?可以一条命令解决吗?
存储命令:
set phoneNumber code
过期命令:
expire phoneNumber 120
一条命令:
set phoneNumber code ex 120
如果执行存储命令后,设置过期命令失效了,该怎么办?
Redis中有内存淘汰策略LRU和LFU,可以解决这个问题。
LRU是:。。。。
LFU是:。。。。
你还用了RabbitMQ,说说是怎么用的?解决了什么问题?
说一说项目里面微信支付的流程
微信支付返回的结果是给前端还是后台?
String是不可变的,那么StringBuffer和StringBuilder是如何实现可变的呢?底层是什么?
StringBuffer和StringBuilder的底层是没有加
final
的char[]
数组,默认长度是16,每次扩容大小为原长度 * 2 + 2
;通过含参构造添加元素时。
- 直接添加一个长度。数组的初始长度为该传入的长度;
- 直接添加一个字符串。数组的初始长度为该字符串的长度+16(str.length+16)。每次扩容为数组
原长度 * 2 + 2
;
突然自己想到一个问题:StringBuffer是怎么实现线程安全的呢?
因为StringBuffer中很多方法上都是用synchronized关键字修饰的。
如果让你来实现StringBuffer和StringBuilder,你会怎么实现?
介绍一下HashMap
HashMap为什么线程不安全?
那ConcurrentHashMap是怎么实现线程安全的?
1.8之前ConcurrentHashMap支持多少线程同时操作?
你提到了synchronized和ReentrantLock,那说一说这两个具体的实现?
你说ReentrantLock是可重入的,那synchronized是可重入的吗?为什么?
synchronized是可重入锁,每个可重入锁都会关联一个线程ID和一个锁状态status。
当一个线程请求方法时,会去检查锁状态。
- 如果锁状态是0,代表该锁没有被占用,使用CAS操作获取锁,将线程ID替换成自己的线程ID。
- 如果锁状态不是0,代表有线程在访问该方法。此时,如果线程ID是自己的线程ID,且是可重入锁,会将status自增1,然后获取到该锁,进而执行相应的方法;如果是非重入锁,就会进入阻塞队列等待。
在释放锁时,
- 如果是可重入锁的,每一次退出方法,就会将status减1,直至status的值为0,最后释放该锁。
- 如果非可重入锁的,线程退出方法,直接就会释放该锁。
如果发生异常,synchronized会释放锁吗?为什么?
如果发生异常,并且没有捕获异常,整个执行流程会立即终止,退出代码块,并释放锁。
知道ThreadLocal吗?介绍一下ThreadLocal的结构
ThreadLocal为什么会引起内存泄漏问题?怎么解决?
反转链表
最长递增子序列