Escola de desenvolupament d'interfícies: anàlisi de tasques per a Minsk i un nou conjunt a Moscou

Avui s'ha obert una nova matrícula Escola de desenvolupament d'interfícies Yandex a Moscou. La primera fase de formació es farà del 7 de setembre al 25 d'octubre. Els estudiants d'altres ciutats podran participar-hi de manera remota o presencial: l'empresa pagarà el viatge i l'allotjament en un alberg. La segona, també darrera fase, s'allargarà fins al 3 de desembre, només es podrà fer presencialment.

Em dic Yulia Seredich, vam escriure aquesta publicació juntament amb Sergei Kazakov. Tots dos som desenvolupadors d'interfícies a l'oficina de Minsk de Yandex i llicenciats en SRI d'anys anteriors.

Escola de desenvolupament d'interfícies: anàlisi de tasques per a Minsk i un nou conjunt a Moscou

Amb motiu de l'obertura de la matrícula a Moscou, estem publicant una anàlisi de les tasques d'introducció a l'escola anterior, aquí a Minsk.

Si rastreges l'historial de les tasques SRI, d'any en any vam provar tres habilitats importants per a un programador:

  • Disseny. Cada desenvolupador hauria de ser capaç de fer el disseny. No passa que tinguis l'oncle Seryozha que dissenya per a tot l'equip, i només escriviu guions. Per tant, cada alumne ha de mostrar com sap com escriure.
  • JavaScript. Si l'assumpte es limités a la maquetació, no tindríem una escola de desenvolupament d'interfícies, sinó una escola de dissenyadors de maquetació. La interfície bellament dissenyada s'ha de reviure. Per tant, sempre hi ha una tasca per a JS, però de vegades també és una tasca per als algorismes: els estimem molt.
  • La resolució de problemes és potser l'habilitat més important d'un desenvolupador. Quan es tracta de crear interfícies, les coses estan canviant molt ràpidament. És com Lewis Carroll: "Has de córrer tan ràpid com puguis per quedar-te al mateix lloc, i per arribar a un altre lloc has de córrer el doble". Cada dia ens trobem amb noves tecnologies, les hem de tenir en compte i ser capaços d'entendre-les. Per tant, a la tercera tasca, vam proposar entendre tecnologies amb les quals un desenvolupador novell normalment no està familiaritzat.

En l'anàlisi de cada tasca, us explicarem no només el procediment correcte, sinó també els errors comuns.

Tasca 1: Cartera

La primera tasca la van treballar el dissenyador de Yandex.Collections Alexey Cherenkevich, que sap com fer maquetació, i el seu company de servei, el desenvolupador d'interfícies Sergey Samsonov.

Condició

Crea una web de portfolio: parla'ns de tu, de la teva feina i de les teves expectatives de l'Escola. El lloc ha de correspondre tant com sigui possible al disseny proposat (enllaços a maquetes: 1000px, 600px, 320px, especificació). Només ens interessa el disseny, així que no utilitzeu JavaScript.

A l'hora de comprovar tindrem en compte:

  • mides de sagnat, correcció del color, estil de lletra, mida de lletra;
  • disposició semàntica;
  • la presència de diferents estats d'elements: visualització de botons i enllaços en moure el cursor, ressaltar camps d'entrada actius, etc.;
  • compatibilitat entre navegadors (provat a les últimes versions dels navegadors populars).

L'avantatge serà:

  • ús de solucions CSS modernes: flexbox, grid, etc.;
  • Disseny adaptatiu;
  • ús de pre i (o) postprocessadors, muntatge, minificació, optimització del codi de sortida;
  • Validació de formularis HTML, botó de càrrega de fitxers estilitzat.

La tasca és bastant voluminosa, de manera que podeu saltar allò que no funcionarà. Això reduirà lleugerament la vostra puntuació, però encara podreu demostrar els vostres coneixements. Quan hàgiu acabat, envieu-nos dos enllaços: a la vostra cartera i al codi font a GitHub.

Els dissenys proposats a l'encàrrec no eren només amb pantalles per a dispositius mòbils, tauletes i ordinadors de sobretaula, sinó també amb especificacions reals.

Per tal d'aportar la màxima objectivitat possible al resultat de la comprovació de la primera tasca, hi havia molts criteris per a aquesta comprovació.

criteris

Web dissenyada. Això sembla obvi, però alguns nois es van saltar alguns blocs completament: o volien estalviar temps o no els van poder fer. El disseny es pot dividir aproximadament en quatre pantalles principals: la pantalla principal amb un avatar, un bloc amb una llista d'expectatives de SRI, un bloc amb una cartera i un bloc amb informació de contacte. Es podien fer per seccions o simplement utilitzant divs, el més important és que els quatre blocs estaven disponibles.

Compliment de la maquetació amb la maquetació. El dissenyador va fer una especificació independent (incloent colors, tipografia, estats de botons, etc.) per facilitar-ho als candidats. A la part inferior hi havia una pista sobre les sagnies i les característiques de la primera pantalla. Vaig estar molt satisfet amb els nois que van tenir en compte tots els desitjos del dissenyador: per exemple, la primera pantalla hauria d'haver estat ni més ni menys que l'alçada del visor.

Disseny adaptatiu - és quan la interfície no només està dissenyada de manera que a tres resolucions tot sigui píxel a píxel en la disposició. En estats intermedis, el disseny tampoc s'ha de trencar. Alguns es van oblidar de limitar l'amplada màxima del contenidor i ho van establir tot a 1920 píxels, alguns van desordenar els fons, però en general els candidats van fer front bé a aquesta tasca.

Disseny semàntic. "Quantes vegades li han dit al món" que l'enllaç s'ha de dissenyar com , el botó - com . Afortunadament, la majoria dels candidats també van complir aquest requisit. No tothom va reconèixer la llista oculta a les expectatives de l'SRI, fent-la servir etiquetes div, però no és tan dolent. Hi havia un candidat que va inserir totes les etiquetes semàntiques que coneixia, on era necessari i on no. Per exemple, en lloc d'una llista - i . Al cap i a la fi, la semàntica: es tracta d'entendre la composició de la vostra pàgina i el propòsit de cada bloc (la majoria ho gestionava aquí), així com l'ús de pre i/o postprocessadors (alguns ho van gestionar aquí, tot i que això també estava en els punts - la majoria de vegades utilitzaven menys i scss) .

Control lliscant de treball. A la tasca vam escriure que no es pot utilitzar JS. Aquí es va provar la capacitat de resoldre problemes: es podria fer un control lliscant amb un munt I . Tota la màgia passa al nivell del selector #button-N:checked ~ .slider-inner .slider-slides. Quan fem clic a una de les caselles de selecció d'entrada, passa a l'estat marcat. Podem aprofitar-ho i assignar la traducció que necessitem al contenidor amb les diapositives: transform: translate(-33%). Podeu veure la implementació del control lliscant aquí.

Llistes desplegables. Aquí també es va reduir tot i un selector similar: .acordion-item input:marcat ~ .accordion-item__content. Podeu veure la implementació aquí.

Disponibilitat dels estats :hover, :active i :focu*. Un punt molt important. La comoditat durant la interacció amb la interfície en depenia. L'usuari ha de rebre sempre comentaris sobre les seves accions. Aquest ítem es va comprovar al llarg de la interacció amb el qüestionari. Si he fet clic al botó "Truca'm" i visualment no ha passat res (tot i que s'ha enviat la sol·licitud), això és dolent, perquè després hi faré clic una i altra vegada. Com a resultat, s'enviaran deu peticions i em tornaran a trucar deu vegades. No hem d'oblidar que els dispositius mòbils no tenen ratolí, la qual cosa significa que no hi hauria d'haver un ratolí. I un punt més que no va afectar els que van complir el punt sobre la semàntica. Si el vostre control no és un element interactiu, quan passeu el cursor per sobre, el cursor es mantindrà estàndard. Sembla molt desordenat, encara que hagis escrit una reacció per passar el ratolí. No subestimeu cursor: punter.

Animacions. És important que totes les reaccions que es produeixin amb els elements siguin suaus. Res a la vida és instantani, així que tenir transicions al ratolí i actives va ser suficient per fer la interfície més agradable. Bé, els que han animat el control lliscant i les llistes són generalment fantàstics.

Utilitzant l'última tecnologia. Molta gent va utilitzar flex, però ningú va completar la tasca amb graella. El punt es va comptar si s'utilitzava correctament flex. Si en algun lloc el disseny es va trencar a causa d'aquestes mateixes flexions, per desgràcia, no vau rebre cap punt addicional.

Validació de formularis. Tot el que calia era afegir l'atribut requerit a cada entrada del formulari. Hem afegit punts als que han validat el camp de correu electrònic com a correu electrònic.

Estil el botó de càrrega de fitxers. Esperàvem veure una combinació com: i Seleccioneu el fitxer . A continuació, havíem d'amagar l'entrada i estilitzar l'etiqueta. Hi ha una altra manera habitual: fer una entrada transparent i posar-la a la part superior del botó. Però no tots els navegadors permeten l'estil , i aquesta solució no es pot anomenar completament entre navegadors. I semànticament és més correcte fer una etiqueta.

Compatibilitat entre navegadors. Hem comprovat que tot anava bé a les dues últimes versions dels navegadors moderns (sense IE: els participants van tenir sort), així com a Safari en iPhone i Chrome a Android.

Al contrari, deduïm punts si algú feia servir JS o Bootstrap: tots dos anirien derrotant el propòsit de tota la tasca. A més, els participants amb Bootstrap no només van rebre un negatiu, sinó que també van perdre molts punts per la semàntica i els elements implementats.

Els que allotjaven el seu lloc en algun lloc d'Internet no van rebre cap avantatge particular, però els revisors estaven molt contents quan no havien de descarregar dipòsits i executar-los localment al seu ordinador. Així que això va servir com un avantatge per al karma.

La primera tasca va ser molt útil principalment per a l'alumne. Aquells que no vam acceptar ara tenen un currículum preparat; podeu adjuntar-lo amb orgull a totes les respostes o publicar-lo a les vostres pàgines gh.

Tasca 2: Ruta de transport

L'autor de la tasca és el cap del grup d'interfícies de cerca Denis Balyko.

Condició

Tens un mapa d'estrelles? Mostra el nom de cada estrella, així com la distància d'aquesta a altres estrelles en segons llum. Implementar la funció de solució, que hauria de prendre tres arguments: un objecte en què les claus són els noms de les estrelles, i els valors són les distàncies a les estrelles (trànsit unidireccional a l'espai), així com els noms de les estrelles. els punts d'inici i final del camí: inici i final, respectivament. La funció hauria de retornar la distància més curta des de l'estrella inicial fins a l'estrella final i el camí a seguir.

Signatura de la funció:

const solution = function(graph, start, finish)  {
    // Ваше решение
} 

Dades d'entrada d'exemple:

const graph = {
  start: { A: 50, B: 20 },
  A: { C: 40, D: 20 },
  B: { A: 90, D: 90 },
  C: { D: 160, finish: 50 },
  D: { finish: 20 },
  finish: {}
};
const start = 'start';
const finish = 'finish'; 

Exemple de sortida:

{
    distance: 90,
    path: ['start', 'A', 'D', 'finish']
} 

Nota: l'esquelet de la solució es troba a la carpeta src/, poseu la vostra solució a solution.js.

La verificació de la segona tasca va ser la més automatitzada i objectiva. La majoria dels nois van endevinar que era necessari implementar l'algoritme de Dijkstra. Els que han trobat la seva descripció i han implementat l'algorisme a JS estan ben fets. Tanmateix, en comprovar el treball, ens hem trobat amb molts treballs amb els mateixos errors. Hem cercat a Internet fragments de codi i hem trobat un article del qual els participants copiaven l'algorisme. És curiós que molta gent hagi copiat el codi de l'article juntament amb els comentaris de l'autor. Aquests treballs van rebre una puntuació baixa. No prohibem l'ús de cap font, però volem que una persona aprofundeixi en el que escriu.

criteris

Es van atorgar punts principals per a les proves. De vegades era evident que els nois estaven fent un embolic amb el dipòsit, canviant el nom de les carpetes i que les proves fallaven simplement perquè no podien trobar els fitxers necessaris. Aquest any hem intentat ajudar aquests tipus i els hem tornat tot al seu lloc. Però l'any que ve tenim previst canviar a un sistema de concursos, i això ja no es perdonarà.

També hi havia criteris “humans”, manuals. Per exemple, la presència d'un únic estil de codi. Ningú va restar punts per utilitzar tabulacions en lloc d'espais o viceversa. Una altra cosa és si alterneu cometes simples amb cometes dobles segons una regla que coneixeu i col·loqueu punt i coma a l'atzar.

La claredat i la llegibilitat de la solució es van tenir en compte per separat. A totes les conferències del món diuen que el 80% de la feina d'un programador consisteix a llegir el codi d'altres persones. Fins i tot els escolars se sotmeten a revisions de codi, dels seus comissaris i dels altres. Per tant, aquest criteri va tenir un pes important. Hi ha hagut obres en què no hi havia variables més llargues d'un caràcter; si us plau, no ho feu. Els comentaris dels participants van ser molt encoratjadors, a excepció dels que eren idèntics als comentaris de Stella Chang.

L'últim criteri és la presència d'autotests. Només unes poques persones els van afegir, però per a tothom es va convertir en un gran avantatge en el seu karma.

La decisió correcta:

const solution = function(graph, START, FINISH)  {
    // Всё не бесплатно в этом мире
    const costs = Object.assign({[FINISH]: Infinity}, graph[START]);

    // Первая волна родительских нод
    const parents = { [FINISH]: null };
    Object.keys(graph[START]).reduce((acc, child) => (acc[child] = START) && acc, parents)

    const visited = [];
    let node;

    // Ищем «дешёвого» родителя, отмечаем пройденные
    do {
        node = lowestCostNode(costs, visited);
        let children = graph[node];
        for (let n in children) {
            let newCost = costs[node] + children[n];

            // Ещё не оценена или нашёлся более дешёвый переход
            if (!costs[n] || costs[n] > newCost) {
                costs[n] = newCost;
                parents[n] = node;
            }
        }
        visited.push(node);
    } while (node)

    return {
        distance: costs[FINISH],
        path: optimalPath(parents)
    };

    // Возврат назад по самым «дешёвым» родителям
    function optimalPath(parents) {
        let optimalPath = [FINISH];
        let parent = parents[FINISH];
        while (parent && parent !== START) {
            optimalPath.push(parent);
            parent = parents[parent];
        }
        optimalPath.push(START);
        return optimalPath.reverse();
    }

    // Минимальная стоимость из текущей ноды среди непросмотренных
    function lowestCostNode(costs, visited) {
        return Object.keys(costs).reduce((lowest, node) => {
            if (lowest === null || costs[node] < costs[lowest]) {
                if (!visited.includes(node)) {
                    lowest = node;
                }
            }

            return lowest;
        }, null);
    };
};

Tasca 3: Calendari d'esdeveniments

Va ser preparat pels desenvolupadors d'interfícies Sergey Kazakov i Alexander Podskrebkin.

Condició

Escriu un mini-calendari per mostrar la teva agenda. Pots agafar qualsevol horari que vulguis. Per exemple, el calendari de conferències de frontend el 2019.

El calendari hauria de semblar una llista. No hi ha altres requisits de disseny. Fes possible configurar recordatoris d'esdeveniments amb 3, 7 i 14 dies d'antelació. Després de la primera descàrrega d'Internet, el calendari hauria d'obrir-se i funcionar fora de línia.

Recursos útils

Horari de conferències de front-end:
confs.tech/javascript?topics=javascript%2Bcss%2Bux

Treballadors del servei:
developer.mozilla.org/ru/docs/Web/API/Service_Worker_API/Using_Service_Workers
developers.google.com/web/fundamentals/primers/service-workers

API de notificacions:
developer.mozilla.org/ru/docs/Web/API/Notifications_API

La tercera tasca va ser la més interessant de provar, perquè hi havia tantes solucions possibles, cadascuna amb la seva. Hem comprovat com el candidat maneja tecnologies desconegudes: si sap investigar, si prova les seves solucions.

criteris

Calendari plegat. Sí, encara s'havia de posar. També hi va haver qui va prendre la condició massa literalment i no va inserir ni una línia de codi CSS. No semblava gaire atractiu, però si tot funcionava, els punts no baixaven.

Obtenció d'una llista d'esdeveniments d'una font. Aquesta no és una tasca de disseny, de manera que la llista d'esdeveniments inclosos en ella no s'ha comptat. Sempre podeu cancel·lar una conferència, reprogramar-la o afegir-ne una de nova. Per tant, era necessari rebre dades de l'exterior i representar el disseny basat en el JSON rebut. Era important obtenir les dades de qualsevol manera (utilitzant el mètode fetch o utilitzant XMLHttpRequest). Si una persona afegia un polyfill per a la recuperació i marcava la seva elecció al readme, això es comptava com un avantatge.

Registre dels treballadors del servei sense errors i treballar fora de línia després de la primera descàrrega. Aquest és un exemple treballador de servei amb memòria cau de programació al primer arrencada. Els detalls sobre els treballadors del servei, les seves capacitats i les maneres de treballar amb ells (estratègies per treballar amb memòria cau, treballar fora de línia) es poden trobar aquí.

Possibilitat d'establir un recordatoride manera que realment funcioni després de 3, 7, 14 dies. Calia entendre l'API de notificacions, enllaç al qual tenia raó a la tasca. No esperàvem cap implementació específica per comprovar si és hora d'impulsar. S'acceptava qualsevol opció de treball: emmagatzematge a localStorage, IndexDB o sondeig periòdic per part d'un treballador del servei. Fins i tot va ser possible fer un servidor push (aquí exemple), però no funcionaria fora de línia. Era igualment important rebre una empenta després de tancar la pàgina i obrir-la després d'un temps. Si el recordatori va morir al mateix temps que es tancava la pàgina, la solució no es comptava. És genial quan els nois van pensar en els revisors i van fer possible obtenir una empenta ara mateix, per no esperar 3 dies.

Possibilitat de col·locar una icona a l'escriptori (PWA). Hem comprovat la presència del fitxer manifest.json amb les icones correctes. Alguns nois van fer aquest fitxer (o el van deixar generat a CreateReactApp), però no van afegir les icones correctes. Aleshores, quan es va intentar instal·lar, es va produir un error com "Es necessita una icona diferent".

Estil de codi i estructura del projecte. Com en la segona tasca, vam mirar un únic estil de codi (encara que no coincideixi amb el nostre). Alguns nois s'enfonsen els linters, això és genial.

Errors de consola. Si hi havia un indicador a la consola que hi havia alguna cosa malament i el participant no hi va prestar atenció, vam restar punts.

Resultats de

Què és curiós de les decisions dels participants:

  • Un qüestionari contenia el text següent: “Un amic programador em va ajudar a crear una aplicació React. El vaig bombardejar amb preguntes sobre com i per què, i em va dir. M'ha agradat molt, vull saber-ne més". Estàvem recolzant aquesta aplicació amb tot el cor, però, malauradament, l'amic del candidat no va ser molt útil per fer que l'aplicació funcionés.
  • Un candidat va enviar un enllaç a GitHub, on es trobava l'arxiu RAR; és difícil comentar-ho. 🙂
  • Un altre candidat, en el comentari de la primera línia del fitxer solution.js, va admetre sincerament que va copiar l'algorisme.

Vam rebre sol·licituds de 76 candidats i vam seleccionar 23 persones. Ens van enviar qüestionaris no només des de Minsk, sinó també des de Moscou, Sant Petersburg i fins i tot Tatarstan. Alguns dels nois ens van sorprendre amb les seves professions actuals: un d'ells és perito forense i l'altre és estudiant de medicina.

El resultat va ser una distribució interessant de les taxes d'èxit en la realització de tasques. Els participants van completar la primera tasca en un 60% de mitjana, la segona en un 50% i la tercera va resultar ser la més difícil i es va completar en un 40% de mitjana.

A primera vista, les tasques semblen complexes i requereixen temps. La raó no és que volem eliminar tants candidats com sigui possible. Durant els seus estudis, els estudiants s'enfronten a tasques de la vida real: fer un xat, Yandex.Music per a nens o Yandex.Weather per a persones dependents del clima. Per a això necessiteu una base de partida.

Recordo haver vist la meva tasca d'entrada a l'SRI fa dos anys i vaig pensar que no la resoldria mai. El més important en aquest moment és seure, llegir atentament les condicions i començar a fer-ho. Resulta que les condicions contenen gairebé el 80% de la solució. Per exemple, en la condició de la tercera tasca (la més difícil), vam afegir enllaços als treballadors del servei i l'API de notificacions a MDN. Els alumnes que van estudiar els continguts dels enllaços el van completar sense dificultat.

M'agradaria molt que llegeixin aquest article els candidats que tenen previst entrar a l'SRI en el futur, que no han pogut entrar a l'escola de Minsk o que estan començant a fer qualsevol altra tasca de prova. Com podeu veure, és molt possible fer-ho. Només cal creure en tu mateix i escoltar tots els consells dels autors.

Font: www.habr.com

Afegeix comentari