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


    1.说一下延迟物化?

    物化和延迟物化_极致OLAP的博客-CSDN博客_延迟物化

    在软件系统中,为了实现计算和存储的优化,会对原始数据做各种中间形态转换,如字典映射,压缩等等。但是数据最后还是要表现它的真实形态的(真实形态才有意义),这时候就需要通过物化,将中间形态转换为原始形态。

    延迟物化就是尽可能将这个过程延后。

     比方说tidb。里面数据是通过chunk来传递的,那么如果一个chunk中有些数据是有效的,有些数据是无效的,那么就可以使用延迟物化技术,构建一个数组来记录有效的行,等最后在将这些行抽出来做成一个新的chunk。

    如果不使用延迟物化,那么每次都构建新chunk,性能损耗就太大了。

    2.对于逻辑地址和物理地址的内存转换原理/映射原理?

    (之前只知道了逻辑地址和物理地址的区别,对于映射关系这块我真没有太深入。然后人家问了,我不会。)

    这里是根据页式内存管理来工作的。浅析逻辑地址与物理地址映射关系_朱里安的博客-CSDN博客_逻辑页号与物理页号的对应关系

    先通过逻辑地址获取逻辑页号和页内偏移量。

    然后可以通过页式内存管理来寻找到对应的物理页号,转换成物理地址。

    其实我是觉得这个和数据库没有啥关系。

    3.如何消除关联子查询?

    PolarDB MySQL 深潜 - 揭秘窗口函数将子查询解关联 - 知乎

     简单来说,就是将子查询转化为join查询。

    根据条件可以转化成join/outer join/semi join/anti join。

    此时的where条件就变成了浮渣存的where条件,可以进行on条件的转换。

    另外子查询还要分成关联子查询和非关联子查询。

    关联子查询采用join的形式,非关联子查询根据数据量转为join或者是where。

    4.并发并行的区别?

    并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。就好像两个人各拿一把铁锨在挖坑,一小时后,每人一个大坑。所以无论从微观还是从宏观来看,二者都是一起执行的。

    并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。这就好像两个人用同一把铁锨,轮流挖坑,一小时后,两个人各挖一个小一点的坑,要想挖两个大一点得坑,一定会用两个小时。

    5.anti join怎么实现?

    和seminjoin类似,但是相反,是在如果完全没有匹配的时候才会进行join,补空值,并返回数据。

    适用于使用 not in的场景,比如

    select * from a where a.id not in(selet b.id from b) 转换成

    select * from a anti join b on a.id=b.id

    6.join reorder怎么实现?

    (这个涉及到的范围比较广了,目前我对cbo那块也不是很熟悉,所以更详细的先搁置)

    是使用cbo查询优化实现的。

    对于两张表的join,比较简单,可以基于数据量多少进行位置转换。

    对于多张表的join,就会变得很复杂,搜索空间会很大,可以使用贪心,动归,记忆化搜索等来减少搜索空间。可以参照一下tidb的实现方式

    7.多线程性能上不去,可能的原因有哪些?

    1.死锁问题

    2.加锁问题,资源抢占

    3.内存同步问题,假并行,不同的cpu对数据读写,多次加载cache。

    4.线程之间协调的开销,上下文切换开销

    5.出现阻塞,生产者消费者协调问题

    (如果要深入问,可能就会问解决方式了)

    两个因素将影响在锁上发生竞争的可能性;

    • 锁的请求频率
    • 以及每次持有该锁的时间

    有三种方式可以降低锁的竞争度

    • 减少锁的持有时间
    • 降低锁的请求频率
    • 使用带有协调机制的独占锁

    并发编程学习——8 学习笔记-多线程影响性能的因素_大·风的博客-CSDN博客

    阻塞上:

    实现阻塞行为时,可以采用自旋等待或者通过操作系统挂起被阻塞的线程。如果等待时间较短,则适合采用自旋等待方式,而如果等待时间较长,则适合采用线程挂起方式。

    go的话是channel,后者。

    锁上优化:

    消除死锁,缩小锁的范围(空间),减少锁的粒度(时间),锁分段(一段数据用多个锁保证)。

    开销上:

    (如果再深入,可能会问线程的几个状态,和怎么切换)

    【五分钟面试题】线程的生命周期和状态切换_是fancy呀的博客-CSDN博客

    线程一共有以下几种状态:

    1、新建状态(New):新创建了一个线程对象。

    2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。

    3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

    4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

    阻塞的情况分三种:

    (1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,

    (2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。

    (3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    8.编程题,给一个字符串,求变换字符串,让每个字符都不在原位置

    (不太好写,最起码当时我是没写出的,需要时间再考虑一下)

  • 相关阅读:
    jenkins结合k8s部署动态slave
    C语言指针操作(四)通过指针引用字符串
    ApiPost接口测试工具
    [架构之路-240]:目标系统 - 纵向分层 - 应用层 - 应用层协议与业务应用程序的多样化,与大自然生物的丰富多彩,异曲同工
    基于Springboot实现口腔牙诊所管理平台项目【项目源码+论文说明】计算机毕业设计
    Jekyll 语句语法、功能的实现方法和结构介绍小手册
    一文讲解Linux内核中的设计模式
    CentOS7---Nginx安装并配置虚拟主机
    house of storm+堆SROP+orw
    安卓毕业设计成品基于Uniapp实现的Android的餐饮订餐点餐管理系统实现的App
  • 原文地址:https://blog.csdn.net/qq_35423190/article/details/126146159