hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Phân tích thiết kế triển khai phần mềm
Bảo trì và tái cấu trúc phần mềm

Bảo trì và tái cấu trúc phần mềm

  • 24-06-2025
  • Toanngo92
  • 0 Comments

Mục lục

  • Bảo trì và Tái cấu trúc trong vòng đời phần mềm
    • 📍 1.1. Giới thiệu
    • 🎯 1.2. Mục tiêu chương này
    • 🧩 1.3. Vị trí của bảo trì trong vòng đời phần mềm
    • 🛠️ 1.4. Refactoring – tái cấu trúc là gì?
    • 💡 1.5. Tư duy chuyển đổi: Từ nhà phát triển sang người bảo trì
    • ⚠️ 1.6. Bảo trì không phải là viết lại toàn bộ
  • Phân loại bảo trì phần mềm
    • 🔍 2.1. Tổng quan
    • 🔄 2.2. Bảo trì thích ứng (Adaptive Maintenance)
      • ✅ Mục đích:
      • 📌 Ví dụ:
      • 🧠 Đặc điểm:
    • 🐞 2.3. Bảo trì sửa lỗi (Corrective Maintenance)
      • ✅ Mục đích:
      • 📌 Ví dụ:
      • 🧠 Đặc điểm:
    • ✨ 2.4. Bảo trì hoàn thiện (Perfective Maintenance)
      • ✅ Mục đích:
      • 📌 Ví dụ:
      • 🧠 Đặc điểm:
    • 🛡️ 2.5. Bảo trì phòng ngừa (Preventive Maintenance)
      • ✅ Mục đích:
      • 📌 Ví dụ:
      • 🧠 Đặc điểm:
    • 📊 2.6. So sánh nhanh các loại bảo trì
    • 🧠 2.7. Kết luận chương
  • Tái cấu trúc mã nguồn (Refactoring)
    • ❓ 3.1. Tái cấu trúc là gì?
    • 🧭 3.2. Tại sao cần refactor?
    • 🚫 3.3. Lưu ý quan trọng khi refactor
    • 📏 3.4. Quy tắc an toàn khi refactor
    • 🧹 3.5. Các kỹ thuật refactor phổ biến
    • 💥 3.6. Khi nào nên refactor?
    • ✅ 3.7. Refactor và kiểm thử (Test)
    • 💡 3.8. Ví dụ minh họa
    • 🧠 3.9. Tổng kết chương
  • Kỹ thuật refactor ở cấp lớp và hệ thống
    • 📚 4.1. Vì sao cần refactor ở cấp lớp?
    • 🧱 4.2. Dấu hiệu cần refactor ở cấp lớp
    • ✂️ 4.3. Kỹ thuật refactor lớp
      • ✅ Tách lớp (Extract Class)
      • ✅ Di chuyển phương thức (Move Method)
      • ✅ Giảm coupling – tăng cohesion
    • 🔁 4.4. Tái cấu trúc kiến trúc module
    • 📦 4.5. Kỹ thuật refactor package/module
      • ✅ Ví dụ:
    • 🧠 4.6. Chiến lược tái cấu trúc hệ thống lớn
    • 🧠 4.7. Kết luận chương
  • Tổng kết – Văn hóa bảo trì và phát triển bền vững
    • 🧠 5.1. Bảo trì không phải là phần việc “hậu kỳ”
    • 💡 5.2. Refactoring không phải là việc “làm thừa”
    • 🧩 5.3. Bảo trì và refactor – trách nhiệm của cả team
    • 📈 5.4. Lợi ích khi duy trì văn hóa refactoring
    • 🧠 5.5. Kết luận cuối cùng

Bảo trì và Tái cấu trúc trong vòng đời phần mềm

📍 1.1. Giới thiệu

Trong các tài liệu và khóa học phát triển phần mềm, phần viết mã và triển khai sản phẩm thường được nhấn mạnh nhiều nhất. Tuy nhiên, việc bảo trì và cải tiến phần mềm sau khi phát hành mới chính là phần chiếm nhiều thời gian và chi phí nhất trong suốt vòng đời của một hệ thống.

✳️ Nói cách khác, viết phần mềm chỉ là bước khởi đầu – phần lớn công việc thực sự nằm ở khâu duy trì, nâng cấp và sửa lỗi.

Trong thực tế, ngay cả khi bạn không còn làm việc ở công ty đã viết phần mềm, thì khả năng cao bạn vẫn sẽ gặp lại nó trong vai trò người duy trì (maintainer) ở những vị trí khác.

Vì vậy, hiểu được bản chất và kỹ thuật của bảo trì phần mềm (software maintenance) và tái cấu trúc mã (refactoring) là điều thiết yếu với mọi lập trình viên và kỹ sư phần mềm chuyên nghiệp.


🎯 1.2. Mục tiêu chương này

Sau khi hoàn thành chương này, bạn sẽ:

  • Phân biệt được các loại hình bảo trì phần mềm phổ biến
  • Hiểu khi nào và tại sao cần thực hiện tái cấu trúc mã nguồn
  • Biết cách phân tích, đánh giá, và cải tiến một đoạn mã để nâng cao chất lượng mà không làm thay đổi hành vi hệ thống
  • Nắm được quy tắc an toàn khi refactor, từ đó tránh gây ra lỗi tiềm ẩn

🧩 1.3. Vị trí của bảo trì trong vòng đời phần mềm

Hãy hình dung vòng đời một sản phẩm phần mềm gồm các giai đoạn:

  1. Khảo sát yêu cầu
  2. Phân tích & Thiết kế
  3. Phát triển
  4. Kiểm thử
  5. Triển khai
  6. 👉 Bảo trì (giai đoạn dài nhất)

Trong một số hệ thống lớn (ví dụ: ngân hàng, y tế, hàng không), phần mềm có thể hoạt động tới 10–15 năm với hàng trăm lần sửa đổi nhỏ sau mỗi lần triển khai.


🛠️ 1.4. Refactoring – tái cấu trúc là gì?

Tái cấu trúc mã (refactoring) là quá trình cải thiện cấu trúc nội tại của mã nguồn mà không làm thay đổi hành vi bên ngoài của phần mềm.

Việc refactor giúp:

  • Mã dễ đọc, dễ hiểu hơn
  • Giảm rủi ro khi mở rộng tính năng
  • Gỡ bỏ các mảng mã “nợ kỹ thuật” tích tụ sau thời gian dài

✅ Nếu bảo trì là “dọn dẹp”, thì refactoring chính là “sắp xếp lại tủ đồ cho gọn gàng hơn”.


💡 1.5. Tư duy chuyển đổi: Từ nhà phát triển sang người bảo trì

Là người thiết kế ban đầu, bạn được tự do tạo ra hệ thống từ con số 0. Nhưng là người bảo trì, bạn thường phải:

  • Làm việc với mã do người khác viết
  • Hiểu ý đồ thiết kế mà không có tài liệu đầy đủ
  • Sửa lỗi trong hệ thống đang vận hành mà không được “phá vỡ” nó

Do đó, bạn cần một tư duy cẩn trọng, kỷ luật và kiên nhẫn hơn nhiều so với giai đoạn phát triển ban đầu.


⚠️ 1.6. Bảo trì không phải là viết lại toàn bộ

Một sai lầm phổ biến là nghĩ rằng:

“Mã cũ khó hiểu quá, thôi viết lại luôn cho nhanh.”

Tuy nhiên, viết lại từ đầu không chỉ tốn thời gian mà còn dễ gây lỗi hơn là cải tiến dần từ mã hiện có.

👉 Việc refactor đúng cách cho phép làm mới hệ thống mà không ảnh hưởng tới khách hàng hoặc người dùng.

Phân loại bảo trì phần mềm

🔍 2.1. Tổng quan

Không phải mọi thay đổi trong phần mềm đều giống nhau. Tùy theo mục tiêu của thay đổi, người ta chia bảo trì phần mềm thành 4 loại chính:

  1. Bảo trì thích ứng (Adaptive)
  2. Bảo trì sửa lỗi (Corrective)
  3. Bảo trì hoàn thiện (Perfective)
  4. Bảo trì phòng ngừa (Preventive)

Hiểu rõ từng loại bảo trì giúp bạn lập kế hoạch, phân công nguồn lực và xác định kỹ thuật phù hợp trong quá trình phát triển phần mềm lâu dài.


🔄 2.2. Bảo trì thích ứng (Adaptive Maintenance)

✅ Mục đích:

Giúp phần mềm thích nghi với môi trường thay đổi mà không thay đổi chức năng cốt lõi.

📌 Ví dụ:

  • Phải cập nhật phần mềm để tương thích với hệ điều hành mới
  • Thay đổi quy trình kinh doanh yêu cầu phần mềm thay đổi theo
  • Luật pháp thay đổi → cần sửa form thuế

🧠 Đặc điểm:

  • Thường không tạo ra tính năng mới
  • Không thay đổi mục tiêu ban đầu
  • Tốn ít chi phí hơn viết lại toàn bộ

🐞 2.3. Bảo trì sửa lỗi (Corrective Maintenance)

✅ Mục đích:

Phát hiện và sửa lỗi (bug) xuất hiện trong quá trình phần mềm vận hành.

📌 Ví dụ:

  • Người dùng báo chức năng in hóa đơn bị lỗi
  • Một số giao diện không hoạt động đúng trên trình duyệt Firefox
  • Lỗi phân quyền khiến người không hợp lệ truy cập được dữ liệu

🧠 Đặc điểm:

  • Có thể ảnh hưởng nghiêm trọng nếu không sửa kịp thời
  • Gắn liền với kỹ năng debug và kiểm thử hồi quy (regression testing)
  • Cần phản ứng nhanh

✨ 2.4. Bảo trì hoàn thiện (Perfective Maintenance)

✅ Mục đích:

Cải tiến hệ thống hiện tại dựa trên phản hồi hoặc yêu cầu mới.

📌 Ví dụ:

  • Người dùng muốn thêm chức năng lọc nâng cao
  • Tối ưu tốc độ xử lý để phục vụ nhiều người hơn
  • Bổ sung biểu đồ thống kê trong dashboard

🧠 Đặc điểm:

  • Thường đi kèm refactoring để mã dễ nâng cấp
  • Góp phần tăng trải nghiệm người dùng (UX)

🛡️ 2.5. Bảo trì phòng ngừa (Preventive Maintenance)

✅ Mục đích:

Phát hiện và sửa lỗi tiềm ẩn trước khi chúng xảy ra trong thực tế.

📌 Ví dụ:

  • Kiểm tra và gỡ bỏ đoạn mã chưa dùng tới
  • Viết lại hàm xử lý rườm rà bằng giải pháp ngắn gọn hơn
  • Chia tách lớp “god object” để giảm độ phức tạp

🧠 Đặc điểm:

  • Có tính chủ động cao
  • Nâng cao độ ổn định dài hạn
  • Không phải lúc nào cũng thấy rõ giá trị ngay lập tức, nhưng rất cần thiết cho bảo trì lâu dài

📊 2.6. So sánh nhanh các loại bảo trì

Loại bảo trìMục tiêuThời điểm xảy ra
Thích ứngPhù hợp với môi trường mớiKhi môi trường thay đổi
Sửa lỗiSửa lỗi chức năng hiện tạiKhi lỗi được phát hiện
Hoàn thiệnCải tiến hệ thốngKhi có phản hồi từ người dùng
Phòng ngừaNgăn lỗi có thể xảy ra trong tương laiKhi đánh giá mã thấy có rủi ro

🧠 2.7. Kết luận chương

  • Bảo trì phần mềm không đơn thuần là “sửa lỗi”
  • Việc nhận diện đúng loại bảo trì sẽ giúp bạn:
    • Xác định kỹ thuật phù hợp
    • Giao tiếp tốt hơn với khách hàng hoặc quản lý
    • Tối ưu quy trình phát triển dài hạn

📌 Hãy nhớ: bảo trì giỏi là dấu hiệu của một lập trình viên có trách nhiệm và tư duy dài hạn.

Tái cấu trúc mã nguồn (Refactoring)

❓ 3.1. Tái cấu trúc là gì?

Refactoring là quá trình cải tiến mã nguồn mà không thay đổi hành vi bên ngoài của chương trình.

🧠 Mục tiêu không phải để tạo tính năng mới, mà là làm cho mã rõ ràng hơn, dễ bảo trì hơn.


🧭 3.2. Tại sao cần refactor?

Tình huống thực tếHành động refactor
Hàm quá dàiTách thành nhiều hàm nhỏ
Tên biến khó hiểuĐổi tên rõ nghĩa hơn
Lớp làm quá nhiều việcTách thành nhiều lớp
Code lặp đi lặp lạiĐưa vào hàm dùng chung

→ Khi hệ thống lớn dần, mã sẽ dần trở nên khó đọc, khó mở rộng nếu không tái cấu trúc định kỳ.


🚫 3.3. Lưu ý quan trọng khi refactor

Refactor phải giữ nguyên chức năng!
Tức là sau khi refactor, chương trình:

  • Vẫn chạy đúng như cũ
  • Không gây lỗi mới
  • Không thay đổi cách người dùng sử dụng

Nếu làm thay đổi kết quả chương trình, đó là viết lại, không còn là refactor.


📏 3.4. Quy tắc an toàn khi refactor

  1. Không thay đổi visibility (phạm vi truy cập: public, private, protected)
  2. Không đổi tên biến/phương thức public (trừ khi bạn sửa tất cả nơi gọi đến)
  3. Không đổi kiểu dữ liệu trả về
  4. Nếu thêm/thay đổi tham số → nên overload thay vì sửa trực tiếp
  5. Viết unit test để đảm bảo tính đúng đắn

🧹 3.5. Các kỹ thuật refactor phổ biến

Kỹ thuậtMục đích
Đổi tên biến/hàm (rename)Làm rõ ý nghĩa
Tách phương thức (extract method)Giảm độ dài và phức tạp
Inline phương thứcGộp hàm không cần thiết vào chỗ dùng
Tách lớp (extract class)Lớp quá lớn, làm quá nhiều việc
Di chuyển phương thức (move method)Cho vào lớp đúng nơi sử dụng
Loại bỏ code chếtXóa code không bao giờ chạy

💥 3.6. Khi nào nên refactor?

Dấu hiệuCách xử lý
Mã lặp đi lặp lạiTrích ra hàm chung
Lớp “God Object” (quá nhiều trách nhiệm)Tách lớp
Tên biến không rõ nghĩaĐổi tên rõ ràng hơn
Có đoạn logic lồng nhau nhiều cấpTách ra hàm riêng

✅ 3.7. Refactor và kiểm thử (Test)

Refactor đúng cách phải đi kèm kiểm thử tự động.

  • Nếu bạn có test unit → yên tâm refactor rồi chạy test lại
  • Nếu không có test → rủi ro cao khi refactor
  • Tốt nhất: refactor theo triết lý TDD (Test Driven Development)

💡 3.8. Ví dụ minh họa

Trước khi refactor:

javaCopyEditpublic double getSalary() {
    double salary;
    if (this.role.equals("manager")) {
        salary = 5000 + 200 * this.years;
    } else {
        salary = 3000 + 100 * this.years;
    }
    return salary;
}

Sau khi refactor:

javaCopyEditpublic double getSalary() {
    return isManager() ? calcManagerSalary() : calcStaffSalary();
}

private boolean isManager() {
    return this.role.equals("manager");
}

private double calcManagerSalary() {
    return 5000 + 200 * this.years;
}

private double calcStaffSalary() {
    return 3000 + 100 * this.years;
}

→ Mã ngắn gọn hơn, dễ hiểu hơn, dễ sửa hơn.


🧠 3.9. Tổng kết chương

  • Refactor là kỹ năng quan trọng giúp nâng cao chất lượng mã
  • Phải giữ nguyên chức năng hệ thống, không làm thay đổi hành vi
  • Có thể bắt đầu từ việc đổi tên, tách hàm, tổ chức lại lớp
  • Cần kết hợp với kiểm thử tự động để tránh rủi ro

Kỹ thuật refactor ở cấp lớp và hệ thống

📚 4.1. Vì sao cần refactor ở cấp lớp?

Refactor không chỉ dừng lại ở tên biến hay chia nhỏ phương thức, mà còn bao gồm:

  • Tái tổ chức mối quan hệ giữa các lớp
  • Giảm độ phụ thuộc giữa module
  • Tăng tính đóng gói và khả năng mở rộng

Đây là bước quan trọng để hệ thống sẵn sàng mở rộng tính năng trong tương lai.


🧱 4.2. Dấu hiệu cần refactor ở cấp lớp

Dấu hiệuCách xử lý
Lớp quá lớn (God Class)Tách ra các lớp nhỏ hơn, mỗi lớp đảm nhiệm 1 chức năng
Lớp phụ thuộc quá nhiều lớp khácDùng Facade hoặc tách module
Quá nhiều tham số truyền giữa các lớpGộp vào đối tượng cấu hình hoặc context
Một lớp thay đổi vì nhiều lý do khác nhauTách lớp theo nguyên tắc SRP (Single Responsibility Principle)

✂️ 4.3. Kỹ thuật refactor lớp

✅ Tách lớp (Extract Class)

Khi một lớp chứa quá nhiều biến, hàm không liên quan nhau → cần chia tách.

Ví dụ: Lớp Employee có cả logic về tính lương, chấm công, và gửi email → nên tách ra:

  • PayrollCalculator
  • AttendanceTracker
  • EmailNotifier

✅ Di chuyển phương thức (Move Method)

Nếu một phương thức dùng dữ liệu của lớp khác nhiều hơn của lớp hiện tại → nên chuyển về lớp kia.


✅ Giảm coupling – tăng cohesion

Hành độngÝ nghĩa
Di chuyển logic vào đúng lớpGiảm phụ thuộc chéo
Dùng interface thay vì gọi cụ thểDễ thay đổi, mở rộng
Dùng Dependency InjectionTách ràng buộc giữa lớp gọi và lớp được gọi

🔁 4.4. Tái cấu trúc kiến trúc module

Ở cấp hệ thống, có thể cần:

  • Tách các chức năng lớn thành package/module riêng
  • Dùng Design Patterns để quản lý tương tác giữa module:
    • Facade: ẩn đi chi tiết
    • Mediator: điều phối giao tiếp
    • Strategy: dễ thay đổi thuật toán

📦 4.5. Kỹ thuật refactor package/module

✅ Ví dụ:

Trước khi refactor, mọi thứ trong package core:

mathematicaCopyEditcom.myapp.core
├── User.java
├── Product.java
├── EmailService.java
├── Order.java

→ Sau refactor:

pgsqlCopyEditcom.myapp.user
├── User.java
├── UserRepository.java

com.myapp.product
├── Product.java
├── InventoryService.java

com.myapp.communication
├── EmailService.java

→ Gọn gàng, rõ ràng chức năng và dễ test từng phần.


🧠 4.6. Chiến lược tái cấu trúc hệ thống lớn

  1. Chia nhỏ mục tiêu: Không refactor toàn bộ một lúc – dễ gây lỗi
  2. Viết test trước: Dù chỉ là smoke test cũng giúp phát hiện lỗi
  3. Tạo branch riêng để refactor
  4. Tự động hóa kiểm thử: Refactor xong phải chạy test lại ngay
  5. Thực hiện định kỳ: Coi refactoring là thói quen phát triển, không phải một dự án riêng biệt

🧠 4.7. Kết luận chương

  • Refactor ở cấp lớp và hệ thống giúp hệ thống trở nên có tổ chức hơn
  • Là bước đệm bắt buộc để chuẩn bị cho mở rộng và bảo trì lâu dài
  • Kỹ năng này thể hiện tư duy kiến trúc phần mềm, không chỉ là viết code

Tổng kết – Văn hóa bảo trì và phát triển bền vững

🧠 5.1. Bảo trì không phải là phần việc “hậu kỳ”

Trong thực tế phát triển phần mềm, bảo trì từng bị coi là công việc:

  • Kém hấp dẫn
  • “Dọn dẹp” sau những gì lập trình viên “nghệ sĩ” để lại
  • Gắn với “vá lỗi” và “câu giờ” hơn là sáng tạo

→ Đây là một hiểu lầm nghiêm trọng.

🔍 Thực tế: bảo trì là một phần trung tâm trong vòng đời phần mềm, và yêu cầu nhiều kỹ năng hơn cả giai đoạn phát triển ban đầu.


💡 5.2. Refactoring không phải là việc “làm thừa”

Refactor mã không phải để “đẹp cho vui”, mà để:

  • Giảm rủi ro khi thay đổi
  • Tăng tốc độ phát triển tính năng mới
  • Giúp người khác (và chính bạn trong tương lai) dễ hiểu và kế thừa mã

✅ Không refactor → chi phí bảo trì sẽ tăng theo thời gian → hệ thống trở thành “mã di sản” (legacy) khó động vào.


🧩 5.3. Bảo trì và refactor – trách nhiệm của cả team

Một sản phẩm phần mềm tốt đòi hỏi văn hóa nhóm đề cao:

Tư duyHành động cụ thể
Clean CodeReview code, refactor liên tục
Kiểm thử tự độngĐảm bảo refactor không gây lỗi
Ghi chú rõ ràngComment ngắn gọn, dễ hiểu
DocumentationCập nhật tài liệu sau khi tái cấu trúc
DevOpsTự động hóa test – build – deploy để giảm rủi ro khi sửa mã

📈 5.4. Lợi ích khi duy trì văn hóa refactoring

Lợi íchMô tả
Dễ bảo trìTốn ít công sức hơn khi thêm tính năng mới
Dễ onboardingNgười mới vào hiểu code nhanh hơn
Ít bugMã rõ ràng hơn → ít lỗi hơn
Hiệu suất tốt hơnCó cơ hội tối ưu logic thường xuyên
Giữ được tốc độ phát triển lâu dàiKhông bị “nợ kỹ thuật” chặn đường

🧠 5.5. Kết luận cuối cùng

Viết code tốt là bước khởi đầu.
Biết duy trì, cải tiến và phát triển lâu dài mới là kỹ năng cấp cao.

  • Bảo trì không phải công việc phụ – nó là một phần chính yếu
  • Refactoring không chỉ là làm “sạch” mã – mà là làm mã bền vững, sẵn sàng phát triển

Bài viết liên quan:

Thiết kế lại và Triển khai
Thiết kế tình huống điển hình, thực hành và ví dụ
Các yếu tố để thiết kế phần mềm hiệu quả
Một số mẫu thiết kế phổ biến
Mẫu thiết kế (Design Pattern)
Phân tích và thiết kế động
Phân tích và Thiết kế Tĩnh
Phân tích & Thiết kế hướng đối tượng linh hoạt (Agile Object Orientation)
Thiết kế Lấy Người Dùng Làm Trung Tâm (User Centred Design)
Giới thiệu nội dung series phân tích thiết kế và triển khai phần mềm

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

3. Quản lý dự án công nghệ thông tin (IT PROJECT MANAGEMENT)

1. Giới thiệu khái niệm chuẩn mực và đạo đức nghề nghiệp trong CNTT

2. Áp dụng các chuẩn mực và đạo đức nghề nghiệp trong CNTT

Phát triển .NET Core và Tương lai.

Kiến trúc Onion trong ASP.NET Core

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×