深拷贝和浅拷贝
比如一个list里嵌套一个list
解释:1浅拷贝最常见的是切片,只要把list切片赋值给另外一个list01,那么就是浅拷贝。浅拷贝只拷贝了最外层list的地址,里面嵌套的list的地址在内存中是共同被双方指向它的。
2深拷贝需要导包,深拷贝是把所有数据全部拷贝一份过来,包括嵌套的。
import copy#深拷贝语法
copy.deepcopy(list)
各有什么优点和缺点:
优点:浅拷贝占用内存少,深拷贝数据之间互不影响。
缺点:深拷贝占用内存多,浅拷贝如果深度修改数据会相互影响。
适用性
当没有深度数据或深度数据不会变时,使用浅拷贝,否则使用深拷贝
列表与字符串的相互转换
1,列表转换为字符串
字符串变量 = 连接符.join(列表)
2,字符串转为列表
列表变量 = 'a-b-c-d'.split('分隔符')
容器总结
一,种类与特点
字符串:储存字符的地址,不可变,有序
列表:储存地址,可变,有序
元祖:储存地址,不可变,有序
字典:存储字符串,键不可变,值随便,有序(3.6版本之前是无序的),键自动去重。
集合:可变,无序,自动去重。
二,可变与不可变。
面试题1:python有多少种数据类型?
答:只有两种,根据内存存储机制可分为可变与不可变。
可变:预留空间+自动扩容,例如:list,dict,set等。
不可变:按需分配,例如:str,数值,bool,tuple等。
面试题2:既然有可变数据,为什么还要有不可变数据?
不可变数据占用内存少,相对于来说性能会更高,应该优先选择。
选择排序
list = [5,566,4]
for i in range(len(list)-1):
for j in range(i+1,len(list)):
if list[i]>list[j]:
list[i],list[j] = list[j],list[i]
print(list)
冒泡排序
# 笔试题:自定义排序算法
# 传统写法
for i in range(len(list)-1):
for j in range(i+1,len(list)):
if list[i]>list[j]:
list[i],list[j] = list[j],list[i]
# 函数式编程思想
# 数据灵活 行为灵活
def sort(target, condition):
"""
对任意元素任意条件排序算法
:param target:具有任意元素的列表
:param condition:函数类型的条件
"""
for r in range(len(target) - 1):
for c in range(r + 1, len(target)):
if condition(target[r], target[c]):
target[r], target[c] = target[c], target[r]
list01 = [4, 5, 6, 6, 7, 8, 9, 0]
sort(list01, lambda a, b: a < b)
print(list01)
sort(list01, lambda a, b: a > b)
print(list01)
面向对象
- 字面意思:考虑问题从对象的角度出发
- 思考流程:现实事物 -抽象化-> 类 -具体化-> 对象
- 三大特征:
封装[分]:分而治之,(行为)变则疏之
例如:创建人类/汽车/飞机
继承[隔]:统一变化,隔离变化
例如:创建交通工具,在运输行为上约束汽车/飞机
人类获得了一种使用方式
多态[做]:继承将相关类型的共性进行统一
例如:火车汽车都有运输方法
多态在继承基础上体现类型的个性
例如:火车汽车通过重写实现自己的运输方式 - 设计原则:
开闭原则:可以增加新功能,但不修改客户端代码
例如:增加轮船,人类不需要发生变化
单一职责:一个类有且只有一个改变的原因
依赖倒置:客户端代码使用父类不使用子类
子类看着父类写代码
例如:人类使用交通工具而不是使用火车汽车
组合复用:如果仅仅是代码的复用,
优先使用组合关系,
而不是继承关系.
继承语义-是一种
组合语义-有一个
例如:人类通过变量调用运输函数,而不是通过继承.
迪米特:低耦合
例如:人类与火车汽车被交通工具隔离
里氏替换:
形参是父类型,实参可以任意子类型
子类重写时建议先super()调用父方法
迭代
每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
"""
迭代 iteration:重复获取下一个元素的过程
可迭代 iterable:可以被迭代,能够参与for循环
迭代器 iterator:完成迭代过程的对象
"""
a = [1, 2, 3, 4, 5]
# 迭代(for循环原理)
# 1. 获取迭代器对象
b = a.__iter__()
while True:
try:
# 2. 获取下一个元素
c = b.__next__()
print(c)
# 3. 如果停止迭代异常,结束循环
except StopIteration:
break
##################################################################
#下面是上面的原理
class B():
def __init__(self, __list_b):
self.__list_b = __list_b
self.b = -1
def __next__(self):
self.b += 1
if self.b == len(self.__list_b):
raise StopIteration()
return self.__list_b[self.b]
class A():
def __init__(self):
self.__list_a = []
def add(self, param):
self.__list_a.append(param)
def __iter__(self):
return B(self.__list_a)
a = A()
a.add(1)
a.add(2)
a.add(3)
a.add(4)
a.add(5)
b = a.__iter__()
while True:
try:
c = b.__next__()
print(c)
except StopIteration:
break
面试题:
对象能够参与for循环的条件是什么?
答1:对象必须具备__iter__函数
答2:对象必须是可迭代对象
为什么存在多种数据类型?
1,不同数据类型在内存中分配的空间大小不同
2,不同类型行为不同(具有的内置方法不同,
对象池:每次创建数据时,都判断池中是否
具有相同数据.如果没有则开辟空间存储。
如果有则直接返回内存地址,不再重复存储.
data06 = "悟空"
data07 = "悟空"
print(id(data06))
print(id(data07))
Python自动内存管理机制
--引用计数:每个对象记录被变量绑定的数量,
当为0时被销毁。
缺点:循环引用
--标记清除:扫描全部内存空间,
检查不在使用的数据.
缺点:耗时长
--分代回收:将全部内存分为小中大三代.
每次创建新数据时,都在小代分配空间.
当内存告急时,再触发标记清除,
将有用的数据升代,没用的数据销毁.
优化内存:
尽少产生垃圾、自定义对象池、配置垃圾回收器
网络通信
理论问题: 1. OSI七层模型和TCP/IP模型
2. 三次握手和四次挥手
3. tcp与udp对比
进程线程
理论问题 :对比进程线程特点
IO
理论问题: 说说epoll和select的区别
网页的访问流程