• 数据库内核面试中我不会的问题(5)


    新一波不会的题目。

    但是我没有都给出答案是啥,一方面我也不知道,另一方面我实在精力有限,只能先记下来。

     

    1.讲一下乐观锁版本号控制

    使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。
    当我们提交更新的时候,判断数据库表对应记录 的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。

    下一步应该会问我乐观锁版本号控制和悲观锁版本号控制的区别。

    2.说一下二阶段锁的优劣

    整个事务分为两个阶段,前一个阶段为加锁,后一个阶段为解锁。在加锁阶段,事务只能加锁,也可以操作数据,但不能解锁,直到事务释放第一个锁,就进入解锁阶段,此过程中事务只能解锁,也可以操作数据,不能再加锁。两阶段锁协议使得事务具有较高的并发度,因为解锁不必发生在事务结尾。它的不足是没有解决死锁的问题,因为它在加锁阶段没有顺序要求。如两个事务分别申请了A, B锁,接着又申请对方的锁,此时进入死锁状态。

    3.进程/线程/协程 调度开销是什么级别的?几kb还是几十kb?时间呢?

    进程切换分两步:

    1.切换页目录以使用新的地址空间

    2.切换内核栈硬件上下文

    对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。

    切换的性能消耗:

    1、线程上下文切换和进程上下问切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。

    2、另外一个隐藏的损耗是上下文的切换会扰乱处理器的缓存机制。简单的说,一旦去切换上下文,处理器中所有已经缓存的内存地址一瞬间都作废了。还有一个显著的区别是当你改变虚拟内存空间的时候,处理的页表缓冲(processor's Translation Lookaside Buffer (TLB))被全部刷新,这将导致内存的访问在一段时间内相当的低效。但是在线程的切换中,不会出现这个问题。

    最显著的性能损耗是将保存寄存器中的内容

    CPU高速缓存失效

    页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个cache就是TLB.当进程切换后页表也要进行切换,页表切换后TLB就失效了,cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢

    开销是kb级别的,因为L1,L2缓存大小也就是kb级的。

    线程切换是微妙级别的。

     

    4.进程的虚拟内存是啥

    虚拟内存详解_神游物外的博客-CSDN博客_虚拟内存

    太多了,我一时半会是看不懂,我大概知道是啥就行了。

     

    5.如何实现缓存一致性?

    (不会让你讲具体实现,但是需要知道一个大概步骤)

    根据缓存一致性协议。

    按照cpu不同,一致性协议也不同,intel用mesi。

    其提供了一种高效的内存数据管理方案,它只会对单个缓存行(缓存行是缓存中数据存储的基本单元)的数据进行加锁,不会影响到内存中其他数据的读写。

    MESI分别代表缓存行数据所处的四种状态,通过这四种状态的切换,来管理缓存数据。

    • M修改(Modefiy):该缓存行有效, 数据被修改了,和内存中的数据不一样,数据只存在于本缓存行中
    • E独享(Exclusive):该缓存行有效,数据和内存中的数据一致,数据只存在本缓存行中
    • S共享(Shared):该缓存行有效,数据和内存中的数据一致,数据同时存在于其他缓存中
    • I无效(Invalid):该缓存行数据无效
       

    当一个处理器请求使用exclusive模式加载load一个缓存行时,其他的处理器会将所有它们自己关于该缓存行的副本都置为invalid。任何一个已修改过自己本地的该对应缓存行的处理器都需要首先将其写回到内存中,之后第一个处理器的load请求才可以被满足。

    当一个处理器请求使用shared模式加载load一个缓存行时,任何一个以exclusive模式加载该line的处理器都必须将其状态置为shared,并且任何一个已经修改过自己本地对应缓存行的处理器都必须将该line写回主内存,之后第一个处理器的load请求才可以被满足。

    如果缓存满了,则可能需要驱逐一个缓存行。如果该line是shared或exclusive状态,那么它可以直接简单的被丢弃。但是如果该line被修改过,那么它必须被首先写回内存之后再丢弃。

    MESI协议只能保证并发编程中的可见性,并未解决原子性和有序性的问题,所以只靠MESI协议是无法完全解决多线程中的所有问题。
     

     

    6.cpu的中断有硬中断软中断,区别?

    中断是一种电信号,当设备有某种事件发生时,它就会产生中断,通过总线把电信号发送给中断控制器。

    (1) 硬中断

    由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包的时候,就会发出一个中断。我们通常所说的中断指的是硬中断(hardirq)。

    (2) 软中断

    为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断(softirq)来完成。
     

    7.悬挂事务解决方案

    (涉及到分布式事务,这块我确实没有学过,没有办法,我觉得一时半会我是没办法学会的。)

    8.线程池如何实现?线程如何关闭?如何确定设置多少

    (几乎是连着问的,既然是并发,那么就会用到线程池。应该是网上找的面试题)

    线程池原理及概念,如何确定线程池大小_飞跃南墙的晓M的博客-CSDN博客_线程池原理

     

    计算型任务: CPU数量的1-2倍
    IO型任务: 根据具体的IO阻塞时长进行考量决定,如tomcat中默认最大线程数:200,也可以考虑根据需要再一个最小数和最大数间自动增减线程数。

    9.了不了解行存和列存底层存储方式?

    (不了解,我是做计算层的,,)

    行存可以看mysql的实现。

    列存可以参照orc格式,hana格式等等。或者 看看ck底层怎么存储的也可以。

  • 相关阅读:
    Python入门系列(四)别再傻傻分不清:列表、元组、字典、集合的区别
    【毕业设计】基于php+mysql+smarttemplate的图片共享系统设计与实现(毕业论文+程序源码)——图片共享系统
    Excel 制作中式排名的方法
    topy库的安装(拓扑优化软件)
    JavaScript对象知识点总结
    [NOIP2007 提高组] 字符串的展开
    微服务项目:尚融宝(29)(后端搭建:实现用户登录(2))
    -0001-11-30 00:00:00 如何处理返回‘-0001-11-30 00:00:00‘的MySQl null日期
    【深入理解Kotlin协程】协程的创建、启动、挂起函数【理论篇】
    【CF1635F】 Closest Pair 题解
  • 原文地址:https://blog.csdn.net/qq_35423190/article/details/126255118