面试题答案
一键面试- 锁机制
- 互斥锁(Mutex):在协程访问共享数据前获取互斥锁,访问结束后释放。这能确保同一时间只有一个协程能操作共享数据,避免数据冲突。例如在Python中使用
threading.Lock
(在支持协程的异步库中类似机制也存在):
- 互斥锁(Mutex):在协程访问共享数据前获取互斥锁,访问结束后释放。这能确保同一时间只有一个协程能操作共享数据,避免数据冲突。例如在Python中使用
import asyncio
import threading
lock = threading.Lock()
shared_data = 0
async def coroutine_function():
global shared_data
with lock:
shared_data += 1
await asyncio.sleep(0)
- **读写锁(Read - Write Lock)**:如果读操作远多于写操作,读写锁能提高性能。多个协程可同时获取读锁进行读操作,但写操作前必须获取写锁,此时其他读写操作都被阻塞。
2. 事务 - 数据库事务:若共享数据存储在数据库中,利用数据库提供的事务机制。以关系型数据库为例,将多个协程对共享数据的操作封装在一个事务内,要么全部成功,要么全部失败。例如在SQL中:
BEGIN;
UPDATE shared_table SET data = data + 1 WHERE id = 1;
COMMIT;
- **分布式事务**:对于微服务架构下跨多个服务的共享数据操作,可采用分布式事务解决方案,如XA协议、TCC(Try - Confirm - Cancel)模式、Saga模式等。
3. 乐观锁
- 乐观锁假设在大多数情况下不会发生数据冲突。每次读取数据时记录版本号,写入时检查版本号是否变化。如果版本号未变,则允许写入并更新版本号;否则,重试操作。在数据库层面,可通过在表中添加version
字段实现:
-- 读取数据及版本号
SELECT data, version FROM shared_table WHERE id = 1;
-- 假设读取到data为10,version为1
-- 更新数据,条件是版本号未变
UPDATE shared_table SET data = data + 1, version = version + 1 WHERE id = 1 AND version = 1;
- 消息队列
- 将对共享数据的操作封装成消息发送到消息队列。每个微服务从队列中按顺序消费消息,依次处理对共享数据的操作,从而保证数据一致性。例如使用Kafka、RabbitMQ等消息队列。
- 分布式一致性算法
- Paxos算法:通过多轮投票决定共享数据的最终状态,确保所有节点达成一致。虽然实现复杂,但能保证强一致性。
- Raft算法:一种简化的一致性算法,通过选举领导者,由领导者处理数据复制和同步,保证数据一致性,常用于分布式存储系统。