首页 > 其他分享 >面试题

面试题

时间:2023-04-10 16:55:42浏览次数:41  
标签:面试题 多线程 开启 回收 线程 进程 gil

面试题

1 什么是gil锁

gil锁:全局解释器锁,他的本质是一个大的互斥锁,他是cpython的一种机制,gil只存在cpython解释器,他限制了一个线程只有获取到gil锁才能执行,如果没有拿到gil锁,线程是不能执行的

解释器有:cpython,pypython,jpython
         
gil锁的作用是什么?
	限制线程只有获取到gil锁才能执行
为什么要有gil锁?保证数据安全?
	保证数据安全用互斥锁就好了,gil锁不能保证数据安全
    Python的垃圾回收机制,需要用逻辑回收线程来做,如果在同一时刻有多个线程在同时执行,垃圾回收机制会把正在其他线程使用的变量给回收掉,因为当时只有单核电脑,本来同一时刻就不能有多个线程同时执行,于是作者就干脆做了一个gil锁,让线程必须获取到gil锁,才能执行,但后来随着多核的出现,导致python的多线程并不能利用多核

2 为什么有了gil锁还要互斥锁

gil锁:全局解释器锁,线程要想执行,必须先获得到gil锁才能执行
互斥锁:为了保证多线程并发操作数据(变量),而设置的锁,保证在加锁和释放锁之间,其他线程不能操作

# gil锁也是大的互斥锁
# 过程:
# 出现了数据错乱,出现了多条线程操作变量,出现的并发安全问题
    a=0
    线程1要计算: a+=1  
    	1 线程1 拿到gil  
        2 读取a=0
        3 假设时间片到了,释放gil,释放cpu
      	4 等待下次被调度执行
        10 轮到它了,获取gil锁
        11 继续往下执行:计算a+1
        12 把结果赋值给a ,a=1
    	13 释放gil锁
     线程2要计算: a+=1 
        5 线程2获得了gil锁
        6 读取a=0
        7 计算a+1
        8 把结果赋值给a ,a=1
        9 释放gil锁
    # 什么临界区?处出现并发安全问题的这段代码称之为临界区,临界区会出现并发安全问题,所以要在临界区加锁
    	# 加锁
    	6 读取a=0
        7 计算a+1
        8 把结果赋值给a ,a=1
        # 释放锁
    	
  
   # 互斥锁保证数据安全
    a=0
    线程1要计算: a+=1  
    	1 线程1 拿到gil  
        # 加锁
        2 读取a=0
        3 假设时间片到了,释放gil,释放cpu
      	4 等待下次被调度执行
        
        7 轮到它了,获取gil锁
        8 继续往下执行:计算a+1
        9 把结果赋值给a ,a=1
    	10 释放gil锁
     线程2要计算: a+=1 
        5 线程2获得了gil锁
        #获取锁,获取不到
        6 释放gil锁
        11 获得gil锁
        
        #加锁
        12 读取a=0
        13 计算a+1
        14 把结果赋值给a ,a=1
        15 释放锁
        16 释放gil锁
    
    # gil锁并不锁住临界区,临界区需要我们自己用互斥锁加锁

3 python的垃圾回收机制是什么样的?

高级一点的语言,为了保证内存的使用效率,都会有垃圾回收机制,而咱们python使用以下三种方式来做垃圾回收
1.引用计数
	有多少变量指向他,他的引用计数就为几,当引用计数为0 的时候就说明没有变量指向它了,这块内存空间就会被回收掉
    引用计数操作的问题:循环引用问题

2.标记清除
	为了解决引用计数存在的循环引用的问题
    第一阶段就标记阶段,它会把所有的“活动对象”打上标记,第二阶段把那些没有标记的“非活动对象”进行回收
    # 简而言之,它会把循环引用的内存空间,打上标记,然后回收掉

3.分代回收
	把对象分为三代,一开始,对象在创建的时候,放在一代中,如果在一次一代的垃圾回收检查中,该对象存活下来,就会被放到二代中,同理在一次二代的垃圾检查中,该对象存活下来,就会被放到三代中,后面优先检查第一代中的对象,优先回收,其次依次往上检查做回收

4 解释为什么计算密集型用多进程,io密集型用多线程

由于GIL锁的存在,即便是多核机器,同一时刻,也只能有一个线程在执行
    -线程需要cpu去调度执行
    -如果开了多线程,是计算密集型,计算是消耗cpu,假设是四核电脑,不能充分利用这四个核,只能有一个核在执行,开多线程没有用
    -而如果计算密集型,开了多进程,gil是在cpython解释器进程中的,再进程中开启线程执行计算,可以充分利用多核优势
    -开了一个进程,就开了一个cpython解释器的进程,就会有一个gil锁
    
    -由于GIL锁的存在,如果是计算密集型,开启多线程,不能利用多核优势,
    -开启多进程,可以利用多核优势
    -io不耗费cpu,开启多线程,在一个时间段内是有并发效果的
     
    -即便是io密集型,用多进程是不是会显著提高效率?
    	本身开启进程是非常消耗资源的,如果是io密集型,没有必要开多进程,并不会有显著的效率提升

5 进程,线程和协程

概念
进程:是资源分配的最小单位,一个应用程序应用起来,至少需要一个进程,在进程管理器(资源管理器)中可以看到一个个进程

线程:是cpu调度,执行的最小单位,一个进程下至少有一个线程

协程:单线程下的并发,程序层面控制的任务切换
代码如何实现
# 开启进程的两种方法:
1.写一个类,继承Process,重写类的run方法,实例化得到对象,对象.start开启进程
2.通过Process类实例化一个对象,传入一个任务,调用对象.start开启进程

# 开启线程的两种方法:
1.写一个类,继承Thread,重写类的run方法,实例化得到对象,对象.start开启线程
2.通过Thread类实例化一个对象,传入一个任务,调用对象.start开启进程

# 开启协程
1.早期的写法:借助于第三方gevent,基于greelet写的
2.现在写法:
	有async和await关键字,不借助于第三方,开启协程asyacio包
    写在一个函数前,async def task()--->这个函数执行的结果就是协程函数
    await只要是io操作的代码,前面必须加await
三者我们在哪里用过
1.一般遇到计算密集型的操作,我会开多进程,遇到io密集型的操作,我会开多线程
2.闲着没事干的时候,爬取别的数据,喜欢开多线程,爬虫io居多
3.程序中,异步做一件事情,也可以开多线程
	eg:
        一个视图函数,异步的把数据写到文件中
        异步的发送钉钉通知
        异步的发送邮件
	实际生活中,在项目中,不需要我们来开启进程线程的,可以借助于第三方的框架比如celery就可以进行异步操作
    celery的worker,就是进程线程架构
4.django框架,是支持并发的,我们没有开启多进程、多线程,但是符合uwsgi的web服务器在进入Django框架之前,就开启了线程和进程来执行视图函数

6 什么是鸭子类型

走路像鸭子,说话像鸭子,我们就可以叫它鸭子
解释:鸭子类型是Python面向对象中描述接口的一个概念,区分与其他编程语言
	eg:
        java中:实现接口,必须显示继承一个接口
        Python中:实现接口,遵循鸭子类型,不需要显示的继承一个接口(类),只要类中有对应的属性跟方法,我们就称这几个类的对象为同一种类型

image

标签:面试题,多线程,开启,回收,线程,进程,gil
From: https://www.cnblogs.com/zx0524/p/17303467.html

相关文章

  • 用 Go 剑指 offer:面试题61. 扑克牌中的顺子
    从若干副扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为0,可以看成任意数字。A不能视为14。 示例 1:输入:[1,2,3,4,5]输出:True 示例 2:输入:[0,0,1,2,5]输出:True 限制:数组长度为5 数组的......
  • Spring Framework面试题
    Spring与SpringFramework以及SpringBoot之间的是什么关系。Spring是一个广泛应用于Java开发的企业级开源框架。它的设计初衷是通过依赖注入(DependencyInjection,DI)和面向切面编程(AspectOrientedProgramming,AOP)等技术,简化Java应用程序的开发、测试和部署。Spring提......
  • 大数据面试题集锦-Hadoop面试题(一)
    目录1、集群的最主要瓶颈2、Hadoop运行模式3、Hadoop生态圈的组件并做简要描述4、解释“hadoop”和“hadoop生态系统”两个概念5、请列出正常工作的Hadoop集群中Hadoop都分别需要启动哪些进程,它们的作用分别是什么?6、基于Hadoop生态系统对比传统数据仓库有何优势?7、如何选择不......
  • 面试题 17.05. 字母与数字
    题目链接:面试题17.05.字母与数字方法:TwoSum解题思路(1)将字符量化为\(+1\),数字量化为\(-1\),那么当子数组的和\(subSum=0\)时,表示子数组中的字符和数字的数量相等;(2)\(subSum=s[j]-s[i],j>=i,i=1,2,...\),\(s[i]\)表示前\(i\)个元素的和;(3)即找\(s[j]-s[i]=0\),也即......
  • 面试题 05.02. 二进制数转字符串
    题目链接:面试题05.02.二进制数转字符串方法:找规律解题思路(1)题目要求:将一个\(0-1\)之间的实数通过二进制进行表示,并通过字符串形式输出。(2)由于二进制的小数只能表示\(\frac{1}{2}\frac{1}{4}\frac{1}{8}...\frac{1}{2^n}\)数之间的和的十进制小数,因此有些十进制小数不能......
  • #yyds干货盘点# LeetCode面试题:爬楼梯
    1.简述:假设你正在爬楼梯。需要n 阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例1:输入:n=2输出:2解释:有两种方法可以爬到楼顶。1.1阶+1阶2.2阶示例2:输入:n=3输出:3解释:有三种方法可以爬到楼顶。1.1阶+1阶+1阶2.1阶......
  • 面试题百日百刷-HBase中HTable API有没有线程安全问题,在程序是单例还是多例?
    锁屏面试题百日百刷,每个工作日坚持更新面试题。请看到最后就能获取你想要的,接下来的是今日的面试题: 1.HBase内部机制是什么?Hbase是一个能适应联机业务的数据库系统物理存储:hbase的持久化数据是将数据存储在HDFS上。存储管理:一个表是划分为很多region的,这些region分布式地......
  • 面试题百日百刷-HBase HRegionServer宕机如何处理
    锁屏面试题百日百刷,每个工作日坚持更新面试题。锁屏面试题app、小程序现已上线,官网地址:https://www.demosoftware.cn。已收录了每日更新的面试题的所有内容,还包含特色的解锁屏幕复习面试题、每日编程题目邮件推送等功能。让你在面试中先人一步!接下来的是今日的面试题: 1.HBase......
  • 免费分享前端面试题,vue面试题,TypeScript基础知识点 PDF格式
    免费分享前端资料,面试题,电子书接前端开发,带徒弟,一对一教学,远程协助,bug修改微信:......
  • #yyds干货盘点# LeetCode面试题:x 的平方根
    1.简述:给你一个非负整数x,计算并返回 x 的算术平方根。由于返回类型是整数,结果只保留整数部分,小数部分将被舍去。注意:不允许使用任何内置指数函数和算符,例如pow(x,0.5)或者x**0.5。 示例1:输入:x=4输出:2示例2:输入:x=8输出:2解释:8的算术平方根是2.82842...,由......