一、前端面试题
1)vue的生命周期(八个钩子函数)
-
beforeCreate:创建vue示例之前;
-
created:创建实例完成,实现数据的异步请求;
-
beforeMount:渲染DOM之前;
-
mounted:渲染DOM完成,加载组件第一次渲染;
-
beforeUpdate:重新渲染DOM之前,数据更新的操作;
-
updated:重新渲染DOM完成;
-
beforeDestroy:销毁之前;
-
destroyed:销毁完成;
2)watch和computed区别
-
computed:
-
data中没有直接声明要计算的变量,也可以直接在computed中写入;
-
支持缓存,只有依赖数据发生改变,才会重新进行计算;
-
不支持异步,当computed内有异步操作时无效,无法监听数据的变化;
-
computed是计算属性,也就是依赖某个值或者props通过计算得来的数据;
-
computed的值是在getter执行之后进行缓存的,只有在它依赖的数据发生变化(依赖的数据可以是单个,也可以是多个)时,会重新调用getter来计算;
-
-
watch:
-
如果data中没有相应的属性的话,是不能watch的;
-
不支持缓存,数据变,直接会触发相应的操作;
-
支持异步操作;
-
watch是监听器,可以监听某一个数据,然后执行相应的操作;
-
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
-
-
总结:
-
当多个属性影响一个属性的时候,建议用computed;
-
当一个值发生变化之后,会引起一系列的操作(改变其他属性值),这种情况就适合用watch;
-
如果一个数据需要经过复杂计算就用 computed;
-
如果在数据变化时执行异步或开销较大的操作时就用 watch;
-
3)路由跳转有哪几种方式
-
HTML标签:
<router-link to="/home">Home</router-link>
-
JS对象:
// 直接跳转 this.$router.push('/home'); // 替换当前路由记录,而不是添加新的记录 this.$router.replace('/home'); // 后退一步 this.$router.go(-1); // 前进一步 this.$router.go(1);
4) v-if和v-for的优先级
-
VUE2:v-for优先于v-if;
-
VUE3:v-if优先于v-for;
-
注意:同时使用
v-if
和v-for
是不推荐的,因为这样二者的优先级不明显。
5)v-if和v-show的区别
-
v-if
:条件渲染,当条件为假时,元素及其子组件不会被渲染或销毁。适用于频繁切换不显示的情况,有较高的渲染和销毁开销。 -
v-show
:条件显示,元素始终被渲染,只是通过CSSdisplay
属性切换显示或隐藏。适用于频繁切换显示状态的情况,有较低的开销。
简单来说,v-if
控制元素的存在与否,而 v-show
控制元素的显示与隐藏。
二、后端面试题
(一)java基础
1)线程池的四种创建方式
-
newCacheThreadPool
:创建一个带缓存的线程池,池的长度可配置; -
newFixedThreadPool
:创建一个固定大小的线程池; -
newScheduleThreadPool
:创建一个定时执行的线程池; -
newSingleThreadPool
:创建一个单线程的线程池;
2)线程池的五个参数
-
corePoolSize:核心线程池的大小;
-
maximumPoolSize:线程池能创建线程的最大个数;
-
keepAliveTime:空闲线程存活时间,到期销毁;
-
workQueue:阻塞队列,用于保存任务的阻塞队列;
-
handler:饱和策略(拒绝策略);
3)synchronized底层原理
底层依赖一对 monitor
指令实现的,分别为 monitorenter
和 monitorexit
进行控制,当执行 monitorenter
时,内部的计数器自增1,执行 monitorexit
指令时,计数器自减1,计数器为0则说明锁释放。本质上就是监听对象头中的 MarkWord
对象的内容, MarkWord
由64位字节码组成,锁占用三位,偏向锁占用一位,锁类型两位(无锁、偏向锁、轻量级锁、重量级锁);
-
普通方法:锁的是当前的对象 this,谁调用谁就是锁;
-
静态方法:锁的是当前类的Class对象,全局唯一;
-
同步代码块:既可以锁对象,也可以锁类Class;
4)ThreadLocal底层原理
-
内部由一个ThreadLocalMap实现,key 存的是当前 ThreadLocal 对象,value 为存储的值。
-
属于空间换时间。使用后必须调用 remove 删除 Entry 对象,否则有内存泄漏的风险;
-
使用线程池的情况下,使用后未进行清除 Entry 操作;
-
由于 key 使用的是弱引用,在进行Full GC时,会回收弱引用的对象,因此,如果未删除,则会导致 key 回收后,value 无法回收且无法访问,最终引起内存泄漏。
-
5)CAS底层原理及ABA问题
-
全称是 compareAndSwap,即比较和交换。它是通过处理器指令,实现程序的原子性。
-
内部涉及三个变量:
-
V:变量内存地址;
-
A:原始值,修改前;
-
B:修改后的值;
-
-
当执行CAS指令时,会先判断V内存中的值是否等于A,只有等于的时候才会修改为B;
-
ABA问题:
-
在CAS更新的过程中,当读取到的值是A,然后准备赋值的时候仍然是 A,但是实际上有可能A的值被改成了B,然后又被改回了A,这个CAS更新的漏洞就叫做ABA;
-
可以通过增加版本号的方式解决,修改前先判断版本号,再进行CAS操作;Java中有
AtomicStampedReference
来解决这个问题,他加入了预期标志和更新后标志两个字段, 更新时不光检查值,还要检查当前的标志是否等于预期标志,全部相等的话才会更新。
-
6)AQS是什么?
-
全称是
AbstractQueueSynchroner
,即抽象队列同步器。它是java在第二种对外提供的锁的实现,位于java.util.current.lock
包下,属于JUC的核心。 -
AQS定义了对双向队列所有的操作,而只开放了 tryLock 和 tryRelease 方法给开发者使用,开发者可以根据自己重写 tryLock 和 tryRelease 方法,实现自己的并发功能。
7)集合概述
-
List集合:有序、有索引、可重复;
-
ArrayList
:底层由数组实现,线程不安全,增删慢,查改快。 -
LinkedList
:底层由链表实现,线程不安全,增删快,查改慢。 -
Vector
:底层由数组实现,线程安全。每个方法添加有 synchronized 锁;
-
-
Set集合:无序、无索引、不可重复;
-
HashSet
:底层由哈希算法实现,内部依赖 HashMap,存储的所有 value 为一个Object对象; -
TreeSet
:底层由二叉树实现,内部依赖 TreeMap,存储的所有 value 为一个Object对象;
-
-
Map集合:双列集合;
-
HashMap
:底层由数组 + 链表 + 红黑树实现,首先根据key的哈希值确定存储的下标,之后根据 equals 方法判断链表的下标位置,相等进行覆盖,不相等插入在所在链表末尾的位置。当数组长度大于64,且链表长度大于8时,链表会转换为红黑树,链表长度小于6时,红黑树转换为链表,目的是为了提升查找的性能; -
TreeMap
:底层由二叉树 + 比较器实现,首先判断根节点是否有值,之后根据compare方法比较值的大小,小的存储在根节点左边,大的存储在右边。每次修改都会进行排序; -
HashTable
:与HashMap的区别:-
HashTable不能存储null键和null值;
-
HashTable是线程安全的,内部方法都添加了synchronized锁;
-
-
8)forEach原理
-
迭代器的forEach:使用的是 Itrator 接口的方法,底层使用增强for循环实现;
-
stream流的forEach:底层调用方法获取对应的 Spliterator 子类对象,每个集合都有自己的实现方式,内部为 do...while 循环实现;
9)重写和重载的区别
-
方法重写:发生在子父类关系中,子类可以重写父类的方法,方法名必须相同,修饰符只能更大,异常只能更小,返回值只能更小;
-
方法重载:发生在同一个类中,方法名相同,方法类型不同、方法参数不同、方法参数顺序不同;
(二)常用框架
1)简述Spring框架
-
IOC:控制反转,反转的是创建对象的权力;
-
DI:依赖注入,是控制反转的一种实现方式。容器中的Bean的属性由IOC容器进行注入;
-
-
AOP:面向切面编程,将不同的对象建立关系,在程序运行期间进行动态结合;
-
jdk动态代理:实现接口。
-
cglib动态代理:继承父类,父类不可被final关键字修饰。
-
2)AOP的五种通知类型
-
前置通知:@Before,在连接点之前执行通知;
-
后置通知:@After,在连接点之后执行,不论方法是否执行成功都进行通知;
-
环绕通知:@Around,在连接点前后都会执行通知;
-
返回后通知:@AfterReturn,方法正常执行结束时通知,抛异常不通知;
-
抛异常通知:@AfterThrowing,方法抛出异常时进行通知;
3)Mybatis中 #{}
与 ${}
的区别
-
#{}
:预编译处理;程序运行时,将#{}
替换为?
进行SQL语句的保存,并解析内部的OGNL表达式,最终执行PreparedStatement
的方法时,使用set方法,将?
替换为#{}
中OGNL表达式的值; -
${}
:字符串替换;程序运行时,将${}
替换为内部的值,不进行OGNL的解析;
4)SpringBoot启动步骤(暂无)
5)描述@SpringBootApplication注解
添加此注解的类,表示为SpringBoot的启动类,内部包含三个注解:
-
@SpringBootConfiguration
:本质为@Configuration
注解,扫描当前包及其子包下的配置类; -
@ComponentScan
:扫描当前包及其子包下的所有Bean注入容器; -
@EnableAutoConfiguration
:开启Spring自动配置类,将符合条件的配置类注入容器;-
内部包含一个
@Import
注解,作用是导入一个扫描器类,自动扫描spring.factories
文件,此文件记录了SpringBoot支持的所有自动配置类,并判断哪些配置类符合自动配置的条件并注入容器;
-
6)SpringBoot自动配置原理
-
Spring Boot 自动配置通过扫描类路径中的依赖项和配置文件,基于条件注解(如
@ConditionalOnClass
、@ConditionalOnMissingBean
)自动配置Spring应用上下文的Bean。它使用spring.factories
文件定义自动配置类,通过@EnableAutoConfiguration
注解启用,简化开发人员的配置工作,提升开发效率。@EnableAutoConfiguration
注解存在于springboot的启动类@SpringBootApplication
注解中。
7)SpringBoot Starter原理
-
自动配置:Spring Boot Starter通常会提供一组默认的自动配置,这些自动配置可以根据类路径上的依赖自动配置Spring应用程序的各个组件。自动配置通过条件注解和条件匹配器来确定是否需要应用某个配置。
-
依赖管理:Spring Boot Starter会管理一组相关的依赖,以确保它们的版本兼容性和稳定性。通过引入Spring Boot Starter,你无需手动管理这些依赖的版本,Spring Boot会自动为你解决版本冲突和依赖关系。
-
提供默认配置:Spring Boot Starter还可以提供一组默认的配置属性,这些属性可以在应用程序中进行自定义配置。通过这些配置属性,你可以修改默认行为,以满足你的需求。
-
简化开发:Spring Boot Starter的目标是简化开发过程,使开发者能够更专注于业务逻辑而非繁琐的配置。通过引入适当的Starter,你可以快速搭建起一个可运行的Spring应用程序,并且可以根据需要选择性地添加其他Starter。
8)OpenFeign原理
-
定义接口:首先,你需要定义一个Java接口来描述要调用的远程服务的API。在接口上使用
@FeignClient
注解指定要调用的服务名称,并使用@RequestMapping
等注解定义具体的API方法。 -
生成代理:当应用启动时,OpenFeign会扫描带有
@FeignClient
注解的接口,并生成该接口的代理对象。代理对象封装了底层的HTTP请求逻辑。 -
发起请求:当你在代码中调用接口的方法时,实际上是在调用代理对象的方法。代理对象会根据方法的注解信息生成对应的HTTP请求。
-
处理请求:代理对象将生成的HTTP请求发送到目标服务,并等待响应。在发送请求之前,OpenFeign会根据配置的负载均衡策略选择一个可用的服务实例。
-
解析响应:一旦接收到响应,OpenFeign会将响应解析成Java对象,并返回给调用方。你可以使用
@ResponseBody
注解指定响应体的解析方式,比如JSON、XML等。
9)Nacos注册中心原理
微服务启动时,检查是否启用nacos的服务发现,如果开启了此配置,将会把当前微服务的微服务名称、IP地址 + 端口号等信息发送至Nacos注册中心,Nacos注册中心采用一个Map进行保存,key为微服务的名称,value维护了一个集合,内部存储了多个节点的微服务信息。
微服务调用时,采用负载均衡算法进行查找对应的微服务IP端口号进行返回。
10)Nacos配置中心原理(暂无)
11)SpringSecurity与Shiro如何使用
-
SpringSecurity:
-
创建配置类,重写
WebSecurityConfigurerAdapter
类的两个configure方法-
认证:用户鉴权,接口认证拦截;
-
授权:权限管理,拦截器与处理器的注册;
-
-
注解开启全局方法安全开关,对所有方法使用注解进行鉴权;
-
-
Shiro:
-
Subject:存储当前用户,或与当前应用交互的对象;
-
SecurityManger:Shiro的核心,管理所有的Subject,与安全有关的操作都会与安全管理器交互;
-
Realm:数据访问控制,获取用户的角色、权限,验证用户身份时需要从Realm获取数据;
-
12)分布式事务:
-
名词解释:
-
TM:
Transaction Manager
,事务管理者。定义全局事务的范围,开始全局事务、提交或回滚; -
RM:
Resource Manager
,资源管理者。管理分支事务处理的资源,与 TC 交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚; -
TC:
Transaction Coordinator
,事务协调者。维护全局和分支事务的状态,驱动全局事务提交或回滚;
-
-
四种事务模式:
-
XA模式:事务提交至事务协调者TC,由TC统一决定是否提交事务;
-
AT模式:事务直接提交,并记录
undo_log
日志(SQL执行前后各一条),异常后根据日志回滚; -
TCC模式:自行决定事务的提交回滚策略,指定执行的方法;
-
Saga模式:长事务解决方案,一种分布式异步事务。分两种实现:
-
状态机引擎:通过事件驱动的方法异步执行提高系统吞吐,可以实现服务编排需求;
-
基于注解和拦截器:开发简单、学习成本低;
-
模式 一致性 隔离性 侵入性 性能 场景 XA 强一致 完全隔离 无 差 对一致性、隔离性有高要求的业务 AT 弱一致 依赖全局锁隔离 无 好 基于关系型数据库的大多数分布式事务场景 TCC 弱一致 资源预留隔离 prepare commit cancel 需编写三个接口 优 对性能要求较高的事务。 有非关系型数据库要参与的事务 Saga 最终一致 无 需编写状态机、 补偿业务 优 业务流程长、业务流程多, 参与者包含其它公司遗留系统服务, 无法提供 TCC 模式要求的三个接口 -
-
设计问题处理:
-
脏写:事务回滚前,需校验数据库与记录日志是否相同,如果不同,说明出现了脏写,需人工处理;
-
允许空回滚:Try拥堵或其它原因未执行,Cancel执行了;
-
防悬挂控制:Cancel比Try先执行了,即允许空回滚,但要拒绝空回滚后的Try操作;
-
幂等控制:Try、Commit、Cancel要保证幂等性,即一次请求和多次请求对系统资源的影响是一致的;
-
13)POI与EasyExcel区别
-
功能和用途:
-
Apache POI是一个功能强大的Java库,用于读取、写入和操作Microsoft Office格式的文件,包括Excel、Word和PowerPoint等。它提供了广泛的API,可以实现对Excel文件的各种操作,如读取、写入、格式化、样式设置、图表生成等。
-
EasyExcel是一个基于POI封装的简单易用的Java库,专注于Excel文件的读写操作。它提供了简洁的API,使得开发者可以更方便地进行Excel文件的读取和写入。
-
-
简易性:
-
EasyExcel相对于POI来说更加简单易用,它提供了一些简化的API和注解,使得开发者可以更快速地进行Excel文件的读写操作。EasyExcel还支持将Java对象直接映射到Excel的行列中,简化了数据的转换和处理过程。
-
-
性能:
-
由于EasyExcel是基于POI进行封装的,因此在性能上两者可能没有明显的差异。但是EasyExcel在一些性能优化方面进行了改进,例如使用缓存、批量写入等,可以提高处理大量数据时的效率。
-
-
社区支持和更新频率:
-
Apache POI是一个成熟的开源项目,拥有广泛的用户群体和活跃的社区支持。它经过多年的发展和更新,具有稳定性和可靠性。
-
EasyExcel是一个相对较新的项目,但也有一定的用户群体和社区支持。它的更新频率可能相对较高,可以更快地适应一些新的需求和变化。
-
总的来说,如果你需要进行复杂的Excel文件处理,包括读取、写入、格式化、样式设置等,那么POI是一个更全面和强大的选择。而如果你只需要进行简单的Excel文件读写操作,并且希望有更简洁易用的API,那么EasyExcel是一个更好的选择。
(三)设计模式
1)单例模式:有且仅有一个实例
2)代理模式:AOP切面编程
3)模板模式:针对复杂API进行一系列的、有规律的封装
4)工厂模式:创建不同的对象的工厂
5)适配器模式:抽象类实现接口,子类继承抽象类,仅需重写需要的方法即可
6)装饰者模式:装饰一个基础类,使其已有的功能更强大
7)责任链模式:一次请求贯穿所有处理器
8)策略模式:减少大量重复性的判断逻辑
9)委托模式:委托他人代替执行某些事情,无需考虑执行逻辑
(四)中间件
1)redis的几种数据结构及时间复杂度(暂无)
2)redis持久化方式
-
rbd形式:默认方式。存储的是对应的二进制文件,占用内存小,恢复快,数据易丢失;
-
aof形式:存储的是redis命令,占用内存大,恢复慢,数据不易丢失;
3)redis缓存淘汰策略
-
redis采用定期删除 + 惰性删除 + 内存淘汰策略;
-
定期删除:每隔100ms,随机抽取数据检查;
-
惰性删除:当获取key时,redis将检查此key是否过期;
-
内存淘汰:当前两种情况不会删除全部的过期数据,导致内存占满,此时实施内存淘汰机制;
-
noeviction:进行报错;
-
allkeys-lru:移除最少使用的key;
-
allkeys-random:随机移除key;
-
volatile-lru:从设置过期时间的key中,移除最少使用的key;
-
volatile-random:从设置过期时间的key中,随机移除key;
-
volatile-ttl:从设置过期时间的key中,移除最先过期的key;
-
-
4)redis的缓存穿透、缓存雪崩
-
缓存穿透:大量请求查询缓存中不存在的数据,导致所有请求打入数据库,导致数据库异常;
-
互斥锁:查询数据库时,需要排队获取锁进行查询;
-
布隆过滤器:维护一系列有效的的key,查询其他的key时直接返回;
-
异步更新:无论key是否取到都进行返回,使用异步线程去维护key的有效性;
-
-
缓存雪崩:大量缓存同时失效,导致所有请求打入数据库,导致数据库异常;
-
随机过期:为每一个key设置随机失效时间,而不是同时失效;
-
双缓存:一个设置失效时间,一个不设置。获取数据依次获取,异步维护key的有效性;
-
5)RabbitMQ原理
-
消息生产者(Producer)将消息发送到RabbitMQ的交换机(Exchange)上。消息可以是任何形式的数据,例如文本、JSON、图像等。
-
交换机根据预定义的路由规则,将消息路由到一个或多个消息队列(Queue)中。路由规则可以根据消息的特性进行匹配,例如消息的标签、类型等。
-
消息队列存储着消息,等待消费者(Consumer)来处理。消费者可以通过订阅特定的队列来接收消息。
-
消费者从队列中获取消息,并对消息进行处理。处理可以是任何业务逻辑,例如存储到数据库、发送邮件、执行计算等。
-
一旦消息被消费者处理完成,RabbitMQ会将消息从队列中删除。
6)Kafka基本原理
-
主题(Topic):数据被发布到Kafka的主题中。主题是消息的逻辑容器,可以理解为数据的分类。
-
分区(Partition):每个主题可以被分为多个分区,每个分区是一个有序的、不可变的消息序列。分区可以在多个服务器上进行复制,以实现冗余和容错性。
-
生产者(Producer):生产者将消息发布到指定的主题中。生产者可以选择将消息发布到特定的分区,也可以让Kafka自动选择分区。
-
消费者(Consumer):消费者订阅一个或多个主题,并从分区中读取消息。消费者可以以不同的方式读取消息,例如按照时间顺序、按照偏移量、按照消息键等。
-
消费者组(Consumer Group):多个消费者可以组成一个消费者组,共同消费一个主题的消息。每个分区只能被消费者组中的一个消费者消费,这样可以实现负载均衡和并行处理。
-
偏移量(Offset):每个消息在分区中都有一个唯一的偏移量,用于标识消息在分区中的位置。消费者可以通过指定偏移量来读取特定位置的消息。
7)ElasticSearch倒排索引
(五)大数据(大数据一点不会啊)
1)百万级数据批量导出
2)上亿数据去除重复
-
使用Redis的BitMap
3)Samza转换Flink
三、数据库面试题
1)事务的四大特性(ACID)
-
原子性:事务只能是同时成功,或者同时失败;
-
一致性:执行结果必须是从一个一致性状态到另一个一致性状态;
-
隔离性:事务之间相互独立,互不影响;
-
持久性:事务执行结束后,数据将保存在数据库中;
2)ABC联合索引:最左匹配原则
Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c)。 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c 进行查找。当最左侧字段是常量引用时,索引就十分有效。
-
where a=3 and b=5 and c=4;
:正序查询,索引生效; -
where c=4 and b=6 and a=3;
:倒序查询,索引生效; -
where a=3 and c=7;
:a 走索引,b没有用,所以 c 不走索引; -
where b=3 and c=4;
:a 没用到,所以 bc 都不走索引;
3)SQL优化技巧
数据库优化三大方案:
-
数据库服务器内核优化;
-
my.cfg 配置文件,搭配压力测试;
-
SQL语句调优:
-
使用缓存,相同的查询结果进行缓存;
-
建立索引,多表联查,根据连接条件建立索引;
-
使用
explain
关键字进行SQL调优,检查是否命中索引; -
明确一条查询结果时,添加
limit 1
,查到结果立即返回; -
数据库字段类型,使用小的类型,提升读取速度;
-
避免使用
select *
,尽量明确字段,当修改表时,返回字段会变化,产生不必要的查询结果; -
数据量过大时,进行分库分表,垂直分割或水平分割;
-
垂直分割:一张大表,分为多张小表;
-
水平分割:建立多张表,表名规律,使用相应算法进行增删查改;
-
-
选择正确的数据库引擎:MyIsam、InnoDb;
-
4)InnoDb索引与MyIsam索引的区别
-
存储方式:InnoDB使用聚簇索引(Clustered Index),而MyISAM使用非聚簇索引(Non-Clustered Index)。
-
数据文件:InnoDB的数据文件本身就是按照主键顺序进行组织的,因此表数据和索引数据存储在同一个文件中。而MyISAM的数据文件和索引文件是分开存储的。
-
主键索引:InnoDB要求每个表必须有主键,如果没有显式指定,InnoDB会自动创建一个6字节的隐藏主键。而MyISAM对主键没有特殊要求,如果没有显式指定,会使用一个内部的行号作为主键。
-
二级索引:InnoDB的二级索引(非主键索引)的叶子节点存储了主键值,因此在通过二级索引查询时,需要先通过二级索引找到主键值,再通过主键值找到对应的数据行。而MyISAM的二级索引的叶子节点存储了指向数据行的物理地址。
-
并发性能:InnoDB支持行级锁定,可以提供更好的并发性能,多个事务可以同时读写不同的行。而MyISAM只支持表级锁定,当一个事务对表进行修改时,其他事务无法同时对同一表进行写操作。
-
容灾恢复:InnoDB支持事务和崩溃恢复,具备更好的容灾性和可靠性。而MyISAM不支持事务和崩溃恢复,容易出现数据损坏。
综上所述,InnoDB适合于需要高并发性能、事务支持和数据可靠性的场景,而MyISAM适合于读操作较多、对事务支持要求不高的场景。
5)聚簇索引与非聚簇索引的区别
-
数据存储方式:聚簇索引决定了数据在磁盘上的物理存储顺序,而非聚簇索引则是独立于数据存储的。聚簇索引将表的行存储在物理上相邻的位置,而非聚簇索引则是将索引的键值和对应的行指针存储在一起。
-
唯一性:一个表只能有一个聚簇索引,而可以有多个非聚簇索引。聚簇索引通常是基于主键或唯一约束创建的,因此它们的键值是唯一的。非聚簇索引可以是唯一或非唯一的。
-
查询性能:由于聚簇索引决定了数据的物理存储顺序,因此当使用聚簇索引进行范围查询或顺序访问时,性能通常较好。而非聚簇索引需要通过索引来查找行的位置,然后再根据行指针找到实际的数据行,所以在范围查询或顺序访问时性能可能较差。
-
数据插入和更新性能:由于聚簇索引决定了数据的物理存储顺序,插入新数据时可能需要移动已有的数据行,因此插入和更新性能可能较低。而非聚簇索引只需要插入索引键值和行指针,所以插入和更新性能通常较好。
6)BTree索引与Hash索引的区别
-
数据结构:BTree索引使用B树(或B+树)数据结构,而Hash索引使用哈希表数据结构。
-
查询方式:BTree索引支持范围查询,可以高效地处理范围查询和排序操作。而Hash索引仅支持精确匹配查询,对于范围查询和排序操作效率较低。
-
内存使用:BTree索引可以有效利用内存,适用于大数据集的索引。Hash索引需要将全部索引数据加载到内存中,适用于较小的数据集。
-
唯一性:BTree索引可以处理重复键值,支持非唯一索引。而Hash索引要求键值是唯一的,不支持重复键值。
-
插入和更新性能:BTree索引在插入和更新操作时需要维护索引的平衡性,性能相对较低。而Hash索引在插入和更新操作时直接计算哈希值,性能较高。
基于以上区别,BTree索引适用于需要范围查询、排序或非唯一索引的场景,比如在关系型数据库中常用于处理SQL查询。而Hash索引适用于需要快速精确匹配查询、唯一键值的场景,比如在内存数据库或缓存中常用于快速查找操作。
7)简述一下binlog、redolog、undolog
-
binlog:数据归档。记录数据修改之后的值。
-
redolog:数据恢复。数据更新后,先写入redolog,再做最终的修改;
-
undolog:数据回滚。记录数据修改之前的值。默认存储在全局表空间内,即写undolog时,也会写入redolog中;
-
总结:
-
Buffer Pool
是MySQL进程管理的一块内存空间,有减少磁盘IO次数的作用。 -
redo log
是InnoDB存储引擎的一种日志,主要作用是崩溃恢复,三种刷盘策略如下:-
innodb_flush_log_at_trx_commit=0
:延迟写,延迟刷,效率高,丢数据几率高; -
innodb_flush_log_at_trx_commit=1
:实时写,实时刷,效率低,丢数据几率低; -
innodb_flush_log_at_trx_commit=2
:实时写,延迟刷,效率较高,丢数据几率较低(推荐);
-
-
undo log
是InnoDB存储引擎的一种日志,主要作用是回滚。 -
bin log
是MySQL Server层的一种日志,主要作用是归档。 -
MySQL挂了有两种情况:
-
操作系统挂了MySQL进程跟着挂了;
-
操作系统没挂,但是MySQL进程挂了。
-
-