这个java面试题怎么破?

专业打酱油 发布于 2013/08/29 11:18
阅读 1K+
收藏 4

1、mysql一个表A,100w数据,有字段id和num

2、java需要两个接口num+1,num-1,修改表字段,根据id把num+1和-1

3、对id=1的对象a进行num+1,num-1时需要同步

4、对id=2的对象b进行num+1,num-1是需要同步

5、对a进行num+1,对b进行num-1不需要同步

简单说是:两个接口对同一个对象的num操作才需要同步

问题

1、如何设计这两个接口(暂不考虑db行锁)?

2、数据库可否优化修改?

加载中
0
winnie_tour
winnie_tour

1. +1和-1的接口都用AtomicInteger的自增1方法和自减1方法就行了。

2. 在保证数据一致性的前提下,如果没有事务性的要求,db可以用myisam引擎,它是行所的,可以提高并发更新数据库的效率

0
menxin
menxin
要求是实时的么?
专业打酱油
专业打酱油
没说
0
我已经报警了
我已经报警了
myisam不是表锁么?inno啊db才是行所
0
0
李国刚
李国刚

myisam是表锁,只有innodb支持行锁!

题目说不考虑行锁,我理解的是不要依赖于数据库的锁!用程序实现锁(如果这里不是这么理解的,以下的分析可能也不符合本题目)。

如果是不依赖于数据库的锁,用程序实现的话,

有三步,第一select原来的值,第二计数加或减,第三update。

只要把这三步保证是原子操作,就可以了。

那么实现这三步原子操作加synchronized或reetrantLock都是可以实现的。

如果这样理解是对的话,这个题本身出的就不好。数据库的操作还是要依赖于数据库的锁和原子性才好,因为数据库可能有很多程序访问,靠程序的锁只能保证单个程序的原子性。无法保证多个程序之间的原子性.效率也不如数据库的控制。

excepiton
excepiton
可以用redis或memcache来代替同步锁,解决多个程序的问题。其实,数据库有解决的还是用数据库的好。
李国刚
李国刚
当然,如果允许程序缓存的话!按照1楼说的AtomicLong来记录数,直接update,效率肯定是最高的。不过要保证每次程序启动的时候要select,保证启动的初始值和数据库的值一样。不然就要出问题。
0
lvwenwen
lvwenwen
要求是实时
0
winnie_tour
winnie_tour

哦,sorry,我说反了。。这个表如果业务上不需要做事务操作就可以用myisam,多线程写入效率高很多

0
李国刚
李国刚

@throwable 

redis做原子计数 效率确实很高!

但是这个和本题目没有联系!
其实mysql也有原子修改!
比如 update table_name set num=num+1 where id=1;这个确实就是利用行级锁(innodb)对于一个原子修改!
不过本题目说了不要考虑行级锁,其实就是想把你引导到用程序加锁上去。
这样其实本身很牵强,正如你所说,可以用redis的原子计数来代替数据库方案。
所以对于这个题目,本身有点问题,没有从实际场景出发,或没有找到更适合的场景来考察这块知识!
0
panmingguang
panmingguang
没看懂我怎么
专业打酱油
专业打酱油
没说清楚,就看不懂
0
panmingguang
panmingguang
而且数据库, 还对象A,对象B, 不知道是被那个框架害的
专业打酱油
专业打酱油
回复 @panmingguang : 你没听过,不代表没有吧,对象和java没啥大关系,对象是设计的东西.
panmingguang
panmingguang
有对象概念的数据库, 那还叫数据库, 对象这种东西 就是被java 滥用了, 你看php操作数据库,没听过 对象吧
专业打酱油
专业打酱油
很多数据库都有对象概念,同学。 上面对象a,b是java实例
返回顶部
顶部