面试题答案
一键面试自定义异常类设计思路
- 继承标准异常类:在Python中,所有的异常都继承自
BaseException
类。通常自定义异常类会继承Exception
类,这是所有非系统退出异常的基类。这样能确保自定义异常与Python标准异常体系保持一致。 - 明确异常用途:根据系统中可能出现的不同异常情况,定义不同的自定义异常类。例如,在分布式系统中,可能有网络连接异常、任务超时异常、数据不一致异常等。
- 添加必要属性:为了在捕获异常时获取更多关于异常的信息,可以在自定义异常类中添加一些属性。比如,网络连接异常类可以添加连接的目标地址等信息。
异常传播机制
- 线程内传播:在多线程环境中,异常会在发生的线程内传播。如果一个线程中抛出了自定义异常,而该线程没有捕获处理这个异常,线程会终止,并将异常信息传递给主线程(如果主线程在等待该线程结束)。
- 分布式系统传播:在分布式系统中,异常传播会复杂一些。当一个分布式任务出现异常时,通常会通过RPC(远程过程调用)框架将异常信息返回给调用方。例如,使用
grpc
框架时,服务端抛出的异常会以特定的状态码和错误信息的形式返回给客户端。
通过异常处理提升系统容错性和稳定性
- 捕获和处理异常:在关键代码段,使用
try - except
语句捕获自定义异常。在except
块中,可以进行相应的处理,比如记录日志、进行任务回滚、重新尝试任务等。 - 任务回滚:对于分布式任务,当某个步骤出现异常时,需要有机制回滚之前执行成功的步骤。可以在每个任务步骤中记录执行状态,当异常发生时,根据状态进行回滚操作。
- 重试机制:对于一些可能是临时性问题导致的异常(如网络短暂故障),可以在捕获异常后进行重试。通过设置重试次数和重试间隔,提高系统的容错性。
关键代码片段示例
import threading
import time
# 自定义异常类
class DistributedTaskError(Exception):
def __init__(self, message, task_info):
self.message = message
self.task_info = task_info
super().__init__(self.message)
def distributed_task(task_id):
try:
# 模拟任务执行
if task_id == 2:
raise DistributedTaskError("任务2出现错误", {"task_id": task_id})
print(f"任务{task_id}执行成功")
except DistributedTaskError as e:
print(f"捕获到自定义异常: {e.message},任务信息: {e.task_info}")
# 进行任务回滚等操作
print(f"任务{task_id}回滚操作")
if __name__ == "__main__":
threads = []
for i in range(3):
t = threading.Thread(target=distributed_task, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
上述代码定义了一个自定义异常类DistributedTaskError
,在distributed_task
函数中模拟了任务执行过程,当task_id
为2时抛出异常,并在捕获异常后进行了简单的处理和回滚操作。在多线程环境中,每个线程执行该任务,保证了线程间协调不受异常影响。