面试题答案
一键面试package main
import (
"database/sql"
"fmt"
"io/ioutil"
"sync"
_ "github.com/lib/pq" // 假设使用PostgreSQL,根据实际情况替换
)
// 假设的数据库连接
var db *sql.DB
func init() {
var err error
// 初始化数据库连接
db, err = sql.Open("postgres", "user=postgres dbname=mydb sslmode=disable")
if err != nil {
panic(err)
}
}
type FirstStruct struct {
ID int
Data string
}
type SecondStruct struct {
Code string
Value float64
}
func concurrentHandler(ch chan interface{}) map[string]interface{} {
var wg sync.WaitGroup
result := make(map[string]interface{})
firstResultChan := make(chan string)
secondResultChan := make(chan float64)
for data := range ch {
switch v := data.(type) {
case FirstStruct:
wg.Add(1)
go func() {
defer wg.Done()
// 拼接字符串并插入数据库
insertStr := fmt.Sprintf("%d-%s", v.ID, v.Data)
_, err := db.Exec("INSERT INTO some_table (col) VALUES ($1)", insertStr)
if err != nil {
fmt.Println("Database insert error:", err)
}
firstResultChan <- insertStr
}()
case SecondStruct:
wg.Add(1)
go func() {
defer wg.Done()
// 进行数学计算
resultValue := v.Value * 2.0
// 写入文件
err := ioutil.WriteFile("result.txt", []byte(fmt.Sprintf("%s-%f", v.Code, resultValue)), 0644)
if err != nil {
fmt.Println("File write error:", err)
}
secondResultChan <- resultValue
}()
}
}
go func() {
wg.Wait()
close(firstResultChan)
close(secondResultChan)
}()
firstResults := []string{}
for res := range firstResultChan {
firstResults = append(firstResults, res)
}
result["first_type_results"] = firstResults
secondResults := []float64{}
for res := range secondResultChan {
secondResults = append(secondResults, res)
}
result["second_type_results"] = secondResults
return result
}
- 数据库连接初始化:在
init
函数中初始化了一个数据库连接(这里假设是PostgreSQL,使用lib/pq
驱动,实际可根据需求更换)。 - 结构体定义:定义了两种结构体
FirstStruct
和SecondStruct
。 concurrentHandler
函数:- 使用
switch v := data.(type)
进行类型断言,区分不同类型的数据。 - 对于
FirstStruct
类型的数据,启动一个goroutine
拼接ID
和Data
,并插入数据库,同时将拼接结果发送到firstResultChan
。 - 对于
SecondStruct
类型的数据,启动一个goroutine
进行数学计算(这里简单乘以2.0),并将结果写入文件,同时将计算结果发送到secondResultChan
。 - 使用
WaitGroup
等待所有goroutine
完成后关闭结果通道。 - 从结果通道中收集所有结果并汇总到
result
这个map
中返回。
- 使用
需要注意:
- 实际应用中,要根据真实需求优化数据库操作,比如使用连接池、事务等。
- 文件写入也可以考虑使用更高效的方式,如
bufio
。 - 以上代码只是示例,实际可能需要更多的错误处理和优化。