- PVSM.RU - https://www.pvsm.ru -
Хотелось бы поделиться своей историей неудачи, если понимать под этим негативный фидбек от компании после ревью технического задания. Конечно же, каждый подобный опыт — это всегда прекрасная возможность пересмотреть стратегию, сделать определенные выводы из своих или чужих ошибок. И в данном случае, у меня есть отличный повод порефлексировать над пережитым опытом интервью, даже несмотря на то, что он не закончился оффером. Хочу заранее выразить свою благодарность за время, которое вы потратите на чтение этой статьи с кодом и усилия, приложенные на их понимание. Хочу выразить двойную благодарность, если при этом читатель поделится своим мнением.
Весь исходный код доступен в публичном репозитории на GitHub по этой ссылке [1]. Он не претерпевал никаких изменений с момента публикации, несмотря на то что в нём есть ряд моментов, которые я бы довел до ума, но намеренно не стал этого делать. Всегда есть некая договоренность с самим собой относительно времени, которое мы тратим на задание. Пытаемся расставить приоритеты, исходя из личных предпочтений, если иное не было подчеркнуто в требованиях к заданию: кто-то предпочтёт написать документацию на свои API, а кто-то решит увеличить покрытие тестами. В моём случае, как вы можете заметить, нет e2e тестов и unit тестов UI компонентов, также CSS накидан на скорую руку и не следует никакой методологии. Вполне вероятно, вы можете продолжить этот список и другими недочетами.
Будучи под впечатлением от профиля одной компании, подкрепив это отзывом одной бывшей коллеги, работавшей там когда-то, я решил отправить туда своё резюме и начать процесс собеседования. Через неделю-две со мной связался рекрутер и предложил пообщаться с лидом одной из команд. Разговор с лидом больше сводился к общим вопросам: что вам нравится, какие технологии используете, чем гордитесь, какие проблемы решали, также было оставлено место и для моих вопросов, — совершенно обычный разговор, вполне типичный для IT компании. Спустя некоторое время этого же дня мне сбросили задание. Ниже я напишу требования этого задания. Текст задания сохранен в оригинале:
Вам предлагается написать сервис для совместной игры в крестики-нолики.
Игра содержит несколько игровых полей, каждый игрок может либо присоединиться к игре на существующем поле, либо создать новое поле.
Начальный экран содержит список игровых полей и их краткое описание (сколько игроков сейчас играет, когда был последний ход). Данные обновляются в реальном времени.
Игровое поле имеет фиксированный размер 10 x 10. На каждом поле могут играть несколько игроков. Каждый игрок может сделать ход в любой момент, но не может сделать несколько ходов подряд.
Игровой сервер может хранить состояние игрового процесса в памяти.
Решение вы можете реализовать на любых удобных вам технологиях, но будет здорово если вы сделаете их на [обозначены технологии проекта]
Я решил делать на удобных мне технологиях. В качестве языков были выбраны: Java и Javascript. В качестве фреймворков: Spring и React. Хранение состояния осуществляется в памяти как и позволено в задании.
Буквально за неделю до этого, я делал техническое задание для другой компании, где так же фигурировала игра, но с другой логикой. Игра называлась Калах [2]. Архитектура, которую я заложил для неё, и принципы, которым следовал, показались мне вполне уместными и здесь. И вообще, кажутся уместными для реализации простых игр в целом. Какие основные приоритеты я ставил для себя при решении задачи:
— это и есть основные принципы, которые получили своё отражение в реализации.
Из особенностей серверного кода, отмечу, что для защиты от race conditions используется мапа ReentrantLock’ов — на игровую сессию свой ReentrantLock. Реализацию синхронизации с клиентским временем я решил не делать, а просто генерировать время хода на сервере.
После первого фидбека относительно UX с предложением поправить и добавить некоторые вещи, я также решил переписать фронтенд на функциональных компонентах с хуками. Давно хотелось прощупать этот подход и он мне понравился. Авторы reactjs в документации подчеркивают, что этот подход минимизирует кол-во ошибок совершаемых программистами, связанных с жизненным циклом компонента при использовании стиля, основанного на классах и callback'ах — и, мне кажется, это важный момент. И если вы ещё не используете новый подход в своей работе — я рекомендую вам его попробовать.
Нижеприведенный фидбек я получаю неделю спустя:
Мы с коллегами внимательно посмотрели новый вариант задания.
По результатам я решил дальше не продолжать процесс.
Ниже фидбек по заданию от нас:
— код запутан, понимать сложно, гораздо сложнее, чем могло бы быть
- оверинжиниринг в части frontend, цитирую нашего frontend разработчика…
Видимо задание сделано на тех технологиях, которые знал кандидат, хотя мы никакого redux и redux-saga не просили при этом CSS, который руками написан – там просто заоверрайжены стили из библиотеки это плохой способ писать CSS
…С учетом сложности codebase в нашем продукте нам важно, чтобы простые вещи кандидат делал просто.
Спасибо Вам за время и усилия!
Конечно, хотелось бы иметь концептуальную дискуссию, иметь возможность защитить те или иные решения. Я принимаю комментарий относительно CSS, но совершенно не понимаю остальных. Оверинжиниринг ли это? Или я столкнулся с технической незрелостью интервьюеров? В принципе, здесь любая оценка будет очень субъективна и по-своему имеет место на существование.
Задумываясь над смыслом вопроса — Что такое сложный код? Мне кажется, что ответ на этот вопрос очень простой: это код который сложно читать и сложно менять. Я, как и многие, предпочитаю думать, что мы пишем код для людей, а не для машин. И стараюсь оставить место для мыслительного процесса о композиции кода перед тем как садиться за его написание. Действительно ли проделанная мною композиция усложняет чтение этого кода и претендует на клеймо — оверинжиниринг? Мнение по этому вопросу я бы с интересом увидел в ваших комментариях.
Автор: Виталий
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/354293
Ссылки в тексте:
[1] ссылке: https://github.com/itallix/noughts-crosses
[2] Калах: https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%BB%D0%B0%D1%85
[3] Spring Rest Docs: https://spring.io/projects/spring-restdocs
[4] TurnRule: https://github.com/itallix/noughts-crosses/blob/master/server/src/main/java/io/karniushin/tictactoe/core/service/handler/rule/DefaultTurnRule.java
[5] EndGameRule: https://github.com/itallix/noughts-crosses/blob/master/server/src/main/java/io/karniushin/tictactoe/core/service/handler/rule/DefaultEndGameRule.java
[6] набор кастомных итераторов: https://github.com/itallix/noughts-crosses/tree/master/server/src/main/java/io/karniushin/tictactoe/core/service/handler/rule/condition
[7] Источник: https://habr.com/ru/post/507684/?utm_source=habrahabr&utm_medium=rss&utm_campaign=507684
Нажмите здесь для печати.