📌 Chủ đề: JavaScript & React Core
Làm chủ Modern Frontend đòi hỏi sự thấu hiểu sâu sắc về cách trình duyệt thực thi mã và cách React quản lý cây thành phần.
#🟢 Cấp độ: Người mới bắt đầu (Beginner)
Q1: JavaScript là ngôn ngữ Single-threaded hay Multi-threaded?
Trả lời: Single-threaded. JavaScript chỉ thực thi một lệnh tại một thời điểm trên luồng chính (Main thread).
Q2: Phân biệt `var`, `let`, và `const`.
Trả lời:
var: Function scope, có hoisting, có thể khai báo lại.let: Block scope, có hoisting nhưng nằm trong “Temporal Dead Zone”, không thể khai báo lại trong cùng scope.const: Giốngletnhưng giá trị không thể gán lại sau khi khởi tạo.
Q3: Các kiểu dữ liệu cơ bản (Primitive types) trong JS là gì?
Trả lời: String, Number, BigInt, Boolean, Undefined, Symbol, NULL.
Q4: React là gì và tại sao gọi nó là "Library" thay vì "Framework"?
Trả lời: React là thư viện UI. Nó chỉ tập trung vào việc render view. Khác với Framework (Angular), nó không ép buộc bạn cách làm routing hay gọi API.
Q5: JSX là gì?
Trả lời:
JavaScript XML. Nó là cú pháp mở rộng cho phép viết HTML bên trong JavaScript. Babel sẽ biên dịch JSX thành React.createElement().
Q6: Component trong React là gì?
Trả lời: Là các khối xây dựng UI độc lập, có thể tái sử dụng. Có 2 loại: Functional Component (phổ biến) và Class Component.
Q7: Props trong React dùng để làm gì?
Trả lời: Dùng để truyền dữ liệu từ component cha xuống component con. Props là “Read-only” (không thể thay đổi từ bên trong component con).
Q8: State trong React là gì?
Trả lời: Dữ liệu nội bộ của một component, có thể thay đổi theo thời gian. Khi state thay đổi, component sẽ tự động re-render.
Q9: Arrow Function khác gì Function truyền thống?
Trả lời:
Cú pháp ngắn gọn hơn, không có this riêng (nó kế thừa this từ scope bên ngoài), không có object arguments.
Q10: DOM là gì?
Trả lời: Document Object Model. Là giao diện lập trình cho các tài liệu HTML/XML, biểu diễn trang web dưới dạng một cây các đối tượng.
#🟡 Cấp độ: Trung cấp (Intermediate)
Q1: Closure trong JavaScript là gì?
Trả lời: Là một hàm có khả năng “nhớ” và truy cập các biến từ phạm vi (scope) bên ngoài ngay cả sau khi scope đó đã thực thi xong.
Q2: Giải thích về Prototype và Prototypal Inheritance.
Trả lời: Mọi object trong JS đều có một thuộc tính ẩn trỏ tới object khác gọi là Prototype. Khi truy cập một thuộc tính không có ở object hiện tại, JS sẽ tìm ngược lên chuỗi Prototype (Prototype Chain).
Q3: Virtual DOM hoạt động như thế nào? Tại sao nó nhanh?
Trả lời: React giữ một bản sao của DOM thật trong bộ nhớ (Virtual DOM). Khi dữ liệu thay đổi, React tạo bản Virtual DOM mới, so sánh với bản cũ (Diffing), rồi chỉ cập nhật những phần thực sự thay đổi lên DOM thật (Reconciliation).
Q4: useEffect dùng để làm gì? Giải thích mảng dependencies.
Trả lời:
Dùng để xử lý side effects (gọi API, subscription). Mảng rỗng []: chạy 1 lần sau khi mount. Có giá trị [prop]: chạy lại khi giá trị đó đổi. Không có mảng: chạy sau mỗi lần render.
Q5: Phân biệt `==` và `===` trong JS.
Trả lời:
Tương tự PHP, == so sánh giá trị sau khi ép kiểu, === so sánh nghiêm ngặt cả giá trị và kiểu dữ liệu.
Q6: Promise là gì? Các trạng thái của Promise?
Trả lời: Là đối tượng đại diện cho kết quả của một tác vụ bất đồng bộ. 3 trạng thái: Pending (đang chờ), Fulfilled (thành công), Rejected (thất bại).
Q7: Async/Await là gì? Nó có thay thế Promise không?
Trả lời: Là cú pháp giúp viết code bất đồng bộ trông như đồng bộ. Nó được xây dựng dựa trên Promise, giúp code dễ đọc và xử lý lỗi (try/catch) tốt hơn.
Q8: HOF (Higher Order Function) là gì?
Trả lời:
Hàm nhận hàm khác làm tham số hoặc trả về một hàm. Ví dụ: map, filter, reduce.
Q9: React Hooks có những quy tắc (Rules) nào?
Trả lời:
- Chỉ gọi ở cấp cao nhất (Top level), không gọi trong vòng lặp hay câu lệnh điều kiện. 2. Chỉ gọi trong React Function Components hoặc Custom Hooks.
Q10: Keys trong danh sách React (`map`) có tác dụng gì?
Trả lời: Giúp React xác định phần tử nào bị thay đổi, thêm mới hoặc xóa bỏ để tối ưu quá trình re-render danh sách.
#🔴 Cấp độ: Nâng cao (Advanced)
Q1: Giải thích sâu về Event Loop (Call Stack, Web APIs, Callback Queue, Microtask Queue).
Trả lời: Call Stack thực thi lệnh. Web APIs xử lý async (setTimeout, fetch). Callback Queue chứa task xong. Microtask Queue (Promise) có ưu tiên cao hơn Callback Queue. Event Loop đẩy task từ Queue lên Stack khi Stack trống.
Q2: React Re-render diễn ra khi nào? Làm thế nào để ngăn chặn re-render vô ích?
Trả lời:
Re-render khi: State đổi, Props đổi, Parent re-render, Context đổi.
Tối ưu: Dùng React.memo, useMemo, useCallback.
Q3: Phân biệt useMemo và useCallback.
Trả lời:
useMemo: Ghi nhớ giá trị kết quả của một phép tính đắt đỏ.useCallback: Ghi nhớ chính instance của hàm để tránh tạo hàm mới mỗi lần render (gây lỗi memo ở component con).
Q4: Giải thích cơ chế Reconciliation và thuật toán Diffing của React.
Trả lời: React so sánh 2 cây Virtual DOM. Nếu type element đổi -> xóa cũ tạo mới. Nếu type giống nhưng thuộc tính đổi -> chỉ update thuộc tính. Thuật toán có độ phức tạp O(n) nhờ giả định key và component type.
Q5: Redux vs Context API: Khi nào dùng cái nào?
Trả lời:
- Context API: Tốt cho dữ liệu ít thay đổi (Theme, Auth).
- Redux: Tốt cho state phức tạp, thay đổi liên tục, cần công cụ debug mạnh (DevTools) và logic tập trung.
Q6: Hoisting trong JavaScript hoạt động như thế nào với Class và Function?
Trả lời:
Function declaration được hoisted hoàn toàn. Class và biến let/const được hoisted nhưng không khởi tạo (nằm trong TDZ), truy cập sớm sẽ báo lỗi.
Q7: Curry Function và ứng dụng thực tế?
Trả lời: Biến đổi một hàm nhận nhiều tham số thành chuỗi các hàm, mỗi hàm nhận 1 tham số. Ứng dụng: cấu hình hàm (partial application), middleware trong Redux.
Q8: Pure Component và Pure Function trong React là gì?
Trả lời:
- Pure Function: Output chỉ phụ thuộc vào Input, không có side effects.
- Pure Component: Chỉ re-render khi props/state thực sự thay đổi giá trị (Shallow compare).
Q9: Cơ chế Hydration trong Server-side Rendering (SSR) là gì?
Trả lời: Server gửi HTML tĩnh xuống. Browser nhận HTML và “gắn” các event listener, khởi tạo state của React lên HTML đó để biến nó thành ứng dụng tương tác.
Q10: "This" keyword trong JS được xác định như thế nào (4 quy tắc)?
Trả lời:
- Default (Global). 2. Implicit (object gọi hàm). 3. Explicit (
bind,call,apply). 4. New (constructor). Arrow function không tuân theo quy tắc này.
#🧠 Cấp độ: Kiến trúc sư (Architect)
Q1: Thiết kế kiến trúc State Management cho một ứng dụng E-commerce khổng lồ.
Trả lời: Dùng mô hình lai:
- Server State: Dùng React Query (TanStack Query) để cache, fetch dữ liệu từ API.
- Global UI State: Dùng Zustand hoặc Redux Toolkit cho giỏ hàng, thông tin user.
- Local State:
useStatecho các UI nhỏ (modal, toggle).
Q2: Giải thích cơ chế React Fiber và Concurrent Mode (Concurrent Rendering).
Trả lời: Fiber chia quá trình render thành các khối nhỏ (unit of work) có thể tạm dừng và ưu tiên. Concurrent Mode cho phép React render nhiều phiên bản UI cùng lúc ngầm, giúp ứng dụng mượt mà hơn khi xử lý task nặng.
Q3: Micro-frontend là gì? Các hướng tiếp cận (Module Federation)?
Trả lời: Chia nhỏ ứng dụng lớn thành các phần độc lập có thể deploy riêng biệt. Module Federation (Webpack 5) cho phép load code từ ứng dụng khác tại runtime một cách hiệu quả.
Q4: Phân tích hiệu năng giữa Client-side Rendering (CSR), SSR, và Static Site Generation (SSG).
Trả lời:
- CSR: Nhanh sau khi load xong, SEO kém.
- SSR: SEO tốt, FCP (First Contentful Paint) nhanh, Server tải nặng.
- SSG: Nhanh nhất, bảo mật, SEO tốt, nhưng dữ liệu không realtime.
Q5: Thiết kế giải pháp Error Boundary toàn cục cho React app.
Trả lời: Dùng Class Component làm Error Boundary bao bọc các module lớn. Kết hợp với dịch vụ log lỗi (Sentry) để báo cáo lỗi runtime về server.
Q6: Làm thế nào để tối ưu hóa Bundle Size của một ứng dụng React lớn?
Trả lời:
Code splitting (React.lazy, Suspense), Tree shaking, dùng thư viện nhẹ, nén ảnh, tối ưu hóa Third-party dependencies.
Q7: Phân tích sự khác biệt giữa Shadow DOM và Virtual DOM.
Trả lời: Shadow DOM: Công nghệ của Web Components để cô lập CSS/HTML. Virtual DOM: Kỹ thuật của thư viện để tối ưu update UI. Chúng không liên quan trực tiếp đến nhau.
Q8: Thiết kế hệ thống Design System (Component Library) dùng chung cho nhiều dự án.
Trả lời: Dùng Storybook để phát triển, TailWind hoặc Styled Components để styling, đóng gói qua NPM, hỗ trợ Typescript và Accessibility (ARIA).
Q9: Cơ chế Garbage Collection trong V8 Engine hoạt động như thế nào?
Trả lời: Dùng Generational Collection: chia bộ nhớ thành Young Generation (Scavenge) và Old Generation (Mark-Sweep-Compact).
Q10: Tương lai của React: Server Components (RSC) giải quyết vấn đề gì?
Trả lời: RSC chạy hoàn toàn trên server, không gửi JS xuống client cho những component đó, giúp bundle size cực nhỏ và fetch data trực tiếp từ nguồn (DB).
#💻 Practical Scenarios (Thực chiến)
S1: Component bị re-render liên tục dù dữ liệu không đổi. Cách tìm nguyên nhân?
Xử lý: Dùng React DevTools Profiler để xem component nào render. Kiểm tra xem có đang tạo object/array mới trong mỗi lần render rồi truyền xuống props không.
S2: Ứng dụng bị giật lag khi người dùng nhập vào ô search lớn. Giải pháp?
Xử lý: Dùng Debounce hoặc Throttle để giới hạn số lần gọi hàm search. Hoặc dùng useDeferredValue trong React 18.
#🚨 MUST-KNOW
- Event Loop và cách JS xử lý bất đồng bộ.
- React Lifecycle và sự ra đời của Hooks.
- Các kỹ thuật tối ưu hóa re-render.
#⚠️ Pitfalls
- Quên cleanup trong
useEffect(gây memory leak). - Thay đổi trực tiếp (mutate) state thay vì dùng
setState. - Sử dụng index làm key trong danh sách có thể thay đổi thứ tự.
#🧩 Tips & Tricks
- Dùng
Optional Chaining(?.) để tránh lỗi crash trang khi dữ liệu bị NULL. - Tận dụng
Strict Modeđể phát hiện các side effects không mong muốn trong quá trình phát triển.
Biên soạn bởi Staff Frontend Engineer & JS Guru.