Welcome to MikeDaDev's Blog – notes on Java, backend & system design.

Explore
MikeDaDev's Blog

#best-practices

Things I've written about #best-practices
  • ChainDrop: con worm npm đi qua cổng chính, mang theo cả provenance

    Sáng 4/8/2026, tài khoản GitHub của maintainer Keyv bị chiếm, và chỉ vài giờ sau hàng trăm package npm khác cũng chứa mã độc chạy ngay lúc npm install. Bài này mổ xẻ ChainDrop, một biến thể họ Shai-Hulud: cách nó đánh cắp token rồi tự publish lại, vì sao bản độc vẫn có provenance hợp lệ, cách rà máy dev và CI, và những thứ nên đổi trong quy trình cài dependency.

  • vận hành database cluster & tính Idempotent

    Script bảo trì hay nâng cấp database phân tán đang chạy thì đứt kết nối, giờ chạy lại có sao không? Bài này nói về cách tự động hoá vận hành cluster, cách thiết kế State Machine cho từng node và vì sao Idempotent là nguyên tắc SRE không được bỏ qua.

  • jev engineering: make ai intelligent more like human

    Sao phải đốt tiền gọi LLM cồng kềnh chỉ để kiểm tra một điều kiện Boolean? Bài này nói về Jev Engineering: mô hình AI System 1 phi tự hồi quy (Non-autoregressive), rẽ nhánh theo ngữ nghĩa với độ trễ cỡ 70-500ms, rẻ hơn LLM nhiều lần theo công bố của TypeSafe, và đầu ra luôn đúng kiểu.

  • in ai / llmops

    llm evaluation & observability

    Đưa AI lên production rồi thì đo độ chính xác và theo dõi nó kiểu gì? LLM-as-a-Judge, RAG Triad (Context Relevance, Faithfulness, Answer Relevance), Prompt Drift và tracing đầu cuối với Langfuse & OpenTelemetry.

  • in ai / rag

    RAG vs Fine-tuning

    Khi nào nên dùng RAG, khi nào nên Fine-tuning? Hiểu sai hai cách này là có thể đốt cả trăm ngàn USD tiền GPU. Mô hình "nhớ" kiến thức ra sao, 7 trục đánh đổi khi chọn kiến trúc, bài toán TCO và cách ghép RAG với một SLM fine-tune riêng để chạy production.

  • cạm bẫy Virtual Threads trong production

    Bật Virtual Threads trong Java 21 xong ứng dụng production lại treo? Bài này đi qua 4 chỗ hay dính: pinning carrier thread do synchronized (và chuyện JDK 24 đã sửa nó), ThreadLocal làm phình bộ nhớ, pool thread không cần thiết và connection pool bị đè bẹp, kèm cách xử lý cho từng cái.

  • in ai / llm

    reasoning models & test-time compute

    DeepSeek-R1 làm cả ngành AI giật mình vì cho thấy năng lực của model không chỉ tăng nhờ pre-training mà còn nhờ cho model nghĩ lâu hơn lúc suy luận (test-time compute). Bài này nói về chuyện đó: scaling law, cách DeepSeek dùng Reinforcement Learning với GRPO, kiến trúc MoE/MLA, và dev phần mềm rút ra được gì.

  • Database Sharding system design

    Lúc nào thì một node SQL không còn gánh nổi tải? Bài này nói về cách ước tính dung lượng nhanh (back-of-the-envelope), cách chọn sharding key, chuyện transaction phân tán và kinh nghiệm từ các hệ thống tài chính.

  • in ai / agent

    langgraph & stateful multi-agent

    Vì sao Chain tuyến tính (DAG) không đủ cho AI Agent phức tạp? Bài này nói về kiến trúc LangGraph, tư duy State Machine, cơ chế time-travel và mấy mẫu phối hợp multi-agent hay gặp.

  • in ai / llm

    vLLM & PagedAttention

    Model chỉ nặng vài chục GB mà GPU cứ báo hết VRAM? Thủ phạm là KV Cache. Bài này mổ xẻ chuyện KV Cache phình to, cách PagedAttention mượn ý tưởng bộ nhớ ảo của hệ điều hành để xử lý nó, và vì sao vLLM đẩy throughput suy luận lên cao gấp nhiều lần (tới 24 lần so với HuggingFace Transformers, theo số đo của nhóm tác giả).

  • kỹ sư phần mềm trong kỷ nguyên AI

    AI viết 1.000 dòng code trong vài giây, vậy giá trị thật của một Software Engineer còn nằm ở đâu? Bài này nói về nghịch lý năng suất, cái bẫy mai một kỹ năng, chuyện review code ngày càng quá tải và cách tự định vị lại bản thân để không bị thay thế.

  • case study Shopify: Redis to MySQL

    Black Friday 2025 đạt đỉnh 5.1 triệu USD/phút, và đó cũng là mùa đầu tiên Shopify giữ chỗ tồn kho bằng MySQL thay cho Redis. Vì sao bỏ Redis, vì sao câu UPDATE trừ số lượng quen thuộc không đủ, và thiết kế một dòng cho mỗi đơn vị hàng với SKIP LOCKED chạy ra sao.

  • Rate Limiting với Bucket4j trong Spring Boot

    Vì sao chỉ rate limit ở Nginx là chưa đủ? Mổ xẻ thuật toán Token Bucket, cách Bucket4j xử lý concurrency không cần lock, và cách dựng rate limiting phân tán với Redis trong Spring Boot để chạy production.

  • RestClient & Fluent API trong Spring Boot 3

    Vì sao RestTemplate bị cho vào chế độ bảo trì rồi sắp bị deprecate? Bài này nói về RestClient và JdbcClient, hai món mới theo kiểu Fluent API từ Spring Framework 6.1 / Spring Boot 3.2, viết gọn hơn, đọc dễ hơn và ít chỗ truyền nhầm tham số hơn.

  • in ai / rag

    graph rag & advanced rag

    Vì sao vector search kiểu truyền thống bó tay trước câu hỏi nhiều bước (multi-hop)? Bài này mổ xẻ kiến trúc GraphRAG, cách kết hợp Knowledge Graph với Hybrid Search để đưa hệ thống RAG lên mức dùng được cho doanh nghiệp.

  • jOOQ vs Hibernate JPA

    Vì sao nhiều team làm hệ thống tài chính cân nhắc jOOQ bên cạnh Hibernate? Chi phí ngầm của ORM, Type-safe SQL của jOOQ, những chỗ Hibernate 6 đã bắt kịp, và kiến trúc Hybrid dùng cả hai.

  • in ai / n8n

    AI agent workflows với n8n

    Từ chỗ viết cả trăm dòng code nối API tới chỗ dựng hẳn một hệ thống AI Agent tự động hoá. Bài này đi qua kiến trúc AI Agent trong n8n, LangChain node, Vector Store, Tool Calling và mấy kinh nghiệm khi đưa lên production.

  • T24 core banking

    T24 (Temenos Transact) là hệ thống core banking, nơi mọi giao dịch tài chính của ngân hàng chạy qua. Chia module rõ ràng, xử lý realtime, nó đang làm xương sống cho nghiệp vụ chính của khoảng một nghìn ngân hàng. Bài này ghi lại những gì dev cần biết khi phải làm việc với nó.

  • activiti 8

    Activiti 8 là engine BPM/workflow mã nguồn mở, làm ra để chạy tốt trên môi trường cloud-native. Nó chạy được BPMN chuẩn, gắn chặt với Spring Boot, nên hay được dùng làm "nhạc trưởng" điều phối microservices, nhất là khi phải quản lý mấy luồng giao dịch phân tán rắc rối theo kiểu Saga.

  • backbase - digital banking platform

    Backbase là một nền tảng ngân hàng số (Engagement Banking Platform) giúp ngân hàng làm mới trải nghiệm khách hàng trên mọi kênh mà không phải thay cả hệ thống core banking cũ. Nó nằm như một lớp tương tác phía trên các hệ thống sẵn có, phục vụ cả ngân hàng bán lẻ, doanh nghiệp lẫn quản lý tài sản.

  • BPMN 2.0

    BPMN 2.0 (Business Process Model and Notation) là chuẩn quốc tế về ký hiệu đồ họa để vẽ và thiết kế quy trình nghiệp vụ. Nó là "ngôn ngữ chung" giữa business analyst, dev và ban quản lý, và model vẽ ra có thể chạy trực tiếp trên workflow engine. Bài này đi qua events, activities, gateways, process variables, listeners, error handling, tích hợp Activiti với Spring Boot và các best practice.

  • clean architecture

    Clean Architecture là kiểu kiến trúc chia hệ thống thành các vòng tròn đồng tâm, với một luật phụ thuộc rất chặt: lớp bên trong (chứa logic nghiệp vụ) không bao giờ được phụ thuộc vào lớp bên ngoài (UI, Database, Framework). Nhờ vậy nghiệp vụ không dính vào công nghệ cụ thể nào, dễ test, dễ bảo trì và dễ mở rộng.

  • RabbitMQ căn bản

    RabbitMQ là gì, vì sao nên dùng, kiến trúc bên trong và cách tích hợp với Spring Boot, kèm các pattern đảm bảo reliability cho production.

  • java advanced performance techniques

    Các kỹ thuật tối ưu hiệu năng Java ở cấp hệ thống: branchless programming, autoboxing, EnumSet, Virtual Threads, bẫy Hibernate/JPA, Caffeine cache, GraalVM Native Image, data locality, lock-free và SIMD.

  • java comparison

    Những cặp khái niệm Java/Spring hay bị hỏi khi phỏng vấn Senior mà cũng dễ dùng sai trên production: == vs equals(), HashMap vs ConcurrentHashMap, synchronized vs ReentrantLock, PUT vs PATCH...

  • Saga pattern trong Microservices

    Saga Pattern là cách xử lý transaction phân tán trong microservices: chia một quy trình dài thành chuỗi local transaction. Bước nào lỗi thì chạy compensating transaction để hoàn tác các bước trước, nhờ vậy dữ liệu vẫn nhất quán (eventual consistency) mà không phải lock cả hệ thống.

  • high-performance java techniques

    Mấy kỹ thuật tối ưu hiệu năng Java ít người để ý: object pooling, primitive arrays, lock-free, batch, zero-copy, viết code dễ cho JIT, kèm ví dụ, cơ chế bên dưới và lúc nào không nên dùng.

  • multithreading vs parallel stream

    So sánh Multithreading truyền thống (Thread, ExecutorService, CompletableFuture) với Parallel Stream trong Java: khác nhau về mô hình, mức kiểm soát, khi nào nên dùng cái nào, các lỗi hay gặp và chỗ Virtual Threads (Java 21+) chen vào.

  • acid in sql

    Nếu database SQL là cái két sắt thì ACID (Atomicity, Consistency, Isolation, Durability) là bộ khoá giữ cho mọi giao dịch an toàn. Nhờ nó, dù hệ thống sập nguồn hay gặp lỗi bất ngờ, thao tác dữ liệu hoặc chạy trọn vẹn, hoặc hoàn tác hết, dữ liệu không bao giờ rơi vào trạng thái nửa vời.

  • mdc tracing

    MDC hoạt động ra sao, cách gắn traceId vào log và chuyền nó qua HTTP, RabbitMQ, Kafka, gRPC, thread pool; khi nào nên để Micrometer Tracing làm thay, và cách xuất log JSON cho dễ tìm.

  • gRPC trong Spring Boot

    gRPC chạy thế nào bên dưới, Protobuf và HTTP/2 giúp nó nhanh ra sao. Kèm cách dựng gRPC với Spring Boot cho production và mấy bài học mình rút ra khi đưa nó lên chạy thật.

  • model context protocol

    Model Context Protocol (MCP) là một chuẩn mở giúp trợ lý AI kết nối thẳng và an toàn tới nguồn dữ liệu, API hay môi trường làm việc bên ngoài. Có một giao thức chung như vậy, AI đọc được ngữ cảnh của người dùng mà không cần ai ngồi viết connector riêng cho từng ứng dụng.

  • maven dependencies

    Thoát khỏi Dependency Hell bằng cách quản lý dependency cho gọn. Đi qua cấu trúc POM, BOM, dependency scope, multi-module và vòng đời build trong project Java.

  • ai agentic systems

    AI agent là bước chuyển lớn của AI: từ chatbot thụ động chỉ biết "hỏi - đáp" sang những "nhân viên số" tự lên kế hoạch, tự hành động để giải quyết việc phức tạp. Bài này đi qua cấu tạo của agent, vòng lặp ReAct, cách lập kế hoạch, multi-agent và mấy kinh nghiệm khi xây agent.

  • rabbitmq pattern

    Các pattern hay dùng của RabbitMQ trong Spring Boot: publisher confirm, manual ack, DLQ, retry, idempotent consumer, giữ thứ tự message, và cách giữ dữ liệu nhất quán bằng Outbox và Saga.

  • redis pattern

    Redis đâu chỉ để làm cache. Bài này gom lại các chiến lược caching, cách cấu hình cho đỡ tốn bộ nhớ và mấy pattern phân tán hay dùng với Redis trong hệ thống Backend.

  • jmeter

    Apache JMeter là phần mềm mã nguồn mở để kiểm thử hiệu năng (performance testing) và kiểm thử chịu tải (load testing) cho ứng dụng web, API hoặc cơ sở dữ liệu. Nó giả lập hàng ngàn người dùng ảo truy cập cùng lúc, để bạn đo thời gian phản hồi, tìm lỗi và biết máy chủ chịu được tới đâu.

  • prometheus

    Prometheus không chỉ là mấy con số khô khan, nó là trung tâm của hệ sinh thái Observability. Bài này nói về kiến trúc, cách nghĩ khi thiết kế metrics và cách tích hợp với Spring Boot.

  • bitwise operations in java

    Bitwise thoạt nhìn hơi khó chịu vì phải nghĩ bằng số nhị phân thay vì thập phân như mọi khi. Nhưng nắm được quy luật rồi thì thấy nó chạy rất nhanh, tốn ít bộ nhớ, và xuất hiện khắp nơi từ permission, HashMap cho tới câu hỏi phỏng vấn.

  • mongodb

    Không dừng ở định nghĩa NoSQL, bài này đi vào kiến trúc MongoDB, cách thiết kế dữ liệu (Embed hay Reference), chiến lược đánh index, và cách dùng MongoDB cho đúng trong microservices với Spring Boot.

  • redis

    Redis làm được nhiều hơn một bộ nhớ đệm. Bài này nói về kiến trúc bên trong, cách tối ưu bộ nhớ và các pattern phân tán dùng Redis trong hệ thống Backend.

  • cqrs pattern

    CQRS là pattern tách hẳn phần đọc dữ liệu (Query) ra khỏi phần ghi, thay đổi dữ liệu (Command). Tách ra rồi thì mỗi bên tự tối ưu hiệu năng, bảo mật và database theo cách của mình, rất đáng dùng cho những hệ thống phức tạp mà lượng đọc và ghi chênh nhau nhiều.

  • coding convention và chuẩn mực java

    Ghi chú về coding convention cho team Java: dùng chuẩn Google, bỏ package-by-layer để chuyển sang Vertical Slice, chặn NullPointer bằng JSpecify & NullAway, và kiểm tra ranh giới kiến trúc tự động trong CI/CD bằng ArchUnit.

  • stack & queue

    Ghi chú về cách chọn và dùng Stack, Queue, Deque trong Java: khi nào dùng ArrayDeque, PriorityQueue, BlockingQueue hay ConcurrentLinkedQueue cho hệ thống chịu tải cao.

  • dependency injection

    Dependency Injection (DI) là pattern dùng để hiện thực nguyên tắc Inversion of Control (IoC). Object không tự `new` mấy thứ nó cần nữa, mà để một bên quản lý chung (như Spring Container) "tiêm" (inject) dependency vào qua constructor, setter hoặc field. Nhờ vậy các class ít dính chặt vào nhau (loose coupling), code linh hoạt, dễ sửa và nhất là dễ viết unit test.

  • postgre-sql

    Đi một vòng PostgreSQL: MVCC, WAL chạy ra sao, đánh index thế nào cho đúng, và mấy kinh nghiệm tối ưu hiệu năng "xương máu" khi dùng chung với Spring Boot.

  • java concurrency

    Concurrency trong Java 21 & Spring Boot 3.x: Virtual Threads, ScopedValue và các pattern xử lý bất đồng bộ trong hệ thống phân tán hiệu năng cao.

  • http abstractions

    Các class và interface HTTP của Spring (ResponseEntity, HttpHeaders, MediaType, RestTemplate, WebClient, RestClient...) gói HTTP thô thành object dễ dùng, giúp code độc lập với web server bên dưới và dễ unit test hơn.

  • map in java

    Mổ xẻ bên trong các loại Map của Java, mỗi loại tốn kém ở đâu, và chọn loại nào cho đúng khi hệ thống chịu tải cao

  • list in java

    Đào xuống tầng low-level xem ArrayList, LinkedList chạy thế nào, vì sao lý thuyết nói một đằng mà hiệu năng thực tế một nẻo, và mấy cái bẫy dễ dính khi chạy đa luồng.

  • project Lombok

    Lombok can thiệp vào Abstract Syntax Tree (AST) thế nào dù JSR 269 không cho phép, những cái bẫy hay gặp trên Production (JPA @Data, @EqualsAndHashCode với kế thừa, @Builder với Jackson, @SneakyThrows) và cách thay bằng Java Records & MapStruct.

  • spring test annotations

    Ghi chú về các Spring Test annotations để viết Unit Test và Integration Test trong Spring Boot: @SpringBootTest, test slices, @MockitoBean/@MockitoSpyBean (thay @MockBean/@SpyBean), Testcontainers.

  • ioc container & application context

    IoC Container là phần lõi của Spring Framework: tự khởi tạo, nối và quản lý vòng đời của các object (Beans) thông qua Dependency Injection. **Application Context** là bản mở rộng (interface) của IoC Container, ngoài các tính năng cơ bản còn có thêm event, đa ngôn ngữ (i18n), tích hợp AOP và nhiều thứ khác.

  • spring data jpa

    Spring Data JPA là module của Spring Framework, nằm trên Java Persistence API (JPA). Thay vì viết boilerplate code để làm việc với database, bạn chỉ cần khai báo interface (kế thừa `JpaRepository`), Spring sẽ tự cung cấp phần implement cho các thao tác CRUD cơ bản. Điểm hay nhất là tự sinh câu SQL từ tên method (ví dụ `findByEmailAndStatus`), và hỗ trợ sẵn phân trang, sắp xếp, auditing.

  • spring jackson annotations

    Các annotation của Jackson (có sẵn trong Spring Boot) cho phép kiểm soát chi tiết việc chuyển đổi (serialization và deserialization) giữa object Java và JSON. Với @JsonProperty (đổi tên trường), @JsonIgnore (bỏ dữ liệu nhạy cảm khi trả về), @JsonFormat (định dạng ngày tháng) hay @JsonInclude (lọc giá trị null), bạn tùy biến được cấu trúc dữ liệu qua API mà không phải đụng vào logic.

  • @Transactional & Spring AOP

    @Transactional và Spring AOP (Aspect-Oriented Programming) là hai thứ đứng sau cơ chế quản lý transaction tự động của Spring. Nhờ chúng mà business logic tách được khỏi mấy việc kỹ thuật lặp đi lặp lại (cross-cutting concerns) như mở transaction, commit hay rollback.

  • spring data core annotations

    Spring Data có một loạt annotation như `@Id`, `@Query`, `@Repository`, `@Transient` để map class Java (entity) vào database và lo phần truy xuất dữ liệu. Nhờ chúng mà bớt được cả đống boilerplate: khai báo khoá chính, quan hệ giữa các bảng hay query tuỳ chỉnh đều gọn, dễ đọc, dễ bảo trì.

  • spring web bind annotations

    Spring Web Bind Annotations là nhóm annotation trong Spring MVC và Spring WebFlux, đóng vai trò cầu nối: tự lấy dữ liệu từ các phần của HTTP Request (URL, Body, Headers) rồi gán (bind) vào tham số của method trong Controller.