Cách tạo Code Challenge. Hệ thống Viblo Code Challenge được xây dựng như thế nào

927
cách tạo code challenge

Chắc hẳn ai trong số chúng ta cũng đã từng tham gia 1 số cuộc thi về contest hay là code challenge. Ví dụ như TalenHub, Viblo Code, Top Coder… Nhưng ít ai để ý xem cách tạo code challenge đó như thế nào? Làm thế nào có thể run được đoạn code mà mình đã submit?

Hôm nay mình sẽ đi đào sâu vào những hệ thống đó xem cụ thể nó được xây dựng như thế nào, và kiến trúc của nó ra sao. Đặc biệt để dễ hình dung thì mình sẽ đi lấy ví dụ về Viblo Code nhé.

  Kiến thức cơ bản và cách tạo WBS
  Nếu cảm thấy chán nản với cuộc sống hiện tại, đây là cách tạo ra phương trình hạnh phúc mà bạn tìm kiếm bấy lâu nay

Hệ thống Code Challenge là gì?

Code Challenge là dịch vụ dành cho lập trình viên rèn luyện kĩ năng về lập trình, cũng như các tư duy về giải thuật.

Cách tạo Code Challenge

Như hình ảnh bên trên về Viblo Code chúng ta có thể thấy, nó bao gồm phần câu hỏi, phần viết code, phần chọn ngôn ngữ mà mình thích …

Ngoài ra còn có 1 số chức năng khác nữa như Ranking (code của ai chạy nhanh sẽ được xếp hạng cao hơn …), nhận thưởng nếu đứng top.

Yêu cầu về mặt chức năng

  • Với mỗi câu hỏi có thể chọn ngôn ngữ lập trình mình muốn làm (shell, php, javascript, java …).
  • Khi submit code trả về kết quả, kèm theo thời gian thực thi
  • Có giới hạn về thời gian làm bài (ví dụ như chỉ làm trong 15p chẳng hạn)
  • Xếp hạng điểm của người dùng

Hôm nay mình sẽ tập trung chủ yếu vào phần thực thi code ứng với từng language (java, php, javascript …) . Còn phần ranking mình sẽ không đề cập đến ở đây.

Kiến trúc hệ thống

Mình nghĩ đầu tiên ai cũng sẽ đưa ra kiến trúc kiểu như này. Cùng xem xem nó có ổn không nhé.

Cách tạo Code Challenge

Chúng ta có 1 con web server, và ở trong con web server này sẽ cài tất cả các package liên quan đến tất cả các ngôn ngữ để có thể chạy được. Ví dụ như sẽ cài php, nodejs, java, python … tất tần tật lên con web server này.

Xem thêm Web Server là gì?

Và khi người dùng submit code của mình lên để test thì khi đó con web server này sẽ nhận request từ người dùng (giả sử như request này dạng json) bao gồm phần content và language.

Nó sẽ lưu cái phần content này vào 1 file. ví dụ như với ngôn ngữ php thì sẽ lưu file dạng main.php, nếu ngôn ngữ javascript thì sẽ lưu dạng main.js.

Và để xem đoạn code này có chạy được hay không thì web server sẽ chạy 1 đoạn code kiểu như này.

Khi đó nó sẽ trả về cho mình output của đoạn code và thời gian runtime cho người dùng. Với trường hợp là javascript hay python … thì cũng làm theo cách tương tự.

Vậy kiến trúc này có ổn không? Theo mình thì là không nhé. Có mấy lí do như sau:

  • Vì web server này chạy trực tiếp shell lên server của mình nên nếu như người dùng gửi 1 đoạn code kiểu như: rm -rf /var/www/html/* thì chắc ăn hành to rồi.
  • Vì cài nhiều package lên con web quá như thế cũng là nguyên nhân gây ra 1 số rủi ro về vấn đề bảo mật.

Để giải quyết bài toán trên thì chúng ta chỉ cần áp dụng docker vào là ok.

Cụ thể dưới đây là kiến trúc mình muốn đưa ra:

Cách tạo Code Challenge

Đầu tiên Web Server nhận request và khởi chạy container tương ứng với language được gửi lên. Sau đó run code thông qua container đó và nhận kết quả trả về cho người dùng.

Vậy chúng ta đã quyết định được kiến trúc hệ thống hợp lý. Tiếp theo sẽ đi vào phần lập trình.

Thiết kế API

Về API thì mình nghĩ chỉ cần 1 cái API về submit code. Thông số đầu vào là content và language. Output sẽ trả về kết quả sau khi compile đoạn code của người dùng cùng với thời gian thực thi đoạn code.

Cách tạo Code Challenge

Demo

Để dễ hiểu thì mình sẽ làm 1 phần demo để các bạn dễ hình dung.

Đây là kết quả sau khi gọi API để submit code.

Cách tạo Code Challenge

Còn đây là màn hình mô phỏng docker container làm việc (các bạn để ý cái màn hình terminal đằng sau đấy nhé). Cứ mỗi lần 1 request được gửi lên thì 1 container được khởi chạy và thực thi code. Nhìn khá là thú vị.

Cách tạo Code Challenge

OK vậy các bạn cũng hiểu hiểu rõ cái API làm việc thế nào rồi đúng không. Bây giờ đi vào phần code nhé.

Về API mình sẽ code bằng Nodejs

Source code: https://github.com/nooptr/code-challenge

Cách tạo Code Challenge

Về image để build cho từng language mình để ở trong thư mục docker.

Ví dụ như với ngôn ngữ PHP thì nội dung của Dockerfile sẽ như sau:

Trong đó nội dung của file script.sh sẽ như sau:

Mục đích của file script.sh này là để thực thi compiler file code. Kết quả sau khi compiler sẽ được ghi vào file $output. Và thời gian thực thi sẽ được in ra màn hình.

Để web server có thể chạy được container thì cần phải cài đặt trước bằng lệnh:

Tiếp theo cùng đi xem API viết như nào nhé:

Nếu ai code nodejs rồi thì mình nghĩ đọc phát có thể hiểu được ngay.

Ban đầu nó sẽ nhận request từ người dùng. Dạng như sau:

Nó sẽ đọc content và ghi vào 1 file gọi là main.php (cái này tuỳ vào ngôn ngữ được gửi lên. Nếu là php thì ghi vào file main.php. Nếu là javascript thì ghi vào file main.js).

Sau đó, web server sẽ gọi docker container để thực thi code bằng lệnh:

Cuối cùng sẽ đọc kết quả từ file /tmp/output và trả về cho người dùng với format response như sau:

Kết luận

Các bạn thấy thế nào? Có đơn giản không? Chỉ với 1 đoạn code ngắn mà chúng ta có thể biết cách tạo Code Challenge rồi đúng không.

Source code này mình chỉ viết dưới dạng demo thôi nên có thể có nhiều chỗ code chưa hợp lí. Các bạn tự sửa theo ý mình nhé.

Đừng bỏ lỡ những bài viết hay về:

Tìm kiếm thêm cơ hội việc làm Software Developers mới trên TopDev

TopDev via Nghệ Thuật Coding

  Ngôn ngữ lập trình Scala là gì?
  Sharding là gì? - Cách Instagram tạo ID trong database của họ bằng Sharding
SHARE