[Ký sự NCSC] Giai đoạn 1: 300 Bài Code Thiếu Nhi

woman programming on a notebook

🐔 “Ký sự NCSC” là chuyên mục bài viết về thời gian mình thực tập tại Trung tâm Giám sát An toàn Không gian mạng Quốc gia (National Cyber Security Center), thuộc Cục An toàn Thông tin, Bộ Thông tin và Truyền thông. Nghe tên Trung tâm thì khủng thế thôi, còn mình thì… gà, đến để “cục tác lá chanh”, học từ những bài học đơn giản nhất.

Trong chuyên mục này, mình sẽ chia sẻ những nhiệm vụ và bài tập mình đã trải qua, cũng như một vài kỷ niệm vui vẻ hay ho trong thời gian ở Trung tâm.

Ở NCSC, lộ trình cho thực tập sinh đã được xây dựng từ trước. Tuỳ vào trình độ và nguyện vọng của bạn, anh chị sẽ xem xét để đưa bạn vào một lộ trình phù hợp.

Tôi là kẻ ngoại đạo, “đá ngang” sang An toàn thông tin trong một giây phút hí hửng của tuổi trẻ, nên tôi vào lộ trình cơ bản nhất. Cũng tốt. Người mới đều bắt đầu từ đây: Tìm hiểu lỗ hổng web cơ bản.

Làm cả vlog cơ mà :> Zô ủng hộ tui nhé các bạn yêu…

Ấy, nhưng đừng vội thế. Chưa nhúng tay vào hack ai được đâu. Nhiệm vụ đầu tiên của tôi trong lộ trình là lên HackerRank. Và cày Python.

Trong bài Sinh viên IT sợ code, tôi từng nói mình ngán code lắm. Có một điều tôi quên không viết, ấy là tôi ngán CP (Competitive Programming, tức Lập trình thi đấu), chứ lập trình thủ tục, scripting, hướng đối tượng các thứ thì tôi chẳng sợ. Cứ túc tắc viết rồi cũng xong bài thôi.

Bí thì hỏi anh bạn phi công (aka. GitHub Copilot), hoặc nếu bạn có thể chịu được sự muối mặt bị chê “gà” sau khi hỏi bất cứ câu gì (thứ vốn là đặc sản của NCSC) thì bạn cứ hỏi mọi người.

Dài dòng thế, túm lại là, bài này tôi viết vài tips – để lỡ bạn có cùng chung lối, con đường của bạn sẽ dễ dàng hơn tôi một chút.

Python 3 và Python 2: Vì sao sẽ chẳng bao giờ có Python 4

Nếu bạn đã có một hệ thống trong Python 2, bạn sẽ hiểu sâu sắc hai chữ “thảm hoạ” khi nói đến việc chuyển đổi sang Python 3. Điều đó đơn giản là bất khả.

Những khác biệt rắc rối… Nguồn: Geeks for Geeks

Cũng vì lý do rắc rối trên, người sáng tạo nên ngôn ngữ con rắn – Guido van Rossum – đã thề non hẹn biển rằng khả năng cao sẽ chẳng bao giờ có Python 4. Xin cảm ơn ông – vì một bi kịch không ngày tái diễn.

HackerRank có mấy lựa chọn phiên bản ngôn ngữ khi bạn code Python, và tôi khuyên là bạn đã chọn cái gì thì cứ gắn với nó xuyên suốt. Tôi khuyến khích bạn chọn Python 3, nếu như bạn chưa từng viết Python 2 quá nhiều. Nó phổ biến nhất hiện nay và… dễ đọc hơn Python 2 nhiều.

Pypy3 là một cài đặt thay thế cho Python 3. Thay vì dùng trình thông dịch (Interpreter) như Python 3 thì nó dùng trình biên dịch JIT (Just-in-Time Compiler), nên về cơ bản sẽ cho tốc độ nhanh hơn.

Có một số bài cho dù bạn viết code Python 3 đúng, nhưng sẽ luôn bị lỗi, phải chuyển sang Pypy3 mới cho kết quả đúng. Đây là do sự khác biệt của phiên bản ngôn ngữ, cơ chế của các hàm khác nhau khiến kết quả trả về khác nhau. Nhưng hi hữu thôi – trong hơn 100 bài tôi cày thì chỉ xuất hiện đâu đó 1-2 bài.

Có hàm built-in cho điều đó không?

Người ta bảo học Python sang học C/C++ thì “cho-ke” (read: choke, nghĩa là chết sặc), mà đã học C/C++ thì học mấy ngôn ngữ bậc cao dễ lắm. Tôi thì vẫn thấy mình sặc sụa chết đuối cho dù là chuyển đổi từ cái gì sang cái gì đó khác, theo bất cứ chiều nào.

Nói thế thôi chứ cái learning curve cũng không to lắm. Vài ngày có lẽ là đủ để bạn quen, nếu bạn đã lập trình những ngôn ngữ bậc thấp hơn đủ nhiều.

Một cái khi sang Python tôi cứ phải dặn chính mình, ấy là Đừng tìm cách sáng chế lại cái bánh xe*. Trong khi ở các ngôn ngữ như C/C++, một vài logic ta cần phải tự viết hàm rồi dùng, thì ở Python, thường là sẽ có hàm làm luôn điều đó cho bạn. Nếu không có ở thư viện chuẩn thì thường nó sẽ ở một cái module nào đó, bạn chỉ cần tìm và import vào thôi.

Bộ tứ siêu đẳng: Dictionary, List, Set, Tuple

Điều làm tôi cảm thấy hay ho nhưng cũng khiến tôi ngáo ngơ khi dùng Python, ấy là những container đa mục đích của ngôn ngữ này. Một lần nữa, thay vì phải code lại cả cấu trúc dữ liệu, bạn chỉ cần dùng sẵn. Hooray!

Trước mắt thì bạn chỉ cần làm quen với 4 cái:

  1. Dictionary
  2. List
  3. Set
  4. Tuple
Sự khác biệt cơ bản của 4 anh bạn này. Nhưng hiện tại bạn cũng chưa cần quá quan tâm về nó đâu… Nguồn: Python in Plain English

Trên mạng đã nhiều tài liệu viết về những thứ này, bạn chỉ cần Google là ra. Tôi không viết lại nữa, vì mục tiêu chính là giúp bạn tự học chứ không phải dạy bạn Python. Vả lại tôi cũng vẫn còn gà…

Một tác vụ bạn sẽ làm khá nhiều khi làm bài là chuyển đổi giữa các container khác nhau để xử lý dữ liệu đầu vào và đầu ra cho hợp lý. Sự chuyển đổi này cũng cần thiết khi bạn cần dùng đến hàm dành riêng cho container đó.

RegEx là cái khỉ gì thế?

Lần đầu nhìn thấy Regex, tôi đã hoảng sợ.

Và sau đó tôi tìm kiếm niềm vui trong khuôn mặt của những người bạn giống tôi khi ấy.

Tôi định gìn giữ thú vui ấy lâu hơn, nhưng cuối cùng thì vẫn viết về nó. Nếu bạn đọc bài này thì tôi sẽ chờ đợi để loè bạn trong một dịp khác.

Regex là viết tắt của Regular Expression, tên thuần Việt là biểu thức chính quy. Nó là các mẫu (pattern) được sử dụng như một công cụ cực mạnh cho xử lí chuỗi.

Bạn hiểu đơn giản là Regex là một biểu thức chứa quy luật định nghĩa những chuỗi hợp lệ tương ứng.

Ví dụ với Regex sau đây:

Cái này không giải thích dễ hiểu thì dễ bị ngáo lắm. Tôi kiếm mãi mới được cái ảnh ưng ý đấy. Nguồn: Tobi Sam, Towards Data Science

Thì các chuỗi hợp lệ là những địa chỉ email hợp lệ. Biểu thức chính quy là thứ biểu diễn những quy luật chung mà những địa chỉ email đó thoả mãn.

Trong lĩnh vực An toàn thông tin, tôi thấy Regex được sử dụng khá nhiều, nhất là trong trường hợp bạn đang cần tìm giữa cả núi dữ liệu một thông tin cụ thể nào đó. (Tìm nhanh, trước khi hệ thống phát hiện ra bạn là kẻ đột nhập!) Mặt khác, kiểu gì thì kiểu, hễ cứ đụng đến xâu ký tự thì sớm muộn gì bạn cũng phải học Regex thôi.

Mấy điều nhắn nhủ của tôi:

  • Có nhiều cách để biểu diễn một quy luật. Hãy viết Regex đơn giản sáng sủa nhất có thể.
  • Mặc dù Regex mạnh, không có nghĩa là ta lạm dụng nó. Việc sử dụng quá nhiều Regex có thể khiến chương trình của bạn khó đọc.
  • Muốn check Regex đúng sai? Có rất nhiều trang web làm điều đó cho bạn. Tìm “Regex checker” là ra.

Đầu vào, đầu ra

Thú thực với bạn cái làm tôi mất thời gian nhất ở giai đoạn này là việc Google đi Google lại: “how to read input in Python”.

Vì sao? Vì các biến trong Python là “loosely (weakly) typed”, nghĩa là ngôn ngữ sẽ tự hiểu kiểu dữ liệu của biến thông qua giá trị nó được gán, chứ bạn không cần phải định nghĩa kiểu từ đầu. Kiểu của biến không được biết ở thời điểm biên dịch (compile-time) mà được xác định sau đó ở thời điểm chạy chương trình (run-time). Điều này cho phép sự linh hoạt, song cũng khiến cho những lỗi bị phát hiện muộn màng hơn.

Bên cạnh Python, đa phần các ngôn ngữ scripting đều định kiểu lỏng lẻo, như Perl, Ruby, PHP hay JavaScript. Nguồn: Daniel Fintinariu, Level Up Coding

Cũng vì thế mà lắm lúc tôi chẳng biết cái được đọc vào là dữ liệu kiểu gì. Sai bung bét cả. Lại phải in kiểu của biến hiện tại ra để biết nó có đúng cái tôi hiểu hay không.

Riêng cái này tôi nghĩ chỉ có làm nhiều thành quen, chứ cũng chẳng có cách nào khác.

Có những bài bạn phải đọc dữ liệu đầu vào theo cách rất phức tạp:

arr = np.array([list(map(int, input().split())) for _ in range(N)])

Trông nó kinh dị thế thôi, bạn hoàn toàn có thể khiến em nó trở nên dễ nhìn hơn bằng cách đặt các biến trung gian, rồi lại đưa biến đó vào ép kiểu tiếp.

Kết: Python Exam

Bài kiểm tra đầu tiên và (có lẽ là) cuối cùng ở NCSC cho thực tập sinh, chính là bài kiểm tra ở giai đoạn đầu tiên này.

Bài thi cũng kiểu easy-game, được tra Internet thoả thích thì tội gì mà không làm được.

Bạn có thể tham khảo bài làm của tôi ở đây.

Anh chị ở đây có thú vui “sấy” những người đàn em, nên bạn cứ chuẩn bị tinh thần code cho chuẩn chỉnh để không bị vặn vẹo thêm bất cứ thứ gì (hoặc bị sấy ít nhất có thể). Tự tôi đánh giá tôi code sạch, handle exception và edge case cũng ổn (hehe)! Vậy là qua giai đoạn 1.

Hẹn bạn trong bài viết tiếp theo ở Giai đoạn 2 nhé. Task tới khó hơn nhiều, nên tôi sẽ viết thành nhiều bài mới hết được, hic.


* Don’t Reinvent The Wheel (thành ngữ.): Lời khuyên không cần thiết phải nỗ lực, hao tổn thời gian và công sức xây dựng lại từ đầu một thứ đã có sẵn.

In