python基础篇

对不定长参数的理解?

*args:传入 不定长参数,用来将参数打包成tuple给函数调用;

**kwargs: 关键字参数,打包关键字参数成dict给函数体调用在定义函数的时候不确定要传入的参数个数会有多少个的时候,就可以使用不定长参数作为形参。

对缺省参数的理解

缺省参数是指在调用函数的时候没有传入参数的情况下,调用默认的参数,在调用函数的同时赋值时,所传入的参数会替代默认参数。

lambda函数及好处

lambda函数是匿名函数,使用lambda函数能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤:

f = lambda x, y : x + y
print(f(2007, 2008))

深拷贝和浅拷贝的区别?

浅拷贝是将对象顶层拷贝,拷贝了引用,并没有拷贝内容,愿对象改变新对象也跟着改变;

深拷贝是对一个对象的所有层次的拷贝(递归),但是修改原来的值,新对象不受影响;

浅拷贝对于可变类型和不可变类型是不同的,对于可变类型值拷贝顶层,不可变类型依然是原来的对象。

什么是可变、不可变?元组里添加字典,会改变id吗?

可变不可变指的是内存中的值是否可以被改变,不可变类型指的是对象所在内存块里面的值不可改变,有数值、字符串、元组;可变类型则可以改变,主要有列表、字典;

元组的顶层元素中包含可变类型,在可变类型中修改或添加字典id不会改变。

生成器、迭代器的区别

一边循环一边计算的机制,称为生成器generator,生成器是可以迭代对象,但是生成器可以通过send传值返回到前面;

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器是一个可以记住遍历的位置的对象。

range() 和 xrange() 的用法

range(start,stop,step)函数按照从start到step生成一个数值,生成的列表对象,一次性将所有数据都返回;

xrange(start, stop, step) 函数按照从start到stop每个step生成一个数值,返回的是可迭代对象,每次调用返回其中的一个值

装饰器的理解

装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象。

import time
def timeit(func):
    def wrapper():
        start = time.clock()
        func() 
        end = time.clock()
        print('used:',end - start)

@timeit
def foo():
    print('in foo()')

foo()

单例模式

确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类成为单例类,单例模式是一种对象创建型模式。

windows的任务管理器task manager、回收站recycle bin、网站计数器

资源共享的情况下,避免由于资源操作时导致的i性能或损耗等,日志文件,应用配置。

控制资源的情况下,方便资源之间的互相通信,如线程池。

并行和并发

线程是并发,进程是并行;进程之间相互独立,是系统分配资源的最小单位,同一个进程中所有线程共享资源。

并行:同一时刻多个任务同时运行
并发:在同一时间间隔内多个任务都在运行,但是并不会在同一时刻同时运行,存在交替执行的情况。

实现并行的库有multiprocessing
实现并发的库有threading

程序需要执行较多的读写、请求和回复任务的需要大量的IO操作,IO密集型操作使用并发更好。

CPU运算量大的程序使用并行会更好。

线程安全、互斥锁

每个对象都对应于一个可称为互斥锁的标记,这个标记用来保证在任何时刻,只能有一个线程访问该对象。

同一个进程中的多线程之间是共享系统资源的,多个线程同时对一个对象进行操作,一个线程操作尚未结束,另一个线程已经对其进行操作,导致最终结果出现错误,此时需要对被操作对象添加互斥锁,保证每个线程对该对象的操作都得到正确的结果。

内存管理机制及调优手段

引用计数:一种非常高效的内存管理手段,当一个python对象被引用时其引用计数增加1,当其不再被一个变量引用时则计数减1。当引用计数等于0时对象被删除。

垃圾回收:引用计数也是一种垃圾收集机制,而且是最直观最简单的垃圾收集技术。当python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾。比如某个新建对象,他被分配给某个引用,对象的引用计数为1,如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。不过如果出现循环引用的话,引用计数就不再起有效的作用了。

标记清除:如果两个对象的引用计数都为1,但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的,也就是说,他们引用计数虽然表现为非0,但世纪上有效的引用计数为0。多疑先将循环引用摘掉,就会得出这两个对象有效计数。

分代回收:从标记清除这样的垃圾收集机制来看,这种垃圾收集机制所带来的额外操作实际上与系统中总的内存块的数量是相关的,当需要回收内存块越多时,垃圾检测带来的额外操作就越多,而垃圾回收带来的额外操作,就越少,反之,当需要回收的内存块越少时,垃圾检测就将比垃圾回收带来更少的操作。

内存池:内存机制呈现金字塔形状,-1,-2层主要有操作系统进行操作。第0层是C中的malloc,free等内存分配和释放函数进行操作;第1层和第2层是内存池,有python的接口函数pymem_malloc函数实现,当对象小于256K时有该层直接分配内存;第3层是最上层,也就是我们对python对象的直接操作。python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,浙江严重影响python的执行效率。为了加速python的执行效率,python引入了一个内存池机制,用于管理对小块内存的申请和释放。

python内部默认的小块内存与大块内存的分界点定在256个字节,当申请的内存小于256字节时,pyobject_malloc会在内存池中申请内存,当申请的内存大于256字节时,pyobject_malloc的行为将蜕化为malloc的行为。当晚,通过修改python源代码,我们可以改变这个默认值,从而改变python的默认内存管理行为。

调优手段:手动垃圾回收、调高垃圾回收阀值、避免循环引用(手动解循环引用和使用弱引用)

read/readline/readlines 区别

read:读取整个文件
readline:读取下一行,使用生成器方法
readlines:读取整个文件到一个迭代器以供我们遍历

死锁

在线程间共享多个资源的时候,如果两个线程分别占有部分资源并且同时等待对方的资源,就会造成死锁

解决:给互斥锁添加超时时间、程序设计时要尽量避免(银行家算法)

闭包

在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称为闭包。

GIL对多线程的影响

全局解释器锁,每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程可以执行字节码。

线程释放GIL锁的情况:在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL;

python3 使用计时器(执行时间达到阀值时,当前线程释放GIL),python2 tickets计数达到100;

python使用多进程是可以利用多核的CPU资源的。多线程爬取比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁。

日志使用

python 自带logging 模块,调用 logging.basicConfig() 方法,配置需要的日志等级和相应的参数,python 解释器会按照配置的参数生成响应的日志。

    原文作者:大猪厂
    原文地址: https://www.jianshu.com/p/d30ac0e1a215
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞