MST

星途 面试题库

面试题:Go语言Goroutine批量任务处理中复杂错误处理与资源优化

在一个大规模的Goroutine批量任务处理场景中,任务涉及到读取不同的文件(文件数量较多),对文件内容进行复杂解析和计算。在处理过程中,可能会遇到文件不存在、解析错误等多种错误,同时要考虑资源(如文件句柄、内存等)的优化使用。请设计一个完整的解决方案,包括错误处理策略、资源管理方式,并用Go语言代码实现关键部分。
37.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

1. 错误处理策略

  • 文件不存在错误:在打开文件时,使用os.Open函数,若文件不存在会返回错误,我们可以记录该错误并跳过该文件。
  • 解析错误:在解析文件内容时,捕获解析过程中返回的错误,记录下来并继续处理下一个文件,避免因单个文件解析错误导致整个任务终止。

2. 资源管理方式

  • 文件句柄:使用defer关键字在函数结束时关闭文件句柄,确保文件句柄及时释放。
  • 内存:尽量复用内存,比如使用对象池(sync.Pool)来管理一些中间数据结构的内存分配和回收,减少频繁的内存分配和垃圾回收压力。

3. Go语言代码实现关键部分

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"sync"
)

// 定义解析函数
func parseFileContent(content []byte) (interface{}, error) {
	// 这里是复杂解析和计算的模拟,实际需要替换为真实逻辑
	if len(content) == 0 {
		return nil, errors.New("empty content")
	}
	return string(content), nil
}

func processFile(filePath string, resultChan chan<- interface{}, errorChan chan<- error) {
	content, err := ioutil.ReadFile(filePath)
	if err != nil {
		errorChan <- err
		return
	}
	defer func() {
		// 这里假设文件已通过ioutil.ReadFile读入内存,无文件句柄需关闭
	}()

	result, err := parseFileContent(content)
	if err != nil {
		errorChan <- err
		return
	}
	resultChan <- result
}

func main() {
	filePaths := []string{"file1.txt", "file2.txt", "file3.txt"} // 模拟文件路径列表
	resultChan := make(chan interface{})
	errorChan := make(chan error)
	var wg sync.WaitGroup

	for _, filePath := range filePaths {
		wg.Add(1)
		go func(fp string) {
			defer wg.Done()
			processFile(fp, resultChan, errorChan)
		}(filePath)
	}

	go func() {
		wg.Wait()
		close(resultChan)
		close(errorChan)
	}()

	for {
		select {
		case result := <-resultChan:
			fmt.Println("Processed result:", result)
		case err := <-errorChan:
			log.Println("Error:", err)
		default:
			if len(resultChan) == 0 && len(errorChan) == 0 {
				return
			}
		}
	}
}

在上述代码中:

  • parseFileContent函数模拟了文件内容的复杂解析和计算。
  • processFile函数负责读取文件内容并调用解析函数,同时处理文件读取和解析过程中的错误。
  • main函数中,通过goroutine并发处理多个文件,并使用resultChanerrorChan分别接收处理结果和错误信息。使用sync.WaitGroup来等待所有goroutine完成,最后关闭通道并处理结果和错误。