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

Python面试题库-持续更新中

问题描述

  1. Python3里面的GIL锁是什么,怎么避免这个问题?
  2. Mysql索引,Django的model层如何加索引,怎么运用到mysql中呢?
  3. 索引为什么快?是怎么实现的?

题解分析:

题解1:Python3里面的GIL锁是什么,怎么避免这个问题?

是什么: Python中的GIL(Global Interpreter Lock,全局解释器锁)是CPython解释器(Python的默认实现)中的一个机制,它确保同一时刻只有一个线程执行Python字节码。GIL的设计初衷是为了简化CPython的内存管理(如引用计数)并避免多线程竞争问题,但它也导致多线程程序在CPU密集型任务中无法充分利用多核CPU。
怎么避免:

  1. 使用多进程替代多线程(不推荐,多进程不仅占用内存多,而且复杂)
  2. 使用Numpy等高效库:其底层C实现会释放GIL,多线程处理数组时可能并行。
  3. 分布式任务队列(如Celery):将任务分发到多台机器执行。
  4. 使用C扩展绕过GIL(干一些不需要操作python对象的 数据计算的活)

题解2:Mysql索引,Django的model层如何加索引,怎么运用到mysql中呢?

代码示例:

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=100)
    email = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        # 单字段索引
        indexes = [
            models.Index(fields=['name']),
        ]
        # 联合索引(多字段)
        indexes = [
            models.Index(fields=['name', 'email']),
        ]
        # 唯一索引
        indexes = [
            models.Index(fields=['email'], name='unique_email_idx', unique=True),
        ]

如何应用到Django

python manage.py makemigrations   # 生成迁移脚本
python manage.py migrate   

引申知识

  1. 选择合适的字段

高频查询字段: WHERE、JOIN、ORDER BY、GROUP BY 涉及的字段。
高区分度字段: 字段值重复率低(如用户ID、邮箱)。
避免冗余索引: 联合索引 (A,B) 可替代单独的 (A) 索引。

  1. 索引类型选择
索引类型适用场景
普通索引(INDEX)常规查询优化
唯一索引(UNIQUE)确保字段唯一性(如邮箱、手机号)
全文索引(FULLTEXT)文本内容搜索(需使用MyISAM或InnoDB)
联合索引多条件组合查询

题解3:索引为什么快?是怎么实现的?

索引之所以能够大幅提升数据库查询速度,其核心原理在于通过高效的数据结构减少数据检索的扫描范围。

一、索引的底层数据结构

B+树:关系型数据库的核心结构

  • 树形分层:B+树是多层平衡树(通常3~4层),每层存储索引键值和子节点指针。
  • 有序性:所有叶子节点按索引键值排序,形成双向链表,支持高效范围查询。

示例:假设一个B+树高度为3,每页(16KB)存储1000个键值:

根节点(1页) → 1000个子节点

中间层(1000页) → 1000×1000=1,000,000个子节点

叶子层(1,000,000页) → 存储实际数据或数据指针

只需3次磁盘I/O即可定位到10亿级数据中的某一行。

  • 哈希索引:精确匹配的极速方案
  • O(1)时间复杂度: 通过哈希函数直接定位数据位置。
  • 局限性: 不支持范围查询,仅适用于等值查询(如WHERE id = 123)。

索引加速查询的三大机制

  1. 减少磁盘I/O次数
  • **全表扫描:**若表有1亿行,需读取所有数据页(假设每页100行,需100万次I/O)。
  • **索引扫描:**通过B+树定位到目标数据,仅需3~4次I/O(树高决定)。
  1. 有序性优化范围查询
-- 范围查询示例:查找2023年的订单
SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';
  • 无索引: 逐行扫描所有记录。
  • 有索引: 定位到2023-01-01的叶子节点,沿双向链表向后遍历至2023-12-31。
  1. 覆盖索引(Covering Index)
  • 无需回表:若索引包含查询所需的所有字段,直接返回索引数据。
-- 假设索引为 (user_id, name)
SELECT name FROM users WHERE user_id = 100;
-- 直接从索引叶子节点读取name,无需访问数据行。

索引的代价

  1. 写操作成本
    插入/更新/删除: 需维护B+树结构,可能触发节点分裂或合并。

示例:插入一条新记录到中间位置,可能导致叶子节点分裂为两页。

  1. 空间占用
    索引大小:一个联合索引(a,b,c)占用的空间可能超过原数据表。


http://www.kler.cn/a/613716.html

相关文章:

  • Android 图片裁剪 压缩等处理记录
  • Stable Diffusion vue本地api接口对接,模型切换, ai功能集成开源项目 ollama-chat-ui-vue
  • java对pdf文件分页拆分
  • [特殊字符] 2025蓝桥杯备赛Day14——P8752 [蓝桥杯 2021 省 B2] 特殊年份
  • 使用QT画带有透明效果的图
  • Linux 配置NFS服务器
  • 自动化发布工具CI/CD实践Jenkins部署与配置教程
  • 算法 | 2024最新算法:鳑鲏鱼优化算法原理,公式,应用,算法改进研究综述,matlab代码
  • Android Gradle 插件问题:The option ‘android.useDeprecatedNdk‘ is deprecated.
  • 浙江大学|DeepSeek系列专题公开课|第一季|PDF+视频(全)
  • word光标一直闪的解决办法
  • linux协议栈网卡接收数据到tcp缓冲区
  • 3.1go流程控制语句
  • 深度学习笔记19-YOLOv5-C3模块实现(Pytorch)
  • Python 爬虫:一键解锁 3GPP 标准协议下载难题
  • XCode16 在Other LInker Flags中,添加-ld64与不添加,有什么区别?
  • sql-labs靶场 less-1
  • hadoop客户端环境准备
  • Linux Shell 脚本使用YAD工具实现Shell图形化界面
  • SpringSecurity过滤器链:核心过滤器的执行顺序与职责