Python 多线程高频面试题,直接把这些答案“甩在”面试官脸上
moboyou 2025-06-07 16:56 18 浏览
点赞、收藏、加关注,下次找我不迷路
不管你是刚入行的新手,还是有一定经验的开发者,掌握多线程的核心问题,都能让你在面试中脱颖而出。今天咱就来盘一盘 5 个高频的 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 再去操作,这样就不会出错了。
答案总结
线程同步是为了保证多个线程对共享资源的访问是有序的,避免数据不一致。实现线程同步的方法主要有以下几种:
- 锁(Lock):最基本的同步机制,获取锁的线程执行完操作后释放锁,其他线程才能获取锁。
- RLock(可重入锁):同一个线程可以多次获取同一个锁,避免死锁,比如在一个函数里多次调用加锁的方法。
- 信号量(Semaphore):控制同时访问资源的线程数量,比如限制最多 3 个线程同时访问某个文件。
- 事件(Event):用于线程之间的通信,一个线程设置事件,其他线程等待事件触发。
记忆诀窍
"线程同步很重要,共享资源别乱搞;锁、信号量、事件,按需选择错不了。"
五、什么是守护线程?怎么设置?有啥用?(细节题)
问题抛出
"守护线程了解吗?怎么设置?它和非守护线程有啥区别?" 这是一个考察细节的问题,很多人可能忽略这个点。
白话解释
守护线程就像是一个 "保镖" 线程,它的作用是为其他线程提供服务。当所有非守护线程都结束时,守护线程会自动终止,不管它有没有完成任务。比如你在下载文件的时候,有一个守护线程在后台监控网络连接,当下载主线程结束后,这个监控线程也会跟着结束。设置守护线程很简单,只需要在创建线程后,调用 setDaemon (True) 方法就行。
举例说明
比如我们有一个主线程,创建了一个守护线程来定期清理临时文件。当主线程运行结束后,不管清理任务有没有完成,守护线程都会被终止。如果不设置守护线程,主线程结束后,还得等待这个清理线程完成才能真正退出。
答案总结
守护线程是在后台运行的线程,用于为其他线程提供服务。设置守护线程的方法是在线程启动前调用 setDaemon (True) 或者在创建线程时传入 daemon=True 参数。守护线程的特点是:当所有非守护线程结束时,守护线程会自动终止,不会阻塞程序的退出。它的主要用途是执行一些辅助性的任务,比如日志记录、资源监控等。
记忆诀窍
"守护线程像保镖,服务他人不傲娇;主线程完它就走,设置 daemon 要记牢。"
来个对比,让你一目了然
面试题 | 核心考点 | 答案要点 | 记忆诀窍 |
线程和进程的区别 | 定义、资源、开销、并发性 | 进程资源独立,线程共享资源;进程开销大,线程开销小 | 进程像部门,线程如员工 |
GIL 是什么?为啥有 GIL 还支持多线程? | GIL 原理、对多线程的影响 | GIL 是全局锁,限制 CPU 密集型任务并行;IO 密集型任务中线程等待 IO 时释放 GIL | GIL 是把锁,CPU 愁 IO 牛 |
创建线程的方式 | Thread 类、继承 Thread 类 | 两种方式的步骤和特点 | 目标函数或继承,简单复杂各不同 |
线程同步 | 原因、实现方法 | 避免共享资源混乱,用锁、信号量等实现 | 线程同步靠锁,共享资源保护好 |
守护线程 | 定义、设置、作用 | 后台服务线程,随非守护线程结束而终止 | 守护线程像保镖,daemon 设置不能少 |
只要你把这些内容吃透,面试的时候肯定能对答如流。赶紧把文章收藏起来,多复习几遍,说不定下一个拿到高薪 offer 的就是你!如果还有其他 Python 问题,欢迎在评论区留言,咱们一起讨论学习!
相关推荐
- 运维从头到尾安装日志服务器,看这一篇就够了
-
一、rsyslog部署1.1)rsyslog介绍Linux的日志记录了用户在系统上一切操作,看日志去分析系统的状态是运维人员必须掌握的基本功。rsyslog日志服务器的优势:1、日志统一,集中式管理...
- 被MySQL慢日志查询搞废了?3分钟教你快速定位慢查询问题
-
一条慢查询会造成什么后果?刚开始使用MySQL的开发、初级DBA以为就是简单的查询变慢些,体验稍微有一丢丢影响,殊不知,慢查询的破坏力远不止如此。业务高峰期,这头SQL还没处理完,大量新的查询请求堆...
- Linux 查看系统日志 执行日志 安全日志 history 登录日志
-
修改history记录打开配置文件vim/etc/profile或~/.bash_profile显示执行的用户及其IP添加,将下面内容添加到末尾USER_IP=`who-uami2>/...
- Linux系统日志的简单分析(linux系统日志文件有哪些)
-
为了保证Linux系统正常运行、准确解决遇到的各种各样的系统问题,认真地读取日志文件是系统管理员的一项非常重要的任务。因为日志文件能够详细记录系统每天发生的各种各样的事件。用户可以通过日志文件检查错误...
- 如何按天切割日志文件(日志切割命令)
-
简单明了,直接开始,给热爱编程的你我apache修改httpd.conf对以下两行进行调整ErrorLog"|/usr/local/apache/bin/rotatelogs/data/...
- Apache 记录请求响应时间日志(apache日志查看)
-
本文章向大家介绍Apache记录请求响应时间日志,主要包括Apache记录请求响应时间日志使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。官网介绍在A...
- Linux系统LOG日志分析与管理(四)——配置Loganalyzer
-
摘要:Loganalyzer是一款syslog日志和其他网络事件数据的Web前端工具。它提供了对日志的浏览、搜索、基本分析和一些图表报告的功能。其分析所需数据可以从数据库或一般的syslog文本文件中...
- PHP-FPM 学习记录(php.fpm)
-
什么是FastCGI请阅读FastCGI(FastCommonGatewayInterface)的理解这里不再赘述什么是(PHP-FPM)PHP5.4之前只是用来管理php-cgi进程的进程管理...
- Nginx access_log 运行日志查询和配置
-
1.介绍当我们学会Nginx的基本配置之后,可以通过Nginx配置Service代理。管理服务器所有的http和https请求。那么接下来就需要了解Nginx的日志控制,以及相关的文档查看了。你通过...
- PHP 单例模式(php单例模式和工厂模式)
-
单例模式(SingletonPattern)单例模式(SingletonPattern):顾名思义,就是只有一个实例。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向...
- PHP之单例模式(php 单例模式优点及如何实现)
-
单例模式属于创建型模式,何为创建型模式,即创建型模式抽象了实例化过程。他们帮助一个系统独立于如何创建、组合和表示他的那些对象。一个类创建型模式使用继承改变被实例化的类。而一个对象创建型模式将实例化委托...
- 2022年SEO还需要交换友情链接吗(seo还有用吗)
-
友情链接是什么意思?这是一个古老的话题,但对于现在的正规网站依然行之有效,本篇详细讲讲2022年对友情链接的理解与操作。今天,小小课堂网(www.xxkt.org.cn)带来的是《2022年SEO...
- 基于maxkb实现对话一键生成docx分析报告,支持图片和表格
-
通过扩展maxkb的知识库管理和ai对话能力,实现一键生成分析报告及word文档;本次优化点在于:实现用户输入多个问题,一键生成分析报告,并提供word文件将内容下载下来word中支持markdown...
- 新版证书查询系统源码 支持自适应多端
-
TP开发证书查询系统适用于各行业相关证书查询,基于ThinkPHP开发,可以同时多字段区配查询,后台管理界面清新,可批量导入导出数据,格式为:JSON、CSV、Excel等,自适应手机端,PC端...
- Rocky Linux 9 源码包安装php8(rocksdb 源码)
-
RockyLinux9源码包安装php8大家好,我是星哥!今天咱们不聊yum一键安装的“快餐式”部署,来点儿硬核的——源码编译安装PHP8.3。为什么要折腾源码?因为它能让你深度定制PHP功能...
- 一周热门
- 最近发表
- 标签列表
-
- 外键约束 oracle (36)
- oracle的row number (32)
- 唯一索引 oracle (34)
- oracle in 表变量 (28)
- oracle导出dmp导出 (28)
- oracle两个表 (20)
- oracle 数据库 字符集 (20)
- oracle安装补丁 (19)
- matlab化简多项式 (20)
- 多线程的创建方式 (29)
- 多线程 python (30)
- java多线程并发处理 (32)
- 宏程序代码一览表 (35)
- c++需要学多久 (25)
- css class选择器用法 (25)
- css样式引入 (30)
- css教程文字移动 (33)
- php简单源码 (36)
- php个人中心源码 (25)
- php小说爬取源码 (23)
- 云电脑app源码 (22)
- html画折线图 (24)
- docker好玩的应用 (28)
- linux有没有pe工具 (34)
- mysql数据库源码 (21)