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中呢?

代码示例:

python 复制代码
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. 有序性优化范围查询
sql 复制代码
-- 范围查询示例:查找2023年的订单
SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';
  • 无索引: 逐行扫描所有记录。
  • 有索引: 定位到2023-01-01的叶子节点,沿双向链表向后遍历至2023-12-31。
  1. 覆盖索引(Covering Index)
  • 无需回表:若索引包含查询所需的所有字段,直接返回索引数据。
sql 复制代码
-- 假设索引为 (user_id, name)
SELECT name FROM users WHERE user_id = 100;
-- 直接从索引叶子节点读取name,无需访问数据行。

索引的代价

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

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

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

相关推荐
小马不起床5 分钟前
零基础玩转 FastAPI_05:后端课程模块
python·fastapi
jimy115 分钟前
c++的 Type Traits (一)
开发语言·c++
小王20440 分钟前
Day 41:模型注意力机制 — SE / CBAM / ECA
python·深度学习·机器学习
171320330计算机毕设编程1 小时前
计算机毕业设计 基于YOLO改进算法的车辆特征识别系统设计与实现--lw
java·大数据·python·sql·算法
Web极客码1 小时前
Python Ollama 本地 Agent 入门与订单查询实践
开发语言·jvm·python
snhna1 小时前
DeerFlow 2.x 源码拆解:多智能体委派、Skills、沙箱与 Linux 部署实战
人工智能·python
Wx-bishekaifayuan1 小时前
springboot桂味美食分享系统40540-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
kimnoic1 小时前
PHP 8.2的DNF类型怎么用才规范
开发语言·php
Metaphor6922 小时前
如何快速拆分超大 Excel 文件【Python 教程】
python·excel
_Evan_Yao2 小时前
前后端联调怎么排查问题?从 Network 到后端日志,一步步定位错误
开发语言·后端·团队开发·需求分析