<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Cà Phê &amp; Code — Lập trình Go</title>
    <link>https://coffeecode.vn/categories/lap-trinh-go</link>
    <description>Cà Phê &amp; Code là blog dành cho những người yêu công nghệ và lập trình. Nơi chia sẻ kiến thức coding, công cụ hữu ích, xu hướng công nghệ, kinh nghiệm phát triển phần mềm và những câu chuyện phía sau màn hình — tất cả được kể theo cách gần gũi, dễ hiểu, như một cuộc trò chuyện bên tách cà phê.</description>
    <language>vi</language>
    <atom:link href="https://coffeecode.vn/categories/lap-trinh-go/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>Đọc GODEBUG=schedtrace trong Go: giải mã trạng thái bộ lập lịch không cần thư viện</title>
      <link>https://coffeecode.vn/posts/go-003-doc-schedtrace</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-003-doc-schedtrace</guid>
      <description>schedtrace là công cụ số một để nhìn vào bộ lập lịch Go. Bài này giải mã từng trường của một dòng SCHED thật, và theo dõi vòng đời một run qua bốn snapshot — từ lúc goroutine dồn vào hàng đợi cục bộ tới khi mọi core bận. Kèm cách đọc để chẩn đoán nút thắt. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Async preemption trong Go: vì sao một vòng lặp for{} từng treo cả chương trình</title>
      <link>https://coffeecode.vn/posts/go-004-async-preemption</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-004-async-preemption</guid>
      <description>Trước Go 1.14, một goroutine chạy vòng lặp chặt không gọi hàm có thể độc chiếm processor mãi mãi. Bài này đo thật: cùng một for{} vô hạn, bật async preemption thì main quay lại được (exit 0), tắt thì treo tới timeout (exit 124). Kèm cơ chế cắt bằng tín hiệu. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Netpoller trong Go: vì sao 5000 kết nối chỉ tốn 16 OS thread</title>
      <link>https://coffeecode.vn/posts/go-005-netpoller</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-005-netpoller</guid>
      <description>I/O mạng chặn goroutine mà không chặn OS thread — nhờ netpoller tích hợp epoll/kqueue vào scheduler. Bài này đo thật: 5000 goroutine chờ network Read chỉ dùng 16 thread, trong khi 200 goroutine chặn trong syscall thật ngốn 203 thread. Đây là cách Go giải bài C10k. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Sysmon: thread giám sát nền của Go, và cách nó cứu goroutine khỏi chết đói vì syscall</title>
      <link>https://coffeecode.vn/posts/go-006-sysmon</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-006-sysmon</guid>
      <description>Sysmon là thread nền không gắn P, chạy suốt vòng đời chương trình Go. Đo thật: GOMAXPROCS=1, một goroutine kẹt syscall 320ms mà goroutine khác vẫn đếm được 103 triệu lần — vì sysmon giành lại P. Và 40 syscall blocking đẻ ra 43 OS thread. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Chuyển ngữ cảnh goroutine rẻ hơn thread 130 lần: đo tận nanosecond</title>
      <link>https://coffeecode.vn/posts/go-008-chuyen-ngu-canh-goroutine-vs-thread</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-008-chuyen-ngu-canh-goroutine-vs-thread</guid>
      <description>Vì sao spawn hàng nghìn goroutine chạy mượt còn hàng nghìn OS thread thì nghẹt? Đo thật: ping-pong qua channel tốn 164 ns/vòng và 0 cấp phát, còn ping-pong qua pipe giữa hai OS thread tốn 21465 ns/vòng — đắt hơn 130 lần. Vì một cái ở user-space, cái kia qua kernel. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>GOMAXPROCS trong container: vì sao Go hiểu taskset nhưng bỏ qua --cpus, và cách sửa</title>
      <link>https://coffeecode.vn/posts/go-009-gomaxprocs-container</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-009-gomaxprocs-container</guid>
      <description>Go đặt GOMAXPROCS theo số CPU nó nhìn thấy — nhưng trong Kubernetes, giới hạn CPU thường là CFS quota mà Go 1.23 không đọc. Đo thật: Go nhận biết affinity (taskset thành NumCPU 2) nhưng khi GOMAXPROCS thừa so với CPU thực, chuyển ngữ cảnh cưỡng bức tăng gấp 4 lần. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Hàng đợi chạy cục bộ và toàn cục trong Go: vì sao mỗi P có queue riêng 256 slot</title>
      <link>https://coffeecode.vn/posts/go-010-local-vs-global-runqueue</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-010-local-vs-global-runqueue</guid>
      <description>Bộ lập lịch Go không dùng một hàng đợi chung. Mỗi P giữ hàng đợi cục bộ lock-free tối đa 256 goroutine, cộng một hàng đợi toàn cục có khoá cho phần tràn. Đo thật bằng schedtrace: local queue không bao giờ vượt 256, global phình tới hàng vạn nhưng không bị bỏ đói. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Escape analysis trong Go: đọc -gcflags=-m để biết biến ở stack hay heap</title>
      <link>https://coffeecode.vn/posts/go-011-escape-analysis</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-011-escape-analysis</guid>
      <description>Trình biên dịch Go tự quyết biến nào ở lại stack (rẻ) và biến nào thoát lên heap (do GC quản). Đo thật: cùng logic, slice cỡ hằng số 0 cấp phát 0.23 ns, slice cỡ biến 128 byte 27.94 ns — chậm 120 lần. Cách đọc output -m và vì sao nó quan trọng. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Vì sao con trỏ thoát ra heap trong Go: bốn thủ phạm và cách đọc leaking param</title>
      <link>https://coffeecode.vn/posts/go-012-vi-sao-con-tro-thoat-heap</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-012-vi-sao-con-tro-thoat-heap</guid>
      <description>Con trỏ không tự làm biến lên heap — nó chỉ buộc thoát khi biến sống lâu hơn hàm. Đo thật bốn mẫu kinh điển bằng gcflags=-m: trả con trỏ, lưu toàn cục, đóng gói interface, và leaking param. Con trỏ dùng nội bộ vẫn ở stack 0 cấp phát. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Allocator ba tầng của Go: mcache, mcentral, mheap và vì sao cấp phát nhỏ không cần khoá</title>
      <link>https://coffeecode.vn/posts/go-013-allocator-mcache-mcentral-mheap</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-013-allocator-mcache-mcentral-mheap</guid>
      <description>Go cấp phát bộ nhớ qua ba tầng như tcmalloc: mcache mỗi P không khoá, mcentral có khoá, mheap khoá heap. Đo thật: cấp đối tượng nhỏ song song còn nhanh hơn một luồng (mcache per-P), cấp lớn song song chậm gấp 3 vì tranh khoá mheap. Và tiny allocator gộp đối tượng nhỏ. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Size classes và span trong Go: vì sao xin 33 byte lại tốn 48, và phí phạm nội bộ</title>
      <link>https://coffeecode.vn/posts/go-014-size-classes-va-span</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-014-size-classes-va-span</guid>
      <description>Go làm tròn mọi cấp phát lên một trong ~68 lớp kích thước cố định. Đo thật: xin 9 byte tốn 16 (phí 44%), xin 33 tốn 48 (phí 31%), nhưng object khớp lớp (16, 32, 48) thì 0 phí. Cách span tổ chức bộ nhớ và cách thiết kế struct khớp lớp. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Tiny allocator của Go: gộp object nhỏ để một byte chỉ tốn một byte</title>
      <link>https://coffeecode.vn/posts/go-015-tiny-allocator</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-015-tiny-allocator</guid>
      <description>Object tí hon rất phổ biến nhưng cấp mỗi cái một slot 8-16 byte quá phí. Tiny allocator gộp object dưới 16 byte không con trỏ vào chung khối 16B. Đo thật: object 1-byte nén xuống đúng 1.0 B mỗi cái (thắng 8 lần), nhưng cùng cỡ mà có con trỏ thì không được gộp. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Đo cấp phát bằng -benchmem: hai cái bẫy khiến benchmark Go nói dối 0 alloc</title>
      <link>https://coffeecode.vn/posts/go-016-do-cap-phat-benchmem</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-016-do-cap-phat-benchmem</guid>
      <description>B/op và allocs/op là công cụ tối ưu bộ nhớ Go, nhưng dễ nói dối. Đo thật: cùng một hàm cấp 1024 byte, benchmark báo 0 alloc khi kết quả bị vứt (compiler xoá code), và 1 alloc khi gán vào sink. Cách viết benchmark cấp phát đáng tin và testing.AllocsPerRun. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Tái dùng buffer trong Go: mẫu [:0] và prealloc cắt allocation từ 10 xuống 0</title>
      <link>https://coffeecode.vn/posts/go-017-giam-allocation-tai-dung-buffer</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-017-giam-allocation-tai-dung-buffer</guid>
      <description>Hai kỹ thuật giảm allocation không cần thư viện. Đo thật: tái dùng buffer với buf[:0] cắt 10 cấp phát xuống 0 (nhanh 3.3 lần); prealloc đúng capacity cắt 12 cấp phát xuống 1 (nhanh 2.5 lần). Cơ chế, khi nào dùng, và các bẫy chia sẻ backing array. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Work-stealing trong Go: vì sao 40 goroutine tạo từ một chỗ vẫn chạy hết 10 core</title>
      <link>https://coffeecode.vn/posts/go-002-work-stealing-scheduler</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-002-work-stealing-scheduler</guid>
      <description>Bộ lập lịch Go dùng work-stealing: một P hết việc sẽ đánh cắp một nửa hàng đợi của P khác. Bài này đo thật 40 việc CPU tạo từ main chạy nhanh 6,5 lần khi bật 10 core, và schedtrace cho thấy idleprocs=0 — mọi core đều bận. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Mô hình GMP trong Go: 100.000 goroutine chạy trên chỉ 5 OS thread</title>
      <link>https://coffeecode.vn/posts/go-001-mo-hinh-gmp</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-001-mo-hinh-gmp</guid>
      <description>Goroutine chạy ở đâu? Go dùng mô hình GMP — G (goroutine) ghép lên M (OS thread) qua P (processor). Bài này đo thật: 100.001 goroutine chạy trên chỉ 5 thread qua 10 processor, và vì sao đó là lý do Go tạo goroutine gần như miễn phí. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>Struct alignment và padding trong Go: đổi thứ tự field, cắt 33% bộ nhớ</title>
      <link>https://coffeecode.vn/posts/go-019-struct-alignment-padding</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-019-struct-alignment-padding</guid>
      <description>Cùng ba field nhưng thứ tự khai báo khác nhau cho hai kích thước struct khác nhau. Đo thật: bool-int64-bool tốn 24 byte, int64-bool-bool tốn 16 byte — chênh 33%, thành 76 MB ở 10 triệu struct. Cách trình biên dịch chèn đệm và cách sắp field để struct gọn nhất. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>sync.Pool trong Go: cơ chế, bẫy làm nó chậm hơn, và vì sao GC dọn sạch nó</title>
      <link>https://coffeecode.vn/posts/go-018-sync-pool-co-che</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-018-sync-pool-co-che</guid>
      <description>sync.Pool tái dùng object giữa các goroutine, nhưng không phải lúc nào cũng nhanh hơn. Đo thật: pool []byte khi buffer không thoát heap còn CHẬM hơn (compiler để stack + boxing); pool *bytes.Buffer khi object thật sự cấp phát thì nhanh 28%. Và GC dọn sạch pool sau hai chu kỳ. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>False sharing trong Go: hai biến không liên quan mà làm chậm nhau 30 lần</title>
      <link>https://coffeecode.vn/posts/go-020-false-sharing-cache-line</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-020-false-sharing-cache-line</guid>
      <description>Tám goroutine tăng tám counter riêng, không chia sẻ dữ liệu — nhưng chậm 30 lần vì chúng nằm chung một cache line. Đo thật: 830 ms so với 27.5 ms sau khi chèn đệm để mỗi counter chiếm một cache line 64 byte. Cơ chế cache coherency và khi nào cần thêm padding. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
    <item>
      <title>GC tricolor mark-sweep của Go: gom rác mà chỉ dừng chương trình 62 micro-giây</title>
      <link>https://coffeecode.vn/posts/go-021-gc-tricolor-mark-sweep</link>
      <guid isPermaLink="true">https://coffeecode.vn/posts/go-021-gc-tricolor-mark-sweep</guid>
      <description>Bộ thu gom rác của Go chạy đồng thời với chương trình, dùng ba màu để đánh dấu object sống. Đo thật: 10 chu kỳ GC chỉ dừng chương trình tổng 0.62 ms (62 micro-giây mỗi lần), trong khi công việc nền chạy 111 triệu lần. Cơ chế tricolor và write barrier. Go 1.23.</description>
      <pubDate>Tue, 22 Sep 2026 00:00:00 +0700</pubDate>
      <category>Lập trình Go</category>
    </item>
  </channel>
</rss>
