栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python 面试

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python 面试

编译性语言与解释性语言

编译:一次运行,无限次使用,不能跨平台

解释:运行时解释,可以跨平台

python中的数据类型

常见的int float 字符串 bool 列表 集合 元组 字典

不可变类型: int float 字符串  bool 元组

可变类型: 列表 字典 集合(其元素是唯一的、不可变的(可哈希的)对象)。不能作为key,字典本质还是hash,key变化了 val就会变化

元组得优势: 1. 某些数据不会改变,减少编写代码时发生错误

                        2. 对于某些特殊得字典,需要列表形式得元素作为key

集合的优势: 1.一些集合运算比列表方便 & | 

                        2.set无序排序且不重复,是可变的,消除重复元素,frozenset是冻结的集合,它是不                             可变的,存在哈希值,好处是它可以作为字典的key,也可以作为其它集合的元                               素。缺点是一旦创建便不能更改,没有add,remove方法

Python参数传递采用的肯定是“传对象引用”的方式。这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值'来传递对象。

python中is和==的区别

Python中对象包含的三个基本要素,分别是:id(身份标识) 、type(数据类型)和value(值)。‘==’比较的是value值‘is’比较的是id

print ([1] + [2] is [1, 2] )
print("a"+ "b" is "ab")

False(属于两个对象)
True(字符串属于不可变类型,他们在内存中属于一个对象两个引用)  

a = "123"
b = "123"
print (id(a), id(b))
a = [1, 2]
b = [1, 2]
print (id(a), id(b))
2159674827472 2159674827472 
2159674833672 2159674832520          

 lamba 匿名函数,简化代码,一般用于高阶函数sort, filter

# -*- coding:utf-8 -*-
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]

print filter(lambda x: x % 3 == 0, foo)  # python 2.x
print sorted(foo, key = lambda x: x%3!=0)
print map(lambda x: x * x, foo)  # python 2.x


[18, 9, 24, 12, 27]
[18, 9, 24, 12, 27, 2, 22, 17, 8]
[4, 324, 81, 484, 289, 576, 64, 144, 729]
a = [('b', 4), ('a', 12), ('d', 7), ('h', 6), ('j', 3)]
a.sort(key=lambda x: x[0])
print(a)

L.sort() 函数排序会改变原有的待排序列表,而sorted()函数则不会改变(稳定排序)。所以在使用列表进行排序时,需要考虑是否需要保存原列表,如果无需保存原列表,则优先使用L.sort() 节省内存空间,提高效率

 函数式编程

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

高阶函数: 编写高阶函数,就是让函数的参数能够接收别的函数。 map filter sorted 

闭包: 内层函数引用了外层函数的局部变量  外函数返回值是内函数的引用

装饰器: 给函数添加额外得功能,高效简洁,利用闭包,将被装饰的函数作为参数传递到装饰器函数中

def my_login(func):
    def wrapper(*args, **kargs):
        kargs['val'] = 5
        print (args)
        print (kargs)
        return func(*args, **kargs)
    return wrapper
@my_login
def login_test(*args, **kargs):
    print (args)
    print (kargs)
if __name__ == '__main__':
    login_test(1,3,a=4,b=5)

装饰器类: 可以使用类的一些特性(继承,重载,不用每个功能都重写)定义__call__函数实现

class decorate(object):
    def __init__(self, logfile):
        self.logfile = logfile
    def __call__(self, *args, **kwargs):
        # 装饰器实现 省略
        print self.logfile
        self.work()
        pass
    def work(self):
        pass
@decorate()
def myfunc1():
    pass

迭代器、生成器

迭代器:可以记录遍历位置的对象,通过next函数来访问下一个元素;迭代器两个属性__iter__, __next__;list dict都属于可迭代对象,但是不是迭代器,可以通过iter()方法将可迭代对象封装成迭代器。

 生成器:也属于迭代器,但是它的下一个元素是通过计算获取的,可以节约内存,需要的时候才会生成,通过yield关键字实现(也可以通过iter和next函数实现)。生成器表达式: ( i * i  for i in range(1,4))

# 通过next和iter实现生成器
class FeiboIterator():
    def __init__(self):
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def __next__(self):
            num = self.a
            self.a,self.b = self.b,self.a+self.b
            return num


iterator = FeiboIterator()
print(next(iterator))

# 通过yield实现
def FeiboIterator():
    a  = 0
    b = 1
    while True:
     
        yield a
        tmp = a
        a = b
        b = tmp + b
test = FeiboIterator()
for i in range(4):
    print(next(test))

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行

内存管理机制

python的内存管理主要通过内存池+垃圾回收实现

 Python中有分为大内存和小内存:(256K为界限分大小内存)

1、大内存使用malloc进行分配 

2、小内存使用内存池进行分配

内存池的好处:1.创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片;                              2. malloc 和free是用户态和核心态直接的切换,频繁的切换会影响python的执行                                  效率

垃圾回收采用引用计数机制,另外采用标记清除机制来解决循环引用的问题,分代回收机制是为了提升垃圾回收的效率

对象被引用的时候计数加一,不被变量引用减一,计数为0表明对象可以被删除,标记清除是为了解决对象间循环引用问题,当一个对象被清理很多次依然存在,可以认为这个对象不需要经常去判断是否需要被清理,可以把它们划分为不同的集合,为了提高效率,这些集合的回收时间间隔不一样

pythpn ORM

Python SQLalchemy的学习与使用 - 战争热诚 - 博客园

orm:对象关系映射模式,主要实现程序对象到关系数据库数据的映射。一张表对应了一个类,表中的字段对象类中的属性, orm模型就是实现这种映射。对数据库中的操作通过session(会话)来实现数据库的操作。好处就是 数据库更加的可视化,提供了通用的数据库交互,并且完全不用考虑SQL语句,从而快速开发。

GIL

python GIL 全局锁_bitcarmanlee的博客-CSDN博客_python 全局锁

当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状态。这种方式我们称之为并发(Concurrent)。当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

gil:全局解释器锁,为了解决多 线程之间数据同步问题,cpython设定每个线程执行的时候都需要获取这个gil,保证同一时刻只有一个线程在执行这是cpython(官方默认解释器) 解释器的问题,不是python的问题, jpython 解释器就没这个问题(是一个将python代码编译成java字节码的实现,运行在JVM(将java编译成机器码))

gil得释放: 遇到IO必释放,时间片到期释放

 gil只是限制了线程的并行,并发仍然存在,类似时间片轮转 适合IO密集任务

元类:

python __new__和__init__的区别

__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是个静态方法。__init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值,通常用在初始化一个类实例的时候。是一个实例方法。

match和search:

match()函数只检测字符串开头位置是否匹配,匹配成功才会返回结果,否则返回None

search()函数会在整个字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。

assert:后面跟合法的表达式,当表达式为True是,不做任何操作,为False时回抛出异常,assert可以快速定位代码中的错误

def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n

foo('0')

# 代码执行结果
# AssertionError: n is zero!

单例模式:

采用new

class base_test(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(base_test, '_instance'):
            base_test._instance = object.__new__(cls)
        return base_test._instance

    def __init__(self, val1):
        self.val = val1
    def work(self):
        print self.val

base_test1 = base_test(1)
base_test2 = base_test(2)
print base_test1
print base_test2
print (base_test1 is base_test2)

<__main__.base_test object at 0x00000000033A40F0>

<__main__.base_test object at 0x00000000033A40F0>
True

考虑线程安全问题 

class base_test(object):
    def __new__(cls, *args, **kwargs):
        _sig_lock = threading.Lock()
        # 单划线标识类共有的属性
        if not hasattr(base_test, '_instance'):
            with _sig_lock:
                if not hasattr(base_test, '_instance'):
                    """
                    两个在python里面确实是差不多,cls是type的实例,self是cls的实例,
                    python2.5以后新类从object继承,
                    object是type的实例,所以所有类都是type的实例,
                    因此类都是cls。type称为类的类或者元类
                    """
                    base_test._instance = object.__new__(cls) #cls 表示类本身
        return base_test._instance

 python实现的常用算法(排序、树的遍历)

def my_quich_sort(a, low, high):
    """
    快速排序
    :param a:
    :param low:
    :param high:
    :return:
    """
    if not a or low >= high:
        return a
    key = a[low]
    left = low
    right = high
    while left < right:
        while right > left and a[right] > key:
            right -= 1
        a[left] = a[right]
        while right > left and a[left] <= key:
            left += 1
        a[right] = a[left]
    a[left] = key
    my_quich_sort(a, low, left - 1)
    my_quich_sort(a, left + 1, high)


# a = [1,3,2,1,8,4]
# my_quich_sort(a, 0, 5)
# print a


def maopao_sort(a):
    """
    冒泡排序
    :param a:
    :return:
    """
    for i in range(len(a)):
        for j in range(len(a) - i - 1):
            if a[j] > a[j + 1]:
                a[j], a[j + 1] = a[j + 1], a[j]


def chose_sort(a):
    """
    选择排序
    :param a:
    :return:
    """
    for i in range(len(a)):
        for j in range(i + 1, len(a)):
            if a[i] > a[j]:
                a[i], a[j] = a[j], a[i]

树的遍历:python实现二叉树的遍历以及基本操作 - pandaWaKaKa - 博客园

def layer_order(root):
    """
    树的层次遍历
    :param root:
    :return:
    """
    if not root:
        return
    que_tree = [root]
    while que_tree:
        q = que_tree.pop(0)
        print q.val,
        if q.left:
            que_tree.append(q.left)
        if q.right:
            que_tree.append(q.right)


def layer_order_print(root):
    """
    逐行打印 树的层次遍历
    :param root:
    :return:
    """
    if not root:
        return
    que_tree = [root]

    while que_tree:
        output_val = list()
        new_que_tree = []
        while que_tree:
            q = que_tree.pop(0)
            output_val.append(q.val)
            if q.left:
                new_que_tree.append(q.left)
                # print "left:", q.left.val
            if q.right:
                new_que_tree.append(q.right)
                # print "right:", q.right.val

        que_tree = new_que_tree
        for instance in output_val:
            print instance,
        print 'rn'

python线程池

def send_each_block_to_ipList(local_mac, local_card, block_ip, protect_list):
    """
        发送被阻断的虚假MAC地址给到每个被保护的设备
    :return:
    """
    from concurrent.futures import ThreadPoolExecutor
    executor = ThreadPoolExecutor(max_workers=Config().ARP_THREAD_NUM)
    for protect_dict in protect_list:
        protect_ip = protect_dict["protect_ip"]
        protect_mac = protect_dict["protect_mac"]
        executor.submit(send_block_to_eachp, local_mac, local_card, block_ip, protect_ip, protect_mac)
    executor.shutdown()  # 会等所有的线程执行完毕

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/714847.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号