• 面试题2.20


    1.什么是lambda函数?他有什么好处?另外python在函数式编程方面提供了些什么函数和语法?
        lambda函数就是可以接受任意多个参数(包括可选参数)并且返回单个表达式值得函数
        好处:
            1.lambda函数比较轻便,即用即扔,适合完成只在一处使用的简单功能 
            2.匿名函数,一般用来给filter,map这样的函数式编程服务
            3.作为回调函数,传递给某些应用,比如消息处理
    2.什么是装饰器?写一个装饰器,可以打印输出方法执行时长的信息。
        装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
        这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
        我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。
        import time
    
        def timer(func):
            def decor(*args):
    
                start_time = time.time()
                func(*args)
                end_time = time.time()
                d_time = end_time - start_time
                print("run the func use : ", d_time)
            return decor
    
        @timer  #printSth = timer(printSth) -> printSth = decor
        def printSth(str, count):
            for i in range(count):
                print("%d hello,%s!"%(i,str))
    
        printSth("world", 1000000)#run the func use :  4.414000034332275
    3.什么是进程,线程,协程,说一说python对他们的支持?
        多进程:进程之间是独立的, 
        python的线程是用的操作系统的原生线程、python的进程也是用的操作系统的原生进程。 
        原生进程是由操作系统去维护的,python只是通过C代码库去起了一个进程,真正进程的管理还是通过操作系统去完成的。 
        操作系统的进程管理是没有全局解释器锁的,进程只是是独立的,根本不需要锁的概念。
    import multiprocessing
    import threading
    import time
    
    def thread_run(i,n):
        print("在进程%s的线程%s"%(i,n))
    
    def run(i):
        print("进程:%s "%i)
        time.sleep(1)
        for n in range(2):
            t = threading.Thread(target=thread_run,args=(i,n))
            t.start()
    
    if __name__ == '__main__':  # 这个必须要有
        for i in range(4):
            p = multiprocessing.Process(target=run,args=(i,))
            p.start()
    
    
    from multiprocessing import Process
    import os
    
    def info(title):  # 打印进程信息
        print(title)
        print('module name:', __name__)  # 模块名
        print('parent process:', os.getppid())  # 父进程ID
        print('process id:', os.getpid())  # 进程ID
        print("
    ")
    
    def f(name):
        info('33[31;1mcalled from child process function f33[0m')  # 打印子进程信息
        print('hello', name)
    
    if __name__ == '__main__':
        info('33[32;1mmain process line33[0m')  # 打印当前进程信息
        p = Process(target=f, args=('FGF',))  # 子进程
        p.start()
        # p.join()
            
        全局解释器锁的存在让多线程只有一个线程在执行,所以python里的多线程是假的多线程,不管多少核,同一时间只能在一个核上运行。 
        所有我们利用多线程的优势只是利用了它的什么优势呢?利用了CPU上下文切换的优势,看上去说并发的效果。
    
        什么时候用多线程呢?
    
        io操作不占用cpu,计算占用cpu 
        大量计算,耗cpu的用单线程 
        python多线程,不适合cpu密集操作型的任务,适合io密集型的任务 
        IO密集开多线程,计算密集开多进程
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import threading
    import time
      
    def show(arg):
        time.sleep(1)
        print 'thread'+str(arg)
      
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
      
    print 'main thread stop'
    
        协程,又称微线程,纤程。英文名Coroutine。协程是一种用户态的轻量级线程。
    
        协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:
    
        协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
    
        线程的切换,会保存到CPU的寄存器里。 
        CPU感觉不到协程的存在,协程是用户自己控制的。
    
        之前通过yield做的生产者消费者模型,就是协程,在单线程下实现并发效果。
    
        协程的好处:
    
        无需线程上下文切换的开销
        无需数据操作锁定及同步的开销
        方便切换控制流,简化编程模型
        高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。
        缺点:
    
        无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。
        进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序
        
        import time
    
    def consumer(name):
        print("--->starting eating baozi...")
        while True:
            new_baozi = yield
            print("[%s] is eating baozi %s" % (name,new_baozi))
            # time.sleep(1)
    
    def producer():
        r = con.__next__()
        r = con2.__next__()
        n = 0
        while n < 5:
            n +=1
            print("33[32;1m[producer]33[0m is making baozi %s" %n )
            con.send(n)
            con2.send(n)
            time.sleep(1)
    
    if __name__ == '__main__':
        con = consumer("c1")  # 第一次调用只是生成器,next的时候才回生成
        con2 = consumer("c2")
        p = producer()
    4.用python实现"九九乘法表",用两种不同的方式实现
        No.1(列表生成式,简单粗暴)
    print('
    '.join('  '.join(['{}*{}={}'.format(i,j,i*j) for i in range(1,j+1)])
    for j in range(1,10)))
     
     
    No.2(递归大法好)
    def f(i):
         if i>=1:
            f(i-1)
            print(['%dx%d=%d'%(j,i,i*j) for j in range(1,i+1)])
             
    if __name__=='__main__':
        f(9)
  • 相关阅读:
    Git 常用命令速查表
    Android的Fragment中onActivityResult不被调用
    git基本操作
    Android混淆
    Shell
    小米手机图标应用图标不改变的问题
    linux常用基本命令
    android新建的项目界面上没有显示怎么办?
    bzoj5249: [2018多省省队联测]IIIDX(线段树)
    bzoj1951: [Sdoi2010]古代猪文(Lucas+CRT+欧拉定理)
  • 原文地址:https://www.cnblogs.com/ldq1996/p/8456378.html
Copyright © 2020-2023  润新知