У чому моя причина провалу тестового завдання яндекса

Всім привіт, недавно вирішив випробувати себе на літнє стажування в Яндекс, як раз канікули будуть. Вчуся в Москві, 2 курс, ніби не дурний. не дуже розумний, однак начебто намагаюся заповнювати свої знання теорією, ось тільки практики не вистачає, інше питання. Виходив з розрахунку, що на стажуванні тебе з сопляка зроблять солдатом, розважливим і холоднокровним, яким зараз не є. Так ось, надіслав заявку, мені вислали завдання:

Питав подробиці, поштою, як конкретно можна вирішувати завдання, не відповідали. Ну, як зрозумів завдання, так і став вирішувати її. Вислав звіти:

Через тиждень відповіли:


Знову ж таки, мені сказали знайомі, що вони тобі не пояснюватимуть як вирішувати задачу, і що ти зробив не так, їх завдання "набір м'яса в Яндекс".

Питання до публіки: Що я не так зробив, що поставило на мені хрест? Може просто бидлокодінгом займаюся, так як виправлятися, що вивчати, і як правильно треба було вирішувати ці завдання? Який досвід з цього можна отримати? Коштував чи взагалі лізти в ці стажування великих компаній, якщо навіть немає бойового досвіду, та й як цей бойовий досвід отримати, коли не беруть до ладу нікуди?

Ну давайте я покритикую:

1) ви не розібралися як оголошувати методи у прототипів з новою нотацією `class`:

2) ви не вмієте користуватися винятками.


3) використання let там де повинен використовуватися const

4) в принципі використання змінних там де їх бути не повинно

5) ви чогось реалізували свою функцію сортування, я не побачив у вимогах відсутності можливості використовувати старий добрий Array.prototype.sort

6) Загальні зауваження по кодинг стайл. snake_case там де повинен бути camelCase, пишіть з великої літери то що повинно бути з маленькою і т.д.

8) Якщо виправити 7-ий пункт то наш клас перетворюється просто в функцію.

Далі. беремо наступний файлик

2) ви чогось тут в прототип об'єкта рядки впихати функції для парсинга CSS. Таким чином ми порушуємо принцип єдиної відповідальності. Та й в цілому розширювати без потреби прототипи об'єктів якось не ок.

Трохи далі проскроліл - ви намагаєтеся розширити прототип рядків для того що б добитися API jquery? ух, батенька.

3) дуже багато дублювання.

4) дуже погано з protected variations.

1) Я так і хотів спочатку зробити, але там не працюють приватні властивості, чому?

class Travelsort let list; // неправильно, проте з точки зору С ++ приватне властивість
constructor () <>
sortTickets (tickets) <>
>

ну да ладно, тоді, якщо в конструкторі оголосити let list. Чому sortTickets () не бачить цю змінну, тому що вона не глобальна, а як її глобальної зробити?

2) Дуже рідко винятками користувався, завжди призначену для користувача обгортку писав, навіть на С ++ чув, що try<> catch () <> теж не завжди використовується через втрату продуктивності.

ValueError - я так зрозумів, наш клас винятків?

3) const там де щось не змінюється, у мене там кожна змінна-масив була схильна до зміни в подальшому, якщо тільки len - змінна розміру масиву, але це теж окремий випадок, звичка var писати залишилася. До того ж, в майбутньому, ми можемо використовувати ту ж змінну len для зберігання розміру іншого масиву.

4) І де ж не повинно бути змінних?

5) Так я ж сортував виключно за словами, придумував свій алгоритм, або стандартна сортування б прокотила? Хм, тоді у мене клас практично порожній був би

6) printError. і sort_ticket?

7) Ну писати він може тільки свій власний приватний список маршрутів, хіба він не може мати інтерфейс виведення? Дивно ..

8) В тому і справа, тоді як треба було вирішувати завдання?

але все ж вирішив потетстіть цей момент, але вже, дуже зручно без назви об'єкта просто в дужках вказати (dom) і застосовувати до нього методи, зручно і працює на прикладі мого рішення СЛАР, і циклів блоків

Ну, а що в цьому поганого конкретно, крім як порушення цілісності базової структури даних? Адже ми з рядками все одно працюємо ..

3) Дублювання багато, але я ж і так в окремі функції все витягав, для кожного нового методу

4) protected variations, а що це таке? і як з цим працювати?

2) так, виключення згубно впливають на продуктивність, але в продакшен коді у вас не повинно взагалі виникати винятків (в ідеалі). Якщо виключення починають впливати на продуктивність js коду - стало бути у вас десь баг.

3) по-перше ви міняли сам масив, а масиви в js зберігаються за посиланням, тобто можна було сміливо використовувати const. По-друге замість мутації стану (до слова забув згадати що stateless завжди краще stateful) можна було просто зібрати новий масив. Та й знову ж повертаємося до пункту 1 - ми не вміємо працювати з об'єктами (властивості, методи, прототип об'єкта)

4) властивості замість змінних.

5) в "стандартну сортування" можна передати функцію сортування, який реалізує ці правила.

6) всі назви функцій і методів - camelCase, конструктори об'єктів (ну або імена класів якщо ми про цукор над Object.create) - CamelCase.

7) він повинен надавати стан, а працювати з document.write повинен хтось інший. Якби це були окремі функції - все було б добре (а це могли б бути просто окремі функції). А так у нас виходить об'єкт з порушенням принципу єдиної відповідальності.

Dave. ну ось давайте міркувати. Вимагати від джуніора розуміння інкапсуляції потрібно чи ні? Або вистачить того що б визначення завчив для соцзабезу?

Не плутайте джуніора і стажиста. Різниця між Джуніором і сіньером по суті буде тільки в тому, що навіть при маєтку розуміння принципів SOLID у першого не з першої спроби виходитиме не порушити випадково ці принципи, і доведеться частіше переробляти і частіше експериментувати.

Це як "навіщо Джуніору вміти тести писати". Саме через такого підходу більшість розробників такі слабкі і можна знайти сотні "сіньеров" які жодного разу не знають що таке технічний борг.

З іншого боку за рахунок цього вартість джуніора така низька, так. Тому що половина з них ще навіть не Джуніор.

А хто небудь намагався вирішити це завдання? Мені ось реально цікаво, як вирішують профі подібні питання.

Máximo progreso hemos alcanzado en minimo seso.

Жесть. Подивився гифку на Гітхабе, там, де весь процес наочно показаний, код навіть не дивився.

Ну ось дивіться, ясно ж, що інформація про маршрути, ось всі ці текстиків, типу, «З Стокгольма на поромі до Риги, каюта 6a ...», це все має генеруватися з даних, а не ручками в textarea писати :)

Вам потрібно було образно придумати, що за АПИ ви будете використовувати і які дані від нього приходять - з цих даних створювати всі записи і весь шлях.

З на до, і інші дані ... - і ще для всього цього потрібна локалізація (не тільки ж на російській тексти будуть), і ще все це потрібно провідмінювати, якщо вже взагалі перфекціоністські робити - погодьтеся, «з Стокгольм до Рига ...» звучить жахливо .

А у вас просто все це пишеться в текстовому полі - тоді вже взагалі потрібно одне текстове поле замість всієї вашої форми і кнопочок, і там оператор напише купу тексту сам, з купою помилок, несистемно :)

Ось зараз візьміть все, що ви зробили, і уявіть, що номер рейсу змінився, або номер сидіння змінився (вас поміняли з кимось, і у вас змінилося місце і в іншої людини) - як ви це обробляти будете? Заходити в кожен маршрут і ручками правити текст в textarea?

А з приводу цих та сортування, елементарно - дані найзвичайніші, звичайний жісончік, масив з об'єктів. Сортування по лівому і правому ключу, nested sets, щоб можна було створювати маршрути будь-якої глибини, наприклад, не просто Рига → Стокгольм, а між ними маршрути по Ризі та маршрути по Стокгольму. ну, як дерево, можна розкрити один маршрут, а там подмаршрути.

1) "Ну ось дивіться, ясно ж, що інформація про маршрути, ось всі ці текстиків, типу,« З Стокгольма на поромі до Риги, каюта 6a ... », це все має генеруватися з даних, а не ручками в textarea писати."

В сенсі? Ми самі ж повинні створювати ці картки. А як ви це зробите, залежить від вас. В інтернеті до мене було багато способів, я вибрав свій ..

2) З на до, і інші дані ... - і ще для всього цього потрібна локалізація (не тільки ж на російській тексти будуть), і ще все це потрібно провідмінювати, якщо вже взагалі перфекціоністські робити - погодьтеся, «З Стокгольм до Рига ...» звучить жахливо.

В тому і справа, що це вже чистої води НЛП, за тиждень без матерів практики таке завдання швидко не вдалося мені зробити. Я намагався вирішити проблему з використанням регулярних виразів:
Як знайти місто в рядку?

Але безрезультатно, всюди були косяки, так все це передбачало наявність строгих вхідних даних.

Тому я вирішив, що строгими вхідними даними будуть тільки інпут ЗВІДКИ і КУДИ, неважливо якою мовою ви пишете, завжди тільки в називному відмінку будуть міста, а інформація про картку була б незалежна, тому не потрібно було парсити текст картки і перевіряти по склонениям, а це вибачте, жорстке завдання, звідси якраз і випливає, що завдання спочатку, в приклад, давали англійською.

У мене був алгоритм сортування по цих самих інпут ЗВІДКИ-КУДИ.

3) Так, у мене все було в textarea, нам же не сказано було, що це все мало б створюватися системним оператором, може це сам мандрівник писав для себе на листку паперу. Напевно, треба було запив простий інтерфейс з СЕЛЕКТА і тд, був би API. Але мені здалося це нудним, тому я зробив сортування по інпут ЗВІДКИ-КУДИ, повторююсь, але сортування мені сподобалася тим, що хоча б працювало ідеально, алгоритм на знаходження шляхів в орієнтованому графі. А це для мене було досягненням. Мабуть, ускладнив.

4) "Ось зараз візьміть все, що ви зробили, і уявіть, що номер рейсу змінився, або номер сидіння змінився (вас поміняли з кимось, і у вас змінилося місце і в іншої людини) - як ви це обробляти будете? Заходити в кожен маршрут і ручками правити текст в textarea? "

Ну мені ж таки не ТЗ писали, а формальну постановку задачі поставили, на реальній роботі, все це б обговорювалося з тімліда, і він би точно поставив би формальні рамки і висвітлив би підводні камені для того, щоб проект був в ідеальному стані.

5) В моєму випадку, був звичайний js-масив, json-чик теж саме практично.

wkololo_4ever. так ніби я написав: є що входить чергу, є сортування. Немає зв'язки - створюємо нову ланцюжок. Після приєднання картки до ланцюжку - перевіряємо початок-кінець всіх інших ланок: якщо є зв'язка - приєднуємо один ланцюжок до іншої. І беремо нову картку з вхідної черги. І так до тих пір, поки не закінчиться входить чергу.
У підсумковій сортуванні буде одна (якщо все картки взаємопов'язані через початковий і кінцевий пункти) або кілька ланцюгів (якщо є незв'язані між собою картки, наприклад - "втрачені").