CHƯƠNG 1: TỔNG QUAN VỀ BÀI TOÁN ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN 1. Tổng quan về sao chép và sử dụng lại mã nguồn 1.1 Vấn đề sao chép và sử dụng lại mã nguồn Cuộc cách mạng công nghiệp lần thứ tư được nhắc đến trong những năm gầy đây được trợ giúp rất lớn từ phát triển vượt bậc của lĩnh vực Công nghệ kỹ thuật số, Công nghệ thông tin. Trong đó, ngành công nghiệp phát triển mềm cũng đóng góp không nhỏ với việc liên tục nghiên cứu ra những công nghệ, ngôn ngữ lập trình, thư viện hay framework mới. Lập trình viên trong thời đại ngày nay được tiếp cận với một lượng tài nguyên khổng lồ và gần như không giới hạn.
Nếu như trước kia, các tài liệu của các ngôn ngữ lập trình hay sự hỗ trợ từ cộng đồng là hạn chế, thì ngày nay, những cộng đồng lập trình trên toàn thế giới (stackoverflow, github…) cho phép lập trình viên nhanh chóng học hỏi và tận dụng lại tri thức từ những người đi trước. Đôi khi một bài toán trước đây cần nhiều thời gian suy nghĩ, thì ngày nay có thể đã được lập trình viên đi trước chia sẻ công khai, chỉ cần sao chép về và đưa vào dự án của mình. Tuy nhiên, việc này cũng có thể gây ra những hậu quả xấu trong giai đoạn bảo trì và nâng cấp phần mềm. Chẳng hạn như một lỗi được phát hiện trong một đoạn mã nguồn đã bị sao chép, tất cả các đoạn tương tự như nó sẽ phải được kiểm tra và sửa cho cùng một lỗi như vậy.
Các đoạn mã nguồn trùng lặp sẽ làm tăng đáng kể công việc cần thực hiện khi cần bảo trì hoặc chỉnh sửa – nâng cấp mã nguồn. Điều này sinh ra nhiều nghiệp vụ trong phát triển phần mềm chẳng hạn như hiểu và chuyển giao chương trình, phân tích chất lượng mã nguồn (ít lặp hơn có nghĩa là mã nguồn chất lượng tốt hơn), kiểm tra tính duy nhất của bộ mã nguồn khi đăng ký bản quyền, phân tích cải tiến phần mềm, phát hiện các đoạn mã nguồn không tốt. Do vậy, việc phát hiện mức độ tương tự giữa các mã nguồn là một phần quan trọng và có giá trị lớn trong phân tích phần mềm. Các sinh viên ngành Công nghệ thông tin trong thời đại mới cũng được thừa hưởng một môi trường sinh động và đa dạng hơn nhiều so với các thế hệ sinh viên trước.
Giờ đây việc tiếp cận các ngôn ngữ lập trình mới, các thư viện/framework có độ trưởng thành cao được cộng Luan van 4 đồng chia sẻ, giúp cho sinh viên dù chưa có nhiều kinh nghiệm cũng có thể dễ dàng xây dựng nên một phần mềm tương đối hoàn chỉnh. Việc này rút ngắn thời gian tạo ra sản phẩm, tuy nhiên điều này sẽ làm giảm khả năng sáng tạo, đào sâu tìm tòi giải pháp của sinh viên. Trong khi đây là yếu tố rất quan trọng trong giai đoạn sinh viên công nghệ thông tin được đào tạo tại trường.2 Những tác động của sao chép và sử dụng lại mã nguồn Mặc dù việc sao chép và kế thừa lại mã nguồn thường có chủ đích và có thể mang lại giá trị ở một số mặt như: tiết kiệm thời gian, nguồn lực phát triển lại, giảm thiểu lỗi do các mã nguồn được sao chép đã chạy tốt và được kiểm chứng. Bên cạnh những ưu điểm trình bày ở trên, việc sao chép, sử dụng lại các mã nguồn cũng có những nhược điểm nhất định cần quan tâm.
Đối với công tác đào tạo: Giảm khả năng sáng tạo của sinh viên: từ đó giảm chất lượng của công tác đào tạo. Kết quả đào tạo không khách quan: từ đó giáo viên khó đánh giá chất lượng kết quả đào tạo để đưa ra phương hướng, điều chỉnh cho nội dung giảng dạy của mình. Đối với quy trình phát triển phần mềm: Tăng khả năng lỗi tiềm ẩn trong những đoạn mã nguồn giống nhau, từ đó gây khó khăn cho công tác bảo trì, phát triển mở rộng. Gây khó khăn cho công tác tối ưu mã nguồn, các đoạn mã nguồn tương tự nhau lặp đi lặp lại trong ứng dụng.3 Ý nghĩa của việc đánh giá mức độ tương tự giữa các mã nguồn Đối với công tác đào tạo: Phát hiện sao chép: Hỗ trợ cho giảng viên trong việc đưa ra mức độ tương tự nhau giữa các cặp mã nguồn, từ đó giảng viên có đánh giá và nhắc nhở sinh viên chủ động thực hiện bài tập của mình.
Luan van 5 Phân tích và đánh giá: Giúp giáo viên phân tích tính trùng lặp giữa các phương án của sinh viên khi triển khai thuật toán (trong trường hợp sinh viên vô tình có cùng ý tưởng). Đối với quy trình phát triển phần mềm: Phân tích và cải tiến hiệu năng của những đoạn mã nguồn tương tự: Từ những đoạn mã nguồn tương tự, lập trình viên có thể tổng quát hóa để chuyển thành các thư viện dùng chung, việc này vừa giảm tải dung lượng mã nguồn, đồng thời đảm bảo tính tinh gọn và dễ bảo trì. Tìm ra những đoạn mã nguồn không tốt: Trong quá trình phát triển dự án, đôi khi lập trình viên tìm kiếm và sử dụng những đoạn mã nguồn được cộng đồng chia sẻ. Đôi khi những đoạn mã này tiềm ẩn nhiều rủi ro và cần tìm kiếm để thay thế.
Việc sao chép chính xác được vị trí những đoạn mã nguồn tương tự nhau này là rất cần thiết. Phát hiện sao chép mã nguồn mà không được phép: Cùng với sự phát triển của Internet, mã nguồn mở, việc chia sẻ và tái sử dụng các đoạn code là vô cùng phổ biến. Điều này dẫn đến có khả năng việc sao chép chưa được sự cho phép của tác giả mã nguồn gốc. Việc xác định mức độ tương tương tự giữa các đoạn mã nguồn, cũng là cơ sở giúp phân định cho các cơ quan quản lý trong việc đảm bảo đăng ký bản quyền mã nguồn.4 Giới thiệu các kiểu sao chép mã nguồn phổ biến Khi một sinh viên sử dụng lại mã nguồn được viết bởi một người khác, sinh viên đó thường có thói quen sẽ điều chỉnh lại một chút nhằm mục đích tránh cho giáo viên có thể nhận biết sự sao chép này.
Bằng cách vận dụng sự sáng tạo và kiến thức đã có về ngôn ngữ lập trình, sinh viên có rất nhiều cách khác nhau để tạo ra một phiên bản mới của mã nguồn mà mình vừa sao chép. Dưới đây là danh sách một số kiểu sao chép mã nguồn phổ biến, được liệt kê theo thứ tự từ đơn giản đến phức tạp: 1. Thay đổi định dạng hoặc thêm/sửa các “comment code” (ghi chú). Thay đổi tên của các hàm hoặc các biến.
Thay đổi thứ tự các toán hạng trong các biểu thức. Thay đổi kiểu dữ liệu của các biến. Thay một biểu thức bằng một biểu thức tương đương 6. Thêm các đoạn code dư thừa (deadcode) 7.
Thay đổi thứ tự của các đoạn mã nguồn độc lập. Thay đổi một vòng lặp bởi một vòng lặp khác 9. Thay đổi cấu trúc của câu lệnh lựa chọn 10. Thay thế việc gọi hàm mới bằng nội dung hàm 11.
Kết hợp mã nguồn sao chép với mã nguồn của bản thân. Dưới góc nhìn đào tạo, việc tìm hiểu và tham khảo mã nguồn của người khác là rất bình thường và không đáng phê phán (trong trường hợp bài tập này được giảng viên cho phép). Đây cũng là một cách để sinh viên học hỏi và ghi nhớ kiến thức một lần nữa. Sau khi hiểu thuật toán, nếu sinh viên cố gắng tự viết lại giải thuật bằng ngôn ngữ của mình cũng là một lần học tập.
Ví dụ cho việc này chính là kiểu sao chép số 11 được liệt kê trên đây. Trong khi đó các kiểu sao chép từ 1 đến số 10, phần nào đó thể hiện khía cạnh sinh viên cố tình sử dụng thủ thuật sau khi đã sao chép mã để tránh giáo viên phát hiện. Đánh giá chương trình xác định mức độ tương đồng giữa các mã nguồn Để xác định tính hiệu quả của một chương trình đánh giá mức độ tương đồng giữa các mã nguồn, người ta thường sử dụng khái niệm ROC (Receiver operating characteristic), còn gọi là đường cong đặc trưng hoạt động. Khái niệm đường cong ROC bắt nguồn từ một phần của lĩnh vực được gọi là thuyết phát hiện tín hiệu.
Từ các tín hiệu nhận được, máy sẽ phân tích và vẽ đường cong ROC, để phân biệt tín hiệu của máy bay địch và tín hiệu nhiễu (noise) trong thế chiến thứ hai. Từ sau những năm 1970, ROC được dùng phổ biến để diễn dịch kết quả các test trong chẩn đoán y học [1]. Với đặc tính là một đồ thị được tạo ra bằng cách biểu diễn tỷ lệ dự báo Dương tính giả (true positive rate - TPR) và tỷ lệ dự báo Âm tính giả (false positive rate - FPR) tại các ngưỡng (threshold) khác nhau, ROC gợi ý cách so sánh hiệu suất của hai chương trình đánh giá độ tương đồng mã nguồn [2]. Luan van 7 Trong phần trình bày tiếp theo dưới đây, chúng ta sẽ giới thiệu về khái niệm Ma trận nhầm lẫn và ứng dụng của đường cong ROC trong bài toán phân tích mức độ tương tự giữa các mã nguồn.1 Khái niệm ma trận nhầm lẫn (Confusion Matrix) Confusion Matrix hay còn gọi là Ma trận nhầm lẫn là bố cục bảng cụ thể cho phép hình dung hiệu suất của một hệ thống phân loại.
Mỗi hàng trong ma trận sẽ biểu diễn thông tin cho một trường hợp của một lớp cụ thể. Với một ma trận nhầm lẫn, có thể dễ dàng nhận ra liệu hệ thống phân loại có gắn nhãn nhầm giữa lớp này với lớp khác hay không [3]. Hãy xem xét ví dụ thực tế dưới đây: Vào một ngày nào đó, Bệnh viện A có 100 bệnh nhân đến khám bệnh, giả sử thực tế là trong 100 bệnh nhân có 60 người mắc bệnh, 40 người không có bệnh. Sau khi thăm khám, bệnh viện đưa ra kết quả: Trong 60 người có bệnh thật gồm: o 50 người chẩn đoán có bệnh o 10 người chẩn đoán không mắc bệnh.
Trong 40 người không có bệnh gồm: o 25 người chẩn đoán không mắc bệnh o 15 người chẩn đoán là mắc bệnh.1: Kết quả ma trận nhầm lẫn sau khi chẩn đoán Dương tính (P) Âm tính (N) Dương tính TP (50) FP (15) Âm tính FN (10) TN (25) Từ ma trận cơ bản này, ta sẽ có một số thuật ngữ sau: Condition positive (P): Tổng số ca dương tính thực tế. Condition Negative (N: Tổng số ca âm tính thực tế. True positive (TP): Số các ca dự đoán dương tính đúng hay dương tính thật. True negative (TN): Số các ca dự đoán âm tính đúng hay âm tính thật.