美文网首页python
python面试题

python面试题

作者: Jerry_Hao | 来源:发表于2018-01-03 14:10 被阅读173次

    python面试题

    python基础

    1. Python的函数参数传递

      类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。

    2. staticmethod classmethod 区别

      类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量cls是子类,而非父类。 对于类方法,可以通过类来调用。如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

    3. python元类与对象实例化

    * Foo(*args, **kwargs) 等价于 Foo.__call__(*args, **kwargs)。
    * 因为 Foo 是 type 的对象,所以 Foo.__call__(*args, **kwargs)调用的是 type.__call__(Foo, *args, **kwargs)。
    * type.__call__(Foo, *args, **kwargs) 调用的是type.__new__(Foo, *args, **kwargs),然后返回了 obj。
    * obj 被 obj.__init__(*args, **kwargs) 初始化, 最后 obj 就被返回了
    
    1. 怎么实现一个单例

      • 一个利用 new 方法的很强大的示例就是实现 Singleton 类:
      class Singleton(object):
        def __new__(cls, *args, **kw):
          if not hasattr(cls, '_instance'):
              orig = super(Singleton, cls)
              cls._instance = orig.__new__(cls, *args, **kw)
          return cls._instance
      
      • 共享属性: 创建实例时把所有实例的dict指向同一个字典,这样它们具有相同的属性和方法.
      class Borg(object):
        _state = {}
        def __new__(cls, *args, **kw):
          ob = super(Borg, cls).__new__(cls, *args, **kw)
          ob.__dict__ = cls._state
          return ob
      
      • 装饰器版本
      def singleton(cls, *args, **kw):
         instances = {}
         def getinstance():
           if cls not in instances:
               instances[cls] = cls(*args, **kw)
           return instances[cls]
       return getinstance
      
    
    - import方法: 作为python的模块是天然的单例模式
    
    ```PYTHON
      # mysingleton.py
      class My_Singleton(object):
          def foo(self):
              pass
      
      my_singleton = My_Singleton()
      
      # to use
      from mysingleton import my_singleton
      
      my_singleton.foo()
    
    1. yield 和 generator, 协程

      http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/1/README.html

      yield实现一个生产者消费者模型:

      import time
      
      def consumer():
          r = ''
          while True:
              n = yield r
              if not n:
                  return
              print('[CONSUMER] Consuming %s...' % n)
              time.sleep(1)
              r = '200 OK'
      
      def produce(c):
          c.next()
          n = 0
          while n < 5:
              n = n + 1
              print('[PRODUCER] Producing %s...' % n)
              r = c.send(n)
              print('[PRODUCER] Consumer return: %s' % r)
          c.close()
      
      if __name__=='__main__':
          c = consumer()
          produce(c)
      

      跟多线程不同的是,协程是非抢占式的。协程的实现跟多线程没什么关系,主要还是通过类似保存栈的上下文环境(或者类似的技术)来实现的。

      python中可以通过多进程+协程来充分利用多核优势,而且避免了多线程之间切换的开销。

      注意到consumer函数是一个generator(生成器),把一个consumer传入produce后:

      1. 首先调用c.next()启动生成器;

      2. 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

      3. consumer通过yield拿到消息,处理,又通过yield把结果传回;

      4. produce拿到consumer处理的结果,继续生产下一条消息;

      5. produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

      整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。

      最后套用Donald Knuth的一句话总结协程的特点:

      “子程序就是协程的一种特例。”

    2. gevent

      from gevent import monkey; monkey.patch_all()
      import gevent
      import urllib2
      
      def f(url):
          print('GET: %s' % url)
          resp = urllib2.urlopen(url)
          data = resp.read()
          print('%d bytes received from %s.' % (len(data), url))
      
      gevent.joinall([
              gevent.spawn(f, 'https://www.python.org/'),
              gevent.spawn(f, 'https://www.yahoo.com/'),
              gevent.spawn(f, 'https://github.com/'),
      ])
      
    3. 面向切面编程AOP和装饰器

    4. 鸭子类型

    5. GIL线程全局锁

    服务器系统

    1. tornado单线程怎么实现非阻塞异步的web服务器系统

    相关文章

      网友评论

        本文标题:python面试题

        本文链接:https://www.haomeiwen.com/subject/xlphnxtx.html