MySQL、内存知识点

230 阅读5分钟

MySQL 索引数据结构,hash 索引怎么获取数据的?

InnoDB 和 MyISAM 默认都是使用的 B+ Tree 索引,所以通常情况我们都是是用的 B+Tree 索引。但是 Mermory 默认使用的 Hash 索引,对于表中的每一行数据,MySQL 都会为其中的所有索引列计算一个 hash code(利用 hash 算法计算)。

使用 MySQL 的 select 语言进行查询操作时,会根据 where 后面的条件索引列计算出 hash code,利用这个 hash code 可以直接获取到对应记录的地址 hash 索引。当然也可以继续补充一下,hash 的索引即只能使用等值查询,不能使用范围查询,所以最好的方式还是用 B+ 树。

聚簇索引和非聚簇索引的区别

通过索引结构来说:

聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据。 非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行。 通过文件存储来说:

聚簇索引:索引和数据是在一个文件里面。 非聚簇索引:索引和数据的存储是分开的两个文件。 通过 MySQL 的存储引擎来说:

MyISAM 使用的是非聚簇索引,InnoDB 使用的是聚簇索引,聚簇索引主键的插入速度要比非聚簇索引主键的插入速度慢很多,聚簇索引适合排序,非聚簇索引不适合用在排序的场合。因为聚簇索引叶节点本身就是索引和数据按相同顺序放置在一起,索引序即是数据序,数据序即是索引序,所以很快。非聚簇索引叶节点只保留了一个指向数据的指针,索引本身当然是排序的,但是数据并未排序,数据查询的时候需要消耗额外更多的 I/O,所以较慢。

设计模式有哪些,动态代理与装饰器模式的区别

把比较常用的说出来就行了,可以选择按照分类进行解答(粗体字是比较重要的设计模式)。

  1. 行为模式包括:策略模式、责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、模板方法模式、访问者模式、状态模式。
  2. 创建型模式包括:抽象工厂模式、建造者模式、工厂方法模式、原型模式、单例模式。
  3. 结构型模式:适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式。

动态代理与装饰器模式的区别:

  • 代理模式就像是入校学习,办理入学手续、分到哪一个班级等等都是年级主任代理校长做的,而校长是不直接见家长和学生的,但是年级主任一样能给学生完成所有的入学流程;
  • 装饰器模式就像是刚刚买来的手机,想要看视频就得下载视频 App,想要聊微信需要下载微信 App,虽然这部手机的功能越来越多,但都是这部手机。

所以两者模式就能容易区分开了,装饰器模式关注于在一个对象上动态地添加方法,而代理模式关注于控制对对象的访问。换句话说,代理模式注重的是对对象的某一功能的流程把控和辅助,它可以控制对象做某些事,重心是为了借用对象的功能完成某一流程,而非对象功能如何。而装饰模式注重的是对对象功能的扩展,不关心外界如何调用,只注重对对象功能加强,装饰后还是对象本身。

什么时候会出现内存溢出,怎么避免这种问题

什么时候会出现内存溢出:

当从年轻代无法回收的对象不停地往老年代复制的时候,老年代区域的对象就会越来越多,最后触发 Full GC,当老年代触发 Full GC 的时候,年轻代还是不停地往老年代复制对象,老年代来不及回收,这个时候就会出现内存溢出,因为老年代没有空间再接收年轻代过来的对象了。当然这是我个人的理解。

咱们看专业的术语,Java 堆用于储存对象的实例,我们只要不断地创建对象,并且保证 GC Roots 到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么随着对象数量的增加,总容量触及最大堆的容量限制后就会产生内存溢出异常。

怎么避免这种问题:

  1. 升级配置,为机器提供更多的内存。
  2. 有一些大的对象如果不使用,可以早早的释放,提醒 JVM 早些进行垃圾回收。
  3. 如果是响应时间优先比如业务系统,可以选择新一代的垃圾回收器,比如 G1。
  4. 如果是吞吐量优先的系统,比如数据分析,可以选择 PS + PO 垃圾回收器。
  5. 如果是单体服务,可以尝试采用集群,减轻服务器垃圾回收的压力。