关于最近遇到的面试题(一)


最近面了某互联网头部公司,整理了下部分面试题和思考

==mysql RR模式下数据可见性问题==

以下是伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
事务A中运行
@Transactional(Isolation=RR)
method1 {
1.select count from demo where xxx;
2.update demo set count = count +1;
3.select count from demo where xxx;
}

事务B中运行
@Transactional(Isolation=RR)
method2 {
1.select count from demo where xxx;
//
2.select count from demo where xxx;
}

method1和method2在两个事务中运行,两个方法中select的查询逻辑一致

问题1: 如果事务A.1 查询出count=40,同时事务B查询count=40,然后事务A.2执行完,然后挂起,此时事务B.2查询的结果是多少?

思路:本题经面试官确认,事务中的查询没存在手动加锁的情况,即不存在select … lock in share mode 或者 select … for update,考察的是数据库乐观锁 mvcc+undo log,参考文章 《Mysql中的MVCC》《 MySQL-InnoDB-MVCC多版本并发控制

思考:了解了mvcc的工作原理进行分析,mvcc默认采用快照读,假设事务A先启动,分配的事务id=1,事务B的事务id=2,事务A启动时read view=[],事务B启动时read view=[1],事务A.1语句执行时[…,0]均已提交,read view=[],当前行事务id=0,可直接返回count=40,
事务B.1执行,当前行事务id=0,可直接返回count=40,然后执行事务A.2,count=40进入undo log,当前行事务id=1,count=41,此时事务B.2执行,当前行事务id=1,在自身read view里,按照mvcc算法,需要取最新的undo log记录,重新循环算法,直到找到符合的记录,因为本题中undo log只有一条记录,并且log记录的事务id=0,故只有count=40符合,所以事务B.2返回count=40,其实这里可以简化以下,其实该算法在undo log很多的情况下,最终返回的都是undo log最早的值

==如何控制线程并发度==

问题1: 有一个method,最多只能支持100的并发度,要对这段代码进行保护,并发度到达100时新请求直接拒绝,并发度不足100时才接受请求

思路:

  1. 信号量(Semaphore)考虑对该类的tryAcquireShared方法进行重写
  2. 通过redis,维护concurrencyLevel字段,最大值100,其实是分布式锁思想,本质上是把锁位置变了一下
  3. 考虑用blockingQueue队列设置成100(这是面试官的方案),当时心里os了下,queueSize + concurrencyLevel最大情况是200,似乎不满足超过100拒绝请求的要求
==dubbo源码==

主要问了dubbo的架构图,关于负载均衡策略及其源码,分析优劣、时空复杂度,容错机制,dubbo连接池,这些东西虽然平时用着,但是源码没有专门花时间看过,展开的很有限,之后会专门开专题聊dubbo源码