Python 面试题_未完

基础部分

1. 为什么学习Python

家里有在这个IT圈子里面,也想让我接触这个圈子,然后给我建议学的Python,
然后自己通过百度和向有学过Python的同学了解了Python,Python这门语言,入门比较简单,
它简单易学,生态圈比较强大,涉及的地方比较多,特别是在人工智能,和数据分析这方面。
在未来我觉得是往自动化,人工智能这方面发展的,所以学习了Python

balabala.....

2. 通过什么途径学习Python

刚开始接触Python的时候,到网上里面跟着视频学基础,
再后来网上到看技术贴,然后看到有人推荐廖雪峰的Python教程, 练项目到GitHub上面找一些小项目学习

balabala....

3. 谈谈对Python和其他语言的区别

Python VS java 
  python
    动态强类型,定义无需声明类型,崇尚鸭子类型
  java
    静态强类型,定义必须要声明定义类型

Python VS PHP
  PHP 弱类型 面向web
  Python 强类型 面向对象
Python VS C
  Python 压倒性的代码简洁程度,缩进的使用。
  C 大量的修饰词以及括号,代码量庞大

4. Python的优势

简易 :代码简单,易懂,易学
开源 可移植性强大

便于移植 :无需再次编译
编程方式多样 :函数编程,面向对象编程都支持 可扩展性和可嵌入性强大 丰富的库

动态类型 : 鸭子类型因此更加方便类型选择

5. python语言的缺点

运行速度比较C较弱

不能加密 : 开源性限制

构架选择太多: 没有官方框架

GIL : 全局解释器锁导致没有多线程

6. 简述解释型和编译型编程语言

解释型:就是边解释边执行
执行速度快、效率高;依赖编译器、跨平台性差些。如C、C++、Delphi、Pascal,Fortran

编译型:编译后再执行
执行速度慢、效率低;依赖解释器、跨平台性好。如Tcl、Perl、Ruby、VBScript、 JavaScript

7. Python的解释器种类以及相关特点?

CPython
官方版本的解释器:CPython。C语言 ,命令行下运行python就是启动CPython解释器。
CPython是使用最广的Python解释器。教程的所有代码也都在CPython下执行。

IPython
IPython是基于CPython之上的一个交互式解释器,
IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。

标识:
CPython用
>>>作为提示符,而IPython用In [序号]:作为提示符。

PyPy
由Python写的解释器,执行速度最快。
PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),
绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。

Jython
Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。

IronPython
IronPython和Jython类似,只不过IronPython是运行在.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

取舍:
使用最广泛的还是CPython。如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是通过网络调用来交互,确保各程序之间的独立性。

8. 位和字节的关系

1字节 = 8 位
位(bit),数据存储是以“字节”(Byte)为单位,数据传输是以大多是以“位”(bit,又名“比特”)为单位,
一个位就代表一个0或1(即一个二进制),二进制是构成存储器的最小单位,每8个位(bit,简写为b)组成一个字节(Byte,简写为B),
字节是最小一级的信息单位

9. b、B、KB、MB、GB的关系

b --->位(bit)    

B --->字节      一个字节等于8位

1B = 8 bit

1kb = 1024 B

1 MB = 1024 KB

1 GB = 1024 MB

10. PE8规范

1、使用4个空格而不是tab键进行缩进。
2、每行长度不能超过79
3、使用空行来间隔函数和类,以及函数内部的大块代码
4、必要时候,在每一行下写注释
5、使用文档注释,写出函数注释
6、在操作符和逗号之后使用空格,但是不要在括号内部使用
7、命名类和函数的时候使用一致的方式,比如使用CamelCase来命名类,
           使用lower_case_with_underscores来命名函数和方法
8、在类中总是使用self来作为默认
9、尽量不要使用魔法方法
10、默认使用UTF-8,甚至ASCII作为编码方式
11、换行可以使用反斜杠,最好使用圆括号。
12、不要在一句import中多个库,

空格的使用   1. 各种右括号前不要加空格。   2. 逗号、冒号、分号前不要加空格。   3. 函数的左括号前不要加空格。如Func(
1)   4. 序列的左括号前不要加空格。如list[2]   5. 操作符左右各加一个空格,不要为了对齐增加空格   6. 函数默认参数使用的赋值符左右省略空格   7. 不要将多句语句写在同一行,尽管使用‘;’允许

if/for/while语句中,即使执行语句只有一句,也必须另起一行 函数命名使用全部小写的方式,常量命名使用大写,类属性(方法和变量)使用小写 类的命名首字母大写

11. 进制转换

# 二进制转换成十进制-->int
v = "0b1111011"
b = int(v,2)
print(b)  # 123


# 十进制转换成二进制--->bin
v2 = 18
print(bin(int(v2)))
# 0b10010

# 八进制转换成十进制
v3 = "011"
print(int(v3))
# 11

# 十进制转换成八进制:---> oct
v4 = 30
print(oct(int(v4)))
# 0o36

# 十六进制转换成十进制:
v5 = "0x12"
print(int(v5,16))
# 18

# 十进制转换成十六进制:---> hex
v6 = 87
print(hex(int(v6)))
# 0x57

12. 请编写一个函数实现将IP地址转换成一个整数

"""
请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:
        10            00001010

         3            00000011

         9            00001001

        12            00001100

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

def v1(addr):
    # 取每个数
    id = [int(x) for x in addr.split(".")]
    print(id)
    return sum(id[i] << [24, 16, 8, 0][i] for i in range(4))

print(v1("127.0.0.1"))

# [127, 0, 0, 1]
# 2130706433

13. python递归的最大层数?

998

视情况而定,机器性能好的话也可以超出此上限

14. 求结果(and or or)

1. 求结果:1 or 3
print(1 or 3)  # 1

2. 求结果:1 and 3
print(1 and 3)  # 3

3. 求结果:0 and 2 and 1
print(0 and 2 and 1)  # 0

4. 求结果:0 and 2 or 1
print(0 and 2 or 1)  # 1

5. 求结果:0 and 2 or 1 or 4
print(0 and 2 or 1 or 4)  # 1

6. 求结果:0 or Flase and 1
print(0 or False and 1)  # Flase

总结:
  # x or y 如果 x为真,则值为x,   否则为y
  # x and y 如果 x 为真,则值为 y,否则为 x
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  -- False
and:前后为真才为真
or:有一为真就为真
优先级:()>not>and>or 
同等优先级下,从左向右

15 运算符

1. 求结果:2 & 5

print(2 & 5)  # 10 & 101 => 000 => 0

2. 求结果:2 ^ 5

print(2 ^ 5)  # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7

16 . ascii、unicode、utf-8、gbk 区别

python2 默认 ascii
python3 默认 utf-8
ascii 最多只能用8位来表示(一个字节),即:
2**8 = 256,所以,ASCII码最多只能表示 256 个符号。 unicode 万国码,任何一个字符==两个字节 utf-8 万国码的升级版 一个中文字符==三个字节 英文是一个字节 欧洲的是 2个字节 gbk 国内版本 一个中文字符==2个字节 英文是一个字节
gbk 转 utf
-8 需通过媒介 unicode

17. 字节码和机器码的区别

什么是机器码

机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。
通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。

总结:机器码是电脑CPU直接读取运行的机器指令,运行速度最快,但是非常晦涩难懂,也比较难编写

什么是字节码
字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。
字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。

总结:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。

18. 简述变量命名规范

  #1、以字母,数字,下划线任由结合
  #2、不能以命名太长,不使用拼音,中文
  #3、不能以数字开头
  #4、不能用关键词

19. is 和 == 的区别

#is  比较的是内存地址
#== 比较的是值

is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。

== 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。默认会调用对象的 __eq__()方法。

20. 三元运算写法和应用场景?

# 应用场景:简化if语句
# 格式
  # 结果+ if  + 条件  + else + 结果
result='gt' if 1>3 else 'lt'
print(result)       # lt
# 理解:如果条件为真,把if前面的值赋值给变量,否则把else后面的值赋值给变量。


lambda 表达式
temp = lambda x,y:x+y
print(temp(4,10))   # 14

可替代:
def foo(x,y):
    return x+y
print(foo(4,10))    # 14

21. Python3和Python2的区别?

1:打印时,py2需要可以不需要加括号,py3 需要
python 2 :print ('lili')   ,   print 'lili'
python 3 : print ('lili')   
python3 必须加括号

exec语句被python3废弃,统一使用exec函数

2:内涵
Python2:1,臃肿,源码的重复量很多。
             2,语法不清晰,掺杂着C,php,Java,的一些陋习。
Python3:几乎是重构后的源码,规范,清晰,优美。

3、输出中文的区别
python2:要输出中文 需加 # -*- encoding:utf-8 -*-
Python3 : 直接搞

4:input不同
python2 :raw_input
python3 :input 统一使用input函数

5:指定字节
python2在编译安装时,可以通过参数-----enable-unicode=ucs2 或-----enable-unicode=ucs4分别用于指定使用2个字节、4个字节表示一个unicode;
python3无法进行选择,默认使用 ucs4
查看当前python中表示unicode字符串时占用的空间:

impor sys
print(sys.maxunicode)
#如果值是65535,则表示使用usc2标准,即:2个字节表示
#如果值是1114111,则表示使用usc4标准,即:4个字节表示

6:
py2:xrange
    range
py3:range  统一使用range,Python3中range的机制也进行修改并提高了大数据集生成效率

7:在包的知识点里
包:一群模块文件的集合 + __init__
区别:py2 : 必须有__init__
   py3:不是必须的了

8:不相等操作符"<>"被Python3废弃,统一使用"!="

9:long整数类型被Python3废弃,统一使用int

10:迭代器iterator的next()函数被Python3废弃,统一使用next(iterator)

11:异常StandardError 被Python3废弃,统一使用Exception

12:字典变量的has_key函数被Python废弃,统一使用in关键词

13:file函数被Python3废弃,统一使用open来处理文件,可以通过io.IOBase检查文件类型

22. 用一行代码实现数值交换

a = 1 
b = 2

a, b = b, a

23. 列列举布尔值为False的常见值?

0,“”,{},[],(),set()
0 False 负数 不成立的表达式  None 等

24. 字符串、列表、元组、字典每个常用的5个方法?

字符串

字符串用单引号(')或双引号(")括起来,不可变

1,find通过元素找索引,可切片,找不到返回-1 2,index,找不到报错。 3,split 由字符串分割成列表,默认按空格。 4,captalize 首字母大写,其他字母小写。 5,upper 全大写。 6,lower 全小写。 7,title,每个单词的首字母大写。 8,startswith 判断以什么为开头,可以切片,整体概念。 9,endswith 判断以什么为结尾,可以切片,整体概念。 10,format格式化输出   #format的三种玩法 格式化输出   res='{} {} {}'.format('egon',18,'male') ==> egon 18 male   res='{1} {0} {1}'.format('egon',18,'male') ==> 18 egon 18   res='{name} {age} {sex}'.format(sex='male',name='egon',age=18) 11,strip 默认去掉两侧空格,有条件, 12,lstrip,rstrip 14,center 居中,默认空格。 15,count查找元素的个数,可以切片,若没有返回0 16,expandtabs 将一个tab键变成8个空格,如果tab前面的字符长度不足8个,则补全8个, 17,replace(old,new,次数) 18,isdigit 字符串由字母或数字组成 isalpha, 字符串只由字母组成 isalnum 字符串只由数字组成 19,swapcase 大小写翻转 20,for i in 可迭代对象。

字典

key: 输出所有的键
clear:清空                       
dic:删除的键如果没有则报错
pop:键值对删,有返回,没有原来的键会报错(自行设置返回键就不会报错)
popitem:随机删键值对
del:删除的键如果没有则报错
update :更新数据 get: 不报错的查询
# 没有可以返回设定的返回值

列表

append:在后面添加。
Insert:按照索引添加,
expend:迭代着添加。
pop 删除并作为返回值
remove 按照元素去删
clear  清空列表
del 删除列表
list.count(obj) - 统计某个元素在列表中出现的次数
list.index(obj) - 从列表中找出某个值第一个匹配项的索引位置
list.reverse() - 反向列表中元素
list.sort([func]) - 对原列表进行排序

元祖

1、cmp(tuple1, tuple2):比较两个元组元素。
2、len(tuple):计算元组元素个数。
3、max(tuple):返回元组中元素最大值。
4、min(tuple):返回元组中元素最小值。
5、tuple(seq):将列表转换为元组。

集合

set:创建集合
add: 添加元素
update:更新元素
clear:清空
pop:随机删除并返回
remove:指定删除
del: 删除集合

25. lambda表达式格式以及应用场景?

匿名函数:为了解决那些功能很简单的需求而设计的一句话函数
函数名 = lambda 参数 :返回值

#参数可以有多个,用逗号隔开
#匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
#返回值和正常的函数一样可以是任意数据类型

lambda 表达式
temp = lambda x,y:x+y
print(temp(4,10))   # 14

可替代:
def foo(x,y):
    return x+y
print(foo(4,10))    # 14

26. pass的作用

pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句。

27. *arg和**kwarg作用

# 他们是一种动态传参,一般不确定需要传入几个参数时,可以使用其定义参数,然后从中取参

'*args':按照位置传参,将传入参数打包成一个‘元组’(打印参数为元组-- tuple)
'**kwargs':按照关键字传参,将传入参数打包成一个‘字典’(打印参数为字典-- dict)

28. 谈谈Python的深浅拷贝?以及实现方法和应用场景。

浅拷贝只是增加了一个指针指向一个存在的地址,
数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层)

深拷贝是增加一个指针并且开辟了新的内存,这个增加的指针指向这个新的内存
数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)

采用浅拷贝的情况,释放内存,会释放同一内存,深拷贝就不会出现释放同一内存的错误
字典套字典、列表套字典、字典套列表,列表套列表,以及各种复杂数据结构的嵌套中,会出现拷贝后的数据发生变化导致源数据发生变化
import copy
 
# 浅拷贝
l1 = [1,2,3,[11,22,33]]
l2 = l1.copy()
print(l2) #[1,2,3,[11,22,33]]
l2[3][2]='aaa'
print(l1) #[1, 2, 3, [11, 22, 'aaa']]
print(l2) #[1, 2, 3, [11, 22, 'aaa']]
l1[0]= 0
print(l1) #[0, 2, 3, [11, 22, 'aaa']]
print(l2) #[1, 2, 3, [11, 22, 'aaa']]
print(id(l1)==id(l2)) #False

# 深拷贝 
import copy
l1 = [1, 2, 3, [11, 22, 33]]
l2 = copy.deepcopy(l1)
print(l1,'>>>',l2)
# [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [11, 22, 33]]
l2[3][0] = 1111
print(l1,">>>",l2)
# [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [1111, 22, 33]]

29. Python垃圾回收机制?

# Python垃圾回收机制
Python垃圾回收机制,主要使用'引用计数'来跟踪和回收垃圾。
在'引用计数'的基础上,通过'标记-清除'(mark and sweep)解决容器对象可能产生的循环引用问题.
通过'分代回收'以空间换时间的方法提高垃圾回收效率。

'引用计数'
PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。
当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,
它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。
    \优点:1.简单 2.实时性
    \缺点:1.维护引用计数消耗资源 2.循环引用

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

'分代技术'
分代回收的整体思想是:
将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,
垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。

30. Python的可变类型和不可变类型?

可变数据类型:列表、字典、可变集合

不可变数据类型:数字、字符串、元组、不可变集合

31. 求结果

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
现有两个元组(('a'),('b')),(('c'),('d')),请使用python中匿名函数生成列表[{'a':'c'},{'b':'d'}]
#匿名函数形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
ret=map(lambda n:{n[0]:n[1]},zip(l1,l2))
print(list(ret))
#列表表达式形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
print([{n[0]:n[1]} for n in zip(l1,l2)])
v = dict.fromkeys(['k1', 'k2'], [])
v['k1'].append(666)
print(v)
v['k1'] = 777
print(v)
结果:
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}

解释:
Python 字典(Dictionary) fromkeys() 函数用于创建一个新字典,以序列seq中元素做字典的键,value为字典所有键对应的初始值,默认为None。
因为所有键对应同一个值,所以对键为‘k1’的值做了添加操作后,其他几个键的值也都添加了相同的值 v1
= dict.fromkeys(['k1', 'k2']) print(v1) # {'k1': None, 'k2': None} v2 = dict.fromkeys(['k1', 'k2'], []) print(v2) # {'k1': [], 'k2': []}

32. 列举常见的内置函数

map

根据函数对指定序列做映射
map()函数接收两个参数,一个是函数,一个是可迭代对象,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

返回值:
  Python2  返回列表
  Python3  返回迭代器

例子1:
def mul(x):
    return x*x
n=[1,2,3,4,5]
res=list(map(mul,n))
print(res)  #[1, 4, 9, 16, 25]

例子2:abs()  返回数字的绝对值
ret = map(abs,[-1,-5,6,-7])
print(list(ret))
# [1, 5, 6, 7]

filter

filter()函数接收一个函数 f(函数)和一个list(可迭代对象),这个函数 f的作用是对每个元素进行判断,返回 True或 False,
filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
def is_odd(x):
    return x % 2 == 1

v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17]))
print(v)  #[1, 7, 9, 17]

reduce

'''
reduce()  函数
reduce() 函数会对参数序列中元素进行累积
函数将一个数据集合(链表、元组等)中的所有数据进行下列操作
'''

注意:
Python3已经将reduce() 函数从全局名字空间里移除了,
它现在被放置在 fucntools 模块里,如果想要使用它,则需要通过引入 functools 模块来调用 reduce() 函数:
from functools import reduce

def add(x,y): return x + y
print(reduce(add,[1,2,3,4,5])) # 15 print(reduce(lambda x, y: x+y, [1,2,3,4,5])) # 15 print(reduce(add,range(1,101))) # 5050

zip

# zip 拉链函数,
# 将对象中对应的元素打包成一个个元组,
# 然后返回由这些元组组成的列表迭代器。
# 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。
print(list(zip([0,1,3],[5,6,7],['a','b'])))
# [(0, 5, 'a'), (1, 6, 'b')]
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]

isinstance\type

isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() 与 type() 区别: type() 不会认为子类是一种父类类型,不考虑继承关系。 isinstance() 会认为子类是一种父类类型,考虑继承关系。 如果要判断两个类型是否相同推荐使用 isinstance()。
# 例一 a = 2 print(isinstance(a,int)) # True print(isinstance(a,str)) # False # type() 与 isinstance() 区别 class A: pass class B(A): pass print("isinstance",isinstance(A(),A)) # isinstance True print("type",type(A()) == A) # type True print('isinstance',isinstance(B(),A) ) # isinstance True print('type',type(B()) == A) # type False

猜你喜欢

转载自www.cnblogs.com/shijieli/p/10398903.html
今日推荐