1.如何区别可变数据类型和不可变数据类型
对象的内存地址方向
- 可变数据类型
- 内存地址不变 值是可以改变的,list dict set
- 不可变数据类型
- 内存地址改变,值也跟着变化,int str tuple bool
2.Python 垃圾回收机制?
- 引用计数机制
遇到循环引用时可以使用下面两种方法 - 标记-清除
- 分代回收
3. Python中会有函数或成员变量包含单下划线前缀和结尾,和双下划线前缀结尾,区别是什么?
- __私有成员
- _保护变量
class Person(object):
def __init__(self):
self.__age = 12
self._age = 13
def _ages(self, age):
self.__age = age
def set_age(self):
pass
def get_age(self):
pass
if __name__ == '__main__':
p = Person()
# print(p.__age) # 私有成员,访问将会报错
# print(p._Person__age) # 访问私有成员方法,但尽量不要使用,因为设置为私有成员就是不希望我们进行访问
# print(p._age) # 保护变量,不希望我们进行修改的变量,但只是一种不成文的规定
4.如何判断一个对象是函数还是方法?
通过types模块中的MethodType(判断是不是方法)和FunctionType(判断是不是函数)
from types import MethodType,FunctionType
class Demo(object):
def foo1(self):
pass
def foo2():
pass
print(isinstance(Demo().foo1, FunctionType)) # False
print(isinstance(Demo().foo1, MethodType)) # True
print(isinstance(foo2, FunctionType)) # True
print(isinstance(foo2, MethodType)) # False
5. super函数的用法
- 调用父类中的方法 实际按照mro算法调用
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
print("B")
super().__init__()
class C(A):
def __init__(self):
print("C")
super().__init__()
class D(B, C):
def __init__(self):
print("D")
super().__init__()
if __name__ == '__main__':
d = D() # D B C A Object
print(D.__mro__)
6.使用isinstance和type的区别
- isinstance考虑类的继承关系
- type不会考虑类的继承关系
7.创建大量实例节省内存
__slots__ = [] ()
单例模式-只实例化一次
8.上下管理器
__enter__
__exit__
class Sample(object):
def __enter__(self):
# 可以获取资源
print('start')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 释放资源
print('end')
# 异常
def demo(self):
print('demo')
with Sample() as f:
f.demo()
9.判断一个对象中是否具有某个属性
- hasattr(object, name)
class Demo(object):
name = 'dog'
def run(self):
return 'hello'
d = Demo()
print(hasattr(d, 'name')) # True
print(hasattr(d, 'run')) # True
print(hasattr(d, 'age')) # False
10.property动态属性的使用
- 装饰器
- get set
# get set 方式
class C(object):
def getx(self): return self._x
def setx(self, value): self._x = value
def delx(self): del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
# Decorators make defining new properties or modifying existing ones easy:
# 装饰器方式
class C(object):
@property
def x(self):
"I am the 'x' property."
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
11.如何使用type创建自定义类
type(name, bases, attr)
name 表示类名称 字符串
bases 继承对象的元组
attr 属性 类属性 类方法 静态方法 字典
12.生成器的创建
- yield
- ()
send 方法 - next
- send
- 如果前面没有调用next的情况下, 第一次必须传None
13.TCP 和 UDP 的区别?
- TCP面向连接 UDP是无连接
- TCP安全可靠 UDP 不保证可靠
- UDP实时性
- TCP是点到点 UDP 支持一对一 一对多
- TCP对系统资源要求较多
14.TCP服务端通信流程
- 创建socket套接字
- 绑定IP和PORT
- listen
- accept等待客户端连接
- 收发数据
15.创建线程的两种方式
- 普通创建 threading
- 类的继承 threading.Thread
import threading
import time
class A(threading.Thread):
def __init__(self, name):
super().__init__(name=name)
def run(self):
for i in range(5):
print(i)
if __name__ == '__main__':
t = A('dog')
t.start()
16.解释线程资源竞争,以及解决方案
a+=1
mutex = threading.Lock()
mutex = threading.RLock() 可重入的锁 多次上锁
mutex.acquire() 加锁
mutex.release() 解锁
17.进程之间的通信,以及进程池中的进程通信
进程之间的通信
multiprocessing.queue
进程池中的进程通信
multiprocessing.Manger.Queue
18.进程、线程、协程对比
- 进程是资源分配的单位
- 线程是操作系统调度的单位
- 进程切换需要的资源比较大
19.使用async和await实现协程
import time, asyncio, random
async def demo(alist):
while len(alist) > 0:
c = random.randint(0, len(alist)-1)
print(alist.pop(c))
await asyncio.sleep(1)
s = ['a', 'b', 'c']
i = [1, 2, 3]
c1 = demo(s)
c2 = demo(i)
if __name__ == '__main__':
# 创建事件loop
loop = asyncio.get_event_loop()
# 任务
tasks = [c1, c2]
# 将协程加入到事件循环中
loop.run_until_complete(asyncio.wait(tasks))
loop.close()