Nguyen ly ngon ngu lap trinh - KHMT K27. Post Views: 1,088 . Đào tạo SĐH. Trung tâm đào tạo đại học, sau đại học, cung cấp nguồn nhân lực, đội ngũ chuyên gia trình độ cao trong lĩnh vực khoa học cơ bản và khoa học công nghệ mũi nhọn, có năng lực sáng tạo, làm việc trong môi Khớp với kết quả tìm kiếm: 7 thg 2, 2021 · NLP hay còn có tên gọi đầy đủ là Neuro Linguistic Programming (Lập trình ngôn ngữ tư duy NLP). Đây là một phương pháp giả khoa học dựa trên Lập trình ngôn ngữ tư duy NLP · Lợi ích của việc ứng dụng lập7 thg 2, 2021 · NLP hay còn có tên gọi đầy đủ là Neuro nguyên lý ngôn ngữ lập trình nguyễn hứa phùng introduction sinhvienzone com Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (84.52 KB, 20 trang ) C o e. on nZ Dr. Nguyen Hua Phung 09, 2015 hV ie HCMC University of Technology, Viet Nam in m Introduction Dr. Nguyen Hua Phung Mỗi ngôn ngữ lập trình có thể được xem như là một tập hợp của các chi tiết kỹ thuật chú trọng đến cú pháp, từ vựng, và ý nghĩa của ngôn ngữ. Những chi tiết kỹ thuật này thường bao gồm: Dữ liệu và cấu trúc dữ liệu. Câu lệnh và dòng điều khiển. Các tên và sa7rhs. trêng ¹i häc KINH TÕ QUèC D¢NVIỆN CÔNG NGHỆ THÔNG TIN – KINH TẾ  TIỂU LUẬNSVTH PHẠM ANH TÚMSV 11134279MÔN NGUYÊN LÝ NGÔN NGỮ LẬP TRÌNHĐỀ TÀI Nghiên cứu các vấn đề về nguyên lý ngôn ngữ lậptrình hướng đối tượng và cài đặt thử nghiệm bàitoán tự chọn bằng ngôn ngữ lập trình hướng đối tượng C++.HÀ NỘI THÁNG 4 NĂM 2015MỤC LỤCI, Nguyên lý Open-Closed……………………………………………trang 3II, Nguyên lý Nghịch đảo phụ thuộc…………………………… trang 9III, Nguyên lý Thay thế Liskov…………………………… trang 12IV, Nguyên lý Phân tách interface…………………………… trang 17Nguyên Lí Của Lập Trình Hướng Đối Tượng22Phương pháp lập trình hướng đối tượng đã được nghiên cứu và phát triển từ lâu nhưng việc vận dụng nó như thế nào cho hiệu quả trong việc xây dựng phần mềm là điều vẫn còn khá mơ hồ đối với nhiều người. Thế nào là một phần mềm hướng đối tượng ? Đâu là những cơ sở nền tảng để xây dựng được phần mềm theo tư tưởng hướng đối tượngđúng nghĩa ? Bài viết này trình bày về các nguyên lý lập trình hướng đối tượng. Đó là những quy tắc phân tích thiết kế hướng đối tượng cơ bản, mang tính chất khái quát. Do lànguyên lý nên nó có tính trừu tượng cao chứ không đi vào chi tiết cách thức giải quyết vấn đề cụ thể việc hiện thực hóa những nguyên lý lập trình hướng đối tượng đòi hỏi chúng ta phải xem xét đến Design Patterns I, Nguyên lý Open-Closed The Open-Closed Principle1. Phát biểu Các thực thể phần mềm hàm, đơn thể, đối tượng, … nên được xây dựng theo hướng mở cho việc mở rộng be opened for extension nhưng đóng đối với việc sửa đổi be closed for modification. 2. Nội dung Các thực thể trong một phần mềm không đứng riêng lẻ mà có sự gắn kết chặt chẽ với nhau. Chúng phối hợp hoạt động để cùng nhau thực hiện các chức năng của phần mềm. Do đó, việc nâng cấp, mở rộng một thực thể nào đó sẽ ảnh hưởng đến nhữngthực thể liên quan. Điều này có thể dẫn đến việc phải nâng cấp, mở rộng cả những thực thể liên quan đó. Và trong thời đại đầy biến động hiện nay, việc phải thường xuyên nâng cấp, mở rộng các thực thể trong phần mềm là điều khó tránh khỏi. Để làm cho quá trình bảo trì, nâng cấp, mở rộng phần mềm diễn ra dễ dàng và hiệu quả hơn, các thực thể phần mềm nên được xây dựng tuân theo nguyên lý Open-Closed. Điều này có nghĩa là các thực thể phần mềm nên được xây dựng sao cho việc nâng cấp, mở rộng đồng nghĩa với việc thêm vào những cái mới chứ không phải là thay đổi những cái hiện có, từ đó tránh33được việc phải thay đổi các thực thể liên quan. Xét ví dụ một đoạn chương trình vẽ đường thẳng và hình chữ nhật bằng C.public enum ShapeType { LINE, RECTANGLE } public abstract class Shape{ public abstract ShapeType getType; } public class Line Shape { public override ShapeType getType { return } public void drawLine { // Draws the line } } public class Rectangle Shape 44{ public override ShapeType getType { return } public void drawRectangle { // Draws the rectangle }} public void drawArrayList shapeList { Line line; Rectangle rectangle; foreach Shape s in shapeList switch { case line = Lines; break; case rectangle = Rectangles;55 break;}}Đoạn chương trình trên hoạt động rất tốt cho đến khi có sự nâng cấp, mở rộng. Giả sử chúng ta cần nâng cấp, mở rộng đoạn chương trình trên để nó có thể vẽ thêm được hình tròn. Lúc bấy giờ ta phải chỉnh sửa lại hàm “draw”, thêm vào một trường hợp vẽ hình tròn. Và trong nhiều tình huống, việc chỉnh sửa hàm “draw” sẽ dẫn đến việc chỉnh sửa những hàm khác liên quan. Hàm “draw” được viết theo cách này được nói là không tuân thủ nguyên lý Open-Closed. Để đoạn chương trình trên tuân thủ nguyên lý Open-Closed, chúng ta sử dụng tính đa hình của lập trình hướng đối abstract class Shape{ public abstract void draw; } public class Line Shape { public override void draw { // Draws the line } } public class Rectangle Shape { public override void draw { // Draws the rectangle } 66} class Circle Shape { public override void draw { // Draws the circle } } public void drawArrayList shapeList { foreach Shape s in shapeList }Với đoạn chương trình trên, khi thêm một hình mới vào, chúng ta chỉ việc thêm lớp đối tượng cho hình đó kế thừa từ Shape mà không cần phải chỉnh sửa lại hàm “draw”.Nó vẫn hoạt động tốt với những hình mới thêm chú i Không phải lúc nào tất cả các thực thể trong phần mềm đều có thể tuân thủ nguyên lý Open-Closed. Nhưng mục tiêu của phân tích thiết kế hướng đối tượng là phải làm sao cho số lượng các thực thể tuân thủ nguyên lý là lớn nhất, trong đó ưu tiên các thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý. ii Việc tuân thủ nguyên lý Open-Closed của một thực thể phần mềm chỉ mang tínhtương đối, phụ thuộc vào ngữ cảnh. Có thể trong ngữ cảnh này, thực thể thỏa nguyên lý, nhưng trong một ngữ cảnh khác, thực thể này không còn tuân thủ nguyên lý nữa. Mục tiêu của phân tích thiết kế hướng đối tượng là phải làm sao cho có nhiều thực thể phần mềm nhất tuân thủ nguyên lý trong ngữ cảnh thường xảy ra nhất của phần mềm, trong đó ưu tiên các thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý. Ví dụ trường hợp hàm “draw” như trong đoạn chương trình vẽ hình trên. public void drawArrayList shapeList { 77foreach Shape s in shapeList } Hàm “draw” chỉ thỏa nguyên lý trong ngữ cảnh nâng cấp mở rộng là “thêm hình mới”. Nếu chúng ta cần nâng cấp, mở rộng theo hướng thay đổi thứ tự vẽ các hình thì hàm “draw” như trên là không thể đáp ứng được. Khi đó nó không còn tuân thủ nguyên lý nữa. iii Một tính chất quan trọng trong lập trình hướng đối tượng giúp cho các thực thể phần mềm tăng khả năng tuân thủ nguyên lý Open-Closed là tính đóng gói encapsulation. Đối tượng nắm giữ thông tin và chịu trách nhiệm trên thông tin mình nắm giữ. Điều này giúp hạn chế sự kết dính coupling giữa các lớp đối tượng với nhau. Trường hợp lý tưởng là tất cả thuộc tính của đối tượng được đặt tầm vực private. việc thay đổi trên thuộc tính chỉ có thể được thực hiên thông qua những xử lý của phương thức. Những phương thức của đối tượng khác, kể cả đối tượng kế thừa không thể truy xuất được đến những thuộc tính này. iv Việc hạn chế sử dụng ép kiểu động runtime type-casting trong các thực thể phần mềm cũng sẽ giúp làm tăng khả năng tuân thủ nguyên lý Open-Closed của chúng. Vì bản chất của việc ép kiểu động là làm việc với một kiểu dữ liệu cụ thể. Khi muốn nâng cấp, mở rộng thực thể để nó có thể làm việc với những kiểu dữ liệu khác, đoạn chương trình sử dụng ép kiểu động phải được thay đổi để có thể làm việc được với các kiểu dữ liệu khác này. public void doSomethingVehicle vehicle { Car car = Carvehicle; } Khi cần nâng cấp, mở rộng để đoạn chương trình trên có thể làm việc được với các lớp đối tượng khác kế thừa từ “Vehicle”, chúng ta phải chỉnh sửa lại nó. 88Ý nghĩa Nguyên lý Open-Closed là nguyên lý cốt lõi và là một trong bốn nguyên lý cơ bản làm nền tảng cho phân tích thiết kế hướng đối tượng. Nó giúp cho phần mềm dễ bảo trì, nâng cấp và mở Nguyên lý Nghịch đảo phụ thuộc The Dependency Inversion Principle1. Phát biểu Các thành phần trong phần mềm không nên phụ thuộc vào những cái riêng, cụ thể details mà ngược lại nên phụ thuộc vào những cái chung, tổng quát abstractions của những cái riêng, cụ thể đó. Những cái chung, tổng quát abstractions không nên phụ vào những cái riêng, cụ thể details. Sự phụ thuộc này nên được đảo ngược lại. 2. Nội dung Những cái chung, tổng quát là tập hợp của những đặc tính chung nhất từ những cái riêng, cụ thể. Những cái riêng, cụ thể dù khác nhau thế nào đi nữa cũng đều tuân theo các quy tắc chung mà cái chung, tổng quát của nó đã địnhnghĩa. Những cái chung, tổng quát là những cái ít thay đổi và ít biến động. Trong khi đó, sự thay đổi lại thường xuyên xảy ra ở những cái riêng, cụ thể. Việc phụ thuộc vào những cái chung, tổng quát sẽ giúp cho các thành phần trong phần mềm trở nên linh động flexible và thích ứng tốt với sự thay đổi thường xuyên diễn ra ở những cái riêng, cụ thể. Khi phụ thuộc vào những cáichung, tổng quát, các thành phần trong phần mềm vẫn có thể hoạt động tốt mà không cần phải sửa đổi một khi cái riêng, cụ thể được thay thế bằng một cái riêng, cụ thể khác cùng loại. Lấy ví dụ đoạn chương trình đọc dữ liệu từ bàn phím và xuất ra máy void copy { Keyboard keyboard = new Keyboard;Printer printer = new Printer; char c; 99while c = != q’ } Khi nâng cấp, mở rộng đoạn chương trình trên để nó có thể xuất dữ liệu ra máy in hoặc tập tin thì chúng ta phải chỉnh sửa lại đoạn chương trình trên như void copyOutputType type { Keyboard keyboard = new Keyboard; Printer printer = new Printer; File file = new File; char c; while c = != q’ if type == else if type == }Rõ ràng hàm “copy” như trên đã vi phạm nguyên lý Open-Closed do khi mỗi lần cần thêm một thiết bị đọc ghi mới vào, chúng ta phải chỉnh sửa lại nó. Nguyên nhân làm cho hàm “copy” vi phạm nguyên lý Open-Closed là do nó làm việc với từng thiết bị đọc ghi cụ thể. Khi thêm một thiết bị đọc ghi mới, chúng ta phải thêm vào hàm “copy” đoạn lệnh để làm việc với thiết bị đọc ghi mới. Khi đó chúng ta nói hàm “copy” vi phạm nguyên lý Nghịch đảo phụ thuộc. Để đoạn chương trình trên tuân thủ Nguyên lý Nghịch đảo phụ thuộc, từ đó tuân thủNguyên lý Open-Closed, chúng ta phải cho nó làm việc với thiết bị đọc ghi tổng void copyReader reader, Writer writer { char c; while c = != q’ }Hàm “copy” như trên có thể làm việc tốt với bất kỳ thiết bị đọc ghi nào tuân thủ interface của Reader và Writer. Khi cần thêm thiết bị đọc ghi mới, chúng ta chỉ việc thêmlớp đối tượng kế thừa từ Reader hoặc Writer mà không phải chỉnh sửa lại hàm “copy”.Trích lời Allen Holub “The more abstraction you add, the greater the flexibility. In today’s business environment, where requirements regularly change as program develops, this flexibility is essential.”. Chú ý i Nguyên lý Nghịch đảo phụ thuộc có mối liên hệ mật thiết với nguyên lý OpenClosed. Một khi nguyên lý Nghịch đảo phụ thuộc bị vi phạm, có nghĩa là những thành phần trong phần mềm phụ thuộc vào những cái riêng, cụ thể, việc nâng cấp, mở rộng ở những cái riêng, cụ thể điều này rất thường xảy ra buộc những thành phần phụ thuộc vào nó bị thay đổi theo. Điều này dẫn đến vi phạm nguyên lý Open-Closed. ii Sự nghịch đảo được đề cập đến ở đây nhằm nhấn mạnh đến việc cần phải thay đổi quan điểm trong phân tích thiết kế phần mềm. Theo lối suy nghĩ “chia để trị” của lập trình hướng cấu trúc, những công việc lớn, phức tạp, mang tính trừu tượng cao thường được phân ra thành những công việc nhỏ, đơn giản và cụ thể hơn. Khi đó, cấu trúc phần mềm có xu hướng theo dạng những thành phần lớn trừu tượng gọi đến những thành phần nhỏ cụ thể hơn để yêu cầu chúng thực hiện công việc. Điều này thường làm cho những thành phần trong phần mềm phụ thuộc vào những cái riêng, cụ thể. Trong phân tích thiết kế hướng đối tượng, sự phụ thuộc này nên được đảo ngược lại. iii Một thành phần trong phần mềm vi phạm nguyên lý Nghịch đảo phụ thuộc sẽ có tính tái sử dụng reusability không cao. Việc mang những thành phần này sử dụng vào một ngữ cảnh khác với những cái riêng, cụ thể khác là khó có thể thực hiện được nếu nhưkhông thực hiện việc chỉnh sửa nào trên chúng. iv Một quy ước trong lập trình hướng đối tượng giúp cho các thành phần trong phần 1111mềm tăng khả năng tuân thủ nguyên lý Nghịch đảo phụ thuộc là thực hiện việc truy xuất đến các đối tượng thông qua interface của chúng. Điều này sẽ làm cho các thành phần bên trong phần mềm có tính linh động flexibility cao, không phải sửa đổi khi thay thế các đối tượng được truy xuất đến bằng đối tượng khác cùng loại. public void doSomethingCar car { } public void doSomethingVehicle vehicle { }Trong hai đoạn chương trình trên, đoạn chương trình thứ hai vẫn làm việc tốt khi chúng ta thêm vào các đối tượng khác cùng loại với “Car” mà kế thừa từ “Vehicle”. Ý nghĩa Nguyên lý Nghịch đảo phụ thuộc có mối liên hệ mật thiết với nguyên lý Open-Closed vàlà một trong bốn nguyên lý cơ bản làm nền tảng cho phân tích thiết kế hướng đối tượng. Nó giúp cho phần mềm có tính tái sử dụng cao, linh động và bền vững robustness trước những sự thay Nguyên lý Thay thế Liskov The Liskov Substitution Principle 1. Phát biểu Lớp B chỉ nên kế thừa từ lớp A khi và chỉ khi với mọi hàm F thao tác trên các đối tượng của A, cách cư xử behaviors của F không thay đổi khi ta thaythế substitute các đối tượng của A bằng các đối tượng của B. 2. Nội dungKế thừa inheritance là một trong những tính chất cơ bản của lập trình hướng đối tượng. Đó là khả năng định nghĩa một lớp đối tượng dựa trên các lớp đối tượng đã được định nghĩa trước đó. Các đối tượng của lớp kế thừa có1212khả năng cư xử behave như các đối tượng của lớp cơ sở. Điều này có nghĩalà các đối tượng của lớp kế thừa hoàn toàn có thể thay thế các đối tượng của lớp cơ sở trong những hàm thao tác trên các đối tượng của lớp cơ sở. Chính vì tính chất này mà chúng ta không thể sử dụng kế thừa một cách tùy tiện. Giả sử ta có lớp A và hàm F thao tác trên các đối tượng của A. Để nâng cấp, mở rộng phần mềm, ta cần thêm vào lớp B kế thừa từ A. Nhưng việc thay thế các đối tượng của A bằng các đối tượng của B lại làm cho F cư xử sai lệch so với trước khi thực hiện việc thay thế. Lúc này, để F có thể cư xử không đổi so với trước, ta phải chỉnh sửa lại F. Điều này làm cho F vi phạm nguyên lý Open-Closed. Đoạn chương trình sau cho thấy việc kế thừa tùy tiện chỉ với mục đích tái sử dụng nguy hiểm như thế class Stack { private ArrayList data; // More data members of stack. Public virtual void pushint n { // Pushes n to stack } public virtual int pop { // Pops value from stack } } public class Queue Stack { // Data members of Queue. public override void pushint n { // Pushes n to queue } public override int pop {1313// Pops value from queue }} public int funcStack p { int a = int b = if a == 7 && b == 6 return a * b; throw new ArgumentException; }Với mục đích tái sử dụng là một số thuộc tính và phương thức trong “Stack”, chúng ta cho “Queue” kế thừa từ Stack. Xét hàm “func” thao tác trên đối tượng của “Stack”, do “Queue” kế thừa từ “Stack” nên chúng ta hoàn toàn có thể truyền đối tượng của “Queue” vào hàm này. Nhưng cách cư xử của hàm “func” khi thao tác trên các đối tượng của “Stack” và “Queue” là khác nhau. Với các đối tượng của “Stack” hàm func luôn trả về chính xác tích của hai số 7 và 6. Nhưng với các đối tượng của “Queue” hàm func lại luôngây ra một exception. Để hàm “func” có thể cư xử trên các đối tượng của “Stack” và “Queue” như nhau, chúng ta phải viết lại nó. Điều này làm cho hàm “func” vi phạm nguyên lý Open-Closed. Khi đó ta nói hàm “func” vi phạm nguyên lý Thay thế Liskov. Chú ý i Nguyên lý Thay thế Liskov có mối liên hệ mật thiết với Nguyên lý Open-Closed. Sự vi phạm nguyên lý Thay thế Liskov sẽ dẫn đến sự vi phạm nguyên lý Open-Closed. Một thực thể phần mềm vi phạm nguyên lý Thay thế Liskov sẽ cư xử khác nhau trên các đối tượng của lớp cơ sở và lớp kế thừa. Để thực thể phần mềm này vẫn có thể làm việc 1414tốt trên các đối tượng của cả lớp cơ sở và lớp kế thừa, chúng ta phải chỉnh sửa lại nó. Điều này dẫn đến vi phạm nguyên lý Open-Closed. ii Không phải lúc nào tất cả các thực thể trong phần mềm đều có thể tuân thủ nguyên lý Thay thế Liskov. Nhưng mục tiêu của phân tích thiết kế hướng đối tượng là phải làm sao cho số lượng các thực thể tuân thủ nguyên lý là lớn nhất, trong đó ưu tiên các thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý. iii Việc tuân thủ nguyên lý Thay thế Liskov của một thực thể phần mềm chỉ mang tính tương đối, phụ thuộc vào ngữ cảnh. Có thể trong ngữ cảnh này, thực thể thỏa nguyênlý, nhưng trong một ngữ cảnh khác, thực thể này không còn tuân thủ nguyên lý nữa. Mục tiêu của phân tích thiết kế hướng đối tượng là phải làm sao cho có nhiều thực thể phần mềm nhất tuân thủ nguyên lý trong ngữ cảnh thường xảy ra nhất của phần mềm, trong đó ưu tiên các thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý. iv Quan hệ “IS-A” thường được dùng để phát hiện kế thừa. Khi lớp đối tượng B về mặt ngữ nghĩa là một trường hợp đặc biệt của lớp đối tượng A thì ta có thể cho B kế thừa từ A. Nhưng thực tế cho thấy, trong một số ngữ cảnh của phần mềm, một lớp đối tượng có quan hệ “IS-A” với những lớp đối tượng khác nhưng việc để nó kế thừa những lớp đốitượng này sẽ dẫn đến việc vi phạm nguyên lý Thay thế Liskov. Xét đoạn chương trình class Rectangle {// Data members of rectangle // Member functions of rectangle } public class Square Rectangle { // Data members of square // Member functions of square 1515} public double doSomethingRectangle obj { if == 30 return throw new ArgumentException; }Ở đoạn chương trình trên, mặc dù về mặt ngữ nghĩa, hình vuông là một trường hợp của hình chữ nhật. Điều này hoàn toàn đúng!!! Nhưng trong ngữ cảnh này, việc để “Square” kế thừa “Rectangle” là không phù hợp. Lúc này hàm “doSomething” cư xử khác nhau trên các đối tượng của “Rectangle” và “Square”. Như vậy hàm “doSomething”đã vi phạm nguyên lý Thay thế Liskov. Để hàm “doSomething” có thể làm việc được trêncả “Rectangle” và “Square” chúng ta phải chỉnh sửa lại nó. Như vậy việc vi phạm nguyênlý Thay thế Liskov đã làm cho hàm “doSomething” vi phạm nguyên lý Open-Closed. v Nguyên lý Thay thế Liskov có mối liên hệ mật thiết với kỹ thuật “Design by Contract” được đề cập bởi Bertrand Meyers. Kỹ thuật này chỉ ra rằng mỗi phương thức trong một lớp đối tượng, khi được định nghĩa, đã hàm chứa trong nó tiền điều kiện pre-condition và hậu điều kiện post-condition. Tiền điều kiện là những điều kiện cần để phương thức có thể thực hiện được. Hậu điều kiện là những ràng buộc phát sinh sau khi thực hiện phương thức. Khi thực hiện việc kế thừa, phương thức được định nghĩa lại trong lớp kế thừa phải có tiền điều kiện lỏng lẻo hơn weaker và hậu điều kiện chặt chẽ hơn stronger. Điều này có nghĩa là trước khi thực hiện, phương thức được định nghĩa lạitrong lớp kế thừa không được đòi hỏi nhiều hơn như khi nó được định nghĩa trong lớp cơ sở. Và sau khi thực hiện, phương thức được định nghĩa lại trong lớp kế thừa phải đảm bảo tất cả những ràng buộc phát sinh như khi nó được định nghĩa trong lớp cơ sở. Chỉ khinào những điều trên được đáp ứng cho mọi phương thức trong lớp kế thừa thì lớp kế thừamới được xem là cư xử như lớp cơ sở. Và khi đó, việc để nó kế thừa từ lớp cơ sở mới là đúng đắn trong ngữ cảnh phần mềm đang xét. 1616vi Nguyên lý Thay thế Liskov và kỹ thuật “Design by Contract” vô tình làm cho việc kế thừa trở nên rất khó thực hiện. Khi cần thêm vào một lớp kế thừa, chúng ta phải xem xét rất kỹ lưỡng lại tất cả hàm có thao tác trên lớp cơ sở xem chúng có vi phạm nguyên lý Thay thế Liskov hay không. Chúng ta cũng cần phải xem xét tất cả các phươngthức của lớp kế thừa xem chúng có vi phạm những quy định của kỹ thuật “Design by Contract” hay không. Tất cả những điều này là do lớp kế thừa có một mối liên hệ mật thiết với lớp cơ sở. Lớp kế thừa bị kết dính coupling chặt chẽ với lớp cơ sở. Sự kết dính này rõ ràng làm cho phần mềm kém linh động flexibility một khi có sự thay đổi xảy ra. Do đó, để hạn chế sự kết dính này mà vẫn đảm bảo được tính tái sử dụng, chúng ta chỉ nên kế thừa interface và sử dụng composition thay cho việc kế nghĩa Nguyên lý Thay thế Liskov có mối liên hệ mật thiết với nguyên lý Open-Closed và là một trong bốn nguyên lý cơ bản làm nền tảng cho phân tích thiết kế hướng đối tượng. Nó giúp nâng cao tính tái sử dụng và bền vững của phần mềm trước những sự thay Nguyên lý Phân tách interface The Interface Segregation 1. Phát biểu Không nên buộc các thực thể phần mềm phụ thuộc vào những interface mà chúng không sử dụng đến. 2. Nội dung Khi xây dựng một lớp đối tượng, đặc biệt là những lớp trừu tượng abstract class, nhiều người thường có xu hướng để cho lớp đối tượng thực hiện càng nghiều chức năng càng tốt, đưa thật nhiều thuộc tính và phương thức vào lớpđối tượng đó. Những lớp đối tượng như vậy được gọi là những lớp đối tượngcó interface bị “ô nhiễm” fat interface or polluted interface. Khi một lớp đối tượng có interface bị “ô nhiễm”, nó sẽ trở nên cồng kềnh. Một thực thể phần mềm nào đó chỉ cần thực hiện một công việc đơn giản mà lớp đối tượng này hỗ trợ buộc phải làm việc với toàn bộ interface của lớp đốitượng đó. Việc phải truyền đi truyền lại nhiều lần những đối tượng có 1717interface bị “ô nhiễm” sẽ làm giảm hiệu năng của phần mềm. Đặc biệt đối với lớp trừu tượng có interface bị “ô nhiễm”, một số lớp kế thừachỉ quan tâm đến một phần interface của lớp cơ sở nhưng bị buộc phải thực hiện việc cài đặt cho cả phần interface không hề có ý nghĩa đối với chúng. Điều này dẫn đến sự dư thừa không cần thiết trong các thực thể phần mềm. Quan trọng hơn nữa, việc buộc các lớp kế thừa phụ thuộc vào phần interface mà chúng không sử dụng đến sẽ làm tăng sự kết dính coupling giữa các thực thể phần mềm. Một khi sự nâng cấp, mở rộng diễn ra, đòi hỏi phần interface đó phải thay đổi, các lớp kế thừa này bị buộc phải chỉnh sửa theo. Điều này làm cho chúng vi phạm nguyên lý Open-Closed. Hình bên dươi là sơ đồ lớp cho đoạn chương trình tính điện trở mạch điện. “Resistor” và “Lamp” là những mạch điện đơn giản với điện trở là một thuộctính của mạch. Trong khi “SeriesCircuit” và “ParallelCircuit” là những mạch điện phức hợp với điện trở của mạch được tính từ các mạch điện con. Để có thể cư xử như nhau trên các loại mạch điện này hay nói cách khác là truy xuất đến chúng một cách “trong suốt” transparency, chúng ta có “Circuit” là lớp trừu tượng chung đại diện cho các mạch điện khác nhau. Lớp “Circuit” được thiết kế như trên được gọi là có interface bị “ô nhiễm”. “Resistor” và “Lamp” bị buộc phải thực hiện việc cài đặt cho các phương thức “add” và “remove” hoàn toàn chẳng có ý nghĩa gì với chúng. Điều này gây ra sự dư thừa code không cần thiết cũng như gây “khó chịu” cho những thực thể phần mềm khác sử dụng “Resistor” và “Lamp”. Nhưng vấn đề chỉ thật sự xảy ra khi chúng ta nâng cấp, mở rộng đoạn chương trình trên. Giả sửchúng ta cần thêm vào phương thức “removeAt” để hỗ trợ việc xóa mạch điện con tại vị trí nào đó trong mạch điện phức hợp. Lúc này, chúng ta phải thực hiện việc chỉnh sửa trên tất cả các lớp đối tượng kế thừa từ “Circuit”. Việc ch ỉnh sửa trên “SeriesCircuit” và “ParallelCircuit” xem ra còn có thể chấp nhận được. Nhưng việc phải chỉnh sửa trên “Resistor” và “Lamp” là không thể chấp nhận được vì phương thức “removeAt” chẳng hề có ý nghĩa 1818gì đối với chúng. Điều này rõ ràng làm cho “Resistor” và “Lamp” vi phạm nguyên lý Open-Closed một cách “không chính đáng”. Chú ý i Nguyên lý Phân tách interface có mối liên hệ với nguyên lý Open-Closed. Sự vi phạm nguyên lý Phân tách interface có khả năng dẫn đến sự vi phạm nguyên lý Open-Closed xem phân tích ở trên.ii Để tránh vi phạm nguyên lý Phân tách Inteface, chúng ta nên giữ cho interface của lớp đối tượng đơn giản và gọn nhẹ, nên làm theo tiêu chí “a class should do one thing and do it well”. Chúng ta không nên để cho lớp đối tượng đảm nhận quá nhiều trách nhiệm vì điều này dễ làm cho interface của nó bị “ô nhiễm”. iii Interface bị “ô nhiễm” của lớp đối tượng nên được phân tách ngay khi có thể để tránh khả năng dẫn đến sự vi phạm nguyên lý Open-Closed. Việc phân tách interface bị “ô nhiễm” của một lớp cơ sở có thể được thực hiện thông qua việc tăng thêm mức độ trừu tượng trong cây kế thừa của nó. Lớp cơ sở ban đầu chỉ nên có interface đơn giản mà mọi lớp kế thừa của nó đều cần phải có. Sau đó, phần interface chung của một bộ phận lớp kế thừa được tổng hợp lại trong một lớp cơ sở. Và lớp cơ sở này lại kế thừa từ lớp cơ sở ban đầu. Như vậy những lớp kế thừa thuộc nhánh khác không bị phụ thuộc vào phần interface mà chúng không sử dụng đến của bộ phận lớp kế thừa kia. Với trường hợp đoạn chương trình tính điện trở mạch điện, để giải quyết vấn đề interface của “Circuit” bị “ô nhiễm”, chúng ta tăng thêm một mức độ trừu tượng trong cây kế thừa của nó. Khi đó, “Circuit” đóng vai trò là lớp trừu tượng cho các mạch điện khác nhau. Nó chỉ chứa phần interface chung nhất của tất cả các mạch điện này. Và trong ngữ cảnh bài toán tính điện trở đơn giản thì nó chỉ chứaphương thức “calcResistance”. 1919Chúng ta sẽ có lớp “SingleCircuit” đại diện cho các mạch điện đơn giản và “ComplexCircuit” đại diện cho cách mạch điện phức hợp. “SingleCircuit” chứa phần interface chung của các mạch điện đơn giản như “Resistor” và “Lamp” trong khi “ComplexCircuit” chứa phần interface chung của các mạch điện phức hợp. Chúng ta sẽ có được cây kế thừa như hình bên dưới. Lúc này, khi cần thêm vào phương thức “removeAt” chúng ta chỉ việc nâng cấp phần interface của “ComplexCircuit”, nhánh kế thừa bên “SingleCircuit” sẽ không bị ảnh hưởng. iv Trong một số trường hợp, sau khi phân tách interface, một số lớp kế thừa mới thêm vào muốn sử dụng những phần interface đã phân tách, chúng có thể thực hiện việc đa kế thừa từ những lớp đối tượng hỗ trợ những phần interface này hoặc cũng có thể kế thừa từ một lớp đối tượng hỗ trợ một phần interface chúng cần và thực hiện composition đối với những đối tượng hỗ trợ phần interface còn lại. Ý nghĩaNguyên lý Phân tách interface có mối liên hệ với nguyên lý Open-Closed và là một trong bốn nguyên lý cơ bản làm nền tảng cho phân tích thiết kế hướng đối tượng. Nó giúp giảm sự cồng kềnh, dư thừa không cần thiết cho phần mềm và quan trọng hơn là giảm sự kết dính copuling làm hạn chế tính linh động flexibility của phần liệu tham khảo • Robert C. Martin, The Open-Closed Principle, Object Mentor, 1996. • Robert C. Martin, The Dependency Inversion Principle, Object Mentor, 1996. • Robert C. Martin, The Liskov Substitution Principle, Object Mentor, 1996. • Robert C. Martin, The Interface Segregation Principle, Object Mentor, 1996. • Allen Holub, Why extends is evil?, Java World, 2003• Internet2121 Ngày đăng 15/05/2015, 1556 Câu 1 Khái niệm và Các yếu tố cấu thành của Ngôn ngữ lập trình Ngôn ngữ lập trình là một hệ thống được kí hiệu hóa để miểu tả những tính toán qua máy tính trong một dạng mà cả con người và máy tính đều có thể đọc và hiểu được. Ngôn ngữ lập trình = Kí hiệu + quy tắc kết hợp • Các yếu tố cấu thành của ngôn ngữ lập trình o Cú pháp Sự kết hợp của các kí hiệu Dạng của biểu thức, các phát triển, các đơn vị nhỏ của chương trình o Ngữ nghĩa Ý nghĩa cuả sự kết hợp. o Ngữ dụng Mối quan hệ của cú pháp,ngữ nghĩa với thế giới bên ngoài Câu 2 Phải có ngôn ngữ lập trình mà k dùng ngôn ngữ máy hay ngôn ngữ tự nhiên để lập trình vì • Ngôn ngữ máy là ngôn ngữ trong đó các lệnh được viết bằng các số nhị phân 0 và 1. Nếu một chương trình được viết bằng ngôn ngữ máy thì chương trình đó sẽ rất dài. Các dòng số này không gợi nên ý nghĩa của lệnh. Người dùng muốn hiểu và sử dụng chương trình thì phải ghi nhớ một cách máy móc các dòng lệnh. • Ngôn ngữ tự nhiên là ngôn ngữ đa nghĩa, giàu cảm xúc biểu đạt, đóng về ngữ nghĩa. Nếu dùng ngôn ngữ tự nhiên để vết chương trình thì máy tính không thể xác định được khả năng biểu đạt của ngôn ngữ.  Phải dùng ngôn ngữ lập trình để làm phương tiện giao tiếp giữa người và máy tính. Câu 3 Lịch sử phát triển của ngôn ngữ lập trình • Ngôn ngữ lập trình đầu tiên là ngôn ngữ máy tính mã nhị phân. Ngôn ngữ máy phụ thuộc toàn bộ vào kiến trúc phần cứng và những quy ước khắt khe của nhà chế tạo → Không có tính khả chuyển • Từ những năm 1950 hợp ngữ assembly ra đời → là những ngôn ngữ bậc thấp. • Từ năm 1957 ngôn ngữ bậc cao đầu tiên ra đời. Đây là sản phẩm của IBM đưa ra. Đó là ngôn ngữ Fortran Formula Translator. Là ngôn ngữ gần gũi với ngôn ngữ tự nhiên, với cách diễn đạt toán học Điều kiện, vòng lặp. • Đầu những năm 1960 COBOL xử lý dữ liệu. Algol 60 có cấu trúc điều khiển hiện đại Lisp Ngôn ngữ lập trình hàm đầu tiên, ngôn ngữ xử lí danh sách • Giữa những năm 1960 PL/1 Kết hợp giữa ngôn ngữ tính toán số học và ngôn ngữ xử lí dữ liệu. Simula Hướng đối tượng • Từ năm 1970 – 1990 Các ngôn ngữ hướng đối tượng C++ Lập trình Logic 1972 Lập trình hàm ML.,miranda Ada • Từ năm 1990 đến nay Hướng đối tượng + WWW C,java Ngôn ngữ kịch bản + Hướng đối tượng + WWWPHP XML Ngôn ngữ kịch bản phía Client Java Script Câu 4 Các xu hướng phát triển & nghiên cứu chính of các ngôn ngữ lập trình trong giai đoạn hiện nay • Moodul hóa, hướng đối tượng. • Mã nguồn mở, framework. • Phát hiện lỗi tự động • Phát triển trình dịch biên. • Bảo mật • Lập trình cho di động • Web điện toán cho đám mây • Lập trình trí tuệ nhân tạo Câu 5 Anh chị hãy cho biết tên của 3 ngôn ngữ lập trình được sử dụng phổ biến hiện nay trên thế giới, và theo anh chị thì vì sao nó lại được sử dụng phổ biến ngữ lập trình C C là một ngôn ngữ lập trình hướng đối tượng được phát triển bởi Microsoft, là phần khởi đầu cho kế hoạch .NET của họ. Tên của ngôn ngữ bao gồm ký tự thăng theo Microsoft nhưng theo ECMA là C, chỉ bao gồm dấu số thường. Microsoft phát triển C dựa trên C++ và Java. C được miêu tả là ngôn ngữ có được sự cân bằng giữa C++, Visual Basic, Delphi và Java. C được thiết kế chủ yếu bởi Anders Hejlsberg kiến trúc sư phần mềm nổi tiếng với các sản phẩm Turbo Pascal, Delphi, J++, WFC. C, theo một hướng nào đó, là ngôn ngữ lập trình phản ánh trực tiếp nhất đến .NET Framework mà tất cả các chương trình .NET chạy, và nó phụ thuộc mạnh mẽ vào Framework này. Mọi dữ liệu cơ sở đều là đối tượng, được cấp phát và hủy bỏ bởi trình dọn rác Garbage-Collector GC, và nhiều kiểu trừu tượng khác chẳng hạn như class, delegate, interface, exception, phản ánh rõ ràng những đặc trưng của .NET runtime. 4. Ngôn ngữ lập trình Java Java đọc như "Gia-va" là một ngôn ngữ lập trình dạng lập trình hướng đối tượng OOP. Khác với phần lớn ngôn ngữ lập trình thông thường, thay vì biên dịch mã nguồn thành mã máy hoặc thông dịch mã nguồn khi chạy, Java được thiết kế để biên dịch mã nguồn thành bytecode, bytecode sau đó sẽ được môi trường thực thi runtime environment chạy. Bằng cách này, Java thường chạy nhanh hơn những ngôn ngữ lập trình thông dịch khác như Python, Perl, PHP, Cú pháp Java được vay mượn nhiều từ C & C++ nhưng có cú pháp hướng đối tượng đơn giản hơn và ít tính năng xử lý cấp thấp hơn. dự định ngôn ngữ Java thay cho C++, nhưng các tính năng giống Objective C. Không nên lẫn lộn Java với JavaScript, hai ngôn ngữ đó chỉ giống tên và loại cú pháp như C. Công ty Sun Microsystems đang giữ bản quyền và phát triển Java thường xuyên. 3. Ngôn ngữ lập trình PHP PHP viết tắt hồi quy "PHP Hypertext Preprocessor" là một ngôn ngữ lập trình kịch bản hay một loại mã lệnh chủ yếu được dùng để phát triển các ứng dụng viết cho máy chủ, mã nguồn mở, dùng cho mục đích tổng quát. Nó rất thích hợp với web và có thể dễ dàng nhúng vào trang HTML. Do được tối ưu hóa cho các ứng dụng web, tốc độ nhanh, nhỏ gọn, cú pháp giống C và Java, dễ học và thời gian xây dựng sản phẩm tương đối ngắn hơn so với các ngôn ngữ khác nên PHP đã nhanh chóng trở thành một ngôn ngữ lập trình web phổ biến nhất thế giới. Ngôn ngữ, các thư viện, tài liệu gốc của PHP được xây dựng bởi cộng đồng và có sự đóng góp rất lớn của Zend Inc., công ty do các nhà phát triển cốt lõi của PHP lập nên nhằm tạo ra một môi trường chuyên nghiệp để đưa PHP phát triển ở quy mô doanh nghiệp. Câu 6 Phân biệt NNLT bậc thấp và NNLT bậc cao - Ngôn ngữ lập trình bậc thấp là một ngôn ngữ lập trình liên quan chặt chẽ đến phần cứng máy tính và không có tính khả chuyển. Từ "thấp" không có nghĩa là ngôn ngữ này kém hơn các ngôn ngữ lập trình bậc cao mà điều này nghĩa là các lệnh của nó rất gần ngôn ngữ máy. Phụ thuộc rất nhiều vào loại máy. Các ngôn ngữ lập trình bậc thấp thường được chia thành hai loại thế hệ thứ nhất và thế hệ thứ hai. + Ngôn ngữ lập trình thế hệ thứ nhất, hay 1GL, là mã máy. Nó là ngôn ngữ duy nhất mà bộ vi xử lý có thể hiểu. Hiện nay các lập trình viên hầu như không bao giờ viết chương trình trực tiếp bằng ngôn ngữ máy vì nó không chỉ yêu cầu chú ý nhiều đến các chi tiết mà một ngôn ngữ bậc cao xử lý một cách tự động mà còn yêu cầu ghi nhớ và tìm những mã lệnh bằng số cho mỗi chỉ thị được sử dụng. + Ngôn ngữ lập trình thế hệ thứ hai, hay 2GL, là ngôn ngữ assembly. Nó được xem là ngôn ngữ thế hệ thứ hai vì mặc dù nó không phải là ngôn ngữ máy nhưng lập trình viên vẫn phải hiểu về kiến trúc của bộ vi xử lý như các thanh ghi và các lệnh của bộ vi xử lý. Những câu lệnh đơn giản được dịch trực tiếp ra mã máy. - Ngôn ngữ lập trình bậc cao Là ngôn ngữ gần với ngôn ngữ tự nhiên nhất. ít phụ thuộc vào loại máy, có tính độc lập cao và phải có chương trình dịch để dịch sang mã máy thì máy tính mới có thể thực hiện được. - Cho ví dụ + Ngôn ngữ bậc thấp Ngôn ngữ máy, Assembly, … + Ngôn ngữ lập trình bậc cao fortran, pascal, C, Cobol…. Câu 7 Họ ngôn ngữ lập trình phổ biến là - Ngôn ngữ máy và ngôn ngữ ASSEMBLY Ngôn ngữ máy là đối tượng thi hành trực tiếp của vi xử lý. Hợp ngữ Assembly 1950s chương trình viết bằng hợp ngữ ngắn hơn, chiếm ít bộ nhớ hơn và chạy nhanh hơn so với ngôn ngữ lập trình bậc cao. Ngôn ngữ Assembly thích hợp cho lập trinh các vi điều khiển VD vi điều khiển trên ô tô - Họ ngôn ngữ cổ điển ngôn ngữ cấp cao loại ngôn ngữ thủ tục gắn chặt với mô hình máy tính cổ điển Von Neumann Kiến trúc Von Neumann có 2 đặc điểm đáng chú ý + Các lệnh được xử lý tuần tự theo thứ tự sắp xếp trong bộ nhớ + Chỉ cho phép đọc ghi mỗi lần 1 từ nhớ Word Memory\ VD Fortran, Pascal, Basic, C, … - Họ ngôn ngữ hàm Chương trình của ngôn ngữ hàm bao gồm các đối tượng dữ liệu, các hàm và các phép áp dụng hàm trên các đối tượng dữ liệu. Sử dụng định nghĩa hàm đệ qui. VD Lisp, ML, Haskell,… - Họ ngôn ngữ hướng đối tượng Chương trình của ngôn ngữ hướng đối tượng là một kịch bản hoạt động của các đối tượng trong chương trình. Các đối tượng gửi các thông điệp qua lại lẫn nhau. VD Smalltalk, Eiffel, C+ +, Java,… - Họ ngôn ngữ lôgic Chương trình viết trên ngôn ngữ lôgic là tập hợp các quy tắc và các sự kiện, được diễn đạt bằng các mệnh đề, liên quan đến vấn đề cần giải quyết. Người lập trình chỉ cần đặc tả lôgic của vấn đề, còn cơ chế giải quyết vấn đề theo đặc tả đó được cài sẵn trong chương trình dịch. VD Prolog, VisiCalc,… Câu 8 Đặc trưng cơ bản của ngôn ngữ lập trình hướng đối tượng - Là kĩ thuật lập trình hỗ trợ công nghệ đối tượng. OOP được xem là giúp tăng năng suất, đơn giản hóa độ phức tạp khi bảo trì cũng như mở rộng phần mềm bằng cách cho phép lập trình viên tập trung vào các đối tượng phần mềm ở bậc cao hơn. Ngoài ra, nhiều người còn cho rằng OOP dễ tiếp thu hơn cho những người mới học về lập trình hơn là các phương pháp trước đó. - Chương trình của ngôn ngữ hướng đối tượng là một kịch bản hoạt động của các đối tượng trong chương trình. Các đối tượng gửi các thông điệp qua lại lẫn nhau - Đặc trưng cơ bản - Tính trừu tượng Đây là khả năng của chương trình bỏ qua hay không chú ý đến một số khía cạnh của thông tin mà nó đang trực tiếp làm việc lên, nghĩa là nó có khả năng tập trung vào những cốt lõi cần thiết. Mỗi đối tượng phục vụ như là một "động tử" có thể hoàn tất các công việc một cách nội bộ, báo cáo, thay đổi trạng thái của nó và liên lạc với các đối tượng khác mà không cần cho biết làm cách nào đối tượng tiến hành được các thao tác. Tính chất này thường được gọi là sự trừu tượng của dữ liệu. Tính trừu tượng còn thể hiện qua việc một đối tượng ban đầu có thể có một số đặc điểm chung cho nhiều đối tượng khác như là sự mở rộng của nó nhưng bản thân đối tượng ban đầu này có thể không có các biện pháp thi hành. Tính trừu tượng này thường được xác định trong khái niệm gọi là lớp trừu tượng hay lớp cơ sở trừu tượng + Đóng gói dữ liệu dữ liệu luôn được tổ chức thành các thuộc tính của lớp đối tượng. Việc truy nhập đến dữ liệu phải thông qua các phương thức của đối tượng lớp. + Sử dụng lại mã nguồn việc sử dụng lại mã nguồn được thể hiện thông qua cơ chế kế thừa. Cơ chế này cho phép các lớp đối tượng có thể kế thừa từ các lớp đối tượng khác. Khi đó, trong các lớp kế thừa, có thể sử dụng các phương thức mã nguồn của các lớp bị kế thừa, mà không cần phải định nghĩa lại. VD Smalltalk, Eiffel, C++, Java,… Câu 9 Phân tích 3 yêu cầu của một ngôn ngữ lập trình - Tính dễ viết + Ngôn ngữ lập trình phải có tính diễn đạt cao Cung cấp cho người lập trình những công cụ để có thể nghĩ sao viết vậy kỹ thuật đệ qui. + Ngôn ngữ phải đơn giản để dễ đọc, dễ nhớ và dễ nắm vững không nên có quá nhiều khái niệm. VD ngôn ngữ C có quá nhiều toán tử, các toán tử gần giống nhau. + Ngôn ngữ phải linh hoạt. VD C linh hoạt hơn Pascal với phát biểu Break, Return - Tính dễ đọc + GOTO Pascal làm chương trình khó đọc + Dấu gạch dưới “_” trong danh hiệu làm chương trình dễ đọc hơn - Tính tin cậy xác suất chạy đúng cao trong quá trình sử dụng + Ngôn ngữ cần hạn chế sự xuất hiện của các lỗi không thể ngờ được. VD phát biểu trong FORTRAN SUMI,J= I + J; + Hiệu ứng lề side effect cũng là một nguồn gây lỗi + Ngôn ngữ cần kiểm tra chặt chẽ sự tương hợp kiểu của các biến trong biểu thức và phép gán, sự tương hợp của danh sách thông số của chương trình con ở nơi gọi và nơi định nghĩa. + Các bộ phận của chương trình cần có tính độc lập đối với nhau cao. + Tính tin cậy còn phụ thuộc vào chất lượng của chương trình dịch Câu 10 Tiêu chuẩn để đánh giá một ngôn ngữ lập trình tốt - Tính rõ ràng clarity, đơn giản simplicity, nhất quán unity của các khái niệm - Tính rõ ràng của cú pháp chương trình clarity of program syntax. Khả năng định nghĩa và sử đụng các cấu trúc hoặc các phép toán phức tạp cho phép bỏ qua các cho tiết. - Tính tự nhiên đối với các ứng dụng naturalness for the application - Hỗ trợ tính trừu tượng hóa support for abstraction - Khả năng của ngôn ngữ lập trình hỗ trợ người lập trình tạo ra các chương trình đúng đắn. Phát hiện và sửa lỗi và thực hiện tiếp tục mà không cần dừng lại. - Dễ dàng kiểm tra chương trình - Môi trường lập trình đơn giản - Tính khả chuyển của chương trình - Chi phí sử dụng thấp chi phí thực thi, dịch, viết, kiểm tra, sử dụng, bảo trì chương trình. Câu 11. Các thành tố cuả một ngôn ngữ lập trình hiện đại -Các dạng câu lệnh định nghĩa, khai báo, gán giá trị, kết hợp, điều kiện, vòng lặp, gọi hàm, thủ tục, macro, các chỉ thị tiền xử lý ifndef MY_LIB include " endif trong C/C++, chú giải • Chương trình con và macro một khối lệnh được dùng lại nhiều lần • Biến, hằng, tham số và đối số • Từ vựng qui ước từ khóa, các tên chuẩn hay tên cho trước, các ký hiệu • Các luật cấm ngoại lệ lỗi cú pháp, lỗi ý nghĩa • Ngoài ra còn 1 số thành tố khác như - Giao diện đồ họa - Điều khiển theo sự kiện - Thời gian thực - Hỗ trợ hệ điều hành Câu 12 Trình bày khái niệm siêu ngôn ngữ meta language, và cho biết vai trò của siêu ngôn ngữ trong quá trình thiết kế ngôn ngữ lập trình, lấy ví dụ một vài siêu ngôn ngữ. - Khái niệm Ngôn ngữ dùng để xác định cú pháp hoặc ngữ nghĩa của một ngôn ngữ lập trình gọi là siêu ngôn ngữ Meta language 777 Khái niệm ngôn ngữ học của GS. Nguyễn Thiện Giáp - Vai trò Nó có vai trò quan trọng trong quá trình thiết kế ngôn ngữ lập trình Cú pháp quy định sự kết hợp giữa các kí hiệu trong bộ từ vựng. Ngữ nghĩa qui định ý nghĩa của mỗi sự kết hợp trong việc thiết kế ngôn ngữ, ngữ nghĩa hình thức cho phép các nhà thiết kế mô tả rõ ràng và chính xác ngữ nghĩa cũng như các đặc tả của ngôn ngữ. Cú pháp là thành phần quan trọng nhất trong một ngôn ngữ. Cú pháp được biểu diễn bởi một bộ luật cú pháp. Bộ luật này dùng để mô tả cấu trúc của chương trình, câu lệnh. Để lập trình, người lập trình phải nắm được bộ luật cú pháp của ngôn ngữ mà mình định xây dựng chương trình, để lập trình đúng. VD Văn phạm phi ngữ cảnh, BNF,… Câu 13. Đặc tả từ vựng trong NNLT - Ngôn ngữ là tập hợp chuỗi các ký tự từ alphabet A…Z, a…z, $,,0 9, +,_,*,/,=,… - Token Một token là một tập hợp các xâu kí tự có một nghĩa xác định. Ví dụ Các từ khoá, định danh, toán tử, hằng, xâu kí tự, … - Pattern Pattern của một token là các qui tắc kết hợp các kí tự để tạo nên token đó - Lexeme Là một chuỗi các kí tự thoả mãn pattern của một token Câu 14. Biểu thức chính quy - Để biểu diễn các token người ta dùng biểu thức chính quy. - Một biểu thức chính quy là một chuỗi miêu tả một bộ các chuỗi khác, theo những quy tắc cú pháp nhất định - BTCQ có thể hiểu như là một ngôn ngữ nhỏ dùng cho mục đích để tìm một chuỗi con trong biểu thức chuỗi lớn. Câu 15 Anh/chị hãy cho biết vì sao cần đặc tả cú pháp ngôn ngữ lập trình. Đầu vào và đầu ra của công việc đặc tả cú pháp là gì ? Phân tích cú pháp có mục đích duyệt chương trình nguồn để phát hiện và thông báo các lỗi không đúng với quy ước của ngôn ngữ. Các lỗi này làm cho nghĩa của chương trình không rõ và do đó không thể dịch đúng được. Ví dụ trong ngôn ngũ PASCAL ta viết dòng lệnh d = a+ b/e-f+g. Khi đọc đến dấu ngoặc đóng thứ 2 sau f, ta sẽ không hiểu được nguời viết muốn tính gì và đương nhiên cũng không thể dịch được. Lý do làm cho dòng lệnh không rõ nghĩa ở đây là thiếu một dấu ngoặc "" ở phía trước, có thể là trước chữ e, cũng có thể trước chữ a. Những lỗi sai với quy ước của ngôn ngữ gọi là lỗi cú pháp. Quá trình phân tích cú pháp cũng tạo ra các thông tin cần thiết về cấu trúc của chương trình và các đối tượng sẽ dùng trong công việc dịch được mô ta tiếp theo đây. Trong quá trình phân tích cú pháp, danh mục các đối tượng cũng được xây dựng để còn sinh mã chương trình trong giai đoạn tiếp theo. Công việc này gọi là phân tích từ vựng. - Đầu vào là chương trình nguồn - Đầu ra là + Những lỗi cú pháp cần sửa + Thông tin cần thiết về cấu trúc của chương trình Câu 16 Trình bày các đặc điểm của cú pháp cụ thể Trả lời * Cú pháp của ngôn ngữ được định nghĩa bởi bộ 4 Văn phạm phi ngữ cảnh Context – Free Grammar - Ký hiệu bắt đầu S ∈ NStart symbol - Tập các ký hiệu không kết thúc N Non-terminals - Tập các ký hiệu kết thúc Terminals - Tập các luật sinh P Production có dạng A → a Với A ∈ N và a là chuỗi các ký hiệu kết thúc và không kết thúc Câu hợp lệ của ngôn ngữ là chuỗi kí hiệu kết thúc được dẫn ra từ kí hiệu khởi đầu S thông qua các luật sinh trong tập luật sinh P * BNF là một siêu ngôn ngữ phổ biến để xây dựng cú pháp cụ thể * Ví dụ Cú pháp cụ thể dạng BNF cho biểu thức trong PASCAL - = - = - = - = a b c,….z - = 0 1 2,…9 - = +, -, or - * / div mod and Cú pháp cụ thể còn được gọi là cú pháp phi ngữ cảnh context-free syntax, trong đó vế trái của mỗi luật sinh chỉ có duy nhất một ký hiệu không kết thúc. Cú pháp phi ngữ cảnh biểu diễn được cú pháp của mọi ngôn ngữ lập trình cấp cao hiện nay. Câu 17 Anh/chị hãy phân tích vai trò của đặc tả ngữ nghĩa ngôn ngữ lập trình. Đầu vào, đầu ra của công việc đặc tả ngữ nghĩa là gì ? - Đặc tả ngữ nghĩa hình thức cho phép + Chứng minh tính đúng đắn của chương trình + Kiểm tra tính đúng đắn của chương trình dịch - Cú pháp và ngữ nghĩa hình thức được dùng để hiện thực và thiết kê ngôn ngữ lập trình. + Cú pháp hình thức được sử dụng để tạo ra bộ phân tích cú pháp của ngôn ngữ + Ngữ nghĩa hình thức giúp cho quá trình sinh tự động các trình thông dịch và biên dịch của ngôn ngữ. + Trong việc thiết kế ngôn ngữ, ngữ nghĩa hình thức cho phép nhà thiết kế mô tả rõ ràng và chính xác ngữ nghĩa cũng như các đặc tính của ngôn ngữ. - Đặc tả ngữ nghĩa hình thức thông qua bộ phân tích ngữ nghĩa. - Bộ phân tích ngữ nghĩa BPTNN thực hiện + Kiểm tra lỗi ngữ nghĩa kiểm tra kiểu; kiểm tra phạm vi của hằng, biến; kiểm tra việc sử dụng tên + Thu nhận thông tin thuộc tính cho các từ tố token, ví dụ như thông tin về giá trị, thông tin về loại hằng, biến hay hàm cho tên. + BPTNN phân tích ý nghĩa của các cấu trúc cú pháp tạo nên chương trình nguồn. VD trong biểu thức gán c=a+b*7, BPTNN xác định ý nghĩa của các tác vụ =, +, *, kiểm tra xem các tác vụ có nhận các đối số thuộc các kiểu thích hợp hay không dựa vào bảng ký hiệu. Câu 18 Anh/chị hãy cho biết đặc điểm của quá trình biên dịch lấy VD về các ngôn ngữ biên dịch mà anh/chị biết Trả lời * Đặc điểm của quá trình biên dịch Chương trình nguồn được trình biên dịch chuyển sang chương trình đích, thường ở dạng mã máy hoặc assembly, sau đó chương trình đích mới được thực thi. Trong hệ thống biên dịch dữ liệu và chương trình nguồn được xử lý ở hai thời điểm khác nhau. Trong đó - Chương trình nguồn viết bằng ngôn ngữ nguồn - Chương trình đối tượng được thể hiện trên ngôn ngữ đối tượng - Thời gian chuyển đổi từ chương trình nguồn sang chương trình đối tượng goi là thời gian dịch compile time - Thời gian diễn ra sự thực thi chương trình đối tượng trên máy tính gọi là thời gian thực thi execution time hoăc run time * Ví dụ về ngôn ngữ biên dịch Ngôn ngữ biên dịch là ngôn ngữ mà chương trình dịch cho nó là chương trình biên dịch. Ví dụ như Fortran , Pascal, C, C++… Câu 19 - Thay vì chuyển đổi toàn bộ chương trình nguồn như trình biên dịch, trình thông dịch chỉ chuyển đổi một mệnh đề của chương trình và thực hiện đoạn mã kết quả ngay, sau đó nó tiếp tục chuyển đổi mệnh đề thứ 2 rồi thi hành đoạn mã kết quả thứ 2 và cứ thế. - Khi sử dụng trình thông dịch, mỗi lần chạy chương trình là mỗi lần chương trình nguồn được thông dịch sang ngôn ngữ máy. Không có chương trình đối tượng nào được tạo ra. Ưu điểm - có thể chạy một chương trình vẫn còn lỗi cú pháp. Chỉ đến lúc thông dịch đến câu lệnh có lỗi cú pháp, quá trình thi hành chương trình mới bị ngừng lại và trình thông dịch sẽ thông báo lỗi. - Do không có chường trình đối tượng nào được tao ra ==> tốn ít dung lượng đĩa - Có thể chạy trên mọi hệ điều hành Nhược điểm - Trong thông dịch thì chương trình đích không được lưu lại nên mỗi lần thực hiện phải dịch lại từ đầu. ngược lại với trình biên dịch • Một số ngôn ngữ thông dịch vbscript, javascript, shell script, sql script. Câu 20 Anh chị hãy liệt kê các giai đoạn của trình biên dịch, đầu vào đầu ra của các giai đoạn? Trả lời Chương trình dịch chia làm 6 giai đoạn - Phân tích từ vựng - Phân tích cúa pháp - Phân tích ngữ nghĩa - Sinh mã trung gian - Tối ưu mã - Sinh mã đích * Phân tích từ vựng - Đầu vào chương trình nguồn là 1 chuỗi các kí hiệu - Đầu ra các kí hiệu trong chuỗi chương trình nguồn được gom lại thành các nhóm kí hiệu có ý nghĩa gọi là các token, như từ khóa, tên biến, hằng, kí hiệu tác vụ. * Phân tích cú pháp - Đầu vào chuỗi các token do bộ phân tích từ vựng cung cấp - Đầu ra cấu trúc phức tạp hơn của chương trình nguồn như biểu thức, phát biểu, chương trình con. Các cấu trúc được thể hiện dưới dạng cây cú pháp với nút lá là các token. * Phân tích ngữ nghĩa - Đầu vào Các cấu trúc cú pháp tạo nên chương trình nguồn - Đầu ra phát hiện các lỗi ngữ nghĩa, thông tin thuộc tính cho các từ tố token cho ra chương trình nguồn đã sửa lỗi * Sinh mã trung gian - Đầu vào Chương trình nguồn có ở bước trên - Đầu ra dạng biểu diễn mã trung gian mã bộ tứ, mã 3 địa chỉ của chương trình nguồn * Tối ưu mã Đầu vào Mã trung gian vừa được sinh ra ở bước trên - Đầu ra chương trình đích tối ưu về tốc độ thực thi và bộ nhớ sử dụng * Sinh mã đích - Đầu vào mã trung gian đã được tối ưu - Đầu ra mã đích thông thường ở dạng mã máy hay mã Assembly Phân tích Tổng hợp Câu 21 Anh/chị hãy trình bày nội dung của quá trình phân tích từ vựng. 1. Source program Chương trình nguồn đối với chương trình dịch chỉ là một chuỗi kí hiệu 2. Lexical analyzer Bộ phân tích từ vựng dò các kí hiệu trong chuỗi kí hiệu chương trình nguồn, và gom chúng lại thành các nhóm kí hiệu có ý nghĩa gọi là các Token như từ khóa, tên biến, hằng, kí hiệu tác vụ. 3. VD phân tích từ vựng phép gán c=a+b*7 thu được c identđịnh danh b identđịnh danh = becomeskí hiệu tác vụ gán * times kí hiệu tác vụ nhân a identđịnh danh 7 number số/hằng + pluskí hiệu tác vụ cộng Chuỗi tokens thu được id1=id2+id3*7 ident, c becomes ident, a plus ident, b times number, 7 4. Parser Bộ phân tích cú pháp nhận các kí hiệu có ý nghĩa gọi là các Token trong chuỗi kí hiệu từ bộ phân tích từ vựng, sau đó bộ phân tích từ vựng lấy token kế Get next token từ bộ phân tích cú pháp. 5. Bảng danh hiệu symbol table Câu 22 Anh chị hãy cho biết bảng danh hiệu Symbol table dùng để làm gì? Và vai trò của nó trong quá trình biên dịch chương trình? * Bảng danh hiệu symbol table là một cấu trúc dữ liệu dùng để lưu trữ tất cả định danh bao gồm các trường lưu giữ ký hiệu và các thuộc tính của nó là thông tin của chương trình Các thông tin này được tập hợp từ các giai đoạn phân tích của trình biên dịch và được sử dụng bởi giai đoạn tổng hợp để sinh mã đích * Vai trò của bảng danh hiệu Symbol table trong quá trình biên dịch chương trình là Source program Lexical analyzer Get next token Token Parser Symbol table c …. a …. b … Danh hiệu Thuộc tính - Là cơ sở dữ liệu cho toàn bộ hệ thống biên dịch - Trong quá trình chạy chương trình chỉ cần lấy lại thông tin từ bảng Symbol table mà không cần kiểm tra lại thông tin - Khi chạy chương trình lần thứ 2 mà dữ liệu nguồn không có gì thay đổi thì nó sẽ chạy trực tiếp trên file đích đã chứa sẵn bảng Symbol table1 lần biên dịch mà thực thi được nhiều lầnthời gian chạy chương trình nhanh Câu 23 Anh chị hãy trình bày nội dung của quá trình phân tích cú pháp - Bộ phân tích cú pháp phân tích chuỗi các token do bộ phân tích từ vựng cung cấp, để thu được các cấu trúc phức tạp hơn của chương trình nguồn như biểu thức, phát biểu, chương trình con. Các cấu trúc được thể hiện dưới dạng cây cú pháp với nút lá là các token. - Ví dụ cây cú pháp thu được của phát biểu gán “c=a+b*7“ Câu 24 Anh chị hãy trình bày nội dung của quá trình phân tích ngữ nghĩa -Bộ phân tích ngữ nghĩa BPTNN thực hiện – Kiểm tra lỗi ngữ nghĩa kiểm tra kiểu; kiểm tra phạm vi của hằng, biến; kiểm tra việc sử dụng tên – Thu nhận thông tin thuộc tính cho các từ tố token, ví dụ như thông tin về giá trị, thông tin về loại hằng, biến hay hàm cho tên. -BPTNN phân tích ý nghĩa của các cấu trúc cú pháp tạo nên chương trình nguồn. VD trong biểu thức gán c=a+b*7, BPTNN xác định ý nghĩa của các tác vụ =, +, *, kiểm tra xem các tác vụ có nhận các đối số thuộc các kiểu thích hợp hay không dựa vào bảng ký hiệu. -Việc phân tích ngữ nghĩa phải dựa vào các luật ngữ nghĩa đi kèm với từng luật cú pháp để thực hiện chức năng sinh thuộc tính cho các từ tố và kiểm tra lỗi ngữ nghĩa. Câu 25 Anh chị hãy cho biết các lỗi của chương trình được phát hiện như thế nào trong quá trình biên dịch chương trình */ Xử lý lỗi cú pháp Chương trình nguồn có thể chứa các lỗi ở nhiều mức độ khác nhau - Lỗi từ vựng như danh biểu, từ khóa, toán tử viết không đúng. - Lỗi cú pháp như ghi một biểu thức toán học với các dấu ngoặc đóng và mở không cân bằng. - Lỗi ngữ nghĩa như một toán tử áp dụng vào một toán hạng không tương thích. - Lỗi logic như thực hiện một lời gọi đệ qui không thể kết thúc. Phần lớn việc phát hiện và phục hồi lỗi trong một trình biện dịch tập trung vào giai đọan phân tích cú pháp. Vì thế, bộ xử lý lỗi error handler trong quá trình phân tích cú pháp phải đạt mục đích sau ™ Ghi nhận và thông báo lỗi một cách rõ ràng và chính xác. ™ Phục hồi lỗi một cách nhanh chóng để có thể xác định các lỗi tiếp theo. ™ Không làm chậm tiến trình của một chương trình đúng. */ Các chiến lược phục hồi lỗi Phục hồi lỗi là kỹ thuật vượt qua các lỗi để tiếp tục quá trình dịch. Nhiều chiến lược phục hồi lỗi có thể dùng trong bộ phân tích cú pháp. Mặc dù không có chiến lược nào được chấp nhận hoàn toàn, nhưng một số trong chúng đã được áp dụng rộng rãi. Ởđây, chúng ta giới thiệu một số chiến lược [...]... chương trình vào trong bảng danh biểu symbol table nơi chứa thông tin về kiểu của các biến và chương trình con - Ưu điểm tất cả các nhánh chương trình, các phép toán đều được kiểm tra nên không bỏ sót các lỗi về kiểu Mặt khác thông tin về kiểu không gắn với ĐTDL tại thời điểm thực thi chương trình nên tiết kiệm bộ nhớ và tăng tốc độ chạy chương trình - Nhược điểm không mềm dẻo, cụ thể người lập trình. .. -Ưu điểm mềm dẻo khi viết chương trình, không cần khai báo kiểu dữ liệu và kiểu của ĐTDL có thể thay đổi trong quá trình thực thi chương trình -Nhược điểm có khả năng bỏ sót lỗi về kiểu; yêu cầu bộ nhớ lớn do phải lưu trữ thông tin kiểu dữ liệu trong quá trình thực hiện chương trình; làm chậm quá trình thực thi do vừa phải tính toán vừa phải kiểm tra kiểu -Các ngôn ngữ kiểm tra kiểu động SNOBOL4,... toán quan hệ so sánh hai giá trị dữ liệu đối số và trả về kết quả là một đối tượng dữ liệu logic đúng hoặc sai - Gán trị Cũng như phép gán tổng quát, phép gán của số nguyên có thể trả về hoặc không trả về một giá trị Sự cài đặt Kiểu dữ liệu nguyên hầu hết được cài đặt một cách trực tiếp bằng cách dùng sự biểu diễn bộ nhớ được xác định bởi phần cứng và tập hợp các phép tính số học, các phép toán... trị “NULL” Tùy thuộc vào kiểu của biến mà giá trị NULL này sẽ có một giá trị cụ thể, ví dụ nếu là biến số thì NULL là 0, nếu là biến chuỗi kí tự thì NULL là chuỗi rỗng, nếu biến là logic thì NULL là FALSE - Khởi tạo biến ngay sau khi nó vừa được tạo ra là một cách lập trình tốt và trong một số ngôn ngữ mới đều cung cấp phương tiện để làm điều này một cách dễ dàng Trong ngôn ngữ Pascal một biến được... phẩy lạ hoặc thêm vào một dấu chấm phẩy c Chiến lược dùng các luật sinh sửa lỗi error production Thêm vào văn phạm của ngôn ngữ những luật sinh lỗi và sử dụng văn phạm này để xây dựng bộ phân tích cú pháp, chúng ta có thể sinh ra bộ đoán lỗi thích hợp để chỉ ra cấu trúc lỗi được nhận biết trong dòng nhập d Chiến lược hiệu chỉnh toàn cục global correction Một cách lý tưởng là trình biên dịch tạo... chương trình con - Khi chương trình được thực thi, chương trình chính được thực hiện đầu tiên Trong thời gian thực thi, chương trình chính có thể gọi các CTC thực hiện Và mỗi CTC này, đến lượt nó, lại có thể gọi các chương trình con khác thực hiện - CTC không được đệ qui - Cần có các phát biểu gọi tường minh - CTC phải được hoàn thành ở mỗi lần gọi - Điều khiển được chuyển ngay tức thời ở điểm gọi - Trình. .. này gọi là giá trị rác iều nguy hiểm là giá trị rác này vẫn là một giá trị hợp lệ Vì thế chương trình có thể xử lý trên giá trị rác này một cách bình thường và chúng ta không thể kiểm sóat được kết quả xử lý đó • Vì tính chất nghiêm trọng như đã nói trên của biến chưa được khởi tạo, các ngôn ngữ lập trình có thể sử dụng các giải pháp sau để khắc phục - Nếu biến chưa được khởi tạo thì sẽ có giá trị... quá trình sống - Các biến tĩnh có một định danh được kết nối với địa chỉ vùng nhớ lưu trữ biến và được truy xuất trực tiếp thông qua định danh đó • Ưu điểm - Khai báo tường minh - Biến tĩnh tồn tại trong suốt thời gian thực thi chương trình - Kích thước của biến không thay đổi trong suốt quá trình sống • Nhược điểm - Cấp phát ô nhớ dư, gây ra lãng phí ô nhớ - Cấp phát ô nhớ thi u, chương trình thực thi. .. lẫn số thực và số nguyên thì số nguyên được chuyển đổi tự động sang kiểu số thực Câu 30 Anh chị hãy phân biệt các loại phép gán khác nhau - Là tác vụ cơ bản để thay đổi giá trị của đối tượng dữ liệu - Đặc tả tác vụ gán = type1 x type2 → void = type1 x type2 → type3 Z = X + Y Z = X + Y = W ƒ 2 A=B=C Ngôn ngữ Pascal Ngôn ngữ C - Các NNLT khác nhau thì có phép gán khác nhau -Khác nhau về cú pháp... hằng MaxInt Miền giá trị của kiểu số nguyên là tập các số nguyên từ - MaxInt đến MaxInt Giá trị MaxInt được lựa chọn phản ánh giá trị nguyên lớn nhất có thể biểu diễn được trong phần cứng 3ặc tả các phép toán - Các phép tính số học cộng +, trừ -, nhân *, chia / hoặc DIV, lấy phần dư MOD hoặc một số phép toán tương tự khác âm -, dương + - Các phép toán quan hệ bằng, khác, nhỏ hơn, lớn . dụ + Ngôn ngữ bậc thấp Ngôn ngữ máy, Assembly, … + Ngôn ngữ lập trình bậc cao fortran, pascal, C, Cobol…. Câu 7 Họ ngôn ngữ lập trình phổ biến là - Ngôn ngữ máy và ngôn ngữ ASSEMBLY Ngôn ngữ. 12 Trình bày khái niệm siêu ngôn ngữ meta language, và cho biết vai trò của siêu ngôn ngữ trong quá trình thi t kế ngôn ngữ lập trình, lấy ví dụ một vài siêu ngôn ngữ. - Khái niệm Ngôn ngữ. Lịch sử phát triển của ngôn ngữ lập trình • Ngôn ngữ lập trình đầu tiên là ngôn ngữ máy tính mã nhị phân. Ngôn ngữ máy phụ thuộc toàn bộ vào kiến trúc phần cứng và những quy ước khắt khe của - Xem thêm -Xem thêm Đề thi và đáp án môn Nguyên lý những ngôn ngữ lập trình, Đề thi và đáp án môn Nguyên lý những ngôn ngữ lập trình, Tài liệu Nguyên lý và phương pháp lập trình bao gồm các kiến thức về nguyên lý các ngôn ngữ lập trình, các phương pháp và kỹ thuật lập trình đệqui, chiến lược tham lam, chia để trị, qui hoạch động, quay lui, các mô thức lập trình lập trình thủ tục, lập trình hướng đối tượng, lập trình hàm, lập trình logic.

nguyen ly ngon ngu lap trinh