1.QPS:每秒能处理查询数目, 即一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
QPS = 并发量/平均响应时间
2、设计表结构 怎么实现用户量大的情况下快速查询用户的粉丝数/关注数
水平分表:关注关系表(follow表)和粉丝表(fans表)
比如有10万用户,ID为1~10000的用户放在表1,ID为10001~20000的用户放在表2,以此类推。
3、IOC:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作
不再由调用者来完成,因此成为控制翻转(IOC)。创建被调用者的工作由spring来完成,然后注入调用者,因此也称为依赖注入。
4、sleep和wait的区别:
*这两个方法来自不同的类分别是Thread和Object.
*最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
*wait,notify和notifyAll只能在同步代码块或者同步控制方法中使用,而sleep方法可以在任何范围内使用(使用方法)。
*sleep、wait需要捕获异常,而notify和notifyAll不需要捕获异常。
*sleep是Thread类的静态方法。sleep的作用是让线程休眠指定的时间,在时间到达时恢复,也就是说sleep将在接到时间到达时间时恢复线程执行。
wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者线程挂起,挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。
5、synchronized底层原理, 是可重入锁吗。
进入时,执行monitorenter,将计数器加1,释放锁monitorexit时,计数器-1.
当一个线程判断计数器为0时,则当前锁空闲,可以占用;反之,当前线程进入等待状态.
synchronized是可重入的,所以不会自己把自己锁死,synchronized锁一旦被一个线程持有,其他试图获取该锁的线程将被阻塞。
6、CAS原理 -> java内存模型 CAS会有什么问题
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。
问题:ABA问题,循环时间长开销大和只能保证一个共享变量的原子操作。
ABA问题的解决思路就是使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加一,那么A-B-A 就会变成1A-2B-3A。
7、HashMap数据结构,线程安全么?
数组+链表。
JDK8及其以后的版本中使用了数组+链表+红黑树实现。
线程不安全。
8、举个例子说明HashMap怎么线程不安全。
主要考虑到了多线程环境下进行扩容可能出现HashMap死循环的问题。
9、HashMap的长度为什么是2的幂次方?
答:我们将一个键值对插入HashMap中,通过将Key的hash值与length-1进行&运算,实现了当前key的定位,2的幂次方可以减少冲突(碰撞)的次数,提高HashMap查询效率。
如果length为2的幂次方,则length-1转化为二进制必定是1111....的形式,在与h的二进制与操作效率会非常快,而且空间不浪费。
如果length不是2的幂次方,比如length为15,则length-1为14,对应的二进制位1110,在与h与操作,最后一位都为0,而0001,0011,0101,1001,1011,0111,1101这几个位置永远都不能存放元素了,
空间浪费相当大,更糟的是这种情况中,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了碰撞的几率,减慢了查询的效率!这样就会造成空间的浪费。