Bug là gì? Tìm hiểu về các lỗi trong phát triển phần mềm

25/05/2024 09:50
Thuật ngữ
Phần mềm đóng vai trò then chốt trong việc điều hành các hoạt động hàng ngày, từ các ứng dụng di động đơn giản đến những hệ thống quản lý doanh nghiệp phức tạp. Một yếu tố không thể tránh khỏi trong quá trình phát triển và thử nghiệm phần mềm là sự xuất hiện của các lỗi, hay còn gọi là "bug".Trong bài viết này, TechWorks sẽ đi sâu vào khái niệm "Bug" là gì trong công nghệ máy tính, phân loại các loại Bug thường gặp và nguyên nhân gây ra “lỗi” trong phần mềm.

Mục lục

Bug là gì?

Bug là gì?

Trong IT, "bug" là lỗi mã hóa trong chương trình máy tính. Quá trình phát hiện lỗi trước khi người dùng gặp phải được gọi là "debugging" (gỡ lỗi). Việc gỡ lỗi diễn ra sau khi mã được viết và tiếp tục trải qua trong từng giai đoạn khi mã được kết hợp với các đơn vị lập trình khác để tạo thành sản phẩm phần mềm hoàn chỉnh, chẳng hạn như hệ điều hành hoặc ứng dụng.

Bug thường được phát hiện sau khi sản phẩm đã ra mắt hoặc trong quá trình thử nghiệm beta. Khi điều này xảy ra, người dùng phải tìm cách tránh sử dụng phần mã lỗi hoặc nhận các bản sửa lỗi từ các software developer. Tuy nhiên, Bug không phải là vấn đề duy nhất mà các chương trình máy tính có thể gặp phải.

Một chương trình có thể chạy mà không gặp Bug. Tuy nhiên, chúng ta có thể gặp những loại vấn đề khó phát hiện và khác phục hơn. Giả sử như việc phần mềm vẫn hoạt động nhưng không đạt được hiệu quả như mong đợi ở một số chức năng quan trọng. 

Một chương trình được thiết kế tốt sẽ được phát triển theo quy trình kiểm soát chất lượng chặt chẽ, giúp giảm thiểu số lượng bug trên hàng nghìn dòng mã. Việc kiểm tra khả năng hoạt động của phần mềm là một phần không thể thiếu trong quy trình phát triển sản phẩm. Nó giúp đảm bảo rằng sản phẩm cuối cùng không chỉ hoạt động ổn định mà còn thân thiện với người dùng và đáp ứng tốt các yêu cầu cụ thể của doanh nghiệp đặt ra.

Đây là lý do tại sao việc thử nghiệm các tính năng của sản phẩm được xem là một bước quan trọng trong quá trình phát triển phần mềm, nhằm mang lại trải nghiệm tốt nhất cho người dùng.

Những nguyên nhân phổ biến gây ra Bug 

Những nguyên nhân phổ biến gây ra Bug

Hầu hết các bug phát sinh là từ sai sót của lập trình viên trong việc thiết lập mã nguồn của kiến ​​trúc phần mềm hoặc sản phẩm. Một ứng dụng phần mềm được coi là có lỗi nếu nó chứa nhiều lỗi ảnh hưởng đến chức năng của hệ thống và dẫn đến kết quả không chính xác.

Một số lý do phổ biến có thể dẫn đến bug trong phần mềm như sau:

  • Độ phức tạp của phần mềm: Khi phần mềm trở nên phức tạp, số lượng dòng mã tăng lên và việc quản lý, kiểm tra toàn bộ hệ thống trở nên khó khăn hơn. Điều này dẫn đến việc khó phát hiện và sửa chữa lỗi kịp thời.
  • Thông tin sai lệch và hiểu lầm giữa developer và tester: Khi các yêu cầu và chức năng của phần mềm không được truyền đạt rõ ràng, developer có thể mã hóa sai, dẫn đến việc hệ thống hoạt động không đúng như mong muốn.
  • Sai sót trong khi mã hóa: Khi các lập trình viên phải làm việc dưới áp lực lớn và trong thời gian ngắn thì việc xảy ra lỗi là không thể tránh khỏi.
  • Sự thay đổi yêu cầu của dự án: Các thay đổi yêu cầu của dự án cũng có thể dẫn đến lỗi. Khi yêu cầu thay đổi mà không có đủ thời gian để điều chỉnh và kiểm tra, các phần mới của mã có thể chứa nhiều lỗi hơn.
  • Thiếu thời gian để viết mã và kiểm tra: Khi các dự án phải hoàn thành trong thời gian ngắn, các giai đoạn kiểm tra và sửa lỗi thường bị cắt giảm, dẫn đến việc phần mềm được phát hành với nhiều lỗi chưa được phát hiện.
  • Sự chủ quan của các lập trình viên: Khi các lập trình viên hoặc tester quá tự tin vào khả năng của mình, họ có thể bỏ qua các bước kiểm tra quan trọng hoặc không chú ý đến các chi tiết nhỏ, dẫn đến việc bỏ sót lỗi.
  • Thiếu tài liệu: Khi tài liệu không đầy đủ hoặc không được cập nhật thường xuyên, các thành viên mới của dự án hoặc tester có thể không hiểu rõ về hệ thống, dẫn đến việc phát hiện lỗi muộn hoặc không phát hiện được lỗi.
  • Thiếu các loại thử nghiệm được sử dụng trong một dự án (chỉ thử nghiệm tự động hóa; chỉ thử nghiệm thủ công, v.v.): Nếu chỉ sử dụng thử nghiệm tự động hoặc chỉ thử nghiệm thủ công, các loại lỗi khác nhau có thể không được phát hiện. Việc sử dụng kết hợp cả hai phương pháp sẽ giúp phát hiện lỗi toàn diện hơn.
  • Thiếu tester có chuyên môn cao: Đây cũng là những yếu tố dẫn đến lỗi. Tester có kinh nghiệm và kỹ năng sẽ có khả năng phát hiện lỗi nhanh chóng và hiệu quả hơn, trong khi các công cụ kiểm tra tiên tiến giúp việc kiểm tra trở nên dễ dàng và chính xác hơn.
  • Thiếu các công cụ kiểm tra mức độ sử dụng hoặc các công cụ kiểm tra bất tiện.

Các loại Bug thường gặp

Trong quá trình phát triển phần mềm, việc gặp phải bug là điều không thể tránh khỏi. Mỗi loại bug đều mang đến những thách thức và rủi ro riêng, có thể ảnh hưởng đến hiệu suất, bảo mật, hoặc trải nghiệm người dùng của sản phẩm. Hiểu rõ và phân loại các loại bug thường gặp không chỉ giúp tester dễ dàng hơn trong việc nhận diện mà còn giúp developer trong việc sửa chữa lỗi, góp phần nâng cao chất lượng sản phẩm cuối cùng. Cùng TechWorks tìm hiểu 8 loại Bug thường gặp nhé!

Logic Errors

Logic error là một trong những loại lỗi nghiêm trọng nhất trong phát triển phần mềm. Đây là loại lỗi xảy ra khi chương trình chạy đúng theo mã đã viết nhưng lại tạo ra kết quả sai. Nguyên nhân gốc rễ của lỗi này thường là do sự cố trong logic lập trình cơ bản, từ đó dẫn đến việc thuật toán được sử dụng trong phần mềm bị sai lệch. Khi gặp logic error, toàn bộ nền tảng mà phần mềm dựa trên bị ảnh hưởng, khiến cho các chức năng của phần mềm không hoạt động như mong muốn.

Để khắc phục logic error, cần có sự thay đổi cơ bản trong thuật toán của phần mềm. Điều này có thể đòi hỏi việc thiết kế lại phần lớn hoặc toàn bộ hệ thống để đảm bảo rằng logic nền tảng của phần mềm là chính xác.

ogic error thường rất khó phát hiện vì chương trình không bị sự cố hoặc dừng hoạt động đột ngột. Thay vào đó, nó chạy bình thường nhưng lại tạo ra các kết quả không chính xác hoặc không như mong đợi. Các lỗi logic có thể phát sinh từ các tính toán sai, vòng lặp không đúng, điều kiện sai hoặc bất kỳ phần nào trong mã mà logic của chương trình bị lệch.

Việc phát hiện và sửa lỗi logic thường đòi hỏi các kỹ thuật thử nghiệm phần mềm chuyên sâu, bao gồm thử nghiệm hộp đen, thử nghiệm hộp trắng và thử nghiệm đơn vị để đảm bảo rằng mọi phần của mã đều hoạt động đúng theo yêu cầu.

Syntax Errors

Syntax Errors

Syntax Bug là loại lỗi xảy ra khi mã nguồn của phần mềm không tuân thủ cú pháp của ngôn ngữ lập trình mà nó được viết. Các ngôn ngữ lập trình như C, Java, Perl hoặc Python đều có các quy tắc cú pháp cụ thể mà mã nguồn phải tuân theo. Khi lập trình viên vi phạm các quy tắc này, sẽ xuất hiện Syntax Bug. Tuy nhiên, may mắn thay, các bug cú pháp thường dễ phát hiện và sửa chữa vì chúng được nhận diện bởi trình biên dịch trong quá trình biên dịch mã nguồn.

Syntax Bug có thể bao gồm các lỗi như thiếu dấu chấm phẩy, dấu ngoặc không khớp, từ khóa bị viết sai hoặc các lỗi khác liên quan đến cấu trúc của mã. Tuy nhiên, các trình biên dịch hiện đại thường cung cấp thông tin chi tiết về vị trí và loại Syntax Bug, giúp lập trình viên dễ dàng tìm và sửa chúng.

Ngoài ra, các công cụ phát triển tích hợp (IDE) cũng cung cấp các chức năng kiểm tra cú pháp tự động, giúp lập trình viên phát hiện Syntax Bug ngay khi viết mã.

Compilation Bugs

Quá trình biên dịch là việc chuyển đổi mã nguồn từ ngôn ngữ lập trình cấp cao sang ngôn ngữ máy mà máy tính có thể hiểu và thực thi được. Trong giai đoạn này, nhiều loại lỗi có thể phát sinh, bao gồm Syntax Bug và các bug khác liên quan đến quá trình biên dịch.

Ngay cả khi mã nguồn không có Syntax Bug, bug biên dịch vẫn có thể xảy ra. Compilation bugs thường do các vấn đề trong chính trình biên dịch hoặc do mã nguồn không tuân thủ các quy tắc ngữ nghĩa của ngôn ngữ lập trình.

Compilation bugs có thể bao gồm các lỗi như biến chưa được khai báo, lỗi kiểu dữ liệu, lỗi truy cập bộ nhớ hoặc các vấn đề khác liên quan đến cách mà mã nguồn tương tác với hệ thống. Các trình biên dịch thường cung cấp thông tin chi tiết về bug biên dịch, giúp lập trình viên xác định và sửa chữa chúng.

Quá trình sửa compilation bugs là một phần quan trọng của giai đoạn phát triển phần mềm, đảm bảo rằng mã nguồn có thể được chuyển đổi thành tệp thực thi một cách chính xác.

Runtime Errors

Runtime Errors là loại lỗi xảy ra khi phần mềm đang chạy và thực hiện các chức năng của nó. Sau khi mã chương trình đã được biên dịch thành công và tệp thực thi đã được tạo, bạn phải chạy phần mềm để kiểm tra hoạt động.

Tuy nhiên, lỗi trong quá trình sử dụng phần mềm có thể xảy ra do sự cố hoặc thiếu tài nguyên. Những lỗi này có thể xuất hiện dưới dạng các thông báo lỗi hoặc sự cố khiến phần mềm dừng hoạt động đột ngột.

Runtime Errors xảy ra có thể do nhiều nguyên nhân, bao gồm các vấn đề về bộ nhớ, logic errors không được phát hiện trong quá trình thử nghiệm, hoặc các điều kiện không mong đợi xảy ra trong môi trường thực thi. Ví dụ, phần mềm có thể gặp lỗi khi cố gắng truy cập vào tài nguyên không tồn tại hoặc khi gặp phải các điều kiện biên mà lập trình viên không lường trước được.

Để khắc phục runtime errors, cần phải quay lại giai đoạn mã hóa và tinh chỉnh mã nguồn. Việc kiểm tra kỹ lưỡng và sử dụng các công cụ thử nghiệm thời gian chạy có thể giúp phát hiện và sửa lỗi này. Ngoài ra, việc dự đoán và chuẩn bị cho các điều kiện triển khai thực tế của phần mềm cũng rất quan trọng, giúp đảm bảo rằng phần mềm có thể hoạt động ổn định trong mọi tình huống.

Resource Errors

Resource Errors xảy ra khi phần mềm cố gắng sử dụng nhiều tài nguyên hơn mức hệ thống cho phép hoặc khi giá trị của biến vượt quá giới hạn cho phép. Các resource errors phổ biến bao gồm tràn bộ đệm, sử dụng biến chưa được khởi tạo, vi phạm quyền truy cập và tràn ngăn xếp.

Những lỗi này thường xuất hiện khi phần mềm cố gắng truy cập vào bộ nhớ hoặc tài nguyên mà nó không có quyền hoặc khi giá trị của biến vượt quá phạm vi cho phép.

Tràn bộ đệm xảy ra khi phần mềm cố gắng ghi dữ liệu vượt quá kích thước của một bộ đệm, dẫn đến việc ghi đè lên các phần khác của bộ nhớ. Điều này có thể gây ra các lỗi nghiêm trọng và khó phát hiện, thậm chí có thể dẫn đến lỗ hổng bảo mật. Sử dụng biến chưa được khởi tạo có thể dẫn đến các giá trị không mong muốn hoặc không xác định, gây ra các hành vi không lường trước của phần mềm.

Ngoài ra, vi phạm quyền truy cập xảy ra khi phần mềm cố gắng truy cập vào bộ nhớ hoặc tài nguyên mà nó không có quyền, dẫn đến runtime errors.

Off-By-One Errors

Off-by-one Errors

Off-by-one Error là một loại logic error phổ biến trong lập trình, xảy ra khi giá trị bị lệch một đơn vị so với giá trị dự định, có thể cao hơn hoặc thấp hơn một đơn vị. Những lỗi này thường xảy ra trong các vòng lặp, khi mục bị thiết lập không chính xác, hoặc khi tính toán phạm vi sai lệch.

Chúng rất khó phát hiện vì mặc dù chương trình vẫn chạy, nhưng hành vi của chúng có thể không đúng như mong muốn. Những lỗi này thường dẫn đến kết quả sai lệch, gây khó khăn cho việc gỡ lỗi và có thể gây ra sự cố nghiêm trọng nếu không được khắc phục kịp thời. Việc kiểm tra cẩn thận các điều kiện và chỉ mục vòng lặp có thể giúp tránh Off-by-one errors.

Race Conditions

Race Conditions là bug xảy ra khi nhiều phần của chương trình cố gắng truy cập hoặc thay đổi cùng một dữ liệu cùng một lúc và kết quả phụ thuộc vào phần nào đến đó trước. Nó giống như hai vận động viên chạy trong một cuộc đua, trong đó kết quả cuối cùng (hành vi của chương trình) phụ thuộc vào vận động viên nào (phần mã) về đích trước.

Hãy tưởng tượng bạn đang xếp hàng thanh toán tại cửa hàng với một người bạn và cả hai đều muốn mua chai nước cuối cùng. Nếu cả hai bạn cố gắng lấy nó cùng một lúc, ai lấy được nó sẽ tùy thuộc vào ai nhanh hơn. Trong một chương trình, thời gian không thể đoán trước này có thể dẫn đến các vấn đề.

Memory Leaks

Trong khoa học máy tính, memory leak là một loại lỗi trong đó chương trình quản lý bộ nhớ không chính xác. Điều này có nghĩa là chương trình sẽ phân bổ bộ nhớ để sử dụng nhưng sau đó quên giải phóng nó trở lại hệ thống khi hoàn thành.

Hãy tưởng tượng nó giống như mượn một cuốn sách từ thư viện. Memory leaks giống như việc bạn quên trả lại cuốn sách sau khi đọc xong. Thư viện (bộ nhớ của máy tính) bắt đầu hết dung lượng vì tất cả sách (bộ nhớ) đã mượn đều không được trả lại.

Interface Errors

Interface Errors xảy ra khi có sự không khớp giữa cách bạn muốn sử dụng chương trình và cách chương trình thực sự hoạt động. Hầu hết các phần mềm đều phải tuân theo một số tiêu chuẩn nhất định. Nếu đầu vào cho chương trình của bạn không tuân theo các tiêu chuẩn này, bạn có thể gặp phải Interface Errors.

Ví dụ, Interface Errors có thể xảy ra nếu bạn có một API yêu cầu các tham số cụ thể, nhưng các tham số này không được cung cấp đúng cách. Nếu không được xử lý đúng, Interface Errors sẽ trông giống như lỗi của bạn, trong khi thực tế là lỗi từ phía người gọi. Điều này có thể gây ra sự khó chịu từ cả hai phía.

Việc có tài liệu rõ ràng và nắm bắt những lỗi này để chuyển lại cho người gọi một cách hữu ích là cách tốt nhất để nói: "Này, bạn chưa cung cấp cho chúng tôi những gì cần thiết để xử lý yêu cầu này." Điều này sẽ giúp giảm chi phí hỗ trợ và làm hài lòng khách hàng vì họ biết họ cần khắc phục điều gì.

Nếu bạn không phát hiện và báo cáo những lỗi này lại cho người gọi, chúng sẽ xuất hiện như runtime errors trong báo cáo của bạn và cuối cùng bạn sẽ phải tốn thời gian để kiểm tra lại mọi thứ.

Performance Bugs

Nhìn chung, không người dùng nào muốn sử dụng phần mềm có hiệu suất kém cả. Các bug trong phần mềm dẫn đến tốc độ giảm, độ ổn định, thời gian phản hồi tăng và mức tiêu thụ tài nguyên cao hơn được coi là performance bugs.

Dấu hiệu quan trọng nhất của loại bug này trong phần mềm là khi nhận thấy tốc độ tải chậm hơn bình thường hoặc phân tích thời gian phản hồi. Không giống như functional bugs gây ra sự cố hoặc kết quả đầu ra không chính xác, performance bugs có thể phức tạp hơn. Chúng có thể làm cho phần mềm chạy chậm, không phản hồi hoặc thậm chí bị treo khi tải nặng.

Nếu tìm thấy bất kỳ dấu hiệu nào như vậy, tester có thể bắt đầu chẩn đoán đó là performance bugs.

Phân biệt Bug, Error, Fault và Failure

“Bug, Error, Fault và Failure” đều được gọi là lỗi. Vậy điều khác biệt giữa 4 thuật ngữ này là gì? Hãy cùng TechWorks tìm hiểu nhé!

Bug

Bug là gì?

Bug được hiểu là sự khác biệt so với các yêu cầu của khách hàng. Nói một cách dễ hiểu, nó là khoảng cách giữa kết quả mong đợi và kết quả thực tế trong một ứng dụng hoặc một mô-đun cụ thể. Những sai lệch này được các lập trình viên phát hiện trong suốt quá trình thử nghiệm. Bug có thể xuất hiện dưới nhiều hình thức khác nhau như lỗi giao diện, lỗi chức năng, lỗi hiệu suất, hoặc lỗi bảo mật. 

Một số lỗi có thể chỉ là những chi tiết nhỏ, như một nút bấm không hoạt động đúng cách, trong khi một số khác có thể gây ra những vấn đề nghiêm trọng hơn, ảnh hưởng đến toàn bộ hệ thống. Để phát hiện và khắc phục những lỗi này, tester thường sử dụng nhiều phương pháp và công cụ khác nhau, từ thử nghiệm thủ công cho đến tự động hóa.

Error

Error là gì?

Error ám chỉ sự sai sót, hiểu lầm hoặc nhầm lẫn của các lập trình viên trong quá trình phát triển phần mềm. Một error có thể phát sinh từ nhiều nguyên nhân khác nhau. Ví dụ, một Software Developer có thể hiểu sai một ký hiệu thiết kế hoặc một lập trình viên có thể nhập sai tên biến – dẫn đến error. Lỗi này thường xuất phát từ việc nhập liệu sai, vòng lặp không chính xác hoặc cú pháp không đúng. 

Một ví dụ cụ thể có thể là việc sử dụng một công thức toán học không đúng cách trong mã nguồn, dẫn đến kết quả tính toán sai. Những error này có thể được phát hiện và sửa chữa thông qua quá trình thử nghiệm và xem xét mã nguồn cẩn thận. Việc sử dụng các công cụ hỗ trợ phát hiện lỗi tự động cũng giúp giảm thiểu các lỗi do con người gây ra.

Fault

Fault là gì?

Fault là một khái niệm quan trọng trong thử nghiệm phần mềm và thường được sử dụng để chỉ các sai sót trong mã nguồn mà dẫn đến sự cố trong việc thực thi phần mềm. Một fault có thể xảy ra khi phần mềm thiếu mã chịu lỗi hoặc mã xử lý các tình huống bất ngờ, dẫn đến ứng dụng không hoạt động đúng cách. 

Những fault này có thể phát sinh do nhiều nguyên nhân, bao gồm thiếu nguồn lực (chẳng hạn như bộ nhớ hoặc tài nguyên hệ thống không đủ), các bước thực hiện không hợp lệ (ví dụ như gọi một hàm với các tham số không đúng), hoặc định nghĩa dữ liệu không phù hợp (ví dụ như sử dụng một kiểu dữ liệu sai cho một biến). 

Những fault này cần được phát hiện và sửa chữa kịp thời để đảm bảo phần mềm hoạt động ổn định và đúng như mong đợi. Việc kiểm tra mã nguồn, thử nghiệm đơn vị và thử nghiệm tích hợp là những phương pháp quan trọng để phát hiện và xử lý các fault.

Failure

Failure là gì?

Khi phần mềm hoàn thành và được bàn giao cho khách hàng, bất kỳ vấn đề nào mà khách hàng phát hiện ra đều được coi là tình trạng "failure" của phần mềm. Một "failure" là biểu hiện cụ thể của một hoặc nhiều "fault" trong phần mềm khi được sử dụng trong môi trường thực tế. 

Nếu khách hàng gặp phải sự cố trong quá trình sử dụng phần mềm, sự cố đó được gọi là "failure". Những "failure" này có thể gây ra nhiều hậu quả khác nhau, từ sự khó chịu của người dùng đến những tổn thất lớn về tài chính hoặc danh tiếng cho công ty phát triển phần mềm. 

Việc phòng tránh và giảm thiểu các "failure" đòi hỏi một quy trình thử nghiệm và đảm bảo chất lượng nghiêm ngặt, bao gồm thử nghiệm chức năng, thử nghiệm phi chức năng, và thử nghiệm người dùng cuối. Đồng thời, việc lắng nghe phản hồi từ người dùng và thực hiện các điều chỉnh cần thiết cũng là một phần quan trọng của việc duy trì và cải thiện chất lượng phần mềm sau khi phát hành.

Lời kết

Qua bài viết này, chúng ta đã có cái nhìn toàn diện về khái niệm "bug" trong công nghệ máy tính, từ định nghĩa đến nguyên nhân gây ra lỗi ở phần mềm. Quá trình phát triển và kiểm thử phần mềm luôn đối mặt với những thách thức, nhưng với kiến thức vững vàng và quy trình kiểm thử hiệu quả, các nhóm phát triển có thể giảm thiểu rủi ro và đảm bảo sản phẩm cuối cùng đạt tiêu chuẩn cao nhất. 

Bài viết liên quan

Proxy là gì? Cách hoạt động và Giao thức của Proxy Server
Khi nhắc đến bảo mật Internet và thiết bị cá nhân, chúng ta thường nghĩ ngay đến các công cụ như phần mềm diệt vi-rút và VPN. Nhưng có những phương pháp bảo vệ ít được biết đến hơn mà bạn nên biết, trong đó có máy chủ proxy. Bài viết này giải thích cho bạn biết máy chủ proxy là gì, chúng hoạt động như thế nào và tại sao bạn có thể cần sử dụng một máy chủ proxy.
10 ngôn ngữ lập trình phổ biến nhất thế giới hiện nay
Theo bảng xếp hạng TIOBE Index và RedMonk, các ngôn ngữ lập trình như Python, JavaScript và Java được dự đoán sẽ tiếp tục chiếm ưu thế trong vài năm tới, đặc biệt khi các công nghệ mới như trí tuệ nhân tạo (AI), điện toán đám mây và blockchain tiếp tục định hình tương lai của ngành công nghệ.
Ngôn ngữ lập trình PHP là gì? Kiến thức cần thiết từ A-Z
PHP, viết tắt của "Hypertext Preprocessor", là một ngôn ngữ lập trình kịch bản phía máy chủ được sử dụng rộng rãi trong phát triển web. Kể từ khi ra đời, PHP đã không ngừng phát triển để đáp ứng nhu cầu ngày càng cao trong lĩnh vực công nghệ, vậy nên nó giữ vững vị trí là một trong những ngôn ngữ được yêu thích nhất bởi lập trình viên toàn cầu.
9