1.GIL锁

GIL锁,又叫全局解释器锁,本质上来讲其实就是一把作用于所有数据的排他锁。

最初的时候,因为多线程之间有很多共享资源,所以在多线程并发的时候,相互之间会影响,造成数据混乱。为了数据安全,几乎对于所有的数据,这种情况下都需要加上一把线程锁。而python奉行一贯是简单,明确,优雅的设计风格,所以当时的设计者就使用cpython设计出了这么一把全局排他锁,在遇到像 io 操作这种会有时间空闲情况造成cpu闲置的情况会自动释放。确保只有一个线程进行数操作,另一个释放GIL的时机是100行微代码执行完毕后自动释放一次。

缺陷也就显而易见,因为频繁的加锁释放,对于多线程来讲会有不小的影响,最典型的就是在多线程遇到CPU密集型代码时单线程会比多线程要更快。(不绝对,python对此应该有所优化--GIL不使用ticks微代码计数,改为使用计时器)。这把锁的存在也意味着python只能实现多并发而难以实现并行。

要彻底解决GIL锁带来的影响,目前还没有特别好的方式。但是我们可以用多进程加协程的方式去改良代码的运行效率。或者使用其他比如C,JAVA等语言,或者cpython,Jpython等解释器去规避。

 

2.Python3 和Python2的区别

python自89年发明以来,经过三十年的发展,从最初的版本,到1.0增加高阶函数完善优化,到2000年,2.0版本加入垃圾回收机制,构成了现在python语言框架基础。于2004年在2.4版本才有了目前最流行的WEB框架Django。08年开始更新第一个python3版本-----3.0版本,目前已经到了python3.7版本了。python2和python3相比毫无疑问python3是要更为强大的。官方都只推荐学习3.x,并且宣布2.x只维护至20年。

两个版本区别有很多,据我所了解和应用的区别主要有:

  1.python2有长整型和整型之分,即long int和int.int在超出-2的31次方和正的32次方这个范围后,会出现整型溢出(结果并非想要的/缓存区溢出)。

  2.print 加上了括号用法,让他更接近于函数用法(或者他的本身就是一个函数,哈哈)。

  3.在python3中input 被统一成了字符串输出,而2.x版本input输出的int。raw_input输出的是str.4.2.x的时候打开文件可以用file或者open,3.x统一用open。(代码中有这个用法,还特地查了一下)。

  4.默认编码在2.x是ascii,3.0是utf-8,另外还有一些字符串储存的差异。没有深究。

  5.在2.0除法只保留整数部分(需要改./),而3.0可以保留所有内容.

  6.python (print(A.__mro__)可以查到类的继承顺序),在python3中所有的类都继承object,全部都是新式类.而python2中继承了的是新式类,否则都是经典类,经典类的继承是深度优先而新式类的继承是C3算法。

对于选择版本的话,适合自己的才是最好的,从前沿的角度来讲,用P3肯定更好,因为他的紧密性会比P2更强,但是还是要参照技术人员和公司情况以及所运用的库的兼容性问题等考虑,往往可能还是需要使用P2。

 

3.什么是解释性语言。

解释性跟编译性语言是相对的两个概念。解释性语言指的是在运行的时候将程序翻译成机器语言。不需要在运行前编译。

而编译性语言的话,指的是需要在运行之前就编译成机器语言,执行直接得出编译代码的结果。

解释性语言:速度相对会慢,开发效率高。调试快,逢错即报,未错即运行。平台独立且可以保证高度的安全性。跨平台和可移植性会更好。

编译性语言:运行速度快,小号内存少。

出于平台独立性,以及严密的安全性是使解释型语言成为适合互联网和Web应用的理想语言的2个最重要的因素。

 

4.如何保障线程安全

线程安全是由于进程下的多线程共享进程的各种数据和资源,为了保证各线程并行执行能够正常且正确的运行使用提出的概念。

(多线程: python多线程 -- 进程, 协程)线程是进程的一个实体,是CPU调度和分派的基本单位,最初的线程是因为进程出现了许多的诸如创建、撤消与切换存在较大的时空开销,多个进程并行开销过大等弊端,因此引入的微型进程,也叫纤程。线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证独立运行的资源。保障线程安全的方式有,GIL锁或者自己加锁。

 

5.COW是什么?

COW是copy on write的缩写即写时复制。是一种子父进程之间的数据复制策略。多进程中,父进程要创建一个子进程其实是用fork函数创建一个完全想同的子进程(子父进程之间虽然是有着不同的虚拟空间,但是其实他们是公用一个物理空间,他们的物理地址就是基址+逻辑地址。)。

子进程是通过复制父进程的正文段,数据段,堆,栈等内容,后来出于效率考虑,引入了写时复制的功能。

因为在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都可以指向父进程的物理空间。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间。所以COW直接映射原始盘的数据内容,当原始盘的旧数据有修改时,再开辟新的空间地址拷贝写入数据给子进程使用。

写时拷贝能减少不必要的内存操作,减少fork时对父进程空间进程整体复制带来的开销,提高程序性能。(但同时也是一把双刃剑,多线程是非线程安全的,写时复制并没有改变这一点。直接操作内存用法的时候不被感知,导致不可察觉的bug。const改成非const)。

多进程一般适用于cpu密集任务,他有明显的缺陷,创建和切换代价高,进程间通信效率相对低,资源消耗大。

 

 

6.什么是覆盖索引?

如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引’。即只需扫描索引而无须回表。select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。

索引的本质上是一种数据的排序,是为了加速对表中数据行的检索而创建的一种存储结构。通常多是应用于数据量比较大,查询字段较多的情况。根据不同的分类索引的叫法也多种多样。除覆盖索引外,还有聚簇索引(普通索引),非聚簇索引(辅助索引),唯一索引,主键索引,单列索引。基本上字面上都可以理解。

**全文索引:

全文索引时将存储在数据库中的整本书或整篇文章中的任意内容信息查找出来的技术。它可以根据需要获取全文中有关章,节,段,句,词等信息,也可以进行各种统计和分析。

之前的MySQL数据库中,INNODB存储引擎并不支持全文索引技术,大多数的用户转向MyISAM存储引擎,不过这可能进行表的拆分,并需要将进行全文索引的数据存储为MyIsam表。这样的确能够解决逻辑业务的需求,但是却丧失了INNODB存储引擎的事务性,而这在生产环境应用中同样是非常关键的。

从INNODB1.2.x版本开始,INNODB存储引擎开始支持全文索引,其支持myisam的全部功能,并且还支持其他的一些特性。

posted on 2019-12-22 17:51  hole_cheng  阅读(311)  评论(0)    收藏  举报