Q

Quản trị viên

Là một lập trình viên yêu công nghệ, thích viết blog để chia sẻ kiến thức, kinh nghiệm lập trình và những điều thú vị trong thế giới tech.

2272 bài viết · Website
Lập trình 22/09/2026 6 phút

Protobuf wire format mổ đến từng byte: vì sao nó nhỏ hơn JSON 3,5 lần và message rỗng tốn 0 byte

Protobuf nhỏ hơn JSON không phải nhờ phép màu — mà nhờ ba quyết định thiết kế gọn gàng. Bài này dùng proto.Marshal rồi hexdump từng byte trong go-lab để giải mã: mỗi field là một tag (field_number dịch bit cộng wire_type) rồi tới value, số nguyên mã hoá bằng varint (số nhỏ chỉ 1 byte), và field mang giá trị mặc định không được ghi lên dây chút nào. Kết quả thật: cùng dữ liệu, JSON 46 byte còn Protobuf 13 byte, message rỗng tốn 0 byte.

Lập trình 22/09/2026 7 phút

Tham lam hay quy hoạch động: khi chọn 'tốt nhất ngay bây giờ' lại cho kết quả tệ nhất

Thuật toán tham lam (greedy) chọn phương án tốt nhất ở mỗi bước — nhanh và đơn giản. Nhưng nó chỉ đúng với một số bài toán. Bài này đo thật trong go-lab bài đổi tiền: với bộ mệnh giá 1,5,10,25 greedy cho lời giải tối ưu, nhưng với bộ 1,7,10 để đổi 14 đồng greedy dùng 5 đồng trong khi DP chỉ cần 2. Greedy nhanh hơn DP 9-93 lần nhưng có thể sai; DP luôn đúng nhưng tốn hơn.

Lập trình 22/09/2026 6 phút

Tiến hoá schema Protobuf: vì sao field number là bất biến, và unknown field cứu dữ liệu qua tay service cũ

Protobuf nhận diện field bằng SỐ chứ không bằng tên — hiểu điều này là hiểu toàn bộ quy tắc tiến hoá schema. Bài này đo thật trong go-lab ba kịch bản: V1 ghi, V2 (thêm field) đọc được, field mới lấy default; V2 ghi có email, service V1 cũ đọc không thấy nhưng GIỮ LẠI email qua round-trip nhờ unknown field; và đổi field number khiến amount biến mất hoàn toàn. Rút ra luật quan trọng nhất của Protobuf.

Lập trình 22/09/2026 5 phút

Deadline và context trong gRPC: hạn chót lan truyền cả chuỗi gọi, và server dừng sớm để không phí tài nguyên

Một request không bao giờ nên treo vô hạn. gRPC gắn deadline vào context, gửi kèm request, để mọi tầng biết còn bao lâu và dừng đúng lúc. Bài này đo thật trong go-lab: call deadline 100ms vào handler làm 500ms trả về sau đúng 100ms với code DeadlineExceeded (không chờ hết việc); và server đọc ctx.Done() để dừng sớm thay vì chạy nốt 500ms vô ích. Hiểu cơ chế này để chống quá tải lan rộng.

Lập trình 22/09/2026 6 phút

Interceptor trong gRPC: middleware bọc mọi RPC cho log, đo thời gian, auth tập trung

Cần log, đo thời gian, và xác thực cho mọi RPC — nhưng không muốn lặp code ở từng handler. Interceptor là lời giải: một lớp bọc quanh mọi call. Bài này chạy thật một chain hai interceptor: logging đo thời gian mỗi call (Fast 1µs, Slow 46ms), và auth chặn /Secure khi thiếu token (trả Unauthenticated, handler không chạy) nhưng cho qua khi token đúng. Viết một lần, áp cho toàn hệ.

Lập trình 22/09/2026 5 phút

Metadata và xác thực trong gRPC: truyền token như header HTTP, kiểm auth một chỗ cho mọi RPC

gRPC không có khái niệm header riêng — nó dùng metadata, cặp key-value gửi kèm mỗi request giống HTTP header. Bài này đo thật trong go-lab: client gắn token qua metadata.AppendToOutgoingContext, server đọc trong một interceptor auth tập trung. Gọi không token trả Unauthenticated, token sai trả PermissionDenied, token đúng mới cho handler chạy và server lấy được user=alice từ token. Và vì sao metadata bắt buộc chạy trên TLS.