АпееСцапе је покренуо изазов ЈаваСцрипт кодирања веб апликација као начин привлачења људи на наше конференцијске кабине. Видевши колико је успео, одлучили смо да направимо пилот на Интернету, отворен за све у нашој заједници и њиховим мрежама.
У време лансирања, подстакли смо мотивисане програмере да осмисле креативне начине за постизање високих резултата у укупном изазову ЈаваСцрипт кодирања. Неки од кључних фактора успеха великих независних слободњака су способност размишљања изван оквира и проналажења креативних начина за рад у оквиру ограничења.
Рукавица се састојала од већег броја ЈаваСцрипт питања - слична онима која би се могла користити као интервју питања — Распоређивање од заиста основних ЈаваСцрипт изазова:
box.double = function double (x) { //return x doubled };
... на више средње:
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 (i.e., '09/01/2019' translates to 244) };
Желели смо да се и почетници и напредни програмери забаве и позову своје пријатеље и колеге да се такмиче са њима за најбоље оцене. Питања су разврстана по бодовима, тако да су чак и млађи програмери могли да постигну неке поене. Редослед питања која су имала исти број бодова био је случајан, па је искуство сваки пут било мало другачије, док је читав низ питања остао исти током целе недеље.
Циљ је био обавити што више задатака у року од три минута. У случају да неко пронађе начин да изврши све задатке у изазову ЈаваСцрипт кодирања, додељује се 10 поена за сваку преосталу секунду. Дозволили смо више покушаја да довршимо изазов.
Прва ствар коју смо очекивали да ће се догодити је да људима треба времена реши питања лаганим темпом, а затим копирајте и налепите одговоре у веб апликацију.
После једног сата и 40 минута покретања изазова, прва особа је следила овај приступ и добила је 1445 максималних бодова колико је апликација дозвољавала, плус неке додатне бодове које смо додељивали за сваку преосталу секунду.
Приступом цопи-анд-пасте, врхунски такмичари нису имали ништа више од фокусирања на кодирање самих одговора. Уместо тога, усмерили су пажњу на то да брзину уведу у своје вештине аутоматизације.
Најлакши приступ у овом тренутку био је писање ЈаваСцрипт-а који ће решити сваки задатак док чекате петљу док дугмад не буду спремна и копирати га и налепити у конзолу прегледача:
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()
Овај део би такође могао бити аутоматизован помоћу уобичајених алата за аутоматизацију попут Селен . Али бржи начин би био аутоматизација употребе АПИ-ја, слање решења задацима:
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)
Треба напоменути да је у овој верзији изазова за брзо кодирање код тестиран само на страни клијента. Због тога је било могуће једноставно послати одговоре на тест случајеве уместо кода. Ово је омогућило оптимизацију и смањило милисекунде на страни клијента.
Три дана резултати су остали исти. Неки људи су писали микро оптимизације за свој код, а неколико људи је слало своја решења у петљи, надајући се да ће сервер постати мање гужве како би могли да добију неколико бодова испред. Требали смо да нас чека велико изненађење.
Прво, хајде да направимо брзу математику: За завршетак свих задатака укупно смо добили 1445 бодова и временско ограничење од 180 секунди. Ако доделимо 10 бодова у секунди преосталих у пријави, максимални теоретски достижни резултат био би 3245 - у случају да се сви одговори дају одмах.
Један од наших корисника постигао је резултат од преко 6000, који је временом непрестано растао.
Како је неко могао да добије тако висок резултат?
Након кратког прегледа открили смо шта се догађало. Наш најбољи такмичар, професионални програмер пуног стека и АпееСцапеер са више од 15 година искуства у такмичарском програмирању, пронашао је рупу у постављању изазова за кодирање. Изродио је више ботова, што је успорило сервер; у међувремену, могао је да изврши исти задатак (онај који је доделио највише поена) што је више пута могуће и доделио њихове оцене једном уносу, непрекидно додајући резултат тог уноса.
Ово није било против правила, јер смо дозволили креативна решења; међутим, одређена метода коју је он користио довела је до тога да је сервер био знатно заузетији, чинећи мрежне захтеве споријим за све остале. Прво што смо урадили било је повећање снаге сервера, што га је натерало да са 56.000 пређе на 70.000 поена и остане на првом месту.
Иако нисмо желели да интервенишемо у начину на који су људи комуницирали са изазовом, ови покушаји су успорили сервер до те мере да је изазов било тешко користити за друге кориснике, па смо одлучили да поправимо рупу.
Исправком је онемогућено да други људи постигну исти резултат током последњег дана изазова ЈаваСцрипт кодирања. Због овога смо одлучили да продужимо број награда додељених најбољим такмичарима. Првобитно је главна награда - пар АирПод-ова - требало да припадне само једном најбољем такмичару. На крају, АирПодс су добили они који су држали првих шест места.
Чак су и наши најбољи стрелци имали потешкоћа у старту. У ствари, од свих људи који су направили пет или више покушаја, најбољи резултат било ког првог покушаја био је 645, а средња оцена за прве покушаје у тој групи била је само 25 поена.
На крају такмичења могло се погодити стратегију која се покушава из укупног броја покушаја. Иако су неки били ефикаснији од других, највећи такмичар тамо далеко је имао највећи број покушаја.
Шта носи будућност?
Ово је била само прва понављања изазова ЈС кодирања. У будућности желимо да урадимо још много изазова за програмирање ЈаваСцрипт-а, научите лекције у односу на претходне вожње и учините то још узбудљивијим. Прво што желимо да урадимо је да применимо покушај пригушивања како бисмо ограничили број пријава. Такође желимо да се проширимо даље од изазова кодирања у ЈаваСцрипт-у, чинећи их доступним у широком спектру програмских језика.
И на крају, док предузимамо мере како бисмо изазов ЈаваСцрипт кодирања учинили сигурнијим, планирамо да и даље дозвољавамо употребу ботова и других креативних приступа за будуће изазове.
Посебна захвалност за Павел Видра , Антон Андрииевскии , Тиаго Цхиланти, и Матеи Цопот за допринос изазову и овом чланку и @Зирак за пројекат отвореног кода који су чинили основу конкурсне апликације. Исто тако, хвала свима који су учествовали на такмичењу и кандидовали се за њега.
Да бисте постали стручњак за решавање изазова кодирања, требало би да се стално побољшавате одабиром све тежих проблема. ЈаваСцрипт изазов АпееСцапе-а садржи широк спектар нивоа тежине задатака. Не прескачите проблеме који изгледају заморно: једини начин да се побољшате је да се усредсредите и на њихово решавање.
ЈаваСцрипт изазов је осмишљен да тестира ваше знање програмирања у временском окружењу. Да бисте га успешно завршили, требали бисте бити у могућности да брзо одаберете структуре података и брзо дизајнирате алгоритме.
Изазови брзог кодирања вежбања, Цодеварс-а, Цодилити-а и АпееСцапе-а (када су доступни) су одлична места за вежбање ЈаваСцрипт кодирања - конкурентно или на неки други начин.