Python 多线程高频面试题,直接把这些答案“甩在”面试官脸上

Python 多线程高频面试题,直接把这些答案“甩在”面试官脸上赞 点赞 收藏 加关注 下次找我不迷路不管你是刚入行的新手 还是有一定经验的开发者 掌握多线程的核心问题 都能让你在面试中脱颖而出 今天咱就来盘一盘 5 个高频的 Python 多线程面试题 用通俗易懂的语言解释 让你轻松弄懂 记得拿小

大家好,欢迎来到IT知识分享网。

点赞、收藏、加关注,下次找我不迷路

不管你是刚入行的新手,还是有一定经验的开发者,掌握多线程的核心问题,都能让你在面试中脱颖而出。今天咱就来盘一盘 5 个高频的 Python 多线程面试题,用通俗易懂的语言解释,让你轻松弄懂,记得拿小本本记好哦!

Python 多线程高频面试题,直接把这些答案“甩在”面试官脸上


一、线程和进程的区别是啥?(基础必考题)

问题抛出

考官一上来可能就会问:”说说线程和进程的区别吧。” 好多新手听到这个问题,脑子一下子就懵圈了,这俩到底啥关系,又有啥不一样呢?

白话解释

咱打个比方,把计算机比作一个大公司。进程就像是公司里的各个部门,比如研发部、销售部、财务部。每个部门都有自己独立的资源,像研发部有自己的电脑、资料、办公用品,销售部也有自己的一套东西,部门之间是相互隔离的,互不干扰。而线程呢,就好比部门里的员工。一个部门里可以有多个员工,这些员工共享部门的资源,比如同一台打印机、同一个文件服务器。员工之间可以协作完成任务,但如果协作不好,也可能会出问题,比如两个员工同时修改同一个文件,就会产生冲突。

举例说明

比如说,你同时打开了一个 Word 文档(这是一个进程)和一个浏览器(这又是一个进程)。Word 进程有自己的内存空间、文件句柄等资源,浏览器进程也有自己独立的一套。而在 Word 进程里,可能有一个线程负责显示文字,一个线程负责处理键盘输入,这两个线程共享 Word 进程的资源。

答案总结

对比项

进程

线程

定义

资源分配的最小单位

CPU 调度的最小单位

资源

独立拥有资源

共享所属进程的资源

开销

创建、销毁开销大

创建、销毁开销小

并发性

进程间并发

同一进程内线程间并发

健壮性

一个进程崩溃不影响其他进程

一个线程崩溃可能导致整个进程崩溃

记忆诀窍

“进程像部门,资源各自管;线程如员工,共享资源干。”


二、Python 里的 GIL 是啥?为啥有 GIL 还能说支持多线程?(灵魂拷问)

问题抛出

“听说过 GIL 吗?它对多线程有啥影响?为啥 Python 有 GIL 还支持多线程呢?” 这个问题可太关键了,很多人对 GIL 一知半解,面试时很容易栽跟头。

白话解释

GIL 就是全局解释器锁,说白了,就是 Python 解释器为了保证线程安全,搞的一个 “枷锁”。在同一时间,这个锁只能被一个线程持有,也就是说,即使你的电脑是多核 CPU,同一时间也只能有一个线程在执行 Python 字节码。这就好比一群人要过一个狭窄的独木桥,一次只能过一个人,其他人都得在旁边等着。那为啥 Python 还有多线程呢?虽然 GIL 限制了 CPU 密集型任务的并行执行,但对于 IO 密集型任务,比如读写文件、网络请求,线程在等待 IO 的时候,会释放 GIL,让其他线程去执行,这样就提高了效率。

举例说明

比如你有两个任务,一个是计算 1 到 1 亿的和(CPU 密集型),一个是从网上下载两个大文件(IO 密集型)。如果用多线程来执行计算任务,因为 GIL 的存在,两个线程只能轮流执行,速度并不会比单线程快多少。但如果是下载文件,当一个线程在等待网络响应时,会释放 GIL,另一个线程就可以开始下载,这样整体时间就会缩短。

答案总结

GIL 是 Python 解释器中的一个全局锁,确保同一时间只有一个线程执行字节码。对于 CPU 密集型任务,多线程由于 GIL 的存在,无法真正利用多核优势,效率可能不如单线程;对于 IO 密集型任务,线程在等待 IO 时释放 GIL,其他线程可以利用这个时间执行,从而提高效率。所以 Python 的多线程在 IO 密集型场景下是有用的,这也是它支持多线程的原因。

记忆诀窍

“GIL 是把锁,线程轮流走;CPU 任务愁,IO 任务牛。”


三、Python 中创建线程的方式有哪些?怎么用?(实操题)

问题抛出

“说说 Python 里创建线程的方法吧,最好能写个例子。” 这可是考察你实际操作能力的问题,得把步骤说清楚。

白话解释

Python 里主要有两种创建线程的方式,一种是通过 threading 模块的 Thread 类,直接创建线程对象,然后传入目标函数;另一种是继承 Thread 类,重写 run 方法,把要执行的代码放在 run 方法里。就好比你要让工人干活,一种是直接告诉工人去做某个具体的任务(目标函数),另一种是给工人定制一个专属的任务类,让他按照类里的步骤去做。

举例说明

方式一:使用 threading.Thread 创建线程

import threading import time # 定义目标函数 def my_task(name, seconds): print(f"线程{name}开始执行") time.sleep(seconds) print(f"线程{name}执行结束") # 创建线程对象 thread1 = threading.Thread(target=my_task, args=("线程1", 2)) thread2 = threading.Thread(target=my_task, args=("线程2", 3)) # 启动线程 thread1.start() thread2.start() # 等待线程结束 thread1.join() thread2.join()

方式二:继承 threading.Thread 类

import threading import time class MyThread(threading.Thread): def __init__(self, name, seconds): super().__init__(name=name) self.seconds = seconds def run(self): print(f"线程{self.name}开始执行") time.sleep(self.seconds) print(f"线程{self.name}执行结束") # 创建线程实例 thread1 = MyThread("线程1", 2) thread2 = MyThread("线程2", 3) # 启动线程 thread1.start() thread2.start() # 等待线程结束 thread1.join() thread2.join()

方式三:面试官问还有么?

那这家公司咱就不去了,哈哈。

答案总结

创建方式

步骤

特点

适用场景

Thread 类创建

1. 定义目标函数;

2. 创建 Thread 对象,传入目标函数和参数;

3. 调用 start () 启动线程

简单直接,适合简单任务

快速创建单个或多个独立任务线程

继承 Thread 类

1. 定义子类继承 Thread;

2. 重写 run 方法;

3. 创建子类实例,调用 start () 启动

可以封装更多线程相关的属性和方法

需要为线程定制复杂功能或维护线程状态

记忆诀窍

“创建线程两招鲜,目标函数或继承;简单任务用前者,复杂定制后者行。”


四、多线程中为什么需要线程同步?怎么实现?(重点应用题)

问题抛出

“多线程中线程同步是什么?为啥需要它?怎么实现呢?” 这涉及到多线程编程的核心难点,必须搞清楚。

白话解释

线程同步就是让多个线程按照一定的顺序执行,避免出现数据不一致的问题。比如多个线程同时修改一个共享的变量,如果不加控制,就会导致结果混乱。就像两个人同时去修改一个账本,你改一笔,我改一笔,最后账本就乱了,不知道到底哪个是正确的。这时候就需要一把 “锁”,让一个线程在修改的时候,其他线程不能修改,等这个线程改完了,再释放锁,让其他线程来改。

举例说明

假设我们有一个银行账户,两个线程同时往这个账户里存钱,每次存 100 元,一共存 100 次。如果没有线程同步,可能会出现这样的情况:线程 1 读取当前余额是 0,准备加上 100;这时候线程 2 也读取当前余额是 0,也准备加上 100。然后两个线程都把余额写成 100,这样实际上只存了一次,却记录了两次,导致余额错误。加上锁之后,线程 1 在读取和修改余额的时候,锁住这个账户,线程 2 只能等待,等线程 1 改完释放锁,线程 2 再去操作,这样就不会出错了。

答案总结

线程同步是为了保证多个线程对共享资源的访问是有序的,避免数据不一致。实现线程同步的方法主要有以下几种:

  1. 锁(Lock):最基本的同步机制,获取锁的线程执行完操作后释放锁,其他线程才能获取锁。
  1. RLock(可重入锁):同一个线程可以多次获取同一个锁,避免死锁,比如在一个函数里多次调用加锁的方法。
  1. 信号量(Semaphore):控制同时访问资源的线程数量,比如限制最多 3 个线程同时访问某个文件。
  1. 事件(Event):用于线程之间的通信,一个线程设置事件,其他线程等待事件触发。

记忆诀窍

“线程同步很重要,共享资源别乱搞;锁、信号量、事件,按需选择错不了。”


五、什么是守护线程?怎么设置?有啥用?(细节题)

问题抛出

“守护线程了解吗?怎么设置?它和非守护线程有啥区别?” 这是一个考察细节的问题,很多人可能忽略这个点。

白话解释

守护线程就像是一个 “保镖” 线程,它的作用是为其他线程提供服务。当所有非守护线程都结束时,守护线程会自动终止,不管它有没有完成任务。比如你在下载文件的时候,有一个守护线程在后台监控网络连接,当下载主线程结束后,这个监控线程也会跟着结束。设置守护线程很简单,只需要在创建线程后,调用 setDaemon (True) 方法就行。

举例说明

比如我们有一个主线程,创建了一个守护线程来定期清理临时文件。当主线程运行结束后,不管清理任务有没有完成,守护线程都会被终止。如果不设置守护线程,主线程结束后,还得等待这个清理线程完成才能真正退出。

答案总结

守护线程是在后台运行的线程,用于为其他线程提供服务。设置守护线程的方法是在线程启动前调用 setDaemon (True) 或者在创建线程时传入 daemon=True 参数。守护线程的特点是:当所有非守护线程结束时,守护线程会自动终止,不会阻塞程序的退出。它的主要用途是执行一些辅助性的任务,比如日志记录、资源监控等。

记忆诀窍

“守护线程像保镖,服务他人不傲娇;主线程完它就走,设置 daemon 要记牢。”


来个对比,让你一目了然

面试题

核心考点

答案要点

记忆诀窍

线程和进程的区别

定义、资源、开销、并发性

进程资源独立,线程共享资源;进程开销大,线程开销小

进程像部门,线程如员工

GIL 是什么?为啥有 GIL 还支持多线程?

GIL 原理、对多线程的影响

GIL 是全局锁,限制 CPU 密集型任务并行;IO 密集型任务中线程等待 IO 时释放 GIL

GIL 是把锁,CPU 愁 IO 牛

创建线程的方式

Thread 类、继承 Thread 类

两种方式的步骤和特点

目标函数或继承,简单复杂各不同

线程同步

原因、实现方法

避免共享资源混乱,用锁、信号量等实现

线程同步靠锁,共享资源保护好

守护线程

定义、设置、作用

后台服务线程,随非守护线程结束而终止

守护线程像保镖,daemon 设置不能少

只要你把这些内容吃透,面试的时候肯定能对答如流。赶紧把文章收藏起来,多复习几遍,说不定下一个拿到高薪 offer 的就是你!如果还有其他 Python 问题,欢迎在评论区留言,咱们一起讨论学习!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/180213.html

(0)
上一篇 2025-06-07 07:26
下一篇 2025-06-07 07:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信