python面试题目汇总

参考:https://www.cnblogs.com/JetpropelledSnake/p/9396511.html#_label1

1、常见的PEP8规范?

缩进:4个空格

空行:函数与函数之间空两行,类内部的函数之间空一行

命名:
1、函数名小写,可采用下划线加字母;类名单词第一个字母大写,采用驼峰式命名;
2、命名必须有意义,可识别性,不能重复;

长度:每行长度不能超过79,可以采用下划线隔开并另起一行

空格:逗号之后和操作符前后采用空格隔开;

import:不要一次导入多个不是一个类型的库;

常量采用大写

2、进制之间转换?

bin:十进制转二进制,例如 bin(10)=0b1010
oct:十进制转八进制, octonary number system(八进制)
hex:十进制转十六进制,hexadecimal
int:将对应的进制转换成十进制
手动转换参考:https://jingyan.baidu.com/article/495ba84109665338b30ede98.html

3、请编写一个函数实现将IP地址转换成一个整数?

def convert_to_int(ip):
    lst = [int(item) for item in ip.split('.') if item]
    return sum(lst) 

4、python最大递归层数?996

def foo(n):
        print(n)
        n += 1
        foo(n)

    if __name__ == '__main__':
        foo(1)

5、and or or?

x or y:若x为真,则为x,否则为y;
x and y:若x为真,则为y,反之为x。
x and y or z:等价于 x and (y or z)

6、按位运算符:

二进制下运算符号。
&:按位与,都为1则为1
例如 print(10&8)=0b1010 & 0b1000 = 0b1000 = 8

|:有一个为真则为真

:当两个对应的二进制相异时,则结果为1,例如print(10^8)=0b0010=2

7、ascii、unicode、utf8、gbk的区别?

都是编码类型,都包含二进制与字符的对应关系。
ascii:仅仅包含 阿拉伯字母以及某些运算符与二进制的对应关系,最早的编码类型,但最多只能表示一个字节。

unicode:全球通用的编码,包含所有字符与二进制的对应关系;任何字符==2Bytes,所以用来存储英文字符浪费空间。

gbk:本国语言与二进制的对应关系,每个国家都有自己的GBK编码,没有统一起来。一个中文字符2Bytes,一个英文字符1Bytes。

utf8:unicode的升级版本,一个中文字符3Bytes,英文字符1Bytes,欧洲字符==2Bytes。

8、字节码和机器码的区别?

机器码:Native code,原生码,cpu可以直接解读的数据,执行速度最快;
字节码:Byte-code中间状态的二进制代码(文件),需要直译器转译才难成为机器码。

9、is 和 ==?

is比较的是内存地址,可以用id()查看;
==比较的是 值是否相等。

10、可变数据类型和不可变数据类型?

可变数据类型:该数据类型对应的变量的值发生改变,那么它对应的内存地址也会发生改变。例如:list、dict、set。
不可变数据类型:该数据类型对应的值发生改变,它对应的内存地址不会发生改变,例如:str,int,float,tuple。

12、小数据池子

int和str,都存在一个小数据池,在这个范围内,若变量值相同,都会指向同一个内存地址。

int小数据池:int在【-5,256】范围内,创建相同的数字会指向同一个内存地址,超过了这个范围,就会指向不同的地址。

字符串小数据池范围:
1、不能有空格:若有空格,则指向两个内存地址;
2、不能包含特殊字符,若包含特殊字符,则指向两个内存地址。

12、三元运算写法以及应用场景?

结构:结果1 + if + 条件 + else + 结果2,若条件为True,则返回结果1,反之返回结果2。

13、py2和py3的区别?

print格式不同。

range()不同:在py2中是range是列表,xrange才是生成器,在py3只有range且是生成器。

默认编码不同:py2的默认编码是ascii,py3的默认编码是utf8。

14、一行代码实现数值交换?

a,b=b,a

15、列举布尔值为False的常见值?

可以通过三元表达式判断,例如:'true' if 1 else 'else'
数字类型:0为False,其余的为True
None为False
列表、tupe、字典、set等:长度为0为false

16、list、str、tuple、dict每个常用的5个方法?

str:字符串为不可变类型,没有增删改查
    统计:
        count(s):统计s出现的次数

    查询:
        index(s):在指定的索引范围内从左到右找出元素s的索引并返回;
        find(s,begin,end):同index方法;

    格式输出:
        lower():将字母改为小写格式;
        upper():将字母改为大写格式;
        capitalize():将首个字母改为大写;
        strip():删除字符串两侧的空格并返回,但是不改变原字符串;
        format():
            In [32]: '{}-{}-{}'.format('alex','kate','bo')                                  
            Out[32]: 'alex-kate-bo'

            In [33]: '{1}-{0}-{2}'.format('alex','kate','bo')                               
            Out[33]: 'kate-alex-bo'
        swapcase(): 大小写反转。

    类型转换:
        s.split(sep):转换成列表

    替换:
        s.replace(old,new)

    判断is系列:
        isdigits()
        isalpha()
        isnumeric()
        islowe()
        isupper()

    判断开头和结尾:
        startwith(s)
        endwith(s)


list:可变数据类型,可以进行增删改查
    创建列表:list('iterable')

    增加:
    append(s):在列表右侧追加元素;
    extend(iterable):循环可迭代对象并添加到列表中,例如:[1].extend('abcd')=[1,'a','b','c','d'];

    删除:
    pop(index):根据index删除元素并返回index;
    clear():删除所有元素;
    remove(s):从左至右删除找到的第一个元素,没找到匹配的元素则ValueError异常;

    统计:
    count(s):统计s出现的次数

    排序:
    sort(reverse=False):升序,可以指定为降序
    reverse():仅仅颠倒当前列表顺序


字典dict:
    创建字典:
        {}.fromkeys(iterable,val)

    增加或修改:
        d.update({'k1':'v2'}):若字典d存在键k1,则更新其值为v2;若不存在键k1,则增加键值对;
        d.setdefault('k1','v2'):若字典d存在k1,则返回其对应的值,若不存在,则增加键值对{'k1':'v2'}

    删除:
        d.pop('k1'):若k1存在,则删除该键值对,并返回value;若不存在,则报KeyError异常。       
        d.clear():清空字典;
        d.popitem():随机删除键值对;

    查询:
        get('k1','not found')
        d.keys():结构类似[k1,k2,k3],主要这个不是列表,还需要经过转换才难成为列表
        d.values():结构类似[v1,v2,v3]
        d.items():返回结构类似 [(k1,v2),(k2,v2)]


tuple元组:不可变数据类型
    创建字典:tuple(iterable)
    统计:
        count(s)
        index(s)

集合set:无序,且不重复
    增加:
        add(item)
        s.update(s1)
        s.union(s1)

    删除:
        discard(item)
    
    差集:
        s1中但是s2中没有的元素:s1.difference(s2) == s1 - s2  

    交集:
        s1.intersection(s2)

    也可以运用 +、- 运算符。

17、lambda表达式以及应用场景?

函数名=lambda 参数(多个时以逗号隔开):返回值
f=lambda x, y : x*y
参数可以有多个,且只能写一行。

18、pass的作用?

保证程序结构完整,无其他任何作用。

19、*args 和 **kwargs作用?

在函数不确定有多少个参数时候,可以采用可变参数。
*args会将接收到的所有的位置参数转换成列表格式,存放在函数内部作用域内;
**kwargs会将接收到的键值对参数转换成字典格式,存放在函数内部作用域内。

20、深浅拷贝:

浅拷贝只是增加了一个指针指向一个存在的内存地址。
而深拷贝是增加了一个指针并且重新开辟一个内存空间。

单层
import copy
# 浅拷贝
li1 = [1, 2, 3]
li2 = li1.copy()
li1.append(4)
print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3,4]
 
# 深拷贝
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]

21、python垃圾回收机制?

参考:
http://www.cnblogs.com/Xjng/p/5128269.html
http://python.jobbole.com/87843/

1、引用计数:
python里每一个东西都是对象,当对象多了一个引用,则此对象的(PyObject)的计数变量(ob_refcnt)+1,反之-1,
当ob—refcnt=0,此对象会被系统回收;
循环引用:
当对象A和B相互引用,但是没有外部再引用它们任何一个,它们的引用计数虽然都为1,但显然应该被回收。

2、标记清除:
解决循环引用的问题,主要是list、set、dict、instance等容器对象,步骤:
I、先标记上所有活动对象
II、再将所有未活动的对象清除

怎么标记?
从根对象(全局变量、调用栈、寄存器)出发,以引用作为线,来连接内存中的对象。
缺点:简单粗暴,清除非活动对象前必须顺序扫描整个堆内存。

3、分代回收:
将内存根据对象存活的时间由短到长分为三代:年轻代、中年代、老年代,垃圾回收频率以此减少,所以老年代的对象可能存活于系统的整个内存空间。
以空间换时间,具体步骤如下:
新创建的对象会被存放在年轻代,当链表总数(gc计数器)达到上限时,会触发垃圾回收(gc.collect),将那些非活动对象和循环引用的对象回收,将剩余的活动对象转移到中年代,以此类推。

22、匿名函数的应用?

题目1:求结果

def multipliers():
    # 返回包含四个匿名函数的列表
    return [lambda x:i*x for i in range(4)]
    # 注意,若返回生成器,则结果未[0,2,4,6]

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

由于函数未被调用,循环中的i值未被写入函数,经过多次替代,循环结束后i值为3,
故结果为:6,6,6,6

题目2:现有两个元组(('a'),('b')),(('c'),('d')),请使用python中匿名函数生成列表[{'a':'c'},{'b':'d'}]

猜你喜欢

转载自www.cnblogs.com/fqh202/p/python-mian-shi-ti-mu-hui-zong.html