Kebutuhan akan Kecepatan: Retrospektif Tantangan Pengkodean JavaScript Toptal

Diterbitkan: 2022-03-11

Toptal memulai aplikasi web tantangan pengkodean JavaScript sebagai cara untuk menarik orang ke stan konferensi kami. Melihat betapa suksesnya itu, kami memutuskan untuk membuat percontohan di web, terbuka untuk semua orang di komunitas kami dan jaringan mereka.

Tangkapan layar dari Tantangan Pengkodean Kecepatan JavaScript Toptal, menunjukkan salah satu pertanyaan pertama. Sebuah fungsi bernama "ganda" disediakan, dan tubuhnya terdiri dari komentar, "kembalikan x dua kali lipat."

Pada waktu peluncuran, kami telah mendorong pengembang yang termotivasi untuk menemukan cara kreatif untuk mendapatkan skor tinggi pada tantangan pengkodean JavaScript secara keseluruhan. Beberapa faktor kunci sukses dari freelancer independen yang hebat adalah kemampuan untuk berpikir di luar kebiasaan dan menemukan cara kreatif untuk bekerja dalam serangkaian kendala.

Pertanyaan Tantangan Pengkodean JavaScript

Tantangannya terdiri dari sejumlah pertanyaan JavaScript—mirip dengan pertanyaan yang mungkin digunakan sebagai pertanyaan wawancara—mulai dari pertanyaan tantangan JavaScript yang sangat mendasar:

 box.double = function double (x) { //return x doubled };

…untuk yang lebih menengah:

 box.dateRank = function dateRank (x) { // x is a date in 2019 as string (example: "06/30/2019") // return the rank of the day in 2019 (ie, "09/01/2019" translates to 244) };

Kami ingin pemula dan pengembang tingkat lanjut bersenang-senang dan mengundang teman dan kolega mereka untuk bersaing dengan mereka untuk mendapatkan skor tertinggi. Pertanyaan diurutkan berdasarkan poin, sehingga bahkan pengembang junior dapat mencetak beberapa poin. Urutan pertanyaan yang memiliki jumlah poin yang sama adalah acak, jadi pengalamannya sedikit berbeda setiap saat, sedangkan set pertanyaan lengkap tetap sama sepanjang minggu.

Tujuannya adalah untuk menyelesaikan tugas sebanyak mungkin dalam batas waktu tiga menit. Jika seseorang menemukan cara untuk menyelesaikan semua tugas dalam tantangan pengkodean JavaScript, 10 poin akan diberikan untuk setiap detik yang tersisa. Kami mengizinkan beberapa upaya untuk menyelesaikan tantangan.

Hal pertama yang kami perkirakan akan terjadi adalah orang akan meluangkan waktu untuk menyelesaikan pertanyaan dengan santai, lalu menyalin dan menempelkan jawabannya ke aplikasi web.

Setelah satu jam 40 menit meluncurkan tantangan, orang pertama mengikuti pendekatan ini dan mendapatkan 1445 poin maksimum yang diizinkan oleh aplikasi, ditambah beberapa poin tambahan yang kami berikan untuk setiap detik tersisa.

Titik Balik dalam Tantangan Pengkodean JavaScript

Dengan pendekatan copy-and-paste, kontestan papan atas tidak memiliki apa-apa lagi dengan berfokus pada pengkodean jawaban sendiri. Sebaliknya, mereka mengalihkan perhatian mereka untuk membawa kecepatan ke keterampilan otomatisasi mereka.

Pendekatan termudah pada saat ini adalah menulis beberapa JavaScript yang akan menyelesaikan setiap tugas sambil menunggu dalam satu putaran hingga tombol siap, dan salin-tempel ke konsol browser:

 const solutions = { 'double': 'return x*2', 'numberToString': '...', 'square': '...', 'floatToInt': '...', 'isEven': '...', 'squareroot': '...', 'removeFirstFive': '...', // ... 'dateRank': '...', // ... }; const get_submit_button = () => document.querySelector('.task-buttons > .col > .btn'); const solve = () => { const ace_editor = ace.edit(document.querySelector('.ace_editor')) const submission = ace_editor.getValue() for (const key in solutions) { if (submission.includes('box.' + key + ' ')) { ace_editor.insert(solutions[key]) get_submit_button().click() setTimeout(() => { get_submit_button().click() setTimeout(() => { solve() }, 400) }, 900) return } } } solve()

Bagian ini juga dapat diotomatisasi menggunakan alat otomatisasi biasa seperti Selenium. Tetapi cara yang lebih cepat adalah dengan mengotomatiskan penggunaan API, mengirimkan solusi ke tugas:

 const request = require('request'); const runTask = (data, entryId, callback) => { const tests = data.nextTask.tests_json; const results = Object.fromEntries( Object.entries(tests).map(([key, value]) => [key, value.result]) ); request.post(`https://speedcoding.toptal.com/webappApi/entry/${entryId}/attemptTask`, { form: { attempt_id: data.attemptId, tests_json: JSON.stringify(results), }, }, (error, res, body) => { if (error) throw error; const next = JSON.parse(body).data if (next.isChallengeEntryFinished) { callback(next) return } runTask(next, entryId, callback) }); } const runEntry = (callback) => { request.post('https://speedcoding.toptal.com/webappApi/entry', { form: { challengeSlug: 'toptal-speedcoding', email: ..., leaderboardName: ..., isConfirmedToBeContacted: ..., dateStop: ... }, }, (error, res, body) => { if (error) throw error; const { data } = JSON.parse(body); const entryId = data.entry.id runTask(data, entryId, callback) }); } runEntry(console.log)

Satu hal yang perlu diperhatikan adalah, dalam versi tantangan pengkodean cepat ini, kode hanya diuji di sisi klien. Karena itu, dimungkinkan untuk hanya mengirimkan jawaban atas kasus uji alih-alih kode. Ini memungkinkan pengoptimalan dan memotong beberapa milidetik di sisi klien.

Setelah tiga hari, kompetisi benar-benar mulai memanas, dengan jumlah upaya per ember tiga jam tiba-tiba dari di bawah 1.000 menjadi hampir 100.000.

Selama tiga hari, skor tetap sama. Beberapa orang menulis optimasi mikro untuk kode mereka, dan beberapa orang mengirimkan solusi mereka dalam satu lingkaran, berharap server akan menjadi kurang ramai sehingga mereka bisa mendapatkan beberapa poin di depan. Kami dijadwalkan untuk kejutan besar.

Memecahkan Skor Maksimum Tantangan Pengkodean JavaScript

Pertama, mari kita lakukan beberapa matematika cepat: Kami memiliki total 1445 poin yang diberikan untuk penyelesaian semua tugas, dan tunjangan waktu 180 detik. Jika kami memberikan 10 poin per detik tersisa dalam aplikasi, skor teoritis maksimum yang dapat dicapai adalah 3245—dalam hal mengirimkan semua jawaban secara instan.

Salah satu pengguna kami mencapai skor lebih dari 6000, yang terus berkembang dari waktu ke waktu.

Bagaimana seseorang bisa mendapatkan skor setinggi itu?

Setelah tinjauan singkat, kami menemukan apa yang telah terjadi. Kontestan teratas kami, pengembang full-stack profesional dan Toptaler dengan pengalaman pemrograman kompetitif lebih dari 15 tahun, menemukan celah dalam penyiapan tantangan pengkodean. Dia melahirkan banyak bot, yang memperlambat server; sementara itu, dia bisa menyelesaikan tugas yang sama (yang memberikan poin terbanyak) sebanyak mungkin dan menetapkan skor mereka ke satu entri, terus menambah skor entri itu.

Ini tidak melanggar aturan, karena kami mengizinkan solusi kreatif; namun, metode khusus yang dia gunakan menyebabkan server menjadi jauh lebih sibuk, membuat permintaan jaringan menjadi lebih lambat untuk semua orang. Hal pertama yang kami lakukan adalah meningkatkan kekuatan server kami, yang hanya membuatnya naik dari 56.000 menjadi 70.000 poin dan tetap di tempat pertama.

Meskipun kami tidak ingin mengintervensi cara orang berinteraksi dengan tantangan, upaya ini memperlambat server sejauh tantangan itu sulit digunakan untuk pengguna lain, jadi kami memutuskan untuk memperbaiki celahnya.

Perbaikan tersebut membuat orang lain tidak mungkin mencapai skor yang sama selama hari terakhir tantangan pengkodean JavaScript. Karena itu, kami memutuskan untuk memperpanjang jumlah penghargaan yang diberikan kepada kontestan teratas. Awalnya, hadiah utama—sepasang AirPods—seharusnya diberikan kepada satu kontestan teratas saja. Pada akhirnya, AirPods diberikan kepada mereka yang memegang enam tempat pertama.

Awal yang Sederhana dan Akhir yang Ganas: Beberapa Statistik Tantangan Pengkodean JavaScript

Bahkan pencetak gol terbanyak kami mengalami beberapa kesulitan memulai. Faktanya, dari semua orang yang melakukan lima percobaan atau lebih, skor tertinggi untuk percobaan pertama seseorang adalah 645, dan skor median untuk percobaan pertama dalam grup itu hanya 25 poin.

Pada akhir kontes, orang bisa menebak strategi yang dicoba dari jumlah total percobaan. Sementara beberapa lebih efisien daripada yang lain, kontestan teratas jauh dan jauh memiliki jumlah upaya tertinggi.

Gabungan grafik batang logaritmik yang menunjukkan skor tertinggi 20 kontestan teratas dan jumlah total percobaan. Sementara jumlah percobaan tertinggi jatuh ke pencetak gol terbanyak, jumlah percobaan tertinggi kedua, ketiga, dan keempat jatuh ke masing-masing kontestan tempat ke-13, kesembilan, dan tempat kedua. Tepat setengah dari 20 besar, termasuk kontestan tempat keempat dan keenam, memiliki di bawah 1.000 upaya. Dua kontestan memiliki di bawah 100 upaya, dan satu lagi bahkan memiliki di bawah 10.

Bergerak kedepan

Apa yang ada di masa depan?

Ini hanya iterasi tantangan pengkodean JS pertama. Kami ingin melakukan lebih banyak tantangan pemrograman JavaScript di masa mendatang, mempelajari pelajaran dari proses sebelumnya, dan membuatnya lebih menarik. Hal pertama yang ingin kami lakukan adalah menerapkan upaya pembatasan untuk membatasi jumlah pengiriman. Kami juga ingin memperluas tantangan pengkodean di JavaScript, membuatnya tersedia dalam berbagai bahasa pemrograman.

Terakhir, sementara kami mengambil langkah-langkah untuk membuat tantangan pengkodean JavaScript lebih aman, kami berencana untuk tetap mengizinkan penggunaan bot dan pendekatan kreatif lainnya untuk tantangan di masa mendatang.


Terima kasih khusus kepada Pavel Vydra, Anton Andriievskyi, Tiago Chilanti, dan Matei Copot atas kontribusi mereka pada tantangan dan artikel ini, dan kepada @Zirak atas proyek sumber terbuka yang menjadi dasar aplikasi kontes. Demikian juga, terima kasih kepada semua orang yang berpartisipasi—dan berlari—kontes.