Java面试题

目录

Mybatis

Spring

锁AQS CAS

JVM

Mysql

Zookeeper

Rabbit

RocketMQ

Redis

分布式锁

微服务调优经验

生产OOM

类加载和双亲委派

排序

TCP握手


Mybatis

  • SqlSessionFatoryBuilder

  • SqlSessionFatory

  • SqlSession

  • \1. 通过SqlSessionFatoryBuilder构建SqlSessionFatory的时候会处理指定的xml文件,创建MapperProxy

  • \2. 执行的时候获取到一个SqlSession,拿到一个Executor来执行MapperProxy。

  • \3. MapperProxy的invoke方法中来执行sql。

Spring

  • Hystrix:

    • 一定时间内(10s) 请求达到一定次数(20次) 失败率达到50%。

    • 断路器关闭、全开、半开。

  • 容器初始化流程-refresh流程

    • 获取工厂对象,包括通过xml中加载BD

    • prepareBeanFactory:设备一些忽略策略、ClassLoad等

    • PostProcessBeanFactory:一个钩子,这时所有xml加载的BD完成,Bean还没初始化。

    • InvokePostProcessBeanFactory: 初始化并执行BeanFactory的后置处理,@Configuration是在这里执行的,

    • registerBeanPostProcessors:实例化Bean后置处理

    • onRefresh:钩子,SpringBoot的tomcat是在这里启动的。

    • finishBeanFactoryInitialization:

      • 实例化Bean

      • 依赖注入

      • AOP等

  • 三级环境

    • singletonFactories

    • earlySingletonObjects

    • SingletonObjects

  • 依赖注入方法:populateBean->postProcessProperties

AQS CAS

  • AQS

    • head、tail、thread、status

    • Node:pre、next、Thread、stat(Signal、propagete)

  • 显式锁

    • 非公平锁,尝试加锁->tryAcquire中尝试->入队->唤醒

    • 公平,tryAcquire如果是首节点尝试->入队->唤醒

JVM

  • CMS

    • 初始标记,并发标记,重新标记,并发清除,重置

    • 三色标记

  • G1

    • 初始标记,并发标记,最终标记,根据指定时间筛选回收。

  • 内存划分

    • 堆区。

    • 栈区:虚拟机栈(一个线程一个栈,一个方法一个帧)、程序计数器(程序执行位置)、本地方法栈(原生方法)。

    • 本地内存:元空间、直接内存。

Mysql

  • 优化记录

    • # 采用前缀索引过短,导致离散率不高。

    • SELECT * FROM imuser_validate WHERE access_token =''

    • # 未添加索引

    • update third_push_token set validity=0 where third_token='' and origin=

    • # 联合索引末端字段,大概率不会走索引

    • SELECT userId FROM imgatewaysubdev WHERE subUserId = '4440433'

    • # 字段类型不一样,int string等。 会导致不走所以

    • delete from iosusertoken where userId=6173390

    • # join过多,导致笛卡尔积太大

  • ACID

    • 读未提交(Read uncommitted),

      • 可能出现脏读。

      • 就是一个事务能够看到其他事务尚未提交的修改,这是最低的隔离水平,允许脏读出现。

    • 读已提交(Read committed)

      • 可能不可重复读和幻象读(Phantom Read)出现。

      • 事务能够看到的数据都是其他事务已经提交的修改,也就是保证不会看到任何中间性状态,当然脏读也不会出现。读已提交仍然是比较低级别的隔离,并不保证再次读取时能够获取同样的数据,也就是允许其他事务并发修改数据。

    • 可重复读(Repeatable reads)

      • 可能出现幻读。

      • 保证同一个事务中多次读取的数据是一致的,这是 MySQL InnoDB 引擎的默认隔离级别,但是和一些其他数据库实现不同的是,可以简单认为 MySQL 在可重复读级别不会出现幻象读。

    • 串行化(Serializable)

      • 并发事务之间是串行化的,通常意味着读取需要获取共享读锁,更新需要获取排他写锁,如果 SQL 使用 WHERE 语句,还会获取区间锁(MySQL 以 GAP 锁形式实现,可重复读级别中默认也会使用),这是最高的隔离级别。

  • B+数的演变

    • 1 二分查找

    • 2 二叉树:二分查找如果放到数组中查找方便,但是插入十分困难。链表没有下标也不行。 所以引入了二叉树

    • 3 平衡二叉树:二叉树虽好,但是容易产生数据倾斜问题,如,只有左链,或者只有右链。

    • 4 B树:平衡二叉树虽好,但是如果数据量太大,树会特别高,影响查询效率。

    • 5 B+树:B树虽好,但是查询效率不稳定:查询靠近顶级的节点最快,叶子节点最慢。

      • 查询效率稳定

      • 磁盘IO次数少

      • 范围查询效率高

  • 成本计算 IO成本, CPU成本

    1. 找出所有可使用的索引。

    2. 计算出全表扫描的成本。

    3. 计算出所有可使用的索引的的成本。

    4. 对比各个方案,找出成本最优的。

Zookeeper

  • 四种节点:持久临时&是否有序

  • leader负责读和写,follow和Observer只负责读。

    • 写的时候需要发起投票,过半数才能写入。所以Follow不能太多

  • ZAB协议分为两种 崩溃恢复和消息广播

    • 选主流程

      • 先比较zxid,然后比较myid,

      • 首次启动只能挨个比较myid

      • 运行期间都投票给自己,然后交换信息选出最大,不行就再来一轮。

  • 脑裂

    • 通过法定人数法 n/2+1

Rabbit

  • channel.size: 提高此参数防止大量的channel不断的打开与关闭。

  • prefetch:提高预取值来减少NetIO

  • concurrency:提高允许同时连接rabbit的客户端数量。

  • rabbit单个queue可以支撑几k的tps,使用多个queue可以将单台tps提升到2w+

  • 如果两万无法满足需求可以使用并列多个rabbit

RocketMQ

  1. Nameser,producer,consumer,broker的关系

    1. namesrv:broker需要注册到所有namesrv,consumer和producer连接到一台namesrv来获取broker信息。

    2. producer:连接所有master节点。

    3. consumer:连接所有master和slave,高可用切换使用。

  2. 消息存储:

    1. CommitLog:一个broker有一个commitLog,存储所有的消息

    2. ComsumeQueue:每个topic有多个queue,queue中存储消息的指针信息,真实消息在CommitLog中。

    3. IndexFile:通过messageKey查消息的索引

  3. 高可用部署

    1. 多组Master+Slave,同步复制异步刷盘。

  4. 零拷贝

    1. 磁盘->copy到内核缓存区->copy到应用程序缓存区->copy到网络缓存区->网络传输

    2. 磁盘->copy到内核缓存区(内存映射可以给应用程序直接读)->copy到网络缓存区->网络传输

  5. 特殊功能

    1. 事务

    2. 延时消息

    3. 广播

Redis

  1. RESP协议

  2. 数据类型String,Set,List,Map,ZSet

  3. 一个字符串类型可以存储的最大 512M

  4. RDB AOF

  5. Redis过期策略

    1. 定时,

    2. LRU

    3. random

  6. Redis 集群方案什么情况下会导致整个集群不可用?

    1. 有 A,B,C 三个节点的集群,在没有复制模型的情况下,如果节点 B 失败了,那么整个集群就会以为缺少 5501-11000 这个范围的槽而不可用。

  7. 说说 Redis 哈希槽的概念?

    1. Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通 过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

  8. 弱事务

  9. redis性能问题

    1. master不要持久化

    2. 主从尽量选择线性的。

  10. Redis集群方案

    1. 哨兵,

      1. 监控各个节点的stat,消息通知,故障转移,配置中心。

      2. 哨兵集群至少需要3个实例,高可用,但不能保证不丢数据。

    2. 集群

      1. 哨兵模式监控权交给了哨兵系统,集群模式中是工作节点自己做监控

      2. 哨兵模式发起选举是选举一个leader哨兵节点来处理故障转移,集群模式是在从节点中选举一个新的主节点,来处理故障的转移

分布式锁

  1. redis Hash{ lockname:{ uuid: 1 }}

  2. zk 通过临时顺序节点,后一个节点watch前一个节点来实现

微服务调优经验

场景接口 200qps > 1200qps

  • mysql 连接池 改大

  • hystrix 改大

  • tomcat 500

  • 打通所以keepalive

  • fegin连接池

  • JVM

  • jackson

  • logback

生产OOM

  • Jprofile & visualvm & gceasy

类加载和双亲委派

  1. 加载: 从本地或者流中加载数据

  2. 验证: 验证数据的正确性

  3. 准备:给基本数据类型赋值等

  4. 解析:将常量池引用改为真实值等。

  5. 初始化:执行用户代码,例如static代码块

  6. 使用:new出来实例

  7. 卸载:jvm中卸载类

排序

java自带的排序:

  1. 小于286是双轴快排

    1. 小于47:插入

    2. 否则:双轴快排

  2. 大于286

    1. 连续升降性 好:归并排序

    2. 不好:快排

冒泡:每次找到最大的元素放到最右边。

归并:和javafork很像

快排:首先用最左端的数字将数组拆分为两部分,左边的小,右边的大。然后左右一次递归这样做。

双轴快排:和快排类似,只是第一次是使用首尾两个数字将数组拆分为三段。

插入排序:自然人最接近的排序方式,我们整理扑克牌经常使用。

TCP握手

三次握手

  • a发起连接确认信息

  • b确认,

  • b发起连接确认信息

  • a确认连接信息

四次挥手同样的。

timewait 是因为不能确定最后一次close的ack能被对方收到,另外房子这个连接通道被立马重用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值