HashMap 的底层原理以及如何扩容?

  • HashMap 由 数组 + 链表 + 红黑树 构成
  • 初始大小为 16,通过哈希策略将数据分布到不同的桶中
  • 扩容机制:
    • 当数组长度小于 64 时,扩容并且会 Rehash
    • 当数组长度大于等于 64 且链表长度超过 8 时,链表转为 红黑树,查询复杂度从 O(n) 变为 O(logN)
    • 扩容时数组大小翻倍(*2),装载因子默认为 0.75,可自定义

Redis 的穿透、击穿、雪崩

缓存穿透

  • 现象:客户端访问不存在的数据,缓存和数据库均未命中,大量请求直达数据库,导致负载过大甚至宕机
  • 原因
    • 业务层误删缓存和数据库的数据
    • 恶意请求不存在的数据
  • 解决方案
    1. 未命中时将空值写入缓存,下次请求直接返回空值
    2. 使用 布隆过滤器拦截不存在的请求

缓存击穿

  • 现象:某个热点数据在缓存失效的瞬间,大量并发请求直达数据库,导致服务崩溃
  • 解决方案
    1. 对热点数据设置 永不过期
    2. 使用 互斥锁,一个线程重建缓存,其他线程等待

缓存雪崩

  • 现象:大量缓存同时过期,或 Redis 节点故障,导致所有请求直达数据库,造成数据库宕机
  • 解决方案
    1. 避免同时过期,设置 随机过期时间
    2. 启用 降级和熔断措施
    3. 热点数据设置 永不过期
    4. 使用 Redis 集群,单点宕机时仍有节点可用

创建线程的方法?

  1. 继承Thread类,重写run()方法;
  2. 实现Runnable接口,实现run()方法;
  3. 实现Callable接口,实现call方法;
  4. 线程池创建。

Spring/SpringBoot怎么理解

  • 其实Spring就是一个管理类的容器,我们通过注解将我们定义好的类添加到Spring容器里,在我们需要的时候就是用注解从Spring容器里拿出之前定义好的类,可以理解为Spring就是一个Map结构,K是类名,V是类,取出来类后就可以调用类的方法了。
  • 存进银行的注解:@Component,@Component可以细化为这三个:@Service@Controller@Repository
  • 从银行取出来的注解:@Resource@Autowired

Redis怎么理解

  • redis很像一个公共的变量,如果是分模块部署的,想要获取公共的东西,就需要去发http请求获取内存里的内容。

单点登录和鉴权

  • 可以使用SpringSecurity进行鉴权的判断,当用户第一次登陆的时候,就去数据库查询该用户的权限并封装成token,这样之后每一个请求都会去token判断用户的类型进而判断是否放行。

消息队列

  • 其实消息队列就是一个Map,然后用List存取很多个Map,当生产数据的时候,就把他存进List,消费数据的时候,就是用get(),然后remove掉;

Docker

  • docker是一个容器,我们之前部署上线的时候是把项目生成一个jar包,然后上Linux服务器启动这个jar包,但是我们可能还需要redis,mysql等一系列的东西,如果有多台服务器,安装就很麻烦;
  • 于是我们使用docker把jar包、mysql、redis、nginx、jdk17全部打包成一个镜像,然后把这个镜像上传到linux上,这样linux只需要安装一个docker,然后docker run就可以运行了。
  • 但是镜像过多,所以出现了k8s去管理镜像。

索引失效的场景有哪些?

  • 使用左或者左右模糊匹配的时候,like %超 /like %超%
  • 对索引使用函数:where length(name)=6,这样就没有走原来定义好的name了
  • 对索引进行表达式计算:where id+1=10
  • 联合索引非最左
  • where的or条件前语句是索引列后语句不是where id = 1 or age = 2;id是索引但是age不是就不会走。

线程池参数该如何设置?

  • 如果是IO密集型,线程的大部分时间都花在了IO上,就会导致CPU利用率低,所以我们需要多开线程让cpu运作起来,一般是2*核心数
  • 如果是计算密集型,大部分线程都在处理计算任务,不会频繁进行上下文切换,所以设置为核心数+1即可

hashCode和equals方法有什么关系?

  • 如果两个对象相等,那他们equals和hashCode的返回值都相等
  • 但如果两个对象的hashCode返回值相同,两个对象不一定相同
  • 所以重写equals方法的时候一定要重写hashCode方法,以保证在使用hash等数据结构的时候能正常工作

如何使用Spring实现事务?

  • 事务四大原则ACID:原子、隔离、持久、一致
  • 使用注解@Transactional
  • @Transactional失效的场景有哪些?
    • 方法不是public:Spring默认基于代理,只有public方法才会被代理拦截
    • 方法内部调用,不会经过代理对象
    • final/static方法
    • 异常没有抛出
    • 多线程调用,因为新线程不会继承老线程的上下文