面试题解决它

1.库分表id如何生成的,怎样保证全局唯一?

推特snakeflow算法,什么UUID,数据生成好像用得少

2.线上内存溢出怎么排查解决的?

3.分布式锁有哪些实现方式

  • zookeeper实现
    创建临时有序节点,取出最小的一个节点且是自己创建的则获得锁,删除节点释放锁,设置超时时间

  • redis实现
    setnx key value 命令表示当且仅当key不存在时才设置,返回结果1,否则返回0,
    且要设置超时时间 参见官网说明及锁的问题与解决方案

    1
    2
    3
    4
    5
    6
    7
    redis> SETNX mykey "Hello"
    (integer) 1
    redis> SETNX mykey "World"
    (integer) 0
    redis> GET mykey
    "Hello"
    redis>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    解决死锁
    考虑一种情况,如果进程获得锁后,断开了与 Redis 的连接(可能是进程挂掉,或者网络中断),如果没有有效的释放锁的机制,那么其他进程都会处于一直等待的状态,即出现“死锁”。
    上面在使用 SETNX 获得锁时,我们将键 lock.foo 的值设置为锁的有效时间,进程获得锁后,其他进程还会不断的检测锁是否已超时,如果超时,那么等待的进程也将有机会获得锁。
    然而,锁超时时,我们不能简单地使用 DEL 命令删除键 lock.foo 以释放锁。考虑以下情况,进程C1已经首先获得了锁 lock.foo,然后进程C1挂掉了。进程C2,C3正在不断地检测锁是否已释放或者已超时,执行流程如下:
    C2和C3进程读取键 lock.foo 的值,检测锁是否已超时(通过比较当前时间和键 lock.foo 的值来判断是否超时)
    C2和C3进程发现锁 lock.foo 已超时
    C2执行 DEL lock.foo命令
    C2执行 SETNX lock.foo命令,并返回1,即C2获得锁
    C3执行 DEL lock.foo命令将C2刚刚设置的键 lock.foo 删除(这步是由于C3刚才已检测到锁已超时)
    C3执行 SETNX lock.foo命令,并返回1,即C3获得锁
    C2和C3同时获得了锁
    从上面的情况可以得知,在检测到锁超时后,进程不能直接简单地执行 DEL 删除键的操作以获得锁。
    为了解决上述算法可能出现的多个进程同时获得锁的问题,我们再来看以下的算法。
    我们同样假设进程C1已经首先获得了锁 lock.foo,然后进程C1挂掉了。接下来的情况:
    进程C4执行 SETNX lock.foo 以尝试获取锁
    由于进程C1已获得了锁,所以C4执行 SETNX lock.foo 返回0,即获取锁失败
    C4执行 GET lock.foo 来检测锁是否已超时,如果没超时,则等待一段时间,再次检测
    如果C4检测到锁已超时,即当前的时间大于键 lock.foo 的值,C4会执行以下操作
    GETSET lock.foo <current Unix timestamC + lock timeout + 1>
    由于 GETSET 操作在设置键的值的同时,还会返回键的旧值,通过比较键 lock.foo 的旧值是否小于当前时间,可以判断进程是否已获得锁
    假如另一个进程C5也检测到锁已超时,并在C4之前执行了 GETSET 操作,那么C4的 GETSET 操作返回的是一个大于当前时间的时间戳,这样C4就不会获得锁而继续等待。注意到,即使C4接下来将键 lock.foo 的值设置了比C5设置的更大的值也没影响。
    另外,值得注意的是,在进程释放锁,即执行 DEL lock.foo 操作前,需要先判断锁是否已超时。如果锁已超时,那么锁可能已由其他进程获得,这时直接执行 DEL lock.foo 操作会导致把其他进程已获得的锁释放掉。
  • memcached实现
    实现原理:memcached带有add函数,利用add函数的特性即可实现分布式锁
    add会添加第一个到达的值,并返回true,后续的添加则都会返回false
    1、memcached采用列入LRU置换策略,内存不够可能导致缓存中的锁信息丢失
    2、memcached无法持久化,一旦重启,将导致信息丢失
    3、加上超时时间避免死锁

3.jdk1.8的特性

  1. 接口的默认方法
  2. Lambda 表达式
  3. 函数式接口
  4. 方法与构造函数引用
  5. Lambda 作用域
  6. 访问局部变量
  7. 访问对象字段与静态变量
  8. Annotation 多重注解
  9. 日期API
  10. 访问接口的默认方法
  11. 总有种鸡肋的感觉,然而面试必问

4.一致性hash

5.算法

  • 心病,永远都准备不完

6.分库分表原理,方案

  • 当当sharding-jdbc, 阿里TDDL,还有Cobar、myCat;
  • 少有机会搞这玩意,实战少
  • 还是再读读书 大型分布式网站架构设计与实践

7.AQS与CAS

  • 先啃啃书 Java并发编程的艺术 再后补

8. 来者可追

1
2
while(才华 < 野心):
print(宁静致远,厚积薄发)