进程

  • 进程间内存是否共享?如何实现通讯?
    进程间内存不共享,可以通过

    1. Manage模块加锁
    2. 通过队列或
    3. 通过管道加锁
    4. socket实现通讯
  • 请聊聊进程队列的特点和实现原理?
    1. 先进先出 Queue
    2. 后进先出 LifoQueue
    3. 优先级队列 PriorityQueue
    4. 线程本身带锁通过put()数据和get()数据,同一时间只有一个线程运行修改任务实现数据安全
  • 请画出进程的三状态转换图
    就绪====运行
\阻塞/
  • 你了解生产者模型消费者模型么?如何实现?
yield:
def consumer():
n = yield
n = yield
n = yield
n = yield
n = yield
n = yield
n = yield
n = yield def producer():
g = consumer()
next(g)
for i in range(2000000):
g.send(i)
  • 从你的角度说说进程在计算机中扮演什么角色?
    进程在计算机中扮演数据集的调用调配角色。
    负责回收和控制子线程的运行,是一个数据集。
    ##线程
  • GIL锁是怎么回事?
    GIL锁是全局解释器锁,只有CPython中使用,同一时间只能有一个线程调度CPU
  • 在python中是否线程安全?
    不安全,需要加锁才安全
  • 什么叫死锁?
    同时满足两个条件锁才能解开,分别有两把或以上的锁,有多个线程分别抢占了两个条件中的锁,互不释放造成阻塞,死锁现象。
  • logging模块是否是线程安全的?
    logging模块是线程安全的,因为使用的是单例设计模式。
  • threading.local的作用?
    Python提供了 threading.local 类,将这个类实例化得到一个全局对象,
    但是不同的线程使用这个对象存储的数据其它线程不可见(本质上就是不同的线程使用这个对象时为其创建一个独立的字典)。
  • 程序从flaga执行到falgb的时间大致是多少秒?
    60s 因为没有设置守护线程,需要等子线程跑完主线程才结束
import threading
import time def _wait():
time.sleep(60)
# flag a
t = threading.Thread(target=_wait, daemon=False)
t.start()
# flag b
  • 程序从flaga执行到falgb的时间大致是多少秒?
    0.01s 因为设置守护线程,子线程等待所有非子线程结束子线程结束。
import threading
import time def _wait():
time.sleep(60)
# flag a
t = threading.Thread(target=_wait, daemon=True)
t.start()
# flag b
  • 程序从flaga执行到falgb的时间大致是多少秒?
    60s 因为设置了阻塞需要等待子线程结束主线程才能结束
import threading
import time def _wait():
time.sleep(60)
# flag a
t = threading.Thread(target=_wait, daemon=True)
t.start()
t.join()
# flag b
  • 读程序,请确认执行到最后number是否一定为0
    不一定,因为存在线程安全问题,同一时间修改变量值
import threading
loop = int(1E7) def _add(loop: int = 1):
global number
for _ in range(loop):
number += 1 def _sub(loop: int = 1):
global number
for _ in range(loop):
number -= 1
number = 0 ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))
ta.start()
ts.start()
ta.join()
ts.join()
print(number)
  • 读程序,请确认执行到最后number是否一定为0
    一定为0 ,因为增删操作只有一条语句不会产生数据安全问题。
import threading
loop = int(1E7)
def _add(loop: int = 1):
global number
for _ in range(loop):
number += 1 def _sub(loop: int = 1):
global number
for _ in range(loop):
number -= 1
number = 0
ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))
ta.start()
ta.join()
ts.start()
ts.join()
print(number)
  • 读程序,请确认执行到最后number的长度是否一定为1
    不一定为1,因为产生了阻塞可能有数据安全问题。
import threading
loop = int(1E7) def _add(loop: int = 1):
global numbers
for _ in range(loop):
numbers.append(0) def _sub(loop: int = 1):
global number
while not numbers:
time.sleep(1E-8)
numbers.pop()
numbers = [0]
ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))
ta.start()
ta.join()
ts.start()
ts.join()
print(numbers)
  • 读程序,请确认执行到最后number的长度是否一定为1
    不一定为1,因为产生了阻塞可能有数据安全问题。
import threading
loop = int(1E7) def _add(loop: int = 1):
global numbers
for _ in range(loop):
numbers.append(0) def _sub(loop: int = 1):
global number
while not numbers:
time.sleep(1E-8)
numbers.pop()
numbers = [0]
ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))
ta.start()
ts.start()
ta.join()
ts.join()
print(numbers)

协程

  • 什么是协程?常用的协程模块有哪些?
    在线程遇到阻塞的情况时切换到另一个线程继续执行,如果遇到阻塞再到另一个线程执行。如果跳转过的线程转为就绪状态就直接执行,
    知道程序中没有阻塞。有gevent,和greenlet.
  • 协程中的join是用来做什么用的?它是如何发挥作用的?
    协程是遇到阻塞才切换,join负责阻塞开始执行程序。
  • 使用协程实现并发的tcp
server端
from gevent import monkey;monkey.patch_all()
import gevent
import time
import random
import socket sk = socket.socket()
server_addr = ('127.0.0.1',9988)
sk.bind(server_addr)
sk.listen() def listen(conn):
while True:
msg = conn.recv(1024).decode('utf-8')
if msg == 'q':break
conn.send(msg.upper().encode('utf-8')) if __name__ == '__main__':
while True:
conn,addr = sk.accept()
gevent.spawn(listen,conn)
  • 在一个列表中有多个url,请使用协程访问所有url,将对应的网页内容写入文件保存
from gevent import monkey;monkey.patch_all()
import time
import random
import gevent
from urllib.request import urlopen
url_dic = {
'协程':'http://www.cnblogs.com/Eva-J/articles/8324673.html',
'线程':'http://www.cnblogs.com/Eva-J/articles/8306047.html',
'目录':'https://www.cnblogs.com/Eva-J/p/7277026.html',
'百度':'http://www.baidu.com',
'sogou':'http://www.sogou.com',
'4399':'http://www.4399.com',
'豆瓣':'http://www.douban.com',
'sina':'http://www.sina.com.cn',
'淘宝':'http://www.taobao.com',
'JD':'http://www.JD.com'
}
def getHtml(url):
ret = urlopen(url)
html = ret.read()
html_file = url.replace('.','_').lstrip('https://').replace('/','_')+'.html'
with open(html_file,mode='wb') as f:
f.write(html)
print(url+'done') if __name__ == '__main__':
print('start')
lst = list()
for url in url_dic:
ret = gevent.spawn(getHtml,url_dic[url])
lst.append(ret) for url in lst:
url.join()
print(1)

综合

  • 进程和线程的区别
    进程是计算机资源分配的最小单位,线程是cpu调度的最小单位,线程较进程来说较轻量,启动更迅速。调用更方便
  • 进程池、线程池的优势和特点
    进程池一般在高计算的条件下使用,资源消耗更多。
    线程池可以运行在一个进程中,执行效率更高,可控cpu使用率。节约资源。
  • 线程和协程的异同?
    协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态。
    协程实际上是在一个线程中,只不过每个协程对CUP进行分时,协程可以访问和使用unity的所有方法和component
    线程,多线程是阻塞式的,每个IO都必须开启一个新的线程,但是对于多CPU的系统应该使用thread,尤其是有大量数据运算的时刻,
    但是IO密集型就不适合;而且thread中不能操作unity的很多方法和component
  • 请简述一下互斥锁和递归锁的异同?
    两者在在单锁的情况下都可以保证数据的可靠性。
    二者唯一的区别是,同一个线程可以多次获取同一个递归锁,不会产生死锁。而如果一个线程多次获取同一个非递归锁,则会产生死锁。
  • 请列举一个python中数据安全的数据类型?
    Queue
  • Python中如何使用线程池和进程池
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import ProcessPoolExector
p = ProcessPoolExector(4)
ret = p.submit(func,aa)
print(ret.result())
  • 简述
    进程、线程、协程的区别
    进程是:一个CPU情况下,多个程序分别使用机器资源(CPU或硬盘等)的概念;
    线程是:一个进程情况下,多个执行流程(即线程)分别使用分配给该进程的机器资源的概念;

    • 协程是:一个线程情况下,多个执行流程(即协程)由线程控制,分别使用分配给该线程的机器资源的概念;
      以及应用场景?
    • 多进程:密集CPU任务,需要充分使用多核CPU资源(服务器,大量的并行计算)的时候,用多进程。 multiprocessing
      缺陷:多个进程之间通信成本高,切换开销大。
    • 多线程:密集I/O任务(网络I/O,磁盘I/O,数据库I/O)使用多线程合适。
      threading.Thread、multiprocessing.dummy
      缺陷:同一个时间切片只能运行一个线程,不能做到高并行,但是可以做到高并发。
    • 多线程请求返回是无序的,那个线程有数据返回就处理那个线程,而协程返回的数据是有序的。
      缺陷:单线程执行,处理密集CPU和本地磁盘IO的时候,性能较低。处理网络I/O性能还是比较高.
  • 什么是并行,什么是并发?
    并行是同一时间在多个cpu上同时执行多个程序
    并发是同一时间在同一个cpu上在不同程序之间切换运行
  • 请解释同步和异步这两个概念?
    同步执行程序需要等待结果
    异步执行程序不需要等待结果
  • 请谈谈对异步非阻塞的了解?
    执行效率高,可以实现高并发的应用场景
  • 简述信号量的实现原理
    • 信号量机制即利用pv操作来对信号量进行处理。什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;
    • 当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。一般来说,信号量S³0时,
    • S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S<0时,表示已经没有可用资源,
    • 请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S的值加1;若S£0,
    • 表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。
  • 程序中的阻塞有哪些?给程序带来了哪些影响?
    input,sleep,io 程序会等待阻塞完成才会进入就绪队列,影响程序运行效率
  • 请分别用多进程、多线程、协程实现生产者消费者模型?

多进程

import time
import random
from multiprocessing import Process,Queue def producer(name,que):
for i in range(10):
time.sleep(random.random())
food = '便便

Python 并发部分的面试题的更多相关文章

  1. Python 并发编程(上)

    Python 并发编程 参考文献:https://gitee.com/wupeiqi/python_course 并发编程:提升代码执行的效率.原来需要 10 分钟执行,并发处理后可以加快到 1 分钟 ...

  2. Python并发编程__多进程

    Python并发编程_多进程 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大 ...

  3. Python并发编程的几篇文章

    Python几种并发实现方案的性能比较 http://www.elias.cn/Python/PyConcurrency?from=Develop.PyConcurrency python并发编程 h ...

  4. Python并发编程之深入理解yield from语法(八)

    大家好,并发编程 进入第八篇. 直到上一篇,我们终于迎来了Python并发编程中,最高级.最重要.当然也是最难的知识点--协程. 当你看到这一篇的时候,请确保你对生成器的知识,有一定的了解.当然不了解 ...

  5. Python并发目录

    Python并发目录 Python-socket网络编程 Python网络编程-IO阻塞与非阻塞及多路复用 Python进程-理论 Python进程-实现 Python进程间通信 Python进程池 ...

  6. 自学Python之路-Python并发编程+数据库+前端

    自学Python之路-Python并发编程+数据库+前端 自学Python之路[第一回]:1.11.2 1.3

  7. Python并发复习1 - 多线程

    一.基本概念 程序: 指令集,静态, 进程: 当程序运行时,会创建进程,是操作系统资源分配的基本单位 线程: 进程的基本执行单元,每个进程至少包含一个线程,是任务调度和执行的基本单位 > 进程和 ...

  8. Python并发编程二(多线程、协程、IO模型)

    1.python并发编程之多线程(理论) 1.1线程概念 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于 ...

  9. Python并发编程一(多进程)

    1.背景知识(进程.多道技术) 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一 ...

随机推荐

  1. 转载:深度学习在NLP中的应用

    之前研究的CRF算法,在中文分词,词性标注,语义分析中应用非常广泛.但是分词技术只是NLP的一个基础部分,在人机对话,机器翻译中,深度学习将大显身手.这篇文章,将展示深度学习的强大之处,区别于之前用符 ...

  2. redis 键值对 有效期设置

    redis 键值对 有效期设置redis中可以使用expire命令设置一个键的生存时间, 到时间后redis会自动删除它<-----> 类比于javaweb系统临时数据 过期删除功能 ex ...

  3. 设计模式主目录 C++实现

    行为性模式 1.观察者模式 结构型模式    ----  组合的艺术 1.外观模式

  4. 《Linux就该这么学》培训笔记_ch03_管道符、重定向与环境变量

    <Linux就该这么学>培训笔记_ch03_管道符.重定向与环境变量 文章最后会post上书本的笔记照片. 文章主要内容: 输入输出重定向 管道命令符 命令行的通配符 常用的转义字符 重要 ...

  5. 027 ElasticSearch----全文检索技术02---快速入门

    1.基本概念 Elasticsearch也是基于Lucene的全文检索库,本质也是存储数据,很多概念与MySQL类似的. 注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,E ...

  6. [转帖]Kubernetes的部署策略

    Kubernetes的部署策略,你常用哪种? https://www.sohu.com/a/318731931_100159565?spm=smpc.author.fd-d.78.1574127778 ...

  7. How to let your website login with domain account when using IIS to deploy it?

    如何让你的网站以域账号登录 Select your website in IIS Manager, open Authentication, enable Windows Authentication ...

  8. SpringBoot 基础(二)

    目录 SpringBoot基础(二) 一.操作数据库 1. SpringBootJdbc 2. SpringBoot 整合 Mybatis 3. SpringBott 使用JPA 二.使用 Thyme ...

  9. 在C++中调用FFTW

    FFTW是一个可以进行可变长度一维或多维DFT的开源C程序库,是目前最快的FFT算法实现. 本文简述了在Windows平台上,如何在C++中调用FFTW,所使用的IDE为Visual Studio 2 ...

  10. 10. Scala数据结构(上)-集合操作

    10.1 数据结构特点 10.1.1 Scala集合基本介绍 uml => 统一建模语言 1) Scala同时支持不可变集合和可变集合,不可变集合可以安全的并发访问 两个主要的包 不可变集合:s ...