面试题答案
一键面试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
并发处理多个文件,并使用resultChan
和errorChan
分别接收处理结果和错误信息。使用sync.WaitGroup
来等待所有goroutine
完成,最后关闭通道并处理结果和错误。