面试题答案
一键面试错误处理思路
- 返回错误值:在每个流水线阶段的函数中,当出现错误时,及时返回错误值。Go语言提倡通过多返回值的方式,将错误作为最后一个返回值返回。
- 全局错误处理:在调用流水线阶段函数的地方,及时检查返回的错误,并进行相应处理。可以根据不同类型的错误进行不同的处理逻辑,比如记录日志、终止流水线等。
- 错误传播:如果某个阶段的错误不需要在当前阶段处理,可以简单地将错误返回给调用者,让调用者决定如何处理,以此实现错误在流水线中的传播。
资源管理思路
- defer关键字:在使用文件、数据库连接等资源时,使用
defer
关键字来确保在函数结束时关闭资源,无论函数是正常结束还是因为错误而提前结束。 - 上下文(Context):使用
context
来管理资源的生命周期,特别是在并发场景下。context
可以用于取消操作、设置截止时间等,从而保证资源在合适的时机被释放。
关键代码片段
- 错误处理示例
package main
import (
"fmt"
)
// 模拟一个流水线阶段函数
func stage1() (string, error) {
// 模拟出现错误
if true {
return "", fmt.Errorf("stage1 error")
}
return "result from stage1", nil
}
// 模拟调用流水线阶段
func main() {
result, err := stage1()
if err != nil {
fmt.Println("Error in stage1:", err)
return
}
fmt.Println("Stage1 result:", result)
}
- 资源管理示例(以文件操作为例)
package main
import (
"fmt"
"os"
)
func readFileContent(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
// 这里可以进行文件读取操作
// 为了简洁省略实际读取代码
return "file content", nil
}
- 使用Context进行资源管理(以数据库连接为例,假设使用database/sql包)
package main
import (
"context"
"database/sql"
"fmt"
_ "github.com/lib/pq" // 假设使用PostgreSQL,根据实际情况替换
)
func queryDatabase(ctx context.Context, db *sql.DB) (string, error) {
var result string
err := db.QueryRowContext(ctx, "SELECT some_column FROM some_table").Scan(&result)
if err != nil {
return "", err
}
return result, nil
}
在使用时:
func main() {
db, err := sql.Open("postgres", "user=postgres dbname=mydb sslmode=disable")
if err != nil {
fmt.Println("Failed to open database:", err)
return
}
defer db.Close()
ctx, cancel := context.WithTimeout(context.Background(), 5)
defer cancel()
result, err := queryDatabase(ctx, db)
if err != nil {
fmt.Println("Database query error:", err)
return
}
fmt.Println("Database query result:", result)
}