python面试总结
目录
Python基础
1、python及其特点
2、动态类型和静态类型?
3、变量命名规则是什么?
4、基本数据类型有哪些?
5、Python 中字典?
6、集合set是什么?有什么特点?
7、python的字符串格式化
函数
1、什么是函数?如何定义一个函数?
2、什么是参数和返回值,如何在函数中返回多个值??
3、什么是默认参数?什么是可变参数(*args 和 **kwargs)
4、什么是递归函数?如何使用 lambda 函数?请给出示例。
5、什么是装饰器?请给出示例。
6、如何处理函数中的异常?请给出示例。
7、什么是闭包(closure)?
8、如何使用 map()、filter() 、reduce()和zip 函数?
面向对象
1、类和对象基本定义,如何定义一个类?
2、构造函数(__init__)?封装?继承?多态?
3、什么是类方法和静态方法
4、如何使用 super() 函数?
5、什么是抽象类和接口
模块与包
1、模块?
2、包
3、pip安装
4、常用模块
sys、os模块
异常
1、异常?处理异常?
2、异常控制实现机制
3、自定义异常
4、上下文管理器?with语句?
文件操作
1、文件的读写
2、二进制文件操作
正则
1、正则?使用?
2、python的re模块
3、贪婪、非贪婪?
4、查找与替换
测试
1、单元测试
2、unittest、pytest
3、测试用例和测试套件
4、如何进行代码覆盖率测试?
设计模式
1、什么是单例模式?使用场景,如何实现?
2、什么是工厂模式?使用场景,请给出示例。
3、什么是观察者模式?使用场景,请解释。
其他
1、生成器、迭代器
2、协程
3、json模块
4、pickle 模块
5、GIL
6、如何优化 Python 代码的性能?
Python基础
1、python及其特点
Python 是一种由 Guido van Rossum 于 1991 年发布的高级、解释型、交互式、面向对象的脚本语言。它具有清晰简洁的语法、丰富的标准库和强大的社区生态,常用于 Web 开发、数据分析、人工智能、自动化运维、科学计算等领域。Python 强调可读性和简洁性,让开发者能用更少的代码完成更多的工作;
特点如下
简洁易读:通过强制缩进(Indentation)来组织代码块,避免了冗长的括号和关键字。
动态类型:变量在运行时才绑定类型,代码更灵活。
丰富的标准库(“Batteries included”):内置模块涵盖文件 I/O、网络通信、正则、数据库、XML、测试等各方面。
多范式支持:支持过程式、面向对象、函数式编程。
跨平台:同一份代码可在 Windows、macOS、Linux 等平台运行。
可扩展性:可通过 C/C++/Java 等语言编写扩展模块,提升性能或复用已有代码。
自动内存管理:垃圾回收机制(GC)和引用计数,减少内存泄漏风险。
强大的社区和第三方生态:PyPI 上有超过 40 万个包,几乎涵盖所有应用场景。
2、动态类型和静态类型?
动态类型(Dynamic Typing):变量在运行时才绑定类型,类型检查在运行时进行,赋值时可改变类型。
静态类型(Static Typing):变量在编译时就确定类型,类型不易改变,编译器会在编译阶段进行类型检查。
特性 | 静态类型语言 | 动态类型语言 |
---|---|---|
类型检查时间 | 编译时 | 运行时 |
变量声明 | 需要指定类型 | 不需要指定类型 |
灵活性 | 较低 | 较高 |
错误发现时间 | 编译阶段 | 运行阶段 |
典型语言 | Java、C++、Go | Python、JavaScrip |
3、变量命名规则是什么?
1)、由字母(A–Z、a–z)、数字(0–9)和下划线(_)组成;2)、不能以数字开头;区分大小写(myVar ≠ myvar);3)、不能使用 Python 保留关键字(如 if、for、class 等);4)、推荐遵循 PEP8 风格:模块和函数使用 snake_case,类使用 CamelCase。尽量语义化命名,避免单字符(除循环索引等常见场景)。
4、基本数据类型有哪些?
数值:int(任意精度整数)、float(双精度浮点)、complex(复数)
布尔:bool(True/False)、文本:str(Unicode 字符串)
二进制:bytes(不可变)、bytearray(可变);序列:list(可变)、tuple(不可变)、range
集合:set(可变)、frozenset(不可变)
映射:dict(键值对)、特殊:NoneType(仅有值 None)
Python中列表list于元组tuple的区别
特性 | 列表 (list) | 元组 (tuple) |
---|---|---|
可变性 | 可变(mutable) | 不可变(immutable) |
语法 | [1, 2, 3] | (1, 2, 3) 或 1,2,3 |
适用场景 | 需要频繁增删改 | 固定数据、可做字典键 |
性能 | 稍慢,内存稍大 | 稍快,内存稍小 |
方法 | append, pop, ... | 仅 count, index |
列表中添加元素、删除元素、反转列表,找到列表最大最小值,列表排序、列表推导式?
添加元素 | append(x):列表末尾添加单个元素; extend(iterable):列表末尾添加可迭代对象中的所有元素; insert(i,x)在索引i处插入元素x extend 相当于多次调用 append,但底层做了优化 |
删除元素 | pop([i]):移除并返回索引 i 处的元素,默认最后一个。 remove(x):移除第一个值为 x 的元素。 del lst[i:j]:删除切片或单个元素。 clear():清空整个列表 |
反转列表 | reverse():原地反转,返回 None。 切片:lst[::-1],返回一个新的反转列表。 reversed():返回一个迭代器,可用于遍历或 list() 转换 |
查找 | max(lst) / min(lst):返回列表中的最大/最小元素。 key 参数:可接收函数,如 max(lst, key=lambda x: abs(x-10)) |
列表排序 | lst.sort(key=…, reverse=…):原地排序,返回 None sorted(lst, key=…,reverse=…):返回新排序列表不改变原列表 key 参数:接收函数,如 key=lambda x: x.lower()。 reverse=True:降序。 |
列表推导 | 在一行内用表达式和循环/条件生成列表,语法简洁、可读性高,通常比 map/filter 更 Pythonic |
st = [1, 2, 3]
lst.append(4) # [1, 2, 3, 4]
lst.extend([5, 6]) # [1, 2, 3, 4, 5, 6]
lst.insert(0, 0) # [0, 1, 2, 3, 4, 5, 6]
lst = [0, 1, 2, 3, 4, 5, 6]
x = lst.pop() # x=6, lst=[0,1,2,3,4,5]
y = lst.pop(0) # y=0, lst=[1,2,3,4,5]
lst.remove(3) # lst=[1,2,4,5]
del lst[1:3] # lst=[1,5]
lst.clear() # lst=[]
lst = [1, 2, 3, 4]
lst.reverse() # lst=[4,3,2,1]
rev = lst[::-1] # rev=[1,2,3,4] # 新列表
for x in reversed(lst): # 迭代:4,3,2,1print(x)
lst = [3, 1, 4, 1, 5, 9]
mx = max(lst) # 9
mn = min(lst) # 1
# 按距离 6 最近来找最大
mx2 = max(lst, key=lambda x: -abs(x-6))
# 相当于找距离 6 最远的元素
fruits = ['banana', 'Apple', 'cherry']
# 原地排序(区分大小写)
fruits.sort() # ['Apple','banana','cherry']
# 不区分大小写
fruits.sort(key=str.lower) # ['Apple','banana','cherry']
desc = sorted(fruits, reverse=True) # 降序
#列表推导式
squares = [x*x for x in range(10)] #平方
evens = [x for x in range(20) if x % 2 == 0] #带条件
pairs = [(i, j) for i in 'ABC' for j in range(3)] #嵌套循环
5、Python 中字典?
创建字典 | 字面量:{key1: value1, key2: value2} 构造函数:dict() 或 dict([(k1, v1), (k2, v2)]) 推导式:{k: v for k, v in iterable} fromkeys:用相同的默认值创建多个键 |
字典合并 | {**d1, **d2}(Python 3.5+):优雅解包,新字典中后者覆盖前者。 d1.update(d2):原地更新 d1,返回 None。 ChainMap:collections.ChainMap(d1, d2),创建视图,不复制。 |
遍历键和值 | for key in d::遍历键。 for key, val in d.items()::遍历键-值对。 |
d1 = {'name': 'Alice', 'age': 30} # 字面量# 构造函数
d2 = dict(name='Bob', age=25)
d3 = dict([('x', 1), ('y', 2)])nums = [1,2,3]
squares = {n: n*n for n in nums} # {1:1,2:4,3:9} # 推导式# fromkeys
keys = ['a','b','c']
d4 = dict.fromkeys(keys, 0) # {'a':0,'b':0,'c':0}
d1 , d2= {'a': 1, 'b': 2} d2 = {'b': 3, 'c': 4}merged = {**d1, **d2} # {'a':1,'b':3,'c':4}
d1.update(d2) # d1={'a':1,'b':3,'c':4}
from collections import ChainMap
view = ChainMap(d2, d1) # lookup 顺序 d2 -> d1for k in d: #键print(k, d[k])
for k, v in d.items(): #键值对print(k, v)
for v in d.values(): #值print(v)
6、集合set是什么?有什么特点?
集合:无序、元素唯一的可变容器,底层基于哈希表。
特点:自动去重; 支持高效的并集、交集、差集、对称差集运算;
元素必须可哈希(immutable); 常用于去重、成员测试、数学集合运算。
7、python的字符串格式化
百分号老式格式化:name = "Alice"; age = 30 s = "Name: %s, Age: %d" % (name, age)
Str.format() (推荐于python3.0)
s="Name:{},Age:{}".format(name,age) s="Name:{n},Age: {a}".format(n=name, a=age)
f-字符串(f-strings,Python 3.6+,最简洁高效):
s = f"Name: {name}, Age: {age}" # 支持表达式和格式说明
pi = 3.14159 s2 = f"Pi ≈ {pi:.2f}"
函数
1、什么是函数?如何定义一个函数?
可重复使用的代码单元,封装特定功能(封装性),python的函数是类的一等对象,意思它可以像基本类型一样的待遇和特性。可以嵌套定义、可作为参数传递、携带状态(通过闭包或类装饰器)
def fun_name(parame: type_hint)->returntype:"""Docstring (PEP 257规范)"""# 函数体return expression
类型注解(Type Hints)提升代码可读性,文档字符串自动生成API文档(可通过_doc__访问),返回None时可省略return语句
2、什么是参数和返回值,如何在函数中返回多个值??
参数是传递给函数的数据,可以在函数定义时指定多个参数,这些参数在函数执行时提供输入
返回值是函数执行后的结果通过return返回结果,无return语句时隐式返回None;协程函数(async def)返回coroutine对象
形参:位置参数、默认参数、关键字参数; 实参:解包操作符*和** 参数传递方式位对象引用(共享传参; 返回多个值实质是返回元组(tuple packing/unpacking)x, y = fun_name()
参数顺序规则:1、位置参数;2、默认参数;3、*args;4、关键字参数;5、**kwargs
3、什么是默认参数?什么是可变参数(*args 和 **kwargs)
默认参数是在函数定义时给参数指定的默认值。如果调用函数时未提供该参数,函数会使用默认值
*args:用于传递任意数量的位置参数,这些参数会被包装成一个元组。原理:收集多余位置参数为元组,星号解包可用于函数调用
**kwargs:用于传递任意数量的关键字参数,这些参数会被包装成一个字典。原理:收集关键字参数为字典,双星号解包字典为关键字参数
def greet(name, greeting="Hello"):return f"{greeting}, {name}!"print(greet("Alice")) # 输出: Hello, Alice!
print(greet("Bob", "Hi")) # 输出: Hi, Bob!def sum_numbers(*args):return sum(args)sum_numbers(1,2,3) # 6def config_logger(**settings):level = settings.get('level', 'INFO')# ...config_logger(level='DEBUG', format='json')
4、什么是递归函数?如何使用 lambda 函数?请给出示例。
递归函数是函数在其自身的定义中调用自身。递归通常用于分治问题,比如计算阶乘、斐波那契数列等。递归函数必须有一个基准条件,用于终止递归。
def factorial(n): #通过调用自身来计算阶乘if n == 0: # 基准条件return 1else:return n * factorial(n - 1)
print(factorial(5)) # 输出: 120
lambda 函数是一个匿名函数,它可以有任意数量的参数,但只能有一个表达式。lambda 函数通常用于需要一个简单函数的场景,如函数式编程和内联计算。add = lambda x, y: x + y (创建匿名函数,接收两个参数并返回他们的和) print(add(2, 3)) # 输出: 5
5、什么是装饰器?请给出示例。
**装饰器(Decorator)**是一个函数,它可以动态地修改另一个函数的功能。装饰器通常用于函数的扩展、日志记录、权限检查等场景
def decorator_function(original_function):def wrapper_function():print("Wrapper executed before the function.")return original_function()return wrapper_function@decorator_function
def display():return "Display function executed"print(display()) # 输出: Wrapper executed before the function. Display function executed
decorator_function是一个装饰器它接收一个函数作为参数返回一个修改后的函数 wrapper_function
高级技巧:1、带参数的装饰器(需要嵌套三层);2、类装饰器(实现__call__方法);3、使用functools.wraps保留元数据;4、装饰器链(多个装饰器堆叠应用)
6、如何处理函数中的异常?请给出示例。
在 Python 中,可以使用 try...except 块来处理函数中的异常,防止程序因错误而崩溃。finally 可以用来执行无论是否发生异常都要执行的代码。
def divide(a, b):try:return a / bexcept ZeroDivisionError:return "Cannot divide by zero!"finally:print("Execution completed.")print(divide(10, 2)) # 输出: 5.0
print(divide(10, 0)) # 输出: Cannot divide by zero!
注意:精确捕获异常类型(避免裸露的except);使用raise from保留原始堆栈信息;自定义异常继承Exception基类;上下文管理器处理资源清理
7、什么是闭包(closure)?
**闭包(Closure)**是一个函数,它能够记住并访问定义时的作用域,即使在其外部被调用。闭包通常用于实现工厂函数、回调函数等。
def outer(msg):def inner():return f"Message: {msg}"return innerclosure = outer("Hello, World!")
print(closure()) # 输出: Message: Hello, World!
inner 函数是一个闭包,它访问并记住了 outer 函数中的 msg 变量,即使 outer 函数已经执行完毕,inner 仍然能访问 msg。
技术细节:通过__closure__属性访问捕获变量;变量存储于cell对象中;
应用:装饰器实现;回调函数;实现私有变量(伪封装)
8、如何使用 map()、filter() 、reduce()和zip 函数?
map(func, iterable):对可迭代对象每个元素应用 func,返回迭代器。
filter(func, iterable):保留 func(x) 为 True 的元素,返回迭代器。
reduce(fun, iterable[, init]):累计地将fun应用于序列元素来自 functools
zip:将多个可迭代对象“压缩”成元组序列,长度为最短输入的长度。
zip(*iterables):加 * 可解压。
from functools import reducenums = [1, 2, 3, 4]
# map: 平方
sq = list(map(lambda x: x*x, nums)) # [1,4,9,16]
# filter: 偶数
ev = list(filter(lambda x: x%2==0, nums))# [2,4]
# reduce: 求和
sm = reduce(lambda a, b: a + b, nums) # 10
#zip
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
cities= ['NY', 'LA', 'SF']
for name, age, city in zip(names, ages, cities):print(name, age, city)
# Alice 25 NY
# Bob 30 LA
# Charlie 35 SF# 解压
pairs = list(zip(names, ages))
names2, ages2 = zip(*pairs)
面向对象
1、类和对象基本定义,如何定义一个类?
类:创建对象的蓝图,包含属性和方法的逻辑模板(class是type类的实例)对象:类的具体实例,包含实际数据和操作能力(Python中所有对象都是object的派生)
class Car:def __init__(self, brand, model):self.brand = brandself.model = modeldef display_info(self):return f"Car brand: {self.brand}, Model: {self.model}"# 创建对象
car1 = Car("Tesla", "Model S")
print(car1.display_info()) # 输出: Car brand: Tesla, Model: Model S
元类编程:通过__metaclass__或继承type类控制类创建过程,
__prepare__方法:控制类命名空间的创建(Python 3.0+)
__slots__优化:限制实例属性以节省内存
2、构造函数(__init__)?封装?继承?多态?
__init__方法本质:实际是初始化方法,并非真正的构造函数;真正的对象创建由__new__方法完成;
class TrueConstructor:def __new__(cls, *args):print("实际创建对象")return super().__new__(cls)def __init__(self):print("初始化对象")
__new__:控制不可变类型(如int/str)的实例创建;__init__:标准对象初始化操作
封装
封装是面向对象编程中的一个重要概念,它将数据(属性)和方法(行为)组合在一起,并对外部提供受控的访问。封装的一个重要特点是通过访问修饰符(如私有属性和方法)来控制外部访问权限。
如何实现封装:使用私有属性(在属性名或方法名前加上双下划线 __)来保护对象的内部数据。提供 getter 和 setter 方法来访问或修改私有属性。
_protected_var:单下划线约定保护成员;__private_var:双下划线触发名称修饰(name mangling)
class Account:def __init__(self):self.__balance = 0 # 存储为_Account__balance@propertydef balance(self): # 只读属性return self.__balance@balance.setterdef balance(self, value): # 可控修改if value >= 0:self.__balance = value
私有属性和方法:通过将类的属性和方法前加上双下划线(__),可以使其变为私有。Python 会将这些私有成员名称修改为 _ClassName__attribute,以防止外部访问
名称修饰原理:
class AccessControl:def __public(self):print("双下划线方法")def call_private(self):self.__public()obj = AccessControl()
obj.call_private() # 正常调用
obj._AccessControl__public() # 强制访问
"We are all consenting adults here"(Python社区理念);通过__dict__仍可访问所有成员;
主要依赖开发者约定而非强制约束
继承:
继承是面向对象编程中的一个重要特性,它允许一个类继承另一个类的属性和方法,从而实现代码的复用和扩展。
class Animal: # 单继承def speak(self):raise NotImplementedError#多继承于C3线性化
class Dog(Animal):def speak(self): # 方法重写return "Woof!"class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass # MRO: D -> B -> C -> A -> object
print(D.mro()) # 查看方法解析顺序
MRO算法原理:基于拓扑排序的C3算法; super()本质:根据MRO链寻找下一个类
多态:
多态是面向对象编程的一种特性,指的是同一个方法或操作作用于不同类型的对象时,可以表现出不同的行为。通常通过方法重写(Overriding)实现多态
class Animal:def speak(self):return "Animal speaks"
class Dog(Animal):def speak(self):return "Woof!"
class Cat(Animal):def speak(self):return "Meow!"
animals = [Dog(), Cat()]
for animal in animals:print(animal.speak()) # 输出: Woof! Meow!
Python多态的实现哲学:鸭子类型;设计理念:"If it walks like a duck and quacks like a duck..."
协议概念:通过__iter__等魔法方法实现隐式接口
class PDFExporter:def export(self):print("Exporting PDF")class HTMLExporter:def export(self):print("Exporting HTML")
def save_report(exporter): # 不依赖类型声明exporter.export()
3、什么是类方法和静态方法
类方法(@classmethod):绑定到类而不是实例上,接收类作为第一个参数 cls。通常用于操作类级别的属性或作为工厂方法。
静态方法(@staticmethod):既不接收实例 (self),也不接收类 (cls),通常用于不依赖于类或实例状态的工具函数。
方法类型 | 装饰器 | 首个参数 | 可修改类状态 | 典型应用场景 |
实例方法 | 无 | self | 是 | 访问实例数据 |
类方法 | @classmethod | cls | 是 | 工厂模式、备选构造器 |
静态方法 | @staticmethod | 无 | 否 | 工具函数 |
4、如何使用 super() 函数?
super() 函数用于调用父类的方法。它通常在子类中重写父类方法时使用,用来确保父类的逻辑不被完全覆盖,或者用来调用父类的构造方法。
class Animal:def speak(self):return "Animal speaks"class Dog(Animal):def speak(self):return super().speak() + " and Woof!"d = Dog()
print(d.speak()) # 输出: Animal speaks and Woof!
#协作式多重继承
class Base:def __init__(self):print("Base init")super().__init__()class MixinA(Base):def __init__(self):print("MixinA init")super().__init__()class MixinB(Base):def __init__(self):print("MixinB init")super().__init__()class Combined(MixinA, MixinB):
pass # 自动协调初始化顺序
#动态参数传递
class Proxy:def __init__(self, obj):self._obj = objdef __getattr__(self, name):return getattr(self._obj, name)
5、什么是抽象类和接口
抽象类(Abstract Class):抽象类不能直接实例化,它为子类提供一个模板,定义了子类必须实现的抽象方法。通过 abc 模块实现。
from abc import ABC, abstractmethodclass Renderer(ABC):@abstractmethoddef render(self, data):passclass SVGRenderer(Renderer):def render(self, data): # 必须实现return f"<svg>{data}</svg>"
接口(Interface):Python 本身没有显式的接口关键字,但可以通过抽象类来模拟接口,接口只是方法声明而没有实现。
from typing import Protocol
class Serializable(Protocol):def serialize(self) -> bytes: ...@classmethoddef deserialize(cls, data: bytes) -> object: ...
模块与包
1、模块?
模块是一个包含 Python 定义和语句的文件。模块可以包含函数、类和变量,甚至可以包含可执行代码。模块使得代码的组织、复用变得更加容易。
技术本质:包含Python定义和语句的.py文件(或C扩展); 核心作用:代码复用、命名空间隔离、代码组织单元; 身份标识:通过__name__属性获取模块全名(__main__表示当前执行模块)
如何导入模块:可以使用 import 语句来导入模块。Python 中有两种常见的导入方式:1、导入整个模块import math print(math.sqrt(16));2、导入特定函数和变量from math import sqrt print(sqrt(16)) # 输出: 4.0
# 导入流程: 1. 检查math.modules缓存; 2. 搜索math.path中的路径; 3. 编译字节码(生成.pyc文件) ; 4. 执行模块代码; 5. 创建模块对象
2、包
包是一个包含多个模块的文件夹。包允许组织更大规模的应用。每个包目录下必须有一个 __init__.py 文件,标识该目录为一个 Python 包。
创建包的步骤:1、创建一个目录,作为包的名称。2、在该目录下添加 Python 文件作为模块。
3、在该目录下添加 __init__.py 文件(即使文件为空,也要存在)。
__init__.py
文件用于标识一个目录为 Python 包,并允许在导入包时执行初始化代码。它可以是空文件,也可以包含初始化代码。当你导入包时,Python 会执行 __init__.py 文件中的代码。
传统作用:标记Python 3.3之前的包目录;执行包级初始化代码;定义__all__列表控制from package import *的行为
现代用法
# 显式导出API
__all__ = ['submodule1', 'submodule2']
# 包级别配置
print(f"Initializing {__name__}")
# 简化导入路径
from .submodule1 import important_func
包的导入:from . import sibling # 相对导入(同一包内);from ..parent import func # 上级包导入;import pkg.module # 绝对导入(推荐)
3、pip安装
pip 是 Python 包管理工具,用于安装和管理 Python 库。你可以通过 pip 安装第三方库
pip install package==1.0.0 # 精确版本安装 | pip install -r requirements.txt # 批量安装 |
pip freeze > requirements.txt # 导出依赖 | pip show package # 查看包信息 |
pipdeptree # 展示依赖关系 | pip list --format=freeze # 标准格式输出 |
poetry show # 使用Poetry工具 | 依赖隔离:pip install --user (用户级安装) |
安装模式:pip install -e . (可编辑模式) |
镜像源加速:pip config set global.index-url httpedu.cn/simple
4、常用模块
sys、os模块
sys 模块提供了与 Python 解释器交互的功能,允许你访问与 Python 运行时环境相关的参数和操作。常用于获取命令行参数、修改模块搜索路径、控制解释器的退出等。
常见功能和使用方法:
sys.argv:获取命令行传递的参数 | sys.exit():退出 Python 程序 |
sys.path:模块搜索路径 | sys.version:Python 解释器的版本 |
sys.platform:操作系统平台的标识符 |
os 模块提供了操作系统接口,允许你访问文件系统、环境变量、创建和删除目录、执行系统命令等操作。常用于与操作系统进行交互,处理文件和目录等任务。
常见功能和使用方法:os.environ:获取环境变量
os.getcwd():获取当前工作目录 | os.chdir(path):改变当前工作目录 |
os.listdir(path):列出指定目录中的文件和目录 | os.mkdir(path):创建一个新目录 |
os.remove(path):删除指定文件 | os.rename(src, dst):重命名文件或目录 |
异常
1、异常?处理异常?
异常(Exception):在程序运行过程中,当发生错误或意外情况时,解释器会抛出一个异常。异常通常表示程序中的错误状态,例如除以零、文件不存在、索引越界等。
异常对象模型:技术本质:继承自BaseException的实例对象;核心类型:Exception:常规异常基类;SystemExit/KeyboardInterrupt:解释器级异常
目的:异常机制使得程序能够在遇到错误时不直接崩溃,而是通过捕获异常来进行适当的处理,保障程序的健壮性。
如何处理异常:EAFP原则:Easier to Ask Forgiveness than Permission
# LBYL风格(非Pythonic)
if os.path.exists("data.txt"):with open("data.txt") as f:content = f.read()# EAFP风格(推荐)
try:with open("data.txt") as f:content = f.read()
except FileNotFoundError:print("文件不存在")
捕获异常:使用 try 和 except 块捕获可能抛出的异常,从而在错误出现时执行备用代码或输出提示信息。
2、异常控制实现机制
try-except-finally 执行模型
try 语句块:将可能产生异常的代码放入 try 块中,确保后续代码能进入异常处理流程。
except 语句块:用于捕获 try 块中抛出的特定异常,并提供相应的处理代码。可以指定捕获的异常类型,多个 except 块可以针对不同异常做出不同处理。
finally 语句块:无论是否发生异常,finally 中的代码都会执行。常用于释放资源、关闭文件等“清理”任务。
def exception_flow():try:print("执行区域")raise ValueError("示例错误")except TypeError:print("不会捕获")except ValueError as ve:print(f"捕获值错误: {ve}")raise # 重新抛出else:print("无异常时执行")finally:print("始终执行")
# 执行输出:
# 执行区域
# 捕获值错误: 示例错误
# 始终执行
底层原理:字节码层面通过SETUP_FINALLY和WITH_CLEANUP_START指令实现
每个try块对应一个栈帧中的异常表(exception table)
3、自定义异常
针对特定业务逻辑或错误状态,自定义异常能使代码更具可读性与扩展性。你可以继承内置异常基类(如 Exception 或其子类)来自定义异常类
# 定义一个自定义异常类,继承自 Exception
class InvalidInputError(Exception):def __init__(self, message="输入无效"):self.message = messagesuper().__init__(self.message)# 在函数中使用自定义异常
def process_input(value):if not isinstance(value, int):# 引发自定义异常raise InvalidInputError("预期输入为整数")return value * 2try:result = process_input("abc")
except InvalidInputError as err:print("捕获到自定义异常:", err)
raise语句:raise 语句用于主动引发异常。通常用于在遇到不符合预期的条件时中断程序执行,并将错误状态传递给调用者。
4、上下文管理器?with语句?
上下文管理器用于管理资源的获取与释放,确保在使用资源后能够自动清理(如文件、网络连接等)。在 Python 中,上下文管理器定义了 __enter__ 和 __exit__ 方法,分别在进入和退出上下文时自动调用。
class MyResource:def __enter__(self):print("资源被获取")return selfdef __exit__(self, exc_type, exc_val, exc_tb):print("资源被释放")# 根据异常类型决定是否抑制异常,此处返回 False 表示不抑制异常return Falsewith MyResource() as resource:print("使用资源")
进入 with 块时调用 __enter__,退出时调用 __exit__ 来释放资源
with 语句简化了资源管理,不必手动调用清理代码。例如,文件操作时使用 with 能自动关闭文件,即使发生异常。
文件操作
1、文件的读写
读文件 | 写文件 |
open():用于打开文件。 read():读取整个文件的内容。 readline():逐行读取文件。 readlines():将文件的每一行作为列表中的一个元素返回 | 写入文本文件时,常用的模式是 "w"(写入,若文件存在则覆盖)和 "a"(追加)。x'排他创建,文件存在则失败 |
with open('large_file.txt', 'r', encoding='utf-8') as f:# 迭代器逐行读取(内存友好)for line in f:process(line)# 按块读取(二进制模式更高效)f.seek(0) # 重置文件指针while chunk := f.read(4096): # 海象运算符(Python 3.8+)process_chunk(chunk)
高级技巧
编码检测:使用chardet库自动识别文件编码;错误处理:errors='replace'参数处理解码错误;内存映射:mmap模块处理超大文件
import mmap
with open('huge.log', 'r+') as f:mm = mmap.mmap(f.fileno(), 0)index = mm.find(b'ERROR')
2、二进制文件操作
二进制文件不同于文本文件,它以字节流的方式存储数据。读取和写入二进制文件时,打开文件时需要使用 "rb"(读取二进制)和 "wb"(写入二进制)模式。
# 读取二进制
with open('image.jpg', 'rb') as f:jpg_header = f.read(4) # b'\xff\xd8\xff\xe0'# 写入二进制
import struct
with open('data.bin', 'wb') as f:
f.write(struct.pack('!I', 1024)) # 网络字节序整型
#内存视图优化
with open('video.mp4', 'rb') as f:buffer = memoryview(f.read())header = buffer[:4].tobytes() # 零拷贝切片
#随机访问模式
with open('database.idx', 'r+b') as f:f.seek(1024 * 8) # 定位到第8KB位置f.write(b'NEWDATA')f.flush() # 强制刷盘
正则
1、正则?使用?
正则表达式的概念:正则表达式(Regular Expression, 简称 regex) 是一种用于匹配字符串的模式,它是一种强大的文本处理工具,广泛应用于搜索、替换和验证操作。正则表达式由特殊字符和元字符组成,能够描述符合特定模式的字符串。
正则表达式的基本语法:字符匹配:例如,a 匹配字符 a。元字符:如 . 表示任意字符,^ 表示行的开始,$ 表示行的结束。字符集:如 [a-z] 匹配所有小写字母,[0-9] 匹配所有数字。量词:如 * 表示零个或多个,+ 表示一个或多个,? 表示零个或一个。
import re
pattern = r'\d{3}-\d{8}' # 示例:匹配电话号码
text = "紧急联系:028-12345678"
result = re.findall(pattern, text)
2、python的re模块
Python 的 re 模块提供了多个方法来执行正则表达式的匹配操作,常用的方法包括:
方法 | 功能特点 | 返回值 | 典型场景 |
re.match() | 仅从字符串起始位置匹配 | MatchObject | 格式验证(如HTTP协议头) |
re.search() | 扫描整个字符串找首个匹配 | MatchObject | 日志关键信息提取 |
re.findall() | 返回所有非重叠匹配列表 | List | 数据采集 |
re.finditer() | 返回迭代器节约内存 | Iterator | 大文件处理 |
3、贪婪、非贪婪?
贪婪匹配:
贪婪匹配是指正则表达式尽可能多地匹配字符,直到无法匹配为止。默认情况下,量词(如 *、+)是贪婪的。使用.* .+ .{n,}示例:<div>content</div>中<.*>会匹配整个标签
非贪婪匹配:
非贪婪匹配(或称懒惰匹配)是指正则表达式尽可能少地匹配字符,即它会尽早停止匹配。通过在量词后面加上 ? 来实现非贪婪匹配。使用.*? .+? .{n,}?
示例:<div>content</div>中<.*?>会逐个匹配标签
text = "<div>First</div><div>Second</div>"# 贪婪匹配
greedy_match = re.findall(r"<div>.*</div>", text)
print(greedy_match) # 输出: ['<div>First</div><div>Second</div>']# 非贪婪匹配
non_greedy_match = re.findall(r"<div>.*?</div>", text)
print(non_greedy_match) # 输出: ['<div>First</div>', '<div>Second</div>']
4、查找与替换
方法 | 返回值 | 特点 |
re.sub() | 新字符串 | 返回替换后的完整字符串 |
re.subn() | (字符串,次数) | 同时返回替换次数统计 |
import re
text = "I have 2 apples and 3 oranges."
pattern = r"\d+" # 匹配数字
# 替换数字
new_text = re.sub(pattern, "X", text)
print(new_text) # 输出: I have X apples and X oranges.
#回调函数动态生成替换内容
def replace(match):return str(int(match.group()) * 2)
new_text = re.sub(r"\d+", replace, text)
print(new_text) # 输出: I have 4 apples and 6 oranges.
测试
1、单元测试
单元测试(Unit Testing) 是一种软件测试方法,它通过对程序的最小单元(通常是函数或方法)进行独立测试,确保每个功能模块按预期工作。单元测试通常由开发人员编写,能够快速发现代码中的问题,增强代码的可维护性和可靠性
最小测试单元:针对程序模块(函数/类方法)的独立验证
白盒测试:基于代码内部逻辑设计的测试案例
快速反馈:毫秒级执行速度,支持开发中实时验证
隔离性:使用Mock/Stub隔离外部依赖
可重复:相同输入永远得到相同结果
原子性:每个测试用例验证单一功能点
2、unittest、pytest
unittest 模块的使用:unittest 是 Python 内置的单元测试框架,提供了丰富的功能来组织、运行和报告测试。主要步骤包括:1、创建测试类,继承 unittest.TestCase。2、编写测试方法。3、使用 unittest.main() 运行所有测试。
import unittest
class MathTest(unittest.TestCase):# 测试夹具def setUp(self):self.calculator = Calculator()def test_addition(self):self.assertEqual(self.calculator.add(2,3), 5) # 基本断言def tearDown(self):del self.calculator
方法 | 作用域 | 执行时机 |
setUpClass() | 类级别 | 整个测试类开始前执行 |
tearDownClass() | 类级别 | 整个测试类结束后执行 |
setUp() | 方法级别 | 每个测试方法前执行 |
tearDown() | 方法级别 | 每个测试方法后执行 |
高级断言方法
self.assertAlmostEqual(0.1 + 0.2, 0.3, places=7) # 浮点数近似断言
self.assertRaisesRegex(ValueError, "除数不能为零", divide, 10, 0) # 异常正则匹配
self.assertListEqual(result, expected) # 复杂数据结构验证
pytest
零样板代码:无需继承特定类;智能发现:自动查找test_*.py文件;丰富插件:超过800个扩展插件生态;
pytest 是一个第三方 Python 测试框架,它比 unittest 更简单易用,支持自动发现测试、丰富的断言和插件系统。pytest 自动识别以 test_ 开头的函数作为测试用例,测试方法不需要继承 unittest.TestCase。pytest 自动发现以 test_ 开头的函数,运行时不需要显式的测试类。assert 语句用于检查结果是否符合预期。
# 参数化测试
@pytest.mark.parametrize("input,expected", [("3+5", 8),("2*4", 8),("6/2", 3)
])def test_eval(input, expected):assert eval(input) == expected# Fixture依赖管理
@pytest.fixture
def db_connection():conn = create_db_conn()yield connconn.close()def test_query(db_connection):result = db_connection.execute("SELECT 1")assert result == 1
3、测试用例和测试套件
测试用例(Test Case):测试用例是对被测试单元(如函数或方法)的一种具体测试,它通过输入数据并检查输出结果来验证单元的正确性。在 unittest 中,每个测试方法就是一个测试用例。
测试套件(Test Suite):测试套件是多个测试用例的集合,它允许将多个测试用例分组并一起运行。测试套件有助于组织复杂的测试流程。
概念 | 组成单位 | 管理方式 | 执行粒度 |
测试用例 | 单个测试方法 | TestCase子类 | 方法级别 |
测试套件 | 多个TestCase | TestSuite容器 | 模块/包级别 |
import unittest# 测试用例1
def add(a, b):return a + bclass TestAdd(unittest.TestCase):def test_add_positive(self):self.assertEqual(add(2, 3), 5)def test_add_negative(self):self.assertEqual(add(-1, 1), 0)# 测试用例2
def multiply(a, b):return a * bclass TestMultiply(unittest.TestCase):def test_multiply_positive(self):self.assertEqual(multiply(2, 3), 6)def test_multiply_negative(self):self.assertEqual(multiply(-1, 1), -1)# 创建测试套件
def suite():suite = unittest.TestSuite()suite.addTest(unittest.makeSuite(TestAdd)) # 添加 TestAdd 测试用例suite.addTest(unittest.makeSuite(TestMultiply)) # 添加 TestMultiply 测试用例return suite# 运行测试
if __name__ == "__main__":unittest.TextTestRunner().run(suite())
4、如何进行代码覆盖率测试?
代码覆盖率:测量测试用例执行过程中,代码中有多少比例的行被执行了。它有助于发现哪些代码没有被测试到,从而提高测试的全面性。
覆盖率类型 | 检测维度 | 重要性 |
语句覆盖率 | 代码执行路径 | 基础指标 |
分支覆盖率 | 条件判断分支 | 关键路径 |
函数覆盖率 | 函数调用情况 | 架构层面 |
行覆盖率 | 具体代码行执行 | 细节层面 |
使用 coverage 工具进行代码覆盖率测试:1、pip install coverage 2、coverage run -m unittest discover # 运行单元测试并收集覆盖率数据 3、coverage report # 生成覆盖率报告;4、coverage html # 生成 HTML 格式的报告
设计模式
1、什么是单例模式?使用场景,如何实现?
单例模式的概念:单例模式(Singleton Pattern)是一种设计模式,确保一个类只有一个实例,并提供全局访问点。这种模式通常用于控制资源的访问,例如数据库连接、日志管理器等。它避免了类被多次实例化,从而节省资源。
使用场景:
日志系统:确保日志类只有一个实例,避免多次打开日志文件。
数据库连接池:确保数据库连接池有且仅有一个实例,避免多个连接池浪费资源。
配置类:确保配置信息只有一个实例,避免重复加载。
如何实现单例模式:通过类变量保存唯一实例。通过 __new__ 方法确保每次创建对象时返回同一个实例。
class Singleton:_instance = Nonedef __new__(cls):if cls._instance is None:cls._instance = super(Singleton, cls).__new__(cls)return cls._instance# 测试
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2) # 输出: True,表示 obj1 和 obj2 是同一个实例
2、什么是工厂模式?使用场景,请给出示例。
工厂模式的概念:工厂模式(Factory Pattern)是一种创建对象的设计模式。它通过定义一个创建对象的接口,由子类决定实例化哪一个类。工厂方法允许类的实例化延迟到子类进行。
使用场景:对象创建复杂:当一个类的实例化过程涉及多个步骤时,使用工厂模式可以将创建过程封装在一个工厂方法中,避免直接调用构造函数。
不同产品对象的创建:如果需要根据不同条件创建不同类型的对象(例如,操作系统不同创建不同的操作系统类),工厂模式非常有效。
class Car:def drive(self):print("Driving a car")class Bike:def drive(self):print("Riding a bike")class VehicleFactory:@staticmethoddef create_vehicle(vehicle_type):if vehicle_type == "car":return Car()elif vehicle_type == "bike":return Bike()else:raise ValueError("Unknown vehicle type")# 测试
vehicle = VehicleFactory.create_vehicle("car")
vehicle.drive() # 输出: Driving a car
vehicle2 = VehicleFactory.create_vehicle("bike")
vehicle2.drive() # 输出: Riding a bike
3、什么是观察者模式?使用场景,请解释。
观察者模式的概念:观察者模式(Observer Pattern)是一种行为设计模式。它定义了一对多的依赖关系,让多个观察者对象监听某一主题对象,当主题对象状态发生变化时,所有依赖于它的观察者都会得到通知并自动更新。
使用场景:事件处理系统:例如图形用户界面的按钮点击事件,多个按钮的监听器需要响应按钮的点击。
订阅发布系统:例如,新闻网站的订阅功能,当新闻内容更新时,所有订阅的用户会自动收到更新通知。
class Subject:def __init__(self):self._observers = []def attach(self, observer):self._observers.append(observer)def detach(self, observer):self._observers.remove(observer)def notify(self):for observer in self._observers:observer.update()
class Observer:def update(self):passclass ConcreteObserver(Observer):def __init__(self, name):self.name = namedef update(self):print(f"{self.name} has been notified.")# 测试
subject = Subject()
observer1 = ConcreteObserver("Observer 1")
observer2 = ConcreteObserver("Observer 2")
subject.attach(observer1)
subject.attach(observer2)
subject.notify() # 输出: Observer 1 has been notified. \n Observer 2 has been notified.
Subject 类维护一个观察者列表,并在状态变化时通知所有观察者。
Observer 类定义了 update() 方法,具体的观察者通过继承该类并实现 update() 方法来定义响应逻辑。
其他
1、生成器、迭代器
生成器:生成器(generator)是 Python 中的一种特殊类型的迭代器,它通过 yield 语句逐步产生值,而不是一次性返回所有值。生成器能让你按需生成大量的数据,因此它比一次性返回所有数据更节省内存。
惰性计算:按需生成数据项,内存效率优化(对比列表)
执行状态保持:通过yield暂停/恢复执行上下文
迭代器协议实现:自动实现__iter__和__next__
# 方式1:生成器函数
def count_down(n):while n > 0:yield nn -= 1# 方式2:生成器表达式
squares = (x**2 for x in range(100))
# 方式3:类实现(高级定制)
class FibGenerator:def __init__(self, max):self.a, self.b = 0, 1self.max = maxdef __iter__(self):return selfdef __next__(self):if self.a > self.max:raise StopIterationresult = self.aself.a, self.b = self.b, self.a + self.breturn result
什么是迭代器(iterator)?
迭代器的概念:迭代器是一个实现了 __iter__() 和 __next__() 方法的对象。可以通过迭代器逐个访问集合中的元素,直到没有更多元素为止。__iter__():返回迭代器对象本身。__next__():返回集合中的下一个元素。如果没有更多元素,抛出 StopIteration 异常。
迭代器的特点:
惰性求值:迭代器是惰性求值的,每次调用 next() 返回一个元素,直到结束。
一次性:迭代器只能被遍历一次,不能回退或重新遍历。
# 定义一个迭代器class MyIterator:def __init__(self, limit):self.limit = limitself.current = 0def __iter__(self):return self # 返回迭代器对象本身def __next__(self):if self.current < self.limit:self.current += 1return self.currentelse:raise StopIteration # 没有更多元素时抛出异常# 使用迭代器
iterator = MyIterator(3)
for num in iterator:print(num)
2、协程
协程是 Python 中的一种特殊的函数,它能暂停执行并且在需要时恢复执行。与普通的函数不同,协程函数在运行时能通过 await 和 async 关键字挂起执行,并等待某些操作完成(如 I/O 操作),然后再恢复执行。
协程能让程序在执行 I/O 密集型任务时不阻塞其他任务,因此非常适合并发处理。
async:定义协程函数的关键字。await:挂起协程执行,等待其他协程或任务完成
维度 | 协程 | 线程 | 进程 |
切换开销 | 函数调用级(ns) | 内核级(μs) | 最高(ms) |
并发数量 | 10万级 | 千级 | 百级 |
数据共享 | 直接共享 | 需同步机制 | IPC通信 |
适用场景 | I/O密集型 | 混合型 | CPU密集型 |
# Python 3.4之前(yield实现)
@asyncio.coroutine
def old_coroutine():yield from asyncio.sleep(1)# Python 3.5+(async/await语法)
async def modern_coroutine():await asyncio.sleep(1)return "done"
3、json模块
Python 的 json 模块用于处理 JSON 数据,可以将 Python 对象转换为 JSON 格式(序列化),也可以将 JSON 格式的数据转换为 Python 对象(反序列化)。常用于 Web 开发中的数据交换。
常用方法
json.dumps():将 Python 对象转换为 JSON 字符串。
json.loads():将 JSON 字符串转换为 Python 对象。
json.dump():将 Python 对象直接写入文件,以 JSON 格式存储。
json.load():从文件中读取 JSON 格式数据并转换为 Python 对象。
import json# Python 对象转换为 JSON 字符串
data = {'name': 'Alice', 'age': 30}
json_str = json.dumps(data)
print(json_str) # 输出: {"name": "Alice", "age": 30}# JSON 字符串转换为 Python 对象
data_dict = json.loads(json_str)
print(data_dict) # 输出: {'name': 'Alice', 'age': 30}# 将 Python 对象写入 JSON 文件
with open('data.json', 'w') as f:json.dump(data, f)# 从 JSON 文件读取数据
with open('data.json', 'r') as f:loaded_data = json.load(f)print(loaded_data) # 输出: {'name': 'Alice', 'age': 30}
4、pickle 模块
pickle 模块用于序列化和反序列化 Python 对象。序列化是将 Python 对象转换为字节流,以便保存到文件或通过网络传输。反序列化是将字节流转换回 Python 对象。
常用方法
pickle.dumps():将 Python 对象序列化为字节流。
pickle.loads():字节流反序列化为 Python 对象
pickle.dump():将 Python 对象序列化并写入文件。
pickle.load():从文件中读取字节流并反序列化为 Python 对象
import pickle
# Python 对象序列化为字节流
data = {'name': 'Bob', 'age': 25}
serialized_data = pickle.dumps(data)
print(serialized_data)# 字节流反序列化为 Python 对象
deserialized_data = pickle.loads(serialized_data)
print(deserialized_data) # 输出: {'name': 'Bob', 'age': 25}# 将 Python 对象写入文件
with open('data.pkl', 'wb') as f:pickle.dump(data, f)# 从文件中读取并反序列化
with open('data.pkl', 'rb') as f:loaded_data = pickle.load(f)print(loaded_data) # 输出: {'name': 'Bob', 'age': 25}
5、GIL
GIL(Global Interpreter Lock) 是 Python 解释器中的一个机制,它确保同一时刻只有一个线程在执行 Python 字节码。即使在多核 CPU 上,GIL 也会限制线程并行执行,导致 Python 在多线程中无法充分利用多核处理器的优势。
GIL 的影响:
多线程中的限制:由于 GIL 的存在,即使在多线程程序中,多个线程也不能同时执行 Python 代码。因此,Python 的多线程并不能提供与其他语言相同的并行性。
I/O 密集型任务:对于 I/O 密集型任务(如文件读取、网络请求),Python 的多线程仍然有效,因为线程在等待 I/O 操作时会释放 GIL。
CPU 密集型任务:对于 CPU 密集型任务,多线程无法充分利用多核 CPU,反而可能因为 GIL 的存在而导致性能瓶颈。
解决方法
多进程:通过 multiprocessing 模块,可以使用多个进程来充分利用多核 CPU,因为每个进程有自己的 GIL。
使用 C 扩展:某些 C 扩展(如 NumPy)能够绕过 GIL,实现并行计算
6、如何优化 Python 代码的性能?
性能优化方法
避免不必要的计算:使用缓存(例如 lru_cache)来避免重复计算;使用生成器(yield)代替列表推导式,避免在内存中存储大量数据。
选择合适的数据结构:
使用哈希表(字典)来快速查找数据;使用 collections.deque 替代列表进行队列操作,因为它在两端操作比列表更高效。
避免过多的函数调用:
内部函数调用会增加调用栈的负担,可以考虑使用内联计算或通过 map() 等高效函数来替代。
使用并行计算:
对于 CPU 密集型任务,使用 multiprocessing 模块创建多进程;对于 I/O 密集型任务,使用 asyncio 或 threading 模块实现异步或多线程处理。
优化内存使用:
使用生成器代替列表,避免一次性加载大量数据到内存中;使用sys.getsizeof() 或 memory_profiler 来分析内存使用情况。
相关文章:
python面试总结
目录 Python基础 1、python及其特点 2、动态类型和静态类型? 3、变量命名规则是什么? 4、基本数据类型有哪些? 5、Python 中字典? 6、集合set是什么?有什么特点? 7、python的字符串格式化 函数 1…...
基于骨骼识别的危险动作报警系统设计与实现
基于骨骼识别的危险动作报警系统设计与实现 基于骨骼识别的危险动作报警分析系统 【包含内容】 【一】项目提供完整源代码及详细注释 【二】系统设计思路与实现说明 【三】基于骨骼识别算法的实时危险行为预警方案 【技术栈】 ①:系统环境:Windows 10…...
HarmonyOS 5.0应用开发——五子棋游戏(鸿蒙版)开发
【高心星出品】 文章目录 五子棋游戏(鸿蒙版)开发运行效果开发步骤项目结构核心代码棋盘组件:游戏逻辑处理:主页面: 五子棋游戏(鸿蒙版)开发 五子棋是一款传统的两人策略型棋类游戏࿰…...
避坑,app 播放器media:MediaElement paly报错
System.Runtime.InteropServices.COMException HResult=0x8001010E Message= Source=WinRT.Runtime StackTrace: 在 WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|38_0(Int32 hr) 在 ABI.Microsoft.UI.Xaml.Controls.IMediaPlayerElementMethods.get_MediaPlay…...
STM32单片机入门学习——第38节: [11-3] 软件SPI读写W25Q64
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.16 STM32开发板学习——第一节: [1-1]课程简介 前言开发板说明引用解答和…...
使用阿里云创建公司官网(使用wordpress)
安装 LNMP 不通的lnmp版本 https://lnmp.org/download.html wget http://soft.vpser.net/lnmp/lnmp2.1.tar.gz -cO lnmp2.1.tar.gztar zxf lnmp2.1.tar.gz && cd lnmp2.1 && ./install.sh lnmp数据库选5.7 选好数据库,会让你设置数据库 root 用户…...
Python程序结构深度解析:顺序结构与对象布尔值的底层逻辑与应用
一、程序结构的三大基石 在计算机科学领域,任何复杂的算法都可以分解为顺序结构、选择结构和循环结构这三种基本结构的组合。这种结构化编程思想由计算机科学家Bhm和Jacopini在1966年首次提出,至今仍是现代编程语言设计的核心原则。 1.1 顺序结构的本质…...
【系统搭建】Ubuntu系统两节点间SSH免密配置
SSH免密配置是MPI分布式、DPDK通信等集群节点间通信的基础配置 1. 安装SSH服务端(所有节点执行) Ubuntu 默认只安装 SSH 客户端(openssh-client),未安装服务端(openssh-server),需要手动安装并…...
美信监控易:揭秘高效数据采集和数据分析双引擎
在当今复杂多变的运维环境中,一款强大的运维管理软件对于保障企业的IT系统稳定运行至关重要。北京美信时代的美信监控易运维管理软件,凭借其卓越的数据分析双引擎,成为了众多运维团队的首选。 首先,美信监控易的数据采集引擎展现出…...
基于STM32+FPGA的地震数据采集器软件设计,支持RK3568+FPGA平台
0 引言 地震观测是地球物理观测的重点,是地震学和 地球物理学发展的基础 [1] 。地震数据采集器主要功 能是将地震计采集的地震波模拟信号转换为数字信 号并进行记录或传输 [2] ,为地震学提供大量的基础 数据。本文将介绍基FPGAARM的地震数据采集器软…...
NO.95十六届蓝桥杯备战|图论基础-单源最短路|负环|BF判断负环|SPFA判断负环|邮递员送信|采购特价产品|拉近距离|最短路计数(C++)
P3385 【模板】负环 - 洛谷 如果图中存在负环,那么有可能不存在最短路。 BF算法判断负环 执⾏n轮松弛操作,如果第n轮还存在松弛操作,那么就有负环。 #include <bits/stdc.h> using namespace std;const int N 2e3 10, M 3e3 1…...
Linux 网络管理深度指南:从基础到高阶的网卡、端口与路由实战
一、网卡管理:构建网络连接的基石 1.1 现代网络工具链解析 在当代Linux系统中,iproute2套件已全面取代传统的net-tools,其优势体现在: 推荐组合命令: ip -c addr show | grep "inet " # 彩色显示有效IP…...
《重构全球贸易体系用户指南》解读
文章目录 背景核心矛盾与理论框架美元的“特里芬难题”核心矛盾目标理论框架 政策工具箱的协同运作机制关税体系的精准打击汇率政策的混合干预安全工具的复合运用 实施路径与全球秩序重构阶段性目标 风险传导与反制效应内部失衡加剧外部反制升级系统性风险 范式突破与理论再思考…...
stateflow中的函数
最近开始使用STATEFLOW,感觉功能比较强大,在嵌入式的应用中应该缺少不了,先将用到的仔细总结一下。还有一点,积极拥抱ai,学会使用AI的强大功能来学习。 在 Stateflow 中,不同类型的函数和状态适用于不同的建模需求。以下是 图形函数(Graphical Function)、Simulink 函…...
41.[前端开发-JavaScript高级]Day06-原型关系图-ES6类的使用-ES6转ES5
JavaScript ES6实现继承 1 原型继承关系图 原型继承关系 创建对象的内存表现 2 class方式定义类 认识class定义类 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible&qu…...
Flutter学习四:Flutter开发基础(一)Widget
Widget 简介 0 引言 本文是对 Flutter Widget 相关知识的学习和总结。 1 Widget 概念 1.1 Widget 基础 Widget 字面意思:控件、组件、部件、微件、插件、小工具widget 的功能是"描述一个UI元素的配置信息",所谓的配置信息就是 Widget 接收…...
Dify智能体平台源码二次开发笔记(6) - 优化知识库pdf文档的识别
目录 前言 新增PdfNewExtractor类 替换ExtractProcessor类 最终结果 前言 dify的1.1.3版本知识库pdf解析实现使用pypdfium2提取文本,主要存在以下问题: 1. 文本提取能力有限,对表格和图片支持不足 2. 缺乏专门的中文处理优化 3. 没有文档结…...
【LaTeX】公式图表进阶操作
公式 解决不认识的符号 查资料:1)知道符号样子;2)知道符号含义 放大版括号 用来括住存在分式的式子,或者用来括住内部由有很多括号的式子。用法是在左右括号[]分别加上\left和\right \[ J_r\dfrac{i \hbar}{2m} \l…...
第二阶段:数据结构与函数
模块4:常用数据结构 (Organizing Lots of Data) 在前面的模块中,我们学习了如何使用变量来存储单个数据,比如一个数字、一个名字或一个布尔值。但很多时候,我们需要处理一组相关的数据,比如班级里所有学生的名字、一本…...
matlab中simulink的快捷使用方法
连接系统模块还有如下更有效的方式:单击起始模块。 按下 Ctrl键,并单击目标块。 图示为已经连接好的系统模块 旋转模块:选中模块后按图示点击即可...
Redux部分
在src文件夹下 的store文件夹下创建modules/user.js和index.js module/ user.js // 存储用户相关const { createSlice } require("reduxjs/toolkit");const userStore createSlice({name:"user",// 数据状态initialState:{token:},// 同步修改方法red…...
基于STM32F103C8T6的温湿度检测装置
一、系统方案设计 1、系统功能分析 本项目设计的是一款基于STM32F103C8T6的温室大棚检测系统低配版。由 STM32F103C8T6最小系统板,OLED显示屏,DHT11温湿度检测传感器,光敏电阻传感器组成, 可以实现如下功能: 使用D…...
设计模式 - 单例模式
一个类不管创建多少次对象,永远只能得到该类型一个对象的实力 常用到的,比如日志模块,数据库模块 饿汉式单例模式:还没有获取实例对象,实例对象就已经产生了 懒汉式单例模式:唯一的实例对象,…...
Linux驱动开发1 - Platform设备
背景 所有驱动开发都是基于全志T507(Android 10)进行开发,用于记录驱动开发过程。 简介 什么是platform驱动自己上网搜索了解。 在driver/linux/platform_device.h中定义了platform_driver结构体。 struct platform_driver {int (*probe…...
力扣-hot100(盛最多水的容器)
11. 盛最多水的容器 中等 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明…...
使用 PyTorch 构建 UNet 图像去噪模型:从数据加载到模型训练的完整流程
图像去噪是计算机视觉中的一个基础问题,在医学图像、遥感、夜间视觉等领域有广泛应用。本文将手把手带你用 PyTorch 构建一个 UNet 架构的图像去噪模型,包括数据预处理、网络搭建、PSNR 评估与模型保存的完整流程。 本项目已支持将数据增强版本保存为独立…...
从信号处理角度理解图像处理的滤波函数
目录 1、预备知识 1.1 什么是LTI系统? 1.1.1 首先来看什么是线性系统,前提我们要了解什么是齐次性和叠加性。...
集合框架--List集合详解
List集合 List 接口直接继承 Collection 接口,它定义为可以存储重复元素的集合,并且元素按照插入顺序有序排列,且可以通过索引访问指定位置的元素。常见的实现有:ArrayList、LinkedList。 Arraylist:有序、可重复、有索引 Linke…...
需求分析---软件架构师武器库中的天眼系统
在软件架构中,需求分析决定了系统的核心设计方向。 然而,现实中的需求往往存在以下问题: 需求被二次加工:产品经理或业务方可能直接提供“解决方案”(如“我们需要一个聊天功能”),而非原始需…...
Spring Cloud Gateway 的执行链路详解
Spring Cloud Gateway 的执行链路详解 🎯 核心目标 明确 Spring Cloud Gateway 的请求处理全过程(从接收到请求 → 到转发 → 到返回响应),方便你在合适的生命周期节点插入你的逻辑。 🧱 核心执行链路图(执…...
Python----机器学习(基于PyTorch框架的逻辑回归)
逻辑回归是一种广泛使用的统计学习方法,主要用于处理二分类问题。它基于线性回归模型,通过Sigmoid函数将输出映射到[0, 1]范围内,表示实例属于正类别的概率。尽管逻辑回归适用于二分类任务,但在多分类问题中常使用Softmax函数&…...
工业数据治理范式革新:时序数据库 TDengine虚拟表技术解析
小T导读:在工业数字化过程中,数据如何从设备采集顺利“爬坡”到上层应用,一直是个难题。传统“单列模型”虽贴合设备协议,却让上层分析举步维艰。TDengine 用一种更聪明的方法打通了这条数据通路:不强求建模、不手动转…...
Linux的应用领域,Linux的介绍,VirtualBox和Ubuntu的安装,VMware的安装和打开虚拟机CentOS
目录 Linux的应用领域 Linux的介绍 Linux的介绍 Linux发行版 Unix和Linux的渊源 虚拟机和Linux的安装 VirtualBox和Ubuntu的安装 安装VirtualBox 安装Ubuntu 下载Ubuntu操作系统的镜像文件 创建虚拟机 虚拟机设置 启动虚拟机,安装Ubuntu系统 Ubuntu基…...
使用 Java 8 Stream实现List重复数据判断
import java.util.*; import java.util.stream.Collectors;public class DeduplicateStreamExample {static class ArchiveItem {// 字段定义与Getter/Setter省略(需根据实际补充)private String mATNR;private String lIFNR;private String suppSpecMod…...
GDAL:地理数据的万能瑞士军刀
目录 1. 什么是GDAL?2. 为什么需要GDAL?3. GDAL的主要功能3.1. 数据转换3.2. 数据裁剪和处理3.3. 读取和写入多种格式 4. 实际应用场景4.1 环境监测4.2 城市规划4.3 导航系统 5. 技术原理简单解释6. 如何使用GDAL?6.1 简单命令示例 7. 学习建…...
每日文献(十三)——Part two
今天从第三章节:“实现细节”开始介绍。 目录 三、实现细节 四、实验 五、总结贡献 六、致谢 三、实现细节 我们在多尺度图像上训练和测试区域建议和目标检测网络。这是在KITTI目标检测基准[13]上基于CNN的目标检测的趋势。例如,在[16]中ÿ…...
ArrayList 和 LinkedList 区别
ArrayList 和 LinkedList 是 Java 集合框架中两种常用的列表实现,它们在底层数据结构、性能特点和适用场景上有显著的区别。以下是它们的详细对比以及 ArrayList 的扩容机制。 1. ArrayList 和 LinkedList 的底层区别 (1) 底层数据结构 ArrayList: 基于…...
【iOS】UITableView性能优化
UITableView性能优化 前言优化从何入手优化的本质 CPU层级优化1. Cell的复用2. 尽量少定义Cell,善于使用hidden控制显示视图3. 提前计算并缓存高度UITableView的代理方法执行顺序Cell高度缓存高度数组 4. 异步绘制5. 滑动时按需加载6. 使用异步加载图片,…...
通过检索增强生成(RAG)和重排序提升大语言模型(LLM)的准确性
探索大语言模型(LLM)结合有效信息检索机制的优势。实现重排序方法,并将其整合到您自己的LLM流程中。 想象一下,一个大语言模型(LLM)不仅能提供相关答案,还能根据您的具体需求进行精细筛选、优先…...
IDEA202403常用快捷键【持续更新】
文章目录 一、全局搜索二、美化格式三、替换四、Git提交五、代码移动六、调试运行 在使用IDEA进行程序开发,快捷键会让这个过程更加酸爽,下面记录各种快捷键的功能。 一、全局搜索 快捷键功能说明Shift Shift全局搜索Ctrl N搜索Java类 二、美化格式 …...
硬件元件三极管:从基础到进阶的电子探秘
一、基础理论 1. PN结(二极管) PN 结是采用不同的掺杂工艺,将 P 型半导体与 N 型半导体紧密接触而形成的一个界面区域。也就是我们常说的二极管。(P型带正电、N型带负电,电流由P流向N) 形成过程࿱…...
4. k8s核心概念 pod deployment service
以下是 Kubernetes 的核心概念详解,涵盖 Pod、Service、Deployment 和 Node,以及它们之间的关系和实际应用场景: 1. Pod 定义与作用 • 最小部署单元:Pod 是 Kubernetes 中可创建和管理的最小计算单元,包含一个或多个…...
12.第二阶段x64游戏实战-远程调试
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:11.第二阶段x64游戏实战-框架代码细节优化 本次写的内容是关于调试、排错相关的…...
自然语言处理的进化:BERT模型深度剖析
自然语言处理(NLP)领域近年来取得了跨越式的发展,尤其是随着深度学习技术的应用,不少新兴模型应运而生。其中,BERT(Bidirectional Encoder Representations from Transformers)作为一种革命性的…...
鸿蒙学习笔记(5)-HTTP请求数据
一、Http请求数据 http模块是鸿蒙内置的一个模块,提供了网络请求的能力。不需要再写比较原始的AJAS代码。 ps:在项目中如果要访问网络资源,不管是图片文件还是网络请求,必须给项目开放权限。 (1)网络连接方式 HTTP数…...
Golang 的 GMP 协程模型详解
Golang 的 GMP 协程模型详解 Golang 的并发模型基于 GMP(Goroutine-M-Processor) 机制,是其高并发能力的核心支撑。以下从原理、机制、优势、缺点和设计理念展开分析: 一、GMP 的组成与运作原理 Goroutine(Gÿ…...
ReportLab 导出 PDF(页面布局)
ReportLab 导出 PDF(文档创建) ReportLab 导出 PDF(页面布局) ReportLab 导出 PDF(图文表格) PLATYPUS - 页面布局和排版 1. 设计目标2. 开始3. Flowables3.1. Flowable.draw()3.2. Flowable.drawOn(canvas,x,y)3.3. F…...
Ubuntu 安装与配置 Docker
Ubuntu 安装与配置 Docker Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包在一个轻量级、可移植的容器中。它可以帮助开发者和运维人员快速构建、部署和管理应用程序,提升开发和运维效率。本文将介绍如何在 Ubuntu 系统上安装和配置…...
【数据结构与算法】LeetCode每日一题
此题跟27.移除数组中的指定值 类似,都是移除且双指针玩法,只不过判断条件发生了变化...
【HDFS入门】数据存储原理全解,从分块到复制的完整流程剖析
目录 1 HDFS架构概览 2 文件分块机制 2.1 为什么需要分块? 2.2 块大小配置 3 数据写入流程 4 数据复制机制 4.1 副本放置策略 4.2 复制流程 5 数据读取流程 6 一致性模型 7 容错机制 7.1 数据节点故障处理 7.2 校验和验证 8 总结 在大数据时代&#x…...