这两种设计模式相对来讲都偏冷门,本题可以回答好的话说明对设计模式有过深刻的了解,在面试偏业务的岗位上有加分mysql
先解释二者概念:面试
再解释二者核心区别和功能不一样点:redis
最后解释二者优缺点和各自使用场景:算法
若是问页分裂问题,通常会在聚簇索引以后紧接着提出,若是没有问,在回答完聚簇索引相关的概念后,要尽可能地给面试官带出页分裂的概念,体现出本身对这一块的熟悉程度sql
数据库索引底层使用B+树来实现,若是插入不规则的数据(指不按key顺序插入),会致使树结构频繁发生较大改变数据库
在数据库中,聚簇索引和非聚簇索引在频繁插入不规律数据时,都会致使严重的页分裂问题。mysql中一页大小为8k,是固定的:设计模式
本题主要用于考察面试者是否了解排序的概念,而不是仅仅背知识点。第一问不难,基本上知道稳定性的概念就能顺势推出其意义,第二问稍微有点难度,可是只要真正了解稳定性的概念,就能想到一些解决办法缓存
排序的稳定性指拥有相同关键字的记录,在排序后的相对次序保持不变。由于有些数据在排序前的相对顺序是有语义的,非稳定性排序会在排序后丢失这些语义,因此在这种场景下须要保证排序的稳定性bash
当必须使用非稳定性排序算法,且须要保证稳定性时,有两种解决方案:服务器
实现原理很简单,但前提是你主动去了解过
HashSet
内部维护了一个HashMap
类型的变量,其key值为Set的元素类型,value为Object类型
对全部添加到Set中的元素,HashSet会添加一个元素 => PRESENT
的键值对到HashMap中,这个PRESENT是HashSet中定义的一个普通的Object对象。由于HashMap中key相同的元素会相互覆盖,因此保证了集合中没有重复key值的元素存在
ACID的概念很简单,可是想说清原理不容易,其中隔离性和持久性是重点。隔离性的要点是锁机制,有的面试官会紧接着出一些场景题,须要提早准备;持久性的要点是
redo log
和binlog
,有的面试官会引伸到读写分离的数据一致性问题,也须要提早作好准备
A(原子性):原理是undo log
,即“撤销日志”。当事务对数据库进行修改时,会生成对应的undo log,若是事务回滚,数据库会使用undo log中的内容将数据修改到以前的状态
C(一致性):经过数据库自己(如外键等)和服务端的代码逻辑层面共同保证
I(隔离性):经过数据库锁机制和MVCC来实现。锁机制保证两个事务的写操做不会相互影响,MVCC保证一个事务的读操做不会被其余事务的写操做影响
D(持久性):原理是redo log
和binlog
,当数据修改时,会在redo log中记录此次操做(记录的是物理数据,内容基于磁盘page),一般当事务提交时,会调用fsync对redo log进行刷盘(将数据写入磁盘),若是mysql机器宕机,可使用redo log对数据进行恢复。同时binlog做为二进制逻辑日志也能够用户数据恢复
若是面试官问你这个问题,惟一的缘由就是他昨天临睡前看到了这个知识点,因此就拿来考你(固然也有多是工做中确实用到)。本题单纯的就是知识扩展,若是不会也不影响
stricpy
,即strict float point(精确浮点)
,只能用来修饰方法或类。被strictpy修饰的方法或类中全部的float/double表达式都严格遵循FP-strict的限制,全部表达式的结果都必须是IEEE-754对操做数预期的结果
strictpy能够消除因硬件不一样而带来的浮点数计算差别,可是并不能避免相似0.05 + 0.01 != 0.06
这样的状况,因此在要求高精度浮点计算时,须要使用BigDecimal
fun1
相互阻塞的方法有哪几个,为何?public synchronized static void fun1() {
try {
Thread.sleep(2000);
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("[同步-静态方法-1]");
}
// -------------------------------------------------
public synchronized static void fun2() {
System.out.println("[同步-静态方法-2]");
}
public static void fun3() {
System.out.println("[普通静态方法]");
}
public void fun4() {
System.out.println("[普通方法]");
}
public void fun5() {
synchronized (Demo.class) {
System.out.println("[类同步-静态方法]");
}
}
public void fun6() {
synchronized (this) {
System.out.println("[对象同步-方法]");
}
}
复制代码
本题考察点是对
synchronized
关键字的掌握程度,有些人理论背的很熟,可是随便丢个场景应用就懵了。因此在学一个知识点的时候,最起码本身要动手写几行代码跑一下看看
与fun1相互阻塞的方法是fun2和fun5
fun2是另外一个被synchronized修饰的方法,和fun1同属一类,因此会相互阻塞
fun5中使用了类锁,而synchronized在静态方法上的锁也属于类锁,因此也会相互阻塞
通常这种并发修改的场景,均可以用消息中间件来将并行转串行解决,可是面试官一般还想要另外一种答案,因此最少要准备两套方案。本题固然不止我下面列出的这两种方案,只要合理便可
MUTLI
和WATCH
实现:在redis中设置一个key,而后WATCH这个key,经过MUTLI开启事务,而后自增这个key的值,接着再执行真正的修改操做,最后使用EXEC提交事务。经过这种方法,若是发生多线程竞争,因为WATCH机制,监听到key值变化的线程会执行redis操做失败本题应该算是偏常规的缓存题,可是有的面试官会把这三个场景放一块儿说来故意迷惑你,因此要注意区分它们之间的不一样点,千万不要死记硬背,不然必定会搞混的
本题主要考察对mvc分层的理解程度,只要能把每一层的概念理解了,说个大概仍是没问题的,即便不知道,举几个反例出来就能够了