面试题答案
一键面试package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
// 定义消息结构
type Message struct {
SenderID int
ReceiverID int
Content string
}
// 定义节点结构
type Node struct {
ID int
IsOnline bool
Messages chan Message
}
// 模拟节点间消息传递
func (node *Node) SendMessage(toNode *Node, message Message, wg *sync.WaitGroup) {
defer wg.Done()
if!toNode.IsOnline {
fmt.Printf("Node %d is offline, message from %d cannot be sent.\n", toNode.ID, node.ID)
return
}
toNode.Messages <- message
fmt.Printf("Message from Node %d to Node %d sent successfully: %s\n", node.ID, toNode.ID, message.Content)
}
func (node *Node) ReceiveMessage(wg *sync.WaitGroup) {
defer wg.Done()
for message := range node.Messages {
fmt.Printf("Node %d received message from Node %d: %s\n", node.ID, message.SenderID, message.Content)
}
}
func main() {
// 初始化随机数种子
rand.Seed(time.Now().UnixNano())
// 创建节点
numNodes := 5
nodes := make([]*Node, numNodes)
for i := 0; i < numNodes; i++ {
nodes[i] = &Node{
ID: i,
IsOnline: rand.Intn(2) == 1, // 随机设置节点在线或离线
Messages: make(chan Message, 100),
}
}
var wg sync.WaitGroup
// 启动接收消息的goroutine
for _, node := range nodes {
wg.Add(1)
go node.ReceiveMessage(&wg)
}
// 模拟发送消息
messages := []Message{
{SenderID: 0, ReceiverID: 1, Content: "Hello, Node 1!"},
{SenderID: 2, ReceiverID: 3, Content: "Hello, Node 3!"},
{SenderID: 4, ReceiverID: 0, Content: "Hello, Node 0!"},
}
for _, message := range messages {
fromNode := nodes[message.SenderID]
toNode := nodes[message.ReceiverID]
wg.Add(1)
go fromNode.SendMessage(toNode, message, &wg)
}
// 等待所有操作完成
wg.Wait()
// 关闭所有节点的消息通道
for _, node := range nodes {
close(node.Messages)
}
}
上述代码实现了以下功能:
- 节点定义:使用
Node
结构体表示节点,每个节点有唯一的ID
,一个布尔值IsOnline
表示是否在线,以及一个Messages
通道用于接收消息。 - 消息传递:
SendMessage
方法用于向目标节点发送消息,在发送前会检查目标节点是否在线。 - 接收消息:
ReceiveMessage
方法在一个独立的goroutine中运行,不断从Messages
通道接收消息并打印。 - 节点离线处理:通过随机设置
IsOnline
字段模拟节点离线,离线节点不能接收或发送消息。 - 并发控制:使用
sync.WaitGroup
确保所有的发送和接收操作完成后再退出程序。