面试题答案
一键面试- 防止注入攻击:
- SQL注入:
- 在Go语言中使用数据库操作时,避免直接拼接SQL语句。例如使用
database/sql
库,采用预编译语句。
import ( "database/sql" _ "github.com/lib/pq" // 以PostgreSQL为例 ) func main() { db, err := sql.Open("postgres", "user=test dbname=test sslmode=disable") if err!= nil { panic(err) } var input string = "test'; DROP TABLE users; --" var count int err = db.QueryRow("SELECT COUNT(*) FROM users WHERE username = $1", input).Scan(&count) if err!= nil { panic(err) } }
- 在Go语言中使用数据库操作时,避免直接拼接SQL语句。例如使用
- 命令注入:当调用外部命令时,使用
exec.Command
并正确处理参数。import ( "fmt" "os/exec" ) func main() { input := "test; rm -rf /" cmd := exec.Command("echo", input) output, err := cmd.Output() if err!= nil { fmt.Println(err) } fmt.Println(string(output)) }
- SQL注入:
- 防止数据篡改:
- 哈希校验:
- 使用
crypto/sha256
等哈希库,在客户端对数据计算哈希值,并随数据一同发送到服务器。
import ( "crypto/sha256" "fmt" ) func main() { data := "example data" h := sha256.New() h.Write([]byte(data)) hash := h.Sum(nil) fmt.Printf("%x\n", hash) }
- 服务器接收到数据和哈希值后,重新计算数据的哈希值并与接收到的哈希值对比。
- 使用
- 数字签名:利用
crypto/rsa
库,私钥签名,公钥验证。- 签名:
import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" ) func signData(privateKeyPEM []byte, data []byte) ([]byte, error) { block, _ := pem.Decode(privateKeyPEM) if block == nil { return nil, fmt.Errorf("failed to decode PEM block") } privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err!= nil { return nil, err } hasher := sha256.New() hasher.Write(data) hashed := hasher.Sum(nil) signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed) if err!= nil { return nil, err } return signature, nil }
- 验证:
import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/pem" "fmt" ) func verifySignature(publicKeyPEM []byte, data []byte, signature []byte) bool { block, _ := pem.Decode(publicKeyPEM) if block == nil { return false } pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err!= nil { return false } publicKey := pubInterface.(*rsa.PublicKey) hasher := sha256.New() hasher.Write(data) hashed := hasher.Sum(nil) err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed, signature) return err == nil }
- 哈希校验:
- 编码转换及性能优化:
- 字符串编码转换:
- 对于UTF - 8编码,Go语言原生支持良好,因为Go语言的
string
类型默认是UTF - 8编码。如果涉及其他编码如GBK,可以使用github.com/mattn/go - iconv
库。
import ( "fmt" "github.com/mattn/go - iconv" ) func main() { cd, err := iconv.Open("utf - 8", "gbk") if err!= nil { panic(err) } defer cd.Close() in := []byte("中文字符") out, err := cd.Conv(in) if err!= nil { panic(err) } fmt.Println(string(out)) }
- 对于UTF - 8编码,Go语言原生支持良好,因为Go语言的
- 传输性能优化:
- 压缩:使用
compress/gzip
库对数据进行压缩后传输。
import ( "bytes" "compress/gzip" "fmt" ) func main() { data := []byte("a very long string data") var buf bytes.Buffer gz := gzip.NewWriter(&buf) _, err := gz.Write(data) if err!= nil { panic(err) } err = gz.Close() if err!= nil { panic(err) } compressed := buf.Bytes() fmt.Println(len(data), len(compressed)) }
- 高效的网络传输:使用
net/http
库构建高性能HTTP服务器,利用连接池等技术优化性能。对于TCP传输,可以使用net
包,并设置合适的TCP参数,如TCP_NODELAY
等。
import ( "net" ) func main() { ln, err := net.Listen("tcp", ":8080") if err!= nil { panic(err) } defer ln.Close() for { conn, err := ln.Accept() if err!= nil { continue } tcpConn := conn.(*net.TCPConn) tcpConn.SetNoDelay(true) // 处理连接 } }
- 压缩:使用
- 字符串编码转换: