系列综述:
💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于拓跋阿秀、小林coding等大佬博客进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞和关注一下呗,谢谢🎈🎄🌷!!!
🌈【C++】秋招&实习面经汇总篇
ACID事务模型的数据库,采用表格形式存储数据,通过表格中的关系连接实现数据的查询和管理。
BASE模型的数据库,采用多种形式存储数据,通过分布式计算技术实现高可扩展性、高性能和高可用性
长连接 *
修改配置文件中的默认连接超时时间,通过心跳机制定义维护或连接池进行管理连接// 短连接
连接 mysql 服务(TCP 三次握手)
执行sql
断开 mysql 服务(TCP 四次挥手)
// 长连接
连接 mysql 服务(TCP 三次握手)
执行sql
执行sql
执行sql
....
断开 mysql 服务(TCP 四次挥手)
/var/lib/mysql/ 自定义数据库名目录下
.ibd的结构

总结:
数据库的数据部分,由存放再磁盘上的三个文件组成:存储字符集和字符校验规则的.opt文件、存储表结构的.frm文件、存储表空间数据的.ibd文件。存储表空间数据的.ibd文件有四个层次,分为为段、区、页、行,其中,段有三种,一个是存放 B + 树的非叶子节点的区集合的索引段,第二个是存放 B + 树的叶子节点的区集合的数据段,第三个是存放的是回滚数据的区集合回滚段。每个区由64个物理地址连续的物理页构成,可以提高磁盘范围查询的顺序IO性能。每个页默认为innodb一次读写的单位16KB。每个行存储一条数据记录,不同记录具有不同的行格式。
范围查询WHERE 、分组查询GROUP BY 和 按属性排序ORDER BY由非叶子结点组成的多路平衡查找树用于快速的随机查找操作由叶子结点组成的按主键顺序的双链表用于高效的数据的增删操作和基于范围的顺序查找多路表示是一棵多叉树(m>2),每个非叶子结点由两部分组成
按主键顺序的子节点索引链表:每个子节点索引指向一个子节点,且索引结点键值等于索引子节点的最小键值(类似目录查找)。最大和最小键值:主要用于快速定位和过滤查询请求的。平衡表示B+树的每个子树的高度是相等的,尽可能“矮胖”查找表示B+树的快速查找能力较强。
相比B树,非叶子结点不存放数据:可以存放更多的索引,使得树更加“矮胖”,极大减少比较耗时的I/O操作。搜索复杂度为$O(log_dN)$:当最大分支数d大于100时,千万级数据量的查询操作也只需做 3~4 次的磁盘 I/O 操作,即树的高度只有3~4层。页目录由槽组成,索引数据记录分组。数据记录分组由数据记录组成,按主键顺序存储可由二分法进行查找。按指定键顺序进行双链表链接。可以高效满足数据的增删操作和基于范围的顺序查找
索引和数据存储在一起,在一个表中只能有一个聚集索引索引和数据都是单独存储,需要通过索引找到数据行联合索引:建立在多列上的索引,遵循最左匹配原则
函数和计算否定操作符使用or进行条件连接含NULL值列查询条件左右两侧类型不匹配的时候会发生隐式转换like "%value"匹配值第一个为%,会导致全表查询复合索引遵守最左匹配原则,索引字段最好按区分度排序Innodb 的回滚日志(undo log)用于记录事务执行的反向操作undo log必须先于数据持久化到磁盘(谋而后动),优先保证回滚日志的完整性四种隔离级别保证事务的隔离锁机制保证数据的访问隔离MVCC(多版本并发控制)保证并发的访问隔离执行中事务的修改操作,用于事务回滚的撤销操作已提交事务的修改操作(循环区满会被覆盖),用于短时的故障恢复所有已提交事务的修改操作(通常来源于重做日志),用于完整的数据恢复和主从复制未提交读(read uncommitted)
提交读(read committed)
修改前先获取写锁,并将修改保存到事务日志中,然后再提交,从而保证其他事务只能读取已经提交的事务所修改的数据。可重复读(repeatable read)
读写锁共享访问数据,事务修改数据前要使用写锁,保证其他事务无法同时修改数据。事务读取数据前加一个读锁,保证其他事务无法修改数据串行化(serializable )
脏读:A事务执行更新数据操作后发生了回滚,而B事务读到了更新后的数据,但是由于A事务的回滚,导致B事务读取数据和数据库中的不一致。
不可重复读:事务针对同一条记录的前后两次读取结果不同
幻读:事务对于一条查询语句的前后两次执行结果不同

flush tables with read lock加锁,会话结束或者执行unlock tables会自动释放数据的修改操作,比如 insert、delete、update等语句;表结构的修改操作,比如 alter table、drop table 等语句。一条记录的读写锁一个范围的读写锁锁定一个范围,并且锁定记录本身 未提交事务在数据库中的修改操作,若发生数据库崩溃或执行ROLLBACK语句,通过undo log将数据库恢复到事务开始前的状态。插入记录时,存储记录的主键,回滚时只需要删除主键对应的记录删除记录时,存储记录的全部内容,回滚时将该记录再插入更新记录时,存储记录的旧值,回滚时再更新为旧值数据版本链保存事务对数据记录修改的多个版本,每个事务通过隔离级别和快照时间选择合适的版本读取。
已提交事务的所有修改操作,当数据库发生故障时,系统会将重做日志中的操作重新执行,进行crash-safe(崩溃恢复),避免内存断电导致未刷盘的数据丢失写满时将最早写入的记录刷盘并覆盖innodb_log_Buffer_size 参数增加redo log容量(默认16 MB) 正常关闭时;大于 redo log buffer 内存空间的一半时,会触发落盘;每隔 1 秒,将 redo log buffer 持久化到磁盘。事务提交时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘
binlog_cache_size 参数控制,超过缓存大小就要暂存到磁盘。

故意等待,成组提交来实现的,因此可能会增加语句的响应时间,但即使 MySQL 进程中途挂了,也没有丢失数据的风险,因为 binlog 早被写入到 page cache 了,只要系统没有宕机,缓存在 page cache 里的 binlog 就会被持久化到磁盘。写入内核缓冲区,异步提交将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000),表示每次提交事务都 write,但累积 N 个事务后才 fsync,相当于延迟了 binlog 刷盘的时机。但是这样做的风险是,主机掉电时会丢 N 个事务的 binlog 日志。详细解释:MySQL中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到Buffer Pool中。后续的查询都是先从Buffer Pool中找,没有命中再去硬盘加载(page fault?),减少硬盘IO开销,提升性能。更新表数据的时候,也是如此,发现Buffer Pool里存在要更新的数据,就直接在Buffer Pool里更新。然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里,接着刷盘到redo log文件里。
以页为基本单位进行磁盘和内存的交互,一个页的默认大小为 16KB。默认配置下为128MB ,并默认以16KB为单位大小划分缓冲页。可通过调整innodb_buffer_pool_size参数来设置 Buffer Pool 的大小,一般建议设置成可用物理内存的 70%左右整个数据页加载到Buffer Pool中,通过索引你定位到具体数据页,再使用页目录定位具体的数据记录先查缓存,命中再去磁盘读)合适的时机将脏页刷盘。空闲缓冲页的控制块的索引的双链表脏页的控制块的索引的双链表,后台线程就可以遍历 Flush 链表,将脏页写入到磁盘即将访问的页移动到链表头部,如果该页不在链表中,则淘汰链表末尾页redo log 日志满了的情况下,会主动触发脏页刷新到磁盘;Buffer Pool 空间不足时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘;空闲时,后台线程会定期将适量的脏页刷入到磁盘;正常关闭之前,会把所有的脏页刷入到磁盘;
哈希表实现单条记录的快速查询B+树组织索引值,实现任意数据记录的查询