Bài viết đăng trên Tạp Chí Lập Trình

Array có mặt trong hầu hết các ngôn ngữ lập trình, là một cấu trúc dữ liệu cho phép lưu trữ và truy xuất các phần tử ngẫu nhiên dựa trên vị trí. Trong Javascript, Array có gì khác?

Một lớp

Và do đó, chúng ta có thể tạo một đối tượng Array để lưu trữ các phần tử. Có 2 cách thường dùng để khởi tạo 1 đối tượng Array:

hoặc:

sẽ khởi tạo 1 đối tượng mảng arr chứa các phần tử “Bob”, “Jobs” và “Bill”.

No-type

Như bạn đã biết, trong Javascript, nói chung các biến không cần chỉ định rõ kiểu. Do đó, chúng ta có thể chứa những phần tử có kiểu khác nhau trong cùng 1 mảng như:

Điều này rất khác so với những ngôn ngữ như C++, Java… khi khai báo mảng với int arr[10]; sẽ giới hạn mảng arr chỉ chứa các số kiểu int.

Mutable

Điều gì xảy ra nếu chúng ta thực hiện đoạn mã sau?

Sẽ chẳng có lỗi OutOfRange nào như chúng ta mong đợi. Đơn giản vì Javascript tự điều chỉnh kích thước của mảng cho phù hợp, hay khả năng “co giãn”, còn gọi là mutable. Có lẽ Array mang hình ảnh của List?

Và..

Ngoài việc lưu trữ những phần tử có kiểu khác nhau, đối tượng Array còn cho phép dùng nhiều kiểu dữ liệu khác nhau làm “key”.

Hãy thử đoạn mã sau:

Đến đây chắc bạn cũng nhận ra, đối tượng Array không giống như mảng thông thường, chỉ cho phép truy xuất qua chỉ số là số nguyên, mà còn cho phép truy xuất qua chỉ số là một đối tượng bất kỳ. Thực ra, Javascript lưu trữ các đối tượng dưới dạng key-value-based, tức là mỗi đối tượng key (khoá) sẽ tương ứng (ánh xạ) với một đối tượng value (giá trị) theo cặp. Cấu trúc dữ liệu nào lưu trữ dưới dạng key-value-based? Có lẽ là Map.

Ngoài ra..

Hãy để ý các phương thức có sẵn của đối tượng Array, có lẽ bạn sẽ ấn tượng với 2 phương thức hay được sử dụng nhất: pop() và push().

Cấu trúc dữ liệu nào sở hữu những phương thức này? Stack và Queue. Vậy đối tuợng Array mang hình ảnh của Stack hay Queue? Cách kiểm chứng đơn giản nhất là dựa trên cơ chế của 2 kiểu cấu trúc dữ liệu này: Stack hoạt động theo phương thức LIFO (Last In First Out – Vào sau ra trước), Queue thì ngược lại LILO (Last In Last Out – Vào sau ra sau) (Có người thích gọi cơ chế hoạt động của Stack là: FILO và Queue là: FIFO). Hãy đưa một phần tử vào một Array đã có dữ liệu qua phương thức push(), tiếp đó, lấy phần tử trong Array qua phương thức pop(). Nếu hai phần tử này giống nhau, chắc chắn Array hoạt động theo phương thức LIFO tức là Stack, ngược lại Array hoạt động theo phương thức LILO hay Queue.

OK, hãy thử đoạn mã sau:

Chắc bạn đã có câu trả lời.

Tiếp theo…

Làm sao có thể biến cấu trúc dữ liệu của đối tượng Array từ Stack sang Queue và ngược lại? Hãy thử sức.

Gợi ý: Sử dụng phương thức reverse() cho phép đảo ngược các phần tử trong đối tượng Array hoặc phương thức shift() cho phép lấy ra khỏi mảng phần tử đứng đầu.

Lời kết

Giờ đây chắc bạn đã thấy sức mạnh của đối tượng Array trong Javascript, nó có thể biến đổi uyển chuyển giữa những cấu trúc dữ liệu phức tạp khác nhau như List, Map, Stack hay Queue.

Một thông tin đáng mừng là Javascript chỉ là một đại diện cho một lớp những scripting language (ngôn ngữ kịch bản, như PHP, Python…), trong đó đối tượng Array được sử dụng như cấu trúc dữ liệu chính và thể hiện rất nhiều hình ảnh khác nhau như trong Javascript.

Hãy tiếp tục tìm hiểu xem Array có thể mô tả cấu trúc dữ liệu nào khác và cùng update vào bài viết.

125 total views, no views today

Bài viết đã đăng trên Tạp Chí Lập Trình

Thế nào là lập trình an toàn?

Có lẽ nên bắt đầu với khái niệm một hệ thống “an toàn” hay “bảo mật” (security). Một hệ thống được coi là “an toàn” khi nó đảm bảo được ba yếu tố chính (thường được gọi là tam giác CIA) bao gồm: Confidentiality (tuyệt mật), Integrity (toàn vẹn) và Availability (sẵn sàng). Để hệ thống an toàn đòi hỏi rất nhiều công sức trong tất cả giai đoạn phát triển phần mềm, trong phạm vi bài viết này tôi chỉ đề cập đến khái niệm an toàn trong giai đoạn lập trình.

Tôi chỉ cố gắng đưa ra một số sai lầm thường gặp nhất trong việc lập trình gây ảnh hưởng tới tính an toàn của hệ thống, đây cũng là những chỉ dẫn đơn giản giúp bạn hiểu về một công việc cần làm để có “good code”.

HTTP method

Form là công cụ hay dùng nhất để client gửi dữ liệu tới server thông qua một trong hai phương thức: GET hoặc POST. Điểm khác nhau cơ bản là GET gửi dữ liệu qua URL, POST thì không.

Điều gì xảy ra nếu chúng ta dùng GET? Một người đứng phía sau có thể nhìn thấy thông tin tài khoản của người dùng khi họ login như:

Vậy tại sao chúng ta vẫn dùng GET? Vì tiện. Các lập trình viên thường có xu hướng dùng GET khi lập trình để tiện thay đổi thông tin cho việc test, nhằm tăng năng suất. Vấn đề là họ thường quên điều chỉnh khi release sản phẩm.

Giải pháp: Luôn sử dụng POST với những thông tin nhạy cảm, và hãy luôn nhớ kiểm tra phương thức HTTP trong các form trước khi đóng gói sản phẩm.

Vi phạm: Tính tuyệt mật

SQL injection

Đây là lỗi kinh điển nhưng có lẽ bạn đã và  vẫn đang mắc phải. Giả sử, hệ thống cho phép đăng nhập qua usernamepassword, tôi nghĩ đây là cách bạn đang làm:

  • Nhận dữ liệu và lưu vào 2 biến, giả sử usr và pwd
  • Tạo câu lệnh

(với tableusernamepassword là bảng và các trường trong DB)

  • Thực thi câu lệnh, nếu (giả sử) ResultSet trả về có nhiều hơn 0 bản ghi, người dùng được coi là nhập đúng thông tin và đăng nhập thành công.

OK? Điều gì xảy ra nếu người dùng nhập:

  • usr: admin
  • pwd: ’ OR ‘1’ = ‘1

Khi đó, câu lệnh SQL trở thành:

Và thường thì sẽ có nhiều hơn 0 bản ghi (chính xác là toàn bộ bản ghi trong bảng table) được trả về, người dùng đăng nhập thành công.

Và khi pwd là: ’ OR ‘1’ = ‘1’; UPDATE users SET password = ‘123’ WHERE username = ‘admin’;

Câu lệnh SQL trở thành:

Hai câu lệnh SQL được thực thi và password của tài khoản admin được đặt lại thành ‘123’.

Lỗi này đặc biệt nghiêm trọng trong những hệ thống mã nguồn mở hoặc trên các diễn đàn, vì tên đăng nhập của người dùng và cấu trúc DB thường được biết trước.

Giải pháp: Chắc bạn cũng thấy, SQL injection lợi dụng những ký tự đặc biệt ‘ trong chuỗi giá trị nhập vào nên giải pháp đơn giản là hãy luôn loại bỏ chúng trước khi chuyển thành câu lệnh SQL. Do đây là một lỗi phổ biến nên hầu hết ngôn ngữ hiện đại đều cung cấp khả năng xử lý. Trong Java, khi làm việc với JDBC, thay vì dùng Statement, hãy sử dụng PreparedStatement hoặc CallableStatement. (http://docs.oracle.com/javase/6/docs/api/java/sql/PreparedStatement.html)

Tham khảo thêm tại: http://www.unixwiz.net/techtips/sql-injection.html

Vi phạm: Tính tuyệt mật, toàn vẹn

Exception

Ai cũng biết, và có lẽ dù có nhắc đến lỗi này cả triệu lần nữa thì chúng ta vẫn có thể mắc phải. Đơn giản vì chúng ta thường lập trình rất nhanh để sớm đưa ra sản phẩm và hay bỏ qua việc tung (throw) và bắt (catch) exception.

Chúng ta xây dựng một chương trình bảng tính tuyệt vời với rất nhiều chức năng và khi người dùng nhập phép toán 1/0, toàn bộ chương trình ngừng hoạt động; tất cả dữ liệu trước đó bị mất do không bắt exception. Các IDE ngày nay rất thông minh, nếu chúng ta viết câu lệnh a = 1/0; Netbeans chắc chắn sẽ bắt chúng ta phải catch exception. Vì vậy, các lập trình viên thường khá chủ quan. Nhưng IDE sẽ bất lực nếu chúng ta viết a = b / c; với c = 0. Đôi khi cả hệ thống sụp đổ chỉ do 1 sự bất cẩn nhỏ trong lập trình. Điều này còn nguy hại hơn nếu bạn xây dựng 1 ứng dụng web server, khi hàng ngàn request có thể không được xử lý chỉ do lỗi của 1 request. Ứng dụng như vậy không được coi là có khả năng chịu lỗi (failure tolerant), ảnh hưởng tới tính sẵn sàng. Nguy hiểm hơn, một số người có thể đọc được lỗi và khai thác lỗ hổng (vulnerability) của hệ thống.

Giải pháp: Hãy luôn bắt exception với bất kỳ thao tác nào có khả năng xảy ra lỗi như: Các phép toán (chia 0, tràn số (c = a * b với a, b có kiểu int có thể vượt ngoài khoảng kiểu int của c là sai), phép trừ ra số âm…), đọc hay ghi dữ liệu vào file (file có thể không tồn tại, không có quyền đọc/ghi), truyền dữ liệu qua mạng (không có kết nối…), sử dụng object chưa được khởi tạo (null pointer exception – lỗi rất phổ biến)…

Đồng thời, hãy luôn tung exception trong các phương thức có khả năng gây lỗi do mình tự viết.

Hãy nhớ rằng, chúng ta không đủ thời gian để kiểm thử (test) tất cả trường hợp và thường chọn trường hợp “rất đẹp” trên những bộ dữ liệu “rất đẹp” khi chào hàng phần mềm. Thực tế, người dùng lại luôn “ngớ ngẩn” và luôn gây lỗi, đừng để một hệ thống hoành tráng bị sụp đổ bởi sự vô trách nhiệm nhỏ.

Vi phạm: Tính tuyệt mật, tính toàn vẹn, tính sẵn sàng.

Duyệt file

Một ứng dụng có thiết kế tốt cũng có thể hay mắc phải lỗi này. Chúng ta tạo ra một template và hiển thị nội dung file theo ngữ cảnh người dùng. Ví dụ, khi người dùng vào trang đăng nhập, bạn sẽ sử dụng URL: http://myweb.com?view=login.html, nhận biết trang cần hiển thị qua parameter view, đọc file login.html và trả về client. Điều gì xảy ra nếu người dùng nhập URL: http://myweb.com?view=../../data/document.doc? Nếu không được phân quyền tốt, có thể bạn sẽ trả về file document.doc nằm trong thư mục data trên ổ cứng.

Giải pháp: Phân quyền cho thư mục và thực hiện rewrite URL là cách tốt nhất, song việc này thường được thực hiện tại bước triển khai. Và nếu bạn không chắc việc triển khai chính xác, hãy luôn kiểm tra tính hợp lệ của các file được trả về.

Vi phạm: Tính tuyệt mật, tính toàn vẹn, tính sẵn sàng.

Và?

Đến đây, có thể bạn đã nhận thấy ba yếu tố trong tam giác CIA nói chung không thể cùng đạt điểm tối đa. Đơn giản vì từng yếu tố này vốn tự mâu thuẫn lẫn nhau. Ví dụ, để tăng cường tính tuyệt mật, hệ thống ngân hàng yêu cầu chúng ta nhập mật mã (được gửi qua SMS) mỗi khi chuyển tiền; gây ảnh hưởng tới tính sẵn sàng của hệ thống do những người quên điện thoại sẽ không thực hiện được giao dịch. Vậy đâu là mức phù hợp cho từng tiêu chí của hệ thống?

Trên đây chỉ là một số rất nhỏ những sai lầm có thể gặp phải trong việc lập trình gây ảnh hưởng tới tính an toàn của hệ thống. Bạn có thể tìm hiểu thêm về những sai lầm thường gặp khác, hoặc tôi sẽ đề cập tiếp nội dung này trong một lần thích hợp.

175 total views, no views today

Là sáng dậy sớm, tập thể dục, chuẩn bị bài và đi dạy.

Là chiều ngồi tập trung làm việc mình thích, không quên dành 30ph cho công việc nhà cửa, điện nước, bát đũa, rau cỏ.

Là khi chiều nhạt nắng thì thơ thẩn ngồi ven hồ cafe và đọc sách.

Là khi tắt nắng thì xách giầy ra sân cùng anh em.

Là giờ viết những dòng bâng quơ này trước khi đeo headphone và lên giường lim dim, chờ đợi…

… Ngày hoàn hảo tiếp theo…

114 total views, no views today

Như vậy là OLP’10 đã khép lại, tự nhiên muốn viết chút xíu, gọi là review:

Cảm nhận đầu tiên về công tác tổ chức là hơi… thất vọng. Đã tham gia 3 kỳ OLP với tư cách thí sinh nhưng theo cảm nhận cá nhân, chưa năm nào công tác tổ chức OLP tệ đến vậy.

Bước chân vào ĐHQG, dù băng-rôn được treo rộn ràng nhưng… vắng bóng tình nguyện viên. Chỉ thấy từng tốp từng tốp sinh viên mặc áo VNPT đứng đùa giỡn với nhau làm mình tưởng đó là sinh viên các trường đã được phát áo rồi mang ra mặc chơi – thật là nực cười. Hậu quả là các trường không hiểu phải đăng ký ở đâu, trình tự ra sao. Khu vực đăng ký được chia làm 2 bàn, 1 để đăng ký, 1 để nộp lệ phí thi; cô em xinh đẹp luôn chuyển danh sách các đội đăng ký xuống cuối, và chi thu ngân cũng lấy từ cuối lên. Nên thật trớ trêu, các đội đến sớm cứ đứng chờ mãi mà không được giải quyết. Thôi thì như một thầy trưởng đoàn nói: “Yên tâm, tập các đội là hữu hạn mà, kiểu gì cũng tới lượt”.

Tất cả các hoạt động của OLP luôn luôn chậm so với lịch, ít nhất là 30 phút, có khi là hơn 1 giờ. Lễ khai mạc, chậm. Lễ bế mạc, chậm. Các buổi thi, chậm. Điển hình là buổi test máy ACM, chậm tới hơn 1 giờ. Buổi thi chính thức cũng chậm hơn 1 giờ. Chỉ thương cho những sinh viên miền Nam không chịu nổi cái lạnh Hà Nội mà cứ phải co ro ngồi chờ, hết cả nhuệ khí thi cử. Trong khi đó, các tình nguyện viên tung tăng cầm bóng đến phòng thi vừa đi vừa chụp hình. Có tới 16 đội nước ngoài và hơn 100 đội Việt Nam đang nhìn vào những hành động đó, thật lố bịch.

Nhớ năm đầu tiên ĐH Công nghệ tổ chức, tất cả các thí sinh cảm thấy thật dễ chịu. Từng team bước qua cổng lớn vào sân thi đấu khi tiếng gọi qua loa cất lên thật trang trọng. Năm nay, thí sinh đứng ở… đường để chờ, một mình bác Long “cò” gân cổ gào tên từng team vào phòng.

Lễ bế mạc và trao giải được coi là tổ chức úi xùi và nhạt nhẽo chưa từng có, có vẻ như chỉ là một công việc cho hết nhiệm vụ tổ chức. Vẫn sử dụng cặp MC của lễ khai mạc khi nam MC thậm chí không thể đọc một câu tiếng Anh tử tế – dù sao anh cũng có thể tự hào là tiếng Anh tốt hơn bác Long “cò”. Năm 2005, ĐH Bách Khoa tổ chức trao giải ở Văn Miếu. Năm 2006, ĐH Công nghệ tổ chức một lễ tra giải hoành tráng tôn vinh Nhà vô địch ACM với nhạc và pháo hoa cùng sự trịnh trọng đến chuyên nghiệp. Năm 2007, ĐH Đà Nẵng trao giải trong bữa tiệc bế mạc, tuy vui vẻ nhưng rất trịnh trọng. Năm nay, giải thưởng cao quý nhất: Cúp vàng siêu cúp – được trao cùng chiếc cúp màu…đồng. Không có cúp bạc và cúp đồng nào được trao dù chúng đã có chủ. Cúp vàng được trao nhanh đến nỗi khó có ai trong khán phòng phân biệt được sự khác biệt của nó với những giải còn lại.

Sau lễ bế mạc là tiệc bế mạc tại nhà ăn sinh viên ĐH Ngoại ngữ, hơn 700 con người được ấn định trong nhà ăn có sức chứa chưa tới 200 chỗ. Bác Long “cò” không còn cách nào khác, rút tiền đưa cho các đội để đi ăn ngoài. Ừ, đưa thì ta nhận. Dẫu sao cũng là ban tổ chức làm không hết trách nhiệm.

Năm 2005, ĐH Công nghệ lần đầu tiên tổ chức ACM đã gây được cảm tình lớn, là bằng chứng để ACM ở lại Việt Nam, là nơi khao khát của sinh viên IT. 5 năm sau, mọi chuyện đã khác.

Bỏ qua sự yếu kém trong khâu tổ chức, OLP’10 là sự thành công vượt trội của ĐH FPT. Nhân đây cũng điểm qua một số “anh tài” và thành tích ấn tượng của ĐH FPT tại OLP’10.

Nhân vật xuất sắc nhất tại OLP’10: Trần Hải Đăng – Cúp vàng Siêu cúp. Với đam mê, khát khao và những nỗ lực không mệt mỏi, Cúp vàng Siêu cúp là phần thưởng xứng đáng dành cho Đăng.

Hồ Vĩnh Thịnh – giải ba Siêu cúp – một tài năng trẻ, hứa hẹn còn nhiều thành công.

Lê Anh Quân – giải nhì Chuyên Tin. Bước vào trường ĐH mà không biết chút gì về tin học, giờ đây em được liệt kê vào dạng “hàng khủng” với những cố gắng liên tục. Khi mới tiếp nhận đội vào tháng 7, thầy đánh giá em còn rất…tầm thường nhưng Quân đã chứng tỏ được sự tiến bộ qua từng tuần thi. Và giờ, rất nhiều người phải nhìn em với con mắt ngưỡng mộ.

Các đội tuyển ACM đã có những thành tích chưa từng có. Bất chấp việc ACM năm nay có quá nhiều các đội mạnh tới từ nước ngoài và việc ra để thi chưa thực sự hợp lý*, 3/6 đội giành giải 3 khu vực. 2/6 đội trong top 5, 3/6 đội trong top 10, 4/6 đội trong top 20 Việt Nam.

uP (Trần Hải Đăng, Lê Thanh Quảng, Phạm Lê Quang – Solved: 8/11): Một chút nuối tiếc vì chưa giành chiến thắng trên sân nhà. Giấc mơ World Final được đặt cược tại Malaysia. Chúc các em thành công!

Turtle’s Coder (Lê Anh Quân, Nguyễn Thành Trung, Hồ Vĩnh Thịnh- Solved: 8/11): Ừ, đặt tên vậy là vì đội code chậm. Chậm là vì lúc đó Trung và Thịnh không hề biết C hay C++. Dù đã mất gần như toàn bộ thời gian cho chuyến học GDQP tại Xuân Hòa, song các em đã nỗ lực, các em đã xứng đáng. Accept 2 bài trong 1 giờ cuối cùng, không còn chậm nữa rồi. Lại mang rùa sang Malaysia và chúng ta lại “nói chuyện” tiếp. Hai gương mặt này rồi sẽ là chủ lực của FPT trong những năm tới.

GUEST (Đặng Trần Tiền Vinh, Lê Nam Phương, Nguyễn Phan Quang Nhật- Solved: 7/11): Chưa có đội nào chỉ có 1 người code mà đứng cao như vậy. Thì ra Vinh có HC Toán Quốc tế. Đề thi này chưa hợp với tụi em. Đề khó hơn thì các đội khác phải dè chừng.

Và giờ, hãy viết tiếp giấc mơ World Final tại Malaysia. Chúc các em thành công!

Bonus thêm 1 giải 3 Mã nguồn mở cho nó đủ mọi hạng mục vậy.

Thay cho lời kết, xin lấy 2 câu trong bản báo cáo OLP’10:

Trường ĐH Tư thục đầu tiên đạt Cúp Vàng Siêu cúp

OLP’10 chứng kiến sự lên ngôi của ĐH FPT

Theo đánh giá cá nhân: Đề thi năm nay không thực sự tốt và tự gây khó cho các đội Việt Nam. Đề thi gồm quá nhiều bài ở dạng cơ bản một cách lộ liễu khiến các đội phải lao vào cuộc đấu về thời gian. Code nhanh và nhiều chưa bao giờ là thế mạnh của các đội VN so với các đội nước ngoài. ĐH Công nghệ nhanh chóng đưa 2 đội dẫn đầu sau 30ph đầu tiên, nhưng không đủ sức chạy một quãng được dài. Thành ra cuộc đấu đã ngã ngũ ngay sau 1/2 thời gian khi ArcOfDream đã sớm giải được 10/11 bài, NTU cũng có 9/11 bài sau thời gian thấp đến kinh ngạc 490 phút.

Note được viết sau OLP & ACM 2010, được copy qua GURUnH. 4 năm sau ĐH FPT đã giành vé dự World Final với đội tuyển Runs of Champion với các thành viên đã tham gia và toả sáng ngay từ 2010 – năm đầu tham dự, gồm Lăng Trung Hiếu, Nguyễn Thành Trung, Hồ Vĩnh Thịnh.

218 total views, no views today