6. Kết quả nghiên cứu, đóng góp khoa học của luận án
4.3.1.2. Lập trình an toàn
Lập trình an toàn liên quan đến các vấn đề về lỗi: phát hiện, chịu lỗi, sao lưu, v.v.. Mục tiêu của nhà phát triển là xây dựng một hệ thống an toàn, trong đó các công việc nghiệp vụ của người dùng được thực hiện một cách đúng đắn. Tuy nhiên, điều đó là thách thức khó khăn để vượt qua trong hiện trạng khoa học kĩ thuật hiện nay.
1. Các biến cần được định nghĩa quyền truy cập private: class Person{
String name; int age;} bởi
class Person{
private String name; private int age;}
2. Các đối tượng cần được thiết lập "uncloneable" class Person{
/*do not use clone()*/} bởi
class Person{
public final void clone()
throws java.lang.CloneNotSupportedException{
throw new java.lang.CloneNotSupportedException();}}
Nhiều nghiên cứu cho thấy hầu hết các lỗi được tạo ra khi lập trình viên mắc phải các lỗi lập trình, vì vậy nhà phát triển cần phải được đào tạo về những vấn đề này.
4.3.1.3. Cây cú pháp trừu tƣợng
"Cây cú pháp trừu tượng" (AST, abstract syntax tree) là một cây biểu diễn cấu trúc cú pháp trừu tượng của mã nguồn: mỗi nút của cây biểu diễn một cấu trúc bên trong mã nguồn. Aho [3] giới thiệu cây cú pháp trừu tượng của một vài thành phần cơ bản như sau: mỗi cấu trúc được biểu diễn bởi một nút sao cho các nút con của nó biểu diễn các thành phần con của cấu trúc đó.
102
1. Biểu diễn các khối bằng cây cú pháp trừu tượng: coi khối như 1 câu lệnh đơn, cây cú pháp trừu tượng của các khối đơn giản là cây cú pháp cho tập có thứ tự các lệnh đơn. Sau đó thay thế nút biểu diễn khối bằng cây cú pháp trừu tượng con biểu diễn bên trong khối đó, đồng thời trỏ liên kết từ nút cha của nút biểu diễn khối đến nút gốc của cây cú pháp trừu tượng biểu diễn trong khối.
2. Cây cú pháp trừu tượng của một lệnh: trước hết cần định nghĩa toán tử của câu lệnh để xây dựng cây cú pháp trừu tượng cho một lệnh đơn: toán tử của một câu lệnh đơn bắt đầu bằng một từ khóa chính là từ khóa đó.
Toán tử while của câu lệnh while. Toán tử do của câu lệnh do-while.
Câu lệnh điều kiện có thể được xử lý bằng cách định nghĩa các toán tử if- else và if tương ứng cho các câu lệnh if có và không có phần else.
3. Cây cú pháp trừu tượng cho một công thức. Khi đó, nút cha sẽ biểu diễn toán tử và các nút con sẽ biểu diễn các toán hạng.
Ví dụ cây cú pháp trừu tượng cho hàm cài đặt thuật toán Euclide trong Hình 4.20. int Euclide{ while b != 0 if a > b a := a - b; else b := b - a; return a;}
Hình 4.20. Cây cú pháp trừu tượng của hàm cài đặt thuật toán Euclide
≠ branch b - - > assign assign while return Statement sequence a b a b b a b 0 a a
103
4.3.2. Luật và việc áp dụng trên cây cú pháp trừu tƣợng
Luật là các nguyên tắc nhằm thay đổi mã nguồn để nâng cao chất lượng công việc. Chúng mang ý nghĩa thực nghiệm và thu được từ những người có kinh nghiệm trong lập trình. Chúng bao gồm một số thông tin quan trọng: mô tả, những câu hỏi về cách áp dụng "như thế nào, vì sao, ở đâu", v.v.. Chúng phải được áp dụng trên một số thành phần cho trước trong một ngữ cảnh đặc biệt, do đó việc triển khai luật trong thực tế phát triển cần đến sự dịch từ mã nguồn sang cây cú pháp trừu tượng.
4.3.2.1. Xây dựng các luật
Từ bài toán lập trình an toàn và tối ưu hóa mã nguồn được nhắc đến ở trên, các lập trình viên cần lưu trữ một tập các luật để sử dụng sau này. Tuy nhiên, các kĩ thuật đó được sử dụng trong ngữ cảnh chung và họ cần tập trung vào các kĩ thuật tương thích với ngôn ngữ Java. Ngoài ra, họ cần sử dụng các luật từ những nguồn an toàn: từ nhà sản xuất IDE, lập trình viên có kinh nghiệm, chuyên gia, v.v.. Ở đây quan tâm đến ngôn ngữ Java, do đó cần tập trung vào tài nguyên từ các nguồn Oracle, Google hay AppPerfect. Khi áp dụng các luật, lập trình viên nên lưu trữ chúng để tái sử dụng hoặc để thu thêm kinh nghiệm trong làm việc sau này.
4.3.2.2. Sử dụng luật phát hiện các thành phần tiềm năng trong mã nguồn
Như đã trình bày ở trên, mỗi luật tác động đến các thành phần khác nhau của mã nguồn, và những thành phần này là kết quả của quá trình chuyển đổi để có được cây cú pháp từ mã nguồn. Vì vậy, chúng tôi đề xuất chiến lược 4 bước được sử dụng để phát hiện các thành phần tiềm năng:
Bước 1. Chuyển đổi tất cả các tệp mã nguồn của dự án Java thành cây cú pháp trừu tượng.
Bước 2. Chia các thành phần của mỗi cây cú pháp trừu tượng thành các nhóm, căn cứ vào đặc điểm của các thành phần: phương thức triệu gọi, khai báo biến, v.v..
Bước 3. Áp dụng từng quy tắc đối với các thành phần phù hợp: nếu 1 thành phần không phù hợp với bất kỳ quy tắc nào, nó là 1 thành phần tiềm năng. Bước 4. Liệt kê tất cả các thành phần tiềm năng và thu thập thông tin có liên
quan với mỗi thành phần tiềm năng. Danh sách này được cung cấp cho các nhà phát triển.
Do kích thước của tập hợp các luật là không dự đoán trước được và việc áp dụng các luật trong bối cảnh cụ thể phụ thuộc vào ý nghĩa ngữ nghĩa của chương trình, vì vậy các thành phần tiềm năng sẽ được liệt kê và cung cấp cho lập trình viên để quyết định áp dụng hay không.
4.3.2.3. Sử dụng các luật để thay đổi mã nguồn
Sau khi phát hiện các thành phần tiềm năng, phần việc tiếp theo là sửa đổi mã nguồn để không vi phạm các luật. Nhà phát triển sẽ phải quyết định những gì và làm thế nào để chuyển đổi mã nguồn. Chúng tôi đề xuất kịch bản 3 bước sau đây:
104
Bước 2. Kiểm tra lại sự vi phạm của thành phần này. Nếu nó vẫn vi phạm, có hai khả năng xảy ra:
- Nếu luật đó không phụ thuộc vào ngữ nghĩa chương trình, mã nguồn sẽ được thay đổi tự động.
- Nếu luật đó phụ thuộc vào ngữ nghĩa chương trình, plug-in sẽ đề xuất với lập trình viên tất cả các thông tin liên quan để quyết định có thay đổi mã nguồn hay không.
Bước 3. Thay đổi mã nguồn.
4.3.3. Cài đặt thực nghiệm 4.3.3.1. Mô tả môi trƣờng 4.3.3.1. Mô tả môi trƣờng
Hệ thống được chúng tôi cài đặt với cấu hình: vi xử lý CPU Intel(R) Core(TM) i5 M520 2.40GHz, bộ nhớ RAM 4GB, hệ điều hành Windows 7 Professional 64-bit và nền tảng Java 6, 32-bit. Kết quả được thu thập bằng cách sử dụng Java VisualVM, là một công cụ cung cấp một giao diện ảo cho phép xem xét thông tin cụ thể về ứng dụng Java đang chạy trên máy ảo Java. Ứng dụng là một Eclipse plug-in và được phát triển bằng Plug-in Development Environment cung cấp bởi Eclipse. Chúng tôi lập trình plug-in dựa trên Eclipse Juno (4.2) SR2, gói "Eclipse for RCP and RAP Developers" và sử dụng ba công cụ:
1. PDE (Plug-in Development Environment): cung cấp công cụ để tạo lập, phát triển, kiểm thử, gỡ lỗi, xây dựng và triển khai các Eclipse plug-in.
2. JDT (Java Development Tools): cung cấp công cụ để triển khai Java IDE hỗ trợ cho phát triển ứng dụng Java, bao gồm cả Eclipse plug-in. Nó cho phép truy nhập, tạo lập và chỉnh sửa các dự án Java trong Eclipse.
3. Eclipse Refactoring API (ERAPI): một phần của Language Toolkit (LTK) của Eclipse và được cài đặt trong hai plug-in: "org.eclipse.ltk.core.refactoring" và "org.eclipse.ltk.ui.refactoring".
4.3.3.2. Mô tả cấu trúc của Eclipse plug-in
Sản phẩm thực nghiệm là một Eclipse plug-in tool nhằm: Cải thiện chất lượng của ứng dụng.
Tạo ra các thói quen lập trình tốt. Chức năng của công cụ:
Tìm kiếm và phân tích các thành phần tiềm năng có thể bị ảnh hưởng bởi việc tối ưu mã nguồn và kỹ thuật lập trình an toàn.
Phương thức hỗ trợ để chỉnh sửa những thành phần đó bằng cách hiển thị thông tin hỗ trợ và đề xuất ý kiến.
Biểu đồ luồng dữ liệu của plug-in được trình bày trong Hình 4.21 gồm 5 module: 1. Bộ tải cấu hình (Configuration Loader): module lưu trữ và tải tất cả các thông
tin về các luật từ tệp XML. Các thông tin cấu hình này cần phải được tải lên đầu tiên và lưu lại trong suốt phiên hoạt động của Eclipse.
105
2. Bộ tiền xử lý (Preprocessor): chuyển đổi tất cả các tệp mã nguồn Java thành cây cú pháp trừu tượng và chia vào các nhóm.
3. Bộ phân tích (Analyzer): module quan trọng nhất của hệ thống, được sử dụng để nhận dạng các thành phần tiềm năng trên cây cú pháp trừu tượng và lưu trữ thông tin về luật, bao gồm: tên, định dang, kiểu, độ ưu tiên, v.v..
4. Bộ hiển thị vấn đề (Display Problem Unit): hiển thị thông tin về các thành phần tiềm năng.
5. Bộ tái tạo (Refactoring Unit): công cụ hỗ trợ tối ưu hóa mã nguồn.
Hình 4.21. Biểu đồ luồng dữ liệu của công cụ Eclipse plug-in
4.3.3.3. Kết quả thực nghiệm
Chúng tôi so sánh hiệu suất của hệ thống trước và sau khi sử dụng tối ưu hóa mã nguồn và kỹ thuật lập trình an toàn. Bảng 4.2 cho thấy thời gian chạy của các phương thức giảm rõ ràng khi áp dụng tối ưu hóa mã nguồn và kỹ thuật lập trình an
toàn. Sự sụt giảm lớn nhất được thể hiện ở phương thức
getTopicDetailsTask() với 33.53% và sự sụt giảm này cho thấy chất lượng của các mã nguồn được cải thiện rõ rệt.
Analyzer Configuration
Loader
Rule Configuration
Preprocessor
Rule Analyzer Rule Condition
Checker
Display Problem Unit
Refactoring Unit
Java Project List
Problem List project information rule-related configuration collected elements rule configuration elements to be checked result detail problem information result element to be checked detail problem information simple problem information
106
Chú thích. BKProfile là một dịch vụ web thông minh, hỗ trợ thông tin liên lạc giữa các giảng viên, công ty, sinh viên và cựu sinh viên thông qua hồ sơ cá nhân. Nó được xây dựng theo hình thức hệ thống hỏi đáp-trả lời: người dùng chia sẻ kiến thức của mình thông qua việc đưa ra câu hỏi hoặc trả lời các câu hỏi của người khác.
Hình 4.22. Kết quả thực nghiệm sử dụng CPU
107
Bảng 4.2. Thời gian chạy của các phương thức của BKProfile
ID Chƣơng trình Phƣơng thức Số lần chạy Thời gian chạy(ms) Cải thiện (%) Trƣớc Sau 1-1 QuickSort generateArray 1 2703 2671 1.18 1-2 QuickSort sort 1 36558 25362 30.63 2-1 BKProfile getTopStatsTask 10000 114 107 6.14 2-2 BKProfile getTopicDetailsTask 10000 68 45.2 33.53 2-3 BKProfile getAnswersTask 20000 1005 951 5.37 2-4 BKProfile getQuestionDetailTask 20000 135 132 2.22 2-5 BKProfile getSimilarQuestionsTask 20000 210 188 10.48 2-6 BKProfile getFollowersTask (1) 20000 266 204 23.31 2-7 BKProfile getFollowersTask (2) 20000 143 113 20.98
Phép đánh giá thứ hai là về việc sử dụng tài nguyên hệ thống: bộ nhớ và CPU, thông qua thông tin thực chạy các hàm chính của hệ thống BKProfile. Hình 4.22 và Hình 4.23 hiển thị so sánh các tài nguyên hệ thống sử dụng trước và sau tối ưu hóa. Hình 4.22 chỉ ra rằng sau khi áp dụng các kỹ thuật tối ưu hóa sẽ giảm sử dụng CPU, cả thông số sử dụng tối đa và trung bình. Hình 4.23 hiển thị thống kê về sử dụng heap. Heap lưu trữ tất cả các đối tượng được tạo ra bởi Java trong thời gian chạy và được đánh giá bởi hai thông số: kích thước và kích thước được sử dụng. Hình 4.23, cho thấy có hai cải tiến của việc sử dụng bộ nhớ:
1. Kích thước heap sử dụng ít hơn trước đây.
2. Hiệu quả sử dụng heap là tốt hơn: tỉ lệ trung bình kích thước heap được sử dụng trên kích thước heap tăng lên.
Từ những lý thuyết và kết quả thực nghiệm được trình bày trong tiểu mục, tác giả luận án rút ra các nhận xét sau:
Các kĩ thuật lập trình an toàn và tối ưu mã nguồn ảnh hưởng nhất định đến hiệu năng của hệ thống.
Để mở rộng công việc, có thể quan tâm đến: (1) Việc mở rộng tập luật. (2) Quá trình thay đổi cập nhật mã nguồn có thể được thực hiện tự động hoặc bán tự động.
Kết quả nghiên cứu trong phần này đã được công bố năm 2013 trong công trình số 1 trong danh mục các công trình đã công bố của luận án.
4.4. Kết chƣơng
Chương 4 trình bày các nội dung liên quan đến dự đoán, tính toán và ứng dụng độ đo độ tin cậy phần mềm trong thực tế, là nội dung nghiên cứu thứ ba trong luận án. Thông qua các nghiên cứu thực hiện tại chương này, luận án đưa ra một số tổng kết cho nội dung này như:
Nhằm đưa ứng dụng của mô hình độ tin cậy phần mềm vào ứng dụng thực tế, luận án đã trình bày các sản phẩm phần mềm thực tế do tác giả và nhóm đồng nghiệp xây dựng. Các ứng dụng được xây dựng trên ngôn ngữ Java với mã nguồn hoàn toàn công khai, kiến trúc mở cho phép bổ sung thêm các mô hình.
108
Độ đo độ tin cậy là một tham số quan trọng trong mô hình tính toán chi phí phát hành có xét đến yếu tố rủi ro. Nếu phát hành quá sớm, những rủi ro tiềm ẩn của phần mềm sẽ phát sinh những chi phí không mong muốn rất lớn. Nếu phát hành quá muộn, chi phí phát triển sản phẩm sẽ tăng lên quá cao. Việc sử dụng các tính toán toán học sẽ giúp định vị được thời gian hợp lý nhất để phát hành phần mềm. Các thực nghiệm trên các dữ liệu thực tại Hoa Kỳ và Việt Nam cho thấy tỉ lệ chi phí rủi ro trên chi phí kiểm thử tác động rất mạnh lên tổng chi phí phát hành.
Các kết quả thực nghiệm đã cho thấy việc áp dụng các luật trong quá trình lập trình và phát triển sản phẩm Java đem lại những lợi ích đáng kể. Hiệu quả hoạt động của hệ thống, trong đó bao gồm cả ước lượng về tính tin cậy, đã được cải thiện rõ rệt.
109
KẾT LUẬN VÀ KIẾN NGHỊ
Kết luận
Khi thực hiện các nghiên cứu trong luận án, chúng tôi tập trung vào mô hình hóa nhằm đánh giá độ tin cậy hệ thống phần mềm. Mô hình hóa độ tin cậy phần mềm là một lĩnh vực lý thuyết sử dụng các công cụ toán học nhằm mô hình hóa một sản phẩm phần mềm, từ đó đưa ra tính toán về các độ đo liên quan đến độ tin cậy. Các nghiên cứu của chúng tôi sử dụng các cách tiếp cận dựa trên tiến trình Markov và tiến trình Poisson không đồng nhất.
Tiến trình Markov với đặc tính phi kí ức hoàn toàn thích hợp để mô hình hóa các dạng trạng thái khác nhau của phần mềm. Xuất phát từ đó, chúng tôi đã đề xuất quy trình hoàn thiện để áp dụng tiến trình Markov trong mô hình quá trình hoạt động của hệ thống phần mềm. Từ các kết quả thực nghiệm, chúng tôi nhận thấy sự lệ thuộc rất lớn của cách thức mô hình các trạng thái và xác suất các phép chuyển trạng thái đến giá trị độ đo độ tin cậy của hệ thống. Ngoài ra, chúng tôi đã áp dụng tiến trình Markov trong xây dựng công thức toán học nhằm đánh giá các thuộc tính chất lượng của hệ thống phần mềm dưới hai điều khoản khác nhau. Các kết quả thực nghiệm trên hệ thống thực với kiến trúc đám mây đã chứng minh tính đúng đắn của các tính toán toán học đó.
Tiến trình Poisson không đồng nhất được sử dụng trong các nghiên cứu của luận án là một dạng đặc biệt của tiến trình Markov với các khoảng thời gian giữa các thất bại tuân theo phân phối Poisson. Xuất phát từ nhu cầu đánh giá, so sánh các mô hình trong nhóm sử dụng tiến trình Poisson không đồng nhất, chúng tôi đề xuất kịch bản tính toán độ đo tổng quát dựa trên các độ đo tiêu chuẩn đơn. Các kết quả thực nghiệm cho thấy sự khác biệt rõ ràng giữa so sánh các mô hình khi sử dụng độ