Python相关面经整理

本文介绍了Python编程中的基础概念,如xrange和range的区别,PEP8编码规范,Python之禅和docstring的使用,变量注释,数据类型及其操作,字符串处理方法,编码转换,垃圾回收机制,函数装饰器,类和对象的特性,异常处理,递归,isinstance和lambda表达式,dir()函数,异常类型,浅拷贝与深拷贝,以及sort和sorted的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://t.csdnimg.cn/Lugucicon-default.png?t=N7T8http://t.csdnimg.cn/Luguc有完整资源的面经,不收费用自取,点个赞吧。
1.xrange 和 range 的区别?

xrange用法与range完全相同,所不同的是生成的不是一个数组,而是一个生成器。
要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间,这两个基本上都是在循环的时候用。

2.什么是 PEP8?

PEP是 Python Enhancement Proposal 的缩写,翻译过来就是 Python增强建议书
简单说就是一种编码规范,是为了让代码“更好看”,更容易被阅读
具体可参考:
https://www.python.org/dev/peps/pep-0008/

3.了解 Python 之禅吗?

import this

4.了解 docstring 吗?

Python有一个很奇妙的特性,称为 文档字符串 ,它通常被简称为 docstrings 。DocStrings是一个重要的工具,由于它帮助你的程序文档更加简单易懂,你应该尽量使用它。你甚至可以在程序运行的时候,从函数恢复文档字符串。
使用魔法方法'__doc__'可以打印docstring的内容

5.如何给变量加注释?

参数注释:以冒号(:)标记
返回值注释:以 -> 标记
示例:
def add(x:int, y:int) -> int:
    return x + y

6.列举 Python 中的基本数据类型。

Python3 中有六个标准的数据类型:

Number(数字)
String(字符串)
List(列表)
Tuple(元组)
Set(集合)
Dictionary(字典)
Python3 的六个标准数据类型中:

不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

7.将 "hello world" 转换为首字母大写 "Hello World"。

z = 'hello world'
z.title()

8.如何检测字符串中只含有数字?

# 分为两种情况
# 1.不包含正负号 +-
a = '32323'
a.isdigit()

9.将字符串 "ilovechina" 进行反转。

s = 'ilovechina'
s = s[::-1]

10.Python 中的字符串格式化方式你知道哪些?

# Python3.6之后的版本提供了三种字符串格式化的方式
# 1. %s占位符
def foo(name):
  return 'hello %s' % name
# 2. format()
def foo(name):
  return 'hello {}'.format(name)
# f-string
def foo(name):
  return f'hello {name}'

11.有一个字符串开头和末尾都有空格,比如 " adabdw "。要求写一个函数把这个字符串的前后空格都去掉。

s = " adabdw "
s.strip()

12.一个编码为 GBK 的字符串 S,要将其转成 UTF-8 编码的字符串,应如何操作?

s.encode('utf-8')

13.怎样将字符串转换为小写?

b = 'HHH'
b.lower()

14.已知 AList = [1,2,3,1,2],对 AList 列表元素去重,写出具体过程。

a_list = [1,2,3,1,2]
ss = set(a_list)

15.给定两个 list,A 和 B,找出相同元素和不同元素。

list_a = [1,2,3,4,5,6]
list_b = [2,3,6]
set1 = set(list_a)
set2 = set(list_b)
# 相同元素
print(set1&set2)
# 不同元素
print(set1^set2)

16.用一行代码展开该列表 [[1,2],[3,4],[5,6]],得出[1,2,3,4,5,6]。

mm = [[1,2],[3,4],[5,6]]
[j for a in mm for j in a]

17.合并列表 [1,5,7,9] 和 [2,2,6,8]。

a = [1,5,7,9]
b = [2,2,6,8]
# 方法1
a.extend(b)
# 方法2
a[0:0] = b
# 方法3
a += b

18.如何打乱一个列表的元素?

import random
a = [1,5,7,9]
random.shuffle(a)

19.字典操作中 del 和 pop 有什么区别?

del 操作删除键值对,不返回值;
pop 操作删除键值对的同时,返回键所对应的值。

20.将如下字典按照年龄排序。

d1 = [
    {'name':'alice', 'age':38},
    {'name':'bob', 'age':18},
    {'name':'Carl', 'age':28},
]

sorted(d1,key=lambda x:x['age'])

21.请合并下面两个字典 a = {"A":1,"B":2},b = {"C":3,"D":4}。

# python3合并字典有三种方式
# 1.
a = {'a':1,'b':2}
b = {'c':3,'d':4}
c = {}
c.update(a)
c.update(b)
# 2.
c = dict(a,**b)
# 3.
c = {**a,**b} # 官方推荐这种方式

22.如何把 元组 ("a","b") 和 元组(1,2),变为字典{"a":1,"b":2}?

a = ('a','b')
b = (1,2)
z=zip(a,b)
c = dict(z)

23.我们知道对于列表可以使用切片操作进行部分元素的选择,那么如何对生成器类型的对象实现相同的功能呢?

使用自带的itertools库进行实现,具体实现方式 itertools.islice(生成器对象,起始位置,结束位置),即可实现切片功能。

24.在读文件操作的时候会使用 read、readline 或者 readlines,简述它们各自的作用。

read将整个文本都读取为一个字符串,占用内存大,readline读取为一个生成器,支持遍历和迭代,占用空间小。readlines将文本读取为列表,占用空间大

25.json 序列化时,默认遇到中文会转换成 unicode,如果想要保留中文怎么办?

使用json.dumps函数时,添加参数ensure_ascii=False,如果想显示的更美观,可以添加indent=2参数,会在每个key值前添加两个空格。

26.Python 字典和 json 字符串相互转化方法。

json.dumps()   将Python中的对象转换为JSON中的字符串对象
json.loads()   将JSON中的字符串对象转换为Python中的对象

27.函数装饰器有什么作用?请列举说明。

函数装饰器可以在不修改原函数的条件下,为原函数添加额外的功能,例如记录日志,运行性能,缓存等
以记录函数运行时间为例,实现一个装饰器
import time
def time_it(func):
    def wrapper(func):
        start_time = time.time()
        res = func()
        end_time = time.time()
        return start_time - end_time
    return wrapper
  

28.简述 Python 垃圾回收机制。

引用计数机制:
python里每一个东西都是对象,它们的核心就是一个结构体:PyObject
 typedef struct_object {
 int ob_refcnt;
 struct_typeobject *ob_type;
} PyObject;

PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少
#define Py_INCREF(op)   ((op)->ob_refcnt++) //增加计数
#define Py_DECREF(op) \ //减少计数
    if (--(op)->ob_refcnt != 0) \
        ; \
    else \
        __Py_Dealloc((PyObject *)(op))

当引用计数为0时,该对象生命就结束了。
引用计数机制的优点:
简单
实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时

29.魔法函数 __call__怎么使用?

class Bar:
    def __call__(self, *args, **kwargs):
        print('i am instance method')

b = Bar()  # 实例化
b()  # 实例对象b 可以作为函数调用 等同于b.__call__ 使用
# OUT: i am instance method
# 带参数的类装饰器
class Bar:
    def __init__(self, p1):
        self.p1 = p1
    def __call__(self, func):
        def wrapper():
            print("Starting", func.__name__)
            print("p1=", self.p1)
            func()
            print("Ending", func.__name__)
        return wrapper
@Bar("foo bar")
def hello():
    print("Hello")

30.如何判断一个对象是函数还是方法?

判断对象是函数或方法应该使用type(obj)

31.简述 @classmethod 和 @staticmethod 用法和区别。

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢
从它们的使用上来看,
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码
class A(object):
    bar = 1
    def foo(self):
        print 'foo'
 
    @staticmethod
    def static_foo():
        print 'static_foo'
        print A.bar
     @classmethod
    def class_foo(cls):
        print 'class_foo'
        print cls.bar
        cls().foo()
A.static_foo()
A.class_foo()

32.Python 中的接口如何实现?

#抽象类加抽象方法就等于面向对象编程中的接口
from abc import ABCMeta,abstractmethod
class interface(object):
    __metaclass__ = ABCMeta #指定这是一个抽象类
    @abstractmethod  #抽象方法
    def Lee(self):
        pass
    def Marlon(self):
        pass
class RelalizeInterfaceLee(interface):#必须实现interface中的所有函数,否则会编译错误
    def __init__(self):   
        print '这是接口interface的实现'
    def Lee(self):
        print '实现Lee功能'       
    def Marlon(self):
        pass  

33.请列举你知道的 Python 的魔法方法及用途。

1. __call__:允许一个类的实例像函数一样被调用。实质上说,这意味着 x() 与 x._call_() 是相同的
2.__init__:显示初始化属性
3.__str__,__repr__,定义类的时候,重写这两个方法可以让类更清晰
再就是__setattr__,__getattr__,__delattr__等等

34.简述 any() 和 all() 方法。

#any(x)判断x对象是否为空对象,如果都为空、0、false,则返回false,如果不都为空、0、false,则返回true

#all(x)如果all(x)参数x对象的所有元素不为0、''、False或者x为空对象,则返回True,否则返回False

35.什么是猴子补丁?

猴子补丁是一个概念,不是python中发明的,其他动态语言也有这么个概念。 《松本行弘的程序世界》这本书,里面专门有一章讲了猴子补丁的设计,所谓的猴子补丁的含义是指在动态语言中,不去改变源码而对功能进行追加和变更

36.当退出 Python 时是否释放所有内存分配?

答案是否定的。那些具有对象循环引用或者全局命名空间引用的变量,在 Python 退出是往往不会被释放
另外不会释放 C 库保留的部分内容。

37.Python 中的 is 和 == 有什么区别?

is比较的是两个对象的id值是否相等,也就是比较两个对象是否为同一个实例对象,是否指向同一个内存地址。
==比较的是两个对象的内容是否相等,默认会调用对象的__eq__()方法。

38.Python 中的作用域有哪些?

L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内建作用域

39.了解 enumerate 吗?

# 遍历列表时候,携带索引index
a = ['a','b','c']
for index,item in enumerate(a):
    print(index,item)

40.请对 Python 中的异常处理写一个简单的应用场景。

class NameTooShortError(ValueError):
    pass
def validate(name):
    if len(name) < 10:
        raise NameTooShortError(name)
       
# 使用自定义异常类,使得发生异常时的错误更容易排查

41.Python 中递归的最大次数是多少?如何突破?

python解释器限制最大的递归深度是999,可以通过
import sys
sys.setrecursionlimit(10000)  # set the maximum depth as 10000
重新设置最大递归深度

42.简述 isinstance 的作用以及应用场景。

来判断一个对象是否是一个已知的类型
举个栗子:
 p= 'sfa'
 isinstance(p,str)
 True

43.lambda 表达式格式以及应用场景。

d = {'a':2,'b':1,'c':3,'d':'4'}
sorted(d,key=lambda x :x[1])
# 将字典d按照值排序

44.dir() 是用来干什么的?

dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。

45.列举 5 个 Python 中的异常类型以及其含义。

1. ArithmeticError 此基类用于派生针对各种算术类错误而引发的内置异常: OverflowError, ZeroDivisionError, FloatingPointError
2. BufferError 当与 缓冲区 相关的操作无法执行时将被引发。
3. LookupError 此基类用于派生当映射或序列所使用的键或索引无效时引发的异常: IndexError, KeyError。 这可以通过 codecs.lookup() 来直接引发
4. ImportError 当 import 语句尝试加载模块遇到麻烦时将被引发。 并且当 from ... import 中的 "from list" 存在无法找到的名称时也会被引发
5. IndexError 当序列抽取超出范围时将被引发。 (切片索引会被静默截短到允许的范围;如果指定索引不是整数则 TypeError 会被引发

46.浅拷贝(copy) 和深拷贝(deepcopy) 的区别是什么?

copy 即所谓的浅拷贝,赋值的时候非递归地复制子对象的引用;
deepcopy 即所谓的深拷贝,赋值的时候递归复制子对象。

47.请阐述代码中经常遇到的 *args, **kwargs 的含义及用法。

这两个是python中的可变参数。*args表示任何多个位置参数,它是一个tuple;**kwargs表示关键字参数,它是一个dict。并且同时使用*args和**kwargs时,必须*args参数列要在**kwargs前

48.Python 中会有函数或成员变量包含单下划线前缀和结尾,或双下划线前缀结尾,它们的区别是什么?

前置单下划线_var:命名约定,用来表示该名称仅在内部使用。一般对 Python 解释器没 有特殊含义(通配符导入除外),只能作为对程序员的提示。
后置单下划线 var_:命名约定,用于避免与 Python 关键字发生命名冲突。
前置双下划线__var:在类环境中使用时会触发名称改写,对 Python 解释器有特殊含义。
前后双下划线__var__:表示由 Python 语言定义的特殊方法。在自定义的属性中要避免
使用这种命名方式。

49.举例 sort 和 sorted 的区别。

sort()与sorted()的不同在于,sort是在原位重新排列列表,而sorted()是产生一个新的列表

50.pprint 模块是干什么的?

print()和pprint()都是python的打印模块,功能基本一样,唯一的区别就是pprint()模块打印出来的数据结构更加完整,每行为一个数据结构,更加方便阅读打印输出结果。特别是对于特别长的数据打印,print()输出结果都在一行,不方便查看,而pprint()采用分行打印输出,所以对于数据结构比较复杂、数据长度较长的数据,适合采用pprint()打印方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好事(花生)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值