京东面试
文章目录
技术一面
Java线程安全和线程非安全的类举例
- 线程安全。 Vector,ConcurrentHashMap
- 线程非安全。ArrayList,HashMap
HashTable和CurrentMap区别
HashTable使用Synchronized关键字进行同步控制,CurrentHashMap使用分段锁进行同步控制,CurrentHashMap性能更好
volatile作用及原理
- 可见性。可见性的解读为一个行程修改的状态对另一个线程是可见的,一个线程修改的结果,另一个线程马上就能看到。volatile关键字会强制将修改的值立即写入主存,一个线程修改volatile修饰变量会导致其他线程的工作内存中缓存失效(从硬件层面上来看就是讲CPU中的L1或L2缓存中对应的缓存行无效)
- 禁止指令重排。保证对volatile变量进行读写时,在其前面的操作的更改肯定全部进行,且结果对后面的操作可见,其后面的操作肯定还没有进行
在进行指令优化时,不能把volatile变量前面的语句放到其后面执行,也不能把volatile变量后面的语句放到其前面执行
volatile内存语义的实现与内存屏障有关,编译器在生成字节码时,会在指令序列插入内存屏障,内存屏障是一组处理器指令,先于这个内存屏障的指令必须先执行,后于这个内存屏障的指令必须后执行,在读指令前插入读屏障,可以让高速缓存中的数据失效,重新从主内存中加载数据,在写指令后插入写屏障,能让写入缓存的最新数据写回主内存。
HttpRequest内容
- 请求行。 请求方法(get/post),请求URL,HTTP协议及版本
- 请求头。 Accept/Cookie/Connection之类
- 请求体。具体请求内容
请求头和请求体之间通过换行分隔
ThreadLocal
- 原理 Thread维护了ThreadLocalMap变量,ThreadLocalMap是ThreadLocal的内部类。ThreadLocalMap的key是ThreadLocal的引用,value是要存储的对象
- 应用场景 ThreadLocal实现当前线程的操作都使用同一个数据库Connection
线程安全的原子类
AtomicInteger/AtomicLong
CAS原理
compare and set,比较旧值是否相同,然后设置新值
线程实现方案有哪些
实现Runnable/Callable接口,继承Thread,使用线程池创建
线程的状态有哪些
new/runnable/blocked/Time waiting/waiting/Terminated
如何理解分布式事务
随着微服务架构的普及,一个大型业务系统往往由若干个子系统构成,这些子系统又拥有各自独立的数据库,一个业务往往由多个子系统共同完成,这些操作需要在一个事务中完成。
- 实现原理
- 两阶段提交协议2PC
- 三阶段提交协议3PC
分布式锁如何实现
- Mysql
- Zookeeper
- Redis。使用
setNx resourceName value
,过期时间控制`set resourceName value ex 5 nx ]
微服务概念
- x,y,z轴切分,服务发现,服务治理
Join和union区别
join是联表查询,union是组合查询,组合查询可以将两个select语句(结果列数相同且字段类型相似)的结果去并集去重,可以使用union all
去重。
数据库隔离级别
- 读未提交
- 读已提交
- 可重复度
- 串行化
数据库可重复读的实现
三级封锁协议,要求读取A数据时必须加S锁,指导事务结束后才能释放S锁,因为读A时,其他事务不能对A加X锁,从而避免了在读的期间数据发生变化
联合索引ABC,对ABC排列组合,哪些用到了索引
根据数据库最左匹配原则,A,AB,ABC的查询用到了联合索引。
Spring AOP原理
Spring AOP主要是通过JDK动态代理和Cglib动态代理实现,将非业务代码通过切面的方式编织到业务代码中去
Spring事务传播机制
- PROPAGATION_REQUIRED 支持当前事务,如果上下文中已经存在事务,那么就加入到事务中执行,如果当前上下文中不存在事务,则新建事务执行。
- PROPAGATION_SUPPORTS 如果上下文存在事务,则支持事务加入事务,如果没有事务,则使用非事务方式执行
- PROPAGATION_MANDATORY 要求上下文中必须存在事务,这个方法不能被单独执行,必须被事务方法调用,否则抛出异常
- PROPAGATION_REQUIRES_NEW 每次都会新建一个事务,并且同时将上下文中的事务挂起。AB均申明事务,如果A失败回滚,B是不会回滚的,因为两个在不同事务中,如果B失败回归,A中捕获异常,事务A仍会提交
- PROPAGATION_NOT_SUPPORTED 不支持事务,如果存在事务则事务被挂起,执行当前逻辑后恢复事务,可以帮助缩小事务粒度
- PROPAGTION_NEVER 逻辑不能在事务中运行,一旦有事务,则抛出异常
- PROPAGATION_NESTED PROPAGATION_NESTED为父子事务,实际上是借助jdbc的savepoint实现的,属于同一个事务。PROPAGATION_NESTED的回滚可以总结为,子事务回滚到savepoint,父事务可选择性回滚或者不不滚;父事务回滚子事务一定回滚。
REQUIRED和SUPPORTS区别,A方法调用B方法,A未申明事务,B申明事务,REQUIRED会为B新建事务,SUPPORTS则以非事务方式执行B
技术二面
讲项目
谈到了排队分流引擎
一致性Hash算法,如何保证散列均匀
机器数量不多的情况下,可以使用虚拟节点
如何防止数据库击穿和数据库雪崩
- 使用互斥锁(mutex key) 缓存失效,使用分布式互斥锁,单线程去load db并设置缓存,其他线程重试get方法
- 流控
JDK锁
- Synchronized
- ReentrantLock
AQS
- state 状态计数
- queue 线程排队