JAVA 基础

JAVA中的几种基本数据类型是什么,各自占用多少字节?

类型字节(byte)位数(bit)
byte18
boolean18
char216
short216
int432
float432
long864
double864

String类能被继承吗,为什么?

不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。

下面这段话摘自《Java编程思想》第四版第143页:

使用final方法的原因有两个。

第一个原因是把方法锁定,以防任何继承类修改它的含义;

第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。

String, Stringbuffer, StringBuilder的区别

  1. String s=123"和 IString s new String(123)区别
  2. ArrayList和 I LinkedList有什么区别。
  3. 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字
    段,当new的时候,他们的执行顺序。
  4. 用过哪些Map类,都有什么区别, HashMap是线程安全的吗并发下使用的Map是什么
    他们内部原理分别是什么,比如存储方式, hashcode,扩容,默认容量等
  5. 有没有顺序的Map实现类,如果有,他们是怎么保证有序
  6. 抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么类可以实现多个接
    口么。
  7. 继承和聚合的区别在哪。
  8. 反射的原理,反射创建类实例的三种方式是什么
  9. 反射中, Class forName和 ClassLoader区别。

13.ClassLoader 原理、分类、加载顺序,双亲委派(加分项)

深入理解Java类加载器(ClassLoader)

原理
分类

引导(Bootstrap)类加载器、扩展(Extension)类加载器、系统(System)类加载器(也称应用类加载器)

双亲委派模式

双亲委派模式是在Java 1.2后引入的,其工作原理的是,如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。

  1. 描述动态代理的几种实现方式,分别说出相应的优缺点。

  2. 动态代理与 cglib实现的区别。

  3. 为什么 CGlib方式可以对接口实现代理。(加分项)

  4. final的用途。

  5. 写出三种单例模式实现。

  6. 如何在父类中为子类自动完成所有的 hashcode和 equals实现?这么做有何优劣。

  7. 请结合设计理念,谈谈访问修饰符 public、 private、 protected、 default在应用设计
    中的作用。

  8. 深拷贝和浅拷贝区别。

  9. volatile 可见性,有序性,如何实现的。不保证原子性

为了解决并发缓存值不一致,最开始采取的方案是 总线加锁(需要加锁,性能差,串行化,无法充分应用多核计算机的特性)。

现在采用的是 MESI 缓存一致性 和 CPU总线嗅探机制

  • 已修改Modified (M)
  • 独占Exclusive (E)
  • 共享Shared (S)
  • 无效Invalid (I)

要加锁,力度小
一旦其他线程修改了值,总线嗅探机制会直接使自身工作内存的副本失效,让线程重新去读。

  1. 为什么volatile不能保证原子性而Atomic可以?

额外

MESI协议

缓存行是脏的(dirty),与主存的值不同。如果别的CPU内核要读主存这块数据,该缓存行必须回写到主存,状态变为共享(S).
独占Exclusive (E)
缓存行只在当前缓存中,但是干净的(clean)--缓存数据同于主存数据。当别的缓存读取它时,状态变为共享;当前写数据时,变为已修改状态。
共享Shared (S)
缓存行也存在于其它缓存中且是干净的。缓存行可以在任意时刻抛弃。
无效Invalid (I)
缓存行是无效的

计算机基础、操作系统

死锁

死锁的四个条件

  • 禁止抢占(no preemption):系统资源不能被强制从一个进程中退出。
  • 持有和等待(hold and wait):一个进程可以在等待时持有系统资源。
  • 互斥(mutual exclusion):资源只能同时分配给一个行程,无法多个行程共享。
  • 循环等待(circular waiting):一系列进程互相持有其他进程所需要的资源。

MYSQL

MySql索引定义、如何设计、最左匹配的考查。

Mysql悲观锁和乐观锁。

MySql的事务隔离级别,如何实现可重复读的,MVCC,间隙锁。

隔离级别脏读(Dirty Read)不可重复读(Non-Repeatable Read)幻读(Phantom Read)
读未提交(READ-UNCOMMITTED)
读已提交(READ-COMMITTED)
可重复度(REPEATABLE-READ)
可串行化(SERIALIZABLE)
  • 间隙锁
  • 间隙锁只有在事务隔离级别 RR 中才会产生,事务级别是RC(读已提交)级别的话,间隙锁将会失效
  • 唯一索引只有锁住多条记录或者一条不存在的记录的时候,才会产生间隙锁,指定给某条存在的记录加锁的时候,只会加记录锁,不会产生间隙锁;
  • 普通索引不管是锁住单条,还是多条记录,都会产生间隙锁;
  • 间隙锁会封锁该条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据,这是为了防止出现 幻读 现象;
  • 普通索引的间隙,优先以普通索引排序,然后再根据主键索引排序;

参考:彻底搞懂 MySQL 事务的隔离级别

事务的ACID、BASE原理、CAP原则。

ACID

  • 是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。

Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。[1]

Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。[1]

Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。[1]
Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。


CAP原则(定理)

  • 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

BASE理论

  • BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写,BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的结论,是基于CAP定理逐步演化而来的,其核心思想是即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)

参考:CAP原则(CAP定理)、BASE理论

分布式事务

分布式事务框架 seata 官方文档

XA

XA是X/Open DTP组织(X/Open DTP group)定义的两阶段提交协议,XA被许多数据库(如Oracle、DB2、SQL Server、MySQL)和中间件等工具(如CICS 和 Tuxedo)本地支持 。
X/Open DTP模型(1994)包括应用程序(AP)、事务管理器(TM)、资源管理器(RM)。

XA接口函数由数据库厂商提供。XA规范的基础是两阶段提交协议2PC。
JTA(Java Transaction API) 是Java实现的XA规范的增强版 接口。

在XA模式下,需要有一个[全局]协调器,每一个数据库事务完成后,进行第一阶段预提交,并通知协调器,把结果给协调器。协调器等所有分支事务操作完成、都预提交后,进行第二步;第二步:协调器通知每个数据库进行逐个commit/rollback。
其中,这个全局协调器就是XA模型中的TM角色,每个分支事务各自的数据库就是RM。

SAGA

Saga 理论出自 Hector & Kenneth 1987发表的论文 Sagas。
saga模式的实现,是长事务解决方案。

Saga 是一种补偿协议,在 Saga 模式下,分布式事务内有多个参与者,每一个参与者都是一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。

AT

AT 模式是一种无侵入的分布式事务解决方案。

阿里seata框架,实现了该模式。

在 AT 模式下,用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作。

TCC

TCC 模式需要用户根据自己的业务场景实现 Try、Confirm 和 Cancel 三个操作;事务发起方在一阶段执行 Try 方式,在二阶段提交执行 Confirm 方法,二阶段回滚执行 Cancel 方法。

  • 关于 TCC(Try-Confirm-Cancel)的概念,最早是由 Pat Helland 于 2007 年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。 TCC 事务机制相比于上面介绍的 XA,解决了其几个缺点:

解决了协调者单点,由主业务方发起并完成这个业务活动。业务活动管理器也变成多点,引入集群。
同步阻塞:引入超时,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小。
数据一致性,有了补偿机制之后,由业务活动管理器控制一致性
TCC(Try Confirm Cancel)
Try 阶段:尝试执行,完成所有业务检查(一致性), 预留必须业务资源(准隔离性)
Confirm 阶段:确认执行真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源,Confirm 操作满足幂等性。要求具备幂等设计,Confirm 失败后需要进行重试。
Cancel 阶段:取消执行,释放 Try 阶段预留的业务资源 Cancel 操作满足幂等性 Cancel 阶段的异常和 Confirm 阶段异常处理方案基本上一致。

在 Try 阶段,是对业务系统进行检查及资源预览,比如订单和存储操作,需要检查库存剩余数量是否够用,并进行预留,预留操作的话就是新建一个可用库存数量字段,Try 阶段操作是对这个可用库存数量进行操作。
基于 TCC 实现分布式事务,会将原来只需要一个接口就可以实现的逻辑拆分为 Try、Confirm、Cancel 三个接口,所以代码实现复杂度相对较高。

Q.E.D.