Bài giảng Lập trình mạng (Phần 2)

3.1. Javascript

3.1.1. Giới thiệu Javascript

JavaScript là ngôn ngữ dưới dạng script có thể gắn với các file HTML. Nó không

được biên dịch mà được trình duyệt diễn dịch. Không giống Java phải chuyển thành các

mã để biên dịch, trình duyệt đọc JavaScript dưới dạng mã nguồn. Chính vì vậy Chúng ta có

thể dễ dàng học JavaScript qua ví dụ bởi vì Chúng ta có thể thấy cách sử dụng JavaScript

trên các trang Web.

JavaScript là ngôn ngữ dựa trên đối tượng, có nghĩa là bao gồm nhiều kiểu đối tượng,

ví dụ đối tượng Math với tất cả các chức năng toán học. Tuy vậy JavaScript không là ngôn

ngữ hướng đối tượng như C++ hay Java do không hỗ trợ các lớp hay tính thừa kế.

JavaScript có thể đáp ứng các sự kiện như tải hay loại bỏ các form. Khả năng này cho

phép JavaScript trở thành một ngôn ngữ script động.

Giống với HTML và Java, JavaScript được thiết kế độc lập với hệ điều hành. Nó có

thể chạy trên bất kỳ hệ điều hành nào có trình duyệt hỗ trợ JavaScript. Ngoài ra JavaScript

giống Java ở khía cạnh an ninh: JavaScript không thể đọc và viết vào file của người dùng.

Các trình duyệt web như Nescape Navigator 2.0 trở đi có thể hiển thị những câu lệnh

JavaScript được nhúng vào trang HTML. Khi trình duyệt yêu cầu một trang, server sẽ gửi

đầy đủ nội dung của trang đó, bao gồm cả HTML và các câu lệnh JavaScript qua mạng tới

client. Client sẽ đọc trang đó từ đầu đến cuối, hiển thị các kết quả của HTML và xử lý các

câu lệnh JavaScript khi nào chúng xuất hiện.

Các câu lệnh JavaScript được nhúng trong một trang HTML có thể trả lời cho các sự

kiện của người sử dụng như kích chuột, nhập vào một form và điều hướng trang. Ví dụ

Chúng ta có thể kiểm tra các giá trị thông tin mà người sử dụng đưa vào mà không cần đến

bất cứ một quá trình truyền trên mạng nào. Trang HTML với JavaScript được nhúng sẽ

kiểm tra các giá trị được đưa vào và sẽ thông báo với người sử dụng khi giá trị đưa vào là

không hợp lệ.

Mục đích của phần này là giới thiệu về ngôn ngữ lập trình JavaScript để Chúng ta có

thể viết các script vào file HTML của mình.

Bài giảng Lập trình mạng (Phần 2) trang 1

Trang 1

Bài giảng Lập trình mạng (Phần 2) trang 2

Trang 2

Bài giảng Lập trình mạng (Phần 2) trang 3

Trang 3

Bài giảng Lập trình mạng (Phần 2) trang 4

Trang 4

Bài giảng Lập trình mạng (Phần 2) trang 5

Trang 5

Bài giảng Lập trình mạng (Phần 2) trang 6

Trang 6

Bài giảng Lập trình mạng (Phần 2) trang 7

Trang 7

Bài giảng Lập trình mạng (Phần 2) trang 8

Trang 8

Bài giảng Lập trình mạng (Phần 2) trang 9

Trang 9

Bài giảng Lập trình mạng (Phần 2) trang 10

Trang 10

Tải về để xem bản đầy đủ

pdf 123 trang xuanhieu 9200
Bạn đang xem 10 trang mẫu của tài liệu "Bài giảng Lập trình mạng (Phần 2)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Lập trình mạng (Phần 2)

Bài giảng Lập trình mạng (Phần 2)
Giá trị mặc định 
3) Đối tƣợng Recordset 
Các phƣơng thức của đối tƣợng Recordset 
Phƣơng thức Diễn giải 
Addnew Tạo mới Record 
Cancel Hủy thao tác đang thực thi 
Close Đóng Recordset và đối tƣợng liên quan 
Delete Xóa record hay tập record hiện thời 
Find Tìm một record thỏa mãn điều kiện 
MoveFirset Đƣa vị trị của record hiện hành về record đầu tiên 
MoveLast Đƣa vị trị của record hiện hành về record cuối cùng 
MoveNext Đƣa vị trị của record hiện hành về record tiếp theo 
MovePrivious Đƣa vị trị của record hiện hành về record trƣớc đó 
 195 
Open Mở một recordset 
Requery Cập nhật lại dữ liệu bằng cách thực hiện lại cậu lệnh 
truy vấn ban đầu 
Resync Làm tuơi lại dữ liệut rong đối tƣợng Recorset hiện thời 
Save Lƣu Recordset vào tệp 
Seek Tìm chỉ mục Recordset 
Update Lƣu thay đổi 
GetRows Lấy nhiều record đƣa vào một mảng 
GetString Trả về recordset dƣới dạng chuỗi 
a. Phương thức Open 
Cú pháp: objRs.Open Source, Connection, CursorType, Locktype, Options 
b. Phương thức Addnew 
 Cho phép tạo một bản ghi mới, gán dữ liệu mới cho các field của các bản ghi và nó 
chỉ đƣợc cập nhật vào CSDL khi ta gọi phƣơng thức Update hay Updatebatch 
c. Phương thức Update 
 Phƣơng thức này dùng để cập nhật bản ghi hiện thời trong CSDL 
d. Phương thức Delete 
 phƣơng thức này cho phép xóa bản ghi trong Recordset 
Cú pháp: objRs.Delete 
e. Phương thức Close: Ngắt kết nối với CSDL 
Lưu trữ dữ liệu trả về 
ADO sử dụng đối tƣợng Recordset để lƣu trữ kết quả trả về từ câu truy vấn dữ liệu 
SELECT. Vì kết quả trả về của một câu truy vấn SELECT có nhiều bản ghi, cho nên có thể 
xem Recordset nhƣ mảng các bản ghi. 
Có 2 cách lấy dữ liệu từ câu truy vấn đặt vào biến Recordset: 
Thực hiện phƣơng thức Exexute của đối tƣợng Connection nhƣ câu lệnh truy vấn và 
trả về kết quả cho Recordset. 
 Ví dụ: Set rs = Conn.Execute(strSQL) 
 196 
Tạo một thực thể cho đối tƣợng Recordset và sử dụng phƣơng thức Open, kết hợp với 
đối tƣợng Connection đã tạo. 
Hiển thị dữ liệu trả về 
Khi muốn lấy dữ liệu của một trƣờng trong bản ghi hiện hành, lấy chuỗi tên của 
trƣờng đó nhƣ là đối số cho đối tƣợng Recordset hay đối số của thuộc tính Fields của đối 
tƣợng Recordset. Ví dụ objRS(―HOTEN‖) hay objRS.Fields(―HOTEN‖). 
Khi muốn dịch chuyển qua lại đến các bản ghi đƣợc lƣu trong đối tƣợng Recordset, 
sử dụng phƣơng thức MoveNext, MovePrevious, MoveFirst, MoveLast và phải đi kèm với 
việc kiểm tra bản ghi hiện thời đang ở vị trí đầu hay cuối bản ghi. Để làm điều đó, dùng 
thuộc tính BOF hoặc EOF để kiểm tra. 
Ví vụ 4.63: Đọc dữ liệu từ bảng cơ cở dữ liệu sinhvien trong cơ sở dữ liệu 
Quanlysinhvien.mdb 
<% 
'khai báo biến kết nối cơ sở dữ liệu 
Dim cnn 
' tạo đối tượng kết nối 
 set cnn = Server.CreateObject("ADODB.Connection") 
 ' Tạo xâu kết nối 
cnn.Connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0; Data 
 Source=D:\asp\quanlysinhvien.mdb" 
 ' Mở kết nối 
 cnn.open 
Dim rs, sql 
' tạo đối tượng RecordSet 
set rs = Server.CreateObject("ADODB.RecordSet") 
' Tạo câu lệnh sql 
sql = "Select * from sinhvien" 
' Mở RecordSet 
 rs.open sql, cn, 1, 3 
 while (Not rs.eof ) 
response.write(rs("masv") &" " & rs("Tensv") &" " & rs("malop")& "" 
) 
 rs.MoveNext 
 wend 
%> 
 197 
4) Đối tƣợng Record 
Đối tƣợng này lƣu trữ bản ghi trong Recordset, một thực mục hay tệp tin trong File 
System. Để sử dụng đối tƣợng này cần phải khai báo thực thể cho đối tƣợng Recordset. 
Dim objRec 
Set objRec = Server.CreateObject (“ADODB.Record”) 
Đối tƣợng Recordset có các phƣơng thức sau: 
Phƣơng thức Diễn giải 
Cancel Hủy thực hiện trên Record 
Close Đóng đối tƣợng Record 
CopyRecord Copy tệp hay thƣ mục 
DeleteRecord Xóa một tệp hoặc thƣ mục 
GetChildren 
Trả về một đối tƣợng Recordset, mỗi dòng của Recordset lƣu 
trong tệp hoặc thƣ mục 
MoveRecord Di chuyển một tệp hay một thƣ mục 
Open Mở một đối tƣợng Record tồn tại, tạo mới một tệp hoặc thƣ mục 
a. Phương thức Open 
Sau khi tạo thực thể của Record, có thể dùng phƣơng thức này để open, tạo mới một 
tệp hay tạo mới một thƣ mục: 
Cú pháp: 
 objRec.Open 
Source,ActiveConnection,[Model],[CreateOption],[Option],[user],[Passwd]) 
b. Phương thức CopyRecord; dùng để chép một tệp hay một thư mục đến nơi khác. 
Cú pháp: 
objRec.CopyRecord (Source, Destionation, Username, Password,opt,async) 
c. Phương thức DeleteRecord xóa một tệp hoặc thư mục chỉ định 
Cú pháp: 
 objRec.DeleteRecord(Source,Async) 
5) Đối tƣợng Stream 
Dùng để lƣu trữ luồng dữ liệu dạng text hoặc nhị phân. Trƣớc khi sử dụng cần phải khai 
báo 
 198 
Set objStream = Server.CreateObject(“ADODB.Stream”) 
Các phƣơng thức Stream: 
Close Đóng đối tƣợng Stream 
Copyto Chép một số kí tự hoặc byte từ đối tƣợng Stream này sáng đối 
tƣợng Stream khác 
Flush Gửi nội dung của đối tƣợng Stream 
LoadFromFile Lấy nội dung của một đối tƣợng vào đối tƣợng Stream 
Open Mở một đối tƣợng stream từ URL hay đối tƣợng Record 
Read Đọc số lƣợng byte trong đối tƣợng Stream chứa dữ liệu nhị phân 
ReadText Đọc số kí tự trong đối tƣợng Stream chứa nội dung là text 
SaveToFile Lƣu nội dụng đối tƣợng Stream vào tệp 
SetEOS Thiết lập thuộc tính của EOS đối với vị strí hiện thời 
SkipLine Bỏ qua một dòng khi đọc một Text Stream 
Write Ghi một số lƣợng byte của dữ liệu nhị phần và đối tƣợng Stream 
WriteText Ghi dữ liệu dạng Text vào đối tƣợng Stream 
4.8.3. Tập hợp các Errors 
Tập hợp Errors (Errors Collection) chứa tất cả các đối tƣợng Errors (Error objects). 
Tất cả các đối tƣợng Errors thuộc về hệ điều hành riêng kết hợp với ADO. Tập hợp Errors 
là chức năng chỉ có hiệu lực với các cơ sở dữ liệu đặc biệt nhƣ SQL server. Điều này đặc 
biệt có lợi khi thực hiện các câu lệnh có hơn nhiều một lỗi. 
Tập hợp Errors có một phƣơng thức và hai thuộc tính: 
- Clear method : Phƣơng thức xoá bỏ tất cả các đối tƣợng Errors trong tập hợp. 
Phƣơng thức này đƣợc sử dụng để xoá bỏ hoàn toàn các lỗi. 
- Count property : Thuộc tính trả lại số của đối tƣợng Errors hiện tại có trong tập hợp. 
- Item property : Thuộc tính trả lại đối tƣợng Errors đƣợc chỉ định. 
Đối tƣợng Error 
Chứa chi tiết lỗi ADO bị máy chủ bắt lỗi của nhà cung cấp dữ liệu. Tập này đƣợc xoá 
bỏ mỗi lần hoạt động mới gây ra lỗi. Từ đối tƣợng Errors có thể truy tìm tên, số và miêu tả 
của lỗi gây ra. 
Các thuộc tính của đối tƣợng Error 
 199 
Description: chuỗi miêu tả gắn với lỗi. 
HelpContext: giá trị ngữ cảnh trong file Help (nếu thuộc tính HelpFile kèm theo chỉ 
rằng có file trợ giúp Windows kết hợp với đối tƣợng Errors). 
HelpFile: chuỗi đƣờng dẫn và tên file của file Help Windows. 
NativeError: mã lỗi do nhà cung cấp dữ liệu địa phƣơng gây ra. 
Number: số lỗi đối với đối tƣợng Error (bằng 0 nếu không có lỗi). 
Source: chuỗi đại diện cho tên đối tƣợng hoặc ứng dụng gây lỗi ADO. 
SQLState: mã lỗi 5 ký tự do nhà cung cấp trả lại. 
Ví dụ 4.64: đoạn mã sau đây đọc các và hiển thị các lỗi 
<% 
For Each dbError In Conn.Errors 
Response.Write "" & dbError.Description & "" 
Response.Write "" & CStr(dbError.NativeError) & "" 
Response.Write "" & dbError.SQLState & "" 
Next 
Conn.Errors.Clear 
%> 
4.8.4. Stored Procedure và truyền tham số 
Thủ tục lƣu trữ là một đối tƣợng trong CSDL, bao gồm nhiều câu lệnh T-SQL đƣợc 
tập hợp lại với nhau thành một nhóm, và tất cả các lệnh này sẽ đƣợc thực thi khi thủ tục 
lƣu trữ đƣợc thực thi.Với thủ tục lƣu trữ, một phần nào đó khả năng của ngôn ngữ lập trình 
đƣợc đƣa vào trong ngôn ngữ SQL. 
 Thủ tục lƣu trữ có thể có các thành phần sau: Các cấu trúc điều khiển (IF, WHILE, 
FOR ) có thể đƣợc sử dụng trong thủ tục. Bên trong thủ tục lƣu trữ có thể sử dụng các biến 
nhƣ trong ngôn ngữ lập trình nhằm lƣu giữ các giá trị tính toán đƣợc, các giá trị đƣợc truy 
xuất đƣợc từ cơ sở dữ liệu. Một tập các câu lệnh SQL đƣợc kết hợp lại với nhau thành một 
khối lệnh bên trong một thủ tục. Một thủ tục có thể nhận các tham số truyền v ào cũng nhƣ 
có thể trả về các giá trị thông qua các tham số (nhƣ trong các ngôn ngữ lập trình). Khi một 
thủ tục lƣu trữ đã đƣợc định nghĩa, nó có thể đƣợc gọi thông qua tên thủ tục, nhận các tham 
số truyền vào, thực thi các câu lệnh SQL bên trong thủ tục và có thể trả về các giá trị sau 
khi thực hiện xong. 
1) Lợi ích của việc sử dụng thủ tục lƣu trữ: 
SQL Server chỉ biên dịch các thủ tục lƣu trữ một lần và sử dụng lại kết quả biên dịch 
này trong các lần tiếp theo trừ khi ngƣời dùng có những thiết lập khác. Việc sử dụng lại kết 
 200 
quả biên dịch không làm ảnh hƣởng đến hiệu suất hệ thống khi thủ tục lƣu trữ đƣợc gọi 
liên tục nhiều lần. 
Thủ tục lƣu trữ đƣợc phân tích, tối ƣu khi tạo ra nên việc thực thi chúng nhanh hơn 
nhiều so với việc phải thực hiện một tập rời rạc các câu lệnh SQL tƣơng đƣơng theo cách 
thông thƣờng. Thủ tục lƣu trữ cho phép chúng ta thực hiện cùng một yêu cầu bằng một câu 
lệnh đơn giản thay vì phải sử dụng nhiều dòng lệnh SQL. Điều này sẽ làm giảm thiểu sự 
lƣu thông trên mạng. 
Thay vì cấp phát quyền trực tiếp cho ng ƣời sử dụng trên các câu lệnh SQL và trên 
các đối tƣợng cơ sở dữ liệu, ta có thể cấp phát quyền cho ngƣời sử dụng thông qua các thủ 
tục lƣu trữ, nhờ đó tăng khả năng bảo mật đối với hệ thống. 
Các thủ tục lƣu trữ trả về kết quả theo 4 cách: 
- Sử dụng các tham số output. 
- Sử dụng các lệnh trả về giá trị, các lệnh này luôn trả về giá trị số nguyên. 
- Tập các giá trị trả vể của mỗi câu lệnh SELECT có trong thủ tục lƣu trữ hoặc của 
quá trình gọi một thủ tục lƣu trữ khác trong một thủ tục lƣu trữ. 
- Một biến con trỏ toàn cục có thể tham chiếu từ bên ngoài thủ tục. 
2) Tạo thủ tục lƣu trữ 
Thủ tục lƣu trữ đƣợc tạo thông qua câu lệnh Create Procedure. 
Cú pháp nhƣ sau: 
Create Procedure tên_thủ_tục [(danh_sách_tham_số)] 
[With Recompile|Encryption|Recompile,Encryption] 
As 
Các_câu_lệnh_của_thủ_tục 
Trong đó: 
With Recompile: yêu cầu SQL Server biên dịch lại thủ tục lƣu trữ mỗi khi đƣợc gọi. 
With Encryption: yêu cầu SQL Server mã hóa thủ tục lƣu trữ. 
Các_câu_lệnh_của_thủ_tục: Các lệnh T-SQL. Các lệnh này có thể nằm trong cặp 
BEGINEND hoặc không. 
3) Truyền tham số 
Cách viết nhƣ trên có hạn chế là: trong quá trình làm việc sẽ có rất nhiều đơn đặt 
hàng mới, do đó ngƣời dùng sẽ phải viết đi viết lại những câu lệnh tƣơng tự nhau cho các 
khách hàng khác nhau. Một cách giải quyết vấn đề này là dùng thủ tục lƣu trữ và dùng 
tham số để nhận các thông tin thay đổi. 
Ví dụ 4.65: 
create procedure sp_InsertOrderAndOrderDetail 
 201 
@customerid int, 
@orderdate datetime, 
@orderid int, 
@itemid int, 
@quantity decimal, 
as 
begin 
insert into orders 
values(@customerid, @orderdate) 
insert into orderdetail 
values(@orderid, @itemid, @quantity) 
end 
Thực hiện thủ tực lưu trữ này như sau: 
sp_InsertOrderAndOrderDetail „3‟, „22/7/2008‟, „4‟, „1‟, „10‟) 
4) Thực thi một Store Procedure 
Thủ tục lƣu trữ đƣợc gọi theo cấu trúc 
Tên_thủ_tục_lƣu _trữ [danh_sách_tham_số] 
Cần lƣu ý là danh sách tham số truyền vào trong lời gọi phải theo đúng thứ tự khai 
báo 
các tham số trong thủ tục lƣu trữ. 
Nếu thủ tục đƣợc gọi từ một thủ tục khác, thực hiện b ên trong một trigger hay phối 
hợp 
với câu lệnh SELECT, cấu trúc nhƣ sau; 
Exec Tên_thủ_tục_lƣu _trữ [danh_sách_tham_số] 
Ví dụ 4.66: Thực thi một procedure sp_InsertOrderAndOrderDetail bằng asp 
<% 
Dim customerid,orderdate, orderid, itemid, quantity 
 customerid = 4 
 orderdate = ―22/7/2008‖ 
 orderid = 4 
 itemid = 1 
 quantity = 10 
 sql = "EXEC sp_InsertOrderAndOrderDetail " &_ 
 " @ customerid =" & customerid & "," &_ 
 " @ orderdate ='" & orderdate & "'," &_ 
 " @ orderid ='" & orderid & "'," &_ 
 202 
 " @ itemid =" & itemid & "," &_ 
 " @ quantity =" & quantity 
 set conn = CreateObject("ADODB.Connection") 
 conn.open "" 
 conn.execute sql, , 129 
 Response.write("Record updated.") 
 conn.close 
 set conn = nothing 
%> 
 203 
Câu hỏi và Bài tập chƣơng 4 
1. Dùng câu lệnh Response.Write() để tạo ra giao diện nhƣ sau 
2. Dùng vòng lặp for để hiển thị các dòng tiêu đề nhƣ sau (hiển thị qua thẻ ) 
Header 1 
Header 2 
Header 3 
Header 4 
Header 5 
Header 6 
3. Viết chƣơng trình bằng asp hiện ra màn hình ngày hiện hành trong tuần bằng tiếng 
việt. 
4. Viết chƣơng trình in ra màn hình 10 dòng chữ Helloworld kích thƣớc tăng dần 
5. Tạo CSDL EShop trong SQL Server hoặc Access gồm các bảng sau: 
 -Tạo bảng catalogs 
-Tạo bảng products 
-Tạo bảng customers 
 204 
 6. Tạo trang kết nối tới CSDL (Connection.asp) cho phép kết nối đến cơ sở dữ liệu đã tạo 
trong câu 5 
7. Tạo trang hiển thị dữ liệu (DisplayCategories.asp) trang này hiển thị tất cửa các loại sản 
phẩm của cửa hàng, nó cho phép ngƣời sử dụng nhấn vào đó để xem các sản phẩm thuộc 
loại đó. 
8. Tạo trang hiển thị sản phẩm theo từng loại (productsByCateogry.asp) trang này hiển thị 
danh sách sản phẩm theo từng loại, Khi nhấn vào đƣờng link ở trang danh mục loại sản 
phẩm, thì trang này sẽ hiển thị ra. 
9. Tạo trang hiển thị thông tin sản phẩm chi tiết (productDetail.asp) trang này hiển thị 
thông tin chi tiết của từng sản phẩm khi bạn nhấn vào đƣờng link trang trƣớc. 
10. Tạo trang nhập thông tin sản phẩm (ProductNew.asp) cho phép nhập thông tin vào bảng 
sản phẩm. 
11. Tạo trang nhập dữ liệu (InsertCategories.asp) cho phép nhập vào một loại sản phẩm 
mới cho cửa hang. 
12. Tạo trang tìm kiếm thông tin về sản phẩm (FindProduct.asp) cho phép tìm kiếm thông 
tin về mặt hàng theo tên mặt hang. 
13. Tạo trang login (Signin.asp) trang này hiển form login để admin login. 
14. Tạo Trang xử lý thông tin login (LoginVerify.asp) trang này xử lý thông tin login, nếu hợp lệ thì 
sẽ chuyển hƣớng sang trang dành cho user, nếu không sẽ thông báo lỗi. 
15. Tạo trang nhập thông tin đăng ký của khách hàng (RegisterForm.asp) trang này dùng để hiển thị 
form đăng ký, nhập dữ liệu ở đây sau đó gọi tời file RegisterAction. 
16. Tạo Trang xử lý thông tin đăng ký (RegisterAction.asp) trang này dùng để đƣa thông 
tin đăng ký của khách hàng vào trong database. 
17. Tạo Trang dành cho khách hàng (UserInfo.asp) trang này dùng để hiển thị thông tin dành cho 
admin, nếu bạn chƣa đăng nhập thì sẽ chuyển hƣớng về trang đăng nhập. 
18. Tạo Trang Logout (Logout.asp) trang này dùng để logout, nó sẽ hủy bỏ session của 
khách hàng, hủy bỏ thông tin đăng nhập của khách hàng. 
 205 
TÀI LIỆU THAM KHẢO 
[1]. Nguyễn Đức Hải, Nguyễn Phƣơng Lan, Lê Hữu Đạt, ―Giáo trình lý thuyết và bài tập 
ASP‖, NXB Lao động - Xã hội 
[2]. Hoàng Mạnh Hùng, Giáo trình lập trình web, Đại học Đà Lạt 
[3]. Phạm Hữu Khang, Hoàng Đức Hải, Phƣơng Lan, ―Giáo trình lập trình web bằng ASP 
3.0‖, NXB Lao động - Xã hội 
[4]. Bùi Thu Giang, Lê Hoàng Nhân, Nguyễn Trƣờng Sinh, Việt Dũng, Thiết kế trang web 
với Microsoft FrontPage, NXB Lao động - Xã hội 
 [5]. Jerry Honeycutt, Special Edition Using HTML 4, Macmillan Computer Publishing 
[6]. WallPearl, Simple CSS Standard Edition, WallPearl‘sBlog, 2008 

File đính kèm:

  • pdfbai_giang_lap_trinh_mang_phan_2.pdf