MST

星途 面试题库

面试题:Go接口与通道整合中的并发控制

假设有多个实现了某个接口的结构体实例,通过通道并发地将这些实例传递给一组处理函数。每个处理函数处理完实例后,通过另一个通道返回结果。请设计并实现这个程序结构,同时要考虑如何优雅地处理并发资源竞争和任务的有序完成。
22.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
	"fmt"
	"sync"
)

// 定义接口
type Processor interface {
	Process() string
}

// 实现接口的结构体
type StructA struct {
	ID int
}

func (s StructA) Process() string {
	return fmt.Sprintf("StructA with ID %d processed", s.ID)
}

type StructB struct {
	Value string
}

func (s StructB) Process() string {
	return fmt.Sprintf("StructB with value %s processed", s.Value)
}

func main() {
	// 实例化结构体
	structs := []Processor{
		StructA{ID: 1},
		StructB{Value: "abc"},
		StructA{ID: 2},
	}

	// 创建通道
	inputCh := make(chan Processor)
	outputCh := make(chan string)
	defer close(inputCh)
	defer close(outputCh)

	// 定义WaitGroup
	var wg sync.WaitGroup
	numWorkers := 3
	wg.Add(numWorkers)

	// 启动处理函数
	for i := 0; i < numWorkers; i++ {
		go func() {
			defer wg.Done()
			for proc := range inputCh {
				result := proc.Process()
				outputCh <- result
			}
		}()
	}

	// 发送实例到通道
	go func() {
		for _, s := range structs {
			inputCh <- s
		}
		close(inputCh)
	}()

	// 等待所有任务完成
	go func() {
		wg.Wait()
		close(outputCh)
	}()

	// 接收并打印结果
	for result := range outputCh {
		fmt.Println(result)
	}
}
  1. 接口定义:首先定义了 Processor 接口,包含 Process 方法。
  2. 结构体实现:创建了 StructAStructB 结构体并实现了 Processor 接口。
  3. 通道和WaitGroup:创建了输入通道 inputCh 和输出通道 outputCh,并使用 sync.WaitGroup 来等待所有处理函数完成。
  4. 处理函数:启动多个处理函数,从输入通道接收实例,处理后将结果发送到输出通道。
  5. 任务发送:将结构体实例发送到输入通道,并在发送完成后关闭输入通道。
  6. 结果接收:从输出通道接收并打印处理结果,在所有处理函数完成后关闭输出通道。通过这种方式可以优雅地处理并发资源竞争和任务的有序完成。