当前位置: 首页 > 面试经验 >

腾讯校招实习后端开发二面:灵活而深入的八股最可怕

优质
小牛编辑
94浏览
2024-03-17

腾讯校招实习后端开发二面:灵活而深入的八股最可怕

嗨~我是可拟雀,一个后端开发工程师,毕业于某985大学,目前供职于bat某大厂核心部门后端。每天分享最新面经答案,希望在大环境不好的当下能帮到你,让你多积累面试经验。需要内推或者面经合集请评论哦。

1. Tbase用过吗?咋用的?

答:TBase是鹅基于开源PostgreSQL开发的一款分布式数据库产品,它拥有高可用、高性能、低延迟等特点,在鹅内部得到了广泛应用。TBase的架构原理主要由分布式协调器、分布式存储引擎和分布式节点三部分组成,这三部分相互协作,共同实现了TBase的特性。

TBase提供了一套Java SDK和插件,可以简化接入进程,提高开发效率。开发者可以依照TBase提供的文档和示例代码使用Java API来接入TBase,实现数据存储和管理功能。同时,TBase还提供了死锁检测机制,使用基于图论的死锁检测算法来检测死锁,确保在并发执行中能够解决可能出现的死锁问题。

2. Mysql什么结构?数据怎么写的?buffer pool?redolog?log buffer?

答:

结构分层:MySQL的体系结构可以分为几个主要部分,包括客户端连接器、数据库连接层、数据库服务层等。每一层都有其特定的功能和职责,共同支持MySQL数据库的正常运行。

MySQL写数据的底层原理涉及多个层次和组件的交互。面试版本简单的说:

客户端请求:

客户端(如应用程序)向MySQL服务器发送写入请求,这通常是一个SQL语句,如INSERT、UPDATE或DELETE。请求中包含了要写入的数据、目标表以及其他相关信息。

SQL解析与优化:

MySQL服务器接收到请求后,首先会进行SQL语句的解析。解析器会检查语句的语法是否正确,并生成一个解析树。然后,优化器会对解析树进行优化,选择最佳的执行计划。

写入InnoDB存储引擎(以InnoDB为例):

MySQL支持多种存储引擎,每种存储引擎都有其特定的数据写入方式。以InnoDB为例,它是MySQL的默认存储引擎,支持事务和行级锁定。

a. 写入Buffer Pool:

当数据需要写入时,它首先会被写入到InnoDB的Buffer Pool中。Buffer Pool是InnoDB用于缓存数据和索引的内存区域,通过缓存可以显著提高读写性能。

b. 更改页(Change Buffer):

对于非主键索引的更改,InnoDB可能会使用更改页(Change Buffer)来缓存这些更改,而不是直接写入磁盘。这样做可以减少磁盘I/O操作,提高性能。当这些页被读取到Buffer Pool中时,更改会被合并到页中。

c. Redo Log(重做日志):

为了确保数据的持久性,InnoDB会将数据的更改写入到Redo Log中。Redo Log是循环使用的日志文件,用于记录对数据库的物理更改。即使在数据库崩溃的情况下,也可以通过Redo Log来恢复数据。

d. 后台刷新:

后台进程会定期将Buffer Pool中的数据和索引页刷新到磁盘上,确保数据的持久保存。这个过程是异步的,不会影响前台的SQL执行。

写入磁盘:

最终,数据和索引的更改会被写入到磁盘上的数据文件和索引文件中。MySQL使用特定的文件格式和存储机制来组织和管理这些数据。

需要注意的是,上述过程是一个简化的概述,实际的MySQL写入过程可能涉及更多的细节和复杂性。此外,不同的存储引擎和配置可能会影响写入性能和数据一致性。因此,在实际应用中,需要根据具体的需求和场景来选择合适的存储引擎和配置参数。

Buffer Pool:是MySQL数据库引擎用于缓存数据页(页是磁盘上的一块固定大小的数据单元)的内存区域。在MySQL服务器启动时,Buffer Pool会被初始化,并在整个数据库生命周期中用于高效地管理数据库页的读取和写入。通过缓存数据页,Buffer Pool可以显著减少与磁盘I/O相关的开销,从而提高数据库的性能。

redo log:是InnoDB存储引擎特有的日志,又称重做日志。它是物理日志,可以理解为一个具有固定空间大小的队列,用于记录对数据库所做的更改。当事务提交时,这些更改会被写入redo log,以确保在发生故障时能够恢复数据。redo log的循环复制机制使得其能够持续记录数据库的更改,保持数据的持久性。

Log Buffer:是一块内存区域,用于保存要写入磁盘上的日志文件的数据。对于InnoDB存储引擎,Log Buffer主要存储redo日志和undo日志。其大小由innodb_log_buffer_size变量定义,默认大小为16MB。Log Buffer的内容会定期刷新到磁盘上,以确保日志的持久性。大的Log Buffer可以允许较大的事务运行,而无需在事务提交之前将日志数据写入磁盘,从而节省磁盘I/O操作。

总的来说,MySQL的体系结构、数据写入方式以及Buffer Pool、redo log和log buffer等组件共同构成了其高效、可靠的数据存储和管理机制。通过合理配置和管理这些组件,可以优化MySQL数据库的性能和稳定性。

3. Mysql主从,主节点binlog是同步还是异步的?主机挂了数据是不是没了?写数据时主节点宕机,但向客户端返回成功了,如何保证从节点数据写进去?

答:MySQL的主从复制中,主节点的二进制日志(binlog)的写入是同步的,但binlog的传输到从节点以及从节点应用这些日志是异步的。

  1. 主节点binlog的写入:当在主节点上执行写操作时(如INSERT、UPDATE、DELETE等),这些操作首先会在主节点的内存中完成,并随后同步地写入到主节点的binlog中。这一步是同步的,意味着写操作在返回给客户端之前,必须确保binlog已经成功写入。
  2. binlog的传输:一旦binlog在主节点上生成,它会被传输到从节点。这个传输过程是异步的,意味着主节点不会等待从节点接收并应用这些日志后再继续处理其他操作。
  3. 从节点应用binlog:从节点接收到binlog后,会异步地应用这些日志到其自己的数据文件中。这也是一个异步过程,从节点不会因为应用日志而阻塞主节点的写操作。

主机挂了数据是不是没了?

如果主节点崩溃,并且没有备份或高可用解决方案(如自动故障转移),那么从该崩溃点开始,尚未复制到从节点的数据将会丢失。但是,已经写入到主节点binlog的数据(并且在崩溃前已经传输到从节点)仍然可以在从节点上恢复。

写数据时主节点宕机,但向客户端返回成功了,如何保证从节点数据写进去?

当主节点宕机时,任何已经返回给客户端的成功写操作都已经被写入到主节点的binlog中。但是,这些变更可能还没有被传输到从节点,或者即使已经传输,也可能还没有被从节点应用。

为了保证从节点上的数据一致性,你可以采取以下策略:

  • 使用半同步复制:MySQL的半同步复制模式确保至少一个从节点已经接收并确认了binlog事件,主节点才会返回写操作的成功给客户端。这增加了数据的安全性,但也可能增加写操作的延迟。
  • 设置多个从节点:通过配置多个从节点,你可以增加数据的冗余性。即使一个从节点失败,其他从节点仍然可以保持数据的副本。
  • 定期备份主节点:定期备份主节点的数据和binlog,以便在必要时恢复数据。
  • 使用GTID或其他复制管理工具:这些工具可以帮助你更好地管理和监控复制过程,确保数据的一致性。
  • 实施故障转移策略:例如,使用像ProxySQL或MHA(Master High Availability Manager)这样的工具来自动检测主节点的故障,并快速地将一个从节点提升为新的主节点。

4. innodb相关,索引为啥用b+树,其他索引为啥不行?数据量很大内存放不下咋办?

答:

  1. 多路搜索特性:B+树是一种多路搜索树,这意味着每个节点可以有多于两个的子节点。这种特性使得B+树在树的高度上相对于二叉树有明显的优势,因此可以减少磁盘I/O次数,提高查询效率。
  2. 有序链表特性:B+树的叶子节点形成了一个有序链表,这使得范围查询变得非常高效。而B+树的叶子节点存储了所有数据记录的指针,可以直接进行范围查询和排序操作。
  3. 内部节点设计:B+树的内部节点只存储索引信息,可以存储更多的索引信息,提高索引的覆盖度,减少回表操作。

因此,使用B+树作为索引结构可以显著提高查询效率和覆盖度,减少回表操作,并支持高效的范围查询。

至于数据量很大导致内存放不下的问题,有以下几种常用的解决方案:

  1. 索引优化:选择性创建索引,避免过度索引,以减少索引占用的空间。同时,可以考虑使用复合索引来覆盖多个列的查询需求。
  2. 分区表:对于大型数据库,可以考虑使用分区表来分散数据和索引的存储。通过将数据水平或垂直拆分到不同的分区中,可以减少单个表的内存占用。
  3. 硬件升级:如果以上方法无法解决问题,可以考虑升级服务器的硬件,特别是增加内存容量,以提供更大的内存空间给MySQL使用。
  4. 数据缓存:使用缓存技术如Redis来存储热点数据,减少对数据库的直接访问压力。这样可以释放部分数据库内存,用于存储更多的数据和索引。

5. redis主从了解吗?

5. 实习项目,细问

6. 之前项目中遇到过的困难,有什么收获?说了一个,又被追着问细节..

7. 最后写一个题,LRUCache

原文链接

 类似资料: