1 分库分区分表, 你们是怎么分的.
分库我们是不做的, 因为我们用的是OceanBase, 他是一个原生的分布式数据库, 所以牵扯到分库的时候都是业务上存在拆分情况, 我们才进行分库操作.分区是按照业务主键分的. 这样就能分表是将一个大表按照业务拆分成一个主表, 若干个小表, 加快了查询速度.
2 一个更新的sql语句执行流程.
mysql执行每个sql语句都需要经过分层处理后才能交给数据引擎处理. 连接层:管理链接和权限校验,例如JDBC分析器:词法分析和语法分析.优化器: 执行计划生成和索引选择执行器:操作引擎,返回结果.存储引擎:存储数据, 提供读写接口. 更新语句与查询语句还有些不同, 更新语句涉及到两个log, binLog和redoLog, 因为现在谈论的都是Innodb, Innodb支持事务是通过在写入binLog之前, 先写入到redoLog中. 然后写入到到binLog中, 最后写入ChangeBuffer, 最终会在changeBuffer中合并为顺序写入磁盘的操作.
redoLog和binLog 两者一起保证了Innodb对事务的支持. 通过的是两阶段提交机制, 先写入变更内容到redoLog, redoLog是四个循环文件, 被数据库执行后会被擦除, 而binLog则是MySQL的变更内容记录文件.
3.MySQL 的主从同步, 是怎么做的.
通过binLog同步, binLog同步有三种方案,
row
statement
mix
一般推荐使用mix, 如果需要主从同步, 则推荐在RC级别下必须使用statement或者mix, RR级别可以使用statement.
4. MySQL 主从同步是异步同步, 那么怎么处理异步的差异.
使用数据库中间件
所有的读写都走数据库中间件,通常情况下,写请求路由到主库,读请求路由到从库
记录所有路由到写库的key,在主从同步时间窗口内(假设是500ms),如果有读请求访问中间件,此时有可能从库还是旧数据,就把这个key上的读请求路由到主库
在主从同步时间过完后,对应key的读请求继续路由到从库
常用的数据库中间件:canal、otter等
优点:保证数据绝对一致
缺点:实现成本较高
缓存记录写key法
如果key要发生写操作,记录在cache里,并根据经验设置的cache超时时间,例如500ms, 然后修改主数据库
读
先到缓存里查看,对应key有没有相关数据
有相关数据,说明缓存命中,这个key刚发生过写操作,此时需要将请求路由到主库读最新的数据
如果缓存没有命中,说明这个key上近期没有发生过写操作,此时将请求路由到从库,继续读写分离
优点: 相对数据库中间件,实现成本较低
缺点: 为了保证“一致性”,引入了一个cache组件,并且读写数据库时都多了缓存操作
5.Spring 的三级缓存讲一下.
简单,不写了, 主要就是每级缓存干了什么, 怎么从一级演变到三级的, 解决了什么问题.
6. SpringBoot 的扩展机制, 讲一下.
简单,不写了, 提一下@Conditional注解 和spring.factories文件.
7. 线程池的核心线程数和最大线程数的初始值, 怎么设置.
IO密集型配置线程数经验值是:2N,其中N代表CPU核数。
CPU密集型配置线程数经验值是:N + 1,其中N代表CPU核数。
8. Redis 分布式锁怎么实现的. 分布式锁超时是怎么解决的.
通过redis提供的setnx指令, 超时问题是通过引入Redisson框架中的看门狗机制来解决的. 这个框架底层是lua脚本保证发送命令的setnx和expire的原子性, 然后定期给还在使用的分布式锁增加过期时间.
9. ArrayList和LinkedList的区别.
这个就是讲一下扩容数组和双向链表的区别, 一般推荐使用ArrayList.
10. CocurrentHashMap的线程安全的原理
按照1.8之前的Segement说下, 1.8之后的锁红黑树的根节点和链表的头节点.
倒序输出链表.
这个当时太紧张了, 没答出来满意的答案, 只说了用栈或者递归.如果要求O(1)空间的话, 直接逆序,然后输出,然后再逆序回去. 就是O(1).
HTTPS 怎么保证安全的
主要就是公钥和私钥加解密, 然后需要一个可信机构颁发证书,
TCP和UDP的区别.
输入一个url, 发生了什么.
ES的底层原理.
RocketMQ 高性能的实现方式 有哪些?
主要是五个方面,
rocketMQ底层是基于文件系统的, 这基本是读写最快的方案,
rocketMQ 基于文件系统实现了读写分离, 生产者写入的文件是commit Log, 这个文件是按照 topic划分, 没个新消息都是顺序写入的, 顺序写入的效率比随机写入高几百倍. 然后读文件是采用的comsuer Queue, 这个queue的每个元素都只存储了message的地址和大小, 消费者需要根据地址去commitLog里查询信息. 直接使用地址读取 效率也很高.
rocketMQ 底层采用了Netty作为 网络框架, Netty底层使用了NIO, 也就是 IO多路复用, 非常见的BIO , 这也是效率高的原因之一
RocketMQ 底层采用了MMap, 零拷贝技术, 原来一个java系统需要四次拷贝
操作系统读取文件到系统内存
系统内存拷贝到应用系统内存
应用系统拷贝到Socket缓存中
Socket缓存拷贝到网卡内存种
使用Mmap的话, 就会直接从系统内存到网卡内存, 省去了应用和Socket缓存得拷贝, 效率提升了.
此外, 源码中使用了较多得 多线程编程, 因为MQ是IO频繁应用, 使用多线程可以有效增加CPU的吞吐量.
ES集群的读写流程是什么?
Elasticsearch写入数据流程
客户端随机选一个节点发送请求,被选择的节点为协调节点(coordinating node)协调节点计算并转发到真正的处理节点(主分片在的节点), 处理节点写入请求, 并同步给分片节点, 协调节点收到所有分片节点的相应信息,后, 返回结果.
Elasticsearch读取数据流程
客户端随机选一个节点发送请求,被选择的节点为协调节点(coordinating node)协调节点查询集群状态信息并使用round-robin随机轮询算法计算出去此次请求的节点(主分片节点和副本节点随机分配),最后处理后的信息原路返回.
Elasticsearch检索数据流程
客户端发送请求到一个协调节点, 协调节点将搜索请求转发到所有的shard对应的primary shard或replica shard也可以每个shard将自己的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果接着由协调节点,根据doc id去各个节点上拉取实际的document数据,最终返回给客户端