⚡ Go Senior Mentor Engine | Phase 1: Week 1 Synthesis & 50-Q Exam
Score: 0 / 50
Answered: 0 / 50
Accuracy: 0%
Phase 1: Week 1 Comprehensive Synthesis 50 Questions Master Exam 5 Weekend Labs

Week 1 Master Synthesis: Data Primitives & Memory Internals

สรุปองค์ความรู้สัปดาห์ที่ 1 สำหรับ Mid-Level Backend สู่ Bare-Metal Systems: ผสาน Values vs Pointers, Slice Growth, Map Architecture, Struct Memory Alignment และ String/Buffer Zero-Copy เข้าด้วยกันในบริบท Core Banking Ledger และ Ultra-Low Latency Ingestion

0. The "Why": ปฏิวัติ Mental Model จาก JVM สู่ Go Bare-Metal

ตลอดสัปดาห์ที่ 1 เราได้ถอดรื้อภาพจำที่คุ้นเคยในโลก JVM (Kotlin / Java / Spring Boot) ออกทั้งหมด เพื่อสร้างสัญชาตญาณแบบ Go Systems Engineer ที่มองทะลุลงไปถึงระดับ Cache Line, CPU Word และ Operating System:

หัวข้อสถาปัตยกรรม JVM / Kotlin / Spring Boot Go Bare-Metal (Idiomatic Go)
1. Object & Memory Allocation ทุกอย่างเป็น Reference ชี้ไปที่ Heap มี Object Header 16-byte บวมทุกตัว พึ่งพา GC เป็นหลัก Value Type เป็นพลเมืองชั้นหนึ่ง (อยู่บน Stack Frame ถ้าไม่ Escape) ไม่ใช้ Pointer พร่ำเพรื่อ
2. Dynamic Collections ArrayList คือ Heap Object ห่อหุ้ม Object Array ภายใน มีปัญหา Pointer Chasing Slice Header (24B) เก็บ Data, Len, Cap ชี้ไปที่ Contiguous Backing Array ใน RAM
3. Hash Maps HashMap เป็น Array of Nodes (Linked-list/Red-Black Tree) แต่ละโหนดมี Header แยก `hmap` + Array of `bmap` (8-slots) เก็บข้อมูลเรียงติดกันเพื่อ Cache Locality และใช้ tophash กวาดสแกนเร็วระดับนาโนวินาที
4. Struct Alignment HotSpot JVM สลับลำดับฟิลด์ให้อัตโนมัติ (Field Reordering) นักพัฒนาไม่รู้ Layout จริงใน RAM Go จัดวางไบต์ตามลำดับที่เขียน 100% ต้องเรียง Descending Alignment เพื่อกำจัดช่องว่าง Padding
5. Strings & Buffers java.lang.String เป็น Heap Object และการแปลงเป็น byte[] ต้องคัดลอกข้อมูลเสมอ StringHeader (16B) เป็น Read-only Slice of Bytes รองรับเทคนิค Zero-Copy ด้วย unsafe
1. Go Syntax & Command Master Blueprint: สรุปไวยากรณ์ที่ใช้ทั้งสัปดาห์

สรุปวิธีเขียนและใช้งานคำสั่งหลักทั้งหมดของ Go Week 1 เทียบกับ Kotlin/Java:

1.1 ตัวแปรและพอยน์เตอร์ (Values vs Pointers)

// ประกาศตัวแปรแบบ Type Inference
amount := int64(50000) // ตัวแปรอยู่บน Stack

// เครื่องหมาย & (Address-of) เพื่อหาแอดเดรสใน RAM
ptr := &amount // ptr คือ *int64 (ขนาด 8 Bytes)

// เครื่องหมาย * (Dereference) เพื่ออ่านหรือแก้ค่าที่แอดเดรสนั้น
*ptr = 60000 // ค่าของ amount เปลี่ยนเป็น 60000 ทันที

// ฟังก์ชันแบบ Pass by Value (Share Down, Copy Up)
func DeductFee(bal int64) int64 { return bal - 10 }      // สำเนาค่า (ปลอดภัย ไม่มี Side-effect)
func MutateBalance(bal *int64)  { *bal = *bal - 10 }     // แก้ไขค่าบน RAM โดยตรง

1.2 สไลซ์และการเพิ่มข้อมูล (Slice Mechanics)

// make([]T, len, cap)
txs := make([]int64, 0, 1000) // จอง Underlying Array รองรับได้ 1,000 ตัวล่วงหน้า

// append ข้อมูล (ถ้าเต็มจะขยายความจุ X2 หรือ +25%)
txs = append(txs, 101, 102, 103)

// copy เพื่อตัดขาด Underlying Array ไม่ให้แชร์หน่วยความจำ
sub := make([]int64, len(txs))
copy(sub, txs) // คัดลอกไบต์แยกลง RAM ก้อนใหม่

1.3 แมพและการค้นหา (Map & Comma-ok Idiom)

// สร้าง map พร้อมจอง Hint Capacity
ledger := make(map[string]int64, 5000)
ledger["ACC-101"] = 15000

// การอ่านค่าแบบ Comma-ok Idiom (แยกแยะระหว่างค่า 0 จริงๆ กับไม่มีคีย์)
if balance, exists := ledger["ACC-101"]; exists {
    fmt.Println("Balance:", balance)
}

// การทำ Set ขนาด 0-Byte Value เพื่อประหยัด RAM สูงสุด
uniqueAccounts := make(map[string]struct{})
uniqueAccounts["ACC-101"] = struct{}{} // struct{}{} กินพื้นที่ 0 ไบต์!

1.4 สตรักต์และการตรวจวัดหน่วยความจำ (Struct & Unsafe)

// จัดเรียงฟิลด์แบบ Descending Alignment (ใหญ่ -> กลาง -> เล็ก)
type TransactionRecord struct {
    AccountID int64  // 8 Bytes (Offset 0)
    Amount    int64  // 8 Bytes (Offset 8)
    Timestamp int32  // 4 Bytes (Offset 16)
    Status    uint8  // 1 Byte  (Offset 20)
    IsValid   bool   // 1 Byte  (Offset 21)
    // Trailing Padding 2 Bytes รวมเป็น 24 Bytes พอดี!
}

// ตรวจสอบขนาดด้วย unsafe package
fmt.Println("Size:", unsafe.Sizeof(TransactionRecord{}))   // 24
fmt.Println("Align:", unsafe.Alignof(TransactionRecord{})) // 8

1.5 สตริงและบัฟเฟอร์ (Strings & Buffers)

// ใช้ strings.Builder พร้อม Grow ล่วงหน้าเพื่อตัด Heap Allocation
var b strings.Builder
b.Grow(128)
b.WriteString("TX-STATUS: SUCCESS")
result := b.String()

// Zero-copy แปลง []byte -> string (Go 1.20+)
func FastBytesToString(buf []byte) string {
    return unsafe.String(unsafe.SliceData(buf), len(buf))
}
2. Memory Architecture: แผนผังโครงสร้าง RAM รวมของ Go Primitives
+---------------------------------------------------------------------------------------------------+ | GO DATA STRUCTURES IN RAM (64-BIT ARCHITECTURE) | +---------------------------------------------------------------------------------------------------+ | 1. SLICE HEADER (24 Bytes on Stack): | | [ Data Pointer (8B) ] ───> [ Backing Array on Stack/Heap: elem0 | elem1 | elem2 | ... ] | | [ Length (8B) ] | | [ Capacity (8B) ] | +---------------------------------------------------------------------------------------------------+ | 2. STRING HEADER (16 Bytes on Stack): | | [ Data Pointer (8B) ] ───> [ Read-Only Backing Array: 'H' | 'E' | 'L' | 'L' | 'O' ] | | [ Length (8B) ] | +---------------------------------------------------------------------------------------------------+ | 3. MAP HEADER (hmap, 8-byte Pointer on Stack -> Heap Struct): | | [ hmap Pointer (8B) ] ───> hmap { count, B, hash0, buckets unsafe.Pointer } | | │ | | ▼ | | [ Array of bmap Buckets (จุ 8 สล็อต) ] | | ┌─────────────────────────────────────────────────────────────┐ | | │ tophash : [ 8 x uint8 ] (8 Bytes สำหรับ Fast Scan) │ | | │ keys : [ 8 x KeyType ] (Keys เรียงติดกัน กำจัด Padding) │ | | │ values : [ 8 x ValueType ] (Values เรียงติดกัน) │ | | │ overflow: *bmap (Pointer ไป Bucket ถัดไปเมื่อชนเกิน 8 ตัว) │ | | └─────────────────────────────────────────────────────────────┘ | +---------------------------------------------------------------------------------------------------+ | 4. STRUCT ALIGNMENT (Machine Word = 8 Bytes): | | - ตัวแปร 8 ไบต์ (int64, ptr) ต้องเริ่มที่ Offset หาร 8 ลงตัว (0, 8, 16, ...) | | - ฟิลด์ 0 ไบต์ (struct{}) ถ้าอยู่ท้ายสุด จะถูกบวม Padding 8 ไบต์ ป้องกัน GC Off-by-one Pointer | +---------------------------------------------------------------------------------------------------+
3. Knowledge Verification: Master 50-Question Synthesis Exam

ชุดข้อสอบมาตรฐาน 50 ข้อ ครอบคลุมเนื้อหา Day 1 ถึง Day 5 ทุกประเด็นทางสถาปัตยกรรม คลิกเลือกคำตอบเพื่อรับผลวิเคราะห์และคำอธิบายเชิงลึกทันที

4. Weekend Engineering Labs & Problem Challenges (5 ข้อรวด)

ชุดปฏิบัติการเขียนโค้ดแก้ปัญหาระบบจริงในระบบ Core Banking Ledger และ Race Timing Stream ทุกข้อมีตัวตรวจ Linter และพิมพ์เขียว Blueprint

🛠️ Lab 1: Zero-Allocation Account Balance Deductor
Pointers & Stack
📋 ข้อกำหนดทางเทคนิค:
  1. สร้างฟังก์ชัน DeductBalance(currentBal *int64, fee int64) bool
  2. ทำการตรวจสอบว่าถ้ายอดเงิน *currentBal >= fee ให้หักเงินบน RAM เดิมโดยตรงและคืนค่า true
  3. ถ้ายอดเงินไม่พอ ห้ามหักเงินและคืนค่า false
🛠️ Lab 2: Safe Transaction Stream Batcher
Slice Isolation
📋 ข้อกำหนดทางเทคนิค:
  1. เขียนฟังก์ชัน CreateIsolatedBatch(stream []int64, count int) []int64
  2. ตัดเอาสมาชิก count ตัวแรกจาก stream ออกมา
  3. ต้องใช้ make และ copy เพื่อตัดขาด Underlying Array ไม่ให้เกิด Memory Sharing เด็ดขาด
🛠️ Lab 3: High-Performance Zero-Byte Account Set
Map 0-Byte Optimization
📋 ข้อกำหนดทางเทคนิค:
  1. เขียนฟังก์ชัน FilterUniqueAccounts(accIDs []string) map[string]struct{}
  2. ใช้ make(map[string]struct{}, len(accIDs)) เพื่อจอง Bucket รองรับตั้งแต่แรก
  3. บันทึก Account ID ลงใน map โดยใช้ struct{}{} เป็น Value เพื่อให้กินพื้นที่ 0 ไบต์
🛠️ Lab 4: Core Banking Ledger Struct Compaction
Struct Alignment
📋 ข้อกำหนดทางเทคนิค:
  1. Struct LedgerHeader ด้านล่างมีขนาดบวม 40 ไบต์เพราะจัดเรียงฟิลด์ไม่ถูกต้อง
  2. จัดเรียงใหม่ตามหลัก Descending Alignment (8B -> 4B -> 2B -> 1B)
  3. ทำให้ขนาดลดเหลือเพียง 24 Bytes โดยไม่ลบฟิลด์ใดทิ้ง
🛠️ Lab 5: Ultra-Fast Protocol Packet Stringifier
Zero-Copy unsafe
📋 ข้อกำหนดทางเทคนิค:
  1. เขียนฟังก์ชัน PacketToStringZeroCopy(packet []byte) string
  2. ต้องใช้ unsafe.String ร่วมกับ unsafe.SliceData ในการแปลงข้อมูลโดยไม่เกิด Heap Allocation
  3. ถ้า len(packet) == 0 ให้คืนค่า "" อย่างปลอดภัย