• No products in the cart.
Back to Top

FCT Club

Bàn về bộ môn Lập Trình Thi Đấu và các bộ môn học thuật khác nói chung

Tác giả: Nguyễn Gia Bách, học viên khóa 2021-2024

Lời nói đầu

          Xin chào tất cả các bạn cùng thầy cô,

          Mình là Bách, học viên khóa 2 của CLB. Ở thời điểm mình viết bài sharing này, một năm cũng đã sắp trôi qua. Nghĩ về những gì bản thân đã đạt được trong năm rồi, với mình, đã có những nuối tiếc, một chút thành công, rất nhiều mối quan hệ và không ít những bước ngoặt của cuộc đời. Theo dõi các thành viên của câu lạc bộ trong suốt một năm qua, mình nhận thấy bạn nào cũng đều là những con người vô cùng tài năng cả và rất đáng ngưỡng mộ. Là một câu lạc bộ được thành lập để tìm kiếm và bồi dưỡng những bạn có thiên hướng CNTT, chắc chắn là những bạn ở đây ai cũng đều có thành tích nào đó liên quan đến chuyên ngành rồi. Ngành công nghệ thông tin thì ai cũng biết là vô cùng rộng lớn, và một đời người thì không thể nào học hết được. Tuy nhiên trong khuôn khổ của môi trường sư phạm thì mình tạm chia CNTT thành hai mảng chính như sau: học nghề và học thuật. Học nghề theo mình là học những kiến thức liên quan trực tiếp tới việc đi làm sau này, có thể bao gồm các kĩ năng làm việc nhóm hay kiến thức về các công nghệ. Còn học thuật lại thiên về giải quyết các bài toán hơn, những vấn đề hóc búa và đôi khi trừu tượng hơn học nghề. Mình biết được cả hai mảng trên trong CLB đều có rất nhiều bạn giỏi, phần đông đều có hiểu biết tốt về các công nghệ ngày nay, phần học thuật thì CLB cũng có một phần không nhỏ các học viên hiện đang theo đuổi.

          Là một người theo đuổi bộ môn lập trình thi đấu – một nhánh của lĩnh vực học thuật trong CNTT, mình cũng có rất nhiều cảm xúc mãnh liệt mỗi khi giải một bài toán nào đấy. Sở dĩ nó mãnh liệt là vì mỗi khi ấy, vui có, buồn có, gay cấn, giật gân đều có, và mình nghĩ hiếm có nghề nào trong cuộc sống đem lại được niềm vui như vậy. Tuy nhiên, đôi khi mình cũng tự hỏi bản thân rằng, liệu lập trình thi đấu đã là đủ cho cuộc sống sau này hay chưa? Rộng ra hơn, ở các bộ môn học thuật khác, như Toán Văn Lý… việc đạt giải cao trong các kì thi Olympiad, hay chỉ đơn giản là hiểu biết rộng, có đem lại lợi thế cao cho chúng ta khi sau này đi làm hay không? Hoặc có lẽ lỗi suy nghĩ thực dụng này đang có lỗ hổng nào đó, và để tìm hiểu sâu hơn về vấn đề này, mình xin chia sẻ những gì mình đã tìm hiểu được thông qua bài sharing ngày hôm nay.

          Mời các bạn và các thầy cô cùng “lướt xuống” nhé!

Lập trình thi đấu là gì?

          Lập trình là sẽ có code, điều đó là đúng nhưng không hẳn là hoàn toàn. Vì khi nói “Lập trình là code”, nhiều người có thể sẽ hiểu nhầm và dường như bỏ qua sự phức tạp của lập trình. Lấy ví dụ đơn giản, bạn được giao để làm một chương trình con cho một công ty, ta không bàn đến thù lao ra sao. Nhiệm vụ đó bất kể có dễ hay khó, bạn đều phải code rất cẩn thận và rõ ràng, vì những dòng mã đó người đọc đâu phải chỉ có mỗi bạn, mà còn cả một đội ngũ nữa. Code không khó, một người mới học vài giờ cũng có thể code được, nhưng để viết ra được một chương trình rõ ràng mạch lạc, tự biết gỡ lỗi và rối cho code, đó mới là phần khó của lập trình.

          Nhưng nếu ta bỏ qua vấn đề code chuẩn đó sang một bên, thì lập trình còn khó cả bởi giải thuật và độ tối ưu của chương trình. Một chương trình chạy càng chậm thì càng ngốn tài nguyên của hệ thống, làm giảm doanh thu đáng có của doanh nghiệp. Đây chính là lí do ngành Khoa học máy tính (Computer Science) xuất hiện. Thông thường, nếu ta cứ theo yêu cầu mà viết ra một chương trình “bảo gì làm nấy”, đó được gọi là một chương trình naïve (ngây thơ) hoặc bruteforce (trâu bò). Những chương trình như vậy thường xoay quanh giải pháp cơ bản là thử mọi khả năng xảy ra, xử lí các thao tác một cách tuần tự, hoặc đôi khi là sử dụng tài nguyên không tối ưu. Ngành khoa học máy tính xem xét các vấn đề liên quan đến tính toán của máy tính một cách nghiêm túc, tìm ra các tính chất, các quy luật để khai thác và tối ưu hóa chương trình. Các tính chất hay quy luật đó lại đòi hỏi kiến thức toán học để tính toán và rút ra nhận xét. Bởi vậy, ngành Công nghệ thông tin từ thuở sơ khai đến giờ đã và sẽ luôn có một mối quan hệ chặt chẽ, mật thiết với Toán học. Thậm chí, gọi môn Tin là một nhánh của Toán học cũng không hoàn toàn là sai, vì trong môn toán cũng có một phần gợi “Toán rời rạc” liên quan đến xử lí các cấu trúc dữ liệu và giải thuật mà ta vẫn hay gặp ở môn Tin.

          Khi ngành khoa học máy tính phát triển dựa theo nhu cầu cần tối ưu các chương trình của con người, việc giáo dục lớp trẻ ngay trong môi trường sư phạm về lĩnh vực này theo đó cũng được quan tâm. Ở bậc tiểu học và trung học cơ sở, chắc hẳn các bạn cũng đã từng học về các phần mềm tin học văn phòng. Nhưng khi lên đến cấp ba, và đại học, giáo trình của chúng ta bắt đầu có những nội dung về giải thuật và lập trình. Và dần dần, ở môi trường sư phạm của chúng ta đã xuất hiện một bộ môn mới, gọi là Lập trình thi đấu.

          Đầu tiên là về khái niệm, Lập Trình Thi Đấu (LTTĐ) trong tiếng Anh là Competitive Programming (CP), hoặc các bạn cũng có thể gọi nó đơn giản là môn Tin Học. Trái với Tin học truyền thống thường nặng về lí thuyết, CP khai thác rất sâu vào vấn đề xử lí các bài toán đòi hỏi nhiều tư duy. Ở trong CP, các bạn sẽ không gặp những câu hỏi về lịch sử của ngôn ngữ lập trình, hay được hỏi cách để sửa máy tính, mà đó sẽ là những bài toán về một vấn đề cụ. CP giống như một phiên bản dễ hơn của ngành Khoa học máy tính, vì các bạn vẫn chưa phải xử lí những gì quá phức tạp thuộc về máy tính. Yêu cầu chính của CP chỉ là tư duy và giải được bài toán đó trong một số ràng buộc cụ thể. Các ràng buộc đó cụ thể như:

  • Thời gian: thường là từ 1-2 giây, một số bài có thể nhiều hơn. Đây là một ràng buộc không thể thiếu trong các bài toán lập trình thi đấu, bởi lẽ để xác định độ tối ưu của một chương trình, thời gian là thước đo mang tính tiêu chuẩn nhất. Nếu chương trình của bạn đẹp và gọn, nhưng chạy với tốc độ chậm gấp nhiều lần thời gian cho phép, như vậy cho biết chương trình của bạn chưa tối ưu. Trong một số kì thi, đây còn là yếu tố quan trọng để quyết định vị trí của bạn trong bảng xếp hạng. Ví dụ như bạn và đối thủ cùng giải được một bài, nhưng đối thủ của bạn có chương trình chạy nhanh hơn, vậy có nghĩa khách quan mà nói, đối thủ của bạn có chương trình tốt hơn.
  • Bộ nhớ: tiêu chuẩn thường là 256 MB, mặc dù tùy từng bài mà sẽ thay đổi. Ràng buộc này được tạo ra cũng là để đánh giá độ tối ưu trong việc sử dụng tài nguyên của chương trình bạn ra sao. Ví dụ như bạn muốn lưu lại toàn bộ các khả năng của ván cờ vua để tạo ra một con bot chơi cờ. Nhưng theo tính toán của một số nhà khoa học, tổng số ván cờ có khả năng xảy ra còn nhiều hơn cả số nguyên tử trong vũ trụ, và để lưu một lượng lớn dữ liệu như vậy là hoàn toàn không thể, chưa nói đến truy xuất dữ liệu. Bộ nhớ đôi khi không phải là hữu hạn, càng sử dụng nhiều thì càng tốn kém cả năng lượng lưu trữ lẫn tài nguyên thiên nhiên. Chính vì vậy trong các kì thi, họ mong muốn chương trình của bạn cũng phải tối ưu, sử dụng vừa đủ số bộ nhớ mà đề cho phép.
  • Giới hạn: là những điều kiện của các biến trong chương trình. Ví dụ chương trình của bạn có thể xử lí được đầu vào (input) của một số nhỏ hơn 106, nhưng đề lần này lại muốn bạn xử lí input với giới hạn lên tới 1018. Lúc này sự khác biệt là rõ rệt, và đây cũng là để thử thách khả năng tư duy và xử lí bài toán của các thí sinh.

          Bên cạnh những ràng buộc trên, khi chấm bài, chương trình của bạn không chỉ được chấm bằng một trường hợp mà rất nhiều trường hợp khác nhau. Đây gọi là những testcases, và trong một số kì thi quan trọng như IOI – Olympic Tin học quốc tế, số testcase có thể lên tới hàng trăm. Lí do chính cho điều này là để đảm bảo chương trình của bạn sẽ được thử nghiệm với mọi loại trường hợp có thể xảy ra. Ví dụ chương trình của bạn lúc đúng lúc sai, lúc nhanh lúc chậm, nhìn chung là không ổn định, thì một bộ test càng lớn xác xuất bạn “va” phải góc chết sẽ càng tăng. Dù trên thực tế, khi sinh test, giám khảo đều sẽ lường trước các lỗi sai mà thí sinh có thể mắc phải để thiết kế bộ test sao cho phù hợp. Thông thường một bài sẽ chiếm khoảng 1 điểm, vậy mỗi test sẽ ứng với một phần điểm của bài toán đó. Tùy vào kì thi mà cách tính điểm cũng sẽ khác nhau.

          Và phần đem lại nhiều cảm xúc nhất cho bộ môn lập trình thi đấu: Ranking. Xếp hạng các thí sinh dựa theo năng lực thể hiện qua bài thi là một cách để đánh giá khách quan năng lực của từng người. Giống như các kì thi thể thao, nếu có hai hay nhiều thí sinh cùng giải được một số bài, thì việc xếp hạng sẽ được xét bằng penalty. Penalty bao gồm thời gian nộp bài của thí sinh, nhanh hay chậm, và có thể là thời gian thực thi chương trình của thí sinh, sử dụng bộ nhớ… Với nhiều bạn trẻ, ranking là một phần không thể thiếu trong quá trình học lập trình thi đấu. Nó giúp ta đánh giá được một cách khách quan vị trí của mình đang ở đâu so với người khác vì sau cùng, xếp hạng càng cao thì phần thưởng mới càng lớn. Và với một số người, chủ yếu là những bạn top đầu, ranking còn là cách để các bạn thể hiện bản thân hay nuôi dưỡng cái tôi của mình.

          Chung quy lại, lập trình thi đấu cũng như các bộ môn học thuật hay thể thao, đều đòi hỏi thí sinh phải không ngừng nâng cao trình độ, có phấn đấu và quyết tâm không ngừng thì mới đạt được thành công.

Lợi ích từ các kì thi, những cơ hội

          Các bộ môn thi đấu thì thường đi kèm theo đó là những kì thi nhằm đáp ứng nhu cầu luyện tập và tranh tài của các thí sinh. Những kì thi là cơ hội rất tốt để các bạn học sinh được dịp cọ xát lẫn nhau, rút ra điểm mạnh và yếu của bản thân để về sau tiến bộ hơn. Trên thực tế, cộng đồng lập trình thi đấu thế giới đã lập ra vô số các trang web liên quan đến tổ chức các thi lập trình online, offline. Tiêu biểu nhất có thể kể đến các trang như Codeforces, Codechef, Atcoder… Nếu bạn đủ giỏi, bạn có thể tham gia vào ra đề cho các cộng đồng trên. Với mỗi lần ra đề, theo mình biết, bạn sẽ nhận được một khoản thù lao tương đối lớn tùy theo mức độ đóng góp của bạn trong kì thi. Có thể nói, ngoài đem đến những cơ hội và sân chơi cho các những người say mê lập trình thi đấu luyện tập, đây còn góp phần giúp một số người kiếm thêm chút thu nhập cho mình, như một cách để khích lệ mọi người tiếp tục phấn đấu trau dồi bản thân hơn.

          Nói về những cơ hội khi bạn học lập trình thi đấu. Ngày nay, một số công ty như Google hay Grab, với những vị trí liên quan tới kỹ sư hay hệ thống, những người nộp đơn đều sẽ được trải qua vài vòng phỏng vấn, và sau đó là làm một bài kiểm tra trình độ. Bài kiểm tra này thường liên quan đến cấu trúc dữ liệu hoặc thuật toán, với mục đích kiểm tra xem các ứng viên có kĩ năng xử lí các công việc mang tính chuyên môn cao hay không. Việc một số công ty lớn hỏi về cấu trúc dữ liệu và giải thuật cho thấy tầm quan trọng của tư duy giải thuật và lập trình ra sao. Vì vậy những người đã thường xuyên tiếp xúc với lập trình thi đấu, được học nhiều thuật toán phức tạp và các bài toán hóc búa… sẽ có khả năng đạt kết quả cao hơn những người không luyện giải thuật nhiều.

          Những người được tiếp xúc từ nhỏ với những kiến thức chuyên ngành, những kì thi học thuật… thường có xu hướng trở nên giỏi ở những lĩnh vực đó hơn những người đến sau. Khi thường xuyên đối mặt với những vấn đề hóc búa, não bộ liên tục phải suy nghĩ và làm việc. Trên thực tế, nhiều nghiên cứu đã chỉ ra rằng: trẻ em có tốc độ phát triển não bộ nhanh hơn nhiều lần so với bất kì lứa tuổi nào khác. Đây có thể là lí do những người trẻ thường có khả năng tiếp thu và học hỏi nhanh hơn những người lớn tuổi hơn, bất kể sức bền của cả hai. Một điều nữa cũng có thể rút ra từ những nghiên cứu trên, đó là: khi còn trẻ thì nên ham học hỏi, bởi nếu không thì càng về sau tuổi tác sẽ càng không cho phép, và thậm chí khi đó bản thân cũng không còn nguồn lực hay thời gian để học (trên 18 tuổi bắt đầu phải tham gia vào lực lượng lao động xã hội).

Sự phát triển của giác quan (vàng), khả năng ngôn ngữ (xanh) và khả năng nhận thức cao (đỏ) theo độ tuổi.

          Ngoài ra học lập trình thi đấu cũng rèn cho chúng ta tính kỉ luật. Vì phải có kỉ luật thì ta mới có thể ôn luyện và đạt được những kết quả tốt. Không có ai trở nên tài giỏi chỉ với một chút thông minh vốn có từ khi sinh ra. Tất cả đều phải do khổ luyện mà thành. Niềm đam mê cũng nằm trong những lợi ích của lập trình thi đấu. Là một bộ môn tư duy, gần giống toán, niềm vui của lập trình thi đấu thường không nằm ở việc gõ code như nào, mà nằm ở việc độ khó của bài toán ra sao. Người giải thường phải suy nghĩ rất lâu trước khi có thể ra được hướng giải cho bài toán, và theo mình, đây chính là biểu hiện của sự đam mê. Phải đam mê thì ta mới chấp nhận bỏ thời gian để đương đầu với các vấn đề hóc búa đến như vậy, và nếu không có đam mê thì việc tự tìm tòi để nâng cao trình độ là điều gần như không thể.

          Cuối cùng là về mặt môi trường. Ở bậc tiểu học, trung học, phổ thông, việc trau dồi tư duy như đã nói ở trên là vô cùng quan trọng. Nếu ta chỉ học lập trình kéo thả không thôi thì tư duy lập trình của chúng ta sẽ có ít khả năng để được trau dồi. Với những độ tuổi phải học nhiều bộ môn đánh đố như vậy, thì việc học lập trình thi đấu dường như khá hợp hoàn cảnh vì với nền tư duy toán học đang sẵn có, học lập trình thi đấu sẽ dễ dàng hơn so với một người trưởng thành phải mò mẫm từ con số 0.

Thực tiễn

          Lợi ích tuy là vậy, nhưng những điều mình liệt kê ở trên chưa đề cập đến một cách kiếm sống ổn định nào từ lập trình thi đấu. Nếu bạn đi thi và đạt giải cao hoặc tham gia ra đề và được chút tiền thưởng, chừng đó cũng chỉ đó để bạn có một cuộc sống ổn định. Bạn không có dư tiền để chi tiêu vào các thú vui khác cho bản thân, hay thậm chí lo cho gia đình. Và đó mới chỉ là nếu bạn rất giỏi, còn những người giỏi một cách trung bình thì sao, họ sẽ kiếm sống như thế nào nếu chỉ giỏi mỗi lập trình thi đấu? Đây thực ra là một câu hỏi chung mà không chỉ những người học lập trình thi đấu gặp phải, mà còn cả mọi người thuộc các bộ môn học thuật khác như Toán Lí Hóa. Trái với các bộ môn thể thao, nếu bạn giỏi, bạn có thể tham gia vào nhiều trận đấu để có tiền thưởng, hoặc đi đóng quảng cáo. Những môn học thuật thì không như vậy, vì rõ ràng các kì thi học thuật có ít hơn các kì thi thể thao (thiếu nhà tài trợ), và mình chưa thấy trường hợp nào của bên học thuật đi đóng quảng cáo cả!

          Nhìn chung, nếu bạn học giỏi và có tư duy cao, bạn có thể làm giáo viên, giáo sư hoặc làm một nhà nghiên cứu chuyên sâu. Ở đây, trong lĩnh vực CNTT, nhà nghiên cứu này có thể là các kỹ sư hoặc chuyên gia công nghệ. Tất cả những ngành kể trên đều sở hữu mức lương rất cao, tuy nhiên trừ giáo viên ra, không một nghề nào chỉ cần cần kiến thức về mỗi một lĩnh vực. Vì khi đi làm, kĩ năng làm việc nhóm cũng là vô cùng quan trọng, kĩ năng giao tiếp, kĩ năng văn phòng, kĩ năng sống cũng quan trọng không kém (gọi chung là kĩ năng mềm). Và nếu bạn làm chuyên gia hay kĩ sư CNTT, bạn còn phải biết rất nhiều về các công nghệ hay phần cứng của máy tính, vì kiến thức lập trình thi đấu một mình chắc chắn không đủ để xử lí các vấn đề thực tiễn trong đời sống. Các hệ thống tối ưu chắc chắn cần đến những thuật toán tối ưu, nhưng một khi công ty đã nâng cấp được hệ thống của mình trở nên tối ưu rồi thì bạn cũng sẽ phải tìm cách cải tiến chúng tốt hơn nữa – điều không phải dễ dàng.

          Mặt khác, có lẽ áp đặt tư duy thực dụng này lên một bộ môn thể thao trí tuệ như lập trình thi đấu là không nên. Cũng như cờ vua hay cờ caro, dẫu là những bộ môn đòi hỏi trí tuệ cao, nhưng chúng không có đóng góp đáng kể gì tới sự phát triển của nhân loại, mà chủ yếu mang tính thể thao, giải trí. Lập trình thi đấu có lẽ cũng giống như vậy. Mặc dù không đóng góp thêm gì nhiều cho sự phát triển của nhân loại, nhưng lập trình thi đấu hoàn toàn là một bộ môn thể thao trí tuệ rất tốt cho cả tinh thần và tư duy của chúng ta. Những kì thi gay cấn, những bài tập khó và đánh đố, hóc búa, đòi hỏi chúng ta phải có những chiến thuật ôn luyện hiệu quả, những chiến lược, kế hoạch cần vạch ra. Tuy có thể xem chỉ như một hoạt động thể thao giải trí như cờ vua, nhưng lập trình thi đấu vẫn có gốc là từ Toán học và ngành Khoa học máy tính. Bằng việc duy trì và phát triển một cộng đồng trí thức hăng say với bộ môn lập trình thi đấu, ngành CNTT sẽ luôn có một lực lượng thường trực với tư duy cao để giải quyết các bài toán hóc búa có thể xuất hiện trong hệ thống, nếu chúng xuất hiện.

Lời kết

          Tổng kết lại, mặc dù lập trình thi đấu có thể có tính ứng dụng không cao, nhưng những giá trị mà nó đem lại là không thể phủ nhận. Hãy tưởng tượng nó giống như Toán học, tuy chỉ là những con số trừu tượng và có rất ít ứng dụng trong các đời sống hàng ngày, nhưng những công trình mang tính chất phức tạp cao như tên lửa, tàu vũ trụ, các loại trang thiết bị khoa học của con người… đều sử dụng rất nhiều kiến thức toán để chế tạo nên. Điều tương tự cũng đúng với lập trình thi đấu. Có thể những kiến thức đó bình thường chưa ai cần, nhưng một khi độ phức tạp của một dự án tăng, thì tất cả những thuật toán ấy sẽ phát huy công dụng của mình. Chưa kể, hiện trên thế giới vẫn còn rất nhiều những bài toán lập trình chưa có lời giải trong thời gian cụ thể. Nếu giải được, sẽ giúp cải thiện rất nhiều chi phí cho các sản phẩm dịch vụ để xã hội ngày một phát triển hơn.

          Nhưng bỏ qua tất cả những điều đó sang một bên, quan trọng là bản thân bản có cảm thấy thích hay không. Sau cùng thì ta không cần phải giàu có để cảm thấy hạnh phúc, đôi khi chỉ cần được theo đuổi đam mê của mình là ta đã sống một cuộc sống đầy đủ nhất rồi. Lập trình thi đấu có tốt hay không? Lợi ích là gì? Những câu hỏi đó có còn quan trọng không nếu như bạn đã biết mình muốn gì. Nếu bạn học chỉ vì tiền hoặc sự nghiệp, đó là một quan điểm sống, nhưng mình chỉ chúc tất cả các bạn, những người đã và đang nỗ lực vì một tương lai tốt đẹp hơn, một năm mới vui vẻ ?

Tài liệu tham khảo
  1. https://ioinformatics.org/page/ioi-2019/51
  2. https://codeforces.com/blog/entry/94884
  3. https://codeforces.com/blog/entry/90257
  4. https://codeforces.com/blog/entry/104642
  5. https://codeforces.com/blog/entry/83499
  6. https://codeforces.com/blog/entry/79449

 1,857 total views,  1 views today

Post a Comment