Как мне сообщить кому-то о серьезных недостатках программирования, чтобы они не приняли это на свой счет?

Я разработчик со стажем всего пару лет, работаю в небольшой компании из восьми разработчиков над Java-проектом. Руководитель нашей группы, также один из менеджеров, старше и очень продуктивен, и говорит, что у него около пятнадцати лет опыта работы с Java.

В прошлом месяце, когда мы обсуждали некоторые написанные им модули с исходным кодом, я заметил в исходном коде, что один класс переопределяет метод equals(), но не метод hashCode()— я имею в виду два метода, объявленных в самом базовом классе Java Object. Когда я очень спокойно и вежливо указал на это руководителю группы, он отрицал, что класс должен переопределять оба метода. На этом проблема закончилась бы, но я счел аморальным позволять такому недостатку (багу) портить продукт позже.

Через несколько дней я подошел к нему лично и наедине и спокойно, без неуважения, объяснил ему проблему и использовал внешние ссылки (например, книгу Джошуа Блоха «Эффективная Java»). Ну, он сказал, что посмотрит на это, и в конце концов он это сделал. Однако с тех пор он относится ко мне холодно.

Хуже того, недавно я увидел серьезную проблему в исходном коде. Некоторые написанные им классы реализуют Serializableинтерфейс, но поле serialVersionUIDне является фиксированным (постоянным) числом. Вместо этого он меняется. Я имею в виду, что мы получаем разные числа каждый раз, когда запускаем приложение.

Опять же, с мотивацией предоставления нормального продукта, я хотел бы сообщить об этом должным образом. Но я не знаю, как правильно это сделать, чтобы он не принял это на свой счет. Видите ли, мои предыдущие подходы не увенчались успехом. Как я мог это сделать?

Любой совет приветствуется.

Редактировать: цель этого вопроса — найти эффективные, продуктивные, вежливые, уважительные, совместные способы сообщить об улучшениях по поводу серьезных проблем с кодом, а не ставить под сомнение авторитетные или управленческие решения, принятые коллегами или даже начальниками.

Какие реальные, а не теоретические проблемы вызывают эти проблемы в вашем коде?
Если этот парень основывает свою информацию на одной единственной книге, то это плохо. Задайте вопрос относительно кода Java на SO. По крайней мере, там вы получите гарантию от экспертов по Java, что правильно, а что нет.
@Philip Описанные проблемы - это те, которые часто могут не приводить к реальным ошибкам, но если / когда они приводят к ошибкам, их обычно трудно исправить. Даже если бы это было не так, этот вопрос в равной степени относится к вопросам стиля и чистоты кода; не имеет значения, были ли обнаружены фактические ошибки.
Как долго ваш коллега относился к вам «холодно»? Похоже, вы смогли убедить его, так что, возможно, вы не были столь неудачливы, как вы думаете — просто может потребоваться некоторое время, чтобы его гордость восстановилась.
@PhilipKendall Меня больше интересует эффективное информирование о некоторых проблемах, не причиняющее никакого вреда ему (или команде и продукту). Тем не менее, в будущем план состоит в том, чтобы некоторые объекты передавались через JMS между разными компьютерами/JVM.
@Rob Спасибо за ваш вклад - эта ситуация длится уже два месяца. Опять же, может быть, я должен просто немного подождать, как вы предлагаете
«Я заметил в исходном коде, что один из методов переопределения классов равен, но не метод hashCode». -- если вы хотите эффективно объяснить программисту, почему что-то подобное является плохим, найдите случаи реальных ошибок в коде, которые могут быть напрямую связаны с этой плохой практикой. Тогда вы можете определенно сказать: «Если мы примем практику X, ошибок этого типа не будет».
Вам не нужно перезаписывать хеш-функцию, если объекты, сравнивающие равные, имеют одинаковый хеш-код. Если класс A сравнивает имена и хеширует имена, а подкласс B сравнивает имена и имена, старый метод хеширования будет работать нормально. Вам также не нужно перезаписывать хэш-функцию, если она никогда не используется.
@Brandin Итак, я думаю создать тестовый пример или даже мини-программу, чтобы доказать эту проблему. Это было бы здорово - если бы мне разрешили фиксировать время на часах и так далее (но ладно, я всегда могу сделать это во время сверхурочной работы, если это необходимо). Тем не менее, я действительно не хочу, чтобы эти проблемы появлялись после доставки и были обнаружены клиентами. Спасибо.
@pek Лучше всего было бы найти реальную доказуемую ошибку, зарегистрировать ее в системе отслеживания ошибок, исправить ее, а затем указать. Эй, я исправил ошибку № 1234. Если мы всегда будем делать X, подобные ошибки больше не повторятся. Я рекомендую сделать его частью стандарта кодирования с этого момента. Остальное действительно зависит от руководства команды.
@ gnasher729 Спасибо за ответ. Наследование в нашем случае не при чем. Каждый из наших классов будет наследоваться только от класса Object (как всегда). Однако у нас есть набор экземпляров этих классов.
@Brandin [Кому: Лучше всего было бы... ] Верно, верно. Вы абсолютно правы, что реальная демонстрируемая ошибка является лучшим доказательством. Большое спасибо
Вы используете ТДД? Если вы можете создать тест-кейс, который провалится, у вас будет единственная ошибка, которая вам нужна, и вы перенесете дебаты из его кода в ваш тест-кейс. Это больше похоже на то, что вы заинтересованы в тщательности, а очень продуктивным программистам часто (не всегда) не хватает этой тщательности. Процесс TDD или, по крайней мере, тестовые примеры будут использовать процесс для замены (потенциально) вредных привычек.
@gnat Я думаю, что это не так, и, честно говоря, спасибо, что указали на другую тему - это помогает избежать недоразумений. Только что тоже сделал правку. Большое спасибо
@ jimm101 Спасибо, что затронули тему TDD. К сожалению, нет. Но я чувствую, что ваш комментарий очень хорошо дополняет комментарии Брандина выше. Спасибо
@pek: Интересно, потому что набор не должен работать, если у вас есть два разных указателя на объект, где объекты сравниваются равными.
Есть ли что-нибудь, что вы заметили за последние 2 года, что дает вам какое-то понимание или вызывает беспокойство? Вы когда-нибудь видели, чтобы кто-то другой противоречил этому человеку? Вам удобно спрашивать?
Наличие другого идентификатора serialVersionID для каждого прогона допустимо, если сериализованные объекты повторно используются только в этом прогоне. Если это так, может быть лучше, если версии будут меняться при каждом запуске.
hashCode полезен только для целей производительности при использовании hashSet/HashMap и подобных объектов, если хэш-код, если он один и тот же, будет выполняться equals(). Для серийного номера: я не ставлю его, я просто добавляю Serializable, чтобы разрешить сериализацию в JSON, и JSON не использует эту переменную, это только для сырой сериализации java, которая блокирует связь только между приложением java. Если старший делает что-то плохое, это должно быть не то, что он не нашел hashCode/serialNumberId, объяснив вам, почему они вам не нужны.

Ответы (12)

Общее напоминание: всегда лучше избегать критического или лекционного тона. Либо сделайте это простым наблюдением («вы, кажется, забыли реализовать здесь хэш-код»), либо задайте вопрос («есть ли причина, по которой вы не реализовали хэш-код?»). Позвольте их ответным реакциям вести дискуссию о том, почему это важно, если это необходимо, но начните с предположения, что они знают принципы и что странность была либо простой оплошностью/опечаткой, либо имела за собой какую-то рациональную причину, которую можно обсудить, а не обсуждать. избили.

Люди слушаются лучше, если вы относитесь к ним с уважением.

И помните, иногда непонимание будет вашим. Таким образом вы опозорите себя гораздо меньше, чем если сделаете более категоричное или дидактическое заявление.

Подход к вопросу очень хороший!
@keshlam Правда, вы правы в трех темах, которые вы затронули в своем подробном ответе. В частности, первый абзац, идея следовать «подходу, основанному на вопросах», открывает совершенно новый взгляд на тему и на методы общения в более общем плане. Действительно, большое спасибо
Такие вопросы, как «Есть ли причина, по которой вы не внедрили хэш-код?» очень хорошо работают, когда имеешь дело с преднамеренными бездельниками; но они имеют тенденцию иметь неприятные последствия, когда имеют дело с людьми, которые чувствуют себя перегруженными (либо потому, что они борются, либо у них слишком много дел). Это заставит их занять оборонительную позицию и, вероятно, вызовет трения. Вопрос по своей сути указывает на их ошибку и просит их оправдать ее. Сформулировано любезно, но требуемый ответ не прост и предполагает приписываемую вину.

Возможно, взглянув на это с другой точки зрения, вы получите лучшее представление.

Я руководитель группы, а также менеджер в небольшой компании из восьми разработчиков. У меня 15 лет опыта программирования на Java. В моей команде появился один новый человек, который намного моложе меня и имеет всего пару лет опыта.

В прошлом месяце, когда мы обсуждали некоторые модули исходного кода, которые я написал, он начал принижать мой код. Несмотря на то, что у него гораздо меньше опыта, чем у меня, он утверждал, что видел ошибки в коде, который работал совершенно нормально. После короткого спора мне показалось, что я смог объяснить ему это.

Но, к сожалению, он просто не может успокоиться в этом вопросе. Он постоянно подрывает мой авторитет, требуя, чтобы мы делали все по учебникам (например, по книге Джошуа Блоха «Эффективная Java») даже в тех случаях, когда это было бы пустой тратой нашего времени и не принесло бы ощутимой пользы для нашего продукта. Как я могу заставить этого младшего разработчика доверять моему опыту?

Младшему трудно убедить старшего изменить свою практику. Кроме того, как менеджер он должен поддерживать ауру превосходства, чтобы иметь возможность эффективно руководить.

Поэтому, если вы хотите улучшить стандарты качества на своем рабочем месте, не имея на то полномочий, подавайте пример. Делайте правильно то, что другие делают неправильно, и покажите , что ваш способ лучше, потому что это приводит к лучшему продукту за меньшее время. Когда вы указываете на ошибки в чужом коде, не делайте этого, придираясь к файлам исходного кода. Сделайте это, представив воспроизводимый дефект в самом продукте и способ его исправления, следуя рекомендациям.

Кстати, одна из самых распространенных профессиональных болезней программистов — это завышенное самомнение. Возможно, он у него уже есть, но у вас тоже начинают проявляться симптомы ранних стадий.

Спасибо за ваш ответ, он великолепен тем, что пытается поставить меня на его место. О сторителлинговой части: я очень надеюсь, что первое обсуждение действительно не было воспринято как аргумент, а проблемы с качеством не были восприняты как "подрыв авторитета". Если нет, то имело место действительно огромное недоразумение. В остальном, я думаю, что ваш подход «показать на хорошем примере» и «показать на тестовых примерах» очень практичен, научен и может в конечном итоге помочь в создании лучшего продукта и, возможно, отношений... так что да, мне это нравится. Действительно, большое спасибо
Ух ты. Проповедуй это, братан.
Я не разработчик Java, но вполне возможно, что у старшего разработчика здесь могут быть веские причины делать вещи так, как они были сделаны. Поскольку (по моему собственному опыту) не делать что-то так, как вы делали это в школе, дает увеличение скорости на порядок (или больше) в критичном по времени приложении... Так почему бы не начать с простого вопроса, почему это было сделано Сюда? Возможно, вы чему-то научитесь.
@jamesqf Те же интерфейсы используются в C#, и хотя код будет работать в большинстве случаев (в зависимости от реализации), отсутствие переопределения Hashcode() приведет к сбою хеш-структур данных (хотя все остальное должно работать) и то же самое с serialVersionUID с вызывая некоторые нежелательные проблемы с отладкой. Легко пропустить переопределение этих методов, если вы не полностью понимаете область действия; что-то, что Пек ожидает, должен понять его старший разработчик.
«Кроме того, как менеджер, он должен поддерживать ауру превосходства, чтобы иметь возможность эффективно руководить» . Нет. Вам не нужно быть выше лидера: вам нужно быть хорошим коммуникатором, который подает хороший пример другим, демонстрируя приверженность, страсть, сочувствие, честность и целостность.
Этот. Это идеальный способ постановки проблемы. Этот комментарий подсказал мне, что это проблема точки зрения: «Я считаю аморальным позволять такому недостатку (ошибке) портить продукт позже». Слово «аморальный» подразумевает, что вы придаете слишком большое значение подобным вещам.
@JoeBradley Слишком большое значение? Мы не знаем, на каком программном обеспечении работает ОП, но если это мой банк, я бы предпочел, чтобы он придавал «слишком большое значение» таким вопросам, чем в итоге на счету было бы на несколько тысяч долларов меньше, потому что какая-то операция не удалась. не могу найти какое-то бронирование, которое перечислило мне деньги и, таким образом, пропустило его. Это важные вопросы, правильная разработка программного обеспечения так же важна, как и правильное построение моста (возможно, иногда больше, иногда меньше). Я согласен с тем, что психологический взгляд на это с другой стороны может помочь задать правильный тон в разговоре.
При этом да, проблема с serialVersionUID, как правило, оказывает меньшее влияние, но я всегда призываю джуниора или любого разработчика обсуждать код, пока они не поймут, почему он такой, а также почему существуют обзоры кода и почему они считаются важно — вовлечь всю команду и выявить проблемы, которые в противном случае могли бы позже привести к проблемам.

Способ смягчить проблему такого рода — «давать и брать». Я много раз добивался успеха с этой стратегией. Люди более восприимчивы к вашим предложениям и критике, когда они двусторонние. Поэтому я задавал вопросы и советовал, когда у меня была возможность, и серьезно относился к их ответам. (Честно говоря, иногда я уже знал ответ, но как знать, я тоже таким образом научился некоторым интересным вещам.)

В конце концов вы строите взаимопонимание, когда вы поддерживаете друг друга, и во многих отношениях дела идут намного лучше. И если у него 15-летний опыт, держу пари, он может многое рассказать вам, что стоит знать.

Я бы не беспокоился о нем и его холодном приеме, это вполне нормально после того, что случилось. По всей вероятности, он примет во внимание ваш вклад и будет осторожен с вами, и вы, вероятно, немного расстроите его. Но это не соревнование за популярность, поэтому, если он не выйдет из-под контроля, дайте ему немного свободы. Оставайтесь дружелюбным и поддерживающим, и он придет.

Хорошая мысль, хорошая стратегия! Это действительно может привести к более сильной связи (раппорту). Спасибо!

Будьте вежливы и профессиональны. Отправьте заявку на ошибку, в своей заявке подробно опишите проблему и возможное исправление, а также оставьте возможность связаться с вами для получения дополнительной информации или объяснения проблемы. Оставьте это на этом. Когда ваши заявки будут проверены, они будут назначены либо вам, чтобы исправить найденную вами ошибку, либо первоначальному разработчику. Надеемся, что другой разработчик поймет и устранит проблему или вернется к вам за дополнительной информацией. Если ничего не происходит, то теперь это проблема управления.

Этот метод не обращается к какому-либо конкретному разработчику за ошибки и позволяет учитывать время ремонта и, возможно, даже включать его в схватку (если вы это делаете).

Поиск ошибок в чужом коде — обычная практика. Каждый раз, когда новый разработчик входит в проект, он обнаруживает проблемы. Возложение вины не важно. Просто создайте тикет, и пусть процессы компании обработают его. Опытные разработчики не должны обижаться на других, обнаруживших проблемы в их коде. И если они это сделают, они, вероятно, не должны быть разработчиками.

Хотя я думаю, что Кешлам делает хорошее замечание. Также важно помнить, что код принадлежит команде, а не отдельному лицу, поэтому я бы не стал использовать «вы», когда вы спрашиваете о потенциальных проблемах с кодом. Вместо этого вы могли бы спросить

«Привет, я заметил, что мы не внедрили здесь хэш-код, есть ли для этого причина?»

Вы решаете потенциальную проблему с кодом, но также выясняете возможную причину проблемы и даете руководителю группы возможность превратить это в опыт обучения для вас.

Вместо того, чтобы превращать это в дискуссию типа «я думаю, вы должны», которая, как уже ясно, ни к чему вас не приведет, превратите ее в техническую дискуссию.

Просмотрев код, я обнаружил проблему и написал тест X, демонстрирующий ее.

(Вы можете написать несколько, если нужно). Затем команда должна обсудить, как правильно исправить это, чтобы ваш тест прошел успешно.

У вас есть утренние стендапы? или какие-то другие групповые встречи, на которых вы можете неформально упомянуть об этом.

Поднимая их всем в совершенно безличном виде: «Ой, я обнаружил эту проблему, этот класс реализовал equals, а не хэш-код, что действительно может вызвать проблемы, если класс когда-либо используется в хэш-карте, поскольку в качестве ключа используется только идентификатор объекта», а затем обсуждение когда это можно исправить.

Вы никого не обвинили в написании плохого кода, теперь все знают, почему это проблема, код исправляют.

Несколько общих указаний, хотя, исходя из этой информации, я думаю, что пункты 4 и 5 могут быть наиболее подходящими:

  1. Отделите код от его автора. Вы здесь, чтобы оценить первое, а не второе. «Этот код [X]» лучше, чем «Вы создали этот код [X]».
  2. Быть конкретной. Не давайте расплывчатых описаний всей кодовой базы. «В X, Y и Z были бы признательны описательные комментарии относительно формулировки этой функции» гораздо ценнее, чем «Для меня это все по-гречески».
  3. Будьте и вы на позитиве! термин для этого процесса — «проверка кода», а не «вербальная разделка кода» по какой-то причине. В большинстве опубликованных обзоров рецензент будет говорить как о хороших сторонах продукта, так и о плохих. Вы должны сделать то же самое.
  4. Выбирайте свои сражения. Не относитесь ко всему как к нарушению условий сделки. Если это немного странно, но работает отлично, дайте ему в лучшем случае сноску и назовите его «незначительной проблемой» или «быстрым вопросом». Вообще говоря, если вам нужно открыть отладчик/декомпилятор, чтобы создать сценарий поломки, это не считается чем-то серьезным.
  5. Убедитесь, что вещи, о которых вы говорите, не являются «теоретическими». Протестируйте приложение самостоятельно или поговорите с группой тестирования о том, что, по вашему мнению, может быть проблемой.

Напишите тестовый пример, описывая поведение, которое вы ожидаете, и покажите, что проблема нарушает тест.

(О, мальчик, какие безумные вещи мы обнаружили, когда начали систематически тестировать hashCode и equals в нашем проекте.....)

Выберите свои сражения

Как разработчикам, может быть трудно упустить мелкие детали. Очень тяжело. И как младший разработчик, вы часто еще не имеете опыта, чтобы отличить серьезные проблемы от мелких гнид. Похоже, что OP прав в двух приведенных примерах, НО являются ли они серьезными проблемами? Честно говоря, это не звучит так, если только это не приводит к поломке чего-либо. Не каждый запах кода - это холм, на котором можно умереть, особенно...

Будьте осторожны с дифференциалами превосходства

...когда ты младше, а они старше. По трем причинам:

  1. Боссы (при условии, что старший разработчик имеет власть над ОП) обычно не любят, когда их поправляют их непосредственные подчиненные. Я не говорю, что так должно быть, но такова природа человека.
  2. Старшие разработчики (включая меня) понимают, что им нужно больше работать, чтобы идти в ногу с младшими разработчиками, когда дело касается их знаний и технических навыков. Они могут быть очень чувствительны ко всему, что подкрепляет этот факт для них, например, когда их выставляют напоказ (особенно случайно снисходительно) младшие разработчики. Опять же не говорю, что так должно быть, но люди есть люди.
  3. Старшие разработчики часто привыкли иметь дело с младшими разработчиками, у которых есть фишка на плече: они думают, что они гениальны, а старшие разработчики — дураки и позёры, и которые всегда ищут возможности, чтобы прояснить это. Так что, даже если вы не один из этих младших разработчиков, если вам покажется, что вы делаете то же, что и они, вы можете получить ту же реакцию, что и они: оборонительную позицию и крайнее недовольство. Опять же, это не идеально, но поставьте себя на место старшего разработчика.

Или, возможно, старший разработчик может быть просто придурком. Или у вас был плохой день. Или что-то другое.

Что делать в следующий раз

  1. Помните, что старший разработчик является старшим, поэтому выбирайте свои сражения и примите тот факт, что как лицо, принимающее решения, старший разработчик имеет право совершать (и признавать!) ошибки.
  2. Сформулируйте свои проблемы так: «У меня есть вопрос, чтобы я мог понять», а не «вы сделали эту очевидную вещь неправильно», чтобы старший разработчик мог сохранить лицо. Это позволит им (надеюсь) увидеть свою ошибку и исправить ее, сохранив при этом отношения. Если они не увидят и не исправят свою ошибку, обратитесь к пункту №1.

Супер хороший вопрос. Я люблю учиться, но когда кто-то оскорбляет меня, я чувствую, что должен бросить это дело. Я рекомендую проверить «стиль кодирования» ваших коллег и определить его сильные стороны, чтобы он не чувствовал, что все время, которое он потратил на обучение, было бессмысленным. ТОГДА ОПРЕДЕЛИТЕ ВОЗМОЖНОСТИ. Таким образом, вы демонстрируете сильные стороны в будущем, которые помогают компании, а также работают над теми «возможностями», которые вы уже определили. Я руковожу командами, предоставляя график на 30-60-90 дней, а затем хвалю изменения, в которых мы извлекли выгоду из «возможностей». Это работает очень хорошо и является справедливым способом идентифицировать лидеров и людей, которые не являются и не должны быть лидерами.

Что ж, спасибо за ответ, но я не уверен, что понимаю вас. Просто для того, чтобы с моей стороны было ясно: я не ставлю под сомнение чье-то лидерство. Никто из них не хочет брать на себя руководящую роль.
Кто-то должен вести. Я говорю из личного опыта. Я не хотел вас запутать.
Мне жаль дурака, который «оскорбляет твою нежность».

Исправьте это сами. Создайте ветку, исправьте ее, протестируйте ее, и если вам нужно одобрение, просто проведите проверку кода. Это перекладывает бремя на вас, но вы тот, кто считает это важным, поэтому бремя действительно ложится на вас, даже если это чужой код.

Единственная проблема с этим подходом заключается в том, что если продукт сломается и отслеживается до этого исправления, то ОП теряет доверие, поскольку его исправление может быть теоретическим «наилучшей практикой», а не фактическим исправлением.
@Дэн, согласен. Ему лучше убедиться, что он прав. Вот почему я включил dev test в шаги. Если он считает, что это нужно сделать, он должен нести ответственность не только за проверку, но и за то, что его предложение что-то сломает, не так ли? Вы предлагаете ему переложить ответственность за свое предложение на кого-то другого?
@ Дэн, в последнем комментарии я должен был сказать: «Иначе он переложил бы ответственность на кого-то другого за свое предложение». Не даёт редактировать комментарии через 5 минут.
Это все еще довольно неловко для старшего разработчика, что приводит к неловким отношениям между старшим разработчиком и младшим разработчиком. Если у них уже есть хорошие рабочие отношения, это может быть хорошо. В противном случае это может быть бензин в огне.