Python面经

Python

基本概念

1. Python是解释型语言还是编译型语言

解释型解释型是边编译边执行。编译型语言是把源程序全部编译成二进制的可运行程序后再运行,如C/C++ 。

注:java程序不是直接编译成机器语言,而是编译成字节码,然后用解释方式执行字节码。

2. Python是面向对象语言还是面向过程语言

面向对象。面向对象编程(OOP)的特点包括:

  • 封装:将数据和操作这些数据的方法组合在一起。
  • 继承:允许新创建的类(子类)继承现有类(父类)的属性和方法。
  • 多态:允许不同类的对象对同一消息做出响应,但具体的行为会根据对象的实际类型而有所不同。

面向过程编程的特点包括:

  • 将程序分解为一系列的过程或函数,每个过程或函数执行特定的任务。
  • 强调过程和函数的调用,而不是对象和类。

3. Python基本数据类型

  • Numbers(数字):3.7以后存储字节数会根据数字大小变化(28+48(num/230))
  • List(列表):有序集合。多维列表本质就是列表里面叠列表
  • Tuple(元组):有序集合。元组是只读的列表
  • Dictionary(字典):无序集合,由键值对(key-value)组成。
  • 集合(set):是一组 key 的集合,每个元素都是唯一不重复无序的。
  • a=(4),a的类型为整数

4.append和 extend区别

  • append()方法用于将一个对象添加到列表的末尾。当使用append()方法添加一个列表到另一个列表时,实际上是将整个列表作为一个单独的元素添加到原列表中。

  • extend()方法用于将一个可迭代对象(如列表、元组、字符串等)的所有元素添加到列表的末尾。使用extend()方法添加一个列表到另一个列表时,实际上是将这个列表中的所有元素逐个添加到原列表中。

my_list = [1, 2, 3]
my_list.extend([4, 5])  # 结果: [1, 2, 3, 4, 5]
my_list.append([5, 6])  # 结果: [1, 2, 3, 4, [5, 6]]

5.del、pop和remove区别

  • del:根据下标进行删除
  • pop:根据下标进行删除并返回删除值,默认删除最后一个元素
  • remove:根据元素的值进行删除
my_list = [1, 2, 3, 4, 5]
del my_list[2]  # my_list: [1, 2, 4, 5]
a=my_list.pop(0)  # my_list: [2, 4, 5], a: 0
my_list.remove(4)  # my_list: [2, 5]

6. sort和sorted区别

  • sorted()是一个内置函数,不会修改原始的序列,而是返回一个新的排序后的列表。不会修改原始的序列,而是返回一个新的排序后的列表。
  • sort()是列表(list)的一个方法,它直接修改原列表,按照指定的顺序对列表中的元素进行排序。
my_list = [3, 1, 4, 1, 5]
my_list.sort()
print(my_list)  # 输出: [1, 1, 3, 4, 5]
sorted_list = sorted(my_list, reverse=True)  # 设置reverse为True进行降序排序
print(my_list)  # 输出: [1, 1, 3, 4, 5]
print(sorted_list)  # 输出: [5, 4, 3, 1, 1]

reverse和reversed同理

my_list = [1, 2, 3, 4, 5]
reversed_iterator = reversed(my_list)
print(list(reversed_iterator))  # 输出: [5, 4, 3, 2, 1]
print(my_list)  # 原始列表未被修改: [1, 2, 3, 4, 5]
my_list.reverse()
print(my_list)  # 输出: [5, 4, 3, 2, 1]

7.介绍一下Python 中的字符串编码

  1. ASCII (American Standard Code for Information Interchange):

    • 最早的字符编码标准,使用7位二进制数表示128个字符,包括英文大小写字母、数字和一些特殊符号。
    • 由于只支持英文字符,因此不适合表示其他语言。
  2. Unicode:

    • 为了解决ASCII编码的局限性,Unicode提供了一种可以表示世界上几乎所有文字的字符集。
  3. UTF-8 (8-bit Unicode Transformation Format):

    • 是Unicode的一种实现方式,可以根据字符的不同使用不同长度(1-4)的字节来表示一个字符。

    • UTF-8最大的特点是它对ASCII编码是兼容的,即ASCII字符在UTF-8中用一个字节表示,与ASCII编码相同。

  • str.encode(): 将字符串编码为指定格式的字节串。
  • bytes.decode(): 将字节串解码为字符串。

8.is 和 == 的区别

==是比较操作符,只是判断对象的(value)是否一致,而 is 则判断的是对象之间的身份(内存地址)是否一致。

对象的身份,可以通过 id() 方法来查看。

9.三元运算

a if condition else b
  • a:当条件condition为真(True)时返回的值。
  • condition:一个布尔表达式,其结果为TrueFalse
  • b:当条件condition为假(False)时返回的值。

进阶

1.shuffle

random.shuffle用于将序列(如列表)中的元素随机打乱位置。它就地修改传入的序列,不返回任何值。

import random

list_items = [1, 2, 3, 4, 5]
random.shuffle(list_items)
print(list_items)  # 输出可能是: [3, 5, 1, 2, 4]

2. 如何判断是函数还是方法

  • 与类和实例无绑定关系的 function都属于函数(function)
  • 与类和实例有绑定关系的 function都属于方法(method)

3. 方法

方法可以分为三种类型:实例方法、类方法和静态方法。

  • 实例方法:依赖于实例的状态,通常用于定义对象的行为。
  • 类方法:依赖于类的状态,通常用于定义与类相关的行为或工厂方法。
  • 静态方法:不依赖于类或实例的状态,通常用于工具函数或不需要访问类或实例数据的方法。
实例方法(Instance Methods)
  • 实例方法是最常见的方法类型,它们需要一个self参数作为第一个参数,代表类的实例本身。
  • 实例方法可以访问和修改实例的状态(属性)。
  • 它们通常用于定义对象的行为。
class MyClass:
    def instance_method(self):
        print("这是实例方法,可以通过实例调用")

obj = MyClass()
obj.instance_method()  # 输出: 这是实例方法,可以通过实例调用
类方法(Class Methods)
  • 类方法是与类相关联的方法,使用@classmethod装饰器定义。
  • 它们需要一个cls参数作为第一个参数,代表类本身。
  • 类方法可以访问和修改类的状态(类属性),但不能访问实例的状态。
  • 它们常用于工厂方法,即根据参数创建类的实例。
class MyClass:
    @classmethod
    def class_method(cls):
        print("这是类方法,可以通过类或实例调用")

# 通过类调用
MyClass.class_method()  # 输出: 这是类方法,可以通过类或实例调用

# 通过实例调用
obj = MyClass()
obj.class_method()  # 同样输出: 这是类方法,可以通过类或实例调用
静态方法(Static Methods)
  • 静态方法是不涉及类或实例数据的方法,使用@staticmethod装饰器定义。
  • 它们不需要selfcls作为第一个参数,这意味着它们不能访问类或实例的属性。
  • 静态方法可以看作是类内部的普通函数,它们仅在需要时通过类来调用。
class MyClass:
    @staticmethod
    def static_method():
        print("这是静态方法,可以通过类或实例调用")

# 通过类调用
MyClass.static_method()  # 输出: 这是静态方法,可以通过类或实例调用

# 通过实例调用
obj = MyClass()
obj.static_method()  # 同样输出: 这是静态方法,可以通过类或实例调用

4.反射

反射(Reflection)是指程序在运行时(Runtime)能够查询和修改自身的属性和方法。

  1. getattr():

    • 根据属性名获取对象的属性值。
    class MyClass:
        def __init__(self):
            self.x = 5
    
    obj = MyClass()
    print(getattr(obj, 'x'))  # 输出: 5
    
  2. setattr():

    • 设置对象的属性值。
    obj = MyClass()
    setattr(obj, 'y', 10)
    print(getattr(obj, 'y'))  # 输出: 10
    
  3. hasattr():

    • 检查对象是否具有指定的属性或方法。
    obj = MyClass()
    print(hasattr(obj, 'x'))  # 输出: True
    

5.元类

元类(Metaclass)是创建类的一种方式,它被称为“类的类”。元类定义了类的创建方式和行为。

class Meta(type):
    def __new__(cls, name, bases, class_dict):
        # 可以在这里修改class_dict
        print(f"Creating class {name}")
        return super().__new__(cls, name, bases, class_dict)

class MyClass(metaclass=Meta):
    pass
# 输出:Creating class MyClass

6.闭包

闭包(Closure)是函数式编程中的一个概念,它指的是一个函数能够记住其创建环境中的变量,即使该环境的执行已经结束。闭包通常由嵌套函数创建,并且能够访问外部函数的非全局变量。

  • 能够访问外部作用域中的变量:闭包可以访问创建它的外部函数中定义的变量。
  • 保持这些变量的绑定:即使外部函数已经执行完毕,闭包仍然能够访问和操作这些变量。
  • 延迟计算:闭包可以推迟对某些变量的计算,直到实际需要它们的时候。
def num():
    return [lambda x:i*x for i in range(4)]
[m(1) for m in num()]  # 输出: [3, 3, 3, 3]

7.装饰器

装饰器(Decorator)本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。用于在不修改原有函数代码的基础上增加函数的新功能。

def my_decorator(func):
    def wrapper():
        print("Something before")
        func()
        print("Something after")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()
# 输出:
# Something before
# Hello!
# Something after

8.isinstance

  • type()不会认为子类是一种父类类型,不考虑继承关系;
  • isinstance()会认为子类是一种父类类型,考虑继承关系。

9.格式化

  1. %操作符

使用%操作符,你可以将值插入到字符串中。这种方法是老版本的Python中常用的格式化方式。

name = "Alice"
age = 30
print("Name: %s, Age: %d" % (name, age))
# 输出: Name: Alice, Age: 30
print("Pi: %.2f" % 3.1415926)  
# 输出: Pi: 3.14
  1. str.format()方法

str.format()方法提供了一个更现代且灵活的字符串格式化方式。你可以在字符串中使用花括号{}作为占位符,然后调用format()方法传入相应的值。

name = "Alice"
age = 30
print("Name: {}, Age: {}".format(name, age))
# 输出: Name: Alice, Age: 30

# 也可以指定位置和格式
print("Name: {0}, Age: {1}".format(name, age))
print("Name: {1}, Age: {0}".format(age, name))

print("Pi: {:.2f}".format(3.1415926))
# 输出: Pi: 3.14
  1. f-string(格式化字符串字面量)

Python 3.6+ 引入了f-string,提供了一种非常简洁和易读的方式来格式化字符串。在字符串前加上字母f,然后直接在花括号{}中写入变量名或表达式。

name = "Alice"
age = 30
print(f"Name: {name}, Age: {age}")
# 输出: Name: Alice, Age: 30

# 直接在字符串中进行表达式计算
print(f"Age squared: {age**2}")

10.浅拷贝(Shallow Copy)&深拷贝(Deep Copy)

  • 浅拷贝复制的是原始对象中包含的引用,而不是对象本身。
  • 深拷贝递归地复制了原始对象中的所有对象。这意味着深拷贝会创建原始对象的完整副本,包括所有嵌套的对象,修改原始对象不会影响深拷贝。
import copy
original_list = [[1, 2, 3], [4, 5, 6]]

shallow_copied_list = copy.copy(original_list)
# 浅拷贝
original_list[0][0] = 'X'
print(shallow_copied_list)  # 输出: [['X', 2, 3], [4, 5, 6]]
# 深拷贝
deep_copied_list = copy.deepcopy(original_list)
original_list[0][0] = 'X'
print(deep_copied_list)  # 输出: [[1, 2, 3], [4, 5, 6]]

11.lambda

lambda是一个用于创建匿名函数的关键字。匿名函数是一种没有名称的函数,它们通常用于需要函数对象的地方,但又不想去定义一个完整的函数。

people = [("Alice", 30), ("Bob", 25), ("Charlie", 35)]
sorted_people = sorted(people, key=lambda person: person[1])
print(sorted_people)  # 输出: [('Bob', 25), ('Alice', 30), ('Charlie', 35)]

12.规约函数reduce

reduce(function, iterable, initializer=None)
  • function:二元操作函数,接受两个参数。应用于iterable的元素。
  • iterable:要累积的序列或可迭代对象。
  • initializer(可选):指定累积的初始值。默认无。

function函数先对集合中的第 1、2 个元素进行操作,得到的结果再与后续数值运算,最后得到一个结果。

13. __new__ 和 __init__区别

  • __new__负责创建对象,__init__负责初始化对象。
  • __new__是一个静态方法,__init__是一个实例方法。
  • __new__必须返回一个实例,__init__不返回任何值。
  • __new____init__之前被调用。

14. *arg 和**kwarg作用

  • *args代表可变数量的位置参数(arguments),它允许你将不定数量的位置参数传递给函数。这些参数被组织为一个元组(tuple),在函数内部可以通过索引来访问。

  • **kwargs代表可变数量的关键字参数(keyword arguments),它允许你将不定数量的关键字参数传递给函数。这些参数被组织为一个字典(dictionary),在函数内部可以通过键来访问。

def my_function(*args, **kwargs):
    for arg in args:
        print(arg)
    for key, value in kwargs.items():
        print(f"{key}: {value}")

my_function(1, 2, name="Alice", age=25)
# 输出: 1, 2, name: Alice, age: 25

15.yield

yield是一个关键字,用于在函数中定义一个生成器(generator)。生成器是一种特殊的迭代器,它允许你逐个产生值,而不是一次性计算并存储所有值。使用yield可以暂停函数的执行,保留当前函数的状态,并在下一次迭代时从它离开的地方继续执行。

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

# 使用生成器
fib = fibonacci(10)
for num in fib:
    print(num)
# 输出斐波那契数列的前10个数

16. zip

将多个可迭代对象(如列表、元组、字符串等)中对应的元素打包成一个个元组,然后返回由这些元组组成的迭代器

# 列表
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']

# 使用zip函数
zipped = zip(list1, list2)

# 将zip对象转换为列表查看结果
print(list(zipped))
# 输出: [(1, 'a'), (2, 'b'), (3, 'c')]

17.排序

排序算法

18.正则表达式

  1. 字符:正则表达式中的普通字符(例如,字母、数字、标点符号)匹配自身。
  2. 量词:
    • *:匹配前面的字符零次或多次。
    • +:匹配前面的字符一次或多次。
    • ?:匹配前面的字符零次或一次。
    • {n}:匹配确定的n次。
    • {n,}:至少匹配n次。
    • {n,m}:最少匹配n次,最多匹配m次。
  3. 字符类:
    • [abc]:匹配任何一个字符(a、b或c)。
    • [^abc]:匹配任何不是字符类中列出的字符。
    • .:匹配任何单个字符(除了换行符)。
  4. 锚点:
    • ^:匹配字符串的开始位置。
    • $:匹配字符串的结束位置。
  5. 分组:
    • ():将多个表达式组合成一个子表达式,并捕获匹配的文本。
  6. 选择:
    • |:逻辑“或”,匹配两个表达式中的任意一个。
  7. 否定:
    • ^(在字符类中):匹配任何不在字符类中的字符。
    • \b:匹配单词边界。
    • \B:匹配非单词边界。

Python通过re模块提供对正则表达式的支持。以下是一些常用的函数:

  • re.match():从字符串的开始位置匹配一个模式。
  • re.search():扫描整个字符串,寻找第一个位置的匹配。
  • re.findall():找出字符串中所有匹配的模式。
  • re.finditer():返回一个迭代器,每次迭代返回一个match对象。
  • re.sub():替换字符串中的匹配项。
  • re.split():根据匹配的模式分割字符串。

19.猴子补丁

猴子补丁(Monkey Patching)是一种在运行时动态地修改或扩展代码的行为。

class MyClass:
    def my_method(self):
        print("Original method")

# 直接修改方法
def new_method(self):
    print("New method")

MyClass.my_method = new_method
obj = MyClass()
obj.my_method()  # 输出: New method

20.assert

在Python中,assert是一个内置的关键字,用于断言某个条件是真的。如果条件为真,则程序继续执行;如果条件为假,则程序抛出AssertionError异常。assert通常用于调试阶段,确保代码中的某些条件一定为真,从而避免潜在的错误。

  • assert的基本语法如下:

    • 条件:一个布尔表达式,必须为真。
    • "可选的错误信息":如果省略,当断言失败时,默认的错误信息是AssertionError;如果提供,将显示该错误信息。
  • assert语句不会影响程序的逻辑,它们仅用于调试目的。在生产环境中,通常应该避免使用assert

  • 可以通过Python解释器的-O(优化)选项关闭assert语句。在优化模式下,所有的assert语句都会被忽略,不会执行。

# 1
def divide(a, b):
    assert b != 0, "除数不能为0"
    return a / b

divide(10, 0)  # 抛出 AssertionError: 除数不能为0
# 2
def add(a, b):
    assert isinstance(a, (int, float)) and isinstance(b, (int, float)), "参数必须是数字"
    return a + b

add("10", 5)  # 抛出 AssertionError: 参数必须是数字

def test_add():
    assert add(1, 2) == 3, "1 + 2 应该等于 3"
    assert add(-1, 1) == 0, "(-1) + 1 应该等于 0"

test_add()
  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python面经八股文是指在面试过程中经常会被问到的一些关于Python语言的基础知识问题。这些问题常常是考察面试者对Python语法、数据类型、函数库等方面的理解和应用。 第一个问题通常是问到Python的特点,比如动态语言、解释型语言等。随后可能会问到Python的命名规范,如变量名、函数名等的命名规则。 接下来可能会被问到Python的数据类型,如字符串、列表、字典和元组的特点和用法。还会询问如何进行类型转换和切片操作。 然后可能会被问到Python的函数,包括如何定义函数、函数参数的类型和默认值,以及如何调用函数和返回值等。 接着可能会被问到Python的模块和库的使用,如time、datetime、random等常用模块的函数和方法。还可能问到如何处理文件、异常等知识点。 另外,面试者还可能会被问到Python的面向对象编程的相关知识,如类和对象的概念、实例化对象、继承和多态等。 最后,可能会被问到Python的常用框架和库,如Django、Flask和NumPy等。还可能会问到如何进行数据库操作、网络编程等相关知识点。 在面试中回答这些问题需要准备充分,对Python的基础知识和常用库要熟悉,并能够清晰地表达自己的观点和经验。同时也可以结合项目经验等实际经历进行回答,展示自己的实际应用能力。 ### 回答2: Python面经八股文主要包括以下几个方面: 一、Python基础知识: 1. 数据类型:了解Python中的常见数据类型,包括字符串、列表、元组、字典等,并能灵活运用。 2. 控制结构:熟悉Python的控制结构,如条件语句、循环语句和异常处理等,并能正确使用。 3. 函数和模块:了解函数和模块的概念,在项目中能够定义并调用函数,以及导入和使用模块。 4. 文件操作:了解Python中的文件操作方法,能够对文件进行读写操作。 5. 面向对象编程:理解面向对象编程的概念,能够定义类、创建对象,并掌握继承、多态等特性。 二、Python常用库和框架: 1. Numpy:了解Numpy库的基本用法,包括数组的创建和操作,矩阵运算等。 2. Pandas:熟悉Pandas库的数据处理功能,包括数据的读取、清洗、排序、合并等。 3. Matplotlib和Seaborn:掌握Matplotlib和Seaborn库用于数据可视化的操作,能够生成各种统计图表。 4. Scikit-learn:熟悉Scikit-learn库的机器学习算法,能够进行数据预处理、特征工程和模型训练等。 三、数据库操作: 1. SQL语言:了解SQL语言的基本语法,能够编写简单的SQL查询语句,实现数据的增删改查等操作。 2. MySQL或MongoDB:了解MySQL或MongoDB数据库的基本操作,包括连接数据库、创建表、插入数据等。 3. ORM框架:熟悉Django或SQLAlchemy等ORM框架的使用,能够进行数据库的ORM操作。 四、Web开发: 1. Flask或Django:了解Flask或Django框架的基本使用方法,能够搭建简单的Web应用。 2. RESTful API:熟悉RESTful API的设计原则,能够使用Flask或Django开发和部署API接口。 3. HTML和CSS:掌握基本的HTML和CSS知识,能够进行网页布局和样式设计。 总结起来,Python面经八股文主要包括Python基础知识、常用库和框架、数据库操作以及Web开发等内容。熟练掌握这些知识点,能够在面试中展现出扎实的编程基础和项目经验,提高自己的面试竞争力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值