
获得徽章 7
- 负载均衡策略:
1.轮询(Round Robin)
2.加权轮询(Weighted Round Robin)
3.随机(Random)
4.最少连接(Least Connections)
5.IP哈希(IP Hash)展开21 - MySQL的索引下推(Index Condition Pushdown):一种优化技术,它在执行查询时将部分筛选条件推送到存储引擎层级进行处理,减少数据的读取和传输量,从而提高查询性能。
假设我们有一个名为"employees"的表,包含以下列:id(主键)、name、age和salary。我们为该表创建了一个名为"idx_age"的索引,针对"age"列。
SELECT id, name, age
FROM employees
WHERE age > 30 AND salary > 5000;
在没有索引下推的情况下,MySQL会首先使用"idx_age"索引定位到满足"age > 30"条件的所有行,然后再根据"salary > 5000"条件进行进一步的筛选。这意味着MySQL需要读取满足"age > 30"条件的所有行,并将它们传输到上层查询进行最终筛选,这可能会导致大量的数据读取和传输。
但是,如果启用了索引下推,MySQL会将"salary > 5000"条件下推到存储引擎层级进行处理。存储引擎可以利用索引的有序性,只读取满足"age > 30"和"salary > 5000"条件的行,而不必读取所有满足"age > 30"条件的行。这样可以减少数据的读取和传输量,提高查询性能。
需要注意的是,索引下推的可用性取决于MySQL版本和存储引擎的支持。在MySQL 5.6及以后的版本中,InnoDB存储引擎开始支持索引下推。在MySQL 8.0及以后的版本中,索引下推被默认启用。展开12 - String被设计为final类型主要有以下几个原因:
1.安全性
将String设计为不可变的是为了保证线程安全。由于String对象是不可变的,所以它是线程安全的,我们可以在多个线程中安全地共享和使用同一个String对象,而不用担心数据竞争或线程同步的问题。如果String是可变的,就需要在多线程环境中进行同步控制,这会导致性能下降和代码复杂度的增加。
2.缓存hashcode
字符串hashcode是通过将其内容通过加权计算而得出的,由于字符串对象是不可变的,所以只要计算一次hashcode就可以在String对象的生命周期内使用了。如果String是可变的,每次修改字符串内容都需要重新计算hashcode,这会导致性能损失。
3.类加载器保证
由于字符串常量是不可变的,Java虚拟机(JVM)会在类加载的时候将所有的字符串字面量加入到常量池中。这样做可以让运行时实例化一个字符串时只需要返回常量池中目标字符串的引用,从而达到节省内存和提高性能的效果。如果String是可变的,字符串无法单例共享,就需要为每个字符串新建实例。
4.支持字符串拼接(+)操作
由于字符串是不可变的,所以编译器可以在编译期通过StringBuffer实现字符串拼接操作。如果字符串是可变的,就无法在编译期完成字符串拼接,只能在运行时通过复制和修改字符串内容来实现,这会影响性能。
5.其他原因
不可变对象使缓存池设计成为可能,字符串 intern() 方法也由此实现。此外,字符串作为键值使用时,不可变性可以有效避免错误。
综上所述,将String设计成final和不可变类型,是考虑到线程安全、缓存hashcode、JVM优化、字符串拼接等因素,从而提高了安全性、性能和设计的简洁性。这些优势在大多数场景下是值得权衡的。展开23 - MYSQL加锁原则:
加锁基本单位next-key lock,next-key lock = 间隙锁 + 行锁,前开后闭
查询过程中访问到的对象都要加锁
索引等值查询,给唯一索引加锁时,next-key lock会退化为行锁
索引等值查询,向右遍历时且最后一个值不满足查询条件,next-key lock会退化为间隙锁
索引上的范围查询会访问到不满足条件的第一个值为止展开62 - ROCKETMQ延迟队列
1.实现原理:
发送延时消息时先把消息按照延迟时间段发送到指定的队列中(rocketmq把每种延迟时间段的消息都存放到同一个队列中)然后通过一个定时器进行轮训这些队列,查看消息是否到期,如果到期就把这个消息发送到指定topic的队列中,这样的好处是同一队列中的消息延时时间是一致的,还有一个好处是这个队列中的消息时按照消息到期时间进行递增排序的,说的简单直白就是队列中消息越靠前的到期时间越早。
2.优点:
设计简单,把所有相同延迟时间的消息都先放到一个队列中,定时扫描,可以保证消息消费的有序性展开11 - CMS(Concurrent Mark Sweep)和G1(Garbage-First)都是Java虚拟机中的垃圾收集器,它们有一些重要的区别:
收集方式:CMS使用标记-清除(Mark-Sweep)算法进行垃圾收集,而G1使用分代式收集和复制算法。G1将堆内存划分为多个相等大小的区域,并在每个区域内执行独立的垃圾收集。
并发能力:CMS是一种并发垃圾收集器,它可以与应用程序同时运行。在标记和清除阶段,CMS会与应用程序并发地执行,以减少停顿时间。而G1也是一种并发垃圾收集器,它在收集过程中尽量减少应用程序的停顿时间。
内存分配方式:CMS在进行垃圾收集时,会产生内存碎片,可能会导致大对象无法分配连续内存空间。G1则通过将堆内存划分为多个独立区域,并使用复制算法,可以更好地管理内存碎片,提供更连续的内存分配。
目标:CMS的目标是减少垃圾收集引起的停顿时间,适用于对延迟要求较高的应用程序。G1的目标是在合理的停顿时间内达到高吞吐量,适用于需要更好的整体吞吐量的应用程序。
需要注意的是,CMS在Java 9之后已被官方标记为废弃,并在Java 14中被标记为已过时。G1则是Java虚拟机默认的垃圾收集器,并且在性能和功能方面提供了更多的优化和改进。因此,在现代的Java应用程序中,建议使用G1垃圾收集器。展开57