Hành Trình Làm Quen Với Ngôn Ngữ Go (Kỳ 3)
Những ngày qua mình đã dành thời gian phát triển một dự án nhỏ và hiện tại cơ bản đã hoàn thành. Nhân dịp này mình xin chia sẻ một đoạn mã nguồn để tiếp tục chuỗi bài viết về Go.
Trong quá trình xây dựng HTTP server hỗ trợ tính năng tải tiếp tục từ điểm gián đoạn, mình gặp phải một vấn đề thuật toán thú vị. Mình muốn sau khi người dùng hoàn tất việc tải toàn bộ nội dung một tệp tin cụ thể, URL tương ứng sẽ ngay lập tức bị vô hiệu hóa. Tuy nhiên, nếu người dùng liên tục thực hiện các yêu cầu tải phân đoạn từ giữa tệp tin, việc xác định trạng thái “đã tải xong” chỉ dựa trên tổng số byte đã truyền sẽ trở nên không khả thi.
Mình quyết định thiết lập tiêu chí xác định “tải xong hoàn toàn” là mọi byte trong tệp tin đều đã được yêu cầu ít nhất một lần. Bài toán này rất phù hợp với cấu trúc dữ liệu cây đoạn (segment tree) để triển khai hiệu quả. Dĩ nhiên vẫn tồn tại nhiều phương án giải quyết khác, nhưng mình xin phép không mở rộng ở đây.
Đoạn mã nguồn mình chia sẻ hôm nay có nhiều không gian để tối ưu hóa, tuy nhiên với yêu cầu thực tế của dự án thì hiệu năng hiện tại đã hoàn toàn đáp ứng được. Về mặt bảo mật, mình cũng đã bổ sung thêm các cơ chế kiểm tra để ngăn chặn các cuộc tấn công ác ý. Chẳng hạn, khi phát hiện có quá nhiều yêu cầu tải phân đoạn nhỏ (ví dụ: cố ý yêu cầu từng byte cách nhau 1 byte), hệ thống sẽ tự động ngắt kết nối để tránh tiêu tốn quá nhiều bộ nhớ cho cấu trúc dữ liệu này. Các biện pháp bảo vệ hệ thống sẽ được đề cập chi tiết hơn trong các bài viết chuyên sâu sau.
Đoạn mã nguồn lần này có phong cách khá gần gũi với ngôn ngữ C, tuy nhiên vẫn toát lên được những ưu điểm vượt trội của Go trong xử lý dữ liệu. Đặc biệt phải kể đến tính năng slice cực kỳ tiện lợi và hàm tích hợp sẵn copy giúp thao tác với các khối dữ liệu vừa an toàn vừa hiệu quả.
Các bạn có thể tham khảo mã nguồn tại đây. Hiện tại hệ thống blog chưa hỗ trợ đánh dấu cú pháp Go nên mình xin phép đăng tải ở một nền tảng phù hợp hơn.
Nhân tiện, theo lời mời của bạn Châu Ái Dân, ngày mai mình sẽ có buổi chia sẻ về ngôn ngữ Go dành cho các kỹ sư tại Alipay. Dù bản thân vẫn còn là người mới học hỏi, nhưng qua việc thực hành với các dự án nhỏ thời gian gần đây, mình đã làm quen được với nhiều đặc tính độc đáo của Go. Hy vọng buổi trình bày sẽ mang lại giá trị thiết thực cho người tham dự.