python面试题

1. 面试总结

先把这个看了,总结的很全面
https://www.cnblogs.com/JetpropelledSnake/p/9396511.html

 

3. 零碎

1. 类继承的super()原理
    Python中每一个类都有一个MRO列表,他代表了类的继承顺序,super会返回当前类index+1的类,然后按照此顺序分别去执行他们的方法,知道最后的base类
2. 单例模式
  线程锁+__new__来实现
  __new__(cls,*args,**kwargs)中判断当前类是否有实例(cls.instance是否为真),没有就开线程锁,然后创建,有的话,就返回当前实例
3. 类的常用方法及解释
  __dict__  以字典的格式返回实例的属性
  __call__ 使实例可以像函数一样加括号被调用,也可以传参数
  __new__ # 创建类时,先执行此方法,返回一个实例,再执行__init__
  __getitem__ 实例动态的获取属性的值
  __setitem__ 实例可以动态的添加属性
  __delitem__ 删除值
  __enter__ # 上下文管理,见4
  __exit__ # 上下文管理,见4
  __setattr__ 用于注册实例的属性,即
  __str__ print时会调用
  示例:
    __setitem__(self,key,value):
    __new__(cls,*args,**kwargs)

4. 上下文管理实现机制
  调用__enter__返回一个文件对象
  执行完成之后自动调用__exit__,关闭文件
5. Python2,3的区别
  主要区别,
  1. 编码问题:2是ascii编码,3是utf8编码。
  2. 整数除法问题:2的整数相除得到整数,3得到浮点数

6. 垃圾回收机制与GRL锁
  垃圾回收机制:
  引用计数:
   变量值每被引用1次,计数加一,当引用计数为0时,变量值就会被解释器清除
   循环引用(引用计数存在的缺陷):两个列表相互引用,引用计数永远不为0
  标记清除:
   当内存达到一定程度时,Python程序停止运行,启动标记清除算法。
   先确定一个肯定不会被清除的变量,然后能够被他直接或间接访问到的标记为存活对象(不会被删除的变量,继续对其扫描),然后依次扫描,将不是存活对象的都清除掉
  分代回收:
   在经历多次扫描的情况下,都没有被回收的变量,认为它是常用变量,对其的扫描频率降低
   新生代:新定义的变量, 假设每5分钟扫描一次
  青春代:从新生代过来的变量, 假设10分钟扫描一次
  老年代:从青春代过来的变量,假设30分钟扫描一次

  GIL全局锁:
  GIL锁仅针对CPython解释器
    每个进程中的线程必须获得这个锁才能获得cpu等资源,然后执行,这导致了python同一进程下的线程不能使用多核同时执行

8. 常用模块
1. 爬虫相关:requests, BS4,selenium,
2. 图片处理:pillow  
3. 日历calendar,chinesecalendar
4. 连接数据库:pymysql
5. 数据分析包:numpy, pandas, matplotlib
6. re
7. xlwt,xlrd
8. datetime
9. traceback
10. os

9. 对于Python的理解

Python 是一种面向对象、解释型语言
代码简洁,写起来很快,很多第三方包
速度很慢

10. 进程,线程,协程

1. 线程锁
    python中有两种线程锁,Lock和Rlock,Lock不能多层嵌套,获取到一次,必须释放一次才能获取下一次锁。但是Rlock可以连续获取多次锁,然后只需多次释放锁即可
  单例模式,加线程锁
2. 进程
  多进程时:windows中启动方式是spawn,系统会新开一个解释器,然后从主进程复制必要的资源(能够让进程启动的资源),主进程与子进程管理各自的资源,互不干扰。
      在linux中,开启一个子进程,子进程会复制几乎所有的主进程的资源
,主进程与子进程管理各自的资源,互不干扰

 

11. 迭代器与生成器

可迭代对象与迭代器:https://blog.csdn.net/Q52099999/article/details/133041121
简单地说,列表,元组,字典,字符串等容器,含有__iter__方法的都叫可迭代对象,然后可迭代对象调用iter方法,就会返回一个迭代器,再次调用next方法就可以往下取值

  

12. 数据结构

13. 架构设计

https://github.com/xitu/system-design-primer#additional-system-design-interview-questions

14. mysql与pg的主要区别

pg对于数据的准确性,一致性执行较好。
mysql因为缺少上面的校验,性能较好
pg是多进程,mysql是多线程
pg支持json格式的存储

15, 读文件

为了不占用内存,推荐使用for,一行一行读
with open(path, 'rb') as infile:
    for line in infile:
        print(line)

 16. lambda函数

def multipliers():
    return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
#解释:
  函数返回值为一个列表表达式,经过4次循环结果为包含四个lambda函数的列表,
由于函数未被调用,循环中的i值未被写入函数,经过多次替代,循环结束后i值为3,
故结果为:6,6,6,6

列表生成式返回的是列表,列表生成器返回的是生成器,使用的时候一次一次的调用。区别是一个是[],一个是()
请修改multipliers的定义来产生期望的结果(0,2,4,6)。
def multipliers():
    return (lambda x:i*x for i in range(4))         #返回一个生成器表达式
print([m(2) for m in multipliers()])

 17.实现一个栈

# 实现一个栈stack,后进先出

'''
class Stack:
    def __init__(self):
        self.items = []

    def is_empty(self):
        # 判断是否为空
        return self.items == []

    def push(self,item):
        # 加入元素
        self.items.append(item)

    def pop(self):
        # 弹出元素
        return self.items.pop()

    def peek(self):
        # 返回栈顶元素
        return self.items[len(self.items)-1]

    def size(self):
        # 返回栈的大小
        return len(self.items)

if __name__ == "__main__":
    stack = Stack()
    stack.push("H")
    stack.push("E")
    stack.push("L")
    print(stack.size())  # 3
    print(stack.peek())  # L 
    print(stack.pop())   # L
    print(stack.pop())   # E
    print(stack.pop())   # H
'''

 18装饰器

@functools.wraps(func)

 19. yield

作为函数的返回值,每次调用返回一个值,然后阻塞,等待下一次调用。
协程会用到
参考:http://events.jianshu.io/p/dda2003e1aa2

 20. 定时任务APschduler

参考:https://zhuanlan.zhihu.com/p/491679794

 21. mysql死锁解决

1. 设计程序时,按照同一个顺序去获取锁
2. 加锁的时候,尽量将所有需要用到的资源一起加锁
3. 事务的持续时间尽可能的短

 22. 类的三大特性

1. 继承,子类继承父类的属性,代码复用
2. 封装,将属性和方法封装在类内,封装的属性会有私有,受保护,公有三种
3. 多态,子类可以重写父类的方法

 23. 上下文管理

写程序进行资源操作的时候,用完要及时释放,不然会造成资源泄露,就是资源一直被占着
参考:https://blog.csdn.net/qdPython/article/details/124198593

 24. 正则匹配

 

\w 字母数字下划线
\W 非~

\s 空白符
\S 非

\d 数字
\D 非

\n 换行符
 
\r 回车符

\t 制表符

{n, m} 匹配至少n次,至多m次

. 匹配除了\n之外的任何其他字符
* 0次或者多次
+ 1次或者多次
? 0次或者1次

 25 . select_related与prefetch_related

作用:减少查询次数
select_related针对一对一,多对一的关系进行查询,类似于sql的连表查询,直接将两张表的数据都同时取出来,这样就不用使用for循环一个一个查了。
prefetch_related针对一对多和多对多,相当于django帮你执行了多次sql,第一次是将主表的符合条件的数据取出来,然后用这个取出来的id,再去关联表中查数据,然后把两个sql执行的结果拼起来,再返回给你(想象多对多表的查询sql就很容易明白了)

 26. F与Q查询

F,可以在不取出数据的情况下,直接对数据库的字段进行操作。比如说对某个字段的值加10,或者两个字段的值做加减乘除等操作
Q,正常的查询filter中的筛选条件是and关系,Q可以指定多个条件之间是and还是or关系

 27. 服务器发布

使用nginx+uwsgi+django的方式
celery的worker和beat和uwsgi通过supervisor管理的
celery使用databaseSchduler调度
celery的启动配置:
  -A 固定的,代表celery实例本身
  -c 10 表示并发数10
  -l 后面跟日志等级
  -logfile 后面跟日志位置
  -worker, beat 启动类型

  

posted @ 2022-02-16 19:33  10132714  阅读(123)  评论(0编辑  收藏  举报