python常见面试题
数值类型,字符串,列表,字典,元组,集合
可变类型: 集合,列表,字典
不可变类型: 字符串,元组,数值
可变数据类型:当数据类型对应的变量的值发生改变的时候,其对应的内存地址不变
不可变数据类型:当该数据类型对应的变量的值发生改变的时候, 其所对应的内存地址发生改变
is比较的是两个对象的地址值,也就是说两个对象是否为同一个实例对象;而==比较的是对象的值是否相等,其调用了对象的__eq__()方法。
*args:可选的位置参数
**kwargs: 可选的关键词参数
python中默认的函数参数顺序: 必选参数,默认参数,位置参数,关键词参数
__new__(): new的作用是创建一个类的实例化对象
__init__():对new创建的实例进行初始化
默认继承第一个父类的同名方法
1 什么是锁?
全局解释器锁(GIL),在同一个进程中只要有一个线程获得了全局解释器(cpu)的使用权限,那么其他的线程就必须等到该线程的全局解释器(cpu)的使用权小时候,才能使用全局解释器。
2 全局解释器锁的好处?
a. 避免了大量的加锁解锁
b. 是数据更加安全,解决多线程间数据完整性和状态同步
3 全局解释器锁的缺点
多核处理器退化为单核处理器,只能并发不能并行
(同一时刻的某个进程下的某个线程只能被一个cpu所处理,所以在GIL锁下的线程只能被并发,不能被并行)
4 出现死锁的原因?
当多个线程同时获取多个锁的时候,容易造成资源的相互竞争,一个线程一直阻塞等待另一个线程释放锁,造成死锁。
# coding:utf-8
import threading
import time
if __name__ == '__main__':
x_lock = threading.Lock()
y_lock = threading.Lock()
# def thread_1():
# while True:
# with x_lock:
# print("thread_1 acquire x_lock, sleep: %s s" % 1)
# with y_lock:
# print("thread_1 acquire y_lock...")
# time.sleep(1)
#
# def thread_2():
# while True:
# with y_lock:
# print("thread_2 acquire y_lock, sleep: %s s" % 1)
# while x_lock:
# print("thread_2 acquire x_lock...")
# time.sleep(1)
#
#
# t1 = threading.Thread(target=thread_1)
# t1.start()
# t2 = threading.Thread(target=thread_2)
# t2.start()
x_lock = threading.Lock()
y_lock = threading.Lock()
def thread_3():
while True:
x_lock.acquire()
print("thread_3 acquire x_lock, sleep: %s s" % 1)
time.sleep(1)
y_lock.acquire()
print("thread_3 acquire y_lock...")
time.sleep(1)
y_lock.acquire()
x_lock.acquire()
def thread_4():
while True:
y_lock.acquire()
print("thread_4 acquire y_lock, sleep: %s s" % 1)
x_lock.acquire()
print("thread_4 acquire x_lock...")
time.sleep(1)
x_lock.acquire()
y_lock.acquire()
t3 = threading.Thread(target=thread_3)
t3.start()
t4 = threading.Thread(target=thread_4)
t4.start()
####################################result#######################################
thread_3 acquire x_lock, sleep: 1 s
thread_4 acquire y_lock, sleep: 1 s
可以发现发生了死锁:
thread_3在获取 y_lock 的锁的时候, 发现该锁已经被 thread_4 获取了, 造成 thread_3 一直在等待 y_lock.
thread_4在获取 x_lock 的锁的时候, 发现该锁已经被 thread_3 获取了, 造成 thread_4 一直在等待 x_lock.
1. 获取锁的时候加一个超时参数, 例如 lock.acquire(timeout=10)
2. 为程序中的每一个锁分配一个唯一的id
方法: 使用上下文管理器
# coding: utf-8
import threading
import time
from contextlib import contextmanager
# Thread-local state to stored information on locks already acquired
_local = threading.local()
@contextmanager
def acquire(*locks):
# Sort locks by object identifier
locks = sorted(locks, key=lambda x :id(x))
# Make sure lock order of previously acquired locks is not viloated
acquired = getattr(_local, "acquired", [])
if acquired and max(id(lock) for lock in acquired) >= id(locks[0]):
raise RuntimeError('Lock Order Violation')
# Acquire all of the locks
acquired.extend(locks)
_local.acquired = acquired
print("acquired: %s" % acquired)
try:
for lock in locks:
print("acquired lock: %s" % lock)
lock.acquire()
yield
finally:
# Release locks in reverse order of acquisition
for lock in reversed(locks):
lock.release()
del acquired[-len(locks):]
if __name__ == '__main__':
x_lock = threading.Lock()
y_lock = threading.Lock()
def thread_1():
while True:
try:
with acquire(x_lock, y_lock):
print("thread_1 acquired x_lock, y_lock: ", getattr(_local, "acquired", []))
time.sleep(1)
except:
print("thread_1 lock error")
# time.sleep(1)
def thread_2():
time.sleep(0.5)
while True:
try:
with acquire(y_lock, x_lock):
print("thread_2 acquired y_lock, x_lock: ", getattr(_local, "acquired", []))
time.sleep(1)
except:
print("thread_2 lock error")
# time.sleep(1)
# print("_local acquired: %s" % getattr(_local, "acquired", []))
t1 = threading.Thread(target=thread_1)
t1.start()
t2 = threading.Thread(target=thread_2)
t2.start()
s="hfkfdlsahfgdiuanvzx"
# 方法 1
result = "".join(set(s))
# 方法 2
list1 = list(set(s))
result = sorted(list1, key=lambda x: ord(x)) # 或者 sorted(list1) 从小到大
result = sorted(list1, key=lambda x: -ord(x)) # 从大到小
换个问法: s 和 t 是否是同构的
ssss