在这里插入图片描述

文章目录


专业、易懂 | 代码可运行 | 覆盖基础与进阶核心考点

一、基础核心模块(必考,占比30%-40%)

1. Python基础语法

Python的核心特性及与其他语言的区别
  • 解释型:代码逐行解释执行,无需编译,调试方便,但执行效率低于编译型语言(如C++、Java)。
  • 面向对象:一切皆对象,支持封装、继承、多态,且支持多继承。
  • 动态类型:变量无需声明类型,运行时自动确定,灵活但可能引入运行时错误。
  • 跨平台:基于CPython解释器,可在Windows、Linux、macOS等系统上运行。
  • 与Java/C++的区别
    • 变量:Python无类型声明,Java/C++需显式声明。
    • 内存管理:Python自动垃圾回收,C++需手动管理。
    • 多线程:Python有GIL(全局解释器锁),计算密集型多线程受限;Java/C++无此限制。
    • 语法风格:Python强制缩进,代码简洁;Java/C++使用花括号。
变量与数据类型
  • 整数(int):任意大小,仅受内存限制。
  • 浮点数(float):双精度浮点数,注意浮点精度问题。
  • 字符串(str):不可变序列,支持Unicode。
  • 布尔值(bool):True/False,可与整数运算(True=1,False=0)。
  • None:表示空值,常用于函数默认返回值或变量占位。

不可变类型 vs 可变类型(核心考点)

类型不可变可变
常见int, float, str, tuplelist, dict, set
特点修改会创建新对象修改不会改变内存地址
# 不可变类型示例
a = 10
print(id(a))  # 140736123456
a += 1
print(id(a))  # 新地址,原对象不变

# 可变类型示例
lst = [1, 2, 3]
print(id(lst))
lst.append(4)
print(id(lst))  # 地址不变
  • list与tuple:list可变,用于数据增删改;tuple不可变,用于固定数据(如配置、字典键)。
  • dict与set:dict存储键值对,键必须不可变;set存储唯一元素,无序。两者底层都是哈希表。
运算符
  • 算术+ - * / // % **(// 整除,** 幂)
  • 比较== != > < >= <= 返回布尔值
  • 逻辑and or not,具有短路特性:False and ... 直接返回False;True or ... 直接返回True
  • 赋值= 以及复合赋值 +=
  • 位运算& | ^ ~ << >>,用于整数二进制操作
# 短路示例
def expensive():
    print("执行")
    return True

if False and expensive():  # expensive不会被调用
    pass

# 优先级:算术 > 比较 > 逻辑 > 赋值
result = 2 + 3 * 4 > 10 and 5 // 2 == 2  # (2+12)>10 and 2==2 -> True and True -> True
流程控制
# if-elif-else
score = 85
if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
else:
    grade = 'C'

# for循环
for i in range(5):      # 0..4
    if i == 2:
        continue        # 跳过本次循环
    if i == 4:
        break           # 终止循环
    print(i)

# while循环
n = 3
while n > 0:
    print(n)
    n -= 1

# pass:空语句,占位
def todo():
    pass

循环嵌套优化技巧:将内层循环中不变的运算提前提取,避免重复计算;使用局部变量加速。

字符串操作
s = "  hello, world!  "
print(s.strip())        # 去除两端空白
print(s.split(','))     # ['  hello', ' world!  ']
parts = ['a', 'b', 'c']
print('-'.join(parts))  # 'a-b-c'
print(s.replace('world', 'Python'))
print(s.find('hello'))  # 2,找不到返回-1
print(s.index('hello')) # 2,找不到抛异常

# 切片 [start:stop:step]
print(s[2:7])   # 'hello'
print(s[::-1])  # 反转

# 字符串格式化:% 旧式,format(),f-string(推荐,Python 3.6+)
name = "Tom"
age = 25
print(f"Name: {name}, Age: {age}")          # 最快、最直观
print("Name: {}, Age: {}".format(name, age))
print("Name: %s, Age: %d" % (name, age))

2. 容器数据结构

列表(list)
# 创建
lst = [1, 2, 3]
lst2 = list(range(5))   # [0,1,2,3,4]

# 增删改查
lst.append(4)           # 末尾加
lst.insert(0, 0)        # 指定位置插入
lst.extend([5,6])       # 合并
lst.pop()               # 删除末尾并返回
lst.remove(2)           # 删除第一个值为2的元素
lst[0] = 99             # 修改

# 排序
lst = [3,1,2]
lst.sort()              # 原地排序,返回None
sorted(lst)             # 返回新列表,原列表不变

# 列表推导式(更高效)
squares = [x**2 for x in range(10) if x % 2 == 0]

# 底层原理:动态数组,超出容量时自动扩容(通常扩容1.125倍或翻倍)
元组(tuple)
t = (1, 2, 3)
t2 = 1, 2, 3            # 括号可省略
single = (1,)           # 单元素元组需加逗号

# 不可变特性:不可增删改,但元素若为可变对象,内部可修改
t3 = ([1,2], 3)
t3[0].append(3)         # 允许,元组内列表id不变

# 元组拆包
a, b, c = t
first, *rest = [10,20,30,40]   # first=10, rest=[20,30,40]
字典(dict)
# 创建
d = {'name': 'Alice', 'age': 20}
d2 = dict(name='Bob', age=25)

# 增删改查
d['score'] = 95         # 增加/修改
del d['age']            # 删除
print(d.get('gender', 'F'))  # 安全获取,不存在返回默认值
print(d.items())        # 键值对视图
print(d.keys())
print(d.values())

# 底层哈希表:键必须可哈希(不可变类型),查找/插入平均O(1)

# Python 3.7+ 字典保持插入顺序,OrderedDict用于需要额外顺序方法的旧版本
from collections import OrderedDict
od = OrderedDict([('a',1), ('b',2)])  # 保持顺序
集合(set)
s = {1, 2, 3}
s2 = set([3,4,5])

s.add(6)
s.remove(3)             # 不存在报错
s.discard(10)           # 不存在不报错

# 集合运算
a = {1,2,3}; b = {3,4,5}
print(a | b)   # 并集 {1,2,3,4,5}
print(a & b)   # 交集 {3}
print(a - b)   # 差集 {1,2}
print(a ^ b)   # 对称差集 {1,2,4,5}

# 去重
names = ['a','b','a','c']
unique = list(set(names))

# 底层也是哈希表,元素必须可哈希
collections模块常用容器
from collections import defaultdict, deque, Counter, namedtuple

# defaultdict:提供默认值
dd = defaultdict(int)   # 缺失键返回0
dd['count'] += 1

# deque:双端队列,高效头尾操作
dq = deque([1,2,3])
dq.appendleft(0)        # 左侧添加
dq.popleft()            # 左侧弹出

# Counter:计数器
cnt = Counter('abracadabra')
print(cnt.most_common(2))  # [('a',5), ('b',2)]

# namedtuple:轻量级数据类
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)

3. 函数基础与进阶

函数定义与参数
def func(a, b=10, *args, c=20, **kwargs):
    """
    a: 位置参数
    b: 默认参数(必须放在位置参数后)
    *args: 可变位置参数,接收元组
    c: 关键字参数(需通过关键字传递)
    **kwargs: 可变关键字参数,接收字典
    """
    print(a, b, args, c, kwargs)

func(1, 2, 3, 4, c=30, name='Tom')
# 输出:1 2 (3,4) 30 {'name':'Tom'}

# 注意:默认参数是可变对象时会有陷阱
def add_item(item, lst=[]):   # 错误示范:lst是共享的
    lst.append(item)
    return lst
print(add_item(1))  # [1]
print(add_item(2))  # [1,2]  预期[2]?实际共享了默认列表

# 正确做法
def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst
返回值
def return_multi():
    return 1, 2, 3       # 实际返回一个元组

x, y, z = return_multi() # 元组拆包

def no_return():
    pass
print(no_return())       # None
闭包

条件:函数嵌套 + 内层函数引用外层变量 + 外层函数返回内层函数。

def outer(x):
    def inner(y):
        return x + y
    return inner

add5 = outer(5)
print(add5(3))  # 8,x被保留在闭包中
装饰器
# 简单装饰器(本质:高阶函数+闭包)
def timer(func):
    import time
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"耗时 {time.time()-start:.4f}s")
        return result
    return wrapper

@timer
def slow_func():
    import time
    time.sleep(0.5)

slow_func()

# 带参数装饰器
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet():
    print("Hello")

greet()  # 打印三次

# 常用内置装饰器
class MyClass:
    @staticmethod
    def static_method(): pass          # 无需self/cls
    @classmethod
    def class_method(cls): pass        # 第一个参数为类
    @property
    def name(self): return self._name  # 将方法转为属性
匿名函数(lambda)
# 语法:lambda 参数: 表达式
square = lambda x: x**2

# 常见应用:排序key
students = [('Tom', 20), ('Jerry', 18)]
students.sort(key=lambda s: s[1])  # 按年龄排序

# 与map/filter结合
nums = [1,2,3,4]
squared = list(map(lambda x: x**2, nums))
evens = list(filter(lambda x: x%2==0, nums))
作用域与global/nonlocal
x = 10      # 全局变量
def outer():
    y = 20  # 外层变量
    def inner():
        nonlocal y   # 修改外层变量
        global x     # 修改全局变量
        y += 1
        x += 1
    inner()
    print(y)
outer()
print(x)

4. 面向对象编程(OOP)

封装、继承、多态
# 封装:将数据和操作封装在类中
class Animal:
    def __init__(self, name):
        self.name = name        # 实例属性
        self._age = 0           # 单下划线:约定保护属性
        self.__weight = 0       # 双下划线:名称修饰,避免子类覆盖

    def speak(self):            # 实例方法
        raise NotImplementedError

    @classmethod
    def from_string(cls, s):    # 类方法
        return cls(s)

    @staticmethod
    def is_animal():            # 静态方法
        return True

# 继承
class Dog(Animal):
    def speak(self):            # 多态:重写父类方法
        return f"{self.name} says woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says meow!"

# 多态:同一接口不同实现
animals = [Dog("Buddy"), Cat("Kitty")]
for a in animals:
    print(a.speak())
MRO与super()
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print(D.__mro__)  # (D, B, C, A, object)  C3算法

class Parent:
    def show(self):
        print("Parent")

class Child(Parent):
    def show(self):
        super().show()   # 调用父类方法
        print("Child")
魔术方法
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __str__(self):
        return f"({self.x},{self.y})"
    def __repr__(self):
        return f"Vector({self.x},{self.y})"
    def __add__(self, other):
        return Vector(self.x+other.x, self.y+other.y)
    def __len__(self):
        return 2

v1 = Vector(1,2)
v2 = Vector(3,4)
print(v1 + v2)      # 调用__add__
print(len(v1))      # 2
@property属性装饰器
class Person:
    def __init__(self, age):
        self._age = age
    @property
    def age(self):
        return self._age
    @age.setter
    def age(self, value):
        if value < 0:
            raise ValueError("Age cannot be negative")
        self._age = value

p = Person(25)
print(p.age)   # 像属性一样访问
p.age = 30     # 调用setter

二、进阶核心模块(高频考,占比25%-35%)

1. 模块与包

模块导入与搜索路径
# 导入方式
import math
from os import path
import sys as system

# 模块搜索路径
import sys
print(sys.path)   # 列表:当前目录、PYTHONPATH、标准库、site-packages

# 动态添加路径
sys.path.append('/my/modules')
包的__init__.py
  • Python 3.3+ 可以省略,但推荐保留以标识目录为包,并可执行初始化代码、控制__all__
# 目录结构
mypackage/
    __init__.py
    module1.py
    module2.py

# __init__.py 内容
__all__ = ['module1']   # 控制 from package import * 的行为
print("Package initialized")
常用内置模块
# sys
import sys
print(sys.argv)          # 命令行参数
sys.exit(0)              # 退出程序

# os
import os
os.listdir('.')          # 列出目录
os.path.join('a','b')    # 路径拼接
os.environ.get('PATH')   # 环境变量

# datetime
from datetime import datetime, timedelta
now = datetime.now()
delta = timedelta(days=1)
yesterday = now - delta

# json / pickle
import json
data = {'name': 'Tom'}
json_str = json.dumps(data)
obj = json.loads(json_str)

import pickle
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)          # 序列化,支持更多Python类型
with open('data.pkl', 'rb') as f:
    restored = pickle.load(f)

# math
import math
math.sqrt(2), math.pi
第三方模块管理
pip install requests
pip uninstall requests
pip freeze > requirements.txt

2. 异常处理

异常与错误
  • 语法错误:代码不符合语法,解释器无法运行。
  • 运行时异常:语法正确,执行时出错,可被捕获。
try-except-else-finally
try:
    n = int(input("输入数字: "))
    result = 10 / n
except ValueError:
    print("不是有效数字")
except ZeroDivisionError:
    print("不能除以零")
except Exception as e:        # 捕获其他所有异常,不推荐
    print(f"未知错误: {e}")
else:
    print(f"结果是 {result}")  # 仅当try无异常时执行
finally:
    print("无论是否异常都执行")  # 常用于释放资源
raise与自定义异常
class ValidationError(Exception):
    """自定义异常"""
    pass

def validate_age(age):
    if age < 0:
        raise ValidationError("年龄不能为负")
    return age

try:
    validate_age(-5)
except ValidationError as e:
    print(e)
常见异常类型
异常场景
SyntaxError语法错误
TypeError类型不匹配
ValueError值不正确
KeyError字典键不存在
IndexError序列索引越界
FileNotFoundError文件不存在
最佳实践
  • 捕获具体异常,避免空except:except Exception:
  • finally中释放资源(关闭文件、释放锁)。
  • 不要滥用异常,正常流程用条件判断。

3. 迭代器与生成器

可迭代对象 vs 迭代器
  • 可迭代对象:实现了__iter__方法,返回迭代器。如list, str, dict。
  • 迭代器:实现了__iter____next__方法,可被next()调用。
# 手动实现迭代器
class CountDown:
    def __init__(self, start):
        self.start = start
    def __iter__(self):
        return self
    def __next__(self):
        if self.start <= 0:
            raise StopIteration
        self.start -= 1
        return self.start + 1

for i in CountDown(3):
    print(i)   # 3,2,1
生成器(yield)
def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

fib = fibonacci(5)
print(list(fib))  # [0,1,1,2,3]

# 生成器表达式(节省内存)
squares = (x**2 for x in range(1000000))  # 不立即生成全部,占内存极小
print(next(squares))  # 0
send()方法
def counter():
    i = 0
    while True:
        val = yield i   # yield接收send的值
        if val is not None:
            i = val
        else:
            i += 1

c = counter()
print(next(c))          # 0
print(c.send(10))       # 将10传给yield,然后继续,输出10
print(next(c))          # 11

4. 装饰器与上下文管理器

类装饰器
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.count = 0
    def __call__(self, *args, **kwargs):
        self.count += 1
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello")

say_hello()
say_hello()
print(say_hello.count)   # 2
上下文管理器(with语句)
# 实现__enter__和__exit__
class ManagedFile:
    def __init__(self, filename):
        self.filename = filename
    def __enter__(self):
        self.file = open(self.filename, 'w')
        return self.file
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()
        return False  # 若返回True,则异常被抑制

with ManagedFile('test.txt') as f:
    f.write('Hello')

# 使用contextmanager装饰器
from contextlib import contextmanager

@contextmanager
def managed_file(filename):
    f = open(filename, 'w')
    try:
        yield f
    finally:
        f.close()

with managed_file('test2.txt') as f:
    f.write('World')
常见应用场景
  • 文件操作:with open(...) as f
  • 数据库连接自动提交/回滚
  • 线程锁自动释放:with lock:

5. 内存管理与垃圾回收

引用计数

Python对象内部维护一个引用计数器,当计数为0时立即销毁。

import sys
a = [1,2,3]
print(sys.getrefcount(a))  # 2(a本身+getrefcount参数引用)
b = a
print(sys.getrefcount(a))  # 3
del b
print(sys.getrefcount(a))  # 2
垃圾回收(GC)
  • 分代回收:处理循环引用(如两个对象互相引用)。Python将对象分为0、1、2三代,新对象在0代,经过一次GC幸存则升代,回收频率随代增高而降低。
  • 标记-清除:GC的辅助算法,从根对象出发标记可达对象,清除未标记对象。
import gc
gc.disable()   # 禁用GC(不推荐)
gc.enable()
gc.collect()   # 手动触发垃圾回收
弱引用(weakref)

弱引用不增加引用计数,用于避免循环引用导致内存泄漏。

import weakref

class Node:
    def __init__(self, value):
        self.value = value
        self.parent = None
        self.children = []

parent = Node(1)
child = Node(2)
parent.children.append(child)
child.parent = weakref.ref(parent)   # 弱引用,不增加引用计数
内存泄漏原因与避免
  • 全局容器不断添加对象而不清理。
  • 循环引用且类定义了__del__(会干扰GC)。
  • 缓存未设置大小限制。

检测工具tracemallocmemory_profilerobjgraph

import tracemalloc
tracemalloc.start()
# ... 运行代码
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
    print(stat)

结语:以上内容覆盖了Python面试中80%以上的核心考点。建议读者动手运行每段代码,并尝试修改参数以加深理解。面试时除了能写出代码,还要能解释底层原理和设计选择。祝面试顺利!


三、实战应用模块(岗位相关,占比20%-30%)

1. 基础实战编程

字符串处理
# 字符串反转
s = "hello"
reversed_s = s[::-1]  # "olleh"

# 字符串去重(保留顺序)
def remove_duplicates(s):
    seen = set()
    result = []
    for ch in s:
        if ch not in seen:
            seen.add(ch)
            result.append(ch)
    return ''.join(result)

print(remove_duplicates("abracadabra"))  # "abrcd"

# 统计字符出现次数
from collections import Counter
s = "abracadabra"
counter = Counter(s)
print(counter['a'])  # 5

# 判断回文(忽略大小写和非字母数字)
def is_palindrome(s):
    cleaned = ''.join(ch.lower() for ch in s if ch.isalnum())
    return cleaned == cleaned[::-1]

print(is_palindrome("A man, a plan, a canal: Panama"))  # True

# 拆分与拼接
s = "a,b,c"
parts = s.split(',')          # ['a','b','c']
joined = '-'.join(parts)      # "a-b-c"
列表/字典/集合操作
# 列表去重(保持顺序)
def list_deduplicate(lst):
    seen = set()
    return [x for x in lst if not (x in seen or seen.add(x))]

# 列表排序(自定义key)
students = [('Tom', 20), ('Jerry', 18), ('Spike', 22)]
students.sort(key=lambda x: x[1])  # 按年龄升序

# 列表合并
a = [1,2,3]; b = [4,5,6]
c = a + b              # [1,2,3,4,5,6]
a.extend(b)            # a变为[1,2,3,4,5,6]

# 字典按键/值排序
d = {'banana': 3, 'apple': 4, 'pear': 1}
# 按键排序
sorted_by_key = dict(sorted(d.items()))           # {'apple':4, 'banana':3, 'pear':1}
# 按值排序
sorted_by_value = dict(sorted(d.items(), key=lambda item: item[1]))  # {'pear':1, 'banana':3, 'apple':4}

# 集合运算实战(找出两个列表的共同元素)
list1 = [1,2,3,4]; list2 = [3,4,5,6]
common = set(list1) & set(list2)   # {3,4}
算法基础
# 冒泡排序
def bubble_sort(arr):
    n = len(arr)
    for i in range(n-1):
        swapped = False
        for j in range(n-1-i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                swapped = True
        if not swapped:
            break
    return arr

# 选择排序
def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        min_idx = i
        for j in range(i+1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

# 插入排序
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i-1
        while j >= 0 and arr[j] > key:
            arr[j+1] = arr[j]
            j -= 1
        arr[j+1] = key
    return arr

# 二分查找(要求数组已排序)
def binary_search(arr, target):
    left, right = 0, len(arr)-1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

arr = [2, 3, 5, 7, 11]
print(binary_search(arr, 5))  # 2
经典小题
# 斐波那契数列
# 递归(效率低,存在重复计算)
def fib_recursive(n):
    if n <= 1:
        return n
    return fib_recursive(n-1) + fib_recursive(n-2)

# 迭代(动态规划,推荐)
def fib_iterative(n):
    if n <= 1:
        return n
    a, b = 0, 1
    for _ in range(2, n+1):
        a, b = b, a+b
    return b

# 生成器版本(节省内存)
def fib_generator(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a+b

print(fib_iterative(10))      # 55
print(list(fib_generator(11)))  # [0,1,1,2,3,5,8,13,21,34,55]

# 阶乘
def factorial(n):
    result = 1
    for i in range(2, n+1):
        result *= i
    return result

# 递归版
def factorial_rec(n):
    return 1 if n <= 1 else n * factorial_rec(n-1)

# 素数判断
def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5)+1):
        if n % i == 0:
            return False
    return True

# 最大公约数(辗转相除法)
def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

# 最小公倍数
def lcm(a, b):
    return a * b // gcd(a, b)

print(gcd(48, 18))   # 6
print(lcm(12, 18))   # 36

2. 文件操作与数据处理

文件读写
# 文本文件读写
# 写入
with open('example.txt', 'w', encoding='utf-8') as f:
    f.write('Hello, 世界!\n')
    f.writelines(['第二行\n', '第三行'])

# 读取
with open('example.txt', 'r', encoding='utf-8') as f:
    content = f.read()          # 全部内容
    # f.readline() 读一行,f.readlines() 读全部行到列表

# 二进制文件(如图片)
with open('image.jpg', 'rb') as src:
    data = src.read()
with open('copy.jpg', 'wb') as dst:
    dst.write(data)

# 编码问题处理
try:
    with open('gbk_file.txt', 'r', encoding='gbk') as f:
        print(f.read())
except UnicodeDecodeError:
    # 尝试其他编码
    with open('gbk_file.txt', 'r', encoding='gb18030') as f:
        print(f.read())
文件操作进阶(os/shutil)
import os
import shutil

# 创建目录
os.makedirs('dir/subdir', exist_ok=True)   # exist_ok避免目录已存在时报错

# 删除文件/目录
os.remove('file.txt')
os.rmdir('empty_dir')           # 只能删除空目录
shutil.rmtree('non_empty_dir')  # 递归删除非空目录

# 复制/移动文件
shutil.copy('src.txt', 'dst.txt')
shutil.move('old.txt', 'new_dir/new.txt')

# 遍历目录
for root, dirs, files in os.walk('.'):
    for file in files:
        print(os.path.join(root, file))
CSV文件读写
import csv

# 写入CSV
data = [
    ['name', 'age', 'city'],
    ['Alice', 25, 'New York'],
    ['Bob', 30, 'London']
]
with open('people.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerows(data)

# 读取CSV
with open('people.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)   # ['name','age','city'] 等

# 使用DictReader/DictWriter(按列名操作)
with open('people.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row['name'], row['age'])
JSON/Pickle序列化
import json
import pickle

# JSON(跨语言,只支持基础类型)
data = {'name': 'Tom', 'age': 30, 'hobbies': ['reading', 'coding']}
json_str = json.dumps(data, ensure_ascii=False, indent=2)  # 转为字符串
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open('data.json', 'r', encoding='utf-8') as f:
    loaded = json.load(f)

# Pickle(Python专用,支持所有对象,但安全性低,不信任源不可用)
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)
with open('data.pkl', 'rb') as f:
    restored = pickle.load(f)

3. 多线程与多进程(后端/大数据岗位重点)

线程与进程的区别 + GIL
  • 进程:资源分配单位,拥有独立内存空间,创建开销大,进程间通信复杂。
  • 线程:CPU调度单位,共享进程内存,创建开销小,但需注意数据同步。
  • GIL(全局解释器锁):CPython中同一时刻只允许一个线程执行Python字节码。因此多线程对CPU密集型任务无效,但对IO密集型任务(网络请求、文件读写)仍有优势,因为IO操作会释放GIL。
多线程(threading)
import threading
import time

def worker(name, delay):
    print(f"线程 {name} 开始")
    time.sleep(delay)
    print(f"线程 {name} 结束")

# 创建线程
t1 = threading.Thread(target=worker, args=('A', 2))
t2 = threading.Thread(target=worker, args=('B', 1))

t1.start()
t2.start()

t1.join()  # 等待t1完成
t2.join()
print("所有线程结束")

# 线程锁(避免竞态条件)
counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(100000):
        with lock:   # 自动获取和释放锁
            counter += 1

threads = [threading.Thread(target=increment) for _ in range(10)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print(counter)  # 1000000
多进程(multiprocessing)
from multiprocessing import Process, Pool, Queue
import os

def cpu_intensive(n):
    """CPU密集型任务:计算素数"""
    count = 0
    for i in range(2, n):
        if all(i % j != 0 for j in range(2, int(i**0.5)+1)):
            count += 1
    return count

# 使用Process
def worker(q, n):
    q.put(cpu_intensive(n))

if __name__ == '__main__':
    q = Queue()
    p = Process(target=worker, args=(q, 100000))
    p.start()
    result = q.get()
    p.join()
    print(result)

# 使用进程池(推荐)
if __name__ == '__main__':
    with Pool(processes=4) as pool:
        results = pool.map(cpu_intensive, [100000, 200000, 300000])
    print(results)
协程(asyncio)
  • 协程:用户态轻量级线程,单线程内实现并发,通过async/await进行非阻塞等待。
  • 优势:极高并发(成千上万连接),内存占用小,无锁竞争。
  • 与多线程/多进程区别:协程是协作式调度(主动让出),多线程是抢占式;协程适合高IO密集型(如Web服务器、爬虫)。
import asyncio

async def fetch_data(delay, name):
    print(f"开始获取 {name}")
    await asyncio.sleep(delay)   # 模拟IO操作,让出控制权
    print(f"完成获取 {name}")
    return f"{name} 的数据"

async def main():
    # 并发执行多个协程
    task1 = asyncio.create_task(fetch_data(2, "A"))
    task2 = asyncio.create_task(fetch_data(1, "B"))
    
    result1 = await task1
    result2 = await task2
    print(result1, result2)

# 运行协程
asyncio.run(main())
IO密集型 vs CPU密集型选型
任务类型推荐方案原因
IO密集型(网络请求、文件读写、数据库查询)多线程 或 协程IO操作释放GIL,线程可并发;协程更轻量
CPU密集型(计算、加密、图像处理)多进程绕过GIL,利用多核CPU

4. 框架相关(根据岗位侧重)

Web框架 - Flask
from flask import Flask, request, jsonify, render_template, Blueprint

app = Flask(__name__)

# 路由定义
@app.route('/')
def home():
    return 'Hello, World!'

# 获取请求参数
@app.route('/user/<int:user_id>')
def get_user(user_id):
    name = request.args.get('name', 'Guest')
    return jsonify({'id': user_id, 'name': name})

# POST请求
@app.route('/data', methods=['POST'])
def handle_data():
    data = request.get_json()
    return jsonify({'received': data}), 201

# 模板渲染(需templates目录)
@app.route('/hello/<name>')
def hello(name):
    return render_template('hello.html', name=name)

# 蓝图(模块化路由)
bp = Blueprint('admin', __name__, url_prefix='/admin')
@bp.route('/dashboard')
def dashboard():
    return 'Admin Dashboard'
app.register_blueprint(bp)

# 中间件(请求前/后钩子)
@app.before_request
def before():
    print("请求前执行")

if __name__ == '__main__':
    app.run(debug=True)
Web框架 - Django(MTV架构简述)
# models.py(模型定义)
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2)

# 查询操作
books = Book.objects.filter(price__lt=50).select_related('author')  # 避免N+1

# views.py(视图)
from django.views.generic import ListView
from .models import Book

class BookListView(ListView):
    model = Book
    template_name = 'book_list.html'
    context_object_name = 'books'

# urls.py(路由)
from django.urls import path
from .views import BookListView

urlpatterns = [
    path('books/', BookListView.as_view(), name='book-list'),
]
数据科学框架 - NumPy
import numpy as np

# 数组创建
arr1 = np.array([1,2,3,4])           # 一维
arr2 = np.zeros((3,4))               # 3x4全0
arr3 = np.random.randn(2,3)          # 标准正态分布

# 索引与切片
arr = np.arange(12).reshape(3,4)
print(arr[0, 1])      # 第0行第1列
print(arr[:, 2])      # 第2列
print(arr[1:, :2])    # 第1行以后,前两列

# 运算
a = np.array([1,2,3]); b = np.array([4,5,6])
print(a + b)          # 逐元素加法
print(a * b)          # 逐元素乘法
print(np.dot(a, b))   # 点积 1*4+2*5+3*6=32

# 统计
print(arr.mean(), arr.std(), arr.sum(axis=0))  # 沿列求和
数据科学框架 - Pandas
import pandas as pd
import numpy as np

# Series与DataFrame
s = pd.Series([1,2,3], index=['a','b','c'])
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'salary': [50000, 60000, 70000]
})

# 数据清洗
# 缺失值处理
df.loc[1, 'age'] = np.nan
print(df.isnull().sum())
df_filled = df.fillna(df['age'].mean())   # 用均值填充

# 去重
df.drop_duplicates(subset=['name'], keep='first', inplace=True)

# 数据筛选
high_salary = df[df['salary'] > 55000]

# 排序
df_sorted = df.sort_values('age', ascending=False)

# 分组统计
grouped = df.groupby('department')['salary'].mean()

# 实战:读取CSV并处理
df = pd.read_csv('data.csv')
df['new_col'] = df['col1'] + df['col2']
df.to_csv('output.csv', index=False)

5. 数据库操作

MySQL(pymysql)
import pymysql

# 连接数据库
conn = pymysql.connect(
    host='localhost',
    user='root',
    password='123456',
    database='testdb',
    charset='utf8mb4'
)

try:
    with conn.cursor() as cursor:
        # 参数化查询(防SQL注入)
        sql = "INSERT INTO users (name, age) VALUES (%s, %s)"
        cursor.execute(sql, ('Tom', 25))
        conn.commit()

        # 查询
        cursor.execute("SELECT id, name FROM users WHERE age > %s", (20,))
        for row in cursor.fetchall():
            print(row)
finally:
    conn.close()
ORM框架 - SQLAlchemy(基础)
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
engine = create_engine('mysql+pymysql://root:123456@localhost/testdb')

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    age = Column(Integer)

Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# 增
user = User(name='Alice', age=28)
session.add(user)
session.commit()

# 查
users = session.query(User).filter(User.age > 25).all()
for u in users:
    print(u.name)

# 改
session.query(User).filter_by(name='Alice').update({'age': 29})
session.commit()

# 删
session.query(User).filter_by(name='Alice').delete()
session.commit()
Redis(redis-py)
import redis

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

# 字符串
r.set('key', 'value')
print(r.get('key'))   # 'value'

# 哈希
r.hset('user:1', mapping={'name': 'Tom', 'age': 25})
print(r.hgetall('user:1'))

# 列表
r.rpush('mylist', 'a', 'b', 'c')
print(r.lrange('mylist', 0, -1))

# 设置过期时间(秒)
r.setex('temp', 10, 'expires in 10s')
MongoDB(pymongo)
from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client['testdb']
collection = db['users']

# 插入
doc = {'name': 'Bob', 'age': 30, 'skills': ['Python', 'MongoDB']}
result = collection.insert_one(doc)
print(result.inserted_id)

# 查询
user = collection.find_one({'name': 'Bob'})
print(user)

# 更新
collection.update_one({'name': 'Bob'}, {'$set': {'age': 31}})

# 删除
collection.delete_one({'name': 'Bob'})

总结:第三部分覆盖了Python面试中常见的实战题型,从基础算法、文件处理到并发编程、数据库操作和框架应用。建议读者针对自己的目标岗位,深入掌握相关模块(如后端岗位重点多线程/多进程、Web框架和数据库)。动手实践是巩固知识的最佳方式,祝面试顺利!


四、综合能力模块(加分项,占比5%-10%)

1. 代码优化

Python代码优化技巧
import timeit
import sys

# 1. 列表推导式替代for循环(更快、更简洁)
# 不推荐
squares = []
for i in range(10):
    squares.append(i**2)

# 推荐
squares = [i**2 for i in range(10)]

# 2. 生成器节省内存(处理大数据集)
# 列表方式:占用大量内存
sum_squares_list = sum([i**2 for i in range(1000000)])   # 先生成全部列表

# 生成器方式:逐个计算,内存占用极小
sum_squares_gen = sum(i**2 for i in range(1000000))      # 生成器表达式

# 查看内存差异
print(sys.getsizeof([i for i in range(10000)]))    # 约 87624 字节
print(sys.getsizeof((i for i in range(10000))))    # 约 112 字节

# 3. 避免冗余计算(将循环内不变的计算提取到外部)
# 不推荐
for i in range(100):
    result = i * len([1,2,3,4,5])   # len每次都计算

# 推荐
length = len([1,2,3,4,5])
for i in range(100):
    result = i * length

# 4. 合理使用内置函数(内置函数通常用C实现,效率高)
from functools import reduce
# 使用sum而非手动累加
nums = [1,2,3,4,5]
total = sum(nums)           # 高效
# total = reduce(lambda a,b: a+b, nums)  # 可读性差且较慢

# 使用any/all代替循环判断
if any(x > 10 for x in nums):   # 遇到第一个True即停止
    print("存在大于10的数")

# 使用map替代显式循环(简单转换时)
list(map(str, [1,2,3]))        # ['1','2','3']
性能分析
# time模块:简单计时
import time
start = time.perf_counter()   # 高精度计时
# 执行代码...
time.sleep(0.1)
end = time.perf_counter()
print(f"耗时: {end-start:.6f}秒")

# timeit模块:精确测量小段代码执行时间(自动重复多次)
import timeit
# 测试列表推导式 vs 显式循环
t1 = timeit.timeit('[i**2 for i in range(100)]', number=10000)
t2 = timeit.timeit('''
squares = []
for i in range(100):
    squares.append(i**2)
''', number=10000)
print(f"列表推导式: {t1:.4f}s, 显式循环: {t2:.4f}s")

# cProfile模块:定位瓶颈函数
import cProfile
def slow_function():
    total = 0
    for i in range(1000000):
        total += i ** 2
    return total

# 在命令行运行:python -m cProfile my_script.py
# 或者在代码中:
cProfile.run('slow_function()')   # 输出函数调用统计,找出耗时最多的函数

2. 项目经验与问题排查

日志分析(logging模块)
import logging

# 配置日志(生产环境推荐)
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('app.log', encoding='utf-8'),  # 输出到文件
        logging.StreamHandler()                            # 输出到控制台
    ]
)
logger = logging.getLogger(__name__)

# 使用不同级别
logger.debug("调试信息")    # 开发时使用
logger.info("正常信息")     # 记录关键操作
logger.warning("警告")      # 潜在问题
logger.error("错误")        # 运行时错误
logger.critical("严重错误") # 程序即将崩溃

# 异常信息完整记录
try:
    1 / 0
except Exception as e:
    logger.exception("捕获到异常")  # 自动记录堆栈信息
线上Bug排查思路
  1. 复现问题:收集用户操作、环境信息、输入数据。
  2. 查看日志:按时间线搜索ERROR、WARNING级别日志,定位首个异常点。
  3. 添加临时诊断日志:在关键路径添加logger.debug,发布后观察。
  4. 检查资源状态:CPU、内存、磁盘、网络连接、数据库连接池。
  5. 二分法定位代码块:注释或跳过可疑模块,缩小范围。
  6. 使用断言验证假设assert condition, "错误信息"
  7. 回滚版本:如近期发版,对比差异。
# 异常排查技巧:捕获特定异常,获取详细信息
try:
    with open('missing.txt') as f:
        data = f.read()
except FileNotFoundError as e:
    logger.error(f"文件不存在: {e}")
    # 可尝试创建默认文件或返回默认值
except PermissionError as e:
    logger.error(f"权限不足: {e}")

3. Python进阶特性与拓展

Python3与Python2的主要区别
特性Python2Python3
printprint "hello"print("hello") 函数形式
整数除法5/2=2(截断)5/2=2.55//2=2
字符串默认ASCII,u"中文"表示Unicode默认Unicode,b"bytes"表示字节串
异常捕获except Exception, e:except Exception as e:
rangerange返回列表,xrange返回生成器range返回可迭代对象(类似xrange)
输入raw_input()input()
函数式编程(map、filter、reduce)
from functools import reduce

# map:对每个元素应用函数
nums = [1,2,3,4]
squared = list(map(lambda x: x**2, nums))   # [1,4,9,16]

# filter:筛选满足条件的元素
evens = list(filter(lambda x: x % 2 == 0, nums))  # [2,4]

# reduce:累积计算
product = reduce(lambda a,b: a*b, nums)  # 1*2*3*4=24

# 列表推导式通常更Pythonic(可读性更好)
squared = [x**2 for x in nums]
evens = [x for x in nums if x % 2 == 0]
推导式大全
# 列表推导式
list_comp = [x*2 for x in range(10) if x % 2 == 0]  # [0,4,8,12,16]

# 字典推导式
dict_comp = {x: x**2 for x in range(5)}  # {0:0,1:1,2:4,3:9,4:16}

# 集合推导式
set_comp = {x%3 for x in range(10)}      # {0,1,2}
上下文管理器高级用法
# 同时管理多个上下文
with open('in.txt') as inf, open('out.txt', 'w') as outf:
    outf.write(inf.read())

# contextlib.closing:自动调用close()(适用于有close方法的对象)
from contextlib import closing
import urllib.request
with closing(urllib.request.urlopen('http://example.com')) as page:
    content = page.read()

# contextlib.suppress:忽略指定异常
from contextlib import suppress
with suppress(FileNotFoundError):
    os.remove('temp.txt')   # 如果文件不存在,不报错
拓展知识速览
  • RESTful API设计:使用HTTP方法(GET/POST/PUT/DELETE),资源用名词复数(/users),状态码规范(200成功、201创建、400错误请求、404未找到)。
  • 接口测试(requests模块)
import requests
resp = requests.get('https://api.github.com/users/octocat')
print(resp.status_code, resp.json()['login'])
# POST JSON数据
resp = requests.post('https://httpbin.org/post', json={'key': 'value'})
  • Docker容器基础Dockerfile定义环境,docker build -t myapp .docker run -p 8080:80 myapp
  • Git版本控制:常用命令 git clonegit addgit commit -mgit pushgit pullgit branchgit merge

五、面试场景补充(适配不同岗位)

初级Python开发

  • 重点模块:一、基础核心模块(全部) + 三.1 基础实战编程 + 二.2 异常处理 + 二.1 模块与包
  • 典型面试题
    • 可变与不可变类型的区别
    • 列表和元组的区别
    • *args**kwargs的作用
    • 如何反转字符串、去重列表
    • try-except-else-finally执行顺序
  • 学习建议:手写代码练习,理解原理而非死记硬背。

中级Python开发

  • 重点模块:一(基础)+ 二(进阶核心全部)+ 三.1(基础编程)+ 三.3(多线程/多进程)+ 三.5(数据库操作)+ 三.4(根据岗位选框架)
  • 典型面试题
    • 装饰器的实现原理和应用场景
    • 生成器和迭代器的区别
    • GIL是什么?如何规避其影响?
    • 进程池和线程池的使用
    • SQL注入如何防范?
    • 如何设计一个简单的RESTful API?
  • 学习建议:深入理解底层实现(如列表动态扩容、字典哈希冲突解决),多写多线程/多进程实例。

高级Python开发

  • 重点模块:全模块覆盖 + 四、综合能力(特别是代码优化、项目经验、性能分析)
  • 典型面试题
    • 如何定位和优化Python程序的性能瓶颈?
    • 设计一个高并发的消息队列系统(结合asyncio、多进程)
    • 如何解决Python内存泄漏问题?
    • 项目中的技术选型考虑(为何选Flask而非Django?)
    • 如何保证微服务架构下的数据一致性?
    • 线上服务CPU飙升如何排查?
  • 学习建议:阅读CPython源码片段,参与开源项目,积累架构设计和故障排查经验。

数据科学/数据分析岗位

  • 重点模块:一(基础,侧重NumPy/Pandas相关)+ 三.4(numpy/pandas)+ 三.1(算法基础)+ 可视化(matplotlib/seaborn简述)
  • 典型面试题
    • Pandas中mergeconcatjoin的区别
    • 如何处理缺失值(dropna、fillna、插值)?
    • NumPy数组和Python列表的性能差异原因
    • 如何用Pandas分组并计算多个聚合函数?
    • 解释groupby后的applytransform区别
  • 学习建议:熟练掌握Pandas数据清洗和特征工程,配合可视化库展示分析结果。

Web开发岗位

  • 重点模块:一、二(基础+进阶)+ 三.4(Flask/Django)+ 三.5(数据库)+ 三.3(多线程/协程用于IO密集型)+ RESTful API
  • 典型面试题
    • Django的ORM如何避免N+1查询?(select_related/prefetch_related
    • Flask上下文(应用上下文、请求上下文)原理
    • 如何实现JWT认证?
    • 异步Web框架(FastAPI/Quart)与同步框架的区别
    • 数据库索引优化和慢查询分析
  • 学习建议:独立完成一个小型Web项目(如博客系统、待办事项API),掌握部署(Nginx+Gunicorn/uWSGI)。

结语:本宝典从基础语法到高并发优化,从单机调试到分布式架构思路,全面覆盖了Python面试的考察维度。真正的掌握需要反复动手实践——让代码成为你的肌肉记忆。祝你在面试中从容应对,斩获心仪Offer!


🌟 感谢您耐心阅读到这里!
💡 如果本文对您有所启发欢迎:
👍 点赞📌 收藏 📤 分享给更多需要的伙伴。
🗣️ 期待在评论区看到您的想法, 共同进步。
🔔 关注我,持续获取更多干货内容~
🤗 我们下篇文章见~

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐