在工作中遇到的问题

  • 呗呗客服系统的在线时长统计
    • 一开始的表设计是一次记录当前该表的状态,但需求是统计当天不同时段咨询师的在线时长、挂起时长,所以每次记录只记录当前状态的话就不是很好统计不同时间段的时长,所以改变了表设计,每次状态变更都把记录当前状态的同时,把上一次状态的结束状态给更新,这样一来每条记录就好统计多了
  • 历史访客接口的优化
    • 响应太慢

分布式唯一ID生成方案

  • UUID: 性能非常高,本地生成,没有网络消耗。
    • 问题
      • 入数据库性能差,因为UUID是无序的,不能生成自增
  • 数据库自增主键(不适合分布式)
  • 基于Redis生成全局ID策略
    • INCRBY:设置增长步长
  • 雪花算法

JVM 调优

  • 一般是数据库到达瓶颈,可以考虑分库分表、归档,或者加入缓存
  • 服务器资源扩容,集群部署
  • 代码优化
  • 最后再是JVM层面上排查并优化
    • 看是否存在多次GC问题
  • 最后,网络和操作系统层面排查
  • 在我的理解下,调优JVM其实就是在「理解」JVM内存结构以及各种垃圾收集器前提下,结合自己的现有的业务来「调整参数」,使自己的应用能够正常稳定运行。
  • 一般调优JVM我们认为会有几种指标可以参考:『吞吐量』、『停顿时间』和『垃圾回收频率』
  • -Xmx:设置堆的最大值、-Xms:设置堆的初始值、-Xmn:表示年轻代的大小、-XX:SurvivorRatio:伊甸区和幸存区的比例等等
  • 按经验来说:IO密集型的可以稍微把「年轻代」空间加大些,因为大多数对象都是在年轻代就会灭亡。内存计算密集型的可以稍微把「老年代」空间加大些,对象存活时间会更长些

  • 排查问题

      1. 通过jps命令查看Java进程「基础」信息(进程号、主类)。这个命令很常用的就是用来看当前服务器有多少Java进程在运行,它们的进程号和加载主类是啥
      1. 通过jstat命令查看Java进程「统计类」相关的信息(类加载、编译相关信息统计,各个内存区域GC概况和统计)。这个命令很常用于看GC的情况
      1. 通过jinfo命令来查看和调整Java进程的「运行参数」。
      1. 通过jmap命令来查看Java进程的「内存信息」。这个命令很常用于把JVM内存信息dump到文件,然后再用MAT( Memory Analyzer tool 内存解析工具)把文件进行分析
      1. 通过jstack命令来查看JVM「线程信息」。这个命令用常用语排查死锁相关的问题
      1. 还有近期比较热门的Arthas(阿里开源的诊断工具),涵盖了上面很多命令的功能且自带图形化界面。这也是我这边常用的排查和分析工具

JVM的JIT优化技术

  • JIT优化技术比较出名的有两种:方法内联和逃逸分析
  • 所谓方法内联就是把「目标方法」的代码复制到「调用的方法」中,避免发生真实的方法调用
  • 因为每次方法调用都会生成栈帧(压栈出栈记录方法调用位置等等)会带来一定的性能损耗,所以「方法内联」的优化可以提高一定的性能
  • 而「逃逸分析」则是判断一个对象是否被外部方法引用或外部线程访问的分析技术,如果「没有被引用」,就可以对其进行优化,比如说:
    • 锁消除(同步忽略):该对象只在方法内部被访问,不会被别的地方引用,那么就一定是线程安全的,可以把锁相关的代码给忽略掉
    • 栈上分配:该对象只会在方法内部被访问,直接将对象分配在「栈」中(Java默认是将对象分配在「堆」中,是需要通过JVM垃圾回收期进行回收,需要损耗一定的性能,而栈内分配则快很多)

怎么利用Redis实现数据的去重?

  • Redis的set:它可以去除重复元素,也可以快速判断某一个元素是否存在于集合中,如果元素很多(比如上亿的计数),消占用内存很大
  • Redis的bit:它可以用来实现比set内存高度压缩的计数,它通过一个bit设置为1或者0

MySQL的B+树的高度怎么计算?

ThreadLocal的使用场景有哪些?原理?内存泄漏?

  • 弱引用比较容易被回收。因此,如果ThreadLocal(ThreadLocalMap的Key)被垃圾回收器回收了,但是因为ThreadLocalMap生命周期和Thread是一样的,它这时候如果不被回收,就会出现这种情况:ThreadLocalMap的key没了,value还在,这就会造成了内存泄漏问题
  • 如何解决内存泄漏问题
    • 使用完ThreadLocal后,及时调用remove()方法释放内存空间。

kafka是如何保证消息的有序性?

  • 在发消息的时候指定Partition Key,Kafka对其进行Hash计算,根据计算结果决定放入哪个Partition。这样Partition Key相同的消息会放在同一个Partition。然后多消费者单线程消费指定的Partition。

Nacos的选举机制了解嘛?说下Raft算法?

Mysql索引在什么情况下会失效

  • 查询条件包含or,可能导致索引失效
  • 如何字段类型是字符串,where时一定用引号括起来,否则索引失效
  • like通配符可能导致索引失效。
  • 联合索引,查询时的条件列不是联合索引中的第一个列,索引失效。
  • 在索引列上使用mysql的内置函数,索引失效。
  • 对索引列运算(如,+、-、*、/),索引失效。
  • 索引字段上使用(!= 或者 < >,not in)时,可能会导致索引失效。
  • 索引字段上使用is null, is not null,可能导致索引失效。
  • 左连接查询或者右连接查询查询关联的字段编码格式不一样,可能导致索引失效。
  • mysql估计使用全表扫描要比使用索引快,则不使用索引。