自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

一切随缘的博客

记录学习历程的同时分享知识

  • 博客(164)
  • 收藏
  • 关注

原创 为什么实际开发中不推荐使用外键?

一般数据库都不会启用读锁,例如MYSQL事务级别设置为读提交,个人认为没有理由使用其它事务级别。数据库的瓶颈在IO,不使用外键代码里做数据完整性检查,磁盘IO省不了,网络IO占用增加。,无论是否使用外键,只要要做数据完整性检查,磁盘IO是省不了的。读写分离也是很成熟的方案。数据库水平扩展不易?64核cpu已发布,最大支持4T内存,主流数据库均支持外键约束。为什么实际开发中不推荐使用外键?只有一个场景不能使用外键,就是。,其它描述都不是真正原因。

2023-10-21 22:31:35 374 2

原创 谈谈 Redis 大 Key 会有什么影响?

或者,定时检查 Redis 是否存在大 key ,如果该大 key 是可以删除的,不要使用 DEL 命令删除,因为该命令删除过程会阻塞主线程,而是用 unlink 命令(Redis 4.0+)删除大 key,因为该命令的删除过程是异步的,不会阻塞主线程。如果创建完子进程后,父进程对共享内存中的大 Key 进行了修改,那么内核就会发生写时复制,会把物理内存复制一份,由于大 Key 占用的物理内存是比较大的,那么在复制物理内存这一过程中,也是比较耗时的,于是父进程(主线程)就会发生阻塞。● 客户端超时阻塞。

2023-10-16 21:43:40 243 1

原创 谈谈 Redis 持久化机制,RDB、AOF

用 AOF 日志的方式来恢复数据其实是很慢的,因为 Redis 执行命令由单线程负责的,而 AOF 日志恢复数据的方式是顺序执行日志里的每一条命令,如果 AOF 日志很大,这个「重放」的过程就会很慢了。加载完 RDB 的内容后,才会加载后半部分的 AOF 内容,这里的内容是 Redis 后台子进程重写 AOF 期间,主线程处理的操作命令,可以使得数据更少的丢失。也就是说,使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据。AOF:存储的是具体的命令。

2023-10-16 21:38:30 193

原创 谈谈什么是缓存穿透,缓存击穿,缓存雪崩?怎么解决?

● 当你做完这些准备之后呢,你再去谈怎么单纯解决缓存击穿的问题,你可以完全忽略,永不过期这种方案,因为一个要去考虑缓存击穿的系统,绝对是高并发和海量数据的?当你最近的 100 次请求,平均 rt 都超过 5 s 了,系统报错率也在飙升,你不应该熔断对数据库的查询操作吗?● 你所有用缓存的场景,哪怕有一刻缓存是失效的,你也要保证数据库能扛得下来。● 第一,需要正确评估系统的容量,和业务中的慢查询,应该要做到什么呢?缓存击穿,缓存穿透,缓存雪崩,背后的本质,从一种更高的角度来看问题。可能造成短期的数据不一致。

2023-10-16 21:30:19 362 1

原创 插入大批数据,怎么优化?

每提交一次事务,redo log buffer,bin log 就要刷一次盘。每一个单独的insert语句,都会隐式开启事务,语句执行完毕自动提交事务。所以优化点,就在于控制日志刷盘次数,减少磁盘IO的次数。我们可以手动的提交事务,批量插入数据之后,再提交事务。让多个commit提交,合并成一个commit提交。其实是牺牲数据的安全性来换取性能的提升。插入大批数据,怎么优化?性能跟日志息息相关。

2023-05-28 11:16:17 129 1

原创 InnoDB 在可重复读 RR 隔离级别下,能解决幻读问题吗?

InnoDB 在可重复读 RR 隔离级别下,能解决幻读问题吗?MySQL 在「可重复读」隔离级别下,可以很大程度上避免幻读现象的发生(注意是很大程度避免,并不是彻底避免),所以 MySQL 并不会使用「串行化」隔离级别来避免幻读现象的发生,因为使用「串行化」隔离级别会影响性能。解决方案有两种:● 针对快照读(普通的select语句),是通过MVCC的方式解决了幻读问题。

2023-05-27 10:13:48 1122

原创 目前互联网大厂 MySQL 使用最多的隔离级别是什么?

可重复读多好啊,解决了脏读,不可重复读问题,又有next-key lock,可以很大程度上避免幻读问题。好的方面:很真实,真实的反映了数据的变化,变迁。RC,就是真实的反映了当前数据的最新状态。因为 RR 隔离级别和Binlog的Statement格式,才能很好的配合,才不会出现主从数据不一致的问题。RC,读已提交,多不好啊,仅仅解决了脏读问题,存在不可重复读,幻读的问题。首先要纠正一个观点:不可重复读,幻读,并不是什么严重的问题。不可重复读,幻读,只是两种现象,并不是什么错误。幂等校验,强制加锁。

2023-05-26 17:20:00 577 2

原创 什么是 limit 深分页问题?怎么解决?

当深分页的时候,优化器都不会选择走key这个辅助索引了,而是选择type = All,全表扫描,因为优化器这时候觉得,你走辅助索引,还要大量的回表,可能效率还不如直接全表扫描 + 排序呢。// 走key的索引,快速定位,然后再往后取10条记录就行了,type = range,extra = using where。先通过子查询拿到第99000页的所有记录的id值,然后和原表进行一次join表连接,比对id值,减少大量的回表操作。我们想到给这个要排序的字段加上索引,但是加上索引之后,查询的速度依旧很慢。

2023-05-24 14:39:48 1046

原创 MySQL limit 是怎么工作的?原理是什么?

如果 B type = index,意味着要进行 5001 次回表操作,优化器觉得执行这么多次回表,代价太大了,还不如直接进行全表扫描 + filesort。两个sql语句从发送给服务端到返回给客户端,耗时时长的区别就在网络开销上面(因为一个是返回的1条记录,一个是返回的1w条记录,数据量不同造成的)。在带有limit的查询语句中,你先把limit删掉,再查看数据,看看数据是不是你想要过滤的。而 B语句 type = all,没有走二级索引,走的是主键索引,进行全表扫描。假设这张表有 1 w 条数据。

2023-05-23 17:50:44 1062

原创 MySQL 的 or 走不走索引?

● 如果 a 字段有索引,b 字段也有索引,那么会走索引,此时就是。有可能走,也可能不走。

2023-05-20 10:28:12 2200

原创 MySQL is null 走不走索引?

因为可为 NULL 的列会使索引、索引统计和值比较都更复杂,比如进行索引统计时,count 会省略值为NULL 的行。比如,select * from table where a = xxx or a is null;● 第二个原因:NULL 值是一个没意义的值,但是它会。网上很多的说法,都是说不能走索引。通过explain 看这条sql的执行计划,为了更好的利用索引,索引列字段要设置为。● 第一原因:索引列存在 NULL 就会。,这条sql语句会查询两次,其实也是又可能走索引的。

2023-05-20 10:25:39 2526 4

原创 索引什么场景下会失效?

● 对索引列进行隐式类型转换,比如索引字段是varchar类型的,你查询的时候输入的字段参数是整数类型的话,这里就会对字段进行类型转换,导致索引失效。,直接全表扫描(Type = All),把主键索引的叶子节点全部走一遍的效率(全表扫描),比走二级索引,然后再回表的效率高。● like “%xx” "%xx%”,这种左模糊查询或者左右模糊查询,就可能导致索引失效,当然。● 对索引列进行计算,或者使用函数,那么也会导致索引失效。,如果两个字段都是索引字段,那么会走索引,这种情况就是。

2023-05-20 09:39:54 781

原创 MySQL 执行计划(Explain)

主要就看一下,type 是什么,走没走索引,走了哪个索引,extra 看看,有没有索引覆盖啊,索引合并啊,索引下推啊…的时候, 这时不得不选择相应的排序算法进行,甚至可能会通过文件排序,效率是很低的,所以要避免这种问题的出现。type这里,网上的各种错误的博客,对 type = all,type = index有很多错误的观点。● key 字段表示实际用的索引,如果这一项为 NULL,说明没有使用索引;:所需数据只需在索引即可全部获得,不须要再到表中取数据,也就是使用了。,避免了回表操作,效率不错。

2023-05-20 09:32:40 598

原创 总结反思在部署上线短链接项目过程中所踩到的坑

总结反思在部署上线短链接项目过程中所踩到的坑

2024-02-05 13:10:51 532 3

原创 IO 模型(BIO、NIO、多路复用)

IO模型,包括 BIO、NIO、多路复用

2024-01-31 14:34:27 619

原创 压测短链接项目的时候,由 Jmeter 报错:java.net.BindException:Address already in use,所引发的一系列困惑与思考

2024.1.31 压测短链接项目的时候,由 Jmeter 的一个报错,所引发的一系列困惑与思考

2024-01-31 13:42:26 474

原创 你知道有哪些常用的限流算法吗,分别有什么优缺点呢?

计数器 / 固定窗口算法a. 实现很简单,通过 Redis 的 inc 自增命令就可以实现了b. 存在“毛刺现象”,如我们一分钟内限流100次,在持续性大流量下,很有可能出现这种情况,第一秒钟解收了100个请求,后面59秒都是拒绝状态,61秒又接收了100个请求,后面59持续拒绝。。。也就是该算法无法均匀的限制流量c. 在两个时间窗口的临界点,存在《临界问题》滑动窗口算法a. 将原本的粗粒度细化,如将1分钟限制100请求切分成6个10秒钟的小窗口b. 可以很大程度的解决固定窗口的《临界问题》

2023-12-07 10:36:10 113

原创 谈谈对于 HashSet 的理解

只不过 HashSet 的所有 value 都是由一个变量 Present 来填充的,是一个 Object 对象。其实内部就是依靠 HashMap 实现的,HashSet 使用了组合,有一个成员变量就是 HashMap。add 方法啊,remove 方法啊,底层都是调用的 HashMap 中的方法。

2023-10-28 13:53:53 112

原创 如何设计线程安全的 HashMap?

如何设计线程安全的 HashMap?

2023-10-28 11:45:23 359

原创 如何解决 HashMap 线程不安全的问题呢?

● Collections.synchronizedMap 是使用 Collections 集合工具的内部类,通过传入 Map 封装出一个 SynchronizedMap 对象,内部定义了一个对象锁,方法内通过对象锁实现;● ConcurrentHashMap 在 jdk1.7 中使用分段锁,在 jdk1.8 中使用 CAS+synchronized。● HashTable 是直接在操作方法上加 synchronized 关键字,锁住整个table数组,粒度比较大;

2023-10-28 11:43:04 104

原创 HashMap 为什么线程不安全?

HashMap 为什么线程不安全?

2023-10-28 11:42:29 107

原创 HashMap 的长度为什么是 2 的幂次方?

HashMap 的长度为什么是 2 的幂次方?

2023-10-24 21:30:40 203

原创 Hashmap 扩容流程?

会遍历每个哈希桶,如果只有一个节点的话,就直接插入到 e.hash & (newCap - 1) 的位置;如果是链表,将原来的链表拆分成两个链表, lo 链表和 hi 链表,并将这两个链表分别放到新的table的 j 位置和 j + oldCap 上, j 位置就是原链表在原 table 中的位置, 拆分的标准就是:如果 (e.hash & oldCap) == 0,就放到原本的位置上。Hashmap 扩容流程?

2023-10-24 21:29:59 368

原创 解决 hash 冲突的办法有哪些?HashMap 用的哪种?

解决Hash冲突方法有:开放定址法、再哈希法、链地址法(拉链法)、建立公共溢出区。HashMap中采用的是。解决 hash 冲突的办法有哪些?HashMap 用的哪种?

2023-10-24 21:27:59 256

原创 HashMap 的底层数据结构是什么?

在JDK1.8 中,由“数组+链表+红黑树”组成:当链表过长,则会严重影响 HashMap 的性能,红黑树搜索时间复杂度是 O(logn),而链表是糟糕的 O(n)。在JDK1.7 中,由“数组+链表”组成:数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的。● 当链表长度 > 8 && 数组长度 >= 64 才会转红黑树;其实这种情况,发生的概率很低。● 将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择。,而不是转换为红黑树,以减少搜索时间。

2023-10-24 21:27:06 307

原创 对于 HashMap 自己的理解

putVal(),getNode()方法,都是一上来就判断,头节点是不是我们要找的节点,比较 hash,key。因为哈希冲突,毕竟是发生概率很小的事情,大概率头节点就是我们要找的节点。至于后面,走红黑树的判断逻辑,去遍历链表,都是小概率事件了。通常我们的 Map 里面是不会存储这么多的数据的,所以通常情况下,并不会发生从链表向红黑树的转换。把 key 为 null 的 Node 节点放在了索引下标为 0 的地方。默认的数组容量为 16,默认的加载因子为 0.75 f。

2023-10-24 21:26:04 58

原创 谈谈 ArrayList

快速失败,modCount 用来记录 ArrayList 结构发生变化的次数,结构发生变化是指添加或者删除至少一个元素的操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。出于效率的考虑,数组可能长度100,但实际只用了50,剩下的50其实不用序列化,这样可以提高序列化和反序列化的效率,还可以节省内存空间。Arrays 工具类,内部有二分搜索,优化版本的快速排序,双轴快速排序,数组拷贝 copyof,数组填充 fill 等方法。

2023-10-24 21:21:49 102

原创 双重检测锁中的单例对象,为什么要使用 Volatile 修饰?

在还没有执行完第三步之前,又来了一个线程,这时候 instance!= null,于是就拿到了一个没有初始化的空对象,就出现了问题。● 第三步:将instance 指向对象的内存地址,将内存地址赋值给instance。如果第二步和第三步,发生了指令重排序,先执行第三步,再执行第二步。双重检测锁中的单例对象,为什么要使用 Volatile 修饰?保证 instance 变量的可见性,同时可以禁止指令重排序。new 一个对象,在JVM层面是 3 条指令。● 第二步:对对象进行初始化操作。

2023-10-20 17:42:46 113

原创 Volatile 是怎么保证可见性的?谈谈Volatile的可见性

谈到Volatile的可见性,就得先谈谈 Java内存模型。每个线程都有自己的工作内存,数据都是先从主存中,拉取到工作内存中,操作完数据之后,再把数据推送回主存中的。被Volatile修饰的变量,被修改之后,会立刻通过总线,将最新值推送回主存中,还会通过总线通知其他线程,你们工作内存中的数据失效了,要到主存中去拉取最新值。底层原理:对于Volatile 修饰的变量,在汇编层面,会在写操作的前面,加上 lock 指令。● 2.由于总线的嗅探技术,对于lock前缀的嗅探,会导致其他cpu核心的缓存失效。

2023-10-20 17:41:48 121

原创 Volatile 可以保证什么特性?有什么作用?

cpu 都是把数据从内存拉取到自己的缓存中进行运算,然后在写回内存的。每个cpu 核心都有自己独立的缓存。所以就造成了,多核并发的场景下,数据可能被 A 线程修改了,但是其他线程不知道,cpu 核心还在使用缓存中旧的数据。可以保证可见性,有序性,禁止指令重排序。但是不能保证原子性。线程上下文切换的时候,还是有可能出现线程安全问题。Volatile 就是来解决这个缓存一致性问题的。Volatile 可以保证什么特性?有序性,就是所谓的禁止指令重排序。

2023-10-20 17:41:16 121

原创 CAS 产生的 ABA 问题是什么?怎么解决?

CAS操作可能会出现ABA问题,所谓ABA问题是指在执行CAS操作时,由于CAS操作只对值进行比较,不考虑值的版本等其它附加信息,因此可能导致某个线程误认为成功地将值从A修改为B,但实际上另一个线程已经将值从B又修改回了A,这样就会导致该线程认为修改成功,但实际上数据已经被修改了两次,出现了不一致的情况。CAS 产生的 ABA 问题是什么?

2023-10-20 17:40:45 403

原创 CAS 是什么?

更新值之前,会先判断跟预期值一不一样,如果不一样则不更新,这里会有重试机制;如果跟预期值一样,则更新。这里会产生 ABA问题。CAS 一般结合 Volatile,来一起使用。Volatile,来保证能拿到变量的最新值。CAS 是硬件层面,CPU提供的原子指令。由于该指令在硬件层面实现,因此效率非常高。Compare And Swap,无锁编程。

2023-10-20 17:40:07 53

原创 谈谈悲观锁

像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。悲观锁就是比较悲观,认为自己使用数据的时候,一定会有其他线程来修改数据,所以在获取数据的时候,会先加锁,确保数据不会被其他线程修改。乐观锁,悲观锁,并不是特指什么具体的锁,而是一种策略,思想。● Lock 接口的实现类,比如 ReentrantLock。● Synchronized 关键字。

2023-10-19 18:14:38 98

原创 谈谈乐观锁

像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。乐观锁,只是在更新数据之前,看一下数据有没有被别的线程修改过,如果没有数据没有被别的线程修改过,也不能说的这么绝对,因为存在ABA的问题,就更新数据;如果数据被别的线程修改过了,就不更新,进行重试。乐观锁就是比较乐观,认为自己在使用数据的时候, 不会有其他线程对其进行修改,所以就不会加锁,说白了乐观锁,根本没有锁,是一种无锁编程。乐观锁,悲观锁,并不是特指什么具体的锁,而是一种策略,思想。

2023-10-19 18:14:04 94

原创 Java 对象是什么样子的?

是因为,Java 对象头中存储了 Class 对象的指针。Java 这样设计的好处,可以节省内存的占用,类的元信息有一份就行了,new 出来的对象,可以复用这一份。其实不然,Java 对象中其实只存储了数据,并没有存储其他属性信息。● Object Body,具体的属性值,基本数据类型,就存储值;● Mark Word,32位,64位Java虚拟机,分别是 32 位,64 位。这里的 s 变量,就是我们常说的引用,这里是强引用。指向对象中的 Java对象。Java对象的具体组成:对象头 + 对象体。

2023-10-19 18:11:42 155

原创 说说对 JVM 内存模型的理解

【缓存的命中率是很高的】CPU读写的时候,只操作缓存里的数据,计算完了之后,再把数据写回到内存中。● Java内存模型可不是一个物理上的结构,内存条中可没有什么主内存,工作内存什么的。它只是JVM制定出来的一套规范,Java内存模型,就是对CPU,寄存器,三级缓存,内存,做的一个封装,一个抽象。○ 子线程不能直接使用主内存中的数据,需要先拷贝一份到自己的工作内存中。● 现在的CPU都是多核的,那么缓存就有多个,A 缓存里面的数据被修改了,但是其他缓存并不知道,这时候这会出现数据不一致的问题。

2023-10-19 18:07:42 88

原创 谈谈 Redis 为什么高性能?

● 第三个也就是单线程执行,但大家都没理解单线程执行为啥快,那是因为单线程执行的话你就不需要加锁来控制了,我们要知道锁是一个很重很耗费资源的事情,实测我自己写的渐进式缓存 dict,单线程跑,写100w+读100w,单线程跑也只需要1000毫秒出头。● 第二个就是协议简单,所以序列化和反序列化很快(可能算是最简单的协议了,你自己实现一个都很轻松)谈谈 Redis 为什么高性能?● 第一个是内存存储这个不用说了。

2023-10-18 12:08:52 40

原创 谈谈 Redis 如何来实现分布式锁

但是还是存在分布式问题,比如说,一个客户端在Redis主节点上面加了锁,但是由于主从同步的延迟问题,Redis从节点还没有同步到这个锁数据,这时候其他的客户端就可以在这个Redis从节点上面加相同的锁了。但是 RedLock 只是减少出问题的概率,而且性能差,不推荐使用。这玩意儿就是一种理论设计,平时工作用 setnx+补偿就行了。基于 Hash 数据类型 + Lua脚本 可以实现可重入的分布式锁。基于 setnx 可以实现,但是不是可重入的。谈谈 Redis 如何来实现分布式锁。

2023-10-18 12:04:19 908

原创 Redis 除了做缓存,还能做什么?

防重提交:比如说一个后台系统的保存按钮,很可能出现双击啊等操作,这样就在数据库中新增了多条重复的数据。可以使用 Redis 来做一个防重提交的组件,控制一下提交的时间,比如说,多长时间内的提交,我都认为它是重复的提交。分布式锁:就是利用 setnx key value。如果 key 没有值,就可以设置成功;如果 key 有值了,就设置失败。分布式锁,防重提交,幂等,分布式限流,简易版的消息队列,延迟任务,session 共享。Redis 除了做缓存,还能做什么?

2023-10-18 12:01:08 88

原创 集群脑裂导致数据丢失怎么办?

集群脑裂导致数据丢失怎么办?

2023-10-18 12:00:21 208

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除