Home Blog Page 13

Cấu trúc dữ liệu và giải thuật là gì? Một số khái niệm trong giải thuật

Cấu trúc dữ liệu và giải thuật

Đối với anh em lập trình viên, cấu trúc dữ liệu và giải thuật luôn là một kiến thức tuy cơ bản nhưng lại khá khó khăn để học, tìm hiểu và thành thạo. Tuy nhiên hầu như ai cũng hiểu được tầm quan trọng của nó trong việc xây dựng một chương trình, tối ưu hóa source code dự án. Bài viết hôm nay chúng ta cùng nhau tìm hiểu về môn học thú vị này để hiểu được tầm quan trọng của nó với lập trình nhé.

Cấu trúc dữ liệu là gì?

Cấu trúc dữ liệu (Data Structures) là cách thức lưu trữ, tổ chức dữ liệu trong chương trình, hệ thống có mục đích để giúp việc sử dụng, thao tác với dữ liệu đó hiệu quả nhất.

Cấu trúc dữ liệu là gì?

Một cấu trúc dữ liệu được định nghĩa sẽ đi kèm với các thao tác, hoạt động trên loại cấu trúc đó. Thông thường sẽ bao gồm các thao tác:

  • Tìm kiếm: tìm và trả về một hoặc nhiều phần tử có giá trị thỏa mãn theo các tiêu chí tìm kiếm
  • Sắp xếp: thực hiện sắp xếp các phần tử dựa trên giá trị theo thứ tự tăng/ giảm
  • Chèn: thêm một phần tử vào cấu trúc
  • Cập nhật: chỉnh sửa giá trị một phần tử trong cấu trúc
  • Xóa: loại bỏ phần tử trong cấu trúc

Một số cấu trúc dữ liệu cơ bản

Một số cấu trúc dữ liệu cơ bản

  • Arrays – Mảng: cấu trúc với kích thước cố định, được đánh chỉ mục giúp truy cập vào từng phần tử.
  • Linked List – Danh sách liên kết: cấu trúc tuần tự chứa chuỗi các items theo một thứ tự tuyến tính được liên kết với nhau.
  • Hash Table – Bảng băm: cấu trúc lưu trữ các giá trị được ánh xạ với một key sinh ra nhờ hàm băm.
  • Stack – Ngăn xếp: cấu trúc dạng LIFO (Last In First Out – phần tử ở cuối cùng được truy cập đầu tiên)
  • Queue – Hàng đợi: cấu trúc dạng FIFO (First In First Out – phần tử ở đầu được truy cập đầu tiên)
  • Tree – Cây: cấu trúc dữ liệu phân cấp, tổ chức theo thứ bậc và được liên kết với nhau giống như một cây với các cành và lá.
  • Graph – Đồ thị: tập hợp hữu hạn các đỉnh (nút) và cạnh (đường đi giữa các đỉnh). 

Giải thuật là gì?

Giải thuật hay thuật toán (Algorithms) là một tập hợp hữu hạn có trình tự các hướng dẫn để thực hiện giải quyết một vấn đề cụ thể. 

Giải thuật là gì?

Một giải thuật cần có đầu vào (input) và đầu ra (output) xác định trước; từng bước thực hiện rõ ràng (clear instructions). Giải thuật không phụ thuộc vào ngôn ngữ lập trình (language independent) mà có thể được triển khai trong nhiều ngôn ngữ lập trình khác nhau. Một giải thuật cần đảm bảo tính khả thi (workable) và phải kết thúc sau một hữu hạn các bước (finiteness). 

Giải thuật là gì?

Một số loại giải thuật phổ biến:

  • Search engine algorithm: Giải thuật tìm kiếm
  • Encryption algorithm: Giải thuật mã hóa
  • Greedy algorithm: Giải thuật tham lam
  • Recursive algorithm: Giải thuật đệ quy
  • Backtracking algorithm: Giải thuật quay lui
  • Divide-and-conquer algorithm: Giải thuật chia để trị
  • Dynamic programming algorithm: Giải thuật quy hoạch động
  • Brute-force algorithm: Giải thuật vét cạn
  • Sorting algorithm: Giải thuật sắp xếp
  • Hashing algorithm: Giải thuật băm
  • Randomized algorithm: Giải thuật ngẫu nhiên

  Cấu trúc dữ liệu List trong Python và các thao tác cơ bản

  Tại sao lập trình viên nên học cấu trúc dữ liệu và giải thuật?

Một số khái niệm trong giải thuật

Lưu đồ giải thuật

Lưu đồ giải thuật hay sơ đồ khối (Flow Chart) là một công cụ giúp biểu diễn thuật toán bằng hình vẽ. Nó mô tả việc nhập, xuất dữ liệu cùng luồng xử lý thông qua các ký hiệu hình học. Sơ đồ khối giúp chúng ta dễ dàng hình dung các bước của thuật toán được triển khai, tăng tính logic của giải thuật. Với một lập trình viên, việc đọc được lưu đồ giải thuật sẽ giúp bạn triển khai viết code theo ngôn ngữ lập trình của mình một cách dễ dàng hơn.

Mã giả

Mã giả (Pseudocode) là một bản mô tả giải thuật lập trình ngắn gọn sử dụng những quy ước có cấu trúc, thường được bỏ đi những chi tiết không cần thiết (ví dụ như khai báo biến, chương trình con,…) giúp giải thuật dễ hiểu hơn. Mục đích của mã giả cũng là giúp người đọc dễ dàng hơn trong việc hiểu giải thuật, và có thể làm mẫu để triển khai trong các ngôn ngữ lập trình khác nhau.

Mã giả

Độ phức tạp của giải thuật

Độ phức tạp (algorithm complexity) của giải thuật là một ước lượng tương đối về số phép tính mà giải thuật cần thực hiện đối với bộ dữ liệu đầu vào có kích thước n. Nó có ý nghĩa giúp đánh giá hiệu quả của một thuật toán, thường được ký hiệu là O(A), trong đó:

  • O(1): thể hiện rằng giải thuật có độ phức tạp hằng số khi thời gian chạy không phụ thuộc kích thước dữ liệu đầu vào
  • O(A): thể hiện rằng giải thuật sẽ cần tối đa A câu lệnh O(1) được thực thi để giải quyết bài toán

Một số độ phức tạp giải thuật thường gặp: O(n), O(log n), O(log n2),…

Tầm quan trọng của CTDL&GT

Cấu trúc dữ liệu và giải thuật luôn có sự song hành với nhau trong việc giải quyết một bài toán. Nhà khoa học máy tính Niklaus Emil Wirth (cha đẻ của ngôn ngữ lập trình Pascal) từng xuất bản cuốn sách với cái tên “Algorithms + Data Structures = Programs” hay có nghĩa là Giải thuật + Cấu trúc dữ liệu = Chương trình; để nói lên tầm quan trọng của CTDL&GT.

Tầm quan trọng của CTDL&GT

Để viết được một chương trình hay giải một bài toán trong lập trình, chúng ta luôn phải kết hợp 2 yếu tố, đó là lựa chọn một cấu trúc dữ liệu phù hợp cho việc lưu trữ các biến, các giá trị; sau đó tìm ra phương hướng kết hợp mọi thứ với nhau bằng giải thuật. Một cấu trúc dữ liệu tốt sẽ giúp chúng ta quản lý dữ liệu một cách hiệu quả, chính xác hơn; một thuật toán tốt sẽ giúp xử lý dữ liệu nhanh chóng, rõ ràng hơn. Kết hợp 2 điều này sẽ giúp chúng ta tạo ra một chương trình chạy đúng, chạy nhanh và phù hợp với các ràng buộc về phần cứng khác.

Hiện nay, bộ môn CTDL&GT luôn xuất hiện trong hầu hết các chương trình giảng dạy chuyên ngành lập trình, công nghệ thông tin ở các trường đại học; và ngay từ các lớp trung học chúng ta cũng đã có môn học liên quan.  Điều này cũng nói lên việc cần thiết phải nắm vững các cấu trúc dữ liệu cơ bản cùng các giải thuật phổ biến để có thể áp dụng vào source code chương trình mà bạn viết.

Kết bài

Bất cứ chương trình được viết bằng ngôn ngữ lập trình nào đều cần có cấu trúc dữ liệu và áp dụng các giải thuật của riêng nó. Nắm được kiến thức về CTDL&GT giúp bạn tự tin hơn trong các buổi phỏng vấn, lấy điểm từ nhà tuyển dụng. Hy vọng bài viết hữu ích dành cho bạn và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm: 

Xem thêm việc làm IT hấp dẫn trên TopDev

Thư viện Driver.js tạo hướng dẫn tương tác trang web

Thư viện Driver.js

Bài viết được sự cho phép của tác giả Nguyễn Thành Nam

Trong thế giới web đầy tính năng ngày nay, việc hướng dẫn người dùng cách sử dụng một trang web hoặc ứng dụng web có thể trở nên khá phức tạp. Vì thế driver.js là một sự lựa chọn hợp lý, nó giúp tạo ra các bước hướng dẫn (tour) tương tác trên trang web của bạn một cách dễ dàng. Trong bài viết này, mình sẽ giới thiệu chi tiết về driver.js và hướng dẫn bạn cách cài đặt cũng như sử dụng thư viện này.

thư viện driver.js

I. Giới thiệu về driver.js

driver.js là một thư viện JavaScript mã nguồn mở giúp bạn tạo các tour du lịch (tour) và hướng dẫn (guide) tương tác cho trang web của mình một cách đơn giản và hiệu quả.

⚡️ Các ưu điểm nổi bật:

  • Đơn giản: Dễ sử dụng và không yêu cầu phụ thuộc bên ngoài.
  • Nhẹ: Dung lượng rất nhỏ sau khi nén, giúp tối ưu hóa hiệu suất trang web.
  • Tính tùy chỉnh cao: Cung cấp API linh động để đáp ứng mọi nhu cầu cá nhân hóa của bạn.
  • Làm nổi bật phần tử trang web: Giúp làm nổi bật bất kỳ phần tử nào trên trang web.
  • Đáp ứng và thân thiện với thiết bị di động.
  • Tương thích với hầu hết các trình duyệt hiện đại.

👉 Bạn có thể sử dụng driver.js để:

  • Tạo các tour du lịch giới thiệu các tính năng chính của trang web của bạn.
  • Cung cấp hướng dẫn từng bước về cách sử dụng trang web của bạn.
  • Làm nổi bật các phần tử quan trọng trên trang web của bạn.
  • Thu hút sự chú ý của người dùng vào nội dung quan trọng.

II. Cài đặt driver.js

📌 Đối với các dự án JavaScript thuần sử dụng câu lệnh để tải gói cài đặt:

npm install driver.js

Hoặc sử dụng CDN nhúng vào tệp HTML của mình:

<script src="https://cdn.jsdelivr.net/npm/driver.js@1.0.1/dist/driver.js.iife.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@1.0.1/dist/driver.css" />

📌 Đối với các dự án sử dụng framework như ReactJS, NextJS… bạn có thể tải bằng lệnh bên dưới.

npm i driver.js

npm package của driverjs xem tại đây

  12 Thư viện JavaScript trực quan hoá dữ liệu hot nhất năm 2024

  FabricJS (Canvas library) và xây dựng tool chế ảnh - thư viện Javascript

III. Cách sử dụng

Sau khi cài đặt, có nhiều cách để cấu hình sử dụng, dưới đây là một mẫu ví dụ đơn giản:

const driverObj = driver({
  showProgress: true,
  steps: [
    { element: '.page-header', popover: { title: 'Title', description: 'Description' } },
    { element: '.top-nav', popover: { title: 'Title', description: 'Description' } },
    { element: '.sidebar', popover: { title: 'Title', description: 'Description' } },
    { element: '.footer', popover: { title: 'Title', description: 'Description' } },
  ],
});

driverObj.drive();

Trong đó:

  • element: Phần tử HTML mà bạn muốn làm nổi bật.
  • popover: Một hộp văn bản hiển thị thông tin.
  • title: Tiêu đề của hộp văn bản
  • description: Mô tả của hộp văn bản

👉 Các cấu hình khác bạn có thể tham khảo tại Configuration và API Reference

Một ví dụ về cấu hình trong ReactJS, NextJS…

import 'driver.js/dist/driver.css';
import { driver } from 'driver.js';

const startTourGuide = () => {
  const config = {
    steps: [
      {
        element: '#element-select',
        popover: {
          title: 'Tiêu đề',
          description: 'Mô tả',
        },
      },
      // Add more steps as needed
    ],
    stageRadius: 7,
    nextBtnText: 'Tiếp tục →',
    prevBtnText: '← Quay lại',
    doneBtnText: '👉 Hoàn thành',
    // Add other configuration options as needed
  };

  const tourInstance = driver(config);

  // Start the tour directly
  tourInstance.drive();
};

Tham khảo tuyển dụng javascript lương cao trên TopDev

Kết quả

thư viện driver.js

III. Kết luận

driver.js là một công cụ mạnh mẽ và linh hoạt giúp bạn cải thiện trải nghiệm người dùng trên trang web của mình. Với driver.js, bạn có thể dễ dàng tạo các tour du lịch và hướng dẫn tương tác giúp thu hút sự chú ý của người dùng và giới thiệu các tính năng chính trong trang web của bạn.

Bài viết gốc được đăng tải tại blog.thanhnamnguyen.dev

Xem thêm:

Xem ngay tin đăng tuyển lập trình viên đãi ngộ tốt trên TopDev

Tìm hiểu về lệnh return trong Python

Tìm hiểu về lệnh return trong Python

Lệnh return là một thành phần cơ bản không thể thiếu trong Python cũng như nhiều ngôn ngữ lập trình khác, giúp hoàn thiện tính năng của một hàm. Tuy đơn giản nhưng để sử dụng return trong hàm một cách tối ưu thì không phải ai cũng nắm rõ được, nhất là với những bạn mới học Python. Bài viết hôm nay chúng ta cùng tìm hiểu về hàm return Python và các cách sử dụng lệnh này nhé.

Lệnh return trong Python

Lệnh return trong Python được sử dụng để thoát khỏi hàm và trở về điểm gọi của hàm đó; cho phép gửi kết quả của hàm trở lại điểm gọi. Lệnh return bao gồm một keyword return và theo sau là giá trị cần trả về của hàm. 

Cú pháp lệnh return:

return [object]

Trong đó, object là một đối tượng bất kỳ, có thể là số (number), chuỗi (string), list, tuple, hàm, lớp (class). Chúng ta cùng xem ví dụ dưới đây:

def return_by_type(type):
  if type == "number":
    return 10
  elif type == "string":
    return "Hello"
  elif type == "list":
    return [1, 2, 3]
  elif type == "tuple":
    return (1, "A", [2, 3])    

print(return_by_type("number")) # 10
print(return_by_type("string")) # Hello
print(return_by_type("list")) # [1, 2, 3]
print(return_by_type("tuple")) # (1, "A", [2, 3])

Lưu ý khi sử dụng lệnh return:

  • Lệnh return chỉ sử dụng được ở trong hàm, nếu sử dụng ở ngoài hàm thì chương trình Python sẽ trả về lỗi: SyntaxError: ‘return’ outside function
  • Lệnh return phải được kèm theo sau là giá trị trả về, không thể khai báo return trống, chương trình sẽ trả ra lỗi: SyntaxError: invalid syntax
  • Một hàm có thể chứa nhiều từ khóa return để trả về các giá trị các khác tùy theo logic; hoặc có thể không chứa một lệnh return nào.

Các loại return trong Python

1. Lệnh return có trả về giá trị

Đây là trường hợp cơ bản nhất của lệnh return với việc trả về một giá trị xác định. 

def cong_hai_so(so_thu_nhat, so_thu_hai):
    ket_qua = so_thu_nhat + so_thu_hai
    return ket_qua
    print("Kết thúc hàm") # Không được thực thi
print(cong_hai_so(8, 18)) # 26

Ví dụ trên, hàm thực hiện việc cộng hai số. Giá trị tính toán ở biến ket_qua và được trả về qua câu lệnh return. Lưu ý là các đoạn lệnh nằm sau câu return sẽ không được chương trình thực hiện, cụ thể như câu print(“Kết thúc hàm”) ở trên.

2. Lệnh return không có giá trị trả về

Một hàm có thể không có lệnh return được triển khai, lúc này mặc định Python sẽ trả về giá trị None.

def ham_khong_return():
    print("Hàm không return")

ket_qua = ham_khong_return()
print(ket_qua)  # None

Giá trị None trong Python là một giá trị đặc biệt được sử dụng để biểu thị “không có giá trị” hay “không có gì”; nó tương tự như giá trị Null trong nhiều ngôn ngữ lập trình khác. Hàm không có lệnh return còn được gọi là hàm không có kết quả trả về hay hàm thủ tục.

  Def trong Python và cách sử dụng

  Hàm trong Python - Cú pháp và một số hàm phổ biến

3. Hàm có nhiều lệnh return

Chúng ta có thể sử dụng nhiều lệnh return trong hàm với việc kết hợp các câu điều kiện if/ else hay match/ case. Tùy vào logic của hàm thực hiện, khi chương trình gặp câu lệnh return sẽ kết thúc ngay hàm và trả kết quả về tương ứng. Các câu lệnh sau sẽ không được thực hiện giúp tránh việc xử lý code dư thừa.

def kiem_tra_dau(x):
    if x > 0:
        return "Số dương"
    elif x < 0:
        return "Số âm"
    else:
        return "Số 0"

print(kiem_tra_dau(5))  # Số dương
print(kiem_tra_dau(-5))  # Số âm
print(kiem_tra_dau(0))  # Số 0

Tuyển dụng Python mọi cấp độ tại đây!

Lệnh return trả về nhiều giá trị

Trong Python, cơ chế unpack object giúp cho một hàm có khả năng trả về nhiều giá trị cùng một lúc. Sử dụng lệnh return để trả ra nhiều giá trị ngăn cách nhau bởi dấu “,”, khi nhận kết quả trả về từ lời gọi hàm, chúng ta dùng cơ chế tương tự để lấy ra giá trị tương ứng.

def tinh_chu_vi_va_dien_tich(chieu_rong, chieu_dai):
    chu_vi = (chieu_rong + chieu_dai) * 2
    dien_tich = chieu_rong * chieu_dai
    return chu_vi, dien_tich

hcn_rong = 3
hcn_dai = 9
hcn_chu_vi, hcn_dien_tich = tinh_chu_vi_va_dien_tich(hcn_rong, hcn_dai)

print(hcn_chu_vi, hcn_dien_tich) # 24 27

Ở ví dụ trên, hàm có nhiệm vụ tính cả chu vi và diện tích của hình chữ nhật, lệnh return sử dụng để trả về cả 2 giá trị này trong 1 câu lệnh; điều này có thể giúp code của chúng ta ngắn gọn hơn trong nhiều trường hợp.

Kết bài

Qua bài viết này, hy vọng các bạn đã nắm rõ được về lệnh return trong Python cùng các trường hợp triển khai source code sử dụng return một cách hiệu quả nhất. Return giá trị hàm trong Python tuy đơn giản nhưng sẽ giúp bạn tối ưu được mã nguồn và cải thiện logic chương trình của mình. Cảm ơn các bạn đã đọc bài và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Xem thêm việc làm công nghệ hấp dẫn trên TopDev

Có nên ghi GPA vào CV không? Điểm bao nhiêu là đủ?

Có nên ghi GPA vào CV không

Bài viết được sự cho phép của tác giả Lê Tuấn Anh

Trong quá trình tư vấn chỉnh sửa CV, mình có nhận được kha khá những câu hỏi xoay quanh vấn đề điểm GPA trong khi đi tìm việc cũng như viết CV, bài viết này mình sẽ giải đáp hết cho các bạn nhé.

1. Có bắt buộc viết GPA vào trong CV không?

Câu trả lời là Không, nếu nhà tuyển dụng không yêu cầu, bạn không bắt buộc phải khai GPA vào CV làm gì cả.

Đa số các tin tuyển dụng hiện nay không có nói gì về GPA hết, ví dụ:

Có bắt buộc viết GPA vào trong CV không

Bạn chỉ viết GPA khi bạn đang có ý định ứng tuyển cho các chương trình Management Trainee của các công ty lớn như Unilever, PepsiCo, vân vân, vì các chương trình của những công ty này thường đòi GPA ở một mức nhất định cụ thể (2.8 hoặc 3.0 trở lên). Ví dụ như một tin dưới đây:

Có bắt buộc viết GPA vào trong CV không

Và nếu các bạn định nộp cho các chương trình mà đòi GPA nhưng GPA của bạn không đủ, đừng tìm cách giấu làm gì, vì khả năng bạn được chọn sẽ không cao đâu – người ta có hệ thống hồ sơ để lọc rất nhanh vấn đề GPA này rồi.

Nhưng như mình đã nói ở trên, các bạn đừng lo quá, có ít chương trình/ công ty hỏi về GPA lắm, đa số các nơi khác chỉ quan tâm bạn tốt nghiệp đại học chưa thôi, chứ bạn loại trung bình hay loại giỏi cũng như nhau thôi à.

2. Tại sao một số công ty lại đòi hỏi GPA?

Vì tư duy của một vài công ty đó là, điểm GPA cao tức là bạn có tư duy tốt, tư duy tốt tức là bạn có khả năng giải quyết công việc tốt. Điều này đúng, nhưng không đúng 100% đâu.

Bạn sẽ khó gặp một đứa bạn nào của mình có GPA 10/10 hay 4/4 nhưng không tham gia hoạt động ngoại khóa nào vẫn được tuyển vào các chương trình của các công ty lớn lắm.

Điểm GPA chỉ đơn giản là một gạch đầu dòng, bên cạnh các gạch đầu dòng khác được yêu cầu thôi. Các gạch đầu dòng khác có thể là kĩ năng chuyên môn, là kinh nghiệm Leadership, là các kinh nghiệm khác đòi hỏi theo từng công việc.

Thế nên nếu GPA của bạn chưa cao, bạn vẫn còn nhiều con đường khác để đi. Bạn xem xem nhà tuyển dụng đòi hỏi kĩ năng nào, tập trung toàn lực CV để làm nổi bật kĩ năng đấy lên cho nhà tuyển dụng thấy.

Việc viết CV sao cho nổi bật được cái kĩ năng mà mình có thuộc về phạm trù kĩ năng viết CV, các bạn có thể click vào để đọc thêm các bài của Tuấn Anh.

  Phân tích “keyword” trong JD để viết CV hiệu quả

  CV chuẩn ATS là gì? Bí kíp đậu phỏng vấn với CV chuẩn ATS

3. Nên đầu tư thời gian học cho GPA cao hay nên đầu tư thời gian đi làm?

Trừ khi bạn là siêu nhân, hoặc bạn đã học được kĩ năng quản lý thời gian cực tốt, hoặc bạn chọn hi sinh các thú vui khác, bạn sẽ vừa có điểm GPA cao, lại vừa tham gia được nhiều hoạt động.

Với đa số những người mình gặp, thường chỉ có thể đạt được một trong hai tiêu chí này mà thôi. Đạt được cái nào, quan trọng là mục tiêu của bạn đặt ra.

Ví dụ, bạn đặt mục tiêu hết đại học xin học bổng du học (yêu cầu học bổng có GPA) hoặc thi Trainee (yêu cầu Trainee có GPA), GPA là một cái bạn cần bỏ thời gian tập trung.

Nếu bạn chỉ muốn học đại học xong đơn giản kiếm một công ty đi làm, công ty to nhỏ vừa gì cũng được, miễn sao đúng sở thích và kĩ năng, cái bạn cần đầu tư là các công việc làm thêm và hoạt động ngoại khóa.

Tham khảo việc làm Java hấp dẫn trên TopDev!

Tuy nhiên như mình đã nói ở trên, nếu chỉ chuyên vào một cái thì không tốt tí nào. Một bạn chỉ biết học và học, GPA 4.0 mà không có bạn bè thì cũng không ổn. Một bạn tham gia mấy chục dự án, hoạt động, mà thi toàn trượt môn mãi không tốt nghiệp được thì cũng không có tốt tí nào. Thế nên ta phải hài hòa, chọn ra cái chính cái phụ, chứ không được bỏ cái nào hết nhé.

Bên cạnh đấy, ngoài chuyện đi học đi làm, ta còn đóng nhiều vai trò khác nhau trong cuộc sống nữa. Ta phải về nhà làm con của ba mẹ, dành thời gian cho ba mẹ. Ta phải đóng vai người yêu tốt cho bạn trai bạn gái, vân vân và mây mây. Liệu để đạt được những thành công về GPA hay hoạt động, bạn có sẵn sàng bỏ đi hay giảm bớt đi những vai trò phụ hay các ham mê giải trí thường ngày của bản thân không?

Bài viết gốc được đăng tải tại anhtuanle.com

Xem thêm:

Xem thêm các việc làm về CNTT hấp dẫn tại TopDev

So sánh Apache Kafka và RabbitMQ: Nên chọn message queue nào?

So sánh Apache Kafka và RabbitMQ

Trong thế giới phát triển phần mềm hiện đại, việc xử lý và truyền tải dữ liệu hiệu quả giữa các hệ thống đã trở thành một yêu cầu quan trọng. Apache Kafka và RabbitMQ là hai nền tảng message broker hàng đầu, mỗi hệ thống đều có những ưu điểm riêng và phù hợp với các tình huống sử dụng khác nhau. Bài viết này sẽ đi sâu vào phân tích, so sánh Apache Kafka và RabbitMQ, giúp các nhà phát triển và kiến trúc sư hệ thống có cái nhìn tổng quan để lựa chọn công cụ phù hợp nhất cho dự án của mình.

Tổng quan về Apache Kafka

Apache Kafka là gì?

Apache Kafka là một nền tảng xử lý dòng dữ liệu phân tán, mã nguồn mở, được phát triển ban đầu bởi LinkedIn và sau đó trở thành một dự án của Apache Software Foundation. Kafka được thiết kế để xử lý dữ liệu theo thời gian thực, với khả năng thu thập, lưu trữ và phân phối lượng dữ liệu lớn một cách hiệu quả. Nó thường được sử dụng để xây dựng các ứng dụng phân tích dữ liệu trực tuyến, hệ thống giám sát và các ứng dụng tích hợp dữ liệu.

Các đặc điểm chính của Apache Kafka

Apache Kafka

1. Khả năng mở rộng (Scalability)

Apache Kafka được thiết kế để xử lý hàng tỷ thông điệp mỗi ngày mà không ảnh hưởng đến hiệu suất. Nó có thể mở rộng theo chiều ngang, nghĩa là bạn có thể thêm nhiều máy chủ vào cluster để tăng cường khả năng xử lý dữ liệu.

2. Hiệu suất cao (High Performance)

Kafka có khả năng xử lý hàng triệu thông điệp mỗi giây với độ trễ thấp. Điều này giúp nó trở thành lựa chọn lý tưởng cho các ứng dụng yêu cầu xử lý dữ liệu thời gian thực.

3. Độ bền (Durability)

Dữ liệu trong Kafka được lưu trữ trên đĩa cứng và có thể được sao chép giữa các broker để đảm bảo tính bền vững và khả năng chịu lỗi. Điều này giúp bảo vệ dữ liệu khỏi mất mát ngay cả khi có sự cố hệ thống.

4. Quản lý dữ liệu theo dòng (Stream Processing)

Apache Kafka hỗ trợ các API mạnh mẽ như Kafka Streams và KSQL để xử lý dữ liệu theo dòng. Các công cụ này cho phép người dùng thực hiện các phép biến đổi và tổng hợp dữ liệu phức tạp một cách dễ dàng và hiệu quả.

5. Khả năng tích hợp (Integration Capabilities)

Kafka dễ dàng tích hợp với nhiều hệ thống khác nhau thông qua các connector có sẵn. Điều này giúp kết nối Kafka với các nguồn dữ liệu và đích dữ liệu khác nhau như cơ sở dữ liệu, hệ thống phân tích, và các dịch vụ đám mây.

Tổng quan về RabbitMQ

RabbitMQ là gì?

RabbitMQ là một hệ thống hàng đợi thông điệp (message queue) mã nguồn mở, được phát triển dựa trên giao thức Advanced Message Queuing Protocol (AMQP). Được phát hành lần đầu vào năm 2007, RabbitMQ là một trong những hệ thống hàng đợi thông điệp phổ biến nhất hiện nay, nổi bật với tính linh hoạt và khả năng hỗ trợ nhiều giao thức truyền thông khác nhau. RabbitMQ giúp các ứng dụng giao tiếp với nhau một cách hiệu quả bằng cách gửi và nhận thông điệp thông qua hàng đợi.

Các đặc điểm chính của RabbitMQ

RabbitMQ là gì?

1. Hỗ trợ nhiều giao thức (Multiple Protocols Support)

RabbitMQ hỗ trợ nhiều giao thức truyền thông như AMQP, MQTT, STOMP, và HTTP. Điều này cho phép nó tương thích với nhiều loại ứng dụng và hệ thống khác nhau, giúp dễ dàng tích hợp vào môi trường IT đa dạng.

2. Khả năng linh hoạt (Flexibility)

RabbitMQ cung cấp nhiều tùy chọn cấu hình và cơ chế routing khác nhau như fanout, direct, topic, và header exchanges. Điều này giúp người dùng dễ dàng tùy chỉnh cách thức thông điệp được gửi và nhận theo nhu cầu cụ thể của họ.

3. Dễ dàng triển khai và quản lý (Ease of Deployment and Management)

RabbitMQ có giao diện quản lý web mạnh mẽ, cho phép người dùng theo dõi và quản lý hệ thống một cách trực quan. Các công cụ này giúp giám sát hàng đợi, kiểm tra hiệu suất và thực hiện các tác vụ quản lý khác một cách dễ dàng.

4. Khả năng mở rộng (Scalability)

Mặc dù RabbitMQ không có khả năng mở rộng mạnh mẽ như Apache Kafka, nó vẫn hỗ trợ clustering và federation để mở rộng hệ thống. Clustering cho phép nhóm nhiều node lại với nhau để tạo ra một hệ thống mạnh mẽ hơn, trong khi federation cho phép kết nối các RabbitMQ server ở các vị trí địa lý khác nhau.

5. Tính nhất quán và độ bền (Consistency and Durability)

RabbitMQ đảm bảo tính nhất quán và độ bền của thông điệp thông qua các cơ chế như persistent messaging, acknowledgements, và confirm. Điều này giúp đảm bảo rằng thông điệp sẽ không bị mất trong quá trình truyền tải và các ứng dụng nhận được thông điệp đúng thứ tự.

6. Khả năng mở rộng ứng dụng (Application-level Flexibility)

RabbitMQ hỗ trợ nhiều ngôn ngữ lập trình thông qua các client libraries, bao gồm Java, Python, Ruby, và nhiều ngôn ngữ khác. Điều này giúp các nhà phát triển dễ dàng tích hợp RabbitMQ vào ứng dụng của họ bất kể ngôn ngữ sử dụng.

  Làm việc với Apache Kafka Topic sử dụng CLI

  Message Brokers là gì? Mesage Brokers trong design system

So sánh Apache Kafka và RabbitMQ

So sánh Apache Kafka và RabbitMQ

1. So sánh về tính năng

Apache Kafka

  • Khả năng mở rộng (Scalability): Kafka có thể mở rộng theo chiều ngang bằng cách thêm nhiều broker vào cluster, giúp tăng khả năng xử lý dữ liệu.
  • Hiệu suất cao (High Performance): Kafka có khả năng xử lý hàng triệu thông điệp mỗi giây với độ trễ thấp, phù hợp cho các ứng dụng yêu cầu xử lý dữ liệu theo thời gian thực.
  • Stream Processing: Hỗ trợ các API như Kafka Streams và KSQL, cho phép xử lý dữ liệu theo dòng một cách mạnh mẽ và linh hoạt.
  • Độ bền (Durability): Kafka lưu trữ dữ liệu trên đĩa và sao chép giữa các broker để đảm bảo tính bền vững của dữ liệu.

RabbitMQ

  • Hỗ trợ nhiều giao thức (Multiple Protocols Support): RabbitMQ hỗ trợ AMQP, MQTT, STOMP, HTTP, giúp tương thích với nhiều loại ứng dụng khác nhau.
  • Linh hoạt trong routing (Flexible Routing): Cung cấp nhiều loại exchanges (fanout, direct, topic, headers) để định tuyến thông điệp theo nhu cầu cụ thể.
  • Dễ triển khai và quản lý (Ease of Deployment and Management): RabbitMQ có giao diện quản lý web mạnh mẽ, giúp theo dõi và quản lý hệ thống dễ dàng.
  • Hỗ trợ clustering và federation: Cho phép mở rộng hệ thống bằng cách nhóm các node lại với nhau hoặc kết nối các server ở nhiều vị trí địa lý.

2. So sánh về cách quản lý message

Apache Kafka

  • Message Storage: Kafka lưu trữ các thông điệp trong các log segment trên đĩa, và mỗi thông điệp được xác định bằng một offset duy nhất.
  • Consumer Groups: Các consumer group giúp quản lý việc tiêu thụ thông điệp một cách song song và độc lập.
  • Retention Policy: Kafka cho phép cấu hình chính sách lưu trữ thông điệp theo thời gian hoặc dung lượng, giúp quản lý và duy trì dữ liệu hiệu quả.

RabbitMQ

  • Message Queues: RabbitMQ lưu trữ thông điệp trong các hàng đợi (queues) và cho phép nhiều consumer đọc từ cùng một hàng đợi.
  • Acknowledgements and Confirmations: Đảm bảo thông điệp được xử lý chính xác bằng cách yêu cầu xác nhận từ consumer hoặc producer.
  • Routing Keys và Exchanges: Sử dụng các routing key và exchanges để định tuyến thông điệp đến các hàng đợi phù hợp.

Tham khảo việc làm Kafka hấp dẫn trên TopDev

3. So sánh về hiệu suất

Apache Kafka

  • Throughput cao: Kafka được thiết kế để xử lý hàng triệu thông điệp mỗi giây với độ trễ thấp, nhờ vào cơ chế ghi đĩa tuần tự và khả năng nén dữ liệu.
  • Latency thấp: Kafka tối ưu hóa độ trễ cho các ứng dụng yêu cầu thời gian thực.

RabbitMQ

  • Throughput trung bình: RabbitMQ có thể xử lý hàng trăm ngàn thông điệp mỗi giây, nhưng không đạt được throughput cao như Kafka.
  • Latency thấp: Mặc dù có độ trễ thấp, RabbitMQ không tối ưu hóa cho việc xử lý dữ liệu theo thời gian thực như Kafka.

4. So sánh về tính ổn định

Apache Kafka

  • Khả năng chịu lỗi cao: Kafka sử dụng cơ chế replication để đảm bảo dữ liệu không bị mất khi có sự cố.
  • Tính nhất quán và độ bền: Đảm bảo tính nhất quán và độ bền thông qua các cơ chế như ISR (In-Sync Replicas).

RabbitMQ

  • Độ tin cậy cao: RabbitMQ sử dụng các cơ chế như persistent messages và acknowledgements để đảm bảo thông điệp không bị mất.
  • Khả năng khôi phục: Hỗ trợ clustering và federation giúp duy trì tính ổn định và khả năng khôi phục khi có sự cố.

5. So sánh về trường hợp sử dụng

Apache Kafka

  • Xử lý dữ liệu theo thời gian thực: Lý tưởng cho các ứng dụng yêu cầu phân tích dữ liệu thời gian thực, hệ thống giám sát và xử lý sự kiện.
  • Tích hợp dữ liệu: Phù hợp cho việc tích hợp dữ liệu từ nhiều nguồn khác nhau vào một hệ thống duy nhất.
  • Stream Processing: Thích hợp cho các ứng dụng yêu cầu xử lý dòng dữ liệu liên tục.

RabbitMQ

  • Quản lý hàng đợi công việc: Phù hợp cho các ứng dụng yêu cầu quản lý hàng đợi công việc và xử lý các tác vụ nền.
  • Truyền thông giữa các dịch vụ: Thích hợp cho việc truyền thông giữa các dịch vụ microservices hoặc các thành phần của một hệ thống phân tán.
  • Xử lý công việc nhỏ lẻ: Hiệu quả trong việc xử lý các tác vụ nhỏ và không yêu cầu throughput cao.

Kết luận

Cả Apache Kafka và RabbitMQ đều là những công cụ mạnh mẽ trong lĩnh vực hệ thống hàng đợi thông điệp và xử lý dữ liệu phân tán, mỗi công cụ đều có những ưu điểm và hạn chế riêng. Apache Kafka nổi bật với khả năng xử lý dữ liệu theo thời gian thực, hiệu suất cao và khả năng mở rộng mạnh mẽ, phù hợp cho các ứng dụng yêu cầu phân tích dữ liệu liên tục và xử lý lượng dữ liệu lớn. Ngược lại, RabbitMQ linh hoạt hơn với nhiều giao thức hỗ trợ, dễ dàng triển khai và quản lý, thích hợp cho việc quản lý hàng đợi công việc và truyền thông giữa các dịch vụ.

Hy vọng qua bài viết này, bạn đã có cái nhìn rõ ràng hơn về hai công cụ Apache Kafka và RabbitMQ, giúp bạn đưa ra quyết định đúng đắn cho nhu cầu của mình. Theo dõi TopDev để cập nhật thêm nhiều kiến thức mới về lập trình và việc làm IT.

Xem thêm:

Xem thêm công việc IT hấp dẫn trên TopDev

Repository Design Pattern và ứng dụng của nó trong Laravel

Repository Design Pattern và ứng dụng của nó trong Laravel

Bài viết được sự cho phép của tác giả Duy Phan

Có khá nhiều bạn đã yêu cầu mình một bài viết về Repository Design Pattern. Vậy mục đích của nó là gì? Nó có thực sự cần thiết cho ứng dụng của bạn hay không? Những điểm mạnh, điểm yếu của nó là gì? Chúng ta cùng đi sâu tìm hiểu qua bài viết này nhé.

Repository Design Pattern là gì?

Đây là một mẫu thiết kế nâng cao mà các bạn mới tiếp xúc lập trình có lẽ cũng không để ý về nó lắm. Đối với các bạn đã có kinh nghiệm thực tập hay làm việc ở các công ti – chắc hẳn cũng đã được nghe các mentor của mình nói về nó.

Repository Design Pattern (mình sẽ tạm viết tắt nó thành RD) là một trong những mẫu thiết kế được sử dụng nhiều nhất trong hầu hết các ngôn ngữ lập trình, các framework… như .NET, Java, PHP…, trải dài từ websites, services, applications,… hay kể cả mobile apps.

Repository Design Pattern là gì?

RD là một lớp trung gian giữa Business Logic (BL) và Data Source (DB), các đối tượng trong lớp trung gian này được gọi là Repository. Giao tiếp giữa BL và DB sẽ được thực hiện thông qua các Interface.

Chúng đem lại sự chuẩn hóa (standardized) cho output và tách biệt hoàn toàn việc xử lí business logic và data access logic, giúp cho BL hoàn toàn không cần quan tâm tới công việc của DB (và ngược lại). Việc chia để trị này hướng tới mục tiêu: ai làm việc nấy, điều đó cũng khiến code của bạn sáng sủa hơn, rõ ràng hơn, và dễ maintenance hơn.

Nói một ví dụ thực tế – trong một nhà máy may mặc, mỗi công nhân đa số đều được chia theo nhóm, và mỗi nhóm chỉ làm một phần nhỏ trong khâu sản xuất. Có nhóm thì chịu trách nhiệm may cổ áo, nhóm may tay áo, nhóm may thân áo, nhóm ráp các bộ phận này lại với nhau, nhóm chịu trách nhiệm hấp ủi… Một nhóm chỉ tập trung vào một công việc cụ thể chắc chắn sẽ nhanh và ít tạo ra sản phẩm lỗi hơn so với một người làm từ đầu đến cuối đúng không nào? ^^

Lợi ích của Repository Design Pattern

  • Code dễ phát triển và maintenance khi làm việc theo nhóm.
  • Giảm thiểu thay đổi code khi có thay đổi về cấu trúc dữ liệu, DB hoặc BL.
  • BL và DB có thể test độc lập
  • Chuẩn hóa đầu ra dữ liệu
  • Giảm thiểu trùng lặp code (DRY – Don’t Repeat Yourself)

Cũng có lợi bất cập hại

  • Viết nhiều, viết mệt, cái gì cũng phải nghĩ đến tách rời và đem xuống Repository và tái sử dụng =))
  • Dự án nhỏ, mì ăn liền thì không cần xài cũng được
  • Với việc thế giới đang chuyển dần sang microservice thì việc áp dụng RD cho mỗi mắt nhỏ trong microservice khá là dư thừa và tốn nhiều chi phí phát triển

Repository Design Pattern và Laravel

Nãy giờ nói lan man quá, toàn là kiến thức khô khan =)), giờ mình xin được phép tiếp tục phần chính của bài viết.

Trong Laravel, Repository là “cây cầu dừa” nối giữa Model và Controller, đây cũng là nơi tập trung xử lí các logic truy vấn dữ liệu.

Các truy vấn này trước đây được thực hiện trực tiếp ở Controller bây giờ sẽ được đưa vào Repository, lúc này Controller sẽ tương tác với DB thông qua Repository thay vì gọi trực tiếp Model. Việc thực hiện truy vấn như thế nào sẽ được Repository giấu kín bên trong (và Controller bản thân nó cũng chẳng cần quan tâm, cứ trả đúng – đủ dữ liệu về cho nó là được rồi).

Điều này cũng giống như bạn ra ngân hàng rút tiền vậy. Bạn chỉ có thể gởi yêu cầu tới nhân viên ngân hàng, sau đó nhân viên ngân hàng kiểm tra và lấy tiền đưa cho bạn. Bạn thử tự xông vào lấy tiền xem sao, vô tù bóc lịch là có nha =))

Ủa rồi phần xử lí BL đâu rồi?

Không phải mình code cùi nên bỏ trực tiếp phần xử lí BL vào trong Controller như vậy đâu nha các bạn =))

Trên thực tế, một số thao tác get dữ liệu đơn giản sẽ được gọi trực tiếp ở Controller thông qua Repository.

Đối với các business phức tạp sẽ có thêm một tầng Service ở giữa nữa. Có nghĩa là lúc này, Controller chỉ có trách nhiệm điều hướng xử lí logic xuống Service, và Service mới là nơi thực hiện các BL và cập nhật xuống DB.

Phần Service này mình sẽ nói rõ thêm với các bạn ở một bài viết khác, dù sao bài viết này cũng chỉ nói về RD thôi mà đúng không ^^

Triển khai Repository Design Pattern đơn giản cho Laravel

Khách hàng của chúng ta cần xây dựng một mạng xã hội cho phép các publishers chia sẻ các albums ảnh và kiếm tiền donate cũng như sự nổi tiếng.

Trước tiên chúng ta sẽ xây dựng một Model.

// app/Album.php namespace App;

use Illuminate\Database\Eloquent\Model;

class Album extends Model
{
    protected $guarded = [
        'id',
        'created_at',
        'updated_at',
    ];
}

Kế tiếp là Controller

// app/Http/Controllers/AlbumController.php

namespace App\Http\Controllers;

use App\Album;

class AlbumController extends Controller
{
    /**
     * Nội dung trang Albums List
     */
    public function index()
    {
        $albums = Album::all();

        return $albums;
    }

    /**
     * Nội dung trang Albums Details
     */
    public function show($id)
    {
        $album = Album::findOrFail($id);

        return $album;
    }
}

Trong Controller, Album được gọi trực tiếp để truy vấn dữ liệu. Mọi chuyện đều êm đẹp cho tới khi khách hàng muốn thay đổi cách truy vấn dữ liệu: các Album sẽ được sắp xếp theo độ tương tác, số lượng views, hoặc trang Album Details được truy vấn bằng hash_id thay vì id… Chắc chắn chúng ta sẽ cần phải cập nhật lại Controller để truy vấn dữ liệu cho phù hợp với requirements của khách hàng.

Điều này hết sức nguy hiểm và củ chuối. Bạn thử tưởng tượng không chỉ có mỗi AlbumController thực hiện các thao tác như thế này, mà rất nhiều Controller khác cũng thực hiện điều tương tự. Việc update code nhiều chỗ như vậy sẽ làm tăng khả năng bỏ sót hoặc thao tác sai lầm.

Và đây là lúc Repository lên sàn =))

Chúng ta sẽ tạo một Repository như sau

// app/Repositories/Eloquent/AlbumRepository.php

namespace App\Repositories\Eloquent;

use App\Album;

class AlbumRepository
{
    public function all()
    {
        return Album::orderBy('views_count', 'desc')->all();
    }

    public function find($id)
    {
        return Album::firstOrFail(['hash_id' => $id]);
    }
}

Cập nhật lại nội dung Controller

// app/Http/AlbumController.php

namespace App\Http\Controllers;

use App\Album;
use App\Repositories\Eloquent\AlbumRepository;

class AlbumController extends Controller
{
    protected $albumRepository;

    public function __construct(AlbumRepository $albumRepository)
    {
        $this->albumRepository = $albumRepository;
    }

    public function index()
    {
        $albums = $this->albumRepository->all();

        return $albums;
    }

    public function show($id)
    {
        $album = $this->albumRepository->find($id);

        return $album;
    }
}

Vậy là từ giờ trở đi, bạn cần thêm logic gì cứ chui vào Repository mà sửa, rõ ràng – sạch sẽ – khô thoáng – dễ hiểu phải không nào ^^

  Hệ thống 23 mẫu Design Patterns

  So sánh Laravel và Phalcon - Framework nào tốt hơn?

Câu chuyện vẫn chưa tới hồi kết

Vào một ngày nọ, khách hàng của chúng ta nghe phong phanh đâu đó bảo rằng dữ liệu của website mình hầu như người ta chỉ có xem là chính, không cần cập nhật gì nhiều cả. Kết thúc chương trình, ông khách hàng yêu cầu chúng ta đọc dữ liệu lên từ cache thay vì truy cập DB như hiện tại.

Giờ chúng ta phải làm sao? Sửa lại các hàm trong AlbumRepository chăng?

Sai. Chúng ta sẽ tạo ra một repository khác chịu trách nhiệm xử lí caching cho AlbumRepository.

Ở đây mình sẽ áp dụng một mẫu thiết kế khác, đó chính là Decorator Pattern. Mẫu thiết kế này giúp chúng ta thêm các tính năng mới mà không cần phải cập nhật lại các lớp hiện tại (lớp ở đây chính là AlbumRepository).

// app/Repositories/Cache/AlbumRepositoryCacheDecorator.php

namespace App\Repositories\Cache;

use App\Repositories\Eloquent\AlbumRepository;;

class AlbumRepositoryCacheDecorator
{
    protected $repository;

    public function __construct()
    {
        $this->repository = new AlbumRepository();
    }

    public function all()
    {
        /*If cache exists, get data from cache*/
        if ('has-cache') {
            return 'data-from-cache';
        }

        $albums = $this->repository->all();

        /*Logic to store cache*/

        return $albums;
    }

    public function find($id)
    {
        /*If cache exists, get data from cache*/
        if ('has-cache') {
            return 'data-from-cache';
        }

        $album = $this->repository->find($id);

        /*Logic to store cache*/

        return $album;
    }

    public function update($id, array $data)
    {
        $this->repository->update($id, $data);

        /*Logic to clear cache*/
    }
}

Sau đó chúng ta cần import AlbumRepositoryCacheDecorator thay vì AlbumRepository

// app/Http/AlbumController.php

namespace App\Http\Controllers;

use App\Repositories\Cache\AlbumRepositoryCacheDecorator;

class AlbumController extends Controller
{
    protected $albumRepository;

    public function __construct(AlbumRepositoryCacheDecorator $albumRepository)
    {
        $this->albumRepository = $albumRepository;
    }

    public function index()
    {
        $albums = $this->albumRepository->all();

        return $albums;
    }

    public function show($id)
    {
        $album = $this->albumRepository->find($id);

        return $album;
    }
}

Các bạn cần chú ý sự thay đổi ở đây: chúng ta đã thay đổi thứ được inject vào __construct.

Củ chuối lắm các bạn à. Bởi AlbumRepository không chỉ được sử dụng ở AlbumController như ví dụ trên, nó còn có thể được sử dụng ở hàng tá chỗ khác, nếu như chúng ta cập nhật một cách thủ công như vậy sẽ có thể dẫn đến nhiều lỗi không muốn, và khiến code của chúng ta lặp đi lặp lại nhiều lần.

Với sự trợ giúp của Laravel Service Container, chúng ta có thể bind một interface tới một class nhất định.

Xem thêm nhiều chương trình tuyển dụng Laravel hấp dẫn trên TopDev

Đầu tiên chúng ta sẽ tạo ra một interface như sau

// app/Repositories/Contracts/AlbumRepositoryContract.php

namespace App\Repositories\Contracts;

interface AlbumRepositoryContract
{
    public function all();

    public function find($id);
}

Sau đó chúng ta cần chỉnh sửa nội dung cho hai lớp AlbumRepository và AlbumRepositoryCacheDecorator sao cho chúng implements AlbumRepositoryContract trên.

use App\Repositories\Contracts\AlbumRepositoryContract;

class AlbumRepository implements AlbumRepositoryContract {}

class AlbumRepositoryCacheDecorator implements AlbumRepositoryContract {}

Bước kế tiếp quan trọng nhất: chúng ta cần khai báo cho Laravel biết cách xử lí khi chúng ta gọi interface binding. Chúng ta sẽ cập nhật nội dung phương thức register bên trong tập tin app/Providers/AppServiceProvider.php.

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Repositories\Contracts\AlbumRepositoryContract;
use App\Repositories\Cache\AlbumRepositoryCacheDecorator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind(AlbumRepositoryContract::class, AlbumRepositoryCacheDecorator::class);
    }
}

Việc cuối cùng chúng ta cần làm là cập nhật lại file AlbumController một chút

namespace App\Http\Controllers;

use App\Repositories\Contracts\AlbumRepositoryContract;

class AlbumController extends Controller
{
    protected $albumRepository;

    public function __construct(AlbumRepositoryContract $albumRepository)
    {
        $this->albumRepository = $albumRepository;
    }

    ...
}

Boom! Mọi thứ tới đây đã khá ổn rồi. Nếu như khách hàng có đổi ý, không muốn sử dụng cache nữa, chúng ta chỉ việc cập nhật lại AppServiceProvider. Khá là đơn giản đúng không nào ^^

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Repositories\Contracts\AlbumRepositoryContract;
use App\Repositories\Eloquent\AlbumRepository;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind(AlbumRepositoryContract::class, AlbumRepository::class);
    }
}

Thậm chí sau này, nếu như khách hàng muốn lưu các albums ở một database khác, chúng ta cũng sẽ không cần cập nhật lại các logic nghiệp vụ ở AlbumController nữa, mà sẽ tạo ra các Repository liên quan và bind chúng lại ở AppServiceProvider.

Bài viết đến đây là kết thúc rồi. Mình hi vọng bài viết này sẽ giúp các bạn hiểu rõ hơn về RD cũng như ứng dụng nó vào Laravel.

Nếu bài viết có nội dung nào đó không chính xác, hoặc các bạn có câu hỏi muốn hỏi mình, hãy để lại comments bên dưới hoặc liên lạc với mình nhé.

Cám ơn các bạn đã theo dõi. Hẹn gặp lại các bạn trong các bài viết vọc vạch Laravel kế tiếp ^^

Bài viết gốc được đăng tải tại duypt.dev

Xem thêm:

Tham khảo thêm các vị trí tuyển dụng ngành IT tại Topdev

Def trong Python và cách sử dụng

Def trong Python và cách sử dụng

Trong bài viết trước về Hàm trong Python, chúng ta đã biết rằng có 2 loại hàm cơ bản bao gồm hàm được tích hợp sẵn và hàm tự định nghĩa bởi người dùng. Để định nghĩa được một hàm trong Python, chúng ta sử dụng đến từ khóa Def. Vậy def là gì trong Python? Bài viết hôm nay chúng ta cùng nhau tìm hiểu về khái niệm này nhé.

Def Python là gì?

Def là một từ khóa (keyword) trong Python dùng để xác định một hàm (function), từ đó chúng ta định nghĩa ra một khối mã có thể gọi và tái sử dụng để thực hiện một số các công việc, nhiệm vụ cụ thể. Khái niệm hàm def dùng để chỉ một hàm mà người dùng tự định nghĩa (user-defined functions), phân biệt với các hàm tích hợp sẵn trong Python (built-in functions).

Cú pháp hàm def trong Python như sau:

Def Python là gì?

 

Trong đó từ khóa def được sử dụng để đánh dấu sự bắt đầu của khai báo hàm, tiếp đến là tên của hàm được kết thúc bằng dấu “:”. Phần thân hàm chứa các câu lệnh được viết thụt vào đầu dòng so với từ khóa def.

Lợi ích khi sử dụng hàm def trong Python:

  • Giúp phân tích một chương trình lớn trong Python thành các khối code nhỏ đảm nhận từng nhiệm vụ rõ ràng và dễ hiểu khi đọc, bảo trì hay gỡ lỗi
  • Giúp source code có khả năng tái sử dụng, tối ưu cấu trúc của chương trình viết bằng Python
  • Giúp tăng khả năng làm việc nhóm, phân chia công việc trong team một cách dễ dàng và thống nhất bằng cách định nghĩa trước cấu trúc, input/ output của hàm

Ví dụ hàm def và cách sử dụng

Chúng ta cùng viết một hàm def đơn giản trong Python có chức năng tính tích của 2 số hạng truyền vào như sau:

# Định nghĩa hàm
def multiply(x, y) :
  """Function calculate multiply of 2 numbers"""
  return x * y

# Gọi hàm sử dụng và truyền tham số
mul = multiply(5, 8)

# In kết quả => 40
print(mul)

Trong đó:

  • multiply: tên hàm def tự định nghĩa
  • x, y: các tham số truyền vào
  • return: từ khóa giúp trả về giá trị tích của 2 số hạng x, y

Một số lưu ý khi viết code khai báo hàm và gọi sử dụng:

  • Khi định nghĩa một hàm, các câu lệnh triển khai nội dung hàm cần được thụt lề so với từ khóa def. Nếu vi phạm thì chương trình Python sẽ thông báo lỗi hoặc chạy không đúng mong đợi
  • Hàm có thể không có tham số hoặc có nhiều tham số
  • Hàm có thể có hoặc không có giá trị trả về
  • Hàm có thể được gọi nhiều lần (không giới hạn) trong chương trình

  Hàm trong Python - Cú pháp và một số hàm phổ biến

  Cấu trúc dữ liệu List trong Python và các thao tác cơ bản

Các trường hợp đặc biệt khi sử dụng def

Def method và Def function

class Weight():
  weight = 100

  def to_pounds(self):
    return 2.205 * self.weight

def to_pounds(kilos):
  return 2.205 * kilos

w = Weight()
pounds = w.to_pounds()

kilos = 100
pounds = to_pounds(kilos)

Ở ví dụ trên chúng ta có 2 từ khóa def được sử dụng để khai báo ra 2 khối code, trong đó khối thứ nhất nằm trong lớp (class) Weight được gọi là một phương thức (method) của lớp Weight; khối bên dưới không thuộc về một lớp nào cả được gọi là một hàm (function). Lời gọi sử dụng của method và function cũng có chút sự khác nhau mà bạn cần lưu ý: method bắt buộc phải gọi thông qua đối tượng của lớp (đối tượng w với phương thức to_pounds), ngược lại, function được gọi một cách trực tiếp.

Def trong Def (Def inside Def)

def outer_function(x, y):
  def inner_function(z):
    return x + y + z

  result = inner_function(3)
  return result

print(outer_function(1, 2))

Ở ví dụ trên chúng ta có thể thấy rằng bên trong hàm def outer_function, chúng ta lại sử dụng từ khóa def khác để định nghĩa hàm inner_function. Đây là cách sử dụng tương đối phổ biến trong Python hay nhiều ngôn ngữ lập trình khác, được gọi là hàm trong hàm (Def inside Def) hay hàm lồng nhau. 

Lưu ý ở đây là phạm vi sử dụng hàm inner_function chỉ nằm trong khối lệnh triển khai hàm outer_function, vì thế bạn không thể gọi sử dụng hàm inner_function ở ngoài chương trình. Nếu thực hiện lời gọi thì lỗi “NameError: name ‘inner_function’ is not defined” sẽ được trả về.

Tuyển dụng Python mọi cấp độ tại đây!

Higher Order Functions

def shout(text):
  return text.upper()

def whisper(text):
  return text.lower()

def greet(func):
  greeting = func("Hi, I am created by a function passed as an argument.")
  print(greeting)

# HI, I AM CREATED BY A FUNCTION PASSED AS AN ARGUMENT.
greet(shout)
# hi, i am created by a function passed as an argument.
greet(whisper)

Higher Order Functions (HOF) là hàm có khả năng nhận đầu vào là một hoặc nhiều hàm khác, cho phép chúng ta tạo ra các hàm mới linh hoạt mà vẫn có thể tái sử dụng được chức năng của hàm cũ. Như ở ví dụ trên, hàm def greet có khả năng nhận tham số func là một hàm truyền vào; nhờ đó chúng ta vẫn có thể sử dụng chức năng của 2 hàm def đã định nghĩa từ trước là shout (viết hoa tất cả ký tự) và whisper (viết thường tất cả ký tự).

Kết bài

Qua bài viết này, hy vọng các bạn đã có câu trả lời cho câu hỏi def trong Python là gì và có thể tự tin tạo ra được những hàm thực hiện chức năng như mong muốn. Bằng cách sử dụng từ khóa def để tạo ra các hàm, bạn sẽ có thể giải quyết được các vấn đề phức tạp và viết code trong Python một cách hiệu quả hơn. Cảm ơn các bạn đã đọc bài và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm việc làm công nghệ hấp dẫn trên TopDev

Vòng lặp trong C++ là gì? 3 loại vòng lặp phổ biến trong C++

vòng lặp trong C++
vòng lặp trong C++
Bạn đam mê lập trình và mới bắt đầu tìm hiểu về lập trình C++? Bạn đã bao giờ nghe thuật ngữ này chưa loop? Loop hay Vòng lặp là một trong những khái niệm quan trọng bạn cần nắm khi học C++. Cùng TopDev theo dõi hết bài viết dưới đây để nắm được tất tần tật kiến thức về vòng lặp trong C++.

Vòng lặp trong C++ là gì?

Loop là một khối mã tự thực thi cho đến khi điều kiện đã chỉ định trở thành sai. Trong phần này, chúng ta sẽ xem xét chi tiết các loại vòng lặp được sử dụng trong lập trình C++.

Sự cần thiết của câu lệnh lặp trong C++

Chúng ta có thể đưa ra một số cách sử dụng trong C++

  • Loops cho phép người dùng thực thi lặp đi lặp lại cùng một bộ câu lệnh mà không cần viết cùng một mã nhiều lần.
  • Nó tiết kiệm thời gian và công sức và tăng hiệu quả.
  • Nó làm giảm nguy cơ mắc lỗi trong quá trình biên dịch.
  • Loops làm cho mã dễ đọc và dễ hiểu hơn, đặc biệt khi xử lý logic phức tạp hoặc tập dữ liệu lớn.
  • Nó thúc đẩy khả năng sử dụng lại và phát triển tiếp đoạn code khi muốn mở rộng chương trình.
  • Loop giúp duyệt qua các cấu trúc dữ liệu như mảng hoặc danh sách liên kết.

Các loại vòng lặp trong C++

Có ba loại được sử dụng trong lập trình C++:

  1. for
  2. while
  3. do while

1. Vòng lặp for trong C++

Vòng lặp for là một cấu trúc điều khiển trong C++ cho phép lặp lại một đoạn mã một số lần nhất định.

vòng lặp for trong C++
Vòng lặp for trong C++
for(initialization; testcondition; updateExpression)
{ 
//code to be executed 
} 

Thành Phần Của Vòng Lặp for:

  1. Initialization (Khởi tạo): Được thực thi một lần duy nhất khi vòng lặp bắt đầu. Thường là khai báo và khởi tạo biến lặp.
  2. Condition (Điều kiện): Được kiểm tra trước mỗi lần lặp. Nếu điều kiện đúng, khối lệnh bên trong vòng lặp sẽ được thực thi. Nếu điều kiện sai, vòng lặp kết thúc.
  3. Increment (Tăng/giảm): Được thực thi sau mỗi lần lặp. Thường dùng để cập nhật biến lặp.

Dưới đây là ví dụ về vòng lặp for in ra các số từ 1 đến 10:

#include <iostream>
using namespace std;

int main() {
    for (int i = 1; i <= 10; i++) {
        cout << i << endl;
    }
    return 0;
}

Trong ví dụ này:

    • Initialization: int i = 1 khởi tạo biến i với giá trị 1.
    • Condition: i <= 10 kiểm tra xem i có nhỏ hơn hoặc bằng 10 không.
    • Increment: ++i tăng giá trị của i lên 1 sau mỗi lần lặp.

Output:

1
2
3
4
5
6
7
8
9
10

2. Vòng lặp while trong C++

Vòng lặp while trong C++ là một cấu trúc lặp cho phép thực thi một khối mã lệnh liên tục khi điều kiện kiểm tra là đúng.

Vòng lặp while trong C++
Vòng lặp while trong C++

Cú pháp cơ bản của vòng lặp while như sau:

while (condition) {
    // Code to be executed
}

Không giống như vòng lặp for, vòng lặp while chỉ chứa một thành phần bên trong dấu ngoặc sau while: một điều kiện đánh giá là đúng hay sai và xác định xem vòng lặp có chạy hay không. Giả sử chúng ta muốn điều kiện tương tự như vòng lặp for ở trên, nghĩa là vòng lặp phải từ 5 trở xuống để vòng lặp chạy. Trong trường hợp này, chúng ta sẽ viết điều kiện này là while (i < 5).

Mặc dù các câu lệnh khởi tạo và tăng/giảm bị thiếu trong dấu ngoặc đơn, nhưng chúng vẫn cần thiết trong vòng lặp while cũng như trong vòng lặp for. Chúng ta phải khởi tạo biến tăng i trước khi vòng lặp while bắt đầu và việc tăng/giảm sẽ xảy ra trong khối mã của vòng lặp

Ví dụ minh họa:

#include <iostream>
using namespace std;

int main() {
    int i = 0;
    
    // Vòng lặp while
    while (i < 5) {
        cout << "i = " << i << endl;
        i++; // Cập nhật điều kiện
    }
    
    return 0;
}

Trong ví dụ này, vòng lặp while sẽ in giá trị của i từ 0 đến 4. Biến i được khởi tạo với giá trị 0 và tăng dần mỗi lần lặp.

Output:

1
2
3
4

3. Vòng lặp do-while trong C++

Vòng lặp do-while trong C++ là một cấu trúc lặp cho phép thực hiện một khối mã lệnh ít nhất một lần và sau đó tiếp tục thực hiện khối lệnh đó khi điều kiện kiểm tra là đúng. Vòng lặp này rất giống với vòng lặp while nhưng có một điểm khác biệt chính: Điều kiện được đánh giá sau khối câu lệnh, không phải trước khối câu lệnh.

Vòng lặp do-while trong C++
Vòng lặp do-while trong C++ 

Cú pháp cơ bản của vòng lặp do-while như sau:

do {
    // Code to be executed
} while (condition);

Chi Tiết:

  1. Khởi Tạo và Thực Thi: Khối mã lệnh trong vòng lặp do-while sẽ được thực hiện ít nhất một lần, ngay cả khi điều kiện kiểm tra ban đầu là sai.
  2. Kiểm Tra Điều Kiện: Sau khi thực thi khối lệnh, điều kiện được kiểm tra. Nếu điều kiện là đúng, vòng lặp sẽ lặp lại. Nếu điều kiện là sai, vòng lặp sẽ kết thúc.

Ví Dụ:

#include <iostream>
using namespace std;

int main() {
    int i = 0;

    // Vòng lặp do-while
    do {
        cout << "i = " << i << endl;
        i++; // Cập nhật biến điều kiện
    } while (i < 5);

    return 0;
}

Trong ví dụ này, vòng lặp do-while sẽ in giá trị của i từ 0 đến 4. Biến i được khởi tạo với giá trị 0 và tăng dần mỗi lần lặp. Vòng lặp sẽ dừng khi điều kiện i < 5 trở nên sai (false).

Output:

1
2
3
4

Khi nào nên sử dụng vòng lặp trong C++

Trong các ví dụ trên, chúng tôi đã in ra số đếm trên mỗi lần lặp của vòng lặp. Các trường hợp sử dụng khác của vòng lặp bao gồm việc thêm một số vào biến tổng ngày càng tăng sau mỗi lần lặp hoặc theo nghĩa rộng hơn, thay đổi bất kỳ biến nào khác theo một cách nào đó.

  1. Vòng lặp for:
    • Khi biết trước số lần lặp.
    • Duyệt qua mảng hoặc danh sách.
  2. Vòng lặp while:
    • Khi số lần lặp không xác định trước.
    • Điều kiện kiểm tra trước khi thực hiện.
  3. Vòng lặp do-while:
    • Khi muốn thực hiện ít nhất một lần trước khi kiểm tra điều kiện.

Vòng lặp lồng nhau và vô hạn trong C++

Cuối cùng, chúng ta hãy xem xét một số trường hợp sử dụng nâng cao của vòng lặp trong C++. Bạn có thể đã thấy các tài liệu tham khảo về vòng lặp lồng nhau và tự hỏi chúng là gì.

Các vòng lặp lồng nhau là các vòng lặp bên trong các vòng lặp; chúng không chỉ có thể mà còn khá phổ biến.

Đây là cách một vòng lặp lồng nhau có thể trông như thế nào:

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 3; i++) {  // Vòng lặp ngoài
        for (int j = 0; j < 3; j++) {  // Vòng lặp trong
            cout << "i = " << i << ", j = " << j << endl;
        }
    }
    return 0;
}

Mặc dù việc sử dụng các vòng lặp lồng nhau có vẻ thuận tiện nhưng tốt nhất nên tránh sử dụng nếu có thể. Nếu có một chức năng trong thư viện tiêu chuẩn thực hiện những gì bạn cần thì nên dùng và tránh dùng vòng lặp lồng nhau vì cú pháp phức tạp của nó có thể khiến bạn có sai sót trong quá trình viết code.

Vòng lặp vô hạn là vòng lặp không bao giờ kết thúc nếu không có điều kiện dừng thích hợp. Vòng lặp này thường được sử dụng trong các chương trình cần chờ sự kiện hoặc điều kiện từ bên ngoài.

Ví dụ:

#include <iostream>
using namespace std;

int main() {
    while (true) {
        // Thực hiện công việc lặp lại
        cout << "This is an infinite loop. Press Ctrl+C to stop." << endl;
    }
    return 0;
}

Vòng lặp trên sẽ lặp lại mãi mãi vì điều kiện true luôn luôn đúng. Để dừng vòng lặp này, bạn có thể sử dụng tổ hợp phím Ctrl+C trên hầu hết các hệ thống để kết thúc chương trình.

TopDev tin rằng bài viết này đã mang lại cho bạn kiến thức tổng quan về cách các nhà phát triển C++ sử dụng vòng lặp và các kiểu vòng lặp phổ biến trong C++. Xem việc làm C++ mới nhất tại đây.

Tài liệu tham khảo:

  • https://www.udacity.com/blog/2021/02/c-loops-what-you-need-to-know.html
  • https://www.scholarhat.com/tutorial/cpp/loops-in-cpp-programming

So sánh C# và C++ – Nên học ngôn ngữ nào?

So sánh C# và C++

Trong thế giới công nghệ phần mềm phát triển và phát triển nhanh chóng, các ngôn ngữ lập trình khác nhau đang cạnh tranh để giành được vị trí của mình. Trong bài viết này, TopDev sẽ xem xét sự khác biệt về tính năng của từng ngôn ngữ giữa C# và C++ – hai ngôn ngữ lập trình khá phổ biến hiện nay.

Sơ lược về lịch sử của C# và C++

Vào những năm 1970, khi nhà khoa học máy tính người Đan Mạch Bjarne Stroustrup làm luận án tiến sĩ, ông muốn sử dụng Simula, ngôn ngữ lập trình hướng đối tượng đầu tiên. Nhưng Simula tỏ ra quá chậm nên Stroustrup quyết định sử dụng C, ngôn ngữ lập trình nhanh nhất—và một số người cho rằng vẫn là—ngôn ngữ lập trình nhanh nhất.

Lịch sử phát triển của C++ và C#
Lịch sử phát triển của C++ và C#

Nguồn: www.toptal.com

Sau trải nghiệm với Simula , Stroustrup bắt đầu phát triển ngôn ngữ hướng đối tượng dựa trên C và đến năm 1985, C++ đã được cung cấp rộng rãi cho công chúng.

Anh ấy quyết định làm cho C++ “gần với C nhất có thể, nhưng không gần hơn”, nghĩa là việc áp dụng sẽ không phải là trở ngại. Bởi vì tất cả các thư viện C đều tự động có sẵn để sử dụng nên nhiều nhà phát triển C hàng đầu có thể chuyển sang C++ bằng cách xây dựng dựa trên kiến ​​thức hiện có của họ.

Thật không may, sự tương đồng bẩm sinh với C cũng là một trong những điểm yếu nhất của C++, vì cả hai ngôn ngữ đều yêu cầu đường cong học tập khó khăn và khó thành thạo, điều này khiến việc viết mã trở thành một thách thức đối với các nhà phát triển thiếu kinh nghiệm.

Đó là một trong những lý do chính đằng sau quyết định tạo ra Java của Sun Microsystems vào giữa những năm 90. Java có cú pháp tương tự như C++ nhưng nó đơn giản hóa cấu trúc ngôn ngữ và giảm khả năng mắc lỗi vô ý. Nhóm Java, do James Gosling đứng đầu, đã hoàn thành việc này chủ yếu bằng cách loại bỏ khả năng tương thích ngược với C.

Năm 2002, Microsoft phát hành C# với tư cách là đối thủ cạnh tranh trực tiếp với Java. Là một ngôn ngữ thay thế, C# chia sẻ một số cú pháp với Java nhưng có nhiều tính năng hơn. Cả C# và C++ đều đã được cải thiện đáng kể kể từ khi phát hành.

Ngôn ngữ lập trình hướng đối tượng cần lưu ý

Khi C++ xuất hiện, phần lớn các ngôn ngữ lập trình đều hướng đến thủ tục.

Trong các ngôn ngữ lập trình thủ tục, một chương trình được tổ chức thành các đơn vị nhỏ hơn, gọi là thủ tục. Mỗi thủ tục tương ứng với một số hành động chung được sử dụng sau này (được gọi từ) trong một đơn vị lớn hơn.

Trong các ngôn ngữ hướng đối tượng, các thủ tục được nhóm xung quanh các đối tượng mà chúng được thực hiện. Một đối tượng là một đơn vị logic chứa một số trạng thái.

C# là ngôn ngữ hướng đối tượng hoàn toàn, trong khi C++ là ngôn ngữ có thể kết hợp mã hướng thủ tục và hướng đối tượng.

Điểm tương đồng giữa C# và C++

Cả hai ngôn ngữ đều hướng đối tượng và dựa trên C. Hơn nữa, C# dựa trên C++, điều này khiến chúng khá giống nhau. Những người không thông thạo một trong hai ngôn ngữ có thể dễ dàng nhầm lẫn ngôn ngữ này với ngôn ngữ kia khi nhìn lướt qua mã.

Cả hai ngôn ngữ đều có những đặc điểm thường thấy trong các ngôn ngữ hướng đối tượng, bao gồm:

  • Đóng gói: Mã được tổ chức theo nhóm logic, được gọi là lớp.
  • Ẩn dữ liệu: Các phần dữ liệu và mã là riêng tư, có nghĩa là chúng chỉ có thể được truy cập từ bên trong một lớp.
  • Kế thừa: Chức năng của lớp chia sẻ có thể được tổ chức trong một lớp chung được kế thừa bởi các lớp dẫn xuất và do đó tránh được sự trùng lặp mã.
  • Đa hình: Mã có thể ảnh hưởng đến một đối tượng của lớp cơ sở nhưng hoạt động khác nhau đối với các lớp dẫn xuất khác nhau.

C# và C++ khác nhau thế nào?

Một số tính năng mạnh mẽ của C++ rất khó hiểu và có thể gây ra lỗi lập trình. Các tính năng này đã bị cố tình bỏ qua trong Java và sau đó là trong C#:

  • Đa kế thừa. Các lớp dẫn xuất kế thừa nhiều lớp cơ sở. Thay vì tính năng này, C# đã giới thiệu các lớp cơ sở mà không cần triển khai. Các lớp như vậy được gọi là giao diện trong C#.
  • Con trỏ. Mặc dù con trỏ có thể được sử dụng trong C# nhưng mã sử dụng con trỏ phải được đánh dấu là “không an toàn”. Cách thực hành này rất không được khuyến khích và các tài liệu tham khảo được sử dụng thay thế.
  • Mất độ chính xác. C# không cho phép mất độ chính xác bằng cách chuyển đổi kiểu ẩn. Nếu độ chính xác sắp bị mất thì cần phải chuyển đổi rõ ràng.

Quản lý bộ nhớ

Có lẽ sự khác biệt quan trọng nhất giữa C# và C++ là quản lý bộ nhớ.

Trong C, bộ nhớ động (tức là không biết trước việc phân bổ bộ nhớ) được phân bổ bằng cách sử dụng mallochàm và giải phóng bằng cách sử dụng free. Các lập trình viên phải quản lý bộ nhớ theo cách thủ công. Kết quả là rò rỉ bộ nhớ là lỗi phổ biến trong mã C.

Việc quản lý bộ nhớ trong C++ được cải thiện vì bộ nhớ được quản lý bán tự động. Các đối tượng được gọi là “con trỏ thông minh” có thể được sử dụng để các lập trình viên không phải phân bổ bộ nhớ theo cách thủ công. Tuy nhiên, có một số trường hợp đặc biệt (tham chiếu vòng tròn) trong đó con trỏ thông minh không đủ để ngăn chặn rò rỉ bộ nhớ.

C# sử dụng trình thu gom rác (GC), tự động giải phóng bộ nhớ không còn được sử dụng. Mặc dù điều này có vẻ lý tưởng, nhưng đôi khi GC gây khó khăn cho việc phân bổ một đối tượng chứa tài nguyên hệ thống ngoài bộ nhớ (ví dụ: thẻ điều khiển tệp hoặc kết nối TCP). Trong trường hợp đó, một hiện tượng được gọi là “rò rỉ tài nguyên” có thể xảy ra và lập trình viên phải phân bổ thủ công đối tượng chứa tài nguyên. Trong những tình huống hiếm gặp này, việc phân bổ trong C# trở nên phức tạp hơn trong C++, vì việc phá hủy các đối tượng trong C# không mang tính quyết định .

Biên dịch: nhị phân so với mã byte

C++ được biên dịch thành mã nhị phân của máy ngay lập tức. C# được biên dịch thành mã byte, mã này sau đó được .NET biên dịch thành mã nhị phân máy. (Trước đây là “.NET Core,” .NET là sự thay thế đa nền tảng, hiện đại của Microsoft cho .NET framework ban đầu.)

Mặc dù C++ có lợi thế về hiệu suất trong các cách tiếp cận biên dịch khác nhau này, nhưng C# có một tính năng mạnh mẽ được gọi là “phản chiếu”, cho phép khởi tạo đối tượng và gọi phương thức với thông tin được thu thập trong thời gian chạy. Ví dụ: người ta có thể gọi một phương thức bằng tên của nó, mặc dù phương thức đó không có sẵn trong thời gian biên dịch. Theo định nghĩa, C++ không thể có sự phản chiếu vì nó được biên dịch ngay lập tức. Thay vào đó, C++ có thông tin loại thời gian chạy (RTTI) . Đây là một tính năng kém mạnh mẽ hơn nhiều vì nó chỉ được sử dụng cho các loại có chức năng ảo.

C++ cũng có các mẫu ở dạng mã được tạo tại thời điểm biên dịch tùy thuộc vào loại biến. Thay vì các mẫu, C# có các tệp generic . Generics không được giải quyết tại thời điểm biên dịch mà tại thời điểm chạy. Như vậy, mẫu nhanh hơn mẫu chung. Mặt khác, generics không yêu cầu bộ nhớ bổ sung cho từng loại biến mới.

Bảng tổng kết so sánh C++ và C#

C++ C#
Biên dịch Trực tiếp sang nhị phân Để mã byte
Thời gian biên dịch Dài Ngắn
Quản lý bộ nhớ Hướng dẫn sử dụng hoặc bán tự động bằng con trỏ thông minh Tự động bởi người thu gom rác
Tốc độ run-time Nhanh nhất có thể Chậm hơn C++
Yêu cầu bộ nhớ run-time Tối ưu Hơn C++
Dễ bị lỗi Dễ bị lỗi đối với các lập trình viên chưa có kinh nghiệm Thân thiện với người mới bắt đầu hơn
Kế thừa lớp Đơn, nhiều và ảo Chỉ một, nhiều với giao diện
Mã chung Mẫu – thời gian biên dịch Generics – thời gian chạy
Tính di động Trình biên dịch có sẵn cho hầu hết mọi hệ điều hành, nhưng mã cần được biên dịch cho mọi mục tiêu Mã byte được biên dịch có thể chạy trên nhiều hệ điều hành
Học hỏi Đường cong học tập dốc; mất thời gian; có thể phức tạp đối với các nhà phát triển mới làm quen; cộng đồng nhỏ hơn với ít tài nguyên học tập được tạo ra hơn Ngôn ngữ cấp cao; dễ đọc hơn; thứ bậc cấp trên; dễ dàng nắm vững hơn đối với người mới bắt đầu, đặc biệt là những người có kinh nghiệm về C++ hoặc Java; cộng đồng lớn hơn và tích cực hơn
Sự phản xạ Thông tin loại thời gian chạy không có sẵn là một sự thay thế kém Có sẵn và rất thuận tiện
Chuyển đổi ngầm Cho phép đối với các loại tích hợp Chỉ được phép nếu an toàn
Khả năng tương thích với C Hoàn toàn tương thích với mã C bên ngoài Không tương thích
Tính mô đun Hoàn thành với các thư viện và tiêu đề Được xây dựng trong ngôn ngữ

Nên chọn ngôn ngữ nào? C++ hay C#?

Nếu bạn cần hiệu suất cao, câu trả lời là C++ trong hầu hết mọi tình huống. “Hiệu suất cao” đề cập đến mã code. Nếu bạn đang sử dụng các thư viện có sẵn cho công việc quan trọng về thời gian thì hiệu suất mã của bạn có thể không phải là yếu tố quyết định.

Nếu hiệu suất không quan trọng thì thời gian phát triển là điều cần xem xét. Nếu bạn có thể bắt đầu lại từ đầu, phát triển dự án của mình bằng C# có lẽ là lựa chọn tốt hơn.

Trên đây là bài viết tổng hợp so sánh C++ và C# của TopDev, mỗi ngôn ngữ lập trình đều có các ưu điểm và phù hợp với tính chất của các loại project riêng. Việc lựa chọn C++ hay C# sẽ tùy thuộc vào tính chất công việc của bạn. Theo dõi TopDev để tiếp tục kiến thức về lập trình bạn nhé!

C# so với C++: Ngôn ngữ nào tốt hơn?

Khi nói đến tốc độ và hiệu quả bộ nhớ, C++ rõ ràng là người chiến thắng. Tuy nhiên, nếu có sẵn một thư viện C# tốt nhưng không có thư viện nào như vậy cho C++ thì C# cuối cùng có thể mang lại giải pháp nhanh hơn và việc triển khai C++ có thể chậm hơn.

Sự phát triển thường nhanh hơn trong C#. Nếu ứng dụng không thực hiện các tác vụ quan trọng về thời gian thì việc chọn ngôn ngữ dễ dàng hơn và ít xảy ra lỗi hơn là điều hợp lý.

Theo truyền thống, C++ là lựa chọn phù hợp cho môi trường không phải Windows, nhưng điều đó đã thay đổi khi Microsoft bắt đầu khuyến khích triển khai .NET nguồn mở . Mã byte C# tương tự có thể chạy trên hầu hết mọi nền tảng, điều này khiến nó trở thành ngôn ngữ được lựa chọn khi nói đến việc đơn giản hóa tính di động.

Do phản ánh, C# là lựa chọn hợp lý hơn khi viết thư viện phải hỗ trợ gọi hàm từ xa hoặc các tính năng tương tự yêu cầu tạo mã bằng cách sử dụng thông tin có sẵn trong thời gian chạy.

Mặc dù cả hai ngôn ngữ đều hỗ trợ thiết kế mô-đun, nhưng khó duy trì hơn trong C++, ngôn ngữ này triển khai tính năng đó bằng cách sử dụng các tiêu đề được thiết kế bằng C—một phương pháp hiện đã bị các phương pháp tiếp cận hiện đại hơn vượt qua. Điều này thường dẫn đến thời gian biên dịch C++ dài hơn đáng kể so với thời gian biên dịch C# sang mã byte.

C++ là ngôn ngữ phức tạp hơn nên người lập trình C++ có thể chuyển sang C# dễ dàng hơn so với ngược lại. Nhưng nếu nhóm của bạn có cả nhà phát triển C++ và C# thì có thể kết hợp hai ngôn ngữ.

Chọn ngôn ngữ phù hợp

Nếu bạn cần hiệu suất cao, câu trả lời là C++ trong hầu hết mọi tình huống. “Hiệu suất cao” đề cập đến mã. Nếu bạn đang sử dụng các thư viện có sẵn cho công việc quan trọng về thời gian thì hiệu suất mã của bạn có thể không phải là yếu tố quyết định.

Nếu hiệu suất không quan trọng thì thời gian phát triển là điều cần xem xét. Nếu bạn có thể bắt đầu lại từ đầu, phát triển dự án của mình bằng C# có lẽ là lựa chọn tốt hơn.

Nếu bạn có thời gian phát triển rảnh rỗi nhưng hiệu suất không quan trọng thì sự lựa chọn phụ thuộc vào kỹ năng của các nhà phát triển hiện có . Hãy nhớ rằng sự trôi chảy của nhà phát triển của bạn có thể ảnh hưởng nghiêm trọng đến việc bảo trì mã trong tương lai. Bất cứ khi nào có thể, hãy xem xét ngôn ngữ mà nhóm của bạn ưa thích.

Tài liệu tham khảo: www.toptal.com/c-sharp/c-sharp-vs-c-plus-plus

So sánh Nodejs với PHP: Nên chọn công nghệ web nào?

So sánh Nodejs với PHP: Nên chọn công nghệ web nào?

Bài viết được sự cho phép bởi tác giả Sơn Dương

Khi bạn là một tech leader được giao nhiệm vụ lựa chọn một công nghệ cho dự án tiếp theo của team. Có nhiều yếu tố để bạn lựa chọn một công nghệ hay một ngôn ngữ lập trình ví dụ như dùng Nodejs và PHP. Có thể liệt kê một số yếu tố như:

  • Khách hàng yêu cầu sử dụng công nghệ gì? Ngôn ngữ lập trình nào?
  • Bài toán mà dự án cần giải quyết là gì? Ví dụ: ứng dụng cần xử lý tác vụ nặng? Hay ứng dụng real time không?
  • Team của bạn có member giỏi về ngôn ngữ nào? Nodejs hay PHP là điểm mạnh của team.

Như bạn thấy đấy, để chọn được công nghệ phù hợp phụ thuộc rất nhiều yếu tố chứ không chỉ có yếu tố kỹ thuật.

Bài viết này mình sẽ so sánh Nodejs và PHP – hai công nghệ web nổi tiếng. Cùng xem ưu điểm và nhược điểm của chúng là gì?

#Nodejs là gì?

Phần tìm hiểu định nghĩa về Nodejs là gì thì mình đã có nói đến trong bài viết giới thiệu NodeJS. Bạn có thể đọc lại, mình đã giải thích rất chi tiết về Nodejs.

Tuy nhiên, ở đây mình chỉ nhấn mạnh một điều thôi. Đó là NodeJS không phải là một ngôn ngữ lập trình. Nodejs là một nền tảng sử dụng Javascript làm ngôn ngữ để xây dựng ứng dụng.

#PHP là gì?

PHP (viết tắt của Hypertext Preprocessor) là một ngôn ngữ lập trình kịch bản dành cho server. Mã nguồn PHP có thể nhúng vào HTML nhờ cặp thẻ <?php>.

PHP kết hợp với MySQL trở thành bộ đôi “song sát” của thế giới web. Với rất nhiều ứng dụng nổi tiếng sử dụng PHP như WordPress, Facebook…

Hiện PHP có rất nhiều framework như: Lavarel, Zend Framework, Yii PHP Framework… hoặc CMS mạnh mẽ: WordPress, Joomla… giúp bạn xây dựng ứng dụng web nhanh chóng và đơn giản.

Có lẽ nhiều bạn thắc mắc tại sao mình lại đi so sánh một nền tảng (nodejs) với một ngôn ngữ lập trình (PHP). Có phải quá khập khiễng không?

Thực ra, vì cả hai đều dùng để xây dựng ứng dụng web trên server. Nếu ghi đúng tiêu đề thì phải là so sánh hệ sinh thái giữa Nodejs và PHP.

Mà mọi sự so sánh đều khập khiễng. Chúng ta cứ thử tìm hiểu xem hai “ông trùm” này có thế mạnh và yếu như nào nhé!

#So sánh Nodejs và PHP – Cuộc chiến cân sức

Mặc dù cả PHP và Nodejs đều có thể xây dựng được những ứng dụng rất phức tạp. Rất nhiều hệ thống lớn sử dụng PHP hay Nodejs. Tất nhiên là PHP và Nodejs khác nhau hoàn toàn về tư tưởng và cả kiến trúc thiết kế.

Chúng ta cùng điểm qua một số chỉ số về PHP và Nodejs xem thế nào.

Đầu tiên là điểm qua 10 website lớn sử dụng hai công nghệ web này:

So sánh Nodejs và PHP

Về cơ bản thì những website lớn đều sử dụng qua lại hai công nghệ này. Nên ở điểm tin cậy thì hai công nghệ này coi như bằng nhau.

Nếu xét về mặt thuần ngôn ngữ thì sao? Xu hướng và cộng đồng sử dụng PHP và Javascript cũng tương đương.

So sánh Nodejs và PHP

Thử kiểm tra trên Google trend xem xu hướng sử dụng hai ngôn ngữ này:

So sánh Nodejs và PHP

Phần tiếp theo mình sẽ so sánh Nodejs và PHP với những ưu và nhược điểm của từng công nghệ này.

#Ưu điểm của Node.js

Ưu điểm của Node.js

1. Hiệu năng cực nhanh

Nodejs là nền tảng được xây dựng trên ngôn ngữ Javascript vì vậy Nodejs hỗ trợ kiến trúc hướng sự kiện (event-driven) và non-blocking I/O.

Do đó ứng dụng Nodejs có thể thể dễ dàng xử lý nhiều kết nối một cách dễ dàng.

Nhờ Nodejs xử lý bất đồng bộ các tác vụ nên chúng ta dễ dàng tạo các giải pháp phía máy chủ có khả năng tận dụng CPU khi phục vụ đồng thời nhiều yêu cầu cực tốt so với ngôn ngữ đa luồng như PHP.

Nhờ ưu điểm này mà Nodejs phù hợp với các ứng dụng kiểu không đồng bộ, dựa trên dữ liệu và các luồng công việc không ràng buộc I/O như RTA( Ứng dụng thời gian thực), SPA( Single page application)… Những ứng dụng kiểu như vậy, Nodejs luôn đảm bảo với hiệu năng tuyệt vời.

2. Sử dụng Javascript – một ngôn ngữ cho cả Server và client

Có rất nhiều frameworks dành cho client như Ember, React hay Angular được viết bằng ngôn ngữ Javascript.

Khi bạn sử dụng Nodejs cho server, bạn có thể sử dụng toàn bộ kiến thức về Javascript mà bạn biết cho server.

Đây là ưu điểm mà lập trình viên Javascript cảm thấy tự hào nhất so với các ngôn ngữ khác.

Sử dụng cùng một ngôn ngữ cho cả front-end và back-end là một lợi thế cho khả năng maintaince ứng dụng cũng như sự phối hợp giữa các thành viên trong team.

Bời vì lúc này, các thành viên trong team của bạn sẽ cùng sử dụng một ngôn ngữ Javascript, sử dụng cùng cấu trúc dữ liệu Javascript, syntax ngôn ngữ hay style convention… Tất cả góp phần đẩy nhanh tốc độ phát triển ứng dụng, sửa lỗi và co-work giữa các members.

3. Nodejs cực mềm dẻo

Nodejs không có nhiều quy tắc bắt buộc các lập trình viên phải tuân theo như Java. Bạn sẽ còn phải biết OOP là gì, không còn phải quan tâm SOLID là gì nữa…

Vì vậy, khi bạn sử dụng Nodejs, bạn sẽ tha hồ sáng tạo với nhiều cách viết code khác nhau.

Bản chất Nodejs là các module, chính các module là bộ phận xây dựng nên các tính năng hay ho cho ứng dụng Nodejs. Như ở bài viết trước: Bắt đầu học lập trình Nodejs, mình cũng có về NPM. Với NPM, bạn sẽ thoải mái sử dụng hàng trăm ngàn module miễn phí.

  So sánh Golang và NodeJS: Nên chọn nền tảng nào cho dự án của bạn?

  So sánh RDBMS và NoSQL. Nên sử dụng loại CSDL nào cho dự án của bạn?

#Nhược điểm của Node.js

1. Ít hiệu quả trong việc xử lý tác vụ cần nhiều CPU

Như các bạn cũng biết, Nodejs là môi trường xử lý đơn luồng và hướng sự kiện( event- driven) nên nó không thích hợp với các ứng dụng cần nhiều CPU. Những ứng dụng kiểu như xử lý ảnh, video… không nên sử dụng Nodejs để xây dựng.

Khi xử lý các tệp lớn hay thực hiện thao tác với đồ họa thì Nodejs có thể không phản hồi hoặc bị treo máy. Khi bạn xây dựng các ứng dụng kiểu như vậy thì nên nghĩ tới các công nghệ hỗ trợ đa luồng như PHP.

2. Thiếu sự kiểm duyệt chất lượng các module Nodejs

Mình cũng không biết cái này là ưu điểm hay nhược điểm nữa. Như ở trên mình có nói Nodejs được xây dựng dựa trên module. Thông qua NPM, bạn được phép sử dụng hàng ngàn module miễn phí.

Tuy nhiên, ngoài những core module như http, crypto… thì phần lớn module là do các bên 3rd-party phát triển. Mà hiện tại thì cộng đồng phát triển các module vẫn còn sơ khai, chất lượng các module thì “thượng vàng hạ cám”…

Ngay cả đến bạn cũng có thể dễ dàng tự tạo một module và publish lên NPM repository. Hệ sinh thái Nodejs vẫn chưa có một cơ chế kiểm duyệt chất lượng tốt.

Thế nên khi bạn sử dụng các module của Nodejs, bạn cần phải tỉnh táo mà lựa chọn cho mình module tốt nhất có thể.

Tuyển NodeJS lương cao hấp dẫn cho bạn

#Ưu điểm của PHP

Ưu điểm của PHP

1. Có nhiều frameworks tốt

PHP có rất nhiều platform tốt phục vụ việc xây dựng website như: WordPress, Joomla, Drupal… hay framework để tạo web app nhanh như Laravel, Symfony, ZendFramework…

Với sự hỗ trợ của các CMS như WordPress, bạn dễ dàng triển khai một blog hay một trang thương mại điện tử với đầy đủ chức năng.

PHP có lịch sử ra đời sớm nên cộng đồng cũng cực đông, có nhiều giải pháp mã nguồn mở được viết bằng PHP.

Ngoài ra, nếu bạn chọn PHP thì khả năng deploy cũng dễ hơn vì trên thị trường có nhiều nhà cung cấp hosting hỗ trợ PHP. Có thể kể đến các tên tuổi như: Hawkhost, A2 Hosting… Đây là ưu điểm dành cho nhà phát triển nhỏ lẻ với chi phí đầu tư ít.

Còn với Nodejs, bạn có rất ít lựa chọn hosting hỗ trợ, hoặc bạn chỉ có thể mua VPS và tự deploy mà thôi.

2. PHP là dành cho web

Không giống như Java hay Python hay những ngôn ngữ đa năng khác, ngay từ đầu PHP được thiết kế dành riêng cho thế giới web. Đó là lý do tại sao PHP có đầy đủ những tính năng để xử lý HTML, server và database (MYSQL nói riêng).

Với một giải pháp toàn diện cho máy chủ như PHP thì bạn không cần phải bận tâm về javascript trên trình duyệt vì tất cả các trang có thể được tạo và render trên máy chủ.

Điều này rất hữu ích nếu bạn muốn xử lý tập trung và tránh quá tải cho trình duyệt người dùng.

Tuy nhiên, việc render các trang phía máy chủ sẽ không phù hợp với các ứng dụng kiểu single page(Single Page Applications).

>>>Dành cho bạn muốn tìm hiểu lập trình web: Lập trình Front-end và những kinh nghiệm để đời

#Nhược điểm của PHP

1. Bị trộn lẫn giữa PHP và HTML

Cái đặc điểm này là thứ mình ghét nhất của PHP. Các bạn có để ý là chúng ta cứ phải mix code giữa PHP và HTML khi tạo trang web không?

Cá nhân mình thì muốn sự rạch ròi giữa PHP và các ngôn ngữ front-end (CSS, HTML, Javascript). Sự rạch ròi sẽ làm mình cảm thấy code thông thoáng và dễ debug hơn nhiều.

Chính vì đặc điểm này mà người ta nói PHP là ngôn ngữ không hỗ trợ tốt mô hình MVC. MVC là mô hình chuẩn của thế giới web rồi. Vì sự mix giữa PHP và HTML nên trong mô hình MVC, chúng ta sẽ khó phân tách rạch ròi giữa View và Controller.

Khi đó ứng dụng web sẽ khó mở rộng và thêm các tính năng mới sau này.

  Tìm hiểu về lập trình hướng đối tượng trong PHP

2. Sử dụng mô hình Client-Server cũ kĩ

PHP tuân theo mô hình client-server cổ điển. Tức là mọi request tới ứng dụng sẽ lần lượt thực hiện các bước như: khởi tạo ứng dụng, kết nối tới database, xử lý tác vụ, sau đó cấu hình thông số và render trang HTML để trả về cho browser.

Chính vì việc thực hiện tuần tự như vậy mà ứng dụng PHP sẽ chậm hơn đôi chút so với Nodejs. Khi mà Nodejs chỉ khởi tạo ứng dụng một lần và chạy mãi mãi.

Nhờ tính năng này mà Nodejs phù hợp hơn với các tính năng của HTML5 , AJAX  và websocket.

Mặc dù nhược điểm này của PHP có thể được giải quyết bằng Memcached. Tuy nhiên, Memcached không phải là một tiêu chuẩn của ngôn ngữ PHP.

Vậy giữa Nodejs và PHP thì đâu là lựa chọn đúng?

So sánh Nodejs và PHP

Để các bạn có thể trả lời những câu hỏi trên thì mình sẽ liệt kê một số câu hỏi phụ khác. Khi bạn trả lời được những câu hỏi đó tức là bạn sẽ câu trả lời cho câu hỏi chính: Chọn PHP hay Nodejs?

1. Điều khác biệt lớn nhất giữa Node.js và PHP là gì?

Là xử lý bất đồng bộ.

Trong khi Nodejs xử lý các tác vụ theo kiểu bất đồng bộ. Còn PHP thì tuần tự.

Trong lập trình, việc giao tiếp với các thiết bị ngoại vi như ổ cứng( HDD, SSD), network… hay thao tác với database gần như lúc nào cũng có.

Tuy nhiên chính các tác vụ này lại cần nhiều khoảng thời gian để thực hiện. Nếu trong khoảng thời gian nhàn rõi chờ đợi mà CPU không biết làm gì thì thật là lãng phí. Có thể mỗi khoảng thời gian đợi đó chỉ tính bằng ms (miliseconds) thôi nhưng đó là khoảng thời gian lớn đối với máy tính.

Nodejs đã tận dụng được thời gian nhàn rỗi đó của CPU, chính vì lẽ đó mà người ta bảo Nodejs nhanh là vậy.

PHP có cách tiếp cận khác đó là xử lý đa luồng (cũng là để tăng tốc độ ứng dụng). Tuy nhiên, đây không phải là tính năng chủ yếu của PHP nên ít người dùng.

2. Mình không có thời gian cho việc học code. Mình còn phải xem phim, lướt facebook, đi chơi với bạn gái… nền tảng nào sẽ dễ dàng hơn?

Câu trả lời là PHP, vì PHP có rất nhiều framework, cộng đồng developer lớn sẽ giúp đỡ bạn khi cần thiết.

3. Sử dụng Nodejs hay PHP thì chi phí phát triển ứng dụng web cao hơn?

Câu trả lời sẽ nêu tên chàng trai trẻ Node.js

Chân dài hơn, đẹp hơn nên bạn cũng sẽ phải tốn nhiều tiền hơn để nuôi em ấy. Chi phí cho nhân sự cũng như môi trường triển khai ứng dụng thì Nodejs có nhỉnh hơn PHP một chút.

Tuy nhiên nếu bạn còn lăn tăn về điều này hãy chú ý đến các ưu điểm của Node.js

#Kết luận

Như vậy, qua bài viết này chúng ta đã cùng nhau so sánh nodejs và PHP. Mỗi ngôn ngữ, mỗi nền tảng đều có ưu và nhược điểm riêng.

Để quyết định sử dụng công nghệ nào phụ thuộc vào mục đích và tình hình nhân sự của bạn.

Minh hi vọng bài viết sẽ có ích cho bạn. Đừng quên để lại comment ý kiến của bạn về vấn đề này nhé.

Hẹn gặp lại ở bài viết sau!

Bài viết gốc được đăng tải tại vntalking.com

Xem thêm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

8 thư viện Date Pickers tốt nhất cho React

thư viện Date Pickers tốt nhất cho React

Bài viết được sự cho phép của tác giả Duy Phan

Là developer, chúng ta luôn tìm cách để tiết kiệm thời gian cho các dự án của mình. Đó là lý do tại sao các thư viện được tạo ra để giảm bớt các khó khăn khi triển khai những thứ lặp đi lặp lại. Với các frontend framework như React, việc chia sẻ chức năng chung cho các dự án khác nhau trở nên dễ dàng hơn bao giờ hết.

Trong bài viết này, mình sẽ hướng dẫn bạn một số thư viện Date Pickers mà mình thấy thực sự hữu ích.

Lưu ý rằng chúng ta sẽ chỉ xem qua các thư viện đã được cập nhật gần đây. Điều này nhằm đảm bảo chúng sẽ hoạt động trơn tru trên dự án của bạn mà không phải tốn quá nhiều thời gian giải quyết các vấn đề.

Material UI Date/Time picker

Material UI Date/Time picker

Nếu bạn đang sử dụng Material UI làm theme chính trong dự án của mình, rất có thể bạn cũng sẽ phải sử dụng bộ chọn ngày và giờ của Material UI.

Mặc dù bạn bị hạn chế với Material Design, nó vẫn rất có thể tùy chỉnh. Bạn có thể tùy chỉnh các kiểu thông qua hàm createMuiTheme() do Material UI cung cấp.

Đây là component duy nhất trong danh sách này có chế độ xem đồng hồ. Điều này giúp bạn dễ dàng chọn thời gian ở cả chế độ xem trên máy tính để bàn và các thiết bị di động.

Các ví dụ trong tài liệu chính thức sử dụng date-fns làm thư viện datetime nhằm phân tích cú pháp và định dạng ngày nhưng bạn có thể sử dụng các thư viện datetime khác.

Nhược điểm duy nhất của thư viện này là nó không có bộ date range picker riêng (ít nhất là trên bản phát hành chính thức). Bộ date range picker vẫn đang được phát triển ở dạng alpha test.

Bộ date picker này không đi kèm với thư viện core của Material UI, do đó bạn cần cài đặt nó bằng lệnh sau:

npm install @material-ui/core date-fns @date-io/date-fns@^1.3.13 @material-ui/pickers --save

Lưu ý rằng đây là mã cho phiên bản stable hiện tại của Material UI. Khi phiên bản tiếp theo của Material UI đã stable thì bạn nên kiểm tra document trên trang Material UI và cập nhật chúng.

import React, { useState } from 'react';
import DateFnsUtils from '@date-io/date-fns';
import {
  MuiPickersUtilsProvider,
  KeyboardDatePicker,
} from '@material-ui/pickers';

export default function MaterialDatePicker() {

  const [selectedDate, setSelectedDate] = useState(new Date());

  const handleDateChange = (date) => {
    setSelectedDate(date);
  };

  return (
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <KeyboardDatePicker
        disableToolbar
        variant="inline"
        format="MM/dd/yyyy"
        margin="normal"
        id="date-picker-inline"
        label="Date picker inline"
        value={selectedDate}
        onChange={handleDateChange}
        KeyboardButtonProps={{
          'aria-label': 'change date',
        }}
      />
    </MuiPickersUtilsProvider>
  );
}

Tính năng:

  • Thiết kế đồng bộ với Material UI
  • Có bộ chọn ngày hoặc giờ riêng
  • Hỗ trợ đa ngôn ngữ

Bạn có thể download nó ở Material Date / Time pickers.

react-day-picker

react-day-picker

Đây là thư viện đơn giản nhất trong danh sách. Nếu bạn đang tìm kiếm một thư viện nhẹ cho dự án của mình thì đây sẽ là một sự lựa chọn khá tốt. Đừng để bị lừa bởi kích thước nhỏ gọn của nó, bởi nó có thể cung cấp hầu hết các chức năng phổ biến mà người dùng cần sử dụng thường ngày và hơn thế nữa.

Style của nó rất đơn giản nên dễ dàng tùy chỉnh. Nó đi kèm với các tiện ích datetime riêng để làm việc với datetime và bản địa hóa ngôn ngữ. Tuy nhiên, bạn có thể sử dụng các thư viện datetime khác nếu bạn muốn.

Cài đặt:

npm install react-day-picker --save

Ví dụ:

import React, { useState } from "react";
import DayPickerInput from "react-day-picker/DayPickerInput";
import "react-day-picker/lib/style.css";

export default function ReactDayPicker() {
  const [date, setDate] = useState(new Date());

  function onChange(date) {
    setDate(date);
  }

  return <DayPickerInput onDayChange={onChange} />;
}

Tính năng:

  • Date range picker
  • Hỗ trợ cách chọn lịch hoặc nhập text trực tiếp
  • Bản địa hóa
  • Dễ dàng tùy chỉnh
  • Đi kèm với bộ thư viện datetime riêng

Bạn có thể download nó ở react-day-picker.

  TOP 10 thư viện React Hook hữu ích lập trình viên nên biết

  Cần cải thiện kỹ năng JavaScript nào để làm React?

Carbon Design System date picker

Carbon Design System date picker

Carbon là hệ thống thiết kế mã nguồn mở của IBM. Nó sử dụng ngôn ngữ thiết kế của IBM làm nền tảng. Nó là một phiên bản của IBM tương đương với Nguyên tắc thiết kế Material Design của Google. Nhưng không giống với Material UI chỉ có sẵn cho React, Carbon cũng hỗ trợ Vue, Angular, Svelte và thậm chí cả JavaScript thuần. Vì vậy, nếu bạn muốn áp dụng thiết kế Carbon cho dự án tiếp theo của mình, thì bạn có thể sử dụng công cụ date picker này. Nếu không, hãy bỏ qua nó.

Về cốt lõi, nó là một hệ thống thiết kế nên nó thực sự tập trung rất nhiều vào tính nhất quán của thiết kế. Những thứ như sự liên kết của các thành phần và trạng thái khác nhau như thế nào được ưu tiên tối đa.

Nhược điểm của thư viện này là nó không có datetime picker. Nó cũng cho phép người dùng nhập ngày tháng theo cách thủ công, và điều này thường dễ bị nhầm lẫn vì vậy bạn sẽ phải tự mình thực hiện xác thực. Phía bên dưới, nó sử dụng flatpickr để bạn có thể tùy chỉnh đầy đủ bằng cách sử dụng các flatpickr options.

Cài đặt:

npm install carbon-components carbon-components-react carbon-icons --save

Ví dụ:

import React from 'react';
import { DatePickerInput } from 'carbon-components-react';

export default function CarbonDatePicker() {

  return (
    <DatePickerInput
        placeholder="mm/dd/yyyy"
        labelText="Date Picker label"
        id="date-picker-single"
        onChange={date => {
          console.log(date);
        }}
      />
    </DatePicker>  
  );
}

Tính năng:

  • Nhất quán về thiết kế
  • Date picker, time picker, date range picker
  • Bản địa hóa

Tham khảo:

wojtekmaj/react-date-picker

wojtekmaj/react-date-picker

Một trong những thư viện nhẹ nhất trong danh sách này. Bộ date picker này không phụ thuộc vào bất kỳ thư viện datetime nào để hoạt động. Nó có chế độ view calendar có thể tùy chỉnh để bạn có thể có chế độ xem tháng, năm, thập kỷ và thậm chí cả thế kỷ.

Nhược điểm của thư viện này là thiếu các mẫu ví dụ sử dụng. Nó chỉ có một mẫu ví dụ cho trường hợp sử dụng phổ biến nhất. Nếu trường hợp của bạn không phổ biến lắm, bạn sẽ cần phải tìm hiểu kỹ tài liệu hỗ trợ.

Cài đặt:

npm install react-date-picker --save

Ví dụ:

import React, { useState } from 'react';
import DatePicker from 'react-date-picker';

export default function MyDatePicker() {
  const [value, updateValue] = useState(new Date());

  const onChange = (date) => {
    updateValue(date);
  }

  return (
    <div>
      <DatePicker
        onChange={onChange}
        value={value}
      />
    </div>
  );
}

Tính năng:

  • Date picker, time picker, và date range picker
  • Bản địa hóa
  • Không phụ thuộc vào thư viện datetime nào khác

Nhà phát triển thư viện này đã tách các chức năng liên quan như time picker, datetime picker và date range picker thành từng gói riêng. Hãy nhớ kiểm tra chúng nếu bạn cần nhiều hơn là một date picker đơn giản:

Xem thêm các việc làm React hấp dẫn lương cao

airbnb/react-dates

airbnb/react-dates

Airbnb’s React Dates là một trong những thư viện cũ hơn trong danh sách này. Tuy nhiên, nó vẫn đang được tích cực maintenance. Nó có thể bản địa hóa, thân thiện với thiết bị di động và được xây dựng với khả năng thao tác dễ dàng. Nó dựa vào Moment.js để làm việc với datetime nên hơi nặng so với các thư viện nhẹ trong danh sách này.

Nhược điểm lớn nhất của thư viện này là chúng không có tài liệu và ví dụ sử dụng phù hợp. Tất cả những gì họ có là một Storybook và một vài ví dụ trên repo GitHub của họ. Vì vậy, nếu bạn là một người khá mới với React hoặc bạn không thích vọc code, bạn có thể bỏ qua component này.

Cài đặt:

npm install react-dates --save

Ví dụ:

import React, { useState } from "react";
import "react-dates/initialize";
import "react-dates/lib/css/_datepicker.css";
import { SingleDatePicker } from "react-dates";

export default function ReactdatesDatepicker() {
  const [date, setDate] = useState(null);
  const [isFocused, setIsFocused] = useState(false);

  function onDateChange(date) {
    setDate(date);
  }

  function onFocusChange({ focused }) {
    setIsFocused(focused);
  }

  return (
    <SingleDatePicker
      id="date_input"
      date={date}
      focused={isFocused}
      onDateChange={onDateChange}
      onFocusChange={onFocusChange}
    />
  );
}

Tính năng:

  • Date picker, date range picker
  • Bản địa hóa
  • Thân thiện với các thiết bị di động
  • Khả năng thao tác dễ dàng

Tham khảo:

React Datepicker by hackerone

React Datepicker by hackerone

Một date picker đơn giản và có thể tái sử dụng.

Điều tuyệt vời về thư viện này là tài liệu của nó có các ví dụ về tất cả các trường hợp sử dụng mà bạn có thể nghĩ đến. Những thứ như sử dụng tên class tùy chỉnh, đánh dấu các ngày cụ thể và thêm bộ lọc ngày và giờ đều có các ví dụ tương ứng. Các ví dụ của họ cũng sử dụng JavaScript thuần, có nghĩa là nhà phát triển có thể sử dụng bất kỳ thư viện datetime nào để thao tác ngày. Tuy nhiên, nó sử dụng date-fns để bản địa hóa.

Nhược điểm của thư viện này là giao diện người dùng mặc định của nó trông không đẹp. Nó được xây dựng để trở nên đơn giản, do đó nó giả định rằng developers sẽ phải tùy chỉnh các styles của riêng mình.

Cài đặt:

npm install react-datepicker --save

Ví dụ:

import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

export default function HackeroneDatepicker() {
  const [date, setDate] = useState(new Date());

  function onChange(date) {
    setDate(date);
  }

  return <DatePicker selected={date} onChange={onChange} />;
}

Tính năng:

  • Date picker, time picker, date range picker
  • Khả năng tùy chỉnh
  • Thao tác dễ dàng
  • Bản địa hóa

Tham khảo:

React Rainbow components date picker

React Rainbow components date picker

React Rainbow là một thư viện components UI giống như Material UI.

Nhược điểm chính của thư viện này là các components của nó không thể cài đặt riêng lẻ, vì vậy bạn phải sử dụng toàn bộ thư viện components UI để sử dụng các component date/time picker của nó.

Một nhược điểm khác là nó rất cố chấp về cách các thành phần sẽ trông và hoạt động như thế nào. Ví dụ: bạn không thể có inline date picker vì mọi thứ cần phải theo một modal.

Cài đặt:

npm install react-rainbow-components --save

Ví dụ:

import React, { useState } from "react";
import { DatePicker } from "react-rainbow-components";

export default function RainbowDatepicker() {
  const [date, setDate] = useState(null);

  function onChange(date) {
    setDate(date);
  }

  return (
    <DatePicker
      id="datePicker-1"
      value={date}
      onChange={onChange}
      label="DatePicker Label"
      formatStyle="large"
    />
  );
}

Tính năng:

  • Date picker, date range picker, time picker
  • Bản địa hóa
  • Thao tác dễ dàng
  • Hỗ trợ TypeScript

Tham khảo

Ant Design DatePicker

Ant Design DatePicker

Cũng giống như React Rainbow, date – time picker được đóng gói với toàn bộ thư viện components UI. Nó tuân theo Thông số kỹ thuật thiết kế của Ant vì vậy thực sự tập trung rất nhiều vào tính nhất quán của thiết kế để cung cấp trải nghiệm người dùng tốt hơn. Điều này có nghĩa là bạn sẽ chỉ nhận được đầy đủ lợi ích của việc sử dụng component này nếu bạn cũng sử dụng toàn bộ thư viện components UI.

Theo mặc định, date picker này sử dụng Moment.js để làm việc với datetime. Nhưng chúng cũng cung cấp một cách sử dụng một cách khác rất hay, đặc biệt nếu bạn lo lắng về kích thước file javascript.

Một điều tuyệt vời khác về nó (và tất cả các components của Ant Design) là chúng cung cấp các bản demo có thể chỉnh sửa thông qua CodeSandbox, CodePen và StackBlitz. Điều này làm cho việc test thử chúng khá dễ dàng bằng cách tạo và sử dụng bản demo.

Cài đặt:

npm install antd --save

Ví dụ:

import React, { useState } from "react";
import { DatePicker } from "antd";
import "antd/dist/antd.css";

export default function AntDatepicker() {
  const [date, setDate] = useState(new Date());

  function onChange(date, dateString) {
    setDate(date);
  }

  return <DatePicker onChange={onChange} />;
}

Tính năng:

  • Date picker, date range picker, và time picker
  • Đi kèm với bộ thư viện components UI
  • Hỗ trợ TypeScript
  • Bản địa hóa

Tham khảo

hypeserver/react-date-range

hypeserver/react-date-range

Nếu bạn đang tìm kiếm một công cụ date picker đẹp mắt với mà không cần tùy chỉnh CSS (hoặc chỉ một ít), thì bộ component này là dành cho bạn. Nhưng ngay cả trong trường hợp đó, thư viện này vẫn khả năng tùy chỉnh cao.

Nhược điểm duy nhất là tài liệu và ví dụ sử dụng. Nếu bạn đang tìm cách triển khai một số chức năng date range picker không phổ biené, thì bạn có thể gặp một chút rắc rối.

Cài đặt:

npm install react-date-range date-fns --save

Ví dụ:

import React, { useState } from "react";
import { Calendar } from "react-date-range";
import "react-date-range/dist/styles.css";
import "react-date-range/dist/theme/default.css";

export default function HypeserverDatepicker() {
  const [date, setDate] = useState(new Date());

  function onChange(date) {
    setDate(date);
  }

  return <Calendar date={date} onChange={onChange} />;
}

Tính năng

  • Date range picker
  • Calendar input
  • Dễ thao tác
  • Click và giữ để chọn

Tham khảo

Tổng kết

Như bạn đã thấy, có rất nhiều thư viện date picker bạn có thể chọn.

Một số bao gồm các component time picker trong khi một số chỉ có date picker.

Một số đơn giản với chỉ chức năng chọn ngày cơ bản, trong khi một số có rất nhiều tùy chọn mà bạn có thể sử dụng để tùy chỉnh trải nghiệm người dùng.

Cuối cùng, có những thứ tích hợp với các thư viện components UI lớn như Material UI và Ant Design.

Các thư viện Date Pickers tốt nhất cho React

Bài viết gốc được đăng tải tại duypt.dev

Xem thêm:

Tìm việc làm IT mới nhất trên TopDev

C++ là gì? Tổng hợp kiến thức và ứng dụng của C++

c++ là gì
c++ là gì

C++ là gì? Có nên học ngôn ngữ lập trình C++? Cùng TopDev tìm hiểu các kiến thức cơ bản về ngôn ngữ C++ cũng như điểm qua các ứng dụng có thể viết bằng C++ cũng như cơ hội việc làm hiện nay.

c++ là gì
Ngôn ngữ lập trình C++ là gì?

C++ là gì?

C++ (còn được viết là C plus plus hay CPP) là một ngôn ngữ lập trình hướng đối tượng (OOP) được nhiều người xem là ngôn ngữ tốt nhất để tạo các ứng dụng quy mô lớn. C++ là một phần mở rộng của ngôn ngữ C.

C++ là một loại ngôn ngữ lập trình bậc trung (middle-level), mang cả tính chất của ngôn ngữ lập trình bật thấp như pascal hay C và ngôn ngữ lập trình bậc cao (C#, Java, Python…)

C++ cho phép các nhà phát triển phần mềm định nghĩa các kiểu dữ liệu của riêng họ và thao tác chúng bằng các hàm và phương thức. Nó cũng cho phép lập trình cấp thấp và cung cấp quyền truy cập vào bộ nhớ, giúp thực thi mã nhanh chóng và hiệu quả. Nó cũng hỗ trợ lập trình tổng quát bằng cách sử dụng các mẫu, cho phép mã được viết dưới dạng tổng quát và tái sử dụng cho các kiểu dữ liệu khác nhau.

C++ được sử dụng trong các lĩnh vực như phần mềm hệ thống, phát triển game, hệ thống nhúng, tính toán khoa học và các ứng dụng hiệu suất cao. Thư viện chuẩn của C++ cung cấp một loạt các tiện ích và hàm mã hóa, giúp phát triển các hệ thống phần mềm phức tạp dễ dàng hơn. C++ có thể chạy trên nhiều nền tảng, bao gồm Linux, Mac và Windows.

Lịch sử hình thành của C++

C++ được phát triển bởi nhà khoa học máy tính Đan Mạch Bjarne Stroustrup vào năm 1983 tại Bell Labs như một phần mở rộng của ngôn ngữ lập trình C. Stroustrup muốn kết hợp các tính năng của lập trình hướng đối tượng từ ngôn ngữ Simula với hiệu suất và tính linh hoạt của C.

Phiên bản đầu tiên của C++ được phát hành vào năm 1985. C++ được chuẩn hóa lần đầu tiên vào năm 1998 bởi Tổ chức Tiêu chuẩn hóa Quốc tế (ISO) dưới tên ISO/IEC 14882:1998. Các phiên bản tiếp theo bao gồm C++03, C++11, C++14, C++17 và gần đây nhất là C++20 được phát hành vào tháng 12 năm 2020. C++ đã trở thành ngôn ngữ lập trình mạnh mẽ và linh hoạt, được sử dụng rộng rãi trong nhiều lĩnh vực khác nhau.

C++ viết được các chương trình gì?

Ứng dụng của ngôn ngữ C++
Ứng dụng của ngôn ngữ C++

C++ được sử dụng theo nhiều cách khác nhau để tận dụng tính linh hoạt và hiệu suất của nó. Một số ứng dụng chính của C++ bao gồm:

  • Hệ điều hành (OS): Khả năng cấp thấp của C++ cho phép quản lý bộ nhớ hiệu quả và kiểm soát tài nguyên hệ thống, phù hợp cho phát triển các hệ điều hành.
  • Trò chơi và đồ họa: Hiệu suất cao của C++ và khả năng tương tác với phần cứng làm cho nó là lựa chọn tốt cho các engine game như Unreal Engine của Epic Games và Unity của Unity Technologies, cũng như các tác vụ lập trình đồ họa như render thời gian thực, xử lý hình ảnh và mô phỏng vật lý.
  • Hệ thống nhúng: C++ thường được sử dụng trong phát triển các hệ thống nhúng, như thiết bị y tế, hệ thống ô tô và các thiết bị Internet of Things.
  • Thư viện phần mềm: C++ là nền tảng cho nhiều thư viện cấp cao, như Boost và Thư viện Mẫu Chuẩn (STL), cung cấp các cấu trúc dữ liệu và thuật toán tổng quát.
  • Tính toán hiệu suất cao (HPC): C++ phù hợp cho các ứng dụng HPC đòi hỏi hiệu suất tính toán tối đa và xử lý song song, thường được sử dụng trong mô phỏng khoa học, phân tích số và mô hình toán học.
  • Phát triển web: Mặc dù C++ không thường được sử dụng cho phát triển web, nó đóng vai trò quan trọng trong backend của các ứng dụng web, như máy chủ web và các giao thức mạng.
  • Lập trình hệ thống: C++ thường được sử dụng cho các tác vụ lập trình hệ thống, như driver thiết bị, giao thức mạng và tiện ích hệ thống.

Ưu điểm và nhược điểm của C++

Ưu điểm

Học C++ vẫn rất quan trọng và hữu ích trong thời điểm hiện tại vì các lý do sau:

  1. Hiệu suất cao: C++ cung cấp khả năng thao tác bộ nhớ cấp thấp và kiểm soát tối ưu tài nguyên hệ thống, phù hợp cho các ứng dụng yêu cầu hiệu suất cao như game, hệ thống nhúng và phần mềm hệ thống.
  2. Tính linh hoạt: Hỗ trợ lập trình hướng đối tượng, tổng quát và hàm, giúp giải quyết nhiều loại vấn đề khác nhau.
  3. Nền tảng vững chắc: Là nền tảng cho nhiều thư viện và framework, hỗ trợ phát triển phần mềm phức tạp.
  4. Ứng dụng rộng rãi: Sử dụng trong nhiều lĩnh vực như hệ điều hành, trình biên dịch, phần mềm mô phỏng khoa học, tài chính, và nhiều lĩnh vực khác.
  5. Tiêu chuẩn hóa và cộng đồng: C++ được tiêu chuẩn hóa bởi ISO và có một cộng đồng lập trình viên lớn hỗ trợ.

Nhược điểm

  1. Độ phức tạp và khó học: C++ có nhiều tính năng và cú pháp phức tạp, làm cho việc học và sử dụng trở nên khó khăn, đặc biệt đối với người mới bắt đầu.
  2. Quản lý bộ nhớ thủ công: C++ yêu cầu lập trình viên phải tự quản lý bộ nhớ, dễ dẫn đến rò rỉ bộ nhớ và các vấn đề khác nếu không được xử lý đúng cách.
  3. Rủi ro bảo mật: Truy cập trực tiếp vào bộ nhớ có thể gây ra các lỗi bảo mật nếu không được kiểm soát cẩn thận.
  4. Không có thu gom rác: Thiếu cơ chế tự động giải phóng bộ nhớ, lập trình viên phải tự tay giải phóng bộ nhớ không cần thiết.
  5. Cú pháp phức tạp: Cú pháp của C++ phức tạp hơn nhiều so với các ngôn ngữ lập trình khác, làm cho việc đọc và viết mã tốn nhiều thời gian hơn.
  6. Thời gian biên dịch lâu: C++ thường có thời gian biên dịch lâu hơn so với các ngôn ngữ có kiểu động hoặc biên dịch ngay lập tức.

Công cụ C++ tiêu biểu

Một số công cụ và framework cho phát triển C++ bao gồm:

  • Môi trường phát triển tích hợp (IDE):
    • Microsoft Visual Studio: Cung cấp công cụ debug và quản lý dự án.
    • JetBrains CLion: IDE đa nền tảng với công cụ tái cấu trúc mã.
    • Eclipse CDT: IDE mã nguồn mở với điều hướng mã và công cụ quản lý dự án.
  • Hệ thống build:
    • CMake: Công cụ mã nguồn mở giúp đơn giản hóa quá trình build.
    • GNU Make: Ứng dụng mã nguồn mở hỗ trợ build tự động.
  • Framework kiểm thử:
    • Google Test: Cung cấp các macro và tiện ích kiểm thử.
    • Catch2: Framework nhẹ nhàng với cú pháp định nghĩa test case đơn giản.
    • Boost.Test: Một phần của thư viện Boost hỗ trợ nhiều kiểu kiểm thử.
  • Công cụ profiling:
    • Valgrind: Công cụ mã nguồn mở phân tích hiệu suất và phát hiện rò rỉ bộ nhớ.
    • Intel VTune Amplifier: Giúp xác định các điểm nghẽn hiệu suất.
  • Công cụ tài liệu:
    • Doxygen: Tự động tạo tài liệu mã nguồn từ các chú thích.
  • Trình quản lý gói:
    • Conan: Trình quản lý gói C/C++ phi tập trung.
    • vcpkg: Trình quản lý gói đa nền tảng của Microsoft.

Lương và Cơ Hội Việc Làm Lập Trình C++ tại Việt Nam

Mức Lương Lập Trình Viên C++

Mức lương của lập trình viên C++ tại Việt Nam phụ thuộc vào nhiều yếu tố như kinh nghiệm, vị trí làm việc và quy mô công ty. Dưới đây là một số mức lương phổ biến:

  • Mức lương trung bình: Lập trình viên C++ trung bình nhận khoảng 20-30 triệu VND/tháng.
  • Mức lương cao: Đối với các vị trí cao cấp hoặc ở các công ty lớn, mức lương có thể lên đến 50-60 triệu VND/tháng hoặc cao hơn.
  • Fresher: Mức lương cho lập trình viên mới ra trường (fresher) thường dao động từ 10-15 triệu VND/tháng.

Các công ty như NAKIVO, Pentalog Việt Nam, LG Electronics Development Vietnam và FOIS VIỆT NAM là những đơn vị trả lương cao nhất cho lập trình viên C++ với mức lương có thể lên tới 64 triệu VND/tháng​ (theo Tổng quan mức thu nhập lập trình viên – TopDev 2023)​.

Cơ Hội Việc Làm

Lập trình viên C++ có nhiều cơ hội việc làm trong các lĩnh vực khác nhau:

  • Phát triển phần mềm hệ thống: C++ được sử dụng rộng rãi trong phát triển hệ điều hành và phần mềm nhúng.
  • Game Development: Các công ty game lớn như VNG và Gameloft thường xuyên tuyển dụng lập trình viên C++ cho việc phát triển các trò chơi.
  • Tài chính và ngân hàng: Các hệ thống tài chính yêu cầu hiệu suất cao và độ tin cậy lớn thường sử dụng C++.
  • Công nghệ ô tô: C++ được sử dụng trong phát triển phần mềm cho xe tự lái và các hệ thống hỗ trợ lái xe.

Qua bài viết của TopDev, bạn chắc hẳn cũng đã tích lũy được các kiến thức căn bản về C++. Theo báo cáo từ các trang tuyển dụng, hiện có rất nhiều công ty tại Việt Nam đang tìm kiếm lập trình viên C++ với mức lương cạnh tranh và cơ hội thăng tiến tốt​.

Xem việc làm C++ tại TopDev

Tài liệu tham khảo: www.techtarget.com/searchdatamanagement/definition/C

40+ câu hỏi phỏng vấn OOP không thể bỏ qua (Phần 2)

câu hỏi phỏng vấn OOP

Bài viết được sự cho phép của tác giả Nguyễn Thành Nam

II. Câu hỏi phỏng vấn về Lập trình hướng đối tượng (OOP) (Phần 2)

20. Các kiểu constructor trong C++?

Các constructor có các phân loại phổ biến như sau:

  • Default Constructor: Hàm khởi tạo mặc định không nhận bất kỳ tham số nào.
class ABC
{
    int x;

    ABC()
    {
        x = 0;
    }
};
  • Parameterized constructor: hàm khởi tạo này nhận về một hay nhiều tham số.
class ABC
{
    int x;

    ABC(int y)
    {
        x = y;
    }
};
  • Copy constructor: là một hàm thành viên khởi tạo một đối tượng bằng cách sử dụng một đối tượng khác của cùng một lớp.
class ABC
{
    int x;

    ABC(int y)
    {
        x = y;
    }
    // Copy constructor
    ABC(ABC abc)
    {
        x = abc.x;
    }
};

21. Copy Constructor là gì?

Copy Constructor hay hàm khởi tạo sao chép, có mục đích là sao chép một đối tượng sang một đối tượng khác. Điều đó có nghĩa là một phương thức khởi tạo sao chép sẽ sao chép một đối tượng và các giá trị của nó, vào một đối tượng khác, với điều kiện là cả hai đối tượng đều thuộc cùng một lớp.

22. Destructor là gì?

Trái ngược với các hàm khởi tạo, khởi tạo các đối tượng và chỉ định không gian cho chúng, các hàm hủy cũng là các phương thức đặc biệt. Nhưng hàm hủy giải phóng tài nguyên và bộ nhớ được sử dụng bởi một đối tượng. Bộ hủy được tự động gọi khi một đối tượng đang bị hủy.

23. Có phải lớp và cấu trúc giống nhau?

Không. Lớp và cấu trúc không giống nhau. Mặc dù chúng có vẻ giống nhau, nhưng chúng có những điểm khác biệt khiến chúng trở nên khác biệt.

Ví dụ, cấu trúc được lưu trong bộ nhớ stack, trong khi lớp được lưu trong bộ nhớ heap. Ngoài ra, tính trừu tượng hóa dữ liệu không thể có trong cấu trúc, nhưng với lớp, tính trừu tượng được sử dụng chủ yếu.

24. Tính kế thừa (inheritance)?

Kế thừa (inheritance) là một trong những đặc điểm chính của lập trình hướng đối tượng, theo đó một thực thể kế thừa một số đặc điểm và hành vi của một thực thể khác và biến chúng thành của riêng mình. Kế thừa giúp cải thiện và tạo điều kiện sử dụng lại code.

Ta sẽ giải thích bằng một ví dụ dễ hiểu. Ta có ba phương tiện khác nhau – xe hơi, xe tải hoặc xe buýt. Ba loại này hoàn toàn khác nhau với những đặc điểm và hành vi cụ thể của riêng chúng. Nhưng ở cả ba, bạn sẽ tìm thấy một số yếu tố chung, như vô lăng, chân ga, ly hợp, phanh, v.v.

Mặc dù những yếu tố này được sử dụng trên các loại xe khác nhau, chúng vẫn có những đặc điểm chung của tất cả các loại xe. Điều này đạt được nhờ vào sự kế thừa. Xe hơi, xe tải và xe buýt đều được thừa hưởng các tính năng như vô lăng, chân ga, ly hợp, phanh, v.v. và sử dụng chúng như của riêng mình. Do đó, chúng không phải tạo các thành phần này từ đầu, nhờ thế tạo điều kiện sử dụng lại code.

Tính kế thừa (inheritance)

25. Có bất kỳ hạn chế nào của kế thừa không?

Có. Với nhiều quyền lực hơn đi kèm với nhiều phức tạp hơn. Kế thừa là một tính năng rất mạnh trong OOP, nhưng nó cũng có một số hạn chế. Kế thừa cần thêm thời gian để xử lý, vì nó cần điều hướng qua nhiều lớp để triển khai.

Ngoài ra, các lớp liên quan đến Kế thừa – lớp cơ sở và lớp con, được kết hợp rất chặt chẽ với nhau.

Vì vậy, nếu một người cần thực hiện một số thay đổi, họ có thể cần thực hiện các thay đổi lồng nhau trong cả hai lớp. Kế thừa cũng có thể phức tạp để thực hiện. Vì nếu không được triển khai chính xác, có thể dẫn đến lỗi không mong muốn hoặc kết quả đầu ra không chính xác.

26. Các kiểu kế thừa khác nhau?

  • Đơn kế thừa (Single inheritance)
  • Đa kế thừa (Multiple inheritance)
  • Kế thừa đa cấp (Multi-level inheritance)
  • Kế thừa phân cấp (Hierarchical inheritance)
  • Siêu kế thừa (Hybrid inheritance)

Các kiểu kế thừa khác nhau

27. Lớp con là gì?

Lớp con là một phần của kế thừa. Lớp con là một thực thể, được kế thừa từ một lớp khác.

28. Lớp cha là gì?

Lớp cha là một phần của kế thừa. Lớp cha là một thực thể, cho phép các lớp con kế thừa từ chính nó.

Lớp cha là gì

29. Interface là gì?

Interface đề cập đến một loại lớp đặc biệt, chứa các phương thức, nhưng không phải là định nghĩa của chúng. Chỉ cho phép khai báo các phương thức bên trong một interface. Bạn không thể tạo các đối tượng bằng cách dùng interface. Thay vào đó, bạn cần triển khai interface đó và xác định các phương pháp để triển khai chúng.

30. Đa hình tĩnh là gì?

Còn gọi là đa hình thời gian biên dịch. Đa hình tĩnh là tính năng mà một đối tượng được liên kết với hàm hoặc toán tử tương ứng dựa trên các giá trị trong thời gian biên dịch. Đa hình thời gian tĩnh hoặc thời gian biên dịch có thể đạt được thông qua nạp chồng phương thức hoặc nạp chồng toán tử.

31. Đa hình động là gì?

Còn gọi là đa hình thời gian chạy, theo đó việc triển khai thực sự của hàm được quyết định trong thời gian chạy hoặc thực thi. Tính đa hình động hoặc thời gian chạy có thể đạt được với sự trợ giúp của ghi đè phương thức.

32. Sự khác biệt giữa nạp chồng (Overloading) và ghi đè (Overriding)?

Nạp chồng (Overloading) là một tính năng đa hình thời gian biên dịch, trong đó một thực thể có nhiều triển khai có cùng tên. Ví dụ: nạp chồng phương thức và nạp chồng toán tử.

Trong khi ghi đè (Overriding) là một tính năng đa hình thời gian chạy trong đó một thực thể có cùng tên, nhưng việc triển khai của nó thay đổi trong quá trình thực thi. Ví dụ: ghi đè phương thức.

33. Quá trình trừu tượng hóa dữ liệu được thực hiện như thế nào?

Sự trừu tượng hóa dữ liệu được thực hiện với sự trợ giúp của các phương thức trừu tượng hoặc các lớp trừu tượng.

34. Lớp trừu tượng là gì?

Một lớp trừu tượng là một lớp đặc biệt chứa các phương thức trừu tượng. Đặc trưng của lớp trừu tượng là các phương thức trừu tượng bên trong nó không được thực thi mà chỉ được khai báo. Do đó, khi một lớp con kế thừa lớp trừu tượng và cần sử dụng các phương thức trừu tượng của nó, chúng cần phải định nghĩa và triển khai chúng.

35. Một lớp trừu tượng khác với một interface như thế nào?

Interface và lớp trừu tượng đều là những kiểu lớp đặc biệt chỉ chứa phần khai báo các phương thức chứ không chứa phần thực thi của chúng. Nhưng interface hoàn toàn khác với một lớp trừu tượng. Sự khác biệt chính của cả hai là, khi một interface được triển khai, lớp con phải xác định tất cả các phương thức của nó và cung cấp cách triển khai của nó. Trong khi đó khi một lớp trừu tượng được kế thừa, lớp con không cần cung cấp định nghĩa về phương thức trừu tượng của nó, cho đến khi lớp con sử dụng nó.

Ngoài ra, một lớp trừu tượng có thể chứa các phương thức trừu tượng cũng như các phương thức không trừu tượng.

36. Các chỉ định truy cập là gì và ý nghĩa của chúng?

Các chỉ định truy cập là một loại từ khóa đặc biệt, được sử dụng để kiểm soát hoặc chỉ định khả năng truy cập của các thực thể như lớp, phương thức, v.v. Một số từ chỉ định truy cập hoặc công cụ sửa đổi truy cập bao gồm “private”, “public”, v.v… Các chỉ định truy cập này cũng đóng một vai trò rất quan trọng trong việc đạt được tính đóng gói – một trong những tính năng chính của OOP.

37. Ngoại lệ (Exception) là gì?

Một ngoại lệ (Exception) có thể được coi là một sự kiện đặc biệt, xuất hiện trong quá trình thực hiện một chương trình trong thời gian chạy, khiến việc thực thi bị tạm dừng. Lý do cho ngoại lệ chủ yếu là do một vị trí trong chương trình, nơi người dùng muốn làm điều gì đó mà chương trình không được chỉ định, chẳng hạn như đầu vào không mong muốn.

38. Xử lý ngoại lệ như thế nào?

Không ai muốn phần mềm của mình bị lỗi hoặc gặp sự cố. Các trường hợp ngoại lệ là lý do chính dẫn đến lỗi phần mềm. Các ngoại lệ có thể được xử lý trước trong chương trình và ngăn việc thực thi dừng lại. Đây được gọi là xử lý ngoại lệ.

Vì vậy, xử lý ngoại lệ là cơ chế xác định các trạng thái không mong muốn mà chương trình có thể có và xác định các kết quả mong muốn của các trạng thái đó.

Try-catch là phương pháp phổ biến nhất được sử dụng để xử lý các ngoại lệ trong chương trình

39. Garbage collection trong OOP là gì?

Lập trình hướng đối tượng xoay quanh các thực thể như các đối tượng. Mỗi đối tượng sử dụng bộ nhớ và có thể có nhiều đối tượng của một lớp. Vì vậy, nếu các đối tượng này và dữ liệu của chúng không được xử lý đúng cách, thì nó có thể dẫn đến một số lỗi liên quan đến bộ nhớ và hệ thống có thể bị lỗi.

Bộ dọn rác (garbage collection) đề cập đến cơ chế xử lý bộ nhớ trong chương trình. Thông qua việc thu gom rác, bộ nhớ không mong muốn sẽ được giải phóng bằng cách loại bỏ các đối tượng không còn cần thiết.

40. Có thể chạy ứng dụng Java mà không triển khai các khái niệm OOP?

Không. Các ứng dụng Java dựa trên các mô hình lập trình hướng đối tượng hoặc khái niệm OOP, do đó chúng không thể được triển khai nếu không có nó.

Tuy nhiên, mặt khác, C++ có thể được thực hiện mà không cần OOP, vì nó cũng hỗ trợ mô hình lập trình cấu trúc giống C.

Bài viết gốc được đăng tải tại blog.thanhnamnguyen.dev

Xem thêm: 

Xem thêm việc làm công nghệ hấp dẫn trên TopDev

40+ câu hỏi phỏng vấn OOP không thể bỏ qua (Phần 1)

câu hỏi phỏng vấn OOP

Bài viết được sự cho phép của tác giả Nguyễn Thành Nam

I. Lập trình hướng đối tượng là gì?

OOP (Object-Oriented Programming) là một mô hình lập trình để giải quyết vấn đề xoay quanh khái niệm “Đối tượng“. Đối tượng có thể được xem như là các thể hiện của thực thế ở thế giới thực như là lớp, chúng chứa một số đặc điểm và hành vi được chỉ định trong lớp mẫu.

Ở các ngôn ngữ đơn giản, một lớp có thể là một bản mẫu, dựa trên nó để tạo ra các đối tượng. Thế nên Đối tượng có thể được xem như là một thể hiện của một lớp và thỉnh thoảng nó có thể được gọi là “thực thể”. Các thuật ngữ đặc trưng ám chỉ đối tượng đó là gì, và hành vi chỉ đối tượng đó như thế nào.

Ví dụ, ta tạo mô hình OOP với một chiếc xe:

  • Lớp: mẫu xe cụ thể như Audi A4, BMW I8, Maruti Suzuki Vitara Brezza,…
  • Đối tượng: Bất kỳ chiếc xe cụ thể nào, như xe của bạn
  • Đặc trưng: Màu sắc của xe? Số khung xe của bạn là gì?
  • Hành vi: Xe chạy như thế nào? Làm thế nào để chuyển số?

Đặc trưng có thể hiểu là dữ liệu, thuộc tính còn hành vi là chức năng, phương thức trong ngôn ngữ lập trình.

Khái niệm “đối tượng” cho phép mô hình OOP dễ dàng truy cập, sử dụng và sửa đổi dữ liệu thực thể và phương thức, tương tác với các đối tượng khác và xác định các phương thức trong thời gian chạy (trong quá trình thực thi chương trình). Điều này mang lại ý nghĩa cho mô hình OOP và làm cho nó trở nên đa dạng trong việc triển khai.

Trên thực tế, mô hình OOP rất phổ biến, đến nỗi nhiều ngôn ngữ lập trình được sử dụng rộng rãi nhất đều hỗ trợ và sử dụng mô hình Lập trình hướng đối tượng hoặc OOP này, chẳng hạn như Java, C++, Python, C#, v.v.

II. Câu hỏi phỏng vấn về Lập trình hướng đối tượng (OOP)

1. Thuật ngữ OOP có nghĩa là gì?

OOP đề cập đến Lập trình hướng đối tượng. Đó là mô hình lập trình được xác định bằng cách sử dụng các đối tượng. Các đối tượng có thể được coi là các thể hiện trong thế giới thực của các thực thể như lớp, có một số đặc điểm và hành vi

2. Tại sao cần OOP?

Có nhiều lý do khiến OOP hầu hết được ưa thích, nhưng quan trọng nhất trong số đó là:

  • OOP giúp người dùng hiểu phần mềm một cách dễ dàng, mặc dù họ không biết cách triển khai thực tế.
  • Với OOP, khả năng đọc, hiểu và khả năng bảo trì của code tăng lên gấp nhiều lần.
  • Ngay cả những phần mềm rất lớn cũng có thể được viết và quản lý dễ dàng bằng OOP.

3. Một số ngôn ngữ lập trình hướng đối tượng

Các ngôn ngữ lập trình sử dụng và tuân theo mô hình lập trình hướng đối tượng hoặc OOP, được gọi là ngôn ngữ lập trình hướng đối tượng. Một số ngôn ngữ lập trình hướng đối tượng chính bao gồm:

  • Java
  • C++
  • Javascript
  • Python
  • PHP

4. Một số mô hình lập trình khác ngoài OOP là gì?

Mô hình lập trình đề cập đến phương pháp phân loại ngôn ngữ lập trình dựa trên các tính năng của chúng. Chủ yếu có hai loại Mô hình lập trình:

  • Mô hình lập trình mệnh lệnh
  • Mô hình lập trình khai báo

Bây giờ, các mô hình này có thể được phân loại thêm dựa trên:

  • Mô hình lập trình mệnh lệnh: Lập trình mệnh lệnh tập trung vào CÁCH thực thi logic chương trình và định nghĩa luồng điều khiển là các câu lệnh thay đổi trạng thái chương trình. Điều này có thể được phân loại thêm là:
    • Mô hình lập trình hướng thủ tục: Lập trình theo thủ tục xác định các bước mà một chương trình phải thực hiện để đạt được trạng thái mong muốn, thường được đọc theo thứ tự từ trên xuống dưới.
    • Lập trình hướng đối tượng hoặc OOP: Lập trình hướng đối tượng (OOP) tổ chức các chương trình dưới dạng các đối tượng, chứa một số thuộc tính và có một số hành vi.
    • Lập trình song song: Mô hình lập trình song song chia một nhiệm vụ thành các nhiệm vụ con và tập trung vào việc thực hiện chúng đồng thời cùng một lúc.
  • Mô hình lập trình khai báo: Lập trình khai báo tập trung vào CÁI GÌ để thực thi và định nghĩa logic chương trình, nhưng không phải là một luồng điều khiển chi tiết. Mô hình khai báo có thể được phân loại thêm thành:
    • Mô hình lập trình logic: Mô hình lập trình logic dựa trên logic hình thức, đề cập đến một tập hợp các câu diễn đạt các dữ kiện và quy tắc về cách giải quyết một vấn đề
    • Mô hình lập trình chức năng: Mô hình lập trình chức năng là mô hình lập trình trong đó các chương trình được xây dựng bằng cách áp dụng và soạn thảo các hàm.
    • Mô hình lập trình cơ sở dữ liệu: Mô hình lập trình cơ sở dữ liệu được sử dụng để quản lý dữ liệu và thông tin có cấu trúc như trường, bản ghi và file.

OOP

5. Lập trình có cấu trúc nghĩa là gì?

Lập trình có cấu trúc đề cập đến phương pháp lập trình bao gồm một luồng điều khiển hoàn toàn có cấu trúc. Ở đây cấu trúc đề cập đến một khối, chứa một tập hợp các quy tắc và có một luồng điều khiển cuối cùng, chẳng hạn như (if/then/else), (while và for), cấu trúc khối và chương trình con.

Gần như tất cả các mô hình lập trình đều bao gồm Lập trình có cấu trúc, bao gồm cả mô hình OOP.

6. Các tính năng chính của OOP?

OOP hoặc Lập trình hướng đối tượng chủ yếu bao gồm bốn tính năng dưới đây và đảm bảo rằng bạn không bỏ lỡ bất kỳ tính năng nào sau đây:

  • Tính kế thừa
  • Tính đóng gói
  • Tính đa hình
  • Tính trừu tượng

Các tính năng chính của OOP

7. Lợi ích khi sử dụng OOP?

  • OOP rất hữu ích trong việc giải quyết các vấn đề ở mức độ rất phức tạp.
  • Các chương trình có độ phức tạp cao có thể được tạo, xử lý và bảo trì dễ dàng bằng cách sử dụng lập trình hướng đối tượng.
  • OOP thúc đẩy việc tái sử dụng code, do đó giảm bớt sự dư thừa.
  • OOP cũng giúp ẩn những chi tiết không cần thiết với sự trợ giúp của tính trừu tượng .
  • OOP dựa trên cách tiếp cận từ dưới lên, không giống như mô hình lập trình cấu trúc, sử dụng cách tiếp cận từ trên xuống.
  • Tính đa hình cung cấp rất nhiều tính linh hoạt trong các OOP.

8. Tại sao OOP lại phổ biến như vậy?

Mô hình lập trình OOP được coi là một phong cách lập trình tốt hơn. Nó không chỉ giúp dễ dàng viết một đoạn code phức tạp mà còn cho phép người dùng xử lý và duy trì chúng một cách dễ dàng. Không chỉ vậy, các tính năng chính của OOP – Trừu tượng hóa, Đóng gói, Kế thừa và Đa hình, giúp lập trình viên dễ dàng giải quyết các tình huống phức tạp. Do đó, OOP rất phổ biến.

9. Lớp (class) là gì?

Một lớp (class) có thể được hiểu là một khuôn mẫu hoặc một bản thiết kế, chứa một số giá trị, được gọi là thuộc tính và một số bộ quy tắc, được gọi là hành vi hoặc chức năng. Vì vậy, khi một đối tượng được tạo, nó sẽ tự động lấy thuộc tính và phương thức đã được định nghĩa trong lớp.

Do đó, về cơ bản lớp là một khuôn mẫu hoặc bản thiết kế cho các đối tượng. Ngoài ra, người ta có thể tạo bao nhiêu đối tượng tùy thích dựa trên một lớp.

Ví dụ: đầu tiên, mẫu của một chiếc ô tô được tạo. Sau đó, nhiều chiếc xe được tạo ra dựa trên mẫu đó.

10. Đối tượng (object) là gì?

Một đối tượng (object) đề cập đến thực thể của lớp, bao gồm toàn bộ các thuộc tính và phương thức được xác định trong lớp mẫu. Trong thực tế, một đối tượng là một thực thể thực tương tác với người dùng trong khi lớp là bản thiết kế cho đối tượng đó. Vì vậy, các đối tượng tiêu thụ không gian và có một số hành vi đặc trưng.

  Object Prototype Javascript – Công cụ hỗ trợ OOP cho JS

  JavaScript là ngôn ngữ lập trình hướng đối tượng (OOP)

11. Tính đóng gói (encapsulation) là gì?

Tính đóng gói (encapsulation)

Người ta có thể hình dung đóng gói là phương pháp đưa mọi thứ cần thiết để thực hiện công việc vào bên trong một viên thuốc và trình bày viên thuốc đó cho người dùng. Điều đó có nghĩa là bằng đóng gói, tất cả các dữ liệu và phương thức cần thiết được liên kết với nhau và tất cả các chi tiết không cần thiết được ẩn đối với người dùng bình thường. Vì vậy, đóng gói là quá trình liên kết các thuộc tính và các phương thức của một chương trình với nhau để thực hiện một công việc cụ thể, mà không để lộ các chi tiết không cần thiết.

Đóng gói có thể được xác định theo hai cách:

  • Data hiding: đóng gói là quá trình ẩn thông tin không mong muốn, hạn chế các truy cập đến thuộc tính của đối tượng.
  • Data binding: là quá trình liên kết các thuộc tính và các phương thức với nhau như một tổng thể.

12. Tính đa hình (polymorphism) là gì?

Đa hình đề cập đến một thứ có thể có nhiều hình dạng.

Tính đa hình (polymorphism)

Trong OOP, đa hình đề cập đến quá trình mà một số code, dữ liệu, phương thức hoặc đối tượng hoạt động khác nhau trong các trường hợp hoặc ngữ cảnh khác nhau. Đa hình thời gian biên dịch và đa hình thời gian chạy là hai loại đa hình trong các ngôn ngữ OOP.

13. Sự khác nhau giữa đa hình thời gian biên dịch và đa hình thời gian chạy?

Sự khác nhau giữa đa hình thời gian biên dịch và đa hình thời gian chạy

Compile Time Polymorphism: còn gọi là đa hình tĩnh, đề cập đến kiểu đa hình xảy khi khi biên dịch. Có nghĩa là trình biên dịch quyết định hình dạng hoặc giá trị nào được thực thể sử dụng.

// In this program, we will see how multiple functions are created with the same name,
// but the compiler decides which function to call easily at the compile time itself.
class CompileTimePolymorphism{
    // 1st method with name add
    public int add(int x, int y){
        return x+y;
    }
    // 2nd method with name add
    public int add(int x, int y, int z){
        return x+y+z;
    }
    // 3rd method with name add
    public int add(double x, int y){
        return (int)x+y;
    }
    // 4th method with name add
    public int add(int x, double y){
        return x+(int)y;
    }
}

class Test{
    public static void main(String[] args){
        CompileTimePolymorphism demo=new CompileTimePolymorphism();
        // In the below statement, the Compiler looks at the argument types and decides to call method 1
        System.out.println(demo.add(2,3));
        // Similarly, in the below statement, the compiler calls method 2
        System.out.println(demo.add(2,3,4));
        // Similarly, in the below statement, the compiler calls method 4
        System.out.println(demo.add(2,3.4));
        // Similarly, in the below statement, the compiler calls method 3
        System.out.println(demo.add(2.5,3));
    }
}

Trong ví dụ trên, có bốn phiên bản của các phương thức add(). Phương thức đầu tiên nhận hai tham số trong khi phương thức thứ hai nhận ba tham số. Đối với phương pháp thứ ba và thứ tư, có sự thay đổi thứ tự của các tham số. Trình biên dịch xem xét dấu hiệu của phương thức và quyết định phương thức nào sẽ gọi cho một lệnh gọi cụ thể tại thời điểm biên dịch.

Runtime Polymorphism: còn gọi là đa hình động, đề cập đến kiểu đa hình xảy khi khi đang chạy. Điều đó có nghĩa là nó không thể được quyết định bởi trình biên dịch. Do đó, hình dạng hoặc giá trị nào phải được thực hiện tùy thuộc vào quá trình thực thi.

class AnyVehicle{
    public void move(){
        System.out.println(Any vehicle should move!!);
    }
}

class Bike extends AnyVehicle{
    public void move(){
        System.out.println(Bike can move too!!);
    }
}

class Test{
    public static void main(String[] args){
        AnyVehicle vehicle = new Bike();
        // In the above statement, as you can see, the object vehicle is of type AnyVehicle
        // But the output of the below statement will be “Bike can move too!!”,
        // because the actual implementation of object ‘vehicle’ is decided during runtime vehicle.move();
        vehicle = new AnyVehicle();
        // Now, the output of the below statement will be “Any vehicle should move!!”,
        vehicle.move();
    }
}

14. C++ hỗ trợ đa hình thế nào?

C++ là ngôn ngữ lập trình hướng đối tượng và hỗ trợ đa hình rất tốt:

  • Compile Time Polymorphism: C++ hỗ trợ tính đa hình thời gian biên dịch với sự trợ giúp của các tính năng như mẫu, nạp chồng hàm và các tham số mặc định.
  • Runtime Polymorphism: C++ hỗ trợ tính đa hình Runtime với sự trợ giúp của các tính năng như hàm ảo. Các hàm ảo có hình dạng của các hàm dựa trên loại đối tượng trong tham chiếu và được giải quyết trong thời gian chạy.

Tham khảo thêm về công việc của Java Developer tại đây

15. Kế thừa là gì?

Thuật ngữ “kế thừa” có nghĩa là “nhận được một số phẩm chất hoặc hành vi từ cha mẹ cho con cái”. Trong lập trình hướng đối tượng, kế thừa là cơ chế mà một đối tượng hoặc lớp (được gọi là con) được tạo ra bằng cách sử dụng định nghĩa của một đối tượng hoặc lớp khác (được gọi là cha). Kế thừa không chỉ giúp giữ cho việc triển khai đơn giản hơn mà còn giúp tạo điều kiện sử dụng lại code.

16. Trừu tượng là gì?

Nếu bạn là người dùng và bạn có một vấn đề, bạn không muốn biết các thành phần của phần mềm hoạt động như thế nào hoặc nó được tạo ra như thế nào. Bạn chỉ muốn biết cách phần mềm giải quyết vấn đề của bạn. Trừu tượng hóa là phương pháp che giấu những chi tiết không cần thiết khỏi những cái cần thiết. Đây là một trong những tính năng chính của OOP.

Ví dụ như một chiếc xe. Bạn chỉ cần biết cách chạy chiếc xe đó, còn nó gồm những bộ phận, động cơ có mấy xi lanh thì không cần quan tâm. Điều này được gọi là trừu tượng.

17. Một lớp chiếm bao nhiêu bộ nhớ?

Lớp không chứa bất kỳ bộ nhớ nào. Nó là một bản thiết kế để cái đối tượng dựa vào nó mà tạo. Chỉ khi đối tượng được tạo, nó mới thực sự tạo các thuộc tính và phương thức và mới tốn bộ nhớ.

18. Có phải lúc nào cũng cần tạo các đối tượng từ lớp không?

Không. Một đối tượng chỉ được tạo nếu lớp cơ sở có các phương thức động. Nhưng nếu lớp có các phương thức tĩnh, thì các đối tượng không cần phải được tạo. Bạn có thể gọi phương thức lớp trực tiếp trong trường hợp này, bằng cách sử dụng tên lớp.

19. Constructor là gì?

Constructor hay hàm khởi tạo là một phương thức đặc biệt có tên giống như tên lớp. Hàm khởi tạo dùng cho mục đích đặc biệt là khởi tạo đối tượng.

Ví dụ: ta có lớp tên là MyClass, khi bạn khởi tạo lớp này, bạn truyền cú pháp:

MyClass myClassObject = new MyClass();

Ở đây, phương thức được gọi sau từ khoá new là MyClass() là hàm khởi tạo của lớp này. Điều này giúp khởi tạo thuộc tính và các phương thức để gán chúng cho đối tượng myClassObject.

Constructor là gì

Bài viết gốc được đăng tải tại blog.thanhnamnguyen.dev

Xem thêm:

Xem thêm việc làm công nghệ thông tin hấp dẫn trên TopDev

Higher order Functions là gì? Sử dụng như thế nào?

Higher order Functions

Bài viết được sự cho phép của tác giả Duy Phan

Đây là một khái niệm rất quan trọng trong Functional Programming. Ở đây mình sẽ cho ví dụ dựa trên Javascript, cụ thể là TypeScript, do đó mình hi vọng các bạn đã có một số kiến thức nhất định về JS trước. Điều này sẽ giúp bạn nắm bắt nội dung bài viết dễ dàng hơn.

Higher order Function là gì?

Higher order function không không phải là một khái niệm mới. Nó khá đặc thù và phổ biến trong Functional Programming.

Concept đơn giản ở đây là một Function nhận một hoặc nhiều function khác làm tham số, sau đó trả về giá trị hoặc một function mới.

Ví dụ, Javascript có hàm Array.filter. Đây là một higher order function, do nó nhận một function làm tham số.

const qrCodes: string[] = ['QR1', 'QR222', 'QR3333', 'QR4444', 'QR5555']

const qrCodesV3: string[] = qrCodes.filter((qrCode) => qrCode.length > 5)

console.log(qrCodesV3) //['QR3333', 'QR4444', 'QR5555']

Javascript cũng có một hàm khác Array.slice. Tuy nhiên, đây không phải là higher order function, do nó không nhận tham số là function, và giá trị trả về của nó cũng không phải một function nào cả.

const qrCodes: string[] = ['QR1', 'QR222', 'QR3333', 'QR4444', 'QR5555']

const firstTwoQrCodes: string[] = qrCodes.slice(0, 2)

console.log(firstTwoQrCodes) //['QR1', 'QR222']

Hữu dụng hay không?

Higher order Function giúp code của chúng ta ngắn gọn, linh hoạt, có thể dễ dàng maintenance.

Nhờ vào khả năng kết hợp giữa các function thông qua higher order function mà chúng được sử dụng rất phổ biến trong Functional Programming.

Ví dụ

Mình sẽ viết lại hàm một filter khác thực hiện công việc tương tự ở ví dụ đầu tiên:

const stringsLengthGreaterThan = (length: number, items: string[]): string[] => {
  const output = []

  for (const item of items) {
    if (item.length > length) {
      output.push(item)
    }
  }

  return output
}

const qrCodes: string[] = ['QR1', 'QR222', 'QR3333', 'QR4444', 'QR5555']

const qrCodesV3: string[] = stringsLengthGreaterThan(5, qrCodes)

console.log(qrCodesV3) //['QR3333', 'QR4444', 'QR5555']

Đoạn code trên có vẻ không được linh hoạt cho lắm. Thử tưởng tượng bạn cần lọc ra một danh sách các number với giá trị lớn hơn 5 chẳng hạn, bạn cần phải tạo một hàm khác, cập nhật thêm một mớ logic khác.

const numberGreaterThan = (value: number, items: number[]): number[] => {
  const output = []

  for (const item of items) {
    if (item > value) {
      output.push(item)
    }
  }

  return output
}

const numbers: number[] = [1, 3, 5, 7, 9, 11]

const highNumbers: number[] = numberGreaterThan(5, numbers)

console.log(highNumbers) //[7, 9, 11]

Hàm numberGreaterThan và stringsLengthGreaterThan hầu như giống nhau, chỉ khác nhau về điều kiện so sánh dữ liệu, điều này thì khá là tệ.

Mình theo phong cách viết càng ít logic càng tốt. Viết càng ít logic thì càng giảm thiểu số lượng unit tests cho các logic này. Rõ ràng là vừa đỡ mệt, vừa đỡ tốn thời gian, lại vừa dễ dàng bảo trì hơn, đúng không?Giờ mình sẽ sửa lại đoạn code trên sử dụng higher order function:

function higherOrderFilter<T = any>(
  iteratee: (item: T) => boolean
): (items: T[]) => T[] {
  return (items) => {
    const output: T[] = []

    for (const item of items) {
      if (iteratee(item)) {
        output.push(item)
      }
    }

    return output
  }
}

const qrCodes: string[] = ['QR1', 'QR222', 'QR3333', 'QR4444', 'QR5555']
const numbers: number[] = [1, 3, 5, 7, 9, 11]

const qrCodesV3: string[] = higherOrderFilter(
  (item: string) => item.length > 5
)(qrCodes)
console.log(qrCodesV3) //['QR3333', 'QR4444', 'QR5555']

const highNumbers: number[] = higherOrderFilter(
  (item: number) => item > 5
)(numbers)
console.log(highNumbers) //[7, 9, 11]

Đấy, code đã clean hơn rất nhiều. Do logic filter đã được tách biệt khỏi điều kiện filter, nên bạn cũng tái sử dụng lại được logic từ hai hàm numberGreaterThan và stringsLengthGreaterThan.

Ở ví dụ trên, có thể có nhiều bạn sẽ thắc mắc tại sao mình lại đem iteratee function làm đối số đầu tiên, và array dữ liệu mẫu làm đối số thứ hai. Thực ra, chúng đều có dụng ý cả.

Ví dụ bên dưới đây sẽ sử dụng thêm thư viện lodash/fp.

Mình sẽ thực hiện việc loại bỏ các giá trị thừa và lặp lại thông qua hàm _.compact và _.uniq, sau đó sẽ trả về các QR codes có length lớn hơn 6.

import _ from 'lodash/fp'

const qrCodes: string[] = [
  '',
  'QR222',
  'QR3333',
  'QR4444',
  'QR5555',
  'QR5555',
  'QR5555',
  'QR66666',
  'QR66666',
  'QR66666',
  'QR77777',
  'QR77777',
  'QR77777',
]

const qrCodesV4: string[] = _.pipe(
  _.compact,
  _.uniq,
  higherOrderFilter((item: string) => item.length > 6)
)(qrCodes)
console.log(qrCodesV4) //['QR66666', 'QR77777']

Bây giờ mình sẽ viết lại hàm higherOrderFilter và đảo ngược thứ tự hai đối số để xem sự khác biệt nhé.

import _ from 'lodash/fp'

const qrCodes: string[] = [
  '',
  'QR222',
  'QR3333',
  'QR4444',
  'QR5555',
  'QR5555',
  'QR5555',
  'QR66666',
  'QR66666',
  'QR66666',
  'QR77777',
  'QR77777',
  'QR77777',
]

function higherOrderFilterReverse<T = any>(
  items: T[]
): (iteratee: (item: T) => boolean) => T[] {
  return (iteratee) => {
    const output: T[] = []

    for (const item of items) {
      if (iteratee(item)) {
        output.push(item)
      }
    }

    return output
  }
}

const qrCodesV5: string[] = _.pipe(
  _.compact, 
  _.uniq, 
  (items: string[]) => higherOrderFilterReverse(items)((item: string) => item.length > 6)
)(qrCodes)
console.log(qrCodesV5) //['QR66666', 'QR77777']

Kết quả vẫn giống như ví dụ trước, nhưng do đối số đầu tiên của hàm higherOrderFilterReverse là một string array (tức kết quả trả về của hàm _.uniq trước đó), chúng ta bắt buộc phải tạo một hàm mới để có thể khai báo iteratee function.

Mình luôn cố gắng viết các đối số cuối cùng của higher order function sao cho có thể nhận giá trị trả về từ các function trước. Lúc đó, code của bạn sẽ ngắn gọn hơn rất nhiều.

Kết

Higher order Function làm một phần cực kỳ quan trọng trong Functional Programming. Nắm rõ chúng sẽ giúp các bạn viết code tốt hơn, ngắn gọn, clean hơn, ứng dụng của bạn cũng sẽ dễ dàng bảo trì hơn.

Mình hi vọng các bạn thích bài viết này. Nếu bạn có câu hỏi, đừng ngại inbox mình hoặc để lại comment nhé.

Cám ơn các bạn rất nhiều.

Bài viết gốc được đăng tải tại duypt.dev

Xem thêm:

Xem thêm các việc làm Developer hấp dẫn tại TopDev

Tìm hiểu về Authentication vs Authorization – Cơ chế hoạt động

Tìm hiểu về Authentication vs Authorization

Bài viết được sự cho phép bởi tác giả Vũ Thành Nam

Khi bạn vào một website nào đó, bạn sẽ thường thấy chức năng đăng nhập, đăng xuất của một ứng dụng. Đa số chúng ta biết đến tính năng này với việc điền tên tài khoản và mật khẩu để có thể truy cập sử dụng một số tính năng khác trong hệ thống.

Phải nói đây có lẽ là một trái tim của một trang web giúp ứng dụng có thể xác thực bạn là ai, cần được quyền truy cập hay tiếp tục thao tác trên ứng dụng hay không.

Đây trong chuyên ngành chính là Authentication và Authorization

Loạt bài viết này hãy cùng mình đi tìm hiểu chuyên sâu một chút về 2 thuật ngữ này và cách thức hoạt động của nó khi sử dụng và không sử dụng framework nhé!

Bắt đầu thôi!

Authentication vs Authorization

Authentication (xác thực) có nghĩa là xác nhận danh tính của riêng bạn, trong khi authorization (ủy quyền) có nghĩa là cấp quyền truy cập vào hệ thống. Nói một cách đơn giản, authentication là quá trình xác minh bạn là ai, trong khi authorization là quá trình xác minh những gì bạn có quyền truy cập.

Authentication là gì?

Authentication là về việc xác thực thông tin đăng nhập của bạn như tên người dùng hoặc định danh người dùng và mật khẩu để xác minh danh tính của bạn. Hệ thống xác thực danh tính người dùng thông qua mật khẩu đăng nhập. Authentication thường được thực hiện bởi tên người dùng và mật khẩu tuy nhiên nó lại kết hợp với các yếu tố xác thực khác như mã OTP hay mã PIN.

Các nhân tố xác thực (Authentication Factor) mà hệ thống sử dụng để xác minh một danh tính trước khi cấp cho họ quyền truy cập vào thực hiện bất cứ điều gì trên ứng dụng của bạn.

Dựa trên cấp độ bảo mật, Authentication Factor có thể thay đổi theo một trong các cách sau:

– Single-Factor Authentication (Xác thực một lớp): Nó là phương thức xác thực đơn giản nhất thường dựa vào mật khẩu đơn giản để cấp cho người dùng quyền truy cập vào một hệ thống cụ thể là một website hoặc network. Người này có thể yêu cầu quyền truy cập vào hệ thống chỉ bằng một trong các thông tin đăng nhập để xác minh danh tính của mình. Ví dụ phổ biến nhất về xác thực một yếu tố sẽ là thông tin đăng nhập chỉ yêu cầu mật khẩu đối với tên người dùng hoặc địa chỉ email.

– Two-Factor Authentication (Xác thực hai lớp): Như tên của nó, nó có một quy trình xác minh gồm hai bước, không chỉ yêu cầu tên người dùng và mật khẩu, mà còn một thứ mà chỉ người dùng biết, để đảm bảo mức độ bảo mật bổ sung, chẳng hạn như pin ATM, chỉ người dùng mới biết. Sử dụng tên người dùng và mật khẩu cùng với một thông tin bí mật bổ sung khiến cho những kẻ lừa đảo hầu như không thể đánh cắp dữ liệu có giá trị.

– Multi-Factor Authentication (Xác thực nhiều lớp): Nó có một phương thức xác thực tiên tiến nhất sử dụng hai hoặc nhiều mức bảo mật từ các loại xác thực độc lập để cấp quyền truy cập cho người dùng vào hệ thống. Tất cả các yếu tố phải độc lập với nhau để loại bỏ bất kỳ lỗ hổng nào trong hệ thống.

Authentication các có thể kết hợp một hoặc nhiều các yếu tố sau:

Password hay Pin: Là mật khẩu hay mã pinMật khẩu là một phương pháp xác thực vô cùng đơn giản, dễ triển khai nên đang được sử dụng rất rộng rãi và phổ biến.

Mỗi khi người dùng thực hiện truy cập vào thì mỗi hệ thống đều sẽ lưu lại mật khẩu dưới dạng mã hóa một chiều (các loại mã hóa có thể là md5, sha1, hoặc tự viết cơ chế mã hóa).
Đây là tính năng sẽ đảm bảo cho mật khẩu dù bị hack nhưng cũng không thể khôi phục được thành chuỗi gốc.  Đây là phương pháp có nhiều biến thể khác nhau như: thiết kế dưới dạng biến thể Swipe Pattern PIN hoặc mật khẩu chỉ bằng cách dùng trong một lần (nó chuyên sử dụng cho những chức năng quan trọng).

Security token: Các mã bảo mật.Đây là phương pháp dựa vào thuật toán mã hóa khóa công cộng và khóa cá nhân để xác thực.

Muốn đăng nhập vào hệ thống, thì bạn chỉ cần có khóa cá nhân ở trên máy rồi thực hiện đăng nhập vào hệ thống mà không cần phải nhớ đến những thông tin đăng nhập như việc sử dụng mật khẩu.  Thường thì các hệ thống quản trị server sẽ thường xuyên áp dụng biện pháp này.

Biometric verification: Sẽ xác minh sinh trắc học, sử dụng tròng mắt, dấu vân tay hoặc khuôn mặt là một trong những phương pháp xác thực dựa trên các yếu tố đặc trưng của một người. Phương pháp này mang lại ưu điểm là Id và mật khẩu sẽ luôn được đi cùng nhau nên bạn hoàn toàn không cần phải lo lắng bị quên hay lạc mất nó.

Mỗi khi bạn muốn đăng nhập lại thì chỉ cần chủ động sử dụng các yếu tố xác thực này một cách dễ dàng, mà không gặp bất kỳ khó khăn nào.

Mặc dù có nhiều phương pháp để có thể xác thực cho một tài khoản, tuy nhiên thì bạn sẽ không thể tránh khỏi những rủi ro như: mất đi mật khẩu, vân tay bị đánh cắp, mất mã khóa cá nhân.

  Tìm hiểu về xác thực và phân quyền trong ứng dụng
\

  Security key là gì? Xác thực 2 yếu tố “xịn xò” với Security key

Authorization là gì?

Authorization là quá trình để xác định xem người dùng được xác thực có quyền truy cập vào các tài nguyên cụ thể hay không. Nó xác minh quyền của bạn để cấp cho bạn quyền truy cập vào các tài nguyên như thông tin, cơ sở dữ liệu, file… Authorization thường được đưa ra sau khi xác thực xác nhận các đặc quyền của bạn để thực hiện. Nói một cách đơn giản hơn, nó giống như cho phép ai đó chính thức làm điều gì đó hoặc bất cứ điều gì.

Authorization xảy ra sau khi hệ thống của bạn được authentication (xác thực) thành công, cuối cùng cho phép bạn toàn quyền truy cập các tài nguyên như thông tin, file, cơ sở dữ liệu, quỹ, địa điểm, hầu hết mọi thứ. Nói một cách đơn giản, authorization xác định khả năng của bạn để truy cập hệ thống và ở mức độ nào. Khi danh tính của bạn được hệ thống xác minh sau khi xác thực thành công, bạn sẽ được phép truy cập tài nguyên của hệ thống.

Ví dụ quy trình xác minh và xác nhận mã nhân viên và mật khẩu trong một tổ chức được gọi là Authentication, nhưng xác định nhân viên nào có quyền truy cập vào tầng nào được gọi là Authorization

Tham khảo việc làm IT Security hấp dẫn trên TopDev

Authentication vs Authorization

Quá trình Authentication và Authorization diễn ra như nào?

Quá trình Authentication và Authorization

Bước 1: Khi người dùng muốn truy cập vào một tài nguyên nào đó, bước đầu tiên họ sẽ phải gửi một request truy cập đến nguồn chứa tài nguyên đó. Để xác định người dùng đó là ai trong hệ thống thì nguồn chứa tài nguyên phải sinh ra một dấu hiệu trước đó. Đây chính là bước đăng ký mà các bạn vẫn hay làm. Hoặc có thể là do phía Admin cấp cho bạn tài khoản định danh. Dấu hiệu này sẽ có thể là mã nhân viên, tên định danh, tên đăng nhập…

Bước 2: Người dùng sẽ vào ứng dụng của bạn và điền các thông tin của dấu hiệu kể trên và yêu cầu quyền truy cập vào ứng dụng. Đây chính là quá trình đăng nhập của bạn.

Bước 3: Nguồn tài nguyên sẽ kiểm tra yêu cầu với thông tin truy cập trên và xác định được người đó là ai, họ có thể là khách, là người mua hàng, người quản lý, hay cộng tác viên. Khi này tài nguyên cần muốn biết phân loại được người truy cập vừa rồi có được quyền sử dụng, chỉnh sửa hay chỉ xem tài nguyên thì hệ thống sẽ tiếp tục xác thực quyền.

Bước 4, 5: Có nhiều cách xác thực quyền truy cập dựa trên các yêu cầu sau khi xác thực định danh (Mình sẽ đề cập rõ hơn trong bài viết sau). Đến đây khi hệ thống biết bạn có những quyền gì nó sẽ chỉ cấp cho bạn đúng quyền hạn đó mà thôi.

Bước 6,7,8: Khi nhận được quyền hạn truy cập các request tiếp theo bạn có thể truy cập được tài nguyên với quyền hạn đi kèm đã cấp.

Bài viết gốc được đăng tải tại ntechdevelopers.com

Xem thêm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Hàm trong Python – Cú pháp và một số hàm phổ biến

Hàm trong Python

Hàm – Function là một khái niệm cơ bản quan trọng nhất trong mọi ngôn ngữ lập trình mà bạn cần nắm vững để có thể sử dụng. Bài viết hôm nay chúng ta cùng nhau tìm hiểu về hàm trong Python, cú pháp khai báo hàm cũng như lời gọi hàm sử dụng trong ngôn ngữ này nhé.

Hàm trong Python là gì?

Trong lập trình Python, hàm được kí hiệu là function là một khối code hay nhóm lệnh có tổ chức và có thể tái sử dụng được dùng để triển khai một hành động liên quan, thực hiện một tác vụ cụ thể. Nó giúp chia một chương trình Python ra thành những khối/ phần/ mô đun nhỏ hơn, có tổ chức để dễ dàng quản lý hơn và tối ưu hóa việc tái sử dụng.

Trong Python có 2 loại hàm cơ bản chính gồm:

Ở phiên bản Python 3.12 mới nhất hiện nay, có khoảng 70 functions được tích hợp sẵn và bạn có thể tham khảo ở link này để sử dụng

hàm trong Python

Cú pháp khai báo function trong Python

Cấu trúc hàm trong Python:

Cú pháp khai báo hàm trong Python

Trong đó:

  • def: từ khóa bắt đầu định nghĩa một hàm trong Python
  • funtion_name: tên function khai báo – định danh duy nhất và tuân thủ quy tắc đặt tên hàm Python
  • arguments: danh sách các tham số/ đối số đặt trong ngoặc đơn, được khai báo tách nhau bởi dấu phẩy
  • dấu “:”: đánh dấu kết thúc khai báo tiêu đề của hàm
  • statement list: danh sách các câu lệnh, khai báo nội dung hàm
  • return: từ khóa để giúp hàm trả về một giá trị nhất định

Với Python, một function có thể trả về dữ liệu (chứa từ khóa return) hoặc không. Trường hợp không có lệnh return thì hàm sẽ trả về None.

Ngoài ra để phục vụ cho việc tạo tài liệu (documents) của hàm, Python sử dụng khai báo bên dưới tiêu đề hàm và nằm trong 3 ký tự [“””]. Phần này được gọi là Docstring (documentation string) giúp giải thích ngắn gọn về chức năng của hàm.

Một ví dụ đầy đủ khi khai báo hàm Python bạn có thể tham khảo dưới đây:

Cú pháp khai báo hàm trong Python

Cú pháp gọi hàm trong Python

Chúng ta định nghĩa một hàm như dưới đây:

def sayHello(name):
    """This function to say hello,
        name is a argument""" 
    print("Hello " + name + ". Have nice day!")

Để gọi sử dụng hàm trên trong Python, chúng ta đơn giản chỉ cần nhập tên hàm và truyền tham số tương ứng, ví dụ:

sayHello("TopDev")
# Hello TopDev. Have nice day!

Lưu ý rằng trong Python, code định nghĩa hàm luôn phải nằm trước lời gọi hàm, nếu không thì chương trình sẽ trả về lỗi hàm chưa được định nghĩa (NameError … not defined).

  Tất tần tật về các loại toán tử trong Python

  Quy tắc đặt tên biến trong Python đúng chuẩn 2024

Phạm vi biến trong hàm Python

Trong Python, phạm vi của biến chính là đoạn chương trình mà ở đó biến được thừa nhận, có thể sử dụng. Với một hàm, biến và các tham số có phạm vi chỉ trong phần khai báo của hàm đó; nghĩa là chúng ta không thể sử dụng các biến đó bên ngoài hàm.

Phạm vi biến trong hàm Python

Thời gian tồn tại của biến trong hàm cũng được đánh dấu tương ứng với lời gọi hàm, chúng được tạo ra khi hàm có lời gọi đến, xuất hiện ở bộ nhớ trong quá trình thực thi hàm và sẽ bị hủy khi chương trình thoát khỏi hàm.

Tuyển dụng Python mọi cấp độ tại đây!

Phân biệt Method và Function trong Python

Trong Python, có 2 khái niệm mà nếu mới tiếp xúc với ngôn ngữ này bạn có thể dễ bị nhầm lẫn, đó là method – phương thức và function – hàm. Cả 2 đều khá giống nhau trong cách khai báo, định nghĩa cũng như lời gọi, cách sử dụng; bạn có thể xem ở ví dụ dưới đây.

Phân biệt Method và Function trong Python

Điểm khác nhau cơ bản giữa method và function đấy là việc method thuộc về một lớp hay đối tượng và để gọi hay truy cập vào method cần thông qua lớp, đối tượng đó. Như ở ví dụ trên, phương thức to_pounds được định nghĩa bên trong class Weight và để gọi được thì bắt buộc phải thông qua đối tượng w

>> Giải đáp chi tiết hơn trong bài viết: Phân biệt Method và Function trong Python

Một số hàm phổ biến trong Python

Những hàm hữu ích tích hợp sẵn và hay được sử dụng trong Python mà bạn nên biết:

  • reduce(): duyệt qua từng phần tử trong một danh sách và trả về một giá trị đơn lẻ
  • split(): ngắt một chuỗi dựa theo tiêu chí
  • enumerate(): trả về độ dài của một vòng lặp
  • eval(): triển khai các biểu thức toán học
  • map(): duyệt qua từng phần tử trong danh sách
  • min(), max(): trả về mục được xếp hạng thấp nhất/ cao nhất trong một lần lặp
  • getattr(): trả về thuộc tính của một đối tượng

Kết bài

Qua bài viết này chắc hẳn các bạn đã nắm được kiến thức cơ bản về hàm, cách định nghĩa cũng như sử dụng hàm trong ngôn ngữ lập trình Python. Hy vọng bài viết hữu ích dành cho bạn và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

.NET core là gì? Lịch sử hình thành và phát triển của .NET core

Bạn mới dấn thân vào con đường lập trình web và bối rối vì quá nhiều thuật ngữ như .NET, .NET core, .NET framework. Vậy sự khác biệt giữa chúng là gì? Nên chọn cái nào tốt nhất để học phát triển web? Trong bài viết này của TopDev, chúng ta sẽ tập trung đi sâu tìm hiểu về .NET core là gì và lịch sử hình thành của nó, đồng thời giúp bạn giải đáp thắc mắc ở đầu bài.

.NET core là gì? Lịch sử hình thành và phát triển của .NET core
.NET core là gì? Lịch sử hình thành và phát triển của .NET core

Tổng quan về .NET Core

.NET Core là gì?

.NET Core là phiên bản cải tiến của .NET Framework, là một nền tảng phát triển đa năng, mã nguồn mở, miễn phí được duy trì bởi Microsoft. Nó là một framework đa nền tảng chạy trên các hệ điều hành Windows, macOS và Linux.

.NET Core có thể được sử dụng để xây dựng các loại ứng dụng khác nhau như thiết bị di động, máy tính để bàn, web, đám mây, IoT, máy học, microservice, trò chơi, v.v.

Xem tin tuyển dụng .NET tại TopDev

Lịch sử hình thành .NET Core

Do một số hạn chế khi sử dụng .NET Framework như nó chỉ chạy trên nền tảng Windows. Ngoài ra, bạn cần sử dụng các API .NET khác nhau cho các thiết bị Windows khác nhau như Windows Desktop, Windows Store, Windows Phone và ứng dụng Web. Ngoài ra, .NET Framework còn là một framework toàn máy. Bất kỳ thay đổi nào được thực hiện đối với nó đều ảnh hưởng đến tất cả các ứng dụng phụ thuộc vào nó.

Ngày nay, việc có một ứng dụng chạy trên nhiều thiết bị là điều phổ biến; một backend trên máy chủ web, giao diện quản trị trên desktop Windows, các ứng dụng web và di động cho người dùng. Do đó, cần có một framework duy nhất hoạt động ở mọi nơi. Với ý tưởng này, Microsoft đã tạo ra .NET Core. Mục tiêu chính của .NET Core là làm cho .NET Framework trở thành mã nguồn mở, tương thích đa nền tảng và có thể được sử dụng trong nhiều lĩnh vực khác nhau, từ trung tâm dữ liệu đến các thiết bị cảm ứng.

Lịch sử hình thành .NET Core
Lịch sử hình thành .NET Core

Tên .NET Core đã được thay đổi sau .NET Core 3.1. Phiên bản tiếp theo của .NET Core sau phiên bản 3.1 được đặt tên là .NET 5. Phiên bản mới nhất của .NET Core là .NET 7 tính đến thời điểm viết bài này.

.NET 5 hợp nhất các nền tảng .NET Core, .NET Framework và Xamarin riêng biệt trước đây, giúp các nhà phát triển dễ dàng sử dụng một nền tảng duy nhất cho nhiều loại ứng dụng khác nhau. Và hiện nay được gọi ngắn gọn là .NET

Đọc thêm: Anh em nhà .NET

Phân biệt .NET, .NET Core và .NET Framework

.NET (từ phiên bản 5.0 trở đi) .NET Core .NET Framework
Ra đời Năm 2020 (kết hợp .NET Core và Mono) Năm 2016 Từ năm 2002
Nền tảng Đa nền tảng. Đa nền tảng (Windows, macOS, Linux) Chỉ chạy trên Windows.
Ứng dụng Tương tự .NET Core nhưng mở rộng và hợp nhất một số tính năng. Phát triển ứng dụng web (ASP.NET Core), ứng dụng console, dịch vụ microservices Phát triển ứng dụng desktop (WinForms, WPF), dịch vụ web (ASP.NET WebForms, ASP.NET MVC)
Hỗ trợ Tất cả các loại ứng dụng (web, mobile, desktop, IoT, AI). Hiệu suất cao, linh hoạt, nhẹ và hiện đại Đầy đủ các thư viện và API

Đặc điểm cốt lõi của .NET Core

  1. Khung nguồn mở: .NET Core là một khung nguồn mở được Microsoft duy trì và có sẵn trên GitHub theo giấy phép MIT và Apache 2. Đây là một dự án thuộc .NET Foundation. Bạn có thể xem, tải xuống hoặc đóng góp cho mã nguồn qua các kho lưu trữ GitHub.
  2. Đa nền tảng: .NET Core chạy trên Windows, macOS và Linux, có các thời gian chạy khác nhau cho mỗi hệ điều hành nhưng tạo ra cùng một đầu ra.
  3. Nhất quán trên các kiến trúc: .NET Core thực thi mã với cùng hành vi trên các kiến trúc tập lệnh khác nhau, bao gồm x64, x86 và ARM.
  4. Hỗ trợ nhiều loại ứng dụng: .NET Core cho phép phát triển và chạy nhiều loại ứng dụng khác nhau như thiết bị di động, desktop, web, đám mây, IoT, máy học, microservices và trò chơi.
  5. Hỗ trợ nhiều ngôn ngữ lập trình: .NET Core hỗ trợ các ngôn ngữ lập trình C#, F# và Visual Basic. Bạn có thể sử dụng các IDE yêu thích như Visual Studio 2017/2019, Visual Studio Code, Sublime Text, Vim, và nhiều hơn nữa.
  6. Kiến trúc mô-đun: .NET Core hỗ trợ kiến trúc mô-đun thông qua các gói NuGet. Các tính năng khác nhau có thể được thêm vào dự án khi cần thiết, giảm dung lượng bộ nhớ và tăng tốc hiệu suất.
  7. Công cụ CLI: .NET Core bao gồm các công cụ CLI (Giao diện dòng lệnh) để phát triển và tích hợp liên tục.
  8. Triển khai linh hoạt: Ứng dụng .NET Core có thể được triển khai trên toàn người dùng, toàn hệ thống hoặc với Docker Container.
  9. Khả năng tương thích: .NET Core tương thích với .NET Framework và Mono API thông qua .NET Standard.
  10. Hiệu suất cao: .NET Core được tối ưu hóa về hiệu suất với các tính năng như biên dịch Just-In-Time (JIT), dịch mã thành hướng dẫn máy trong thời gian chạy để cải thiện tốc độ thực thi.
  11. Nền tảng hợp nhất: Từ .NET Core 3.1 trở đi, Microsoft đã hợp nhất các nền tảng .NET, tập hợp .NET Core, .NET Framework và Xamarin thành một nền tảng duy nhất gọi là “.NET” bắt đầu từ .NET 5, nhằm cung cấp tính nhất quán API và hành vi thời gian chạy trên các loại ứng dụng khác nhau.

Xem thêm:

Như vậy, bài viết của TopDev đã giúp bạn hiểu rõ .NET Core là gì? Đồng thời biết về lịch sử hình thành và phát triển .NET framework và .NET Core… Hãy cũng khám phá nhiều hơn về nền tảng phát triển này qua các bài tiếp theo của chúng tôi!

Nguồn tham khảo: www.tutorialsteacher.com/core/dotnet-core

ASP.NET là gì? Phân tích thành phần và phương thức hoạt động chi tiết

Trong thời đại công nghệ hiện nay, việc phát triển các ứng dụng web động và dịch vụ web là một nhu cầu thiết yếu của các doanh nghiệp và lập trình viên. ASP.NET, một framework mã nguồn mở được phát triển bởi Microsoft, đã nhanh chóng trở thành công cụ không thể thiếu cho việc này. Được thiết kế để đơn giản hóa quá trình phát triển ứng dụng web, ASP.NET cung cấp nhiều tính năng mạnh mẽ và linh hoạt, giúp lập trình viên dễ dàng tạo ra các ứng dụng chất lượng cao, bảo mật và hiệu quả.

Cùng TopDev tìm hiểu ASP.NET là gì? và các lợi ích tuyệt vời của ASP.NET ngay trong bài viết dưới đây!

ASP.NET là gì? Phân tích thành phần và phương thức hoạt động chi tiết
ASP.NET là gì? Phân tích thành phần và phương thức hoạt động chi tiết

ASP.NET là gì?

ASP.NET là một framework mã nguồn mở phía server được phát triển bởi Microsoft, nhằm mục đích xây dựng các ứng dụng web động và dịch vụ web. Nó cho phép các lập trình viên tạo ra các trang web và ứng dụng sử dụng HTML5, CSS, và JavaScript. Được giới thiệu lần đầu tiên vào đầu thế kỷ 21, ASP.NET đã nhanh chóng trở thành một công cụ quan trọng trong việc phát triển ứng dụng web, đặc biệt là trong môi trường doanh nghiệp.

Xem tin tuyển dụng asp.NET mới nhất tại TopDev

Thành phần của ASP.NET

ASP.NET được cấu thành từ ba thành phần chính, mỗi thành phần đảm nhận một vai trò cụ thể trong việc phát triển ứng dụng:

Thành phần của ASP.NET
Thành phần của ASP.NET

Ngôn ngữ lập trình

    • C#: Ngôn ngữ lập trình hướng đối tượng, phổ biến nhất trong .NET framework, được sử dụng rộng rãi để phát triển các ứng dụng web và dịch vụ web.
    • VB.NET: Ngôn ngữ lập trình lâu đời của Microsoft, cũng được sử dụng để phát triển các ứng dụng web.
    • F#: Ngôn ngữ lập trình chức năng, hỗ trợ lập trình hướng đối tượng và hướng chức năng.

Thư viện

Thư viện .NET (CoreFX): Chứa các lớp và phương thức cần thiết để thực hiện các chức năng cơ bản như quản lý tệp tin, xử lý ngoại lệ, giao tiếp mạng và nhiều chức năng khác.

Common Language Infrastructure (CLI)

    • Common Language Runtime (CLR): Nền tảng thực thi các chương trình Dot Net, giúp quản lý bộ nhớ, bảo mật và xử lý ngoại lệ.
    • Common Intermediate Language (CIL): Mã trung gian được biên dịch từ mã nguồn, sau đó được CLR thực thi.

Xem tin tuyển dụng .NET mới nhất tại đây

Các Mô Hình Ứng Dụng của ASP.NET

Các Mô Hình Ứng Dụng của ASP.NET
Các Mô Hình Ứng Dụng của ASP.NET

ASP.NET hỗ trợ nhiều mô hình phát triển ứng dụng khác nhau, tùy thuộc vào yêu cầu cụ thể của từng dự án:

  1. Web Forms: Cho phép xây dựng các ứng dụng web với giao diện người dùng phong phú, sử dụng kéo và thả để thiết kế trang web.
  2. ASP.NET MVC: Mô hình phát triển theo kiến trúc MVC (Model-View-Controller), tách biệt giữa logic ứng dụng, giao diện người dùng và luồng dữ liệu, giúp dễ dàng quản lý và mở rộng ứng dụng.
  3. ASP.NET Web Pages: Đơn giản hóa việc phát triển ứng dụng web bằng cách sử dụng Razor syntax, cho phép viết mã HTML và C# trong cùng một trang.
  4. ASP.NET Web API: Dùng để xây dựng các dịch vụ web và API RESTful, cho phép các ứng dụng khác tương tác thông qua HTTP.
  5. ASP.NET Core: Phiên bản mới nhất và linh hoạt nhất của ASP.NET, hỗ trợ đa nền tảng và cải thiện hiệu suất, cho phép chạy trên Windows, macOS và Linux.

Đọc thêm:

Lợi ích của ASP.NET

  1. Đơn giản, bảo mật và hỗ trợ tốt: ASP.NET cung cấp quản lý bộ nhớ tự động, bảo mật tích hợp và xử lý ngoại lệ hiệu quả, giúp bảo vệ ứng dụng khỏi các mối đe dọa bảo mật. Nó được xây dựng trên môi trường Windows server quen thuộc, giúp tiết kiệm thời gian thiết lập và cấu hình cho các lập trình viên.
  2. Tốc độ và hiệu suất cao: Các ứng dụng ASP.NET được biên dịch, giúp mã nguồn chạy nhanh và hiệu quả hơn so với các mã nguồn được diễn dịch như PHP và JavaScript. Quá trình biên dịch tạo ra mã đối tượng, sau đó được thực thi nhanh chóng bởi nền tảng .NET, giúp tăng tốc độ và khả năng mở rộng của ứng dụng.
  3. Tiết kiệm chi phí: ASP.NET giúp giảm chi phí phát triển và triển khai nhờ vào việc sử dụng phần mềm miễn phí và khả năng lưu trữ trên nhiều nền tảng như Linux, macOS và Windows. Các công cụ phát triển như Visual Studio Code miễn phí cho tất cả người dùng, kể cả các công ty lớn, giúp tiết kiệm chi phí phần mềm.
  4. Cộng đồng lớn và tài nguyên hỗ trợ phong phú: ASP.NET có một cộng đồng lập trình viên .NET lớn và nhiều tài nguyên học tập, bao gồm các khóa học, tài liệu và diễn đàn hỗ trợ. Microsoft đầu tư mạnh mẽ vào việc phát triển và duy trì ASP.NET, đảm bảo rằng nền tảng này luôn cập nhật với các tính năng và công nghệ mới nhất.
  5. Quản lý trạng thái và bộ nhớ đệm (Caching): ASP.NET cho phép quản lý trạng thái và bộ nhớ đệm hiệu quả, giúp cải thiện hiệu suất ứng dụng. Các trang web và ứng dụng thường được truy cập có thể được lưu vào bộ nhớ đệm, giảm thiểu thời gian phản hồi và cung cấp trải nghiệm người dùng tốt hơn.
  6. Khả năng mở rộng và tích hợp: ASP.NET dễ dàng tích hợp với các công nghệ và dịch vụ khác của Microsoft, cũng như các công cụ và nền tảng của bên thứ ba, giúp xây dựng các ứng dụng mạnh mẽ và đa chức năng.
  Todo App ASP.NET MVC x Entity Framework
  Google AMP là gì ? Cài đặt AMP cho website asp.net mvc

ASP.NET và .NET khác nhau như thế nào?

.NET đã được phát hành và ứng dụng từ nhiều năm trước. Vào năm 2016, Microsoft giới thiệu một phiên bản mới hơn gọi là .NET Core, và ngược lại gọi phiên bản ban đầu là .NET Full Framework. Ban đầu, bạn có thể sử dụng một trong hai .NET Full Framework hoặc .NET Core. Tuy nhiên, đến hiện tại, .NET Full Framework không còn được phát triển và .NET Core hiện nay chỉ được gọi là .NET (với phiên bản .NET 5 trở đi).

ASP.NET là một framework phát triển web chạy trên nền tảng .NET. Phiên bản đầu tiên của ASP.NET hiện được biết đến là ASP.NET WebForms, thuộc phần của ASP.NET Full Framework và không còn được phát triển nữa. Sau WebForms là ASP.NET MVC, một phiên bản giống Ruby on Rails nhưng về mặt kỹ thuật nó được xây dựng trên nền tảng ASP.NET thuộc Full Framework. Khi .NET Core được phát hành, một phiên bản cập nhật của ASP.NET MVC cũng được phát hành cùng với nó và được gọi là ASP.NET Core.

Tóm lại, ta có thể phân biệt đơn giản .NET là nền tảng và ASP.NET Core là framework phát triển web chạy trên nền tảng đó.

Bài viết liên quan: 

ASP.NET là một framework mạnh mẽ và linh hoạt, lý tưởng cho việc phát triển các ứng dụng web và dịch vụ web. Với các tính năng vượt trội về hiệu suất, bảo mật và khả năng mở rộng, ASP.NET giúp các doanh nghiệp và lập trình viên tạo ra các ứng dụng web chất lượng cao, đáp ứng nhu cầu của người dùng. Hãy cân nhắc sử dụng ASP.NET cho dự án tiếp theo của bạn để tận dụng những lợi ích mà nền tảng này mang lại.

Nguồn tham khảo: www.shareitsolutions.com/blog/what-is-asp-net/

.NET là gì? Nền tảng phát triển ứng dụng toàn diện của Microsoft

.NET là gì? .NET là nền tảng phát triển ứng dụng toàn diện của Microsoft, đã được sử dụng trong nhiều thập kỷ để xây dựng các ứng dụng web, desktop và di động, từ các startup đến các doanh nghiệp lớn. .NET không chỉ đóng vai trò trung tâm trong ngành phát triển phần mềm mà còn được ưa chuộng rộng rãi trong cộng đồng lập trình viên. Điều này thể hiện qua số lượng dự án mã nguồn mở và sự hiện diện của C# trong top năm ngôn ngữ lập trình phổ biến nhất. Với phiên bản mới nhất, .NET 5, Microsoft đã cách mạng hóa ngành công nghiệp bằng việc tiên phong khái niệm phát triển phần mềm toàn cầu.

Cùng TopDev tìm hiểu chi tiết về .NET trong bài viết dưới đây!

dotnet là gì?
.NET là gì? Nền tảng phát triển ứng dụng toàn diện của Microsoft

.NET là gì?

.NET hay còn được gọi là dotnet là một nền tảng phát triển mã nguồn mở và đa nền tảng, được thiết kế để xây dựng nhiều loại ứng dụng khác nhau. Được phát triển bởi Microsoft, .NET hỗ trợ nhiều ngôn ngữ lập trình và thư viện để xây dựng các ứng dụng web, di động, desktop, IoT và nhiều hơn nữa.

Các ngôn ngữ lập trình hỗ trợ bởi .NET

  • C# (C sharp): Ngôn ngữ lập trình hướng đối tượng hiện đại, thuộc họ ngôn ngữ C. Cú pháp của nó quen thuộc với các lập trình viên C, C++, Java và JavaScript.
  • F# (F sharp): Ngôn ngữ lập trình chức năng, cũng hỗ trợ lập trình hướng đối tượng.
  • Visual Basic: Ngôn ngữ lập trình lịch sử của Microsoft, nay đã trở thành ngôn ngữ lập trình hướng đối tượng hoàn chỉnh trong .NET.

Ngoài các ngôn ngữ trên, .NET còn hỗ trợ nhiều ngôn ngữ khác thông qua Common Language Infrastructure (CLI), đảm bảo khả năng tương tác giữa các ngôn ngữ trên nền tảng này.

Thị trường .NET tuyển dụng như thế nào? Xem ngay việc làm .NET tại TopDev

Kiến trúc và thành phần của .NET

.NET cho phép bạn xây dựng nhiều loại ứng dụng khác nhau nhờ vào kiến trúc tối ưu và mô đun của nó. Các thành phần chính bao gồm:

  • CoreCLR: Đây là runtime của .NET, chịu trách nhiệm thực thi các chương trình CLI và bao gồm một trình biên dịch just-in-time.
  • CoreFX: API của nền tảng, cung cấp các thư viện chuẩn để thực hiện các chức năng thông dụng như quản lý hệ thống tệp, xử lý ngoại lệ, giao tiếp mạng, đa luồng, và nhiều hơn nữa.

Mô hình ứng dụng .NET

Ngoài các thành phần cốt lõi trên, .NET cung cấp các framework hỗ trợ phát triển các loại ứng dụng khác nhau:

  • ASP.NET: Framework cho phép xây dựng các ứng dụng web và web API.
  • Windows Presentation Foundation (WPF): Giao diện người dùng đồ họa cho các ứng dụng desktop Windows.
  • Xamarin: Framework để xây dựng các ứng dụng di động, TV và desktop đa nền tảng.
  • Blazor: Framework để xây dựng ứng dụng web client bằng C#, cũng cho phép tạo các ứng dụng web client bằng mã WebAssembly.
  • ML.NET: Framework học máy, giúp tích hợp các mô hình học máy vào ứng dụng .NET của bạn.

Ngoài ra, .NET còn hỗ trợ nhiều tác vụ lập trình thông dụng khác như quản lý tệp, giao tiếp mạng, bảo mật, truy cập cơ sở dữ liệu và nhiều hơn nữa. Các thư viện cụ thể có thể được tìm thấy trên kho lưu trữ NuGet, giúp bạn tạo, chia sẻ và sử dụng các thư viện .NET cho hầu hết mọi mục đích.

.NET không chỉ hỗ trợ nhiều ngôn ngữ lập trình mà còn khuyến khích các best practices như Dependency Injection, giúp giảm sự phụ thuộc giữa các thành phần của ứng dụng và dễ dàng kiểm thử. .NET cũng hỗ trợ kiểm thử đơn vị và tích hợp thông qua xUnit.

>> Đọc thêm: Hệ sinh thái .NET – dotNET Ecosystem

Từ .NET Framework đến .NET Platform

.NET được ra mắt vào năm 2002 với mục tiêu tạo ra một nền tảng phát triển toàn cầu cho mọi ngôn ngữ lập trình. Ban đầu, .NET chủ yếu hướng đến Windows, nhưng sau đó đã mở rộng ra nhiều nền tảng khác như Linux, hệ thống nhúng, thiết bị di động và trình duyệt.

  • .NET Framework: Phiên bản ban đầu của .NET, chỉ chạy trên Windows và hiện đang trong giai đoạn kết thúc vòng đời sau khi phát hành .NET 5.
  • Mono: Dự án mang .NET đến các máy Linux, nhưng không luôn tương thích hoàn toàn với .NET Framework.
  • .NET Core: Phiên bản viết lại hoàn toàn của .NET Framework với mục tiêu đa nền tảng, hỗ trợ Windows, Linux và Mac.
  • .NET Standard: Tiêu chuẩn hóa các API của .NET để tạo ra các thư viện đa nền tảng.

Để hiểu rõ hơn về các khái niệm trên, đọc ngay bách khoa toàn thư .NET

Cài đặt .NET

Vì vậy, chúng tôi biết mình muốn làm việc với C# và chúng tôi biết mình cần .NET. Làm cách nào để có được nền tảng .NET trên máy tính của chúng tôi?

Cài đặt .NET
Cài đặt .NET – cách 1
  1. Tải xuống Visual Studio – một môi trường phát triển tích hợp (IDE) dành cho các ứng dụng .NET. Nó hoạt động như một ứng dụng, giống như trình duyệt web bạn đang sử dụng để xem bài viết này. Visual Studio đi kèm với nền tảng .NET, một trình chỉnh sửa mã, và các công cụ bổ sung để giúp bạn viết mã.
  2. Tải xuống .NET SDK (bộ công cụ phát triển phần mềm). SDK cũng đi kèm với nền tảng .NET, nhưng không có công cụ chỉnh sửa mã. Thay vì là một ứng dụng trên máy tính của bạn, SDK được truy cập thông qua giao diện dòng lệnh (CLI) — để sử dụng SDK, bạn sẽ mở terminal trên máy tính của mình và gõ lệnh thay vì nhấp vào các nút. Trong ví dụ này, bạn có thể thấy một terminal trong đó người dùng đã chạy các lệnh như dotnet newdotnet run để xây dựng một ứng dụng mới, sau đó chạy nó (ứng dụng chỉ in ra “Hello World!“).
Cài đặt .NET
Cài đặt dotNET – cách 2

Đọc thêm: Tìm hiểu về các khái niệm liên quan cũng như cách tạo một strong named assembly trong .NET

Ưu và Nhược Điểm của .NET

Ưu Điểm của .NET

  1. Hiệu Suất Cao: .NET có hiệu suất cao nhờ vào khả năng biên dịch Just-In-Time (JIT) và tối ưu hóa mã nguồn.
  2. Đa Nền Tảng: .NET Core và .NET 5+ hỗ trợ chạy trên nhiều hệ điều hành như Windows, macOS, và Linux, giúp phát triển ứng dụng đa nền tảng dễ dàng hơn.
  3. Hỗ Trợ Nhiều Ngôn Ngữ Lập Trình: .NET hỗ trợ nhiều ngôn ngữ lập trình như C#, F#, Visual Basic, giúp lập trình viên lựa chọn ngôn ngữ phù hợp với nhu cầu của mình.
  4. Bảo Mật Tốt: .NET cung cấp nhiều tính năng bảo mật như xác thực và ủy quyền, mã hóa dữ liệu, và bảo vệ chống tấn công XSS, CSRF.
  5. Thư Viện Phong Phú: .NET có một hệ thống thư viện phong phú (CoreFX) hỗ trợ nhiều chức năng từ quản lý tệp, giao tiếp mạng, đến xử lý dữ liệu.
  6. Phát Triển Nhanh Chóng với Visual Studio: Visual Studio là môi trường phát triển tích hợp mạnh mẽ, hỗ trợ tốt cho lập trình .NET, giúp tăng tốc quá trình phát triển và gỡ lỗi.
  7. Cộng Đồng Lớn và Tài Nguyên Hỗ Trợ: .NET có một cộng đồng lập trình viên lớn và nhiều tài nguyên học tập, giúp dễ dàng tìm kiếm hỗ trợ và giải pháp cho các vấn đề kỹ thuật.
  8. Hỗ Trợ Kiểm Thử: .NET hỗ trợ tốt cho việc kiểm thử đơn vị và kiểm thử tích hợp với các công cụ như xUnit, MSTest, và NUnit.

Nhược Điểm của .NET

  1. Khó Khăn Trong Việc Học: .NET có thể khó khăn đối với người mới bắt đầu do sự phức tạp của hệ thống và yêu cầu kiến thức về nhiều ngôn ngữ và công nghệ khác nhau.
  2. Chi Phí Cao: Một số công cụ và dịch vụ liên quan đến .NET, đặc biệt là các phiên bản cao cấp của Visual Studio và Azure, có chi phí cao.
  3. Kích Thước Lớn: Ứng dụng .NET thường có kích thước lớn do cần bao gồm nhiều thư viện và phụ thuộc.
  4. Tốc Độ Cập Nhật Nhanh: .NET thường xuyên cập nhật phiên bản mới, điều này đòi hỏi lập trình viên phải luôn cập nhật kiến thức và có thể gặp khó khăn trong việc duy trì tính tương thích của các ứng dụng hiện có.
  5. Hiệu Suất Đối Với Ứng Dụng Nhẹ: Đối với một số ứng dụng nhẹ và đơn giản, việc sử dụng .NET có thể dẫn đến hiệu suất không tối ưu so với các công nghệ khác như Node.js hoặc Python.
  6. Phụ Thuộc vào Microsoft: .NET là sản phẩm của Microsoft, do đó có sự phụ thuộc vào các quyết định và chiến lược của công ty này.

Bài viết liên quan:

.NET đã và đang là nền tảng phát triển ứng dụng toàn diện, đáp ứng mọi nhu cầu từ web, di động, desktop đến IoT. Với .NET 5, Microsoft tiếp tục củng cố vị thế của mình trong ngành phát triển phần mềm, mang lại cho các nhà phát triển một công cụ mạnh mẽ và linh hoạt để xây dựng các ứng dụng hiện đại.

Xem việc làm .NET fresher update mới nhất tại TopDev

Nguồn tham khảo:

  • www.codecademy.com/article/what-is-net
  • auth0.com/blog/what-is-dotnet-platform-overview/