select、poll、epoll的区别

select、poll和epoll这三个函数是Linux系统中I/O复用的系统调用函数。 select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

  • select 时间复杂度o(n)
    仅知道I/O发生,但需要轮询所有流,找到可以操作的流。
    缺点:监视的fd数量有限,轮询效率低,需要维护存放fd的数据结构
  • poll 时间复杂度o(n)
    它将用户传入的数组拷贝到内核空间,然后查询每个fd(文件描述符)对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的. 缺点:大量数组被整体复制于用户态和内核地址之间,
  • epoll==>时间复杂度O(1)
    epoll是事件驱动,,会把哪个流发生了哪些事情通知我们。 优点:没有最大并发限制,效率高 缺点:当所有socket都活跃时,可能有性能问题。

  • 三者都是IO多路复用的机制,监视多个描述符。但都是堵塞的,需要自己负责读写,而异步IO的实现会负责 讲数据从内核拷贝到用户控件

  • 表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。 select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
  • 文件描述符: Linux下一切皆文件。当然设备也不例外,如果要对某个设备进行操作,就不得不打开此设备文件,打开文件就会获得该文件的文件描述符fd( file discriptor), 它就是一个很小的整数,每个进程在PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。

CMS垃圾回收过程

  1. CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合。 在启动JVM参数加上-XX:+UseConcMarkSweepGC ,这个参数表示对于老年代的回收采用CMS。CMS采用的基础算法是:标记—清除。

  2. CMS过程
    • 初始标记:STW,标记GCRoot(栈或寄存器中引用的对象,还有静态变量)
    • 并发标记:与用户线程同时进行,从GCRoot开始向下标记溯源。用户不会感到停顿
    • 并发预清理:查找并发标记阶段进入老年代的对象,减小下一个阶段重新标记的工作(会STW)
    • 重新标记:STW,查找CMS堆中剩余对象
    • 并发清理
    • 并发重置:重置CMS的数据结构,准备下一次清理
  3. CMS缺点
    • Mark—Swap,不会整理堆空间,产生内存碎片。将空闲碎片汇总成一个列表,以供下次分配。
    • 需要更多CPU资源。
    • 需要更大的堆空间。默认在68%时,就CMS开始行动了
  4. 何时使用
    • CPU、内存多,老年代较多时,适合使用

如何实现分布式事务

这里 ,还有 这里

操作系统调度方式

  • 先来先服务调度算法
  • 短作业优先
  • 高优先权 抢占式(来个更高优先级)/非抢占式
  • 时间轮,优先级高的时间占用更久

Mysql索引为何用B+树

  • 同一节点存更多元素,查询IO更少
  • 所有查询都要查找到叶子结点,性能稳定
  • 叶子结点形成有序链表,便于范围查询
  • 相比红黑树,每个节点存更多内容,减少IO,树的深度更小

    TCP滑动窗口

Redis脑裂

  • 所谓的集群脑裂就是,由于redis master节点和redis salve节点和sentinel处于不同的网络分区, 使得sentinel没有能够心跳感知到master,所以通过选举的方式提升了一个salve为master, 这样就存在了两个master,就像大脑分裂了一样,这样会导致客户端还在old master那里写入数据, 新节点无法同步数据,当网络恢复后,sentinel会将old master降为salve, 这时再从新master同步数据,这会导致大量数据丢失。

  • 脑裂

AOP的原理

Cglib和jdk动态代理 cgLib不能代理final类 JDK动态代理类实现: 继承InvocationHandler,增加接口field,实现invoke方法 Work o = (Work)Proxy.newProxyInstance(p.getClass().getClassLoader(), RealPerson.class.getInterfaces(), w);

#线程池的参数

  • 核心线程数
  • 最大线程数
  • 阻塞队列
  • keepAliveTime
  • 拒绝策略:1、直接丢弃 2、丢弃并报错 3、丢弃最老的线程 4、使用用户线程执行

kafka同步机制,副本拉还是master推?,每个Kafka副本对象都有两个重要的属性:LEO和HW,讲讲

Redis同步机制,通信协议,何如判断主节点挂掉,有没有一些优化工作

Redis集群模式 1、主从复制模式的工作机制:

slave启动后,向master发送SYNC命令,master接收到SYNC命令后通过bgsave保存快照(即上文所介绍的RDB持久化),并使用缓冲区记录保存快照这段时间内执行的写命令 master将保存的快照文件发送给slave,并继续记录执行的写命令

slave接收到快照文件后,加载快照文件,载入数据

master快照发送完后开始向slave发送缓冲区的写命令,slave接收命令并执行,完成复制初始化 此后master每次执行一个写命令都会同步发送给slave,保持master与slave之间数据的一致性

优缺点: 不能自动容错与恢复,需要手动重启 master宕机会导致数据不一致 难以在线扩容

2、哨兵模式 如果被PING的数据库或者节点超时(通过 sentinel down-after-milliseconds master-name milliseconds 配置)未回复,哨兵认为其主观下线(sdown,s就是Subjectively —— 主观地)。如果下线的是master,哨兵会向其它哨兵发送命令询问它们是否也认为该master主观下线,如果达到一定数目(即配置文件中的quorum)投票,哨兵会认为该master已经客观下线(odown,o就是Objectively —— 客观地),并选举领头的哨兵节点对主从系统发起故障恢复。若没有足够的sentinel进程同意master下线,master的客观下线状态会被移除,若master重新向sentinel进程发送的PING命令返回有效回复,master的主观下线状态就会被移除

哨兵认为master客观下线后,故障恢复的操作需要由选举的领头哨兵来执行,选举采用Raft算法:

发现master下线的哨兵节点(我们称他为A)向每个哨兵发送命令,要求对方选自己为领头哨兵

如果目标哨兵节点没有选过其他人,则会同意选举A为领头哨兵

如果有超过一半的哨兵同意选举A为领头,则A当选

如果有多个哨兵节点同时参选领头,此时有可能存在一轮投票无竞选者胜出,此时每个参选的节点等待一个随机时间后再次发起参选请求,进行下一轮投票竞选,直至选举出领头哨兵

缺点 不能在线扩容,容量受单机限制 需要额外资源启动sentinel进程,slave不提供服务

3、Cluster模式

所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽

节点的fail是通过集群中超过半数的节点检测失效时才生效

客户端与redis节点直连,不需要中间代理层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

Cluster模式具体工作机制:

  1. 在Redis的每个节点上,都有一个插槽(slot),取值范围为0-16383
  2. 当我们存取key的时候,Redis会根据CRC16的算法得出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号在0-16383之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
  3. 为了保证高可用,Cluster模式也引入主从复制模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点
  4. 当其它主节点ping一个主节点A时,如果半数以上的主节点与A通信超时,那么认为主节点A宕机了。如果主节点A和它的从节点都宕机了,那么该集群就无法再提供服务了

优缺点

能够实现自动故障转移,节点之间通过gossip协议交换状态信息,用投票机制完成slave到master的角色转换

key事务操作支持有线,只支持多key在同一节点的事务操作,多key分布不同节点时无法使用事务功能

不支持多数据库空间,单机redis可以支持16个db,集群模式下只能使用一个,即db 0

协议: 哨兵模式: Raft协议 cluster: Gossip协议

  • MongoDB索引类型

  • 分布式事务的设计

  • JDK装饰器模式的设计

  • JDK动态代理