当前位置: 首页 > news >正文

八股-2025.10.11

1.C++ 的多态机制与虚函数实现原理

当用基类指针或者引用调用同名函数时,能自动根据指针/引用指向的“对象实际类型”,匹配对应的子类实现,而不是由指针本身的类型决定。而实现这一切,底层完全依赖“虚函数”以及配套的“虚表”和“虚指针”结构。

实现多态分为两步:

a.编译期:编译器会为含虚函数的类做两项关键处理

一是为每个“有虚函数的类”生成一张独立的虚表。虚表本质是一个“函数指针数组”,专门存该类所有虚函数的地址。子类的虚表,会优先继承基类的虚表结构(保证虚函数索引位置不变),再使用子类虚函数地址覆盖掉原来基类虚函数的地址;如果子类新增加虚函数,就追加到虚表末尾。

二是为每个“含虚函数的类的对象”偷偷插入一个“虚指针(vptr)”。这个vptr是对象的隐藏成员变量,通常在对象内存对象的开头,它的值就是“当前对象所属类的虚表首地址”。

b.运行期:当用基类指针/引用调用虚函数时,会按三个步骤找到正确的函数:

先通过基类指针拿到指向对象的vptr。再通过vptr,找到对象所属类的虚表。最后根据虚函数在虚表内的“索引位置”,找到对应的函数地址并调用。

https://www.bilibili.com/video/BV1TF411h7k6/?spm_id_from=333.337.search-card.all.click&vd_source=3abe3667e67749032f72d6f512b2a967

2.讲一下乐观锁和悲观锁。

A.悲观锁认为“冲突一定会发生”,所以提前加锁阻塞并发。

a.优点:

实现简单,直接依赖成熟的锁机制,无需手动处理冲突。

数据库安全性高,提前加锁保证原子性,不会出现“脏写”“数据不一致”等问题。

b.缺点:

性能损耗高,锁的获取和释放会带来上下文切换,且未拿到锁的线程会阻塞等待,并发高时会导致“线程排队”,吞吐量下降。

可能引发死锁,若锁的释放逻辑异常(如线程宕机未释放锁),会导致其他线程永久阻塞,需额外处理死锁(如设置锁超时和定时释放)。

c.适用场景:

并发冲突概率高的场景(秒杀系统扣库存或金融交易对账),因为冲突频繁,悲观锁提前加锁能减少“重试开销”。

对数据一致性要求极高的场景(如银行转账),不允许任何并发修改导致的错误,必须通过锁确保操作独占。

d.常见实现方式:

数据库层面:MySQl中的行锁,表锁。

编程语言层面:JAVA的synchronized关键字,ReentranLock类。

分布式层面:基于Redis实现的分布式锁,ZooKeeper分布式锁。

B.乐观锁认为“冲突大概率不会发生”,所以先操作再校验冲突。

a.优点:

性能高,无锁机制,不会阻塞线程,也没有锁的上下文切换开销,高并发下吞吐量比悲观锁高。

无死锁风险,不依赖锁机制。

支持高并发,适合大量“读多写少”的场景,读操作不阻塞,写操作仅在冲突时重试。

b.缺点:

重试开销:若冲突频繁,会导致线程反复重试,浪费CPU资源。

实现复杂:需手动处理“冲突重试”逻辑(重试次数,重试延迟),且无法解决“ABA问题”。

无法解决“写饥饿”问题,若某线程一直重试失败,可能导致“写操作一直延迟”。

c.适用场景:

并发冲突概率低的场景,(如用户资料修改和商品详情页点击量统计),冲突少,重试开销小,,性能优势明显。

读多写少的场景(如电商商品详情查询),乐观锁允许读操作无阻塞,大幅提升吞吐量。

分布式系统避免“分布式锁开销”的场景(如分布式缓存更新),无需竞争分布式锁,通过版本号校验即可实现安全更新。

d.常见实现方式:

版本号机制:给共享资源加一个“版本号字段”,每次修改资源时,版本号+1。

CAS机制:乐观锁的底层实现原理,核心逻辑是“先比较资源当前值是否等于预期值,若等于则交换为新的值,否则失败”,整个操作是原子性的。

https://www.bilibili.com/video/BV1ff4y1q7we/?spm_id_from=333.337.search-card.all.click&vd_source=3abe3667e67749032f72d6f512b2a967

3.MySQL 中的 MVCC 是什么?Read View 在 MVCC 中如何工作?如果没有 MVCC 会怎样?

A.MVCC是InnoDB存储引擎实现高并发读写的核心机制,其核心思想是通过维护数据的多个版本,让读写操作和读操作能并发执行,互不阻塞,从而在保持数据一致性的同时提升系统吞吐量。

a.实现原理:

依赖三个关键组件:

隐藏列:InnoDB为每张表的每条记录添加了三个隐藏列(用户不可见);

  • DB_TRX_ID:创建或最后修改该记录的事务 ID(6 字节);
  • DB_ROLL_PTR:回滚指针(7 字节),指向该记录的上一个版本(存储在 undo 日志中);
  • DB_ROW_ID:若表没有主键,InnoDB 会自动生成该列作为隐含主键(6 字节)。

undolog:存储历史版本

当事务修改记录时,InnoDB不会直接覆盖旧纪录,而是生成记录的新版本,并将新版本的DB_TRX_ID设为当前事务ID。将旧版本的记录写入undolog,新版本的DB_ROLL_PTR指向旧版本在undolog中的位置,形成一条版本链。

Read VIew:判断版本可见性

Read View是事务执行查询时生成的“可见性规则集合”,用于判断当前事务中能看到版本链中的哪些记录。包含四个核心参数:

  • m_ids:当前活跃(未提交)的事务ID列表
  • min_trx_id:m_id中的最小事务ID
  • min_trx_id:系统下一个待分配的事务ID(大于当前所有已分配的ID)
  • creator_trx_id:当前事务的ID

可见性规则判断:对于版本链中的某条记录(trx_id为该版本的事务ID):

  • trx_id == creator_trx_id:可见(当前事务修改的记录,自己可见);
  • trx_id < min_trx_id:可见(该版本由已提交事务创建);
  • trx_id > max_trx_id:不可见(该版本由 “未来” 事务创建);
  • min_trx_id ≤ trx_id ≤ max_trx_id
    • trx_idm_ids中(事务未提交):不可见;
    • trx_id不在m_ids中(事务已提交):可见。

https://www.bilibili.com/video/BV1Hr421p7EK/?spm_id_from=333.337.search-card.all.click&vd_source=3abe3667e67749032f72d6f512b2a967

4.什么是索引?索引有哪些分类?

A.索引是一种用于加速查询效率的数据结构

a.优点:显著提升SELECT查询和WHERE条件过滤的效率

b.缺点:会占用额外空间,且会降低INSERT,UPDATE,DELETE性能(因为修改数据时需要同步维护索引结构)。

B.索引的分类

a.按数据结构分:

B+树索引:底层是B+树,是MySQL最常用的索引类型

哈希索引:基于哈希表实现,通过键值对存储,查询时直接计算哈希值定位数据

全文索引:用于对文本内容进行关键字检索,而非单个字段的精确匹配

R树索引:主要用于空间数据类型,支持范围查询

b.按物理存储分:

聚簇索引:索引结构与数据行存储在一起,索引的叶子节点直接包含整行数据

非聚簇索引:索引结构与数据行分开存储,索引的叶子节点存储的是指向数据行的指针(或主键值)

c.按功能逻辑分:

主键索引(唯一且非空),普通索引,唯一索引(索引列的值必须唯一,但允许NULL),联合索引(基于多个列创建的索引),覆盖索引(索引包含查询所需的所有列)

d.特殊索引:

前缀索引(对字符串的前N个字符创建的索引),空间索引(针对空间数据类型的索引)
https://www.bilibili.com/video/BV1tsakezETs/?spm_id_from=333.337.search-card.all.click&vd_source=3abe3667e67749032f72d6f512b2a967

5.什么是智能指针?有哪些种类?

A.智能指针是C++中用于自动管理动态内存的工具,它本质上是封装了原始指针的类模板。

核心作用是:在对象的生命周期结束时,自动调用析构函数释放所指向的内存,从而避免了内存泄漏-这解决了原始指针需要手动delete,容易因遗忘或异常导致内存泄漏的问题。

B.三种智能指针

a.unique_ptr:独占所有权的智能指针

核心特性:同一时间,一个unique_ptr独占指向的内存,不允许拷贝或赋值(避免多个指针管理同一块内存),只能通过移动语义转移所有权。

b.shared_ptr:共享所有权的智能指针

核心特性:多个shared_ptr可以管理同一块内存,内部通过引用计数机制管理-每增加一个指针指向该内存,计数+1,每销毁一个指针,计数-1,当计数为0时,释放该内存。

c.weak_ptr:弱引用的智能指针(解决了shared_ptr的循环引用问题)

核心特性:一种“弱引用”,不拥有内存的所有权,也不增加引用计数,仅用于管擦和shared_ptr管理的内存。它可以shared_ptr创建,用于判断指向的内存是否还存在(通过lock()方法尝试获取shared_ptr)。

https://www.bilibili.com/video/BV1F3DpYaEcA/?spm_id_from=333.337.search-card.all.click&vd_source=3abe3667e67749032f72d6f512b2a967

https://www.bilibili.com/video/BV1zaDGYTEoS?spm_id_from=333.788.player.switch&vd_source=3abe3667e67749032f72d6f512b2a967

http://www.dtcms.com/a/469465.html

相关文章:

  • 图片上传网站变形的处理旅游网站建设的概念
  • 集团培训网站建设注册公司需要什么条件和手续
  • Spark RDD详解 —— RDD特性、lineage、缓存、checkpoint、依赖关系
  • 玩转Docker系列专栏大纲
  • 网络攻防技术:信息收集技术
  • spark on hive 还是 hive on spark?
  • 搞懂数据通信不用愁!网络基础 + 参考模型 + VRP 配置,一篇全搞定
  • 解决MacOS上CLion调试的时候容器的值显示为0的问题
  • Docker快速入门——第一章Docker入门
  • 建站助手官网淘宝seo具体优化方法
  • 邯郸网站建设哪儿好网站建设参考文献英文书籍
  • STM32 串口收发数据-中断的方式
  • k8s ingress-nginx 学习
  • 【含文档+PPT+源码】基于springboot的旅游路线推荐系统的设计与实现
  • 嘉兴seo网站优化竞价托管的注意事项
  • K8S 概念、安装与核心工作机制详解
  • 做网站需要公司有哪些网站最新点击量排名
  • VUE 开发实例 一则
  • jmeter使用之--MD5加密
  • ESim电工仿真APP使用说明书
  • 【碎片化学习】 Apache JMeter 取样器指南:从入门到精通
  • 【无标题】生活琐记(7)
  • 苍穹外卖day04总结
  • Java Redis “核心基础”面试清单(含超通俗生活案例与深度理解)
  • jmeter中使用正则表达式提取器传递参数
  • 基于大数据的学习资源推送系统的设计与实现 _django
  • 朝阳双桥网站建设竞争对手网站分析
  • 江阴招聘网站建设学徒黄页网页的推广网站
  • C 语言11:输入方法全解析
  • ASP Session详解