面试题合集

  • 生成器和迭代器
    迭代器:迭代器其实是python中的一个比较抽象的概念,为什么这么说?因为任何对象之中,只有含有next方法或者是iter方法(getitem方法,必须返回特殊的迭代器对象),返回自己本身,我们都可以称之为迭代器。python中常用的迭代器对象有list、str、tuple、set、dict、collection deque都是迭代器。通常我们采用for循环来取其中的元素。当我们在for循环之中调用iter函数的时候,他会返回一个定义了next方法的迭代器对象,通过调用next方法我们就可以遍历出来每一个元素,当元素全部遍历结束之后会抛出一个StopIteration异常。
s = 'abc'
it = iter(s)
it
<str_iterator at 0x107ac29d0>
next(it)
next(it)
'a'
next(it)
'b'
next(it)
'c'
next(it)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-5-bc1ab118995a> in <module>
----> 1 next(it)

StopIteration: 

生成器:首先我们思考这样一个问题,假设现在我们想要储存一百万个数据,我们都知道,通常情况下非常占据系统的内存,恰巧现在我们只需要前3条数据,那么剩下的数据我们就可以认为非常浪费内存空间,那么能否有这样一个算法,可以在循环的过程中推算出后续元素的大小呢?
答案是可以的,这种一边循环生成,一边计算机制我们就称之为生成器。
但是生成器有一个非常大的缺点,就是他只会迭代一次,也就是说,如果我们想要得到全部的元素就需要放在一个for或者是while循环中。

def reverse(str1):
    for i in range(len(str1)):
        yield str1[i]

for char in reverse('golf'):
    print(char)

g
o
l
f

判断是迭代器还是生成器:生成器有一个明显的标志就是yield关键值,英文意思是“产出”。每次遇到yield关键字就会停止,而当遇到next方法的时候,就会从上一次yield停止的地方再一次运行。

  • 线程安全
    线程安全就是指多线程环境下,能够保证多个线程同时执行程序的时候正确运行,而且保证共享的数据可以有多个线程进行存储,但是在同一个时刻只能有一个线程进行操作。多线程环境下解决资源竞争问题的方法就是加锁。
  • 最简单的列表去重
    set集合
  • yield用法
    简单来说就是一个生成器,函数会记住上一次停止在函数体中的位置。当下一次调用next方法的时候,再继续冲上一次停止的位置继续执行。
  • python2和python3的区别
    语法方面:
    函数方面:
    数据类型:
    异常方面:
  • GIL锁对python多线程的影响
    GIL的全称是全局解释锁,为了数据安全所进行的设计,保证每个cpu在同一时间只能执行一个线程。
    在python多线程下,每个线程执行方式:
    1、获取GIL锁
    2、执行代码,知道sleep或者是python虚拟机将其挂起
    3、释放GIL锁
    由此我们看到,某个线程想要执行,必须先要拿到GIL,拿不到GIL就无法进入cpu执行。
    在python2的版本中,GIL释放逻辑是当线程遇到I/O操作或者是ticks技术达到100的时候就进行释放,然后其他进程进行锁的竞争,并且保证每次只能一个进程进行运行。
    I/O密集型代码,多线程可以有效提升效率,但线程的情况下有I/O操作会进行等待,造成时间的浪费。而当开启多线程能够在A等待的时候,自动切换到线程B,可以不浪费CPU资源。
  • python的内存管理
    1、垃圾回收机制
    2、引用计数
    3、内存池机制是金字塔方式,-1、-2层主要由操作系统进行操作
    第0层:主要是C语言中的free,malloc等内存分配和释放函数进行操作。
    第1层和第2层:是内存池,由python的接口函数Pymen Malloc函数实现,当对象小于256k时,直接进行分配内存。
    第3层:最上层,也就是我们直接对python对象进行操作。
    如果请求分配的内存在1~256字节之间,就会调用自己的内存管理系统,都则就会使用malloc。需要注意的是经过有内存池登记的对象不会调用free直接释放掉。而是回到内存池当中,便于下一次的使用。
  • 10个常用的Linux命令
  • find和grep的区别
    find通常用来在特定的目录下搜索合适的文件,也可以用来搜索特定用户属性的文件
    grep搜索比较强大,支持正则表达式搜索,允许对文本文件进行模式查找,如果查找到就会输出所有行。
  • Django中当一个用户登陆A服务器,然后下一次请求被nginx代理到B应用服务器,会发生什么?
    如果A用户服务器登陆的session没有被共享到B服务器,那么之前的登陆状态就没有了
  • 跨域请求问题Django是如何解决的
    启用中间件、post请求、验证码、表单中添加{%csrf_token%}标签
  • 解释描述一下Django架构
    Django架构遵循MVC设计架构,并且有一些专有名词叫做MVT
    M:全拼为Model,与MVC中的M功能相同,负责数据的处理,内嵌入ORM框架
    V:全拼为View,与MVC中的C功能相同,接收HttpRequest,业务处理,返回HttpResponse
    T:全拼为Template,与MVC中的V功能相同,负责封装html,内嵌模版引擎
  • Django对数据的查询结果排序怎么做
    排序使用order_by()
    降序需要在排序的字段前面加-
    查询某个字段大于某个值:使用filter(字段名_gt=值)
  • 说一下Django MiddleWare中间件的作用
    中间件是一个介于request和response处理之间的一道工序,是一个轻量级的软件,并且在全局上改变django的输入和输出
  • Django如何实现重定向
    使用HttpResponseRedirct中的redirct和reverse
    状态码:302,301
  • Ngnix正向代理和反向代理


    代理模拟图

    代理解释图

正向代理:客户端 <一> 代理 一>服务端
正向代理简单地打个租房的比方:
A(客户端)想租C(服务端)的房子,但是A(客户端)并不认识C(服务端)租不到。
B(代理)认识C(服务端)能租这个房子所以你找了B(代理)帮忙租到了这个房子。
这个过程中C(服务端)不认识A(客户端)只认识B(代理)
C(服务端)并不知道A(客户端)租了房子,只知道房子租给了B(代理)。
反向代理:客户端 一>代理 <一> 服务端

反向代理也用一个租房的例子:
A(客户端)想租一个房子,B(代理)就把这个房子租给了他。
这时候实际上C(服务端)才是房东。
B(代理)是中介把这个房子租给了A(客户端)。
这个过程中A(客户端)并不知道这个房子到底谁才是房东
他都有可能认为这个房子就是B(代理)的

由上的例子和图我们可以知道正向代理和反向代理的区别在于代理的对象不一样,正向代理的代理对象是客户端,反向代理的代理对象是服务端。

  • Tornado核心是什么
    Tornado核心是ioloop核iostream这两个模块。前者提供了一个高效率的I/O事件循环,后者封装了一个无堵塞的scoket。通过向ioloop中添加I/O事件,利用无堵塞的scoket,再搭配相应的回调函数,便可以达到高效率的异步执行。

  • Django本身也提供了runserver,为什么不能用来部署
    首先runserver是一个调试Django运用的方法,他是Django自带的。而WSGI Server运行,主要在测试和开发中使用,并且runserver开启的方式也是单进程的。
    uWSGI也是一个Web服务器,他实现了WSGI协议,HTTP等协议。uWSGI具有超快的性能,低内存占用和多app管理等优点,并且搭配nginx服务器。
    可以说就是一个生产环境了,能够将用户请求和app隔离开,实现真正的部署,支持高并发。

  • 什么是AJAX,如何使用AJAX
    AJAX(异步的javascript和xml)能够刷新局部网页数据而不重新加载整个网页。
    第一步:创建一个xmlhttprequest对象,用来和服务器进行数据交换
    第二步:使用该对象的open和send方法给服务器发送资源
    第三步:使用response和responseXML属性获得服务器的相应
    第四步:如果我们想要服务器执行一些功能就需要使用onreadystatechange函数,每次xmlhttprequest对象的readystate改变都会触发onreadystatechange函数。

  • 常见的HTTP状态码和含义
    1xx:信息请求已经接收,继续处理
    2xx:表示请求已经被成功接收
    3xx:重定向-要完成的请求需要进一步执行
    4xx:客户端错误
    5xx:服务器错误
    200:OK
    400:Bad request--客户端请求语法错误
    401:未授权--需要和WWW-Authenticate一起使用
    403:收到请求,但是拒绝提供服务
    404:请求资源不存在
    500:服务器发生错误
    503:服务器不能处理客户端请求,一段时间后可以恢复

  • POST和GET的区别

  • Cookie和Session的区别
    1、cookie存放在客户端,session存在服务器端
    2、cookie安全性很低,别人可以通过分析存放在本地的cookie,进行cookie欺骗,为了安全性应该使用session
    3、session会在一定时间内保存在服务器上,当访问增加时候,会占用服务器资源
    4、单个的cookie保存数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookie
    5、将登陆等一些信息存在session中,其他资源保存在cookie 中。

  • 创建一个TCP服务器的流程
    1、socket创建一个套接字
    2、bind绑定ip和port
    3、listen让套接字变成被动链接
    4、accept等待客户端的链接
    5、recv/send接收发送数据

  • 说一下TCP的三次握手和四次握手?什么是2msl?为什么这么做

  • 为什么使用redis数据库
    内存数据库,速度快,支持数据持久化。
    不仅支持ket-value类型,还提供list、set、zset、hash等数据结构储存。
    支持数据备份、master-slave数据备份

  • 数据库InnoDB和MyISAM的区别
    最大区别就是InnoDB支持事务,事务是一种高级别的处理方式。但是MyISAM就不可以了。
    MyISAM主要以查询和插入为主,但是InnoDB适合频繁修改或涉及到安全性较高的数据
    InnoDB支持外键,但是MyISAM不支持。
    MyISAM需要指定,InnoDB默认引擎。
    InnoDB不支持FULLTEXT类型的索引。
    InnoDB需要扫描全表,但是MyISAM只需要记录号行数就可以。
    MyISAM支持和自增长字段建立联合索引,但是InnoDB必须包含一个只有自增长字段的索引。
    清空表的时候,InnoDB一行一行删除,但是MyISAM是重建表。

  • 什么是关联查询
    就是将多个表联合在一起同时进行查询,包括内外链接、左右链接

  • 数据库的优化
    1、优化索引、sql语句
    2、设计遵循数据库范式
    3、使用缓存
    4、不采用全文索引
    5、采用更快的存储方式---Nosql存储
    6、垂直分表:把不常读的数据放在一张表里面
    7、优化硬件

  • 什么是PEP8
    就是一种编程规范,关于如何让你的程序更加具有可读性

  • 什么是pickling和unpickling
    pickle模块读入的任何python对象,将他们转换成字符串,使用dump函数储存到一个文件中
    unpickling从储存字符串中提取原始的python对象

  • python如何被解释的
    python解释器会将源代码转换成为中间语言,之后再翻译成机器码执行

  • python中的debug或者是静态分析
    pychecker是一个静态分析工具--报告错误类型和复杂度
    pylint检验是否达到代码标准

  • python的装饰器
    简单来说就是增强一个函数的功能

  • 什么是python命名空间
    在python中,所有的名字都存在于一个空间中,他们在该空间中存在和被操作

  • 为什么lambda语句没有语句
    原因是他在使用的时候构建新的函数对象,并且直接被返回

  • 数组和元祖的区别

  • 参数传递和值传递

  • 字典、列表推导式

  • 自带的数据结构

  • pass语句作用

  • unittest是什么?
    他是python中的一个单元测试框架,支持共享搭建,自动测试,在测试代码中暂停等功能

  • 什么slicing?
    slicing是一种在有序的对象类型中节选某一段语法

  • 什么是构造器

  • python中的docstring是什么?
    文档字符串,为函数、模块和类注释生成文档

  • python中如何copy一个对象
    可以使用copy.copy()和copy.deepcopy()。并不是所有对象都可以被拷贝。

  • 什么是负索引
    索引可以是正数也可食负数。正数的话就是从左到右。而负索引就是从右到左。

  • 如何转换成一个字符串
    str方法,八进制-oct方法,十六进制-hex方法

  • range和xrange的区别
    xrange返回的是一个xrange对象,而range返回一个数组。不管范围多大,xrange只使用同样的内存大小。

  • 如何删除list中的重复元素
    set()

a = [1,2,3,4,5,4,3,2,1]
b = dict.fromkeys(a)
print(type(b))
c = list(b.keys())
print(c)
<class 'dict'>
[1, 2, 3, 4, 5]
  • python如何拷贝一个对象
    赋值:= 就是创建了一个新的对象的引用,修改任意一个变量都会影响到另一个。
    浅拷贝:
    深拷贝:
  • python中的expect
    expect用来处理异常的代码段,将容易引发异常的代码段放在try中,如果出现了异常,会自动寻找expect所对应的进行匹配,执行expect中相应的语句。如果都不匹配,则异常会传递到下一个调用本代码的最高层的try中。如果try语句正常执行,则接下来执行else语句,如果发生异常就不会执行else。finally是一定会执行的。
  • python如何生成一个随机数
    random模块
    random.randint(a,b)生成一个x,a<=x<=b
    random.randrange(start,stop,step)生成一个x,start<=x<stop
    random.random()返回0~1之间的随机数
    random.uniform(a,b)返回指定范围内的浮点数
  • python中的匹配HTML tag的时候,<.>和<.?>有什么区别
    这是贪婪匹配和非贪婪匹配,贪婪模式在匹配的时候尽可能多的匹配字符串,而非贪婪模式就是相反的,在匹配的时候尽可能少的匹配字符串。
  • python中的match和search方法的区别
    match是从头开始检查string的开头是否和pattern是否匹配。
    search是在string中搜索pattern的第一个匹配值。
import re
re.match(pattern,string)
re.search(pattern,string)
  • 如何使用python来进行查询替换一个文本的字符串
    可以使用re模块的sub函数
替换字符串中的red和blue为color
print(re.sub(r'blue|red','color','blue socks and
 red shoes'))
  • 修改不可变类型抛出什么错误
    TypeError错误
  • print调用底层的什么方法
    默认调用底层的sys.stdout.write方法
  • input方法
    python3中的input不管输入什么都是输出字符串类型
    python3中raw_input方法输入什么类型,输出就是什么类型
  • python实现单例模式
def sing(cls,*args,**kwargs):
    instance = {}
    def get_instance(*args,**kwargs):
        if cls not in instance:
            instance[cls] = cls(*args,**kwargs)
        return instance[cls]
    return get_instance

@sing
class Student():
    def __init__(self,name,age):
        self.name = name
        self.age = age
student1 = Student('Albert',25)   
student2 = Student('Akkklbert',25)   
print(id(student1)==id(student2))

class singleton():
    _instance = None
    def __new__(cls,*args,**kwargs):
        if singleton._instance == None:
            singleton._instance = super().__new__(cls)
        return singleton._instance
a1 = singleton()
a2 = singleton()
print(id(a1)==id(a2))
  • python如何进行类型转换
    int---数字字符串的转换,如果是浮点数,则直接截去小数点后面的数字
  • 反序迭代
  • 生成一个全局变量
  • python优点
    解释性语言,动态特性,面向对象,简单开明,开源
  • 深拷贝和浅拷贝
  • 列表和元祖的区别
  • python中的三元运算符
  • python中的多线程
  • python中的继承
  • python中的help和dir函数
    help函数用于查看函数的模块用途和说明
    dir用于返回当前范围内的变量、方法和定义的类型列表
  • python退出的时候是否释放全部内存
    不会释放全部内存,循环引用其他对象或者是引用全局变量空间的对象模块,在python退出的时候不会全部释放。
  • 身份运算符有哪些?
    in、not in
  • 元祖的解封
  • python的函数传递
    不可变类型直接进行值传递
    可变类型直接进行引用传递
  • python中的元类
    就是你所创建的那个类的类,我们称之为元类
  • 静态方法、实例方法和类方法
    实例方法:创建实例之后才可以调用的方法
    静态方法:和普通方法差不多,关键字staticmethod,可以用类名或者是实例名称进行调用
    类方法:必须有关键字classmethod,所修饰的方法必须包括cls,表示对象本身,可以用类名或者是实例名称进行调用。
  • 类变量和实例变量
    类内部的变量,就是类变量。实例变量就是创建实例后,实例调用的变量就是实例变量。注意区分可变类型和不可变类型
  • python自省
    就是说运行的时候能够获得对象的类型dir,hasattr,getattr,type
  • 字典推导式
    [key,value for (key,value) in iterable]
  • python中的单下划线、双下划线
    单下划线:表示这是一个保护成员,只有类对象和自类对象才能访问到这些对象。
    双下划线:表示这是一个私有成员,只允许类本身进行访问,子类也不可以。只能通过:对象名.__类名__xxx
    xx:表示python内部内建的属性方法。
  • 鸭子类型
    在python中,我们不要知道对象是什么类型,只需要知道他的行为。比如list.extends,我们不需要知道到底是字典还是列表,只需要知道他是一个可迭代对象就可以。
  • python没有函数的重载
    参数个数不同(可变长参数)和参数类型不同(默认参数)
  • new init的区别
    前者:静态方法,后者实例方法
    前者:返回一个创建的新的实例,后者什么都不返回
    只有在new返回一个cls的实例之后,后者才可以被调用
    创建一个实例采用前者,初始化一个实例采用后者。
  • 作用域的搜索顺序
    本地作用域-当前作用域被嵌入的本地作用域-全局作用域-内置作用域
  • 协程
    就是线程和进程的升级版,协程就是用户自己控制切换时机,不需要陷入系统的内核态。
  • 函数编程
    就是允许将函数作为参数来嵌入到另外 一个函数中去。
    例如:map、reduce、filter等等。
  • python中的函数可以返回多个值,返回的形式就是一个元祖
  • python中的is
    is对比的是地址,==对比的是值
  • read、readlines、readline
    read:读取整个文件
    readlines:读取整个文件到一个迭代器,来进行遍历
    readline:读取下一行,使用的是生成器的方法
  • python中变量的作用域
    LEGB---L本地作用域---E本地作用域嵌套的作用域---G全局作用域---B内置作用域
  • super的具体用法
    调用父类的话,一般会super关键字
    在子类中,使用super.init,确保父类被正确初始化了。
    覆盖python中的一些特殊方法。(setattr)
  • 抽象类和接口类
    抽象类:规定了一系列的方法,并且由它的子类进行实现,不可以实例化
    接口类:python内部不存在接口类的。接口类需要被实现。
    区别和联系:
    接口可以继承,但是抽象类不可以
    接口定义方法,但是没有实现代码。抽象类可以实现部分代码
    接口中的基本数据类型是static,而抽象类不是。
  • python如何动态获取和设置对象的属性
    hasattr,getattr
  • python哪些操作导致内存溢出
    循环引用,死循环都会导致。
  • python内存管机制+调优手段
    手动垃圾回收
    设置垃圾回收的阈值
    避免循环引用
  • 内存泄漏
    由于自身的操作失误,将本应该释放的内存而没有正确释放掉。并不是物理意义上的内存消失,而是由于设计问题,导致失去了对内存的控制,造成了内存的浪费。
    使用del object来删除一个对象的引用计数就可以防止内存泄漏。
    gc模块来查看不能回收的对象的详细信息。
  • 什么是Hash
    称为散列函数。是一种从数据中创建数据指纹的犯法。把数据压缩成摘要,把数据的格式确定下来,然后将数据打乱混合,重新创建一个散列值的指纹。
  • 函数设计的规则
    设计短小
    声明简单、容易使用
    向下兼容
    一个函数只做一件事情
  • map函数
    根据提供的函数和序列,返回一个新的列表。
  • 回调函数如何通信的
    就是把函数的地址作为参数,传递给另外一个函数,将整个函数作为一个对象,赋值给调用的函数。
  • lambda函数?为什么使用?
    是一个可以接收任意多个参数,返回单个表达式值的函数。
    1、用来完成某个单一的功能,连名称起的都很随意
    2、匿名函数---filter、map、reduce来使用
    3、作为一个回调函数,传递给某些应用。
  • 对设计模式的理解
    设计模式是经过总结和优化的一些可重用的解决方案。他不想类或者是模块那样可以直接作用于我们的代码。相反,设计模式更加高级,在一种特定情形下实现的一种方法模版。
  • 单例模式的应用场景
    数据库配置,数据库连接池,资源之间的相互通信,日志等。
  • 什么是进程
    运行在操作系统上的一个实例,我们就称之为一个进程。
  • 如何创建一个进程
    导入multiprocessing中的Process
    创建一个process对象,创建完毕之后,我们可以像其中添加参数,target表示指定的任务数量,args、kwargs表示任务函数的参数。利用start启动进程。进程之间不会共享全局变量。
  • 进程之间的通信
    使用Queue模块,,如果在Queue中没有指定最大可接受消息数量,那就表示一直储存到内存尽头。
    qsize-返回当前队列包含的消息数量。
    empty-队列是否为空。
    full-队列是否已经满了。
    get-获取队列中的一条消息,然后在移除。
    put-将消息写入队列。
  • python异步使用场景有哪些?
    1、不涉及共享资源,非互斥操作。
    2、没有时许上的严格关系
    3、不需要原子操作
    4、不影响主线程逻辑
    5、常用于IO操作。
  • 多线程的竞争
    由于线程之间是非独立的并且进程之间的数据是共享的,所以当多个线程访问数据资源的时候,会出现竞争状态,数据就会被多个线程占用,造成数据混乱,所谓的线程不安全。解决这种问题的方式就是采用锁机制。好处就是确保了需要共享的数据从头到尾只能被一个线程所使用,解决了多线程竞争资源的问题。坏处就是阻止线程的并发执行,实际上就是以单线程的方式在运行代码,效率降低了。容易出现死锁问题。
  • 简介一下python的线程同步
    setDaemon(False),当一个进程启动之后,会默认创建一个主线程,python中,默认就是这种情况,主线成执行完成自己的任务之后就会退出,此时子线程才会执行自己的任务。直到任务结束。
    setDaemon(True),当一个进程启动之后,会默认创建一个主线程,当主线程执行结束之后,则全部的子线程就会被强制结束,不会在继续运行
    join所完成的工作就是线程的同步,就是说当主线程完成自己的任务之后,就会进入堵塞状态,之后开始进行子线程的执行,一直等待所有的子线程全部执行完毕之后才会结束主线程。
    当设置子线程的守护的时候,主线线程对于等待子线程timeout的时间将会杀死该子线程。
    当没有设置线程守护的时候,主线程将会登台timeout的累加和这样的一段时间,时间一到,主线成就会结束,但是并没有杀死子线程,直到子线程全部结束,程序就会退出。
  • python中的锁及其分类
    python中的锁是对线程进行控制的对象.包括互斥锁、可重入锁、死锁。
  • 什么是死锁
    指若干子线程在系统的资源竞争的时候,双方都在等待对方先释放资源,结果谁都不愿意先释放,导致程序无法执行下去,这就是死锁。
    GIL锁,全局解释锁
    限制多线程同时执行,但是保证在同一时间只有一个线程进行执行,在cpython中就是一个伪多线程。
    所以python中经常采用的是协程技术来代替多线程。他是一种轻量级的线程。表示我们可以手动切换线程。在模块gevent下切换是遇到了耗时操作时才会切换。
    三者之间的关系:进程包括线程,线程包括协程。
  • 怎么避免重读
    创建一个已经访问的数据列表,用于储存已经访问过的数据,并且加上互斥锁,再多线程访问数据的时候,先查看数据是否已经在访问的列表中,若存在就跳过。
  • 什么是线程安全?什么是互斥锁?
    在python中,每个对象都可以有一个互斥锁的标记,这个标记保证,在任何一个时刻,只可以有一个线程来访问该对象。
    在同一个进程中,多个线程之间的资源是共享的,多个线程操作同一个对象的时候,如果一个线程操作还没有结束,另外一个线程就对其进行操作,就会导致结果出现错误。此时需要添加互斥锁,保证每个线程对该对象的操作都可以得到正确的结果。
  • 同步、异步、阻塞、非阻塞的概念
    同步:多个任务之间有先后的顺序进行执行,一个执行完成之后下一个才会继续执行。
    异步:多个任务之间的执行顺序没有先后顺序,可以同时执行,有时候一个线程在执行的过程中,可能需要另一个线程的结果,这个过程我们就叫做回调。
    阻塞:如果卡住了调用者,导致调用者不能在继续往下执行,我们就称之为阻塞。
    非阻塞:如果不会卡住,可以继续向下执行,我们就称之为非阻塞。
    同步和异步是相对于多任务而言的。阻塞和非阻塞是相对于代码而执行的。
  • 什么是僵尸进程和孤儿进程?怎么避免僵尸过程
    孤儿进程:父进程已经退出,但是子进程还在执行,这些都是孤儿进程。孤儿进程会被init 进程收养,并有init进程对他们完成状态收集工作。
    僵尸进程:使用fork创建了一个子进程,但是父进程并没有调用wait或者是waiid获取子进程的状态信息,那么子进程的进程仍然存在于系统中,这些就是僵尸进程。
    避免僵尸进程的办法:
    使用fork两次用孙子进程完成子进程的任务。
    用wait函数使父进程阻塞。
  • python进程和线程使用场景
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容