面试题锦集

第一部分 Python基础篇(80题)
1. 为什么学习Python?
IT行业是目前乃至以后的趋势,并且我也对IT行业有浓厚的兴趣,现在都是实体与互联网相结合,生活中小到扫码付款,大到淘宝京东,甚至买房都可以在通过互联网实现,而我从知乎和其他网站了解到的,
在众多语言当中,python是未来语言,python不仅可以写网站,前后端交互,还涉及人工智能,金融,爬虫,人脸识别等等,美国早在几年前就将python纳入大学的基本课程,现在中国杭州和一些试点城市,
从小学都开始普及Python课程,所以我要学习Python。
2. 通过什么途径学习的Python?
在学校期间无意间看到别人在弄这个人脸识别,通过一张照片能分辨出性别,年龄范围和颜值,然后就从网上搜了一下python,发现有好多的文档和路飞学诚等都有python的课程与讲解,
让后我通过阅读相关书籍以及网上的一些课程进行学习。
3.Python和Java、PHP、C、C#、C++等其他语言的对比?
python,php是解释性语言,代码运行期间逐行翻译成目标机器码,下次执行时逐行解释
而C、Java是编译型语言,编译后再执行。
python和以上语言对比,第一点开发效率快,有非常强大的第三方模块支持,第二点语法清晰简单,第三点有非常强大的跨平台和扩展性
4.简述解释型和编译型编程语言?
编译型:运行前先由编译器将高级语言代码编译为对应机器的cpu汇编指令集,再由汇编器汇编为目标机器码,生成可执行文件,然最后运行生成的可执行文件。最典型的代表语言为C/C++,一般生成的可执行文件及.exe文件。 

解释型:在运行时由翻译器将高级语言代码翻译成易于执行的中间代码,并由解释器(例如浏览器、虚拟机)逐一将该中间代码解释成机器码并执行(可看做是将编译、运行合二为一了)。最典型的代表语言为JavaScript、Python、Ruby和Perl等。 

总结:
    编译型的语言就类似于去饭店点菜,菜上来了就吃
    解释型的语言就类似于去饭店吃火锅,以一边吃一边涮
解释性:边解释变执行(py,php)
编译型:编译后再执行(jaca,c,c#)"""
5.Python解释器种类以及特点?
CPython:# c语言开发的,官方推荐,最常用
   当 从Python官方网站下载并安装好Python2.7后,就直接获得了一个官方版本的解释器:Cpython,这个解释器是用C语言开发的,所以叫 CPython,在命名行下运行python,就是启动CPython解释器,CPython是使用最广的Python解释器。
IPython:# 基于CPython之上的交互式解释器,只是在交互上有增强
   IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的,好比很多国产浏览器虽然外观不同,但内核其实是调用了IE。
JPython:JAVA写的解释器
   PyPy # 是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,对Python代码进行动态编译,所以可以显著提高Python代码的执行速度。
Pypy:python写的解释器,目前执行速度最快的解释器,采用JTT技术,对python进行动态编译
IronPython:c#写的解释器
  IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。
  在Python的解释器中,使用广泛的是CPython,对于Python的编译,除了可以采用以上解释器进行编译外,技术高超的开发者还可以按照自己的需求自行编写Python解释器来执行Python代码,十分的方便!
Qpython
安卓端的一个python解释器,Qpython是一种通用叫法,其实它分为两款,分别是Qpython和Qpython3分别对应的是python2和python3
6.位和字节的关系?
1字节=8位
1byte=8bit(数据储存以字节为单位)
7.b、B、KB、MB、GB 的关系?
1B=8bit;
1KB=1024B
1MB=1024KB
8.请至少列举5个 PEP8 规范(越多越好)。
空格使用
    各种右括号前不要加空格
    逗号,冒号,分号前不要加空格
    函数的左括号前不要加空格func(1)
    序列的左括号前不要加空格list[1,2]
    操作符左右各加一个空格,不要为了对齐增加空格
    函数默认参数使用的赋值符左右省略空格
    不要将多句语句写在同一行,尽管使用;
    if/for/while语句中,即使执行语句只有一句,也必须另起一行
代码编排
    缩进,四个空格,而不是tab键
    每行长度79,换行可使用反斜杠,做好使用圆括号
    类与类之间空两行
    方法之间空一行

1.缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。
2.每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。
3.类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行
4.注释 总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释!注释必须使用英文,最好是完整的句子,首字母大写,句后要有结束符,结束符后跟两个空格,开始下一句。如果是短语,可以省略结束符。
块注释,在一段代码前增加的注释。在‘#’后加一空格。段落之间以只有‘#’的行间隔。
行注释,在一句代码后加注释。比如:(但是这种方式尽量少使用)
避免无谓的注释
5.文档描述为所有的共有模块、函数、类、方法写docstrings;非共有的没有必要,但是可以写注释(在def的下一行)。
如果docstring要换行
6.命名规范总体原则,新编代码必须按下面命名风格进行,现有库的编码尽量保持风格。
尽量单独使用小写字母‘l’,大写字母‘O’等容易混淆的字母。
模块命名尽量短小,使用全部小写的方式,可以使用下划线。
包命名尽量短小,使用全部小写的方式,不可以使用下划线。
类的命名使用CapWords的方式,模块内部使用的类采用_CapWords的方式。
异常命名使用CapWords+Error后缀的方式。
全局变量尽量只在模块内有效,类似C语言中的static。实现方法有两种,一是all机制;二是前缀一个下划线。
函数命名使用全部小写的方式,可以使用下划线。
常量命名使用全部大写的方式,可以使用下划线。
类的属性(方法和变量)命名使用全部小写的方式,可以使用下划线。
类的属性有3种作用域public、non-public和subclass API,可以理解成C++中的public、private、protected,non-public属性前,前缀一条下划线。
类的属性若与关键字名字冲突,后缀一下划线,尽量不要使用缩略等其他方式。
为避免与子类属性命名冲突,在类的一些属性前,前缀两条下划线。比如:类Foo中声明__a,访问时,只能通过Foo._Foo__a,避免歧义。如果子类也叫Foo,那就无能为力了。
类的方法第一个参数必须是self,而静态方法第一个参数必须是cls。
具体详情请查看
9.通过代码实现如下转换:
  二进制转换成十进制:v = “0b1111011”

  十进制转换成二进制:v = 18

  八进制转换成十进制:v = “011”

  十进制转换成八进制:v = 30

  十六进制转换成十进制:v = “0x12”

  十进制转换成十六进制:v = 87
print(int(0b1111011))  # 123=(1+2+2**3+2**4+2**5+2**6),0b是二进制符号,不参与运算
print(bin(18))  # 0b10010
print(int("011"))  # 11
print(oct(30))  # 0o36
print(int(0x12))  # 18
print(hex(87))  # 0x57

相关知识点

# bin(18) 将整数转换为2进制   0b 二进制标识符
# oct(30)转整数转换为8进制   0o 八进制标识符
# hex(87) 转整数转换为16进制  0x 十六进制标识符
# hex(integer) 将integer转换为16进制,形式为0x0123456789abcdef。integer必须为整型
print(hex(87))  # 0x57
# otc(integer) 将integer转换为8进制
print(oct(30))
# bin(integer) 将integer转换为2进制
print(bin(18))
# format(integer, 'x') 将integer转换为16进制,不带0x。integer为整型,'x'可换为'o','b','d'相对应八、二、十进制。
print(format(10,'x'))  # a  转化为16进制的数
print(format(10,'o'))  # 12   转化为8进制的数
print(format(10,'b')) # 1010  转化为2进制的数
print(format(10,'d'))  # 10  转化为10进制的数

# int(string, number)将任意进制的s(string类型)转换为十进制。s与number的进制类型需匹配,如s是16进制,则number = 16,否侧会出错。若s为16进制,0x可带可不带,其他进制同。

print(int("011",8))
print(int("0x12",16))
print(int("12",16))
# 若string前面带有表示进制的符号,可以用int直接转
print(int(0o011))
print(int(0x12))
10.请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010

 3 00000011

9 00001001

 12 00001100

再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
ip = "10.3.9.12"


def ip_to_int(ip):  # 将ip转化为整数
    ip_list = ip.split('.')
    sum = 0
    for i in range(4):  # 0,1,2,3
        sum = sum + int(ip_list[i]) * 256 ** (3 - i)  # 相当于256进制的数在向10进制转化,这里只有4位,前4位均为0
    return sum


num = ip_to_int(ip)


# print(ret)
# num = 167971084

def int_to_ip(sum):
    int_list = []
    ys = sum
    for i in reversed(range(4)):  # 3,2,1,0
        res = divmod(ys, 256 ** i)
        int_list.append(str(res[0]))
        ys = res[1]
    return ".".join(int_list)


a = int_to_ip(num)
print(a)
11.python递归的最大层数?
python默认是998层,实际和计算机性能关系很大,windows一般再3000多,MAC一般在1万以上
12.求结果:
  v1 = 1 or 3
                1
    v2 = 1 and 3
               3
    v3 = 0 and 2 and 1         0

    v4 = 0 and 2 or 1          1

    v5 = 0 and 2 or 1 or 4     1

    v6 = 0 or Flase and 1      Flase
    
   # 优先级:()>not>and>or
   #a or b
        #a为真,返回a,否则返回b
   # and 相反,记住一个算法就行
13.ascii、unicode、utf-8、gbk 区别?
ASCII:
       由于计算机是美国人发明的,因此最早只把127个字符编码到计算机里,即大小写英文字母、数字、部分西欧字符和一些常用符号等。
ASCII码只需要1个字节(1byte=8bit)即可存放。
Unicode:
       如果想要处理非ASCII码表里的字符,显然1个字节是不够用的,因此,中国将中文字符编入了GB2312,日本将日文编入了Shift-JIS、韩国将韩文编入了Euc-kr,其他国家也有自己的编码,
这样做的结果就是如果将含有多种编码格式的字符存放到同一个文本里,就会出现令人头痛的乱码问题(乱码问题本质就是解码的字典不同导致的。) 鉴于上述原因,Unicode应运而生,它将所有字符都统一编入在一个字典里,之前用2个字节表示一个字符,后来发现两个字节不能表示全部字符后来改为4个字节表示一个字符,
这样再也不用担心不同的字符集里的字符放在一起出现乱码的问题了。所以现在Unicode是有两个版本,之前的版本是2个字节表示一个字符,现在是4个字节表示一个字符,
python3x使用的unicode全部是4个字节表示一个字符。 Unicode和ASCII的区别就是:
1,前者是用4个字节(或者2个字节)表示一个字符,后者是用1个字节表示的。 2,前者叫万国码,包含有记录的所有的文字,而后者只包含数字,字母,特殊符号。 UTF-8: Unicode的出现似乎完美的解决了乱码问题,但是会带来一个新的问题:如果你的文本基本全是英文或数字,那么用Unicode存储会比ASCII存储多出几倍的空间,而且传输起来也不划算(要占用更多的带宽),
怎么办呢?能不能根据字符的种类来决定采取占用的字节呢? 回答是可以的,这就是UTF
-8,也就是“可变长编码”,它能根据Unicode字符的种类来决定存储的长度,例如:常用的英文编码成1个字节,汉字编码成3个字节 如果你的文本里含有大量的英文字符、数字、常用符号,那么使用UTF-8将会节省大量的存储空间,传输起来也会快很多 GB2312和GBK: GB2312是中国自己发布的一套汉字编码规范,于1980年发布。而GBK是中国在1995年颁布的,它向下兼容了GB2312,还向上兼容了ISO国际标准(ANSI),包含的字符更多了。
但是无论是GBK,还是GB2312,都只是
'国标',他只包含常用中文,数字,字母,特殊符号。 8位表示1个字节 Ascii:1个字节表示1个字符,支持英文 unicode:4个字节表示1个字符 utf-8: 英文:1个字节表示1个字符 欧洲:2个字节表示1个字符 亚洲:3个字节表示1个字符 gbk: 英文:1个字节表示1个字符 中文:2个字节表示1个字符
14.字节码和机器码的区别?
字节码:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码
机器码:电脑的CPU可直接解读的数据,是计算机可以直接执行,并且执行速度最快的代码。
机器码

机器码 学名机器语言指令,白话文就是计算机能够识别的一种指令.比如
我们在程序中写hello world其实就是将我们人类能够识别的内容转换成计算机能够识别的01010101

字节码 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。

总结:
    机器码就是交于cpu运行的一种文件
    字节码是一种中间状态(中间码)的二进制文件,需要转译后才能成为机器码。
15.三元运算规则以及应用场景?
做简单逻辑判断的时候用到
c=a if a>b else b  # 如果a大于1的话,c=a,否则c=b
16.列举 Python2和Python3的区别?
print:
    py2:print 内容
    py3:print(内容)
编码:
    py2默认unicode
    py3默认utf-8
字符串:
    py2:
        ascii:8位表示一个字符
        unicode:16位表示一个字符
    py3:都是unicode字符串
True和False:
        py2:是两个全局变量(1和0),可以重新赋值
        py3:两个关键字,不能重新赋值
迭代:
    py2:xrange
    py3:range
nonlocal:
    py3:专有的(声明为非全局变量)
    # nonlocal  适用于在局部函数 中 的局部函数, 把最内层的局部 变量设置成外层局部可用,但是还不是全局的。
    # global 定义的变量,表明其作用域在局部以外,即局部函数执行完之后,不销毁
经典类,新式类:
    py2:经典类和新式类并存
    py3:新式类默认继承object
yield:
    py2:yield
    py3:yield/yield from
文件操作:
    py2:readlines() 读取文件的所有行,返回一个列表,包含所有行的结束符
        xreadlines() 返回一个生成器,循环取值
    py3:只有readlines()
long:
    py3:
        没有long(长整型),统一使用int,范围和py2中long的范围相似
    py2:
        int最大不能超过sys.maxint,根据不同平台大小不同
        在int类型数字后面加L定义长整型,范围比int
17.用一行代码实现数值交换:
a=1
b=2
a,b=b,a
print(a,b)
18.Python3和Python2中 int 和 long的区别?
py3:
    没有long(长整型),统一使用int,范围和py2中long的范围相似
py2:
    int最大不能超过sys.maxint,根据不同平台大小不同
    在int类型数字后面加L定义长整型,范围比int大
19. xrange和range的区别?
xrange:
    产生的是生成器,通过yield每次返回一个,数据较大时,xrange比较好,
range:
    产生的是列表,把数据一次性返回

 1) read([size])方法从文件当前位置起读取size个字节,若无参数size,则表示读取至文件结束为止,它范围为字符串对象
    2) 从字面意思可以看出,该方法每次读出一行内容,所以,读取时占用内存小,比较适合大文件,该方法返回一个字符串对象。
    3) readlines()方法读取整个文件所有行,保存在一个列表(list)变量中,每行作为一个元素,但读取大文件会比较占内存。
    4)xreadlines()方法则是直接返回一个iter迭代器,在python2.3之后就不推荐这种方法了。
    for line in f:
      拿到每一行数据
20.文件操作时:xreadlines和readlines的区别?
xreadlines:返回一个生成器,循环使用,和readlines基本一致(py2有,py3没有)
readlines:读取文件的所有行,返回一个列表,包含所有行的结束符
21.列举布尔值为False的常见值?
布尔型,False表示False,其他为True
  整数和浮点数,0表示False,其他为True
  字符串和类字符串类型(包括bytes和unicode),空字符串表示False,其他为True
  序列类型(包括tuple,list,dict,set等),空表示False,非空表示True
  None永远表示False
22.字符串、列表、元组、字典每个常用的5个方法?
str:
    split:分割
    strip:去掉两边的空格
    startwith:以什么开头
    endwith:以什么结尾
    lower:大写
    upper:小写
    join:将可迭代的对象变成字符串
list:
    append:追加
    insert:插入
    reverse:反转
    index:索引
    copy:浅拷贝
    pop:删除指定索引处的值,不指定索引,默认删除最后一个
tuple:
    count:查看某个元素出现的次数
    index:索引
dict:
    get:根据key获取value,获取不到报错
    items:用于循环,取出所有的key和value
    keys:取出所有的key
    values:取出所有的value
    clear:清空字典
    pop:删除指定键对应的值,有返回值(对应的值)。
23.lambda表达式格式以及应用场景?
格式
    匿名函数:res=lambda x: i*x  print(res(2))
应用场景
    filter(),map(),reduce(),sorted()函数中经常用到,它们都需要函数形参
    一般定义调用一次
    reduce() 对参数序列中元素进行积累,接收两个参数

省去函数命名的烦恼
 lambda存在意义就是对简单函数的简洁表示
 列表生成式配合
  min/max/filter/map/sorted/reduce  
  
  min:(最小的)
      li = [-1,2,-3,4]
      s = min(li,key=lambda x:x)
  max:(最大的)
      li = [-1,2,-3,4]
      s = max(li,key=lambda x:x)
      print(s)
  filter:(过滤)
      li = [-1,2,-3,4,8,9,-4]
      s = list(filter(lambda x:x >3,li))
  map:(映射)
      li = [1,2,3]
      s = list(map(lambda x,y,z:x*y*z,li,li,li))
  sorted:(排序)
    dic = {'a1':44,'a2':33}
    s = sorted(dic.items(),key=lambda x:x[1])
    这样是将按照字典的值中小的排序,返回的是一个列表中有多个元祖
    s = sorted(dic.items(),key=lambda x:x[1],reverse=True)   
    这样是将按照字典的值中大的排序,返回的是一个列表中有多个元祖  
    
  reduce:(归纳)  
    python2:
        python2中reduce是内置方法
        li = [6,2,3,4,5]
        s = reduce(lambda x,y:x+y,li)
        
    python3:
        python3中reduce方法内置到functools中
        from functools import reduce
        li = [6,2,3,4,5]
        s = reduce(lambda x,y:x+y,li)
24.pass的作用?
pass一般用于站位语句,保持代码的完整性,不会做任何操作
当你在编写一个程序时,执行语句部分思路还没有完成,这时你可以用pass语句来占位,也可以当做是一个标记,是要过后来完成的代码。
程序当中 ... 功能和pass功能一样
25.*arg和**kwarg作用
他们是动态参数,一般不确定要传入几个参数时,可以使用他们定义参数
*args:位置参数,按照位置传参,将传入的参数打包成一个元祖,打印参数类型文元组
**kwargs:关键字参数,在位置参数之后。按照关键字传参,将传入的参数打包成一个字典

 *args:(表示的就是将实参中按照位置传值,多出来的值都给args,且以元组的方式呈现)在形参表示聚合, 在实参表示打散
  **kwargs:(表示的就是实参中按照关键字传值把多余的传值以字典的方式呈现)在形参表示聚合, 在实参表示打散
26.is和==的区别
is和===意思是一样的 :比较的是内存地址
==:比较的是数值是否相等
is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。莱布尼茨说过:“世界上没有两片完全相同的叶子”,这个is正是这样的比较,比较是不是同一片叶子(即比较的id是否相同,这id类似于人的身份证标识)。
  == 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。这里比较的并非是同一片叶子,可能叶子的种类或者脉络相同就可以了。默认会调用对象的 __eq__()方法。
  
 总结:
     == 是比较这俩个人长的是不是一样
     is 是比较这俩个人是不是一个人
27.简述Python的深浅拷贝以及应用场景?
浅拷贝:
    不管多么复杂的数据结构,只copy对象最外层本身,该对象引用的其他对象不变
    内存里两个变量的地址是一样的,一个改变,另外一个也改变。
深拷贝:
    完全复制原数据的所有数据,内存中生成一套完全一样的内容,只是值一样,内存地址币一样,
  一方修改,另一方不受影响

  Python采用基于值得内存管理模式,赋值语句的执行过程是:首先把等号右侧标识的表达式计算出来,然后在内存中找一个位置把值存放进去,最后创建变量并指向这个内存地址。Python中的变量并不直接存储值,而是存储了值的内存地址或者引用
  简单地说,浅拷贝只拷贝一层(如果有嵌套),深拷贝拷贝所有层。
  一层的情况:
    import copy
    # 浅拷贝  
    li1 = [1, 2, 3]
    li2 = li1.copy()
    li1.append(4)
    print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]
    # 深拷贝
    li1 = [1, 2, 3]
    li2 = copy.deepcopy(li1)
    li1.append(4)
    print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]
  多层的情况:
    import copy
    # 浅拷贝
    li1 = [1, 2, 3, [4, 5], 6]
    li2 = li1.copy()
    li1[3].append(7)
    print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]
    # 深拷贝
    li1 = [1, 2, 3, [4, 5], 6]
    li2 = copy.deepcopy(li1)
    li1[3].append(7)
    print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]
    
    应用场景:项目中的配置文件。
28.Python垃圾回收机制?
#python垃圾回收机制,主要使用"引数计数"来跟踪和回收垃圾
#在"引数计数"的基础上,通过"标记-清除"(mark and sweep)解决容器对象可能产生的循环引用问题
#通过"分代回收"以空间换时间的方法提高垃圾回收效率

#"引数计数"
pyobject是每个对象必有的内容,其中ob_refcnt就是作为引用计数。
当一个对象有新的引用时,他的ob_refcnt就会增加,
当引用他的对象被删除,他的ob_refcnt就会减少,
引用计数为零时,该对象的生命就结束了
    优点:简单,实时性
    缺点:维护引用计数消耗资源,循环引用

#"标记-清除机制"
基本思路是,先按零分配,等到没有空闲内存的时候,从寄存器和程序栈上的引用出发,
遍历以对象为节点,以引用为边构成的图,把所有可以访问到的对象打上标记,
然后清扫一遍内存空间,把所有没标记的对象释放

#"分代技术"
分代回收的整体思想是:
将系统中所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个""
垃圾收集频率随着""的存活时间的增大而较小,存活时间通常利用经过几次垃圾回收来度量
29.Python的可变类型和不可变类型?
可变类型:列表,字典,集合,数据发生改变时,内存地址不变
不可变类型:数字,字符串,元祖,数据发生改变时,重新开辟了一个内存地址,内存地址不变
30.求结果:
v = dict.fromkeys(['k1','k2'],[])

   v[‘k1’].append(666)

   print(v)

   v[‘k1’] = 777

   print(v

anser:

# Python 字典(Dictionary) fromkeys()方法
# 描述
# Python 字典 fromkeys() 函数用于创建一个新字典,以序列 seq 中元素做字典的键,
#                       value 为字典所有键对应的初始值。
#
# 语法
# fromkeys()方法语法:

# dict.fromkeys(seq[, value])
# 参数
#     seq -- 字典键值列表。
#     value -- 可选参数, 设置键序列(seq)的值。
# 返回值
#    该方法返回一个新字典。
v=dict.fromkeys(['k1','k2'],[])
# v = {'k1':'[]','k2':'[]'}
v['k1'].append(666)  #将列表k1的值变为[666],刚开始,k1和k2公用一个值[]
# v:{'k1':'[666]','k2':'[666]'}
print(v)
v['k1']=777  #将k1的值变为777,列表不变。
# v:{'k1':'777','k2':'[666]'}
print(v)

d = {}
dict.fromkeys("ab", [123,123,12,3,21,321,31]) # fromkeys 返回的新字典. 和d没有关系
# {'a': [123, 123, 12, 3, 21, 321, 31], 'b': [123, 123, 12, 3, 21, 321, 31]}
print(d) # {}
31求结果:
def num():
    return [lambda x: i * x for i in range(4)]

print([m(2) for m in num()])
此函数可变形为下图:
[6, 6, 6, 6]
# 匿名函数某面试题题详解
def mu():  # 上边函数拆解后是这种结构
    l = []  # 定义一个列表
    for i in range(4):  # for循环4次
        def fun(x):  # 代码不执行
            return i * x  # 代码不执行

        l.append(fun)  # 列表中添加进去了4个未执行的函数,当列表中的函数被调用时,才会去内存中找i,此时的i是for循环的最后一位元素。
    return l  # 返回此列表

 拓展

def num():
    for i in range(5):
        yield lambda x:x*i

print([m(2) for m in num()])  # [0, 2, 4, 6, 8] 生成器一次出来一个数据


def add(a, b): return a + b def test(): for i in range(6): yield i g = test() # 生成器 0,1,2,3,4,5 for n in [2, 100]: g = (add(n, j) for j in g) # 执行了两遍 # n=2 # g = (add(n, j) for j in g) # n=100 # g = (add(n, j) for j in g) # n=15 # 将n变为15,则结果为[30, 31, 32, 33, 34, 35] print(list(g)) # [200, 201, 202, 203, 204, 205] """ 注意:生成器在不执行的时候,就是一堆代码 1.先将g = test()生成器放到内存中 2.循环两遍for n in [2, 100]: 此时n=100 3.list(g)调用两次 g = (add(n, j) for j in g) 注意:list(g)调用的是n=100的那个生成器g, n=100的那个生成器g的执行需要通过n=2的那个生成器(倒着执行) j的值是通过g = test()找到的,n的值是后者覆盖前者 1.g调用两次def add(a, b): # 顺序执行 2.第一次a=n=100,b=0 3.第二次a=n=100,b=10=第一次调用def add(a, b):的值 """
32.列举常见的内置函数?
 float(x)  # 把x转换成浮点数
    str(x)   # 转换成字符串
    list(x)  # 转换成列表
    tuple(x) # 转换成元组
   
     
    进制相互转换
     r= bin(10) #二进制
     r= int(10) #十进制

     r = oct(10) #八进制
     r = hex(10) #十六进制
     i= int("11",base=10)#进制间的相互转换base后跟 2/8/10/16
     
    chr(x)//返回x对应的字符,如chr(65)返回‘A'
    ord(x)//返回字符对应的ASC码数字编号,如ord('A')返回65
    abs() #绝对值
    input() # 程序交互
    id() # 查看内存地址
    enumerate() #枚举
    eval() #执行一个字符串表达式
    max() # 求最大
    min() # 求最小
    sum() # 求和
    range() # 范围
    type() # 查看数据类型
    len() #获取数据类型的长度
    zip()
    sorted()
    reversed()
    filter()
# map:遍历序列,为每一个序列进行操作,返回一个结果列表
l = [1, 2, 3, 4, 5, 6, 7]
def pow2(x):
   return x * x
res = map(pow2, l)
print(list(res)) #[1, 4, 9, 16, 25, 36, 49]
# reduce:对于序列里面的所有内容进行累计操作
from functools import reduce
def add(x, y):
   return x+y
print(reduce(add, [1,2,3,4])) #10
# filter:对序列里面的元素进行筛选,最终获取符合条件的序列
l = [1, 2, 3, 4, 5]
def is_odd(x):  # 求奇数
   return x % 2 == 1
print(list(filter(is_odd, l))) #[1, 3, 5]
# zip:用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表
a = [1,2,3]
b=[4,5,6]
c=[4,5,6,7,8]
ziped1 = zip(a,b)
print('ziped1>>>',list(ziped1)) #[(1, 4), (2, 5), (3, 6)]
ziped2 = zip(a,c)
print('ziped2>>>',list(ziped2)) #[(1, 4), (2, 5), (3, 6)],以短的为基准
33.filter、map、reduce的作用?
 filter:对于序列中的元素进行筛选,最终获取符合条件的序列
  map:遍历序列,对序列中每个元素进行操作,最终获取新的序列
  reduce:对于序列内所有元素进行累计操作
34.一行代码实现9*9乘法表
print("\n".join("\t".join(["%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)]) for x in range(1, 10)) )

print('\n'.join([''.join(['%s*%s=%2s' % (j,i,i*j) for j in range(1+i+1)])for i in range(1,10)]))
35.如何安装第三方模块?以及用过哪些第三方模块?
1.在pycharm的settings中手动下载,添加第三方模块
2输入cmd,在终端中pip install +模块名 安装
用过的第三方模块:requests,pymysql,DBUtils

- pip包管理器
      pip install 模块名
  - 源码安装
      - 下载->解压->cd 到对应路径
      - python setup.py build
      - python setup.py install 
  
  requests
  selenium
  urllib3
  pymysql
  redis
  celery
  beautifulsoup4
  sqlarchmy
  xlrd
  gevent
36.至少列举8个常用模块都有那些?
re:正则
os:提供了一种方便的 操作系统函数的方法
sys:可供访问由解释器使用或维护的变量和解释器记性交互的函数
random:随机数
json:序列化
time:时间
37.re的match和search区别?

38.什么是正则的贪婪匹配?
39.求结果:
 a. [ i % 2 for i in range(10) ]
 b. ( i % 2 for i in range(10) )
40.求结果:
 a. 1 or 2
 b. 1 and 2
 c. 1 < (2==2)
 d. 1 < 2 == 2
41.def func(a,b=[]) 这种写法有什么坑?
42.如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
43.如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
44.比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?
45.如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?
46.一行代码实现删除列表中重复的值 ?
47.如何在函数中设置一个全局变量 ?
48.logging模块的作用?以及应用场景?
49.请用代码简答实现stack 。
50.常用字符串格式化哪几种?
51.简述 生成器、迭代器、可迭代对象 以及应用场景?
52.用Python实现一个二分查找的函数。
53.谈谈你对闭包的理解?
54.os和sys模块的作用?
55.如何生成一个随机数?
56.如何使用python删除一个文件?
57.谈谈你对面向对象的理解?
58.Python面向对象中的继承有什么特点?
59.面向对象深度优先和广度优先是什么?
60.对象中super的作用?
61.是否使用过functools中的函数?其作用是什么?
62.列举面向对象中带爽下划线的特殊方法,如:__new__、__init__
63.如何判断是函数还是方法?
64.静态方法和类方法区别?
65.列举面向对象中的特殊成员以及应用场景
66.1、2、3、4、5 能组成多少个互不相同且无重复的三位数
67.什么是反射?以及应用场景?
68.metaclass作用?以及应用场景?
69.用尽量多的方法实现单例模式。
70.装饰器的写法以及应用场景。
71.异常处理写法以及如何主动跑出异常(应用场景)
72.什么是面向对象的mro
73.isinstance作用以及应用场景?
74.写代码并实现:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
Example:

          Given nums = [2, 7, 11, 15], target = 9,
           
Because nums[0] + nums[1] = 2 + 7 = 9,

           return [0, 1]
75.json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
76.json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
77.什么是断言?应用场景?
78.有用过with statement吗?它的好处是什么?
79.使用代码实现查看列举目录下的所有文件。
80.简述 yield和yield from关键字。
第二部分 网络编程和并发(34题)
1 简述 OSI 七层协议。
物理层:主要基于电器特性发送高低电压(1,0),设备有集线器,中继器,双绞线等,单位bit
数据链路层:定义了电信号的分组方式,设备:交换机,网卡,网桥,单位:帧
网络层:主要功能是将网络地址翻译成对应的物理地址,设备:路由
传输层:建立端口之间的通信,tcp,udp协议
会话层:建立客户端与服务端链接
表示层:对来自应用层的命令和数据进行解释,按照一定格式传给会话层。如编码,数据格式转换,加密解密,压缩解压等
应用层:规定应用程序的数据格式
2.什么是C/S和B/S架构?
C/S架构:
    client和 server端的服务架构
B/S架构:
    隶属于C/S架构,Broswer端(网页端)与server端
    优点:统一了所有应用的入口,方便,轻量级
3.简述 三次握手、四次挥手的流程。
三次握手:
    客户端向服务端发起一次请求
    服务端确认并且恢复客户端
    客户端检验确认请求,建立连接
四次挥手:
    客户端向服务端发一次请求
    服务端回复客户端(断开客户端)
    服务端再次向客户端发起请求(告诉客户端可以断开了)
    客户端确认请求
4.什么是arp协议?
5.TCP和UDP的区别?
6.什么是局域网和广域网?
7.为何基于tcp协议的通信比基于udp协议的通信更可靠?
8.什么是socket?简述基于tcp协议的套接字通信流程。
9.什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
10.多路复用的作用?
11.什么是防火墙以及作用?
12.select、poll、epoll 模型的区别?
13.简述 进程、线程、协程的区别 以及应用场景?
14.GIL锁是什么鬼?
15.Python中如何使用线程池和进程池?
16.threading.local的作用?
17.进程之间如何进行通信?
18.什么是并发和并行?
19.进程锁和线程锁的作用?
20.解释什么是异步非阻塞?
21.路由器和交换机的区别?
22.什么是域名解析?
23.如何修改本地hosts文件?
24.生产者消费者模型应用场景及优势?
25.什么是cdn?
26.LVS是什么及作用?
27.Nginx是什么及作用?
28.keepalived是什么及作用?
29.haproxy是什么以及作用?
30.什么是负载均衡?
31.什么是rpc及应用场景?
32.简述 asynio模块的作用和应用场景。
33.简述 gevent模块的作用和应用场景。
34twisted框架的使用和应用?
数据库和缓存(46题)
1.列举常见的关系型数据库和非关系型都有那些?
关系型:
    sqlite,db2,oracle,access,SQLserver,MYSQL
    sql语句通用,需要有表结构
非关系型:
    mongodb,redis,memcache
    非关系型数据库是key-value存储的,没有表结构
2.MySQL常见数据库引擎及比较?
MYisam:
    支持全文索引
    查询速度相对较快
    支持表锁
        表锁:select * from tb for update;(锁:for update)
InnoDB:
    支持会务
    支持行锁,表锁
        表锁:select * from tb for update; (锁:for update) 
        行锁:select id ,name from tb where id=2,for update; (锁:for update)
3.简述数据三大范式?
数据库的三大特性:
    实体:表
    属性:表中的数据(字段)
    关系:表与表之间的关系
数据库设计三大规范:
    第一范式(1NF):
        数据表中的每一列(每个字段),必须是不可拆分的最小单元
        也就是确认每一列的原子性
    第二范式(2NF):
        满足第一范式,要求表中的所有列,都必须依赖主键
        而不能有任何一列,与主键没有关系,也就是说一个表只描述一件事情
    第三范式(3NF):
        必须满足第二范式
        要求:表中每一列只与主键直接相关,而不是间接相关(表中每一列只能依赖于主键)
4.什么是事务?MySQL如何支持事务?
5.简述数据库设计中一对多和多对多的应用场景?
6.如何基于数据库实现商城商品计数器?
7.常见SQL(必备)
  详见武沛齐博客:https://www.cnblogs.com/wupeiqi/articles/5729934.html
8.如何高效的找出redis中以"new"开头的key?
9.简述触发器、函数、视图、存储过程?
10.MySQL索引种类
11.索引在什么情况下遵循最左前缀的规则?
12.主键和外键的区别?
13.MySQL常见的函数?
14.列举 创建索引但是无法命中索引的8种情况。
15.如何开启慢日志查询?
16.数据库导入导出命令(结构+数据)?
17.数据库优化方案?
18.char和varchar的区别?
19.简述MySQL的执行计划?
20.在对name做了唯一索引前提下,简述以下区别:

select * from tb where name = ‘Oldboy-Wupeiqi’ 

select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1
21.1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?
22.什么是索引合并?
23.什么是覆盖索引?
24.简述数据库读写分离?
25.简述数据库分库分表?(水平、垂直)
26.redis和memcached比较?
27.redis中数据库默认是多少个db 及作用?
28.python操作redis的模块?
29.如果redis中的某个列表中的数据量非常大,如果实现循环显示每一个值?
30.redis如何实现主从复制?以及数据同步机制?
31.redis中的sentinel的作用?
32.如何实现redis集群?
33.redis中默认有多少个哈希槽?
34.简述redis的有哪几种持久化策略及比较?
35.列举redis支持的过期策略。
36.MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中都是热点数据?
37.写代码,基于redis的列表实现 先进先出、后进先出队列、优先级队列。
38.如何基于redis实现消息队列?
39.如何基于redis实现发布和订阅?以及发布订阅和消息队列的区别?
40.什么是codis及作用?
41.什么是twemproxy及作用?
42.写代码实现redis事务操作。
43redis中的watch的命令的作用?
44.基于redis如何实现商城商品数量计数器?
45.简述redis分布式锁和redlock的实现机制。
46.什么是一致性哈希?Python中是否有相应模块?
前端,框架和其他(155题)
1.谈谈你对http协议的认识。
超文本传输协议
    特点:
        无状态:请求响应之后,再次发起请求时,不认识
        短链接:一次请求和一次响应就断开连接
    格式:
        通过/r/n分割
        请求头和请求体之间:/r/n/r/n分割
2.谈谈你对websocket协议的认识。
什么是websocket?
    是给浏览器新建的一套协议
    协议规定:创建连接后不断开
    通过"/r/n"分割,让客户端和服务端创建连接后不断开,验证+数据加密
本质:
    一个创建后不断开的socket
    当连接成功后:
        客户端会自动向服务端发送消息
        服务端接收后,会对该数据加密:base64(sha1(swk+magic_string))
        构造响应头
        发送给客户端
        建立双工通道,进行收发数据
框架中是如何使用websocket的?
    django:channel
    flask:gevent-websocket
    tornado:内置
websocket的优缺点
    有点:代码简单,不在重复创建链接
    缺点:兼容性没有长轮询好,如IE会不兼容
3.什么是magicstring ?
它是websocket里面的用于加密的一个字符串,全球唯一
客户端向请求端发送消息时,会有一个sec-websocket-key和magic string 的随机字符串(魔法字符串)
服务端收到消息后,会把他拼接成一个新的key字符串,先进行sha1算法,后进行base64进行加密,确保信息的安全性。
4.如何创建响应式布局?
a.可以通过引用Bootstrap实现
b.通过看Bootstrap源码文件,可知其本质就是通过css实现的
<style>
        /*浏览器窗口宽度大于768,背景色变为 green*/
        @media (min-width: 768px) {
            .pg-header{
                background-color: green;
            }
        }

        /*浏览器窗口宽度大于992,背景色变为 pink*/
        @media (min-width: 992px) {
            .pg-header{
                background-color: pink;
            }
        }
    </style>
</head>
<body>
<div class="pg-header"></div>
</body>
5.你曾经使用过哪些前端框架?
Jquery,Vue,Bootstrap
6.什么是ajax请求?并使用jQuery和XMLHttpRequest对象实现一个ajax请求。
7.如何在前端实现轮训?
8.如何在前端实现长轮训?
9.vuex的作用?
10.vue中的路由的拦截器的作用?
11.axios的作用?
12.列举vue的常见指令。
13.简述jsonp及实现原理?
14.是什么cors ?
15列举Http请求中常见的请求方式?
16.列举Http请求中的状态码?
17.列举Http请求中常见的请求头?
18.看图写结果:

 

19.看图写结果:

20.看图写结果:

21.看图写结果:

22.看图写结果:

23.看图写结果:

24.django、flask、tornado框架的比较?
25.什么是wsgi?
26.django请求的生命周期?
27.列举django的内置组件?
28.列举django中间件的5个方法?以及django中间件的应用场景?
29.简述什么是FBV和CBV?
30.django的request对象是在什么时候创建的?
31.如何给CBV的程序添加装饰器?
32.列举django,orm中所有的方法(QuerySet对象的所有方法)
33.only和defer的区别?
34.select_related和prefetch_related的区别?
35.filter和exclude的区别?
36.列举django orm中三种能写sql语句的方法。
37.django orm中如何设置读写分离?
38.F和Q的作用?
39.values和values_list的区别?
40.如何使用django orm批量创建数据?
41.django的Form和ModeForm的作用?
42.django的Form组件中,如果字段中包含choices参数,请使用两种方式实现数据源实时更新。
43.django的Model中的ForeignKey字段中的on_delete参数有什么作用?
44.django中csrf的实现机制?
45.django如何实现websocket?
46.基于django使用ajax发送post请求时,都可以使用哪种方法携带csrftoken?
47.django中如何实现orm表中添加数据时创建一条日志记录。
48.django缓存如何设置?
49.django的缓存能使用redis吗?如果可以的话,如何配置?
50.django路由系统中name的作用?
51.django的模板中filter和simple_tag的区别?
52.django - debug - toolbar的作用?
53.django中如何实现单元测试?
54.解释orm中db first和code first的含义?
55.django中如何根据数据库表生成model中的类?
56.使用orm和原生sql的优缺点?
57.简述MVC和MTV
58.django的contenttype组件的作用?
59.谈谈你对restfull 规范的认识?
60.接口的幂等性是什么意思?
61.什么是RPC?
62.Http和Https的区别?
63.为什么要使用django rest framework框架?
64.django rest framework框架中都有那些组件?
65.django rest framework框架中的视图都可以继承哪些类?
66.简述 django rest framework框架的认证流程。
67.django rest framework如何实现的用户访问频率控制?
68.Flask框架的优势?
69.Flask框架依赖组件?
70.Flask蓝图的作用?
71.列举使用过的Flask第三方组件?
72.简述Flask上下文管理流程?
73.Flask中的g的作用?
74.Flask中上下文管理主要涉及到了那些相关的类?并描述类主要作用?
75.为什么要Flask把Local对象中的的值stack 维护成一个列表?
76.Flask中多app应用是怎么完成?
77.在Flask中实现WebSocket需要什么组件?
78.wtforms组件的作用?
79.Flask框架默认session处理机制?
80.解释Flask框架中的Local对象和threading.local对象的区别?
81.Flask中blinke是什么?
82.SQLAlchemy中的session和scoped_session的区别?
83.SQLAlchemy如何执行原生SQL?
84.ORM的实现原理?
85.DBUtils模块的作用?
86.以下SQLAlchemy的字段是否正确?如果不正确请更正:
from datetime import datetime

from sqlalchemy.ext.declarative
import declarative_base

from sqlalchemy import Column, Integer, String, DateTime



Base = declarative_base()


class UserInfo(Base):
   
    __tablename__ = 'userinfo'
   
    id = Column(Integer, primary_key=True, autoincrement=True)

    name = Column(String(64), unique=True)

    ctime = Column(DateTime, default=datetime.now())
87.SQLAchemy中如何为表设置引擎和字符编码?
88.SQLAchemy中如何设置联合唯一索引?
89.简述Tornado框架的特点。
90.简述Tornado框架中Future对象的作用?
91.Tornado框架中如何编写WebSocket程序?
92.Tornado中静态文件是如何处理的?

  如: <link href="{{static_url("commons.css")}}" rel="stylesheet" />
93.Tornado操作MySQL使用的模
94.Tornado操作redis使用的模
95.简述Tornado框架的适用
96.git常见命令作用:
97.简述以下git中stash命令作用以及相关其他命令。
98.git中 merge和rebase命令的区别。
99.公司如何基于git做的协同开发?
100.如何基于git实现代码review?
101.git如何实现v1 .0 、v2.0等版本的管理?
102.什么是gitlab?
103.github和gitlab的区别?
104.如何为github上牛逼的开源项目贡献代码?
105.git中.gitignore文件的作用?
106.什么是敏捷开发?
107.简述 jenkins工具的作用?
108.公司如何实现代码发布?
109.简述RabbitMQ、Kafka、ZeroMQ的区别?
110.RabbitMQ如何在消费者获取任务后未处理完前就挂掉时,保证数据不丢失?
111.RabbitMQ如何对消息做持久化?
112.RabbitMQ如何控制消息被消费的顺序?
113.以下RabbitMQ的exchange type分别代表什么意思?如:fanout、direct、topic。
114.简述celery是什么以及应用场景?
115.简述celery运行机制。
116.celery如何实现定时任务?
117.简述celery多任务结构目录?
118.celery中装饰器 @ app.task和 @ shared_task的区别?
119.简述requests模块的作用及基本使用?
120.简述beautifulsoup模块的作用及基本使用?
121.简述seleninu模块的作用及基本使用?
122.scrapy框架中各组件的工作流程?
123.在scrapy框架中如何设置代理(两种方法)?
124.scrapy框架中如何实现大文件的下载?
125.scrapy中如何实现限速?
126.scrapy中如何实现暂定爬虫?
127.scrapy中如何进行自定制命令?
128.scrapy中如何实现的记录爬虫的深度?
129.scrapy中的pipelines工作原理?
130.scrapy的pipelines如何丢弃一个item对象?
131.简述scrapy中爬虫中间件和下载中间件的作用?
132.scrapy - redis组件的作用?
133.scrapy - redis组件中如何实现的任务的去重?
134.scrapy - redis的调度器如何实现任务的深度优先和广度优先?
135.简述vitualenv及应用场景?
136.简述pipreqs及应用场景?
137.在Python中使用过什么代码检查工具?
138.简述saltstack、ansible、fabric、puppet工具的作用?
139.B Tree和B + Tree的区别?
140.请列举常见排序并通过代码实现任意三种。
141.请列举常见查找并通过代码实现任意三种。
142.请列举你熟悉的设计模式?
143.有没有刷过leetcode?
144.列举熟悉的的Linux命令。
145.公司线上服务器是什么系统?
146.解释PV、UV的含义?
147.解释 QPS的含义?
148.uwsgi和wsgi的区别?
149.supervisor的作用?
150.什么是反向代理?
151.简述SSH的整个过程。
152.有问题都去那些找解决方案?
153.是否有关注什么技术类的公众号?
154.最近在研究什么新技术?
155.是否了解过领域驱动模型?
有 如下 a = 1 b = 3,用一行代码将a b值互换。(分别赋值)
a=1
b=3
a,b=b,a
print(a,b)
有字符串"k:1|k1:2|k2:3|k3:4" 处理成字典 {'k':1,'k1':2....}#考试题
l='k:1|k1:2|k2:3|k3:4'.split('|')#['k:1', 'k1:2', 'k2:3', 'k3:4']
dic={}
for i in l:
   # dic[i.split(':')[0]]=int(i.split(':')[1])#不要想一步到位,理清思路,从概念上去解决他
    i=i.split(':')
    dic[i[0]]=int(i[1])
print(dic)

对于切片来说,这是浅copy。
对于切片来说,这是浅copy。
l1 = [1, 2, 3, 4, 5, 6, [11,22]]
l2 = l1[:]
l1.append(666)
print(l1, l2)
l1[-1].append(666)
print(l1, l2)
上台阶
一次可以上1个台阶,一个可以上2个台阶,一次可以上3个台阶,一次可以上4个台阶,
总共n个台阶,一共有多少种走法。
思路:假如倒着走
                    f(n)          f(n-1)
从倒数第一层开始往上走(n-1):       1         只有一种走法
从倒数第二层开始往上走(n-2):    2 种走法     只有一种不重复走法
从倒数第三层开始往上走(n-3):    4 种走法     只有一种不重复走法
由此推出-->f(n)=f(n-1)+f(n-2)+f(n-3)

实例:

def f(n):
    if n == 1:
        return 1
    elif n == 2:
        return 2
    elif n == 3:
        return 4
    return f(n-1)+f(n-2)+f(n-3)
ret=f(6)
print(ret)

# 分析
# f6=f5+f4+f3=13+7+4=24

#     f5=f4+f3+f2=(f3+f2+f1)+f3+f2=(4+2+1)+4+2=13
#     f4=f3+f2+f1=4+2+1=7
#     f3=4

看代码写结果(列表推导式,闭包函数)

def mul():
    return [lambda x: x*i for i in range(4)]

print([m(2) for m in mul()]) 

分析:

# 上面函数可以转化为如下:
def mul():
    ret = []
    for i in range(4):
        def fun(x):
            return x*i
        ret.append(fun)

    return ret
print([m(2) for m in mul()])

# 最后一行的列表推导式调用mul函数
# Ret=[]
# 执行for 循环
# 跳过fun函数,执行ret.append,添加四次,列表ret的值为[0,1,2,3]
# 将ret返回给函数的调用者(列表推导式)
# 执行fun函数,取for 循环的值i,闭包函数,延期赋值,取得是最后一个,所以取的值一直        是最后一个数3,
# (取值时不再走for循环)取列表推导式传的参数x=2,执行结果为6,
# for循环执行了4次,for循环传给函数的值也是四个,所以函数执行4次,结果为[6,6,6,6]

# 将方括号变成小括号,变成生成器
def mul():
    return (lambda x: x*i for i in range(4))

print([m(2) for m in mul()])

# 变形后为
def mul2():
    for i in range(4):
        def func(x):
            print(locals())  #打印变量
            return x*i
        yield func

print([m(2) for m in mul2()])

# 将return里面的值变成生成器后,也是循环四次,变化的是,生成器每执行一次,就会夯住,(在用的时候才会调用)
# 等函数就调用一次后才往下面执行,执行里面的值取完为止(每次取值都要走for循环),执行结果为[0,2,4,6]

# 默认参数

def mul():
    return [lambda x,i=i: x*i for i in range(4)]

print([m(2) for m in mul()])

# 变形后为
def mul2():
    ret = []
    for i in range(4):
        def fun(x,i=i):
            print(locals())
            return x*i
        ret.append(fun)

    return ret
print([m(2) for m in mul2()])
# [0,2,4,6]

def mul():
    return (lambda x,i=i: x*i for i in range(4))

print([m(2) for m in mul()])


# 变形后为
def mul2():
    for i in range(4):
        def func(x,i=i):
            print(locals())  #打印变量
            return x*i
        yield func

print([m(2) for m in mul2()])

# [0,2,4,6]
分析

 写打印结果

class Parent:                           
def func(self):
        print('in parent func')
    def __init__(self):
        self.func()
class Son(Parent):
    def func(self):
        print('in son func')
s=Son()
The answer:in son func

参数陷阱:默认参数是一个可变数据类型

def defult_param(a,l = []):
    l.append(a)
    print(l)

defult_param('alex')#['alex']
defult_param('egon')#['alex', 'egon']
defult_param([])#这个[]不是默认参数,而是新添加元素。['alex', 'egon', []

1

def defult_param(a,l = []):
    l.append(a)
    print(l)

l1=defult_param('alex')#['alex']
l2=defult_param('egon')#['alex', 'egon']
l3=defult_param([])#这个[]不是默认参数,而是新添加元素。['alex', 'egon', []]
print(l1,l2,l3)#None None None 没有返回值

def defult_param(a,l = []):
    l.append(a)
    return l

l1=defult_param('alex')#['alex']
l2=defult_param('egon')#['alex', 'egon']
l3=defult_param([])#这个[]不是默认参数,而是新添加元素。['alex', 'egon', []]
print(l1,l2,l3)#['alex', 'egon', []] ['alex', 'egon', []] ['alex', 'egon', []]

def defult_param(a,l = []):
    l.append(a)
    return l

l1=defult_param('alex')#['alex']
print(l1)['alex']
l2=defult_param('egon')# ['alex', 'egon'] ['alex', 'egon']
print(l1,l2)#['alex', 'egon'] ['alex', 'egon']
l3=defult_param([])#这个[]不是默认参数,而是新添加元素。['alex', 'egon', []]
print(l1,l2,l3)#['alex', 'egon', []] ['alex', 'egon', []] ['alex', 'egon', []]

 123

 

猜你喜欢

转载自www.cnblogs.com/daofaziran/p/8963205.html
今日推荐