数据库基础面试第二弹

1. 乐观锁和悲观锁的理解及使用

乐观锁和悲观锁是在并发编程中使用的两种并发控制机制,用于解决多线程或多进程环境下的数据一致性问题。

1. 悲观锁(Pessimistic Locking):
  悲观锁的思想是假设并发访问会导致冲突,因此在访问共享资源之前,悲观锁会将资源锁定,确保其他线程无法修改资源。悲观锁的典型应用是数据库中的行级锁,使用SELECT...FOR

UPDATE语句锁定查询结果。

使用悲观锁的过程如下:

  • 当一个线程要访问共享资源时,它会先尝试获取锁。
  • 如果锁已经被其他线程获取,则当前线程会被阻塞,直到锁被释放。
  • 当线程获得了锁之后,它可以安全地访问共享资源,其他线程无法修改该资源。
  • 当线程完成操作后,释放锁,其他线程可以获取到锁并访问资源。

悲观锁的优点是保证了数据的一致性,但是它的缺点是在高并发环境下,锁的竞争会导致性能下降。

2. 乐观锁(Optimistic Locking):
乐观锁的思想是假设并发访问不会导致冲突,因此在线程访问共享资源之前,不会加锁。相反,乐观锁会在更新资源时,检查在此期间是否有其他线程修改了资源。

使用乐观锁的过程如下:

  • 当一个线程要更新共享资源时,它首先会读取资源的版本号或标识。
  • 在进行更新之前,线程会检查资源的版本号是否发生了变化。
  • 如果资源的版本号没有变化,线程会更新资源,并更新版本号。
  • 如果资源的版本号发生了变化,表示有其他线程已经修改过资源,当前线程的操作可能会产生冲突。
  • 在发生冲突时,可以选择进行回滚操作或者重试整个过程。

  乐观锁的优点是在无冲突的情况下,不需要进行加锁操作,从而提高了并发性能。然而,如果冲突频繁发生,会导致大量的回滚和重试操作,降低性能。

总的来说,悲观锁适合对于冲突频繁发生的场景,可以保证数据的一致性;而乐观锁适合对于冲突较少发生的场景,可以提高并发性能。选择使用哪种锁要根据具体的应用场景和性能需求进行

权衡。

乐观锁与悲观锁例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

SELECT stock FROM inventory WHERE product_id = <product_id> FOR UPDATE;

```

在上述代码中,使用 `FOR UPDATE` 子句来锁定库存行,确保其他并发操作无法修改库存数量。

START TRANSACTION;  -- 开启事务

SELECT stock FROM inventory WHERE product_id = <product_id> FOR UPDATE;  -- 获取并锁定库存行

-- 检查库存是否足够

IF stock >= <quantity> THEN

    UPDATE inventory SET stock = stock - <quantity> WHERE product_id = <product_id>;  -- 更新库存

    COMMIT;  -- 提交事务

    -- 库存更新成功,继续后续操作

ELSE

    ROLLBACK;  -- 回滚事务

    -- 库存不足,处理相应逻辑,如提示用户库存不足

END IF;

```

2. 聚集索引和非聚集索引的区别:

聚集索引(Clustered Index)和非聚集索引(Non-clustered Index)是数据库中常用的索引类型,它们在索引的组织方式和数据访问方式上存在一些区别。

聚集索引:

  • 聚集索引定义了数据表的物理排序方式。每个表只能有一个聚集索引,它决定了表中数据行的物理存储顺序。如果一个表有聚集索引,那么数据行将按照聚集索引的排序顺序存储在磁盘上。
  • 聚集索引的叶子节点包含了整个数据行的信息,因此当使用聚集索引进行数据查询时,可以直接通过索引找到所需的数据行。
  • 由于每个表只能有一个聚集索引,一般情况下,聚集索引会选择主键作为索引键。

非聚集索引:

  • 非聚集索引是基于表中的列创建的索引,它存储了索引键和指向对应数据行的指针。一个表可以有多个非聚集索引。
  • 非聚集索引的叶子节点不包含完整的数据行,而是包含了索引键和指向对应数据行的指针。当使用非聚集索引进行数据查询时,首先通过索引找到对应的数据行的指针,然后再通过指针获取完整的数据行。
  • 非聚集索引可以加快数据的查找速度,尤其是在涉及到过滤和排序的查询操作中。

区别总结:

  • 聚集索引决定了数据行的物理存储顺序,而非聚集索引只是提供了数据行的逻辑顺序。
  • 聚集索引的叶子节点包含完整的数据行,而非聚集索引的叶子节点只包含索引键和指向数据行的指针。
  • 一个表只能有一个聚集索引,但可以有多个非聚集索引。

在实际使用中,根据具体的查询需求和数据特点,可以根据需要选择适当的索引类型,以提高数据库的查询性能和数据访问效率。

创建聚集索引和非聚集索引的示例:

1

2

3

4

5

6

7

8

CREATE CLUSTERED INDEX idx_Orders_OrderID ON Orders (OrderID);

上述语句创建了一个名为 "idx_Orders_OrderID" 的聚集索引,它基于 "Orders" 表的 "OrderID" 列。

CREATE NONCLUSTERED INDEX idx_Customers_Email ON Customers (Email);

上述语句创建了一个名为 "idx_Customers_Email" 的非聚集索引,它基于 "Customers" 表的 "Email" 列。

3.  为什么索引用B+树,而不用普通的二叉树

  1. 磁盘访问效率: B+树是一种多叉树,它具有分支因子(即子节点的最大数量)更高的特点。相比之下,二叉树每个节点只有两个子节点。在磁盘上,每次读取或写入的开销是非常昂贵的操作,因此减少磁盘访问次数可以提高索引的性能。B+树的高分支因子意味着在相同高度的情况下,它可以存储更多的键值对,减少了磁盘I/O次数。而二叉树的分支因子较低,可能需要更多的磁盘访问来定位目标数据。

  2. 顺序访问性能: B+树的叶子节点使用链表连接起来,形成一个有序的链表结构。这使得范围查询和顺序访问非常高效。例如,在数据库中,如果需要查询某个范围内的数据(如按时间排序的记录),B+树可以利用有序的叶子节点链表进行快速定位和遍历。而在二叉树中,由于没有有序链表结构,需要进行中序遍历才能获取有序数据,这会增加额外的开销。

  3. 索引的稳定性: B+树作为一种自平衡树结构,对于插入和删除操作具有较好的稳定性。当在B+树中进行插入或删除操作时,只需要对树的部分节点进行修改,而不需要像二叉树那样进行全局的重新平衡。这种特性使得B+树更适合于高效地维护索引结构。

  4. 缓存利用: 现代计算机系统通常都有层次化的缓存结构,其中内存缓存(如CPU缓存)的访问速度远高于磁盘。B+树由于具有高的分支因子,可以存储更多的键值对在每个节点中,因此在搜索过程中可以利用更好地利用缓存,减少内存访问的次数。而二叉树由于分支因子较低,可能需要更多的内存访问来获取相同数量的键值对。

综上所述,B+树相对于普通的二叉树具有更好的磁盘访问效率、顺序访问性能、稳定性和缓存利用,使其成为了广泛应用于索引结构的一种理想选择。

4. Hash索引和B+树索引区别:

Hash索引和B+树索引是两种常见的索引结构,它们在实现原理、适用场景和性能方面存在一些区别。

实现原理:

  • Hash索引: Hash索引使用散列函数将索引键转换为存储位置的散列码。散列码经过映射后直接指向存储数据的位置,因此在访问数据时具有固定的时间复杂度(O(1))。
  • B+树索引: B+树索引是一种多叉树结构,具有根节点、内部节点和叶子节点。每个节点包含多个键值对,通过比较键值来导航到下一个节点。B+树索引通过在树中进行有序查找来定位数据,因此访问时间的复杂度与树的高度相关(通常为O(log n))。

适用场景:

  • Hash索引: Hash索引适用于等值查询,即根据精确的索引键值查找数据。它对于相等比较非常快速,但不适用于范围查询或排序操作。
  • B+树索引: B+树索引适用于范围查询、排序操作和模糊查询。由于B+树的有序性,它可以支持按顺序遍历数据和快速定位范围内的数据。

数据访问性能:

  • Hash索引: Hash索引具有固定的访问时间复杂度(O(1)),因此在等值查询方面非常高效。但是,由于散列函数的散列冲突可能导致链表的形成,这可能会影响性能,尤其是在高负载情况下。
  • B+树索引: B+树索引的访问时间复杂度与树的高度相关,通常为O(log n)。尽管每次访问可能需要多次磁盘I/O,但B+树索引在范围查询和顺序访问方面具有良好的性能。

存储空间利用:

  • Hash索引: Hash索引通常需要预先分配足够的散列槽位,以防止散列冲突。这可能会导致存储空间的浪费,尤其是在数据分布不均匀的情况下。
  • B+树索引: B+树索引在内部节点上存储键值对和子节点指针,而叶子节点上存储键值对和指向数据的指针。相比之下,B+树索引通常可以更好地利用存储空间。

综上所述,Hash索引适用于等值查询,具有固定的访问时间,但不支持范围查询和排序操作。B+树索引适用于范围查询、排序操作和模糊查询,具有较好的顺序访问性能和稳定性,但访问时间复杂度与树的高度相关。选择使用哪种索引结构取决于具体的应用需求和数据访问模式。

5. 索引不适合哪些场景以及有哪些优缺点:

索引在大多数情况下可以显著提高数据库查询的性能,但并不适合所有场景。以下是索引不适合的一些场景以及索引的一些优点和缺点:

索引不适合的场景:

  1. 低基数列: 当列中的唯一值较少时,例如性别列只有两个可能的取值(男或女),建立索引可能不会带来明显的性能提升。在这种情况下,扫描整个表的代价可能比使用索引更低。
  2. 频繁更新的列: 如果一个列经常被更新,索引的维护成本会很高。每次更新列的值时,可能需要更新索引数据结构,这会增加写操作的开销。频繁更新的列可能会导致索引失去效益,甚至降低性能。
  3. 小表: 对于非常小的表,建立索引可能没有太大意义。在小表中,全表扫描的代价可能相对较低,而使用索引进行查找可能会增加额外的开销。

索引的优点:

  1. 加速查询: 索引可以大大加速查询操作,特别是在大型表中。通过使用索引,数据库引擎可以快速定位满足查询条件的数据行,减少了全表扫描的需要。
  2. 支持排序和聚合操作: 索引可以使排序和聚合操作更高效。通过使用有序索引,数据库引擎可以避免对整个表进行排序,从而提高操作的性能。
  3. 优化连接操作: 对于连接操作(如JOIN),索引可以帮助加速数据的查找和匹配,减少连接操作的成本。

索引的缺点:

  1. 占用存储空间: 索引需要占用额外的存储空间。对于大型表和多个索引的情况,索引可能占据相当大的存储空间。
  2. 增加写操作的开销: 当插入、更新或删除数据时,索引需要进行相应的维护操作,这会增加写操作的开销。如果频繁进行写操作,索引的维护成本可能会成为性能瓶颈。
  3. 索引选择和调优困难: 在设计索引时,需要根据实际查询模式和数据访问模式进行权衡和选择。选择不当的索引或过多的索引可能会导致性能下降,而调优索引可能需要经验和测试。

综上所述,索引在大多数情况下是数据库性能优化的重要工具,但在某些场景下可能不适用或需要谨慎使用。正确的索引设计和调优可以提高查询性能,而错误的使用可能会导致额外的开销和性能下降。

6.最左前缀匹配原则是什么

最左前缀匹配原则是数据库索引设计中的一个重要原则,它指出在使用复合索引(Composite Index)时,索引将按照索引键的顺序进行匹配和检索,并且只能利用索引的最左前缀来进行匹配。

具体来说,如果一个复合索引包含多个列(例如(A, B, C)),那么在查询时,最左前缀匹配原则要求查询条件必须从索引的最左侧开始,并且连续地匹配到索引的某个位置为止。也就是说,查询条件可以是(A)、(A, B)或者(A, B, C),但不能是(B)、(C)或者(B, C)。

遵循最左前缀匹配原则的好处是可以最大程度地利用索引的有序性,提高查询的效率。由于索引按照键的顺序存储,因此在查询时只需定位到满足最左前缀条件的索引位置,而不需要扫描整个索引。

举个例子,假设有一个复合索引 (A, B, C),如果查询条件是(A = 1),那么索引可以用于加速查询,因为最左前缀 (A) 匹配成功。但如果查询条件是(B = 2),即使索引中包含了列 B,也无法利用索引进行加速,因为最左前缀不匹配。

需要注意的是,最左前缀匹配原则并不意味着只有最左侧的列可以使用索引,而是强调索引的有序性和连续性。在某些情况下,可以通过创建单列索引或调整索引顺序来更好地利用索引。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/579487.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贪吃蛇小游戏的代码实现之知识点铺垫篇

今天给大家介绍一个很经典的小游戏&#xff0c;它和扫雷在经典小游戏这方面可以说是旗鼓相当&#xff0c;它的名字就是贪吃蛇。贪吃蛇游戏最初为单机模式&#xff0c;后续又陆续推出团战模式、赏金模式、挑战模式等多种玩法。该游戏具体玩法是&#xff1a;用游戏把子上下左右控…

前端常用的工具网站

前端常用的工具网站&#x1f516; 文章目录 前端常用的工具网站&#x1f516;1. 图片在线压缩2. iconfont--矢量图标3. JSON在线格式化4. EMOJIALL--表情符号5. removebg--去除图片背景6. FREE API--免费API接口7. Lorem picsum --随机图片8.UU在线工具 -- 聚合工具 1. 图片在线…

生活服务网站搭建的作用是什么

如今生活服务商家面临获客、信息展示及多渠道传播信息的难题&#xff0c;传统线下形式如街道发传单、人口相传等形式非常低效&#xff0c;容易投入成本得不到回报&#xff0c;且数据难以统计。 互联网时代&#xff0c;线上渠道平台汇聚亿级流量&#xff0c;生活服务商家也需要一…

C++ std::string使用效率优化

字符串操作是任何一个C开发程序无法绕过的点&#xff0c;很多时候针对字符串的操作需要进行优化&#xff0c;从而达到更优的使用效率和内存利用率。一般会采用标准的std::string替代C字符串&#xff0c;一方面是std::string为一个成熟的类对象&#xff0c;其成员操作基本能满足…

什么是“私域流量”?

公域流量&#xff0c;字面意思就是人人都可以用的流量&#xff0c;但要付出一定成本&#xff0c;而且不一定可持续。 具体到实际对象&#xff0c;则是线下流量以及BAT等几个互联网流量大户&#xff0c;尤其是后者&#xff0c;比如微信、QQ、天猫、淘宝、百度、抖音、快手、微博…

vue-awesome-swiper轮播组件

安装版本&#xff1a;"swiper": "^6.0.0", 安装版本&#xff1a;"vue-awesome-swiper": "^4.1.1", <div class"swiper_conter"><swiper class"swiper" :options"swiperOption" ref"mySw…

算法leetcode|94. 二叉树的中序遍历(多语言实现)

文章目录 94. 二叉树的中序遍历&#xff1a;样例 1&#xff1a;样例 2&#xff1a;样例 3&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 94. 二叉树的中序遍历&#xff1a; …

Spring高手之路-Spring AOP

目录 什么是AOP Spring AOP有如下概念 补充&#xff1a; AOP是如何实现的 Spring AOP 是通过代理模式实现的。 Spring AOP默认使用标准的JDK动态代理进行AOP代理。 什么是AOP AOP(Aspect-Oriented Programming)&#xff0c;即面向切面编程&#xff0c;用人话说就是把公共的…

开发人工智能 需要什么工具

人工智能&#xff08;Artificial Intelligence, AI&#xff09;是指利用计算机模拟、扩展和延伸人类智能的理论、方法、技术和应用系统的一门学科。人工智能研究的目标是使计算机能够像人类一样具有智能&#xff0c;能够感知和理解环境、学习和推理、决策和规划&#xff0c;具备…

jar 运行清单文件MANIFEST.MF生成定义Main-Class Premain-Class IDEA maven-assembly-plugin

可运行jar文件中的启动清单文件 META-INF/MANIFEST.MF 内容自定义生成 清单文件中的 Main-Class: Premain-Class: Can-Retransform-Classes: 在maven-assembly-plugin插件中的生成配置如下, 注意命名 <archive> <manifest> <mainClass>c…

Dockerfile构建镜像

Dockerfile构建镜像 Dockerfile 是一个文本格式的配置文件&#xff0c; 用户可以使用 Dockerfile 来快速创建自定义的镜像&#xff0c;另外&#xff0c;使 用Dockerfile去构建镜像好比使用pom去构建maven项目一样&#xff0c;有异曲同工之妙 基本结构 Dockerfile 由一行行…

Intel® SGX Instruction References(五)

文章目录 前言一、Intel SGX Instruction Syntax and Operation1.1 ENCLS Register Usage Summary1.2 ENCLU Register Usage Summary1.3 ENCLV Register Usage Summary1.4 Information and Error Codes1.5 Internal CREGs1.6 Concurrent Operation Restrictions 二、Intel SGX …

亚马逊云科技 re:Invent 2023 产品体验:亚马逊云科技产品应用实践 王炸产品 Amazon Q,你的 AI 助手

意料之中 2023年9月25日&#xff0c;亚马逊宣布与 Anthropic 正式展开战略合作&#xff0c;结合双方在更安全的生成式 AI 领域的先进技术和专业知识&#xff0c;加速 Anthropic 未来基础模型的开发&#xff0c;并将其广泛提供给亚马逊云科技的客户使用。 亚马逊云科技开发者社…

TypeScript学习(基础篇)

前言 在现代的Web开发生态系统中&#xff0c;JavaScript已经成为一种必备的技术。然而&#xff0c;随着应用的增大&#xff0c;JavaScript的一些限制开始显现&#xff0c;例如缺乏静态类型检查和编译时错误检查。这正是TypeScript发挥作用的地方&#xff0c;TypeScript是一种静…

【Linux系统基础】(2)在Linux上部署MySQL、RabbitMQ、ElasticSearch等各类软件

实战章节&#xff1a;在Linux上部署各类软件 前言 为什么学习各类软件在Linux上的部署 在前面&#xff0c;我们学习了许多的Linux命令和高级技巧&#xff0c;这些知识点比较零散&#xff0c;同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用&#xff0c;…

12.26ARM作业

三个按键中断&#xff0c;控制对应灯亮灭 main.c #include "key_it.h"void delay(int ms){int i,j;for(i0;i<ms;i){for(j0;j<2000;j);}}int main(){all_led_init();key1_it_config();key2_it_config();key3_it_config();while(1){printf("do main...\n&…

Linux c++开发-14-IO复用

什么是文件 程序员使用I/O最终都逃不过文件这个概念。 在Linux世界中文件是一个很简单的概念&#xff0c;作为程序员我们只需要将其理解为一个N byte的序列就可以了&#xff1a; b1, b2, b3, b4, … bN 实际上所有的I/O设备都被抽象为了文件这个概念&#xff0c;一切皆文件…

常用命令-设置

目录 系统配置查看系统架构屏幕演示工具合并终端命令Windows cmd命令提示符重启网卡禁止系统更新CMD运行powshell获取文件安装目录微软VC运行库合集强制刷新IP默认程序打开文件SSH免密登录关闭IE增强配置警告滑动关机最近操作记录解决谷歌翻译禁止系统休眠文件传输文件批量改名…

基于Java (spring-boot)的宠物管理系统

一、项目介绍 1、用户端功能&#xff1a; 首页&#xff1a;展示公告列表&#xff0c;宠物科普&#xff0c;介绍流浪宠物&#xff0c;热门活动。 宠物领养&#xff1a;用户搜索想要领养宠物&#xff0c;申请领养&#xff0c;查看自己领养的宠物。 宠物救助&#xff1a;用户能…

C# .Net学习笔记—— 加密和解密算法

一、四种加密方式 1、MD5不可逆加密 2、Des对称可逆加密 3、RSA非对称可逆加密 4、数字证书SSL 二、详解 1、MD5加密 public class MD5Encrypt{public static string Encrypt(string source, int length 32){if (string.IsNullOrEmpty(source)) return string.Empty;HashA…