<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>TDD on miti99</title><link>https://miti99.com/tags/tdd/</link><description>Recent content in TDD on miti99</description><generator>Hugo -- gohugo.io</generator><language>vi</language><lastBuildDate>Mon, 28 Sep 2026 09:25:57 +0700</lastBuildDate><atom:link href="https://miti99.com/tags/tdd/index.xml" rel="self" type="application/rss+xml"/><item><title>Newsletter #46</title><link>https://miti99.com/post/2025/08/05/</link><pubDate>Tue, 05 Aug 2025 00:00:00 +0700</pubDate><guid>https://miti99.com/post/2025/08/05/</guid><description>&lt;p&gt;&lt;em&gt;&lt;del&gt;Bài viết này sẽ quay lại dùng Claude Code nha :D (chân ái là đây, chỉ khi nào ngại tốn token mới phải nhảy sang agent khác).&lt;/del&gt; Mời bạn thưởng thức Newsletter #46.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-pragmatic-engineer-2025-survey-what"&gt;&lt;a class="link" href="https://newsletter.pragmaticengineer.com/p/the-pragmatic-engineer-2025-survey" target="_blank" rel="noopener"
&gt;The Pragmatic Engineer 2025 Survey: What&amp;rsquo;s in your tech stack?&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Gergely Orosz công bố phần đầu kết quả khảo sát công nghệ năm 2025 của The Pragmatic Engineer, dựa trên gần 3.000 phản hồi hợp lệ. &amp;ldquo;Người trả lời điển hình&amp;rdquo; là một kỹ sư phần mềm cấp senior với 6–10 năm kinh nghiệm, làm backend ở công ty đủ mọi quy mô. Có tới 85% người tham gia nhắc đến ít nhất một công cụ AI. GitHub Copilot vươn lên dẫn đầu, cứ hai người thì một người dùng; Cursor dù mới ra mắt năm 2023 và chưa chi đồng nào cho tiếp thị đã đứng thứ hai. Claude thu hẹp đáng kể khoảng cách với ChatGPT, còn Claude Code đã được nhắc khá nhiều dù lúc khảo sát đóng lại nó mới chính thức ra mắt được vài ngày.&lt;/p&gt;
&lt;p&gt;Về ngôn ngữ, TypeScript, Python và Swift được dùng nhiều nhất, trong khi Ruby on Rails và Elixir được yêu thích hơn hẳn so với mức độ phổ biến, và không ngôn ngữ nào bị chê nhiều hơn được khen. JIRA là công cụ bị ghét nhất, vượt cả bốn cái tên kế tiếp cộng lại, chủ yếu vì chậm và rườm rà; Linear thường được nhắc tới như lựa chọn thay thế. Git gần như là mặc định cho quản lý phiên bản, nhưng GitLab và Bitbucket vẫn có lượng người dùng đáng kể, còn GitHub Actions dẫn đầu mảng CI/CD. Ở mảng hạ tầng, AWS đứng đầu, theo sau là Azure và Google Cloud, và Vercel là nhà cung cấp nổi bật nhất ngoài nhóm &amp;ldquo;Big 3&amp;rdquo;. Bài học rút ra: lập trình viên không ngại thử công cụ mới ở những lĩnh vực đang thay đổi nhanh như AI.&lt;/p&gt;
&lt;h2 id="algorithms-for-making-interesting-organic-simulations"&gt;&lt;a class="link" href="https://bleuje.com/physarum-explanation/" target="_blank" rel="noopener"
&gt;Algorithms for making interesting organic simulations&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Bài viết giải thích các kỹ thuật tạo ra những mô phỏng mang dáng vẻ sinh học, thiên về mục đích nghệ thuật hơn là khoa học. Điểm xuất phát là thuật toán Physarum của Jeff Jones (2010): rất nhiều tác nhân (agent) di chuyển trên mặt phẳng 2D, mỗi tác nhân có vị trí và hướng đi. Ở mỗi vòng lặp, tác nhân &amp;ldquo;nhìn&amp;rdquo; ba điểm phía trước (thẳng, lệch trái, lệch phải), quay về phía có vết tích mạnh nhất, tiến lên một đoạn rồi để lại vết tích trên một ảnh gọi là trail map; sau đó ảnh này được làm mờ nhẹ và nhân với hệ số suy giảm để hệ thống ổn định. Chỉ với bốn tham số (khoảng cách cảm nhận, góc cảm nhận, góc quay, bước di chuyển) đã có thể tạo ra nhiều hành vi khác nhau.&lt;/p&gt;
&lt;p&gt;Phần thú vị nhất đến từ tác phẩm &lt;em&gt;36 Points&lt;/em&gt; của Sage Jenson: thay vì giữ tham số cố định, mỗi tham số được tính theo giá trị vết tích tại vị trí của tác nhân, cộng thêm các độ lệch khi lấy mẫu, nâng tổng số lên khoảng 14–20 tham số và cho ra những hành vi đa dạng đến bất ngờ. Tác giả chia sẻ bản cài đặt riêng (physarum-36p) dùng compute shader trên GPU qua openFrameworks, gồm bốn shader cho các bước đặt lại bộ đếm, di chuyển hạt, để lại vết tích và khuếch tán, chạy mượt với hàng triệu hạt. Đây là minh chứng đẹp cho việc vài quy tắc đơn giản có thể sinh ra hành vi phức tạp.&lt;/p&gt;
&lt;h2 id="ai-coding-tools-are-shifting-to-a-surprising-place-the-terminal"&gt;&lt;a class="link" href="https://techcrunch.com/2025/07/15/ai-coding-tools-are-shifting-to-a-surprising-place-the-terminal/" target="_blank" rel="noopener"
&gt;AI coding tools are shifting to a surprising place: The terminal&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Theo TechCrunch, các công cụ lập trình bằng AI đang dịch chuyển từ trình soạn thảo mã nguồn sang terminal. Kể từ tháng 2, Anthropic, DeepMind và OpenAI lần lượt ra mắt công cụ dòng lệnh của mình (Claude Code, Gemini CLI và Codex CLI), và chúng nhanh chóng trở thành những sản phẩm được ưa chuộng nhất của các công ty này. Mike Merrill, đồng tác giả benchmark Terminal-Bench, đặt cược rằng trong tương lai 95% tương tác giữa LLM và máy tính sẽ diễn ra qua giao diện kiểu terminal. Trong khi đó, nhóm công cụ dựa trên trình soạn thảo lại có dấu hiệu chững lại: Windsurf bị chia cắt sau các thương vụ thâu tóm, còn một nghiên cứu của METR cho thấy lập trình viên dùng Cursor Pro tưởng mình nhanh hơn 20–30% nhưng thực tế lại chậm hơn gần 20%.&lt;/p&gt;
&lt;p&gt;Khác biệt nằm ở phạm vi công việc. Thế hệ công cụ cũ, đo bằng SWE-Bench, tập trung sửa mã nguồn lỗi từ các issue trên GitHub; còn công cụ terminal nhìn vào toàn bộ môi trường chạy chương trình, bao gồm cả các tác vụ DevOps như cấu hình Git server, biên dịch Linux kernel hay tìm hiểu vì sao một script không chạy. Warp, đang dẫn đầu Terminal-Bench, cũng chỉ giải được hơn một nửa số bài, cho thấy còn nhiều việc phải làm. Dù vậy, nhà sáng lập Warp tin rằng những việc như khởi tạo dự án, xử lý phụ thuộc và làm cho nó chạy được giờ đã có thể giao gần như hoàn toàn cho AI.&lt;/p&gt;
&lt;h2 id="distributed-systems-reliability-glossary"&gt;&lt;a class="link" href="https://antithesis.com/resources/reliability_glossary/" target="_blank" rel="noopener"
&gt;Distributed Systems Reliability Glossary&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Jepsen và Antithesis cùng biên soạn một bảng thuật ngữ về độ tin cậy của hệ thống phân tán, hướng tới lập trình viên ở mọi giai đoạn sự nghiệp. Theo nhóm tác giả, đây là nguồn đầu tiên gom về một chỗ những khái niệm vốn nằm rải rác ở nhiều lĩnh vực khác nhau. Tài liệu được chia thành các phần: khái niệm nền tảng, mô hình nhất quán (hệ thống được phép làm gì), mô hình khả dụng, các hiện tượng bất thường, các loại lỗi (từ mất dữ liệu, lệch đồng hồ đến lỗi Byzantine) và kỹ thuật kiểm thử, kèm một danh sách tài liệu đọc thêm. Mỗi mục có định nghĩa trực quan và đường dẫn tới nguồn học thuật chính thống khi cần đào sâu.&lt;/p&gt;
&lt;p&gt;Điểm đáng quý là tinh thần thực tế: tác giả nhấn mạnh đây là tài liệu tra cứu chứ không phải bài bắt buộc phải đọc hết, và mỗi lần viết integration test là bạn đã kiểm thử một hệ thống phân tán rồi. Phần kiểm thử giải thích vì sao hệ thống phân tán khó: chúng vốn chạy đồng thời và thường xuyên gặp lỗi cục bộ. Từ đó tài liệu giới thiệu các kỹ thuật như kiểm thử đồng thời, chủ động gây lỗi (fault injection), kiểm thử mô phỏng tất định, kiểm thử dựa trên thuộc tính (property-based testing) và thu gọn đầu vào lỗi (shrinking). Một tài liệu nên lưu lại để tra cứu khi làm việc với cơ sở dữ liệu hay hệ thống nhiều node.&lt;/p&gt;
&lt;h2 id="test-driven-development-tdd-with-dbt"&gt;&lt;a class="link" href="https://xebia.com/blog/test-driven-development-tdd-with-dbt/" target="_blank" rel="noopener"
&gt;Test-Driven Development (TDD) with dbt&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Dumky de Wilde (Xebia) bàn về việc áp dụng phát triển hướng kiểm thử (TDD) cho dbt, công cụ biến đổi dữ liệu phổ biến trong analytics engineering. Thay vì viết model rồi hy vọng số liệu đúng, bạn định nghĩa trước thế nào là &amp;ldquo;dữ liệu tốt&amp;rdquo;, viết kiểm thử, nhìn nó thất bại, rồi mới viết SQL vừa đủ để vượt qua. Tác giả phân biệt các nhóm kiểm thử: kiểm tra từng dòng trên một hoặc nhiều cột (như &lt;code&gt;not_null&lt;/code&gt;, &lt;code&gt;unique&lt;/code&gt;), kiểm thử tổng hợp trên cả model, unit test cho model (có sẵn từ dbt 1.8, dùng dữ liệu giả lập thay vì dữ liệu thật), unit test cho macro và model contract. Contract đặc biệt hữu ích vì ràng buộc được áp ngay ở tầng cơ sở dữ liệu trong lúc xây dựng, model sai cấu trúc sẽ không build được.&lt;/p&gt;
&lt;p&gt;Bài có ví dụ viết trước một kiểm thử giới hạn số dòng cho model chưa tồn tại, buộc bạn phải trả lời những câu hỏi nghiệp vụ như &amp;ldquo;vì sao lại từ 1 đến 99 dòng?&amp;rdquo; trước khi viết dòng SQL nào. Về thực hành, tác giả khuyên luôn chạy unit test và contract khi phát triển cục bộ và trong CI/CD, chỉ chạy data test có chọn lọc, và bỏ unit test ở môi trường production. Nên dùng tag để nhóm kiểm thử, tự tạo bộ dữ liệu mẫu (fixture) nhỏ cho các trường hợp biên và ghi lại lý do tồn tại của từng kiểm thử. Thông điệp chính là chuyển tư duy từ &amp;ldquo;xây trước, kiểm thử sau&amp;rdquo; sang &amp;ldquo;định nghĩa thành công trước, rồi mới xây&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="rethinking-oop"&gt;&lt;a class="link" href="https://max.xz.ax/blog/rethinking-oop/" target="_blank" rel="noopener"
&gt;Rethinking OOP&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Tác giả mở đầu bằng một ví dụ từ khóa AP Computer Science A: định nghĩa &amp;ldquo;class là bản thiết kế để tạo ra object, object là một thể hiện của class&amp;rdquo; gần như vô nghĩa với người mới học. Theo tác giả, dạy OOP quá sớm và không giải thích lý do khiến học sinh làm theo khuôn mẫu một cách máy móc thay vì suy nghĩ xem bài toán có thực sự cần đến nó hay không. Lấy cảm hứng từ &amp;ldquo;design recipe&amp;rdquo; của giáo sư Matthias Felleisen và cách dạy Java hiện đại của Ethan McCue, bài đề xuất bắt đầu từ thứ thật đơn giản, chỉ giới thiệu tính năng mới khi người học đã gặp giới hạn của bộ công cụ hiện có.&lt;/p&gt;
&lt;p&gt;Cụ thể, người học có thể dùng tệp nguồn gọn nhẹ của JDK 25 (hoặc JShell) để viết ngay các câu lệnh tuần tự mà không cần đến &lt;code&gt;public static void main&lt;/code&gt;. Khi phải chép lại cùng một đoạn kiểm tra số nguyên tố cho nhiều biến, họ tự thấy cần phương thức; khi quản lý quá nhiều biến rời rạc, họ mới hiểu giá trị của việc gom dữ liệu thành class. Tác giả thừa nhận cách này khiến học sinh viết mã nguồn &amp;ldquo;xấu&amp;rdquo; lúc đầu, nhưng chính việc sống chung với mã nguồn lặp lại, vụng về mới giúp các lựa chọn thiết kế trở nên có ý nghĩa. Kết luận của bài rất đáng suy ngẫm: các best practice không cần học thuộc từ sách, mà có thể trở nên trực quan qua việc tăng dần độ phức tạp của chương trình.&lt;/p&gt;
&lt;h2 id="how-i-write-code-that-i-don"&gt;&lt;del&gt;&lt;a class="link" href="https://dev.to/resource_bunk_1077cab07da/how-i-write-code-that-i-dont-hate-reading-a-week-later-303b" target="_blank" rel="noopener"
&gt;How I Write Code That I Don&amp;rsquo;t Hate Reading a Week Later&lt;/a&gt;&lt;/del&gt;
&lt;/h2&gt;&lt;p&gt;&lt;del&gt;Một bài viết thực tế và hữu ích về cách viết mã dễ đọc - một kỹ năng quan trọng mà nhiều lập trình viên thường bỏ qua. Tác giả chia sẻ triết lý cốt lõi: &amp;ldquo;Viết mã như thể bạn sẽ phải debug nó lúc 2 giờ sáng, trong trạng thái buồn ngủ, với deadline cận kề.&amp;quot;&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;&lt;del&gt;Các nguyên tắc chính bao gồm: đặt tên biến và hàm mô tả rõ ràng (ví dụ &lt;code&gt;parsed_user_profile_data&lt;/code&gt; thay vì chỉ &lt;code&gt;d&lt;/code&gt;), viết comment giải thích &amp;ldquo;tại sao&amp;rdquo; thay vì &amp;ldquo;cái gì&amp;rdquo;, ưu tiên tính dễ đọc hơn là &amp;ldquo;sự thông minh&amp;rdquo; của mã. Thay vì viết những dòng mã phức tạp để khoe kỹ thuật, hãy tách chúng thành nhiều dòng dễ hiểu hơn.&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;&lt;del&gt;Điểm hay nhất là nguyên tắc viết hàm nhỏ và tập trung: mỗi hàm chỉ làm một việc cụ thể với tên mô tả rõ ràng như &lt;code&gt;handleLoginFormSubmission()&lt;/code&gt;. Khi mã trở nên rối rắm, hãy dừng lại và tái cấu trúc thay vì cứ thêm độ phức tạp. Tác giả cũng giới thiệu các công cụ hỗ trợ như Prettier, Black cho Python, và thậm chí ChatGPT để giúp tái cấu trúc mã. Đây là những lời khuyên đơn giản nhưng cực kỳ thực tế cho bất kỳ lập trình viên nào muốn code của mình dễ bảo trì hơn.&lt;/del&gt;&lt;/p&gt;
&lt;h2 id="7-habits-that-quietly-made-me-a-10x-developer-no-not-chatgpt"&gt;&lt;a class="link" href="https://dev.to/abubakersiddique771/7-habits-that-quietly-made-me-a-10x-developer-no-not-chatgpt-13c4" target="_blank" rel="noopener"
&gt;7 Habits That Quietly Made Me A 10x Developer (No, Not ChatGPT)&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Bài viết cho rằng trở thành &amp;ldquo;lập trình viên 10x&amp;rdquo; không nằm ở tài năng bẩm sinh hay làm việc 20 tiếng mỗi ngày, mà ở những thói quen nhỏ được duy trì đều đặn, không cần đến trợ lý AI. Thói quen đầu tiên là viết mã nguồn để sinh ra mã nguồn: dùng script, generator và công cụ scaffolding để tự động hóa phần khung, các endpoint CRUD, khung kiểm thử hay workflow GitHub Actions, để không phải giải cùng một bài toán hai lần. Thứ hai là thiết kế cho &amp;ldquo;bản thân trong tương lai&amp;rdquo; với commit message mô tả rõ, tên hàm dễ hiểu, cấu trúc thư mục hợp lý và viết README.md trước khi bắt tay xây dựng. Thứ ba là ghi một &amp;ldquo;nhật ký debug&amp;rdquo; ngắn gồm vấn đề, giả thuyết và kế hoạch trước khi sửa lỗi, vì viết ra buộc mình suy nghĩ rõ ràng.&lt;/p&gt;
&lt;p&gt;Các thói quen còn lại gồm tự làm những công cụ nhỏ cho riêng mình (CLI đổi tên ảnh chụp màn hình, trình sinh snippet), dành các khối 90 phút tập trung sâu không Slack hay mạng xã hội, học cách người khác tổ chức quy trình làm việc chứ không chỉ sao chép mã nguồn, và tự nhìn lại mỗi thứ Sáu với ba câu hỏi: điều gì tốt, điều gì làm mình chậm lại, và sẽ tự động hóa hay cải thiện gì tiếp theo. Theo tác giả, hiệu quả &amp;ldquo;10x&amp;rdquo; là kết quả cộng dồn của nhiều cải tiến nhỏ theo thời gian.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Claude Code thật sự là chân ái :D Xử lý nhanh, tóm tắt gọn, càng ngày càng tốt. Thật tuyệt vời!&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Bài viết đã được viết lại bởi Claude Code với Opus 5.5 vào ngày 27/09/2026.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Newsletter #34</title><link>https://miti99.com/post/2025/07/23/</link><pubDate>Wed, 23 Jul 2025 00:00:00 +0700</pubDate><guid>https://miti99.com/post/2025/07/23/</guid><description>&lt;p&gt;&lt;em&gt;Mời bạn thưởng thức Newsletter #34.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="why-tdd-doesn"&gt;&lt;a class="link" href="https://tidyfirst.substack.com/p/why-tdd-doesnt-lead-to-dumb-code" target="_blank" rel="noopener"
&gt;Why TDD Doesn&amp;rsquo;t Lead to Dumb Code&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Kent Beck phản bác một lập luận quen thuộc: phát triển hướng kiểm thử (TDD) sẽ khiến mã nguồn trở nên &amp;ldquo;ngớ ngẩn&amp;rdquo; vì lập trình viên chỉ viết đúng đủ để vượt qua từng ca kiểm thử mà không bao giờ tổng quát hóa. Theo ông, chất lượng thiết kế của mã viết theo TDD cũng chỉ tốt đúng bằng những quyết định thiết kế mà người viết đưa ra, không khác gì mã không dùng TDD. Ông minh họa bằng hàm tính giai thừa: bắt đầu với &lt;code&gt;assert factorial(1) == 1&lt;/code&gt; và cài đặt trả về 1, thêm &lt;code&gt;assert factorial(2) == 2&lt;/code&gt; thì tạm trả về 2. Thay vì cứ thêm từng dòng điều kiện, lập trình viên nhận ra cấu trúc ẩn: số 2 thực chất là &lt;code&gt;2 * 1&lt;/code&gt;, số 2 ấy chính là tham số &lt;code&gt;n&lt;/code&gt;, còn số 1 là kết quả của lời gọi đệ quy, và từ đó thu được hàm &lt;code&gt;n * factorial(n - 1)&lt;/code&gt; tổng quát qua những bước rất nhỏ.&lt;/p&gt;
&lt;p&gt;Khó khăn thực tế nằm ở chỗ khác: đôi khi chưa có đủ ca kiểm thử để ràng buộc mã nguồn chỉ ở trạng thái đúng, và đôi khi ta chưa biết cách tổng quát hóa, có thể giữ vài trường hợp đặc biệt trong nhiều năm, điều đó vẫn chấp nhận được miễn là mã chạy đúng với các trường hợp cần thiết. Điều không bao giờ xảy ra là sao chép mã vô tận. Cuối cùng, ông chỉ ra rằng cài đặt ngây thơ bị ràng buộc chặt với bộ kiểm thử, mỗi lần thêm khẳng định lại phải sửa hàm, còn tổng quát hóa giúp gỡ bỏ sự ràng buộc đó, cho phép thêm kiểm thử mà không đổi mã và ngược lại.&lt;/p&gt;
&lt;h2 id="how-discord-indexes-trillions-of-messages"&gt;&lt;a class="link" href="https://discord.com/blog/how-discord-indexes-trillions-of-messages" target="_blank" rel="noopener"
&gt;How Discord Indexes Trillions of Messages&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Discord kể lại cách họ làm lại hệ thống tìm kiếm tin nhắn, vốn được xây trên Elasticsearch từ năm 2017, để theo kịp quy mô hàng nghìn tỷ tin nhắn. Hệ thống cũ bộc lộ nhiều vết nứt: hàng đợi đánh chỉ mục dựa trên Redis làm rơi tin nhắn khi bị dồn ứ, việc đánh chỉ mục hàng loạt không chịu được lỗi khi một chỉ mục hay nút Elasticsearch gặp sự cố, các cụm lớn tốn nhiều chi phí vận hành và khó nâng cấp hay khởi động lại cuốn chiếu, còn chỉ mục của những máy chủ (guild) rất lớn phình to quá mức. Giải pháp là triển khai Elasticsearch trên Kubernetes bằng Elastic Operator, chia thành nhiều cụm nhỏ gom nhóm theo kiến trúc &amp;ldquo;cell&amp;rdquo;, chuyển hàng đợi sang Google PubSub để bảo đảm không mất tin nhắn, và viết bộ định tuyến bằng Rust với Tokio để gom tin nhắn theo cụm và chỉ mục đích trước khi đánh chỉ mục hàng loạt.&lt;/p&gt;
&lt;p&gt;Kiến trúc cell còn mở ra tính năng mới: tin nhắn riêng (DM) được phân mảnh theo &lt;code&gt;user_id&lt;/code&gt; trong một cell riêng, cho phép tìm kiếm xuyên qua mọi DM của người dùng. Với các &amp;ldquo;Big Freaking Guilds&amp;rdquo; chạm giới hạn khoảng 2 tỷ tài liệu của Lucene, Discord đánh chỉ mục lại tin nhắn sang chỉ mục có nhiều phân mảnh chính hơn trong một cell dành riêng. Kết quả: thông lượng đánh chỉ mục tăng gấp đôi, độ trễ truy vấn trung vị giảm từ 500ms xuống dưới 100ms (p99 từ 1 giây xuống dưới 500ms), vận hành 40 cụm với hàng nghìn chỉ mục, và nâng cấp cụm tự động mà không ảnh hưởng dịch vụ.&lt;/p&gt;
&lt;h2 id="data-oriented-programming-dop-in-java"&gt;&lt;a class="link" href="https://nejckorasa.github.io/posts/data-oriented-programming-in-java/" target="_blank" rel="noopener"
&gt;Data Oriented Programming (DOP) in Java&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Lập trình hướng dữ liệu (DOP) đảo ngược thói quen của lập trình hướng đối tượng: thay vì gói trạng thái và hành vi chung trong một lớp, dữ liệu được mô hình bằng các cấu trúc đơn giản, thụ động, còn logic nằm trong các hàm độc lập thao tác trên dữ liệu đó. Bài viết nêu bốn nguyên tắc: mô hình hóa dữ liệu bất biến và minh bạch, chỉ mô hình đúng và đủ dữ liệu, khiến trạng thái không hợp lệ không thể biểu diễn được, và tách thao tác khỏi dữ liệu. Java hiện đại hỗ trợ tốt cách làm này qua ba tính năng: records làm lớp mang dữ liệu bất biến gọn nhẹ, sealed classes giới hạn tập kiểu con để trình biên dịch biết hết các trường hợp, và &lt;code&gt;switch&lt;/code&gt; kết hợp so khớp mẫu có kiểm tra tính đầy đủ, chuyển lỗi từ lúc chạy sang lúc biên dịch.&lt;/p&gt;
&lt;p&gt;Với ví dụ &lt;code&gt;Shape&lt;/code&gt; gồm &lt;code&gt;Circle&lt;/code&gt;, &lt;code&gt;Rectangle&lt;/code&gt;, &lt;code&gt;Triangle&lt;/code&gt;, hàm &lt;code&gt;getCenter&lt;/code&gt; viết bằng một biểu thức &lt;code&gt;switch&lt;/code&gt; thay cho việc thêm phương thức vào mọi lớp con, khiến mẫu thiết kế Visitor trở nên thừa. Khi thêm kiểu dữ liệu mới như &lt;code&gt;Pentagon&lt;/code&gt;, trình biên dịch sẽ báo mọi &lt;code&gt;switch&lt;/code&gt; còn thiếu nhánh, vì vậy tác giả khuyên tránh nhánh &lt;code&gt;default&lt;/code&gt; để không làm mất kiểm tra này. DOP cũng phù hợp để xử lý kết quả tường minh, chẳng hạn kiểu &lt;code&gt;Result&lt;/code&gt; với hai biến thể &lt;code&gt;Ok&lt;/code&gt; và &lt;code&gt;Error&lt;/code&gt; buộc bên gọi xử lý đủ mọi khả năng. Lợi ích tổng kết gồm mã dễ đọc, dễ bảo trì, ít ràng buộc, dễ kiểm thử và tái cấu trúc an toàn, rẻ hơn.&lt;/p&gt;
&lt;h2 id="why-performance-optimization-is-hard-work"&gt;&lt;a class="link" href="https://purplesyringa.moe/blog/why-performance-optimization-is-hard-work/" target="_blank" rel="noopener"
&gt;Why performance optimization is hard work&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Tác giả cho rằng tối ưu hiệu năng khó không phải vì thiếu kỹ năng hay kiến thức, mà vì về bản chất đó là công việc vét cạn, phải thử rất nhiều phương án. Về tính kết hợp, có những kỹ thuật chỉ phát huy khi đi cùng nhau, có những kỹ thuật lại làm chậm đi khi kết hợp, và việc loại bỏ các cách &amp;ldquo;hiển nhiên là kém&amp;rdquo; chỉ là phỏng đoán, vì thuật toán đơn giản có thể thắng nhờ vector hóa còn mã thông minh có thể thua vì dự đoán nhánh sai. Về tính liên tục, các thuật toán có ngưỡng chuyển đổi, như sắp xếp lai hay FFT, đòi hỏi chọn tham số bằng thử nghiệm và phải đo lại mỗi khi thay đổi, nên một bộ đo tự động là rất đáng giá. Về tính không tương thích, các ràng buộc phần cứng như hai bảng tra cứu không cùng vừa bộ nhớ đệm hay áp lực thanh ghi buộc ta phải chấp nhận đánh đổi.&lt;/p&gt;
&lt;p&gt;Tác giả cũng phản bác quan niệm &amp;ldquo;trình biên dịch thông minh hơn con người&amp;rdquo;: trình biên dịch không suy luận theo trừu tượng của bạn, thậm chí phân bổ thanh ghi kém, nên cần luôn kiểm tra mã hợp ngữ và dùng công cụ phân tích như &lt;code&gt;perf&lt;/code&gt;. Tài liệu cũng là một rào cản: x86 có nhiều nguồn chi tiết, còn Apple Silicon gần như không có, khiến việc tối ưu chủ yếu là dịch ngược. Tóm lại, tối ưu đòi hỏi khám phá hàng chục trường hợp, làm việc với công cụ chưa đủ tốt và dung hòa các tối ưu xung khắc, nhưng những cải thiện nhỏ cộng dồn lại vẫn đáng giá vì chúng tiết kiệm thời gian của người dùng.&lt;/p&gt;
&lt;h2 id="good-vs-great-animations"&gt;&lt;a class="link" href="https://emilkowal.ski/ui/good-vs-great-animations" target="_blank" rel="noopener"
&gt;Good vs Great Animations&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Emil Kowalski tổng hợp các mẹo thực tế để đưa hiệu ứng chuyển động trên giao diện từ mức tốt lên mức xuất sắc. Trước hết, chuyển động cần có điểm xuất phát rõ ràng: một menu thả xuống nên mở ra từ vị trí nút bấm bằng cách đổi &lt;code&gt;transform-origin&lt;/code&gt;, và với Radix có thể dùng sẵn biến CSS tương ứng. Hàm gia tốc (easing) là yếu tố quan trọng nhất; với phần tử đã có trên màn hình và đang di chuyển, &lt;code&gt;ease-in-out&lt;/code&gt; mô phỏng tăng tốc rồi giảm tốc tự nhiên như một chiếc xe, còn trong đa số trường hợp nên mặc định dùng &lt;code&gt;ease-out&lt;/code&gt;. Các đường cong có sẵn của CSS thường chưa đủ mạnh, nên tác giả gần như luôn dùng đường cong tùy chỉnh, gợi ý easing.dev và easings.co.&lt;/p&gt;
&lt;p&gt;Với tương tác theo vị trí chuột, gắn trực tiếp giá trị vào con trỏ sẽ trông giả tạo; hook &lt;code&gt;useSpring&lt;/code&gt; của Motion nội suy thay đổi theo kiểu lò xo giúp cảm giác tự nhiên hơn, nhưng chỉ nên dùng cho chuyển động mang tính trang trí, còn biểu đồ chức năng như trong ứng dụng ngân hàng thì không cần hiệu ứng. Hiểu rõ công cụ cũng quan trọng: dùng &lt;code&gt;clip-path&lt;/code&gt; giúp chuyển màu chữ ở thanh tab ăn khớp với thanh đánh dấu, còn biến đổi 3D mở ra những hiệu ứng mới. Theo tác giả, khi phần mềm nào cũng đủ tốt, chuyển động được chăm chút là một cách để sản phẩm nổi bật.&lt;/p&gt;
&lt;h2 id="senior-engineers-should-make-side-bets"&gt;&lt;a class="link" href="https://www.seangoedecke.com/side-bets/" target="_blank" rel="noopener"
&gt;Senior engineers should make side bets&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Sean Goedecke cho rằng kỹ sư junior nên làm đúng việc được giao, vì công việc cần được người có kinh nghiệm giám sát và cách tốt nhất để thăng tiến là hoàn thành xuất sắc nhiệm vụ trước mắt. Ngược lại, kỹ sư senior không nên chỉ làm theo danh sách đầu việc mà nên dành 10–20% thời gian cho các &amp;ldquo;canh bạc phụ&amp;rdquo; (side bets): những dự án họ tin là có giá trị cho công ty nhưng chưa ai để ý tới, như một tính năng mới, một tối ưu hiệu năng hay một thay đổi giúp tăng tốc phát triển, với điều kiện phải mang lại lợi ích cụ thể. Canh bạc phụ đầy rủi ro: tệ nhất là mất thời gian và bị cấp quản lý đánh giá là làm việc không quan trọng, và phần lớn sẽ thất bại, khi đó cứ lặng lẽ bỏ qua và chuyển sang việc khác.&lt;/p&gt;
&lt;p&gt;Lý do đáng làm là một canh bạc thành công bù đắp cho tất cả: với công việc thường ngày, người khác cũng có thể làm thay, còn giá trị từ canh bạc phụ hoàn toàn nhờ bạn. Khi thành công, hãy chủ động chia sẻ qua bài viết nội bộ hoặc trao đổi với quản lý; nếu thấy ngại khoe, có lẽ lợi ích chưa đủ cụ thể. Tác giả kể ví dụ tại GitHub: nút mở prompt trong trình soạn prompt không ai dùng, còn việc tích hợp quyền suy luận AI vào GitHub Actions thì được dùng thực tế. Ông thắng hai đến ba canh bạc mỗi năm, và nếu liên tục thất bại thì có lẽ nên dừng lại.&lt;/p&gt;
&lt;h2 id="avoiding-skill-atrophy-in-the-age-of-ai"&gt;&lt;a class="link" href="https://addyo.substack.com/p/avoiding-skill-atrophy-in-the-age" target="_blank" rel="noopener"
&gt;Avoiding Skill Atrophy in the Age of AI&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;Addy Osmani cảnh báo nghịch lý của trợ lý lập trình AI: năng suất tăng nhưng kỹ năng có thể mai một nếu không cẩn thận. Một nghiên cứu năm 2025 của Microsoft và Carnegie Mellon cho thấy càng dựa vào AI, người ta càng ít tư duy phản biện. Dấu hiệu thường đến từ từ: ngừng đọc tài liệu, không còn tự gỡ lỗi mà dán thẳng thông báo lỗi cho AI, chép mã mà không hiểu vì sao nó chạy, ngại tự thiết kế kiến trúc và quên cả cú pháp cơ bản. Về lâu dài, lập trình viên có thể bế tắc trước vấn đề mới mà AI không giải được, lập trình viên junior dễ chững lại, và việc kèm cặp trong đội bị ảnh hưởng. Tác giả thừa nhận việc bỏ đi một số kỹ năng lỗi thời là bình thường, điều quan trọng là phân biệt kỹ năng nào có thể giao cho máy và kỹ năng nào phải giữ sắc bén.&lt;/p&gt;
&lt;p&gt;Giải pháp là coi AI như một cộng sự, không phải cái nạng: luôn kiểm chứng và hiểu kết quả, chủ động tìm lỗi và trường hợp biên, nhờ AI giải thích từng dòng; dành những &amp;ldquo;ngày không AI&amp;rdquo; để tự viết mã và đọc tài liệu; tự thử giải quyết vấn đề 15–30 phút trước khi hỏi; rà soát mã do AI sinh ra như mã của đồng nghiệp; ghi lại những chủ đề thường phải nhờ AI để bổ sung kiến thức còn thiếu; và làm việc theo kiểu lập trình cặp để giữ vai trò cầm lái. Thông điệp cốt lõi: dùng AI để khuếch đại năng lực chứ không thay thế nó, giữ lại niềm vui và tay nghề giải quyết vấn đề.&lt;/p&gt;
&lt;h2 id="cursor-best-practices"&gt;&lt;a class="link" href="https://x.com/paraschopra/status/1917466537637859544" target="_blank" rel="noopener"
&gt;Cursor best practices&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;&lt;img src="https://pbs.twimg.com/media/Gpw1p1waYAAeAyY?format=jpg"
loading="lazy"
alt="Cursor best practices"
&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Bài viết đã được viết lại bởi Claude Code với Opus 5.5 vào ngày 27/09/2026.&lt;/em&gt;&lt;/p&gt;</description></item></channel></rss>