获得徽章 21
- 2024.4.1 面试题打卡 Day001
问题:如何判断一个结构体是否实现了某接口?【From Go社招面经】
答:把 nil 转成结构体指针并赋值给该 interface,变量用 _ 去忽视防止报未使用错误,这样编译的时候的时候就会报错。
代码参考:
type T struct{}
var _ I = T{} // 判断 T 结构体是否实现了 I 接口
var _ I = (*T)(nil) // 判断 *T(结构体指针)是否实现了 I 接口
当然平时开发场景下 IDE 会提前报错,不用等到编译,这估计是蛮早的题目了,目前测试了下如果有对结构体实际调用的其他场景,哪怕代码运行没有实际运行到那一行,编译时也会报错。估计这个实现更多用于快速标记某个结构体实现了某个接口。
另外注意类型是对接口用的,不能用在这。展开评论点赞 - 2023.8.23 第六届青训营打卡 Day72
今天继续阅读MySQL索引原理相关的文章,这次记录下手动创建索引后,如果表数据为空会发生的事。
MySQL会先看一下当前表的存储引擎是谁,接着会判断一下表中是否存在数据,如果表中没有数据,则直接构建一些索引的信息,例如索引字段是谁、索引键占多少个字节、创建的是啥类型索引、索引的名字、索引归属哪张表、索引的数据结构.....,然后直接写入对应的磁盘文件中,比如MyISAM的表则写入到.MYI文件中,InnoDB引擎的表则写入到.ibd文件中。展开评论点赞 - 2023.8.22 第六届青训营打卡 Day71
今天继续阅读MySQL索引原理相关的文章,这次记录下MySQL两个存储引擎建立索引之后产生的文件:
使用SQL分别创建了两张表:zz_myisam_index、zz_innodb_index,分别使用 MyISAM、InnoDB。
使用 MyISAM 的表会生成有三个文件:
zz_myisam_index.frm:该文件中存储表的结构信息。
zz_myisam_index.MYD:该文件中存储表的行数据。
zz_myisam_index.MYI:该文件中存储表的索引数据。
而 InnoDB 的表只有两个文件:
zz_innodb_index.frm:该文件中存储表的结构信息。
zz_innodb_index.ibd:该文件中存储表的行数据和索引数据。
InnoDB中,表数据和索引数据都一起放在.ibd文件中,也就代表着索引数据和表数据是处于同一块空间存储的,这符合聚簇索引的定义,因此InnoDB支持聚簇索引。
使用 InnoDB 未主动创建聚簇索引,会按照主键 -> 非空唯一索引 -> 引擎定义的隐藏主键的优先级顺序来创建聚簇索引。展开评论点赞 - 2023.8.21 第六届青训营打卡 Day70
今天继续阅读MySQL索引原理相关的文章,这次记录下根据数据量计算 MySQL B+ 树层数相关:
想要计算出树高,首先得有三个值:
①索引字段值的大小。(InnoDB引擎的一页大小为16384Bytes)
②MySQL中B+Tree单个节点的大小。(单个节点中可存储多少个索引信息呢?16KB / 10B ≈ 1638个。)
③MySQL中单个指针的大小。(单个指针被缩小到6Bytes大小)
此时树高为3,也就代表着中间一排是叶节点,只存储指针并不存储数据,而每个节点可容纳1638个索引键+指针信息,因此计算过程是:1638 * 1638 * 16 = 42928704条。展开评论点赞 - 2023.8.20 第六届青训营打卡 Day69
今天继续阅读MySQL索引原理相关的文章,这次聊聊MySQL的索引为什么默认选择了B+Tree这个数据结构。
1、为什么不选用二叉树or红黑树?:树层无法较为稳定的控制,无法很好的利用局部性原理。
2、为什么不选用B-Tree?:对于大范围查询的需求,依旧需要通过多次磁盘IO来检索数据。
3、为什么选用B+Tree?:B+树中上层节点只存储索引值,在叶子节点处存储实际的叶子数。据,并且在叶子节点直接维护了类似链表的数据结构,当需要做范围查询时,只需要定位第一个节点,然后就可以直接根据各节点之间的指针,获取到对应范围之内的所有节点,也就是只需要发生一次IO,就能够确定所查范围之内的所有数据位置。
另外MySQL对传统的B+Tree也进行了下改造,在最底层的叶子节点使用双向链表的方式连接,可支持正序和倒序两种快速范围查询操作。展开评论点赞 - 2023.8.19 第六届青训营打卡 Day68
今天继续阅读MySQL索引原理相关的文章,今天记录下全表扫描过程。
如果确定需要全表扫描,则会运用局部性原理的思想进行一次磁盘IO,再从磁盘IO里的数据去找是否有符合条件的数据。
当本次磁盘IO读取到的所有数据全部筛选完成后,紧接着会看一下表中是否还有其他数据,如果还有则继续触发磁盘IO检索数据,如果没有则将内存中的结果集返回。展开评论点赞 - 2023.8.18 第六届青训营打卡 Day67
今天继续阅读MySQL索引原理相关的文章,今天记录下OS、MySQL中都有的一个优化措施:局部性原理。
局部性原理的思想比较简单,比如目前有三块内存页x、y、z是相连的,CPU此刻在操作x页中的数据,那按照计算机的特性,一般同一个数据都会放入到物理相连的内存地址上存储,也就是当前在操作x页的数据,那么对于y,z这两页内存的数据也很有可能在接下来的时间内被操作,因此对于y,z这两页数据则会提前将其载入到高速缓冲区(L1/L2/L3),这个过程叫做利用局部性原理“预读”数据。
这个是由缓存行大小决定的,比如因特尔的MESI协议中,缓存行的默认大小为64Bytes,也就是说在因特尔的CPU中,一次性会将“当前操作数据”附近的64Bytes数据(2页数据)提前载入进高速缓冲区。
在InnoDB引擎中,一次磁盘IO默认会读取16KB数据到内存。展开评论点赞 - 2023.8.17 第六届青训营打卡 Day66
索引为什么不支持数组、链表、队列等结构,因为这些结构中的元素都是按序并排存储,如果选择这些结构来实现索引,那走索引依旧等价于走全表,并未带来查询时的效率提升,反而带来了额外的存储开销,这是没有意义的。评论点赞 - 2023.8.16 第六届青训营打卡 Day65
今天继续阅读MySQL索引应用相关的文章,给最后的知识点收个尾
1、MRR(Multi-Range Read)机制:MRR机制中,对于辅助索引中查询出的ID,会将其放到缓冲区的read_rnd_buffer中,然后等全部的索引检索工作完成后,或者缓冲区中的数据达到read_rnd_buffer_size大小时,此时MySQL会对缓冲区中的数据排序,从而得到一个有序的ID集合:rest_sort,最终再根据顺序IO去聚簇/主键索引中回表查询数据。
2、Index Skip Scan索引跳跃式扫描:如果没有使用联合索引的第一列数据,MySQL优化器会自动对联合索引中的第一个字段的值去重,然后基于去重后的值全部拼接起来查一遍。该机制在MySQL8.0版本才有,限制也蛮多的,算个MySQL新特性吧。
3、最后是两条关于索引的查询命令:
show status like '%Handler_read%';查看当前会话的索引使用情况。
show global status like 'Handler_read%';:查询全局索引使用情况。展开评论点赞 - 2023.8.15 第六届青训营打卡 Day64
今天继续阅读MySQL索引应用相关的文章,今天记录一下索引的一些机制:
1、索引覆盖:当所查询的列字段在索引中完全包含的时候,可以不经过回表的过程,直接走索引一次查询到数据。
2、索引下推:将Server层筛选数据的工作,下推到引擎层处理。比如查询条件是SELECT * FROM `zz_users` WHERE `user_name` LIKE "竹%" AND `user_sex`="男"; 没有索引下推的时候,会先走`user_name`的索引查出数据,然后返回Server层再回表查 `user_sex`="男",而有了索引下推后,就可以在引擎层就做一次`user_sex`="男"的条件筛选,再返回ID去做回表。展开评论点赞