---
title: "Game System Design GonnaCrash được làm như thế nào"
description: "Kéo thả một hệ thống rồi nhìn nó trụ hay sập: cách mình dựng GonnaCrash, từ server làm trọng tài, con bot giải đề đến skin whiteboard."
canonical: "https://200lab.io/blog/game-system-design-gonnacrash-duoc-lam-nhu-the-nao"
published: "2026-10-22T11:33:26Z"
updated: "2026-10-22T11:33:26Z"
authors: ["Việt Trần"]
tags: ["Backend", "Golang", "Frontend"]
reading_minutes: 18
access: "public"
---

GonnaCrash mới ra gần đây. Ý tưởng gốc tới từ một người bạn của mình, và mình đã dùng nó để xây dựng lại game System Design ở 200Lab. Cách chơi rất đơn giản: bạn kéo các thành phần như Load Balancer, App Server, Cache, Database lên canvas, kết nối chúng với nhau, bấm chạy rồi ngồi nhìn traffic đổ vào. Hệ thống trụ được thì bạn qua màn. Còn nếu sập, bạn ăn ngay con dấu CRASHED to tướng, kèm lời giải thích vì sao nó sập.

Game chính thức mở tại systemdesign.200lab.io từ chiều 20/10, gồm 4 world với 90 màn chơi, và phần engine được mình viết lại từ đầu. Trong bài này mình kể lại hành trình đó: game chấm điểm thế nào, vì sao mình bắt nó phải tính ra đúng một kết quả trên mọi máy, và phần mà lúc đầu mình hoàn toàn không ngờ lại tốn công nhất: test từng màn chơi.

Bạn không cần biết code để đọc bài này. Chỗ nào có thuật ngữ kỹ thuật, mình sẽ giải thích bằng ví dụ đời thường.

![Trình duyệt chỉ gửi thiết kế, server tự mô phỏng và chấm điểm; phía dưới là quy trình dựng và test màn chơi.](https://assets.200lab.io/sha256/0c/0c0f27aa534f7294aaedcd33db9d1d1be63cacd0e7d48dafa231aa57d3b4b11c/generations/07c6c25a81fbbd442508e0d007e746665cc2d3fb1428ba98e72ee172176b2b89)

## Chơi GonnaCrash là chơi gì?

Mỗi app bạn dùng hằng ngày, từ app đọc báo tới app ngân hàng, đều chạy trên một hệ thống phía sau gồm nhiều máy làm nhiều việc khác nhau. System design là việc chọn dùng những máy nào và ráp chúng với nhau ra sao, để khi hàng nghìn người cùng vào một lúc thì app vẫn chạy mượt mà vẫn không tốn tiền vô lý.

Thử hình dung một quán ăn:
- **Database** là cái bếp chính, nơi giữ mọi dữ liệu. Bếp nấu ngon nhưng chậm, và khi quá tải thì sẽ sập.
- **App Server** là người phục vụ, nhận yêu cầu của khách rồi chạy vào bếp lấy món.
- **Load Balancer** là người đứng cửa chia khách cho từng người phục vụ, để không ai bị dồn việc.
- **Cache** là quầy món làm sẵn. Món nào nhiều người gọi thì bày sẵn ở đây để khỏi phải vào bếp.

![Hệ thống phía sau một app giống một quán ăn: người chia khách, người phục vụ, quầy món làm sẵn và bếp chính.](https://assets.200lab.io/sha256/66/662b073cd43626a236f143ae36590d472e8ac108b75dc5e194d21e9b12ac1afe/generations/1efa349b093139179961b13a92a0553df86c0a35491fbe81a5d234a8eda8626b)

Mỗi màn chơi là một tình huống. Ví dụ màn 5 của world Nền tảng tên là "Cả nước lướt app giờ trưa": mỗi giây có 1.800 lượt đọc và 200 lượt ghi, và ai cũng đọc đúng mấy bài đang hot. Bạn được phát một bộ thành phần, mỗi loại có vài cỡ to nhỏ khác nhau, kèm theo các mục tiêu cần đạt: 99% yêu cầu phải được trả lời, thời gian chờ trung bình dưới 300 ms, và không vượt ngân sách.

Ráp xong thiết kế, bạn bấm chạy. Server sẽ mô phỏng khoảng hai phút traffic rồi trả về kết quả. Nếu qua màn, bạn được từ 1 đến 3 sao, tùy thiết kế của bạn tiết kiệm tới đâu so với lời giải tốt nhất mà máy tìm được. Nếu sập, game sẽ chỉ ra thành phần nào sập, vì sao sập, và bài học nào nên đọc.

Ở màn giờ trưa này, nếu không có cache thì database sẽ chết vì bị đọc quá nhiều. Thêm cache vào là qua màn, nhưng chọn cache to quá thì tốn tiền và mất sao. Cả game xoay quanh đúng cái cảm giác đó: không có thiết kế đúng tuyệt đối, chỉ có thiết kế vừa đủ cho lượng khách này.

## Server làm trọng tài, và trọng tài thì không được "gần như"

Cách dễ nhất là để trình duyệt của người chơi tự chạy mô phỏng rồi gửi điểm lên server. Mình không làm vậy, vì làm thế chẳng khác gì để thí sinh tự chấm bài thi của mình. Game có bảng xếp hạng, có badge, có danh hiệu, nên điểm phải là thứ không ai sửa được.

Vì thế trình duyệt chỉ gửi lên đúng bản thiết kế: gồm những thành phần nào và chúng kết nối với nhau ra sao. Server tự kiểm tra, tự mô phỏng, tự chấm và lưu kết quả. Hoạt ảnh traffic chạy qua từng kết nối mà bạn thấy trên màn hình thực ra chỉ là bản phát lại từ số liệu server gửi về, giống như xem lại highlight của một trận bóng đã đá xong.

Mà đã làm trọng tài thì server phải trả lời được một câu hỏi: cùng một thiết kế, chạy hai lần có ra cùng một kết quả không? Chạy trên laptop của mình và trên server thật có giống nhau không?

Nghe thì có vẻ hiển nhiên, nhưng thực tế không hẳn vậy. Khi tính với số có phần thập phân, máy tính phải làm tròn ở những chữ số rất xa sau dấu phẩy, và chỉ cần đổi thứ tự cộng là kết quả đã có thể lệch đi một chút. Bình thường lệch vậy chẳng ai quan tâm. Nhưng khi ranh giới giữa 2 sao và 3 sao chỉ là một con số, "gần như giống nhau" là không đủ.

Nên mình đặt cho engine một luật cứng: **cùng một thiết kế phải ra kết quả giống hệt nhau, tới từng byte, trên mọi máy.** Để làm được điều đó:
- **Không dùng số thập phân.** Mọi thứ được đếm bằng số nguyên ở đơn vị thật nhỏ, giống như đếm tiền bằng từng đồng thay vì nói "1,5 nghìn". Thời gian tính bằng micro giây, tiền tính bằng phần triệu của một cent.
- **Không có gì ngẫu nhiên.** Engine không đọc đồng hồ, không dùng số ngẫu nhiên, không chạy nhiều việc song song. Các thành phần luôn được xét theo một thứ tự cố định.
- **Chia không làm rơi phần lẻ.** Chia 10 cho 3 phần thì ra 4, 3, 3, chứ không phải 3, 3, 3 rồi mất đi 1.

Có cả một bài test riêng chuyên đọc code của engine để chặn không cho mấy thứ trên lọt vào. Nghe hơi cực đoan, nhưng nó mang lại rất nhiều lợi ích. Bạn nào báo lỗi là mình tái hiện được ngay, đúng từng con số. Một thiết kế đã chấm rồi, nếu gửi lại y hệt thì server chỉ cần trả luôn kết quả cũ. Và như phần sau bạn sẽ thấy, nó là nền móng cho toàn bộ việc test màn chơi.

> 💡 Tính "giống hệt nhau" ở đây không phải để chạy nhanh hơn. Nó là điều kiện để mọi thứ khác đáng tin: bảng xếp hạng, số sao, và cả việc chứng minh một màn chơi không có đường tắt.

## Bên trong một lượt chạy

Engine không mô phỏng liên tục mà chạy theo từng nhịp, gọi là tick, giống các khung hình của một đoạn phim. Tùy màn, mỗi tick là 1 giây, 1 phút hoặc 3 phút, và một lượt chạy có tối đa 600 tick. Ở mỗi tick, engine làm đúng một chuỗi việc theo cùng một thứ tự: áp dụng sự cố nếu có, cho traffic vào, tính xem mỗi thành phần phải gánh bao nhiêu, rồi tính ngược lại xem bao nhiêu yêu cầu được trả lời và mất bao lâu.

Engine cũng không đếm từng người dùng một. Nó gom traffic thành từng dòng, kiểu "dòng người đọc bài từ app" hay "dòng người đăng bài". Nhờ vậy, 50 hay 50.000 lượt mỗi giây thì máy cũng tính nhanh như nhau.

Phần mình thích nhất là vài luật nhỏ, mà mỗi luật lại dạy một bài học có thật ngoài đời:

- **Thêm server mà không có Load Balancer thì vô ích.** Không có người đứng cửa chia khách thì khách vẫn dồn vào một người phục vụ, dù bạn thuê thêm bao nhiêu người. Rất nhiều bạn tăng số App Server lên gấp ba rồi ngạc nhiên vì hệ thống vẫn sập.
- **Quá tải thì chậm trước, rớt sau.** Giống như quán cà phê vào giờ cao điểm: càng gần kín chỗ thì càng chờ lâu, tới lúc quá sức thì bắt đầu có khách bỏ về.
- **Chồng hai lớp cache cũng không ăn gian được.** Món đã không có ở quầy thứ nhất thì quầy thứ hai cũng không có, vì hai quầy bày cùng một thực đơn.
- **Nhân bản thành phần gọi AI không làm tăng hạn mức.** Mấy thành phần cùng gọi một nhà cung cấp LLM thì dùng chung một hạn mức, nên thêm thành phần cũng không giúp gì.
- **Sự cố có hai kiểu.** Những sự cố như mất cả một vùng máy chủ hay nhà cung cấp bị sập sẽ kéo dài một khoảng thời gian rồi hết. Còn những sự cố như một máy bị chết hay cache bị xóa sạch thì xảy ra ngay lập tức và không tự hồi phục. Load Balancer cũng phải mất một lúc mới nhận ra một máy đã chết.

## Thêm màn mới mà không cần sửa engine

Mình không muốn mỗi lần thêm một màn lại phải sửa code của engine. Vì vậy toàn bộ nội dung game được viết thành các file cấu hình (YAML), đọc lên giống như một danh sách khai báo:
- **41 loại thành phần:** mỗi loại có các cỡ, sức chịu tải, tốc độ, giá tiền, và những việc nó biết làm.
- **76 loại traffic:** mỗi loại đi qua những chặng nào, ghé mỗi chặng bao nhiêu lần, và tốn bao nhiêu sức ở từng chặng.
- **90 màn chơi:** đề bài, bộ thành phần được phát, traffic, sự cố, luật chấm, và bài học mà màn muốn dạy.

Phần thật sự phải viết code chỉ có 29 hành vi bằng Go, chẳng hạn như phục vụ yêu cầu, chuyển tiếp, trả từ cache, giới hạn tốc độ, gọi LLM, chạy agent. Thêm một loại thành phần mới thường chỉ là ghép vài hành vi có sẵn lại với nhau, giống lắp Lego.

Trong file của mỗi màn có một dòng mình rất quý: dòng ghi màn đó dạy gì. Màn giờ trưa ghi rằng nó dạy về tỉ lệ trúng cache, kèm một lời hứa: cấm dùng cache thì không có cách nào qua màn với giá hợp lý. Dòng đó không phải để trang trí đâu. Phần test bên dưới sẽ bắt máy chứng minh lời hứa đó.

## Sập thì phải biết vì sao

Mỗi màn có một bộ luật chấm, lấy từ 15 loại: tỉ lệ được trả lời, thời gian chờ, ngân sách, mất dữ liệu, dữ liệu có bị cũ không, có bị trùng không, câu trả lời của AI có đạt không... Engine chấm hết các luật trên số liệu của cả lượt chạy, và luật trượt đầu tiên quyết định bạn thua kiểu gì.

Nhưng "thua vì chậm" vẫn chưa phải là lý do. Người chơi cần biết **cái gì** làm chậm. Vì vậy engine làm thêm hai bước:
1. **Tìm thủ phạm:** tùy theo kiểu thua, engine xếp hạng các thành phần theo mức làm rớt yêu cầu, mức chậm hơn bình thường, hoặc mức tốn tiền.
2. **Gọi đúng tên bệnh:** với mỗi thành phần bị nghi, engine dò một danh sách 112 lỗi xếp từ cụ thể tới chung chung. Lỗi cụ thể như "database quá tải vì bị đọc quá nhiều" được ưu tiên trước lỗi chung như "quá tải". Cuối danh sách luôn có vài lỗi chung nhất, nên lần thua nào cũng có lý do.

Thủ phạm đứng đầu được báo là nguyên nhân chính, kèm theo tối đa ba nguyên nhân phụ, và mỗi lỗi dẫn bạn tới bài học tương ứng.

Còn số sao thì được tính theo chi phí. Thiết kế có chi phí sát với lời giải tốt nhất mà máy tìm được thì được 3 sao, dư một chút thì được 2 sao, còn miễn nằm trong ngân sách là được 1 sao. Cứ chọn mọi thứ to nhất cho chắc thì không bao giờ có sao, và điều đó cũng được test hẳn hoi.

## Phần mình không ngờ tốn công nhất: test từng màn

Viết engine xong mình mới nhận ra: engine đúng chưa đủ, màn chơi cũng phải đúng. Mà một màn có thể sai theo những kiểu rất khó thấy:
- có đường tắt, qua được mà chẳng cần học gì;
- quá dễ, ai chơi cũng được 3 sao;
- sự cố chỉ để trang trí, có hay không cũng vậy;
- người chơi thua vì một lý do chẳng liên quan gì tới bài học.

Nếu chỉ chơi thử bằng tay thì không bao giờ bắt hết được các lỗi này. Vì vậy mỗi màn phải qua 14 bước kiểm tra tự động. Engine chạy được ngay trên máy cá nhân, không cần server hay database, nên mỗi vòng thử rồi sửa diễn ra rất nhanh. Dưới đây là vài bước đáng kể nhất:

| Bước kiểm tra | Câu hỏi nó trả lời |
|---|---|
| Lời giải mẫu và thiết kế sai | Lời giải mẫu có qua không? Thiết kế sai có thua đúng lý do không? |
| Giấu bài học đi | Nếu cấm thứ mà màn muốn dạy, máy còn tìm được cách qua màn với giá rẻ không? |
| Chọn to hết | Nếu chọn mọi thứ to nhất, người chơi có tự động được sao không? |
| Sự cố có tác dụng | Mỗi sự cố có thật sự làm thay đổi kết quả không? |
| Đúng bài học | Lỗi mà người chơi gặp có đúng với điều màn định dạy không? |

Đứng sau mấy bước này là một con **bot giải đề**, đóng vai một người chơi rất khó tính. Nó thử hàng nghìn thiết kế: thêm bớt thành phần, đổi lại kết nối, đổi cỡ, đổi số lượng, và xuất phát lại từ nhiều điểm khác nhau để không bị mắc kẹt ở một hướng. Nó ưu tiên thiết kế ít luật trượt nhất, rồi tới thiết kế rẻ nhất.

Bước "giấu bài học đi" là bước mình thấy hay nhất. Màn nào bắt buộc phải dùng cache thì khi cấm cache, con bot không được tìm ra bất kỳ cách nào qua màn. Còn ở màn mà cache chỉ giúp tiết kiệm hơn, con bot vẫn được phép qua màn, nhưng thiết kế của nó phải đắt hơn hẳn. Ngược lại, nếu con bot tìm ra thiết kế rẻ hơn cả lời giải mẫu, người soạn màn phải ngồi xem lại: hoặc lời giải mẫu chưa tối ưu, hoặc màn có lỗ hổng.

![Bot giải đề kiểm tra mỗi màn: lời giải mẫu phải qua, thiết kế sai phải sập, và khi giấu bài học đi thì không còn đường qua.](https://assets.200lab.io/sha256/e0/e0e7a83672bb0a7ce779c020821df74b52fb08c944c6dda9c5662184323e28a4/generations/66064c030ade4d4a1c56e928a91fc857d292e3e099a8ab69af012df2520e5d31)

> ⚠️ Con bot không tìm ra đường tắt chưa có nghĩa là không có đường tắt. Trừ khi màn đủ nhỏ để nó thử hết mọi khả năng, nó chỉ nói được rằng với chừng này công sức, nó chưa tìm ra cách nào tốt hơn. Vì vậy vẫn cần người và agent khác soát lại.

Ngoài ra còn một lớp bảo vệ nữa: mình lưu sẵn kết quả của mọi lời giải mẫu và thiết kế sai trong cả 90 màn. Mỗi lần sửa engine, máy chạy lại hết và so từng byte với kết quả đã lưu, chỉ trừ số phiên bản engine. Chỉ cần lệch một chỗ là test báo đỏ ngay, và muốn chấp nhận chỗ lệch đó thì phải giải thích được vì sao. Đây chính là lúc cái luật "giống hệt từng byte" ở trên phát huy tác dụng.

Quy trình soạn một màn của mình như sau:
1. Một agent soạn màn, kèm lời giải mẫu và thiết kế sai.
2. Chạy kiểm tra nhanh.
3. Một agent khác chỉ được đọc đề, rồi tự giải "mù".
4. Chạy kiểm tra đầy đủ và lưu lại kết quả.
5. Sửa tối đa ba vòng.
6. Người thật chơi thử rồi mới mở cho mọi người.

Chạy kiểm tra đầy đủ cho cả 90 màn khá nặng, vì mỗi màn con bot phải giải lại 20 lần từ 20 điểm xuất phát khác nhau. Vì vậy mình đóng gói phần backend lại, mang sang chạy trên một cái PC riêng, chạy xong thì mang kết quả về.

## Gợi ý: câu chuyện ở màn 7

Khi bí quá, bạn có thể mở gợi ý. Gợi ý gồm 4 bước, mở dần theo số lần bạn thua:
1. **Hướng đi:** nên thử thành phần nào.
2. **Cơ chế:** kết nối thế nào, kèm phép tính.
3. **Cách sửa:** gọt bớt một thiết kế đã qua nhưng còn thừa.
4. **Lời giải.**

Lúc mới mở game, gợi ý miễn phí ở nhiều màn toàn là câu hỏi gợi mở kiểu "bạn nghĩ chỗ nào đang nghẽn?", còn nước đi quyết định thì lại nằm ở bước sau. Màn 7, "Đêm Hacker News", là chỗ rất nhiều bạn bị kẹt lại. Mình đổi gợi ý thành hành động cụ thể, kiểu "Hãy thử dùng các cụm service cho gọn", "Hãy thử cho các cụm service nối với Read Replica". Có lộ bài một chút cũng không sao, vì phải qua được màn thì bạn mới học tiếp được.

## Skin Sketch: biến canvas thành whiteboard

Game có hai giao diện để bạn chọn, Soft và Sketch. Sketch là giao diện mình đầu tư kỹ nhất về mặt hình ảnh: giấy trắng trên nền chấm, nét marker đen, màu marker tươi kiểu Excalidraw, chữ viết tay Patrick Hand (có đủ dấu tiếng Việt) cho tiêu đề và tên thành phần, còn các dòng thông tin dùng chữ thường cho dễ đọc.

![Skin Sketch: sticky note, nút, con dấu CRASHED và PASSED, và một canvas có thành phần đang được chọn cùng database bị đóng dấu CRASHED.](https://assets.200lab.io/sha256/45/458050e112675a81230a0a10af8d7370201e3a7a45b9a4bc136ce611475a9510/generations/d1889592c229316d3ad68fbd345e4563d0e2eb6052533709258ab6aa3e9f15b4)

Vài luật giữ cho giao diện này vừa đẹp vừa nhẹ:
- **Chiều sâu bằng nét mực, không bằng bóng đổ.** Card và nút chỉ có một viền mực mảnh. Ở chế độ tối, viền được chuyển sang màu xám, vì nếu card nào cũng viền trắng thì màn hình trông như một bức tường đầy khung trắng.
- **Khi rê chuột, mọi thứ chỉ đổi màu, không có gì nhảy lên nhảy xuống.** Khi bạn không làm gì, canvas đứng yên hoàn toàn, máy không phải vẽ lại gì cả.
- **Hình vẽ tay chỉ được vẽ một lần.** Mỗi thành phần có một hình nói lên nó là gì: load balancer hình quạt, database hình trụ, hàng đợi hình ống, LLM hình con chip. Hình được vẽ bằng thư viện rough.js với một "hạt giống" cố định cho từng loại, nên nét run tay lần nào cũng y như nhau. Còn khi một thành phần được chọn, đang nóng hay đã sập, game chỉ tô lại màu trên đúng hình đã vẽ sẵn.

Có một lỗi trên production đã dạy mình một bài học nhớ đời. Nút "Xem trên board" thay toàn bộ thiết kế đang có bằng một thiết kế mới. Thiết kế mới cũng đặt tên các thành phần là n1, n2… như thiết kế cũ, nhưng n1 bây giờ lại là một loại thành phần khác. Thư viện vẽ canvas nhớ vị trí các điểm kết nối theo tên thành phần, nên nó vẫn dùng vị trí cũ, và kết quả là các kết nối không vẽ ra được. Từ đó, mọi tính năng thay thiết kế trên canvas (mở, xem trước, hoàn tác, dán) đều phải test với một thiết kế trùng tên thành phần nhưng khác loại.

## Bộ file để bạn tự dựng lại với Agent

Đọc tới đây là bạn đã có gần đủ bức tranh để tự làm một game kiểu này. Phần còn lại là vài trăm quyết định nhỏ mà mình đã phải sửa đi sửa lại, có nhiều chỗ mình chỉ phát hiện ra là đã mô tả sai so với engine thật sau khi nhờ Codex soát lại.

Mình đã gom chúng vào 3 file, viết để bạn đưa thẳng cho một coding agent (Claude Code, Codex…) và bảo nó dựng lại trên công nghệ bạn chọn:

- **Engine rules:** đầy đủ những luật mà bài này chỉ kể sơ qua, gồm:
  - cách khai báo thành phần, traffic, màn chơi và thiết kế;
  - cách cộng dồn thời gian chờ và tỉ lệ thành công qua nhiều chặng;
  - cách chia traffic, cache, hạn mức dùng chung, vòng lặp, hàng đợi, thử lại, tự tăng máy;
  - cách tính tiền, chấm luật, tìm nguyên nhân, tính sao và thang gợi ý;
  - 10 bước kiểm tra màn bắt buộc, kèm cách chạy bot giải đề và cách lưu kết quả để so sánh;
  - thứ tự nên xây, khi nào coi là xong, và cách làm nếu ngôn ngữ của bạn không có sẵn số nguyên 64-bit nhanh.
- **CSS của skin Sketch:** dùng được ngay, có cả chế độ sáng và tối. File gồm bảng màu whiteboard, nền chấm, nét gạch lượn sóng, khung viền run tay, nút, chip, công tắc, sticky note, con dấu CRASHED và PASSED, cùng mọi trạng thái của canvas (thành phần, kết nối, đang nóng, đã sập, hiệu ứng qua màn).
- **Hướng dẫn skin Sketch:** 9 luật thiết kế, bảng màu, công thức vẽ thành phần và kết nối bằng rough.js với đúng thông số trong game, và bảng 20 kiểu hình vẽ theo vai trò của từng thành phần.

Cả 3 file đều không gắn với công nghệ của 200Lab. Bạn dùng React hay Vue, Go hay Node đều được, hoặc chỉ lấy phần skin cho một app vẽ sơ đồ của riêng mình cũng được.

**Bộ engine rules và skin Sketch của GonnaCrash**

Bộ 3 file cho coding Agent dựng lại game system design kiểu GonnaCrash: engine rules (mô phỏng tất định, chấm điểm, kiểm chứng level, solver), CSS và hướng dẫn skin Sketch vẽ bằng rough.js.

- Định dạng: ZIP · 1 tệp · 20,7 KB
- Giá: 49.000 ₫ · giá gốc 99.000 ₫ · mua một lần
- Truy cập: tải về sau khi mua, cần đăng nhập
- Mua: https://200lab.io/blog/game-system-design-gonnacrash-duoc-lam-nhu-the-nao#artifact-01a16360-94e9-76ae-af82-986240ad6fc8

## Đọc thêm

- [Architecture Pattern - Phần 7: Hexagonal Architecture](https://200lab.io/blog/hexagonal-architecture-la-gi.md): Hexagonal Architecture là pattern kiến trúc mà mọi tương tác từ bên ngoài đều phải đi qua một Adapter để kết nối vào một Port của Application
- [File __init__.py trong Python: Hướng dẫn sử dụng toàn diện](https://200lab.io/blog/huong-dan-su-dung-toan-dien-file-init-trong-python.md): __init__.py không chỉ đơn thuần là một file đánh dấu package, nó quyết định cách package của bạn được cấu trúc, import và tối ưu ra sao
- [Thiết kế Leaderboard hiệu năng cao: Khi nào chọn SQL, Khi nào dùng Redis?](https://200lab.io/blog/thiet-ke-leaderboard-hieu-nang-cao-khi-nao-chon-sql-khi-nao-dung-redis.md): Khám phá cách thiết kế hệ thống Leaderboard tối ưu, linh hoạt, dễ mở rộng, kết hợp giữa tư duy thiết kế hệ thống hiện đại và kinh nghiệm thực tế
- [Hành vi giúp Phân biệt các Senior Engineer với những người còn lại](https://200lab.io/blog/hanh-vi-giup-phan-biet-cac-senior-engineer-voi-nhung-nguoi-con-lai.md): Việc trở thành một senior engineer thực sự không chỉ nằm ở chức danh bạn được giao, mà là kết quả của tư duy, cách tiếp cận công việc mà bạn rèn luyện mỗi ngày
- [Asynchronous Request-Reply Pattern: Giải pháp cho những tác vụ nặng](https://200lab.io/blog/asynchronous-request-reply-pattern-la-gi.md): Pattern giúp tách rời phần xử lý backend, diễn ra bất đồng bộ khỏi frontend nhưng vẫn phải đảm bảo frontend nhận được thông báo kết quả cuối cùng
- [Mọi bài viết chủ đề Backend](https://200lab.io/blog/tags/backend.md)

Toàn bộ nội dung: https://200lab.io/llms.txt
