# 1.密封类跟抽象类有啥区别?
抽象类:抽象类不能实例化,只能被继承。抽象类中可以有抽象方法,抽象方法没有方法体。抽象方法必须被继承类实现。
密封类:密封类可以被实例化,不能被继承
# 数据库读写分离和分库分表的主要区别
数据库读写分离是将数据库分为一个主库和多个从库,主库用于增删改,从库用于读
分库分表分为两种方式
1. 垂直拆分: 根据业务将数据库中的表进行分组,将相关表放在同一个数据库中。
这种方式会增加应用的复杂度,可能引发跨库事务和木桶效应
2. 水平拆分: 根据某种分片算法将一个库(表)拆分为多个库(表),水平拆分可以显著提示读写性能,但是需要处理分布式事务和跨库查询问题
应用场景:
--读写分离: 适用读多写少的场景,在高并发读操作下,可以有效提升读的性能
--分库分表: 适用于大数据量和高并发的场景,通过分散数据和请求来提升系统整体的性能
# 什么是缓存雪崩、缓存穿透和缓存击穿?
缓存雪崩是指: 由于大量缓存数据在同一时间过期,导致所有原本应该访问缓存的请求都直接打到数据库上,从而对数据库的CPU和内存造成巨大压力,严重时可能导致数据库崩溃。这种情况通常发生在缓存设置了相同的过期时间,导致大量缓存同时失效
缓存穿透是指: 用户查询的数据在缓存和数据库中都不存在,但用户仍然不断发起请求,导致每次请求都会查询数据库,从而给数据库带来巨大压力。这种情况常见于恶意攻击或系统错误
缓存击穿是指: 热点数据在缓存失效的瞬间,大量并发请求未能命中缓存,直接打到数据库上,导致数据库压力骤增。这种情况通常发生在热点数据过期失效的瞬间,大量用户同时访问该数据,导致数据库无法承受如此高的并发请求
解决方案:
缓存雪崩:
1.分散过期时间:避免所有缓存数据同时过期,可以通过随机生成过期时间来分散压力。
2.限流和降级:在缓存失效时,通过限流和降级措施减少对数据库的压力。
3.双层缓存:使用双层缓存策略,一层是热点数据永不过期,一层是普通数据按需加载。
缓存穿透:
a.业务层校验:在业务层对请求参数进行校验,过滤掉明显错误的请求。
b.设置空值缓存:对于不存在的数据,可以在缓存中设置一个短过期的空值。
c.使用布隆过滤器:通过布隆过滤器提前拦截不存在的key,减少对数据库的查询。
缓存击穿:
1.热点数据永不过期:对于热点数据设置永不过期或通过定时任务更新。
2.互斥锁:在热点数据过期时,通过互斥锁控制只有一个请求去查询数据库并更新缓存。
分布式锁:在分布式环境中使用分布式锁来确保只有一个请求去更新缓存。
# 什么是多线程?
多线程是指在一个进程中同时运行多个线程的技术
多线程是一种并发编程技术,允许一个进程中的多个线程同时执行不同的任务。每个线程是进程中的一个独立执行单元,共享进程的内存空间和资源,但拥有自己的执行路径。多线程的主要目的是提高程序的执行效率和响应能力,尤其是在处理并发任务时。
# Static静态属性
不要在多线程情况下修改static定义的属性,会导致数据出现异常
# Hashtable和Dictionary的使用注意
多线程下推荐使用Hashtable,单线程下推荐使用Dictionary, 因为Dictionary在多线程下存在线程锁的问题