MST

星途 面试题库

面试题:Go接口在并发编程中的多态应用

在Go的并发编程场景下,结合接口与多态性,设计一个程序,实现多个不同类型的任务并发执行,并且能通过一个统一的接口来管理和控制这些任务,比如启动、暂停和终止任务。描述设计思路并给出核心代码。
14.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义任务接口:创建一个接口,包含启动、暂停和终止任务的方法,这样不同类型的任务只要实现该接口,就能通过统一的方式管理。
  2. 实现具体任务结构体:针对不同类型的任务,创建相应的结构体,并实现上述定义的接口方法。
  3. 并发执行任务:利用Go语言的goroutine实现任务的并发执行,通过channel来传递控制信号,如暂停和终止信号。

核心代码

package main

import (
    "fmt"
    "sync"
    "time"
)

// Task 定义任务接口
type Task interface {
    Start()
    Pause()
    Terminate()
}

// ExampleTask1 具体任务1
type ExampleTask1 struct {
    isRunning bool
    pauseChan chan struct{}
    stopChan  chan struct{}
}

func NewExampleTask1() *ExampleTask1 {
    return &ExampleTask1{
        isRunning: false,
        pauseChan: make(chan struct{}),
        stopChan:  make(chan struct{}),
    }
}

func (t *ExampleTask1) Start() {
    t.isRunning = true
    go func() {
        for {
            select {
            case <-t.pauseChan:
                fmt.Println("ExampleTask1 paused")
                <-t.pauseChan
                fmt.Println("ExampleTask1 resumed")
            case <-t.stopChan:
                fmt.Println("ExampleTask1 terminated")
                t.isRunning = false
                return
            default:
                fmt.Println("ExampleTask1 is running")
                time.Sleep(time.Second)
            }
        }
    }()
}

func (t *ExampleTask1) Pause() {
    if t.isRunning {
        t.pauseChan <- struct{}{}
    }
}

func (t *ExampleTask1) Terminate() {
    if t.isRunning {
        t.stopChan <- struct{}{}
    }
}

// ExampleTask2 具体任务2
type ExampleTask2 struct {
    isRunning bool
    pauseChan chan struct{}
    stopChan  chan struct{}
}

func NewExampleTask2() *ExampleTask2 {
    return &ExampleTask2{
        isRunning: false,
        pauseChan: make(chan struct{}),
        stopChan:  make(chan struct{}),
    }
}

func (t *ExampleTask2) Start() {
    t.isRunning = true
    go func() {
        for {
            select {
            case <-t.pauseChan:
                fmt.Println("ExampleTask2 paused")
                <-t.pauseChan
                fmt.Println("ExampleTask2 resumed")
            case <-t.stopChan:
                fmt.Println("ExampleTask2 terminated")
                t.isRunning = false
                return
            default:
                fmt.Println("ExampleTask2 is running")
                time.Sleep(time.Second)
            }
        }
    }()
}

func (t *ExampleTask2) Pause() {
    if t.isRunning {
        t.pauseChan <- struct{}{}
    }
}

func (t *ExampleTask2) Terminate() {
    if t.isRunning {
        t.stopChan <- struct{}{}
    }
}

func main() {
    var wg sync.WaitGroup
    tasks := []Task{NewExampleTask1(), NewExampleTask2()}

    for _, task := range tasks {
        wg.Add(1)
        task.Start()
        go func(t Task) {
            defer wg.Done()
            time.Sleep(3 * time.Second)
            t.Pause()
            time.Sleep(2 * time.Second)
            t.Terminate()
        }(task)
    }

    wg.Wait()
}