Go 1.26 สัมภาษณ์งาน: Green Tea GC, go fix และการเพิ่มประสิทธิภาพ Stack สำหรับนักพัฒนา
เตรียมตัวสัมภาษณ์งาน Go 1.26 ครอบคลุม Green Tea garbage collector ลด overhead 10-40%, เครื่องมือ go fix พร้อม modernizers, การจัดสรร slice บน stack, ตรวจจับ goroutine leak และระบบรักษาความปลอดภัย post-quantum พร้อมตัวอย่างโค้ดและคำตอบที่คาดหวัง

Go 1.26 ซึ่งเปิดตัวในเดือนกุมภาพันธ์ 2026 ได้นำเสนอการเปลี่ยนแปลงระดับ runtime ที่สำคัญที่สุดในรอบหลายปี ประกอบด้วย Green Tea garbage collector ที่กลายเป็น GC ตัวมาตรฐาน เครื่องมือ go fix ที่ถูกเขียนขึ้นใหม่ทั้งหมดเพื่อรองรับ modernizers และการปรับปรุงการจัดสรรหน่วยความจำบน stack สำหรับ slice backing store การเปลี่ยนแปลงเหล่านี้ส่งผลโดยตรงต่อประสิทธิภาพของโปรแกรม Go ทุกตัว โดยไม่จำเป็นต้องแก้ไขโค้ดแม้แต่บรรทัดเดียว สำหรับผู้ที่กำลังเตรียมตัวสัมภาษณ์ตำแหน่ง Go developer การทำความเข้าใจฟีเจอร์เหล่านี้อย่างถ่องแท้จะช่วยสร้างความแตกต่างจากผู้สมัครคนอื่นได้อย่างชัดเจน
สามฟีเจอร์สำคัญที่มักถูกถามในการสัมภาษณ์: Green Tea GC (ลด GC overhead 10-40%), เครื่องมือ go fix เวอร์ชันใหม่พร้อม modernizers และ slice backing store ที่จัดสรรบน stack ฟีเจอร์ทั้งสามให้ประโยชน์ด้านประสิทธิภาพทันทีโดยไม่ต้องแก้ไขโค้ดเดิม
Green Tea Garbage Collector คืออะไร และทำงานอย่างไร
คำตอบที่คาดหวัง: Green Tea คือ garbage collector ตัวใหม่ที่เป็นค่าเริ่มต้นใน Go 1.26 ซึ่งมาแทนที่กลยุทธ์การสแกนแบบเดิมของ tri-color concurrent collector แทนที่จะติดตาม pointer ของแต่ละ object ที่กระจัดกระจายอยู่ทั่ว heap (pointer-chasing) Green Tea จะทำการสแกนหน้าหน่วยความจำขนาด 8 KiB แบบต่อเนื่อง รูปแบบการเข้าถึงหน่วยความจำแบบ sequential นี้ช่วยให้ CPU prefetcher ทำงานได้อย่างมีประสิทธิภาพ ส่งผลให้ GC overhead ลดลง 10-40% ในโปรแกรมจริง
สำหรับ CPU รุ่นใหม่ (Intel Ice Lake หรือ AMD Zen 4 ขึ้นไป) GC จะใช้ SIMD vector instructions ในการสแกน object ขนาดเล็ก ซึ่งเพิ่มประสิทธิภาพได้อีกประมาณ 10%
คำถามเจาะลึก: Green Tea ปรับปรุงพฤติกรรม CPU cache ระหว่างการทำ garbage collection อย่างไร
GC ตัวเดิมจะติดตาม pointer ของ object ข้ามไปมาทั่ว heap ทำให้เกิด cache miss บ่อยครั้ง ในขณะที่ Green Tea ประมวลผล object ทีละหน้าในบล็อกขนาด 8 KiB ที่ต่อเนื่องกัน CPU prefetcher สามารถคาดการณ์รูปแบบการเข้าถึงหน่วยความจำแบบ sequential ได้ จึงช่วยให้ L1/L2 cache ทำงานอย่างมีประสิทธิภาพ การปรับปรุง memory locality นี้เป็นปัจจัยหลักที่ทำให้ overhead ลดลง 10-40%
// Previous approach: follow pointers across heap
func scanObject(obj *mspan) {
for _, ptr := range obj.pointers {
markReachable(ptr) // cache miss likely
}
}
// Green Tea approach: scan contiguous pages
func scanPage(page *pageBlock) {
// Sequential 8 KiB scan - CPU prefetcher friendly
for offset := 0; offset < pageSize; offset += objSize {
scanSlot(page.base + offset) // cache hit likely
}
}สามารถปิดการใช้งาน Green Tea ได้โดยการตั้งค่า GOEXPERIMENT=nogreenteagc ในขั้นตอน build แต่ตัวเลือกนี้มีแนวโน้มจะถูกเอาออกใน Go 1.27
การเพิ่มประสิทธิภาพ Stack Allocation สำหรับ Slice
คำตอบที่คาดหวัง: Go 1.26 ขยายความสามารถของ stack allocation ให้ครอบคลุม slice backing store ในกรณีที่มีการสะสมข้อมูลด้วย append ก่อนหน้านี้ การเรียก append ครั้งแรกจะจัดสรร slice ขนาด 1 บน heap จากนั้นขยายเป็น 2, 4, 8 ตามลำดับ (การขยายแบบ doubling มาตรฐาน) ใน Go 1.26 compiler จะจัดสรร buffer ขนาดเล็กบน stack ก่อนเข้าสู่ลูป ทำให้การ append ในรอบแรกๆ ใช้ stack buffer โดยไม่ต้องจัดสรรหน่วยความจำบน heap เลย
func collectTasks(items []Item) []Task {
var tasks []Task
// Before Go 1.26: first append allocates on heap (size 1, 2, 4...)
// Go 1.26: compiler inserts a stack-backed buffer
for _, item := range items {
if item.IsReady() {
tasks = append(tasks, item.ToTask())
// First ~4 appends use stack buffer, zero heap allocations
}
}
return tasks
// If slice escapes, runtime.move2heap() copies once at return
}คำถามเจาะลึก: เกิดอะไรขึ้นเมื่อ slice หลุดออกจาก scope ของฟังก์ชัน
แม้ว่า slice จะต้องหลุดไปยัง heap (เนื่องจากฟังก์ชัน return ค่า slice ออกไป) Go 1.26 ยังคงใช้ stack buffer ระหว่างขั้นตอนการสะสมข้อมูล compiler จะแทรกการเรียก runtime.move2heap() เพื่อคัดลอกข้อมูลสุดท้ายไปยัง heap เพียงครั้งเดียวที่จุด return แทนที่จะมี heap allocation 3 ครั้งขึ้นไปในช่วงเริ่มต้น (ขนาด 1, 2, 4...) จะเหลือ heap allocation เพียงครั้งเดียวที่ตอนจบ วิธีนี้ในหลายกรณีให้ประสิทธิภาพดีกว่าการ pre-allocate ด้วยตนเอง เนื่องจากการคัดลอกเกิดขึ้นก็ต่อเมื่อข้อมูลอยู่บน stack เท่านั้นจนถึงจุด return
เครื่องมือ go fix เวอร์ชันใหม่ พร้อม Modernizers
คำตอบที่คาดหวัง: เครื่องมือ go fix ถูกเขียนขึ้นใหม่ทั้งหมดให้เป็นศูนย์กลางของ Go modernizers โดยมีจุดประสงค์เพื่อช่วยอัปเดต codebase ให้ใช้ idiom และ standard library API รุ่นล่าสุด เครื่องมือ go fix ตัวใหม่นี้ใช้ analysis framework เดียวกันกับ go vet ทำให้ analyzer ตัวเดียวกันที่ให้ diagnostic สามารถแนะนำและประยุกต์ใช้การแก้ไขได้ด้วย
คุณสมบัติหลักของ go fix ตัวใหม่ ได้แก่
- fixer หลายสิบตัวสำหรับ idiom และ API สมัยใหม่ของ Go
- source-level inliner ที่เปิดใช้งานผ่าน directive
//go:fix inline - รับประกันว่าจะไม่เปลี่ยนพฤติกรรมของโค้ด (ปลอดภัยสำหรับ production code)
- fixer ตัวเก่าที่ล้าสมัยถูกเอาออกแล้ว
# Apply all modernizers to the current module
go fix ./...
# The tool automatically updates patterns like:
# - Old-style error wrapping to fmt.Errorf with %w
# - Deprecated API calls to their replacements
# - Legacy patterns to modern Go idiomsคำถามเจาะลึก: //go:fix inline ทำงานอย่างไร
directive //go:fix inline ทำเครื่องหมายฟังก์ชันหรือ method ว่าเป็นตัวเลือกสำหรับ source-level inlining โดย go fix เมื่อรันคำสั่ง go fix ระบบจะแทนที่จุดเรียกใช้ฟังก์ชันที่ถูกทำเครื่องหมายไว้ด้วยเนื้อหาของฟังก์ชันนั้น สิ่งนี้แตกต่างจาก compiler inlining ตรงที่เป็นการแปลงซอร์สโค้ด ไม่ใช่ machine code ผู้เขียนไลบรารีสามารถใช้วิธีนี้เพื่อ deprecate wrapper function โดยการ inline ไปยัง modern equivalent ที่จุดเรียกใช้
ประสิทธิภาพ cgo ดีขึ้นประมาณ 30%
คำตอบที่คาดหวัง: Go 1.26 ลด overhead พื้นฐานของทุกการเรียก cgo ลงประมาณ 30% runtime ทำได้โดยการกำจัด processor state _Psyscall ซึ่งเป็น intermediate state ที่ goroutine ต้องผ่านระหว่างการเรียก cgo การเอา transition state นี้ออกช่วยลดจำนวน state transition ในแต่ละการเรียก cgo ซึ่งลด latency ลงโดยตรง
การปรับปรุงนี้มีความสำคัญสำหรับแอปพลิเคชันที่เรียก cgo บ่อยครั้ง เช่น โปรแกรมที่ใช้ C library สำหรับ database driver, image processing หรือ cryptographic operations โดยไม่ต้องแก้ไขโค้ดใดๆ
การเปลี่ยนแปลงระดับภาษา: new() และ Self-Referential Generics
คำตอบที่คาดหวัง: Go 1.26 นำเสนอการเปลี่ยนแปลงระดับภาษาสองประการ
1. ฟังก์ชัน new() ที่ปรับปรุงแล้ว: ฟังก์ชัน built-in new รับ expression เป็น operand ได้แล้ว เพื่อกำหนดค่าเริ่มต้นของตัวแปร ก่อนหน้านี้ new(T) จะ return *T ที่มีค่าเป็น zero value เสมอ
type Config struct {
Timeout *int
MaxRetry *int
}
// Before Go 1.26: helper function needed
func intPtr(v int) *int { return &v }
func makeConfig() Config {
return Config{
Timeout: intPtr(30),
MaxRetry: intPtr(3),
}
}
// Go 1.26: direct initialization
func makeConfig() Config {
return Config{
Timeout: new(30), // *int pointing to 30
MaxRetry: new(3), // *int pointing to 3
}
}2. Generic type ที่อ้างอิงตัวเอง: generic type สามารถอ้างอิงถึงตัวเองใน type parameter constraint ได้แล้ว ซึ่งเปิดทางให้ใช้ pattern ขั้นสูงอย่าง F-bounded polymorphism
type Adder[A Adder[A]] interface {
Add(A) A
}
type Vector2D struct{ X, Y float64 }
func (v Vector2D) Add(other Vector2D) Vector2D {
return Vector2D{v.X + other.X, v.Y + other.Y}
}
// The constraint ensures the return type matches the receiver type
func Sum[A Adder[A]](items []A) A {
var result A
for _, item := range items {
result = result.Add(item)
}
return result
}พร้อมที่จะพิชิตการสัมภาษณ์ Go แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
การตรวจจับ Goroutine Leak
คำตอบที่คาดหวัง: Go 1.26 เพิ่ม profile type ใหม่แบบทดลองชื่อ goroutineleak ใน runtime/pprof goroutine ที่ leak คือ goroutine ที่ถูก block อยู่ที่ concurrency primitive (channel, sync.Mutex, sync.Cond) และไม่มีทางถูก unblock ได้อีก runtime ตรวจจับสถานการณ์เหล่านี้โดยใช้ garbage collector กล่าวคือ ถ้า goroutine G ถูก block อยู่ที่ primitive P และ P ไม่สามารถเข้าถึงได้จาก goroutine ใดๆ ที่ยังทำงานอยู่ แสดงว่า G จะไม่มีวัน wake up ได้
func processWorkItems(ws []workItem) ([]workResult, error) {
ch := make(chan result)
for _, w := range ws {
go func() {
res, err := processWorkItem(w)
ch <- result{res, err} // goroutine blocks here if early return
}()
}
for range len(ws) {
r := <-ch
if r.err != nil {
return nil, r.err // remaining goroutines leak
}
}
return results, nil
}
// Enable detection: GOEXPERIMENT=goroutineleakprofile
// Endpoint: /debug/pprof/goroutineleakการตรวจจับนี้ใช้ reachability analysis ของ GC จึงสามารถจับ leak ได้หลายประเภทโดยไม่ต้องเพิ่ม instrumentation ด้วยตนเอง ฟีเจอร์นี้คาดว่าจะเปิดใช้งานเป็นค่าเริ่มต้นใน Go 1.27
การปรับปรุงด้านความปลอดภัย: Heap Randomization และ Post-Quantum Crypto
คำตอบที่คาดหวัง: Go 1.26 มีการปรับปรุงด้านความปลอดภัยที่สำคัญสองประการ
Heap base address randomization (แพลตฟอร์ม 64-bit): runtime จะทำการ randomize heap base address เมื่อเริ่มต้นโปรแกรม ทำให้ผู้โจมตีคาดเดาตำแหน่งหน่วยความจำได้ยากขึ้นในกรณีที่มีช่องโหว่ผ่าน cgo นี่คือการป้องกันแบบ ASLR สำหรับ heap memory ของ Go สามารถปิดการใช้งานได้ด้วย GOEXPERIMENT=norandomizedheapbase64
Post-quantum cryptography เปิดใช้งานเป็นค่าเริ่มต้น: การเชื่อมต่อ TLS จะใช้ hybrid key exchange เป็นค่าเริ่มต้น (SecP256r1MLKEM768, SecP384r1MLKEM1024) ซึ่งรวม elliptic-curve cryptography แบบดั้งเดิมเข้ากับ ML-KEM (เดิมชื่อ CRYSTALS-Kyber) เพื่อความทนทานต่อ quantum computing นอกจากนี้ package crypto/mlkem ยังได้รับการปรับปรุงให้เร็วขึ้นประมาณ 18% ในส่วนของ encapsulation และ decapsulation
ประสิทธิภาพของ Standard Library ที่ดีขึ้นอย่างเห็นได้ชัด
คำตอบที่คาดหวัง: ฟังก์ชันหลายตัวใน standard library ได้รับการปรับปรุงประสิทธิภาพอย่างตรงจุด
| ฟังก์ชัน | การปรับปรุง | รายละเอียด |
|---|---|---|
fmt.Errorf (ไม่มี format verb) | เร็วขึ้นประมาณ 92% | การเรียกแบบไม่มี format verb มีประสิทธิภาพเทียบเท่า errors.New |
io.ReadAll | เร็วขึ้นประมาณ 2 เท่า ใช้หน่วยความจำน้อยลง 50% | ใช้การขยาย buffer แบบ exponential แทน linear |
crypto/mlkem | เร็วขึ้นประมาณ 18% | ปรับปรุง encapsulation และ decapsulation |
image/jpeg | เร็วขึ้นและแม่นยำขึ้น | encoder/decoder ที่เขียนใหม่ทั้งหมด |
นอกจากนี้ bytes.Buffer ยังเพิ่ม method Peek() และ errors ได้รับฟังก์ชัน generic AsType() ส่วน reflect เพิ่ม iterator method (Type.Fields(), Type.Methods(), Value.Fields()) ที่สอดคล้องกับ range-over-func pattern ของ Go
ฟังก์ชัน errors.AsType แบบ Generic สำหรับการจัดการ Error
คำตอบที่คาดหวัง: errors.AsType[T]() เป็นทางเลือกแบบ generic ของ errors.As() ที่ช่วยลด boilerplate code โดยไม่ต้องประกาศตัวแปร target ก่อนเรียกใช้ As
// Before Go 1.26: two-step process
var pathErr *os.PathError
if errors.As(err, &pathErr) {
log.Printf("path error on %s: %v", pathErr.Path, pathErr.Err)
}
// Go 1.26: single expression
if pathErr, ok := errors.AsType[*os.PathError](err); ok {
log.Printf("path error on %s: %v", pathErr.Path, pathErr.Err)
}เวอร์ชัน generic นี้ให้ความปลอดภัยด้าน type ตั้งแต่ compile time และอ่านเข้าใจง่ายกว่าเมื่อใช้ในเงื่อนไขแบบลูกโซ่
พร้อมที่จะพิชิตการสัมภาษณ์ Go แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
สรุป
- Green Tea GC สแกนหน้าหน่วยความจำขนาด 8 KiB แทนการติดตาม pointer ทำให้ GC overhead ลดลง 10-40% โดยไม่ต้องแก้ไขโค้ดแม้แต่บรรทัดเดียว
- Slice backing store ที่จัดสรรบน stack ช่วยกำจัด heap allocation 3 ครั้งขึ้นไปในช่วงเริ่มต้นของลูป append โดยคัดลอกไปยัง heap เพียงครั้งเดียวที่จุด escape
- เครื่องมือ
go fixเวอร์ชันใหม่ประยุกต์ใช้ modernizer หลายสิบตัวบน analysis framework เดียวกันกับgo vetโดยรับประกันว่าจะไม่เปลี่ยนพฤติกรรมของโค้ด new()รับ expression เป็น argument ได้แล้ว ทำให้ไม่ต้องเขียน helper function สำหรับสร้าง pointer อีกต่อไป- Self-referential generic type constraint เปิดทางให้ใช้ F-bounded polymorphism pattern
- การตรวจจับ goroutine leak (แบบทดลอง) ใช้ GC reachability analysis เพื่อค้นหา goroutine ที่ถูก block ถาวร
fmt.Errorfที่ไม่มี format verb เร็วขึ้น 92% และio.ReadAllใช้หน่วยความจำน้อยลง 50%- Hybrid post-quantum key exchange เปิดใช้งานเป็นค่าเริ่มต้นสำหรับการเชื่อมต่อ TLS ทุกรายการ
การเตรียมตัวสำหรับคำถามสัมภาษณ์ Go จะได้ประโยชน์อย่างมากจากความเข้าใจในการเปลี่ยนแปลงระดับ runtime เหล่านี้ คู่มือ concurrency ใน Go ครอบคลุม goroutine pattern พื้นฐานที่เสริมฟีเจอร์ leak detection ที่กล่าวถึงในบทความนี้
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
คุณหาบั๊กใน Go เจอไหม
โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

เขียนโดย
Anthony Fillion-Mailletผู้ก่อตั้ง SharpSkill
เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่
อัปเดตเมื่อ 28 เมษายน 2569
แท็ก
แชร์
บทความที่เกี่ยวข้อง

Go Error Handling ในปี 2026: รูปแบบการจัดการ Error, Wrapping และแนวปฏิบัติที่ดีที่สุดสำหรับการสัมภาษณ์งาน
เจาะลึกรูปแบบการจัดการ error ใน Go ปี 2026 ครอบคลุม error interface, custom error types, error wrapping ด้วย fmt.Errorf, sentinel errors, domain errors และคำถามสัมภาษณ์งานที่พบบ่อยสำหรับนักพัฒนา Go

Interface Go ขั้นสูงในปี 2026: การประกอบ Type Assertion และคำถามสัมภาษณ์
คู่มือเชิงลึกเกี่ยวกับ interface Go สมัยใหม่: การประกอบ interface, type assertion ที่ปลอดภัย, generic แบบอ้างอิงตนเอง และคำถามสัมภาษณ์ที่พบบ่อยสำหรับนักพัฒนา Go

Go SIMD และ Package ArchSIMD ในปี 2026: การเพิ่มประสิทธิภาพและคำถามสัมภาษณ์งาน
คู่มือฉบับสมบูรณ์เกี่ยวกับ package simd/archsimd ใน Go 1.26 สำหรับการดำเนินการ vector แบบ native เรียนรู้ประเภท vector การเพิ่มประสิทธิภาพ และคำถามสัมภาษณ์ Go SIMD