进程

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

    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. 使用Java8特性对list进行按属性去重

    编写工具类 public class DistinctUtil { public static <T> Predicate<T> distinctByKey(Function& ...

  2. SQL2008R2下数据库修复一例

    某天访问某个数据库的时候,系统报错.连上去看了一下,服务器是SQL2008R2.由于有上次修复的经验,先使用DBCC查看数据库情况. DBCC的返回: XXXXXXXXXXX发生异常数据库 ID 7, ...

  3. Java查询MySQL数据库指定数据库中所有表名、字段名、字段类型、字段长度、字段描述

    1,查询方法 public static List<Map<String, String>> getColumnInfoByTableName(String databaseN ...

  4. php 跳出循环 break

    break语句可以带一个参数n,表示跳出循环的层数,如果要跳出多重循环的话,可以用n来表示跳出的层数,如果不带参数默认是跳出本重循环.

  5. [转帖]ORACLE 12C连接时报ORA28040和ORA01017的错误

    ORACLE 12C连接时报ORA28040和ORA01017的错误 http://blog.itpub.net/12679300/viewspace-2150667/ 我一直在的处理方式是让更新or ...

  6. Effective.Java第34-44条(枚举)

    34.  使用枚举类型替代整型常量 常量的语义表达不清晰,只能靠前面的名称来区分.枚举具有可读性.更安全.更强大等优势.而且枚举类型对象之间的值比较可以使用==来比较值是否相等的,不是必须使用equa ...

  7. 消除VS中动态申请二维数组C6011,C6385,C6386的警告

    动态申请二维数组,无非就是通过指针来实现.@wowpH 过程分三步:1.申请内存,2.使用数组,3.释放内存. 代码如下: /************************************* ...

  8. Go语言【数据结构】切片

    切片 简介 简单地说,切片就是一种简化版的动态数组.Go 数组的长度不可改变,而切片长度是不固定,切片的长度自然也就不能是类型的组成部分了.数组虽然有适用它们的地方,但是数组的类型和操作都不够灵活,因 ...

  9. 软件——解决Modelsim10.1d窗口不停弹出问题(一直弹窗)

    博主在编写Verilog HDL时需要用到Modelsim,于是博主便安装了Modelsim10.1d,然后兴高采烈打开准备跑仿真时,打开软件发现Modelsim10.1d的各种窗口在不停弹出,终止进 ...

  10. 在 flutter 上使用 c 代码 - (一) 有源码的项目

    在 flutter 的 1.10.x 后的分支, dart:ffi 被并入 flutter, 现在 flutter 中也可以使用 ffi 了. 这东西是啥玩意呢, 就是让 dart 可以直接调用 c/ ...