
käännös
Kokemuksemme osoittavat, että ei-tekniset kehittäjät ja itseoppineet kehittäjät eivät usein luota teoreettisiin periaatteisiin, vaan heuristisiin menetelmiin.
Heuristiikka ovat malleja ja todistettuja sääntöjä, jotka kehittäjä on oppinut käytännössä. Ne eivät ehkä toimi täydellisesti tai rajoitetusti, mutta ne toimivat riittävän hyvin eivätkä vaadi vakavaa harkintaa. Tässä on esimerkkejä heuristiikasta:
- "Käyttää
$(document).ready(function(){})koodin alustamiseen jQuery-sivustoilla" - "Design
var self = thisvaaditaan menetelmän kutsumiseen takaisinsoittofunktiossa" - "Nuolifunktioilla ei ole operaattoreita
return»
Samalla teoreettisen periaatteen avulla voidaan löytää ratkaisuja muihin ongelmiin. Se on aina totta ja määrittää usein tietyn elementin toiminnan rakenteen. Teoreettisia periaatteita ovat mm.
Huomaa, että laitamme vain esimerkkejä heuristiikasta lainausmerkkeihin korostaaksemme heuristiikan käsiteollista luonnetta verrattuna teoreettisen viitekehyksen tarkkuuteen. Mikään heuristisista esimerkeistä ei ole yleisesti sovellettavissa, mutta ne toimivat tarpeeksi tilanteissa, jotta niitä käyttävät kehittäjät saavat toimivan koodin ymmärtämättä täysin sen toimintaa.
Argumentit teoreettisen lähestymistavan puolesta
Olemme usein havainneet, että ei-tekniset kehittäjät ovat haluttomia ratkaisemaan ongelmia teoreettisten periaatteiden avulla. Tämä johtuu yleensä siitä, että heillä ei ollut mahdollisuutta oppia niitä uransa varhaisessa vaiheessa, ja koska heuristiikka toimii tyydyttävästi, he jatkavat niiden käyttöä.
Näennäisestä monimutkaisuudesta huolimatta teorian oppiminen voi kuitenkin olla erittäin hyödyllistä. Minkä vuoksi? Koska teorian avulla voit luottaa siihen, että ratkaisusi toimii, ja myös saada itsenäisesti vastauksia uusiin kysymyksiin ilman, että sinun tarvitsee etsiä jonkun muun ratkaisuja. Lyhyellä aikavälillä heuristiset algoritmit voivat vaikuttaa yksinkertaiselta ja nopealta ratkaisulta, mutta johtavat usein vähemmän kuin ihanteellisiin ratkaisuihin – jos niitä on ollenkaan.
Lisäksi heuristiikkaan luottamalla et koskaan opi ratkaisemaan ongelmia. Ehkä melko usein pystyt löytämään toimivan ratkaisun, mutta ennemmin tai myöhemmin tulet umpikujaan, josta et näe ulospääsyä. C&P-ohjelmoijat luottavat heuristiikkaan työssään.
Kehittäjän taitotason kriteeri
Haastatellessamme käyttöliittymäkehittäjiä annamme heille ohjelmointihaasteen ja kerromme heille, että he voivat vapaasti käyttää mitä tahansa lähteitä, olipa kyse sitten Googlesta tai Stack Overflowsta. Näin voit helposti määrittää, onko kehittäjä heuristinen vai teorian seuraaja.
Ensimmäiset kopioivat poikkeuksetta koodia enemmän tai vähemmän sopivista Stack Overflow -esimerkeistä. Vasta kun koodi ei toimi suunnitellusti, he alkavat muokata sitä itselleen sopivaksi. Usein he eivät pysty tekemään tätä.
Jälkimmäiset etsivät vastauksia yleensä API-dokumentaatiosta. Sieltä he löytävät tietoa siitä, kuinka monta parametria tietty funktio ottaa, tai halutun CSS-ominaisuuden laajennetun muodon tietyn syntaksin.
Jo haastattelun viiden ensimmäisen minuutin aikana voit määrittää tarkasti, minkä tyyppinen ohjelmoija ehdokas on.
Esimerkki
Otetaan esimerkkinä kehittäjä Bill. Hän osallistui useille kursseille, ratkaisi useita JavaScript-ongelmia ja kirjoitti verkkosivustoja vapaa-ajallaan, mutta hän ei "todella" opiskellut JavaScriptiä.
Eräänä päivänä Bill törmää tällaiseen esineeseen:
const usersById = {
"5": { "id": "5", "name": "Adam", "registered": true },
"27": { "id": "27", "name": "Bobby", "registered": true },
"32": { "id": "32", "name": "Clarence", "registered": false },
"39": { "id": "39", "name": "Danielle", "registered": true },
"42": { "id": "42", "name": "Ekaterina", "registered": false }
}
Tällainen objekti voi näyttää luettelon käyttäjistä ja siitä, ovatko he rekisteröityneet tiettyyn tapahtumaan.
Oletetaan, että Billin on haettava luettelo rekisteröityneistä käyttäjistä. Toisin sanoen suodata ne pois. Hän törmäsi koodiin, jossa menetelmä .filter() käytetään luettelon suodattamiseen. Joten hän yrittää jotain tällaista:
const attendees = usersById.filter(user => user.registered);Ja tämän hän saa:
TypeError: usersById.filter is not a function "Tämä on jonkinlaista hölynpölyä", Bill ajattelee, koska hän näki koodin, jossa .filter() toimi suodattimena.
Ongelmana on, että Bill luotti heuristiseen menetelmään. Hän ei ymmärrä sitä filter on taulukoille määritetty menetelmä, kun taas usersById - tavallinen esine, jolla ei ole menetelmää filter.
Hämmentynyt Bill Googles "javascript-suodatin" Hän löytää paljon mainintoja taulukoista ja tajuaa, että hänen täytyy kääntyä usersById taulukkoon. Sitten pyynnöstä"javascript muuttaa objektin taulukoksi» hän löytää esimerkkejä Stack Overflow -sovelluksesta Object.keys(). Tämän jälkeen hän yrittää:
const attendees = Object.keys(usersById).filter(user => user.registered); Tällä kertaa virhettä ei näy, mutta Billin yllätykseksi kenttä attendees jää tyhjäksi.
Tosiasia on, että Object.keys() palauttaa objektin avaimet, mutta ei sen arvoja. Pohjimmiltaan muuttujan nimi user helposti harhaanjohtava, koska se ei ole esine user, ja tunniste eli merkkijono. Attribuutista lähtien registered ei määritetty merkkijonoille, filter arvioi jokaisen merkinnän epätosi, ja taulukko tulee tyhjäksi.
Bill tarkastelee tarkemmin Stack Overflow -sivuston vastauksia ja tekee seuraavan muutoksen:
const attendees = Object.keys(usersById).filter(id => usersById[id].registered); Tällä kertaa tulos on parempi: ["5", "27", "39"]. Mutta Bill halusi saada vierailijoiden esineet, ei heidän henkilötodistuksiaan.
Selvittääkseen, kuinka kävijöitä suodatetaan, ärsyyntynyt Bill tekee haun "javascript-objektisuodatin", tutkii Stack Overflow -sivuston hakutuloksia ja löytää seuraavalla koodilla:
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );Bill kopioi nämä rivit ja yrittää:
const attendees = Object.filter(usersById, user => user.registered); Kaikki toimii - vaikka ei ole selvää miksi. Bill ei ymmärrä, mitä varten se on reduce ja miten sitä käytetään. Lisäksi Bill ei ymmärrä, että hän määritteli juuri globaalille objektille Object uusi epästandardi menetelmä.
Mutta Bill ei välitä - se toimii! Hän ei ole vielä kiinnostunut seurauksista.
Mitä Bill teki väärin?
Bill kokeili heuristista menetelmää ongelman ratkaisemiseksi ja kohtasi seuraavat ongelmat:
- Käyttämällä
.filter()muuttujalla, Bill saiTypeError. Hän ei ymmärtänyt sitäfilterei havaita tavallisissa esineissä. - Hän haki
Object.keys()"muuttaa objekti taulukoksi", mutta tämä ei sinänsä tuonut mitään tulosta. Hänen täytyi luoda joukko objektiarvoja. - Jopa saatuaan arvot ja käyttäessään niitä suodatuksen ehtona, hän sai vain tunnisteet niihin liittyvien käyttäjäobjektien sijaan. Tämä johtuu siitä, että suodatettu taulukko sisälsi tunnuksia, ei käyttäjäobjekteja.
- Ajan myötä Bill hylkäsi tämän lähestymistavan ja löysi toimivan ratkaisun Internetistä. Hän ei kuitenkaan vieläkään ymmärrä, kuinka se toimii - eikä hän tuhlaa aikaa sen selvittämiseen, koska hänellä on muutakin tekemistä.
Tämä on keinotekoinen esimerkki, mutta olemme nähneet kehittäjien ratkaisevan ongelmia samalla tavalla monta kertaa. Niiden tehokkaaksi ratkaisemiseksi sinun on siirryttävä pois heuristisista menetelmistä ja opiskella teoriaa.
Mennään perusasioihin
Jos Bill olisi teoreettisen lähestymistavan kannattaja, prosessi näyttäisi tältä:
- Tunnista annetut tulot ja määritä halutut lähdöt - niiden ominaisuuksien perusteella: "Minulla on objekti, jonka avaimet ovat tunnuksia edustavia merkkijonoja ja joiden arvot ovat käyttäjiä edustavia objekteja. Haluan saada taulukon, jonka arvot ovat käyttäjäobjekteja - mutta vain rekisteröityjä käyttäjäobjekteja"
- Ymmärrä kuinka iteroida objektin läpi: "Tiedän, että voin saada objektin avainjoukon soittamalla
Object.keys(). Haluan saada taulukon, koska taulukot tukevat iteraatiota". - Ymmärrä, että tämä menetelmä auttaa saamaan avaimet, ja sinun on muutettava avaimet arvoiksi ja muista ne
mapon ilmeinen tapa luoda uusi taulukko muuntamalla toisen taulukon arvot:Object.keys(usersById).map(id => usersById[id]) - Varmista, että sinulla on nyt suodatettava joukko mukautettuja objekteja, joka sisältää todelliset arvot, jotka haluat suodattaa:
Object.keys(usersById).map(id => usersById[id]).filter(user => user.registered)
Jos Bill olisi mennyt tälle tielle, hän olisi voinut työskennellä meille.
Mikseivät ihmiset turvaudu teoriaan useammin?
Joskus he eivät vain tunne häntä. Useimmiten he ovat liian kiireisiä ottaakseen aikaa oppiakseen tämän tavan ratkaista ongelmia - heidän täytyy vain saada asiat toimimaan. He ovat vaarassa muuttaa tämän lähestymistavan tapaksi, joka tulee esteeksi heidän taitojensa kehittämiselle.
Tällaisten virheiden välttämiseksi aloita aina teoriasta. Ajattele prosessin jokaisessa vaiheessa, mitä tietoja käsittelet. Sen sijaan, että luottaisit jatkuvasti tuttuihin malleihin, harkitse primitiivisiä tietotyyppejä: taulukko, objekti, merkkijono jne. Kun käytät funktiota tai menetelmää, tarkista dokumentaatiosta, että tiedät tarkalleen, mitä tietotyyppejä se tukee, mitä argumentteja se vaatii ja mikä sen tulos on.
Tällä lähestymistavalla voit löytää toimivan ratkaisun ensimmäisellä kerralla. Voit olla varma sen oikeellisuudesta, koska olet nimenomaan valinnut toimintasi annettujen tulo- ja lähtötietojen perusteella. Tutustu kunkin toiminnon perusteisiin (tietotyyppeihin ja palautusarvoihin) epämääräisen liikekielen (kuten "rekisteröityjen käyttäjien") sijaan.
Lähde: www.habr.com
