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

Explore
MikeDaDev's Blog

#software-architecture

Things I've written about #software-architecture
  • 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.

  • bảo mật LLM & OWASP Top 10

    Bảo mật cho hệ thống Generative AI và Agentic Workflows: vì sao Code Plane và Data Plane lẫn vào nhau trong LLM, các kiểu tấn công theo OWASP Top 10 for LLM, mô hình Dual-LLM Sandbox, Zero-Trust Tool Broker và Guardrails nhiều lớp (Defense-in-Depth) cho production.

  • in ai / slm

    Small Language Models (SLM)

    Nhìn Small Language Models (1B - 8B) từ góc độ người làm kiến trúc: tính VRAM và KV-Cache, chọn kiểu lượng tử hoá (AWQ hay GGUF), chạy Dynamic Multi-LoRA trên vLLM, ghép SLM với LLM thành Compound AI, và bài toán TCO, ROI.

  • zero-downtime database migration

    Làm Zero-Downtime Migration cho database: ma trận lock như AccessExclusiveLock, chiến lược Expand-Contract 5 pha, Shadow Reads (dark launching), Throttled Keyset Backfill và so sánh gh-ost với pg_repack.

  • spring ai và kiến trúc rag

    Mổ kiến trúc Spring AI 1.x: ChatClient Fluent API, chuỗi Advisors, RAG với VectorStore và PgVector, Function Calling, Observability với Micrometer/OpenTelemetry và mấy pattern resilience để sống sót qua rate-limit.

  • kiến trúc API Gateway

    Mổ kiến trúc API Gateway trong hệ thống microservices cỡ lớn: đặt Kong, Spring Cloud Gateway và Envoy lên bàn cân, làm distributed rate limiting kiểu token bucket bằng Redis Lua, mô hình BFF và circuit breaker để hệ thống tự hồi phục.

  • command pattern

    Command Pattern nhìn từ góc độ kiến trúc: biến động từ thành danh từ (Objectifying Actions), Undo/Redo dùng hai stack kết hợp Memento, đường tiến hóa sang CQRS (Command Query Responsibility Segregation) và Compensating Transactions trong Saga.

  • strategy pattern

    Nhìn Strategy Pattern bằng con mắt Solution Architect: Strategy khác State và Template Method ở đâu, dùng Functional Interface của Java để khỏi đẻ ra cả đống class thừa, và dựng một Dynamic Promotion Engine bằng Spring Boot.

  • observer pattern

    Đi từ Observer Pattern kinh điển tới Event-Driven Architecture (EDA): vì sao java.util.Observable bị deprecate từ Java 9, quản lý transaction với @TransactionalEventListener AFTER_COMMIT, xử lý backpressure trong Reactive Streams và so sánh với Apache Kafka.

  • facade pattern

    Nhìn Facade Pattern bằng con mắt Solution Architect: nó liên quan gì tới Law of Demeter, khác Adapter, Proxy, Decorator ở đâu, và lớn lên thành Anti-Corruption Layer (ACL trong DDD) ra sao khi phải bọc một hệ thống Core Banking legacy.

  • abstract factory pattern

    Abstract Factory Pattern nhìn từ góc độ kiến trúc hệ thống: dùng nó để thoát vendor lock-in khi chạy multi-cloud, dựng lớp trừu tượng cho Blob Storage, Message Queue và Secret Manager trên AWS/GCP, và cái giá phải trả gọi là Lowest Common Denominator.

  • decorator pattern

    Decorator Pattern nhìn từ góc Solution Architect: vì sao kế thừa gây Class Explosion, Decorator thủ công khác gì Spring AOP Proxies (JDK vs CGLIB), bẫy Self-Invocation trong AOP và ví dụ Resilient Caching Decorator kèm những điểm cần lưu ý trước khi đem lên production.

  • factory pattern

    Nhìn lại Factory Pattern từ góc độ kiến trúc: vì sao Factory kiểu switch-case kinh điển lại vi phạm chính Open/Closed Principle, cách inject Map bean trong Spring Boot để bỏ hẳn if-else, Functional Factory với Java Supplier, và phân biệt Factory Method với Abstract Factory qua ví dụ multi-cloud.

  • singleton pattern

    Singleton Pattern nhìn kỹ hơn một chút: vì sao việc đảo lệnh của JIT và CPU buộc Double-Checked Locking phải có volatile, 4 cách phá Singleton (Reflection, Serialization, Clone, ClassLoader) và vì sao dự án Spring nên để IoC Container quản lý singleton.

  • CORS & CSRF

    Hiểu cho đúng mấy cơ chế bảo mật của trình duyệt: Same-Origin Policy thật ra là gì, preflight OPTIONS tốn thêm bao nhiêu, cái bẫy Access-Control-Allow-Origin dùng wildcard, và vì sao nên gom cấu hình CORS về API Gateway.

  • in java / jvm

    Optional trong Java

    Nhìn kỹ Java Optional: mỗi instance tốn 16-24 bytes heap và khi nào thì chuyện đó thật sự đáng lo, 6 anti-pattern hay gặp, khác biệt quan trọng giữa orElse và orElseGet, và cách làm null-safety bài bản hơn với JSpecify.

  • Criteria API trong Hibernate

    Viết dynamic query trong Java enterprise cho đàng hoàng: Hibernate 6 SQM chạy bên dưới ra sao, JPA Metamodel Generator, Spring Data Specification, cái bẫy fetch join với N+1 và phân trang, kèm bảng so sánh Criteria API, Specification, QueryDSL và jOOQ.

  • spring profiles và externalized config

    Quản lý cấu hình trong Spring Boot cho bài bản: nguyên tắc 12-Factor Config, thứ tự ưu tiên giữa các PropertySource, spring.config.import (Spring Boot 2.4+), kết hợp HashiCorp Vault & Kubernetes ConfigMaps, và reload nóng với @RefreshScope.

  • Spring Boot Auto-configuration

    Spring Boot Auto-Configuration chạy thế nào bên dưới: AutoConfigurationImportSelector, bộ lọc sớm dựa trên metadata sinh lúc build, ASM đọc annotation mà không nạp class, thứ tự của DeferredImportSelector, chuyển từ spring.factories sang AutoConfiguration.imports, và cách viết một Custom Starter dùng được trên production.

  • java records

    Hiểu Java Records cho đúng: "transparent carrier" nghĩa là gì, vì sao serialization của Record an toàn hơn, Pattern Matching với Sealed Types, Shallow vs Deep Immutability và mấy cái bẫy khi đem Record dùng với JPA / Hibernate.

  • @OneToOne trong JPA

    Đào sâu quan hệ @OneToOne trong Hibernate & JPA: vì sao FetchType.LAZY "tịt" ở Non-Owning side và kéo theo N+1, cách dùng chung khoá chính với @MapsId, Bytecode Enhancement, và vì sao gắn Lombok @Data lên Entity là anti-pattern.

  • in java / jvm

    string vs stringbuilder vs stringbuffer

    Chuỗi ký tự trong JVM hoạt động thế nào: Compact Strings (JEP 254), việc toán tử + chuyển từ StringBuilder sang invokedynamic StringConcatFactory (JEP 280), so sánh String, StringBuilder, StringBuffer và chuyện JIT bỏ lock của StringBuffer nhờ Escape Analysis.

  • in java / jvm

    java string pool

    Đi sâu vào StringTable native trong HotSpot JVM: vì sao String Pool dời từ PermGen sang Java Heap, bảng băm C++ từng tụt từ O(1) về O(N) ra sao và JDK 11 sửa thế nào, cái bẫy của String.intern(), và String Interning khác String Deduplication (JEP 192) chỗ nào.

  • threadpool executor pool size

    ThreadPoolExecutor nhìn từ góc kiến trúc: biến bit ctl, Định luật Little & công thức Goetz để tính Pool Size, cái bẫy Unbounded Queue gây OOM, Thread Starvation Deadlock và so sánh với Virtual Threads.