Pull to refresh
46
2.5

Пользователь

Send message

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

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

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

Ну, хорошо, допустим, каша. И что дальше? Какие варианты? Сказать, что вы все дураки, у вас тут каша, я устал я ухожу? Или просто на всё забить, и если менеджер решил реализовать совершенно бессмысленную фичу, то разработчику просто молча её реализовывать, а если разработчики делают какую-то дичь, то менеджеру просто молча на это смотреть? Мне все эти варианты не нравятся, возможно у вас есть вариант лучше

На мой взгляд, неожиданно глубокая статья!

Неожиданно, потому что начинается со слов "менеджер", "гуманитарий", "тяжело работать", "продакт", "ментор", а потом "куда бечь прокачиваться", "апгрейднуть мышление". Для полного набора не хватает чего-нибудь про поток, прокрастинацию, выгорание, вкатывание или выкатывание из айти, достигаторство, эффективность, как я стал тимлидом в 20 лет и т.д. Обычно после этого идёт набор штампов, и наверное часть людей тригерятся уже на сами слова. (Если честно у меня мечта написать статью, в которой использовались бы все эти слова и штампы, и чтобы было побольше пафоса, чсв, криво построенных предложений. Что-то типа "Сказ о том что роляет вайтишечке и во что умеет 20-летний solution architect поймавший поток")

Если по сути, то действительно время от времени я сталкиваюсь с бинарным мышлением. Попробую привести пример с одного проекта.

Нужно разработать относительно сложное приложение. В этой области уже есть готовые фреймвоки. Также для фреймвока есть готовый пример приложения, который мы берем за основу. Но в этом примере посредственный пользовательский интерфейс, а его доработка занимает много времени, потому что в команде пока не хватает сеньорных фронтендеров. Из чего руководитель делает вывод, что и сам фреймвок плохой и нужно срочно перескакивать на другой фреймвок или писать всё с нуля. При этом его не устраивают никакие наши сравнительные обзоры по этому и другим фреймвокам, или доводы, что давайте приоретизируем разработку - сначала реализуем основную функциональность, а когда появятся фронтендеры займемся "цветом кнопок", или доводы, что этот фреймвок разрабатывался 10 лет гораздо большей командой, нам за полгода будет сложно повторить то же самое, давайте сначала сделаем хоть как-то работающий прототип, а потом займемся его улучшением. К слову интерфейс был не до такой степени ужасен, был аналогичен тому, что уже использовался у заказчика, да и для заказчика функциональность была важнее.

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

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

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

С одной стороны, конечно нужно пытаться понимать позицию оппонентов, пытаться найти компромисс. И наверное во многих вопросах мы его находили. Но иногда это сложно сделать, на обсуждения начинает уходить слишком много времени и тогда остаётся просто остановить поиски истины и принять одну из точек зрения. Лично я придерживаюсь такого правила, что время обсуждения должно быть пропорционально важности вопроса. Если вопрос второстепенный, то просто пофиг если будет принято "неправильное" на мой взгляд решение.

Вообще, я думаю, что в ИТ такие споры часто возникают из-за того, что люди не могут декомпозировать задачи. Например, если реализация не соответствует на 100% требованиям в силу каких-то причин, то всё, капец, это ужас, этим невозможно пользоваться. Хотя всего-то нужно разбить реализацию на этапы: 1) сначала простые вещи закрывающие максимум потребностей (20% усилий на 80% результата) 2) потом важные, но сложные вещи 3) потом простые и неважные 4) в конце сложные и неважные. Я достаточно часто слышу, что здесь нечего декомпозировать, всё одинаково важно и если хоть чего-то не будет, то капец.

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

  1. Если ничего непонятно, то нужна исследовательская задача - почитать документацию, посмотреть исходники и т.д.

  2. Если есть много вариантов решения, то нужно их перечислить и описать

  3. Если непонятно какой вариант выбрать, то нужно определить критерии выбора, отсеять явно не подходящие варианты

  4. Если всё равно непонятно что выбрать, то можно подключить к решению тимлида. Если не кого подключить к решению, то выбрать самое простое решение (иногда оно заключается в том, чтобы просто ничего не делать)

  5. На исправление каких-то связанных багов завести отдельные задачи

  6. На исправление архитектурных проблем тоже завести отдельные задачи

  7. и т.д.

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

Вообще меня не хило тригернула эта тема :) На самом деле и в обществе мышление часто бинарное. Люди делят всех на "друзей" и "врагов", на "прогрессивных, которые придерживаются моей точки зрения" и "тупых, которые придерживаются другой точки зрения и им невозможно ничего объяснить". А если относиться к этому проще, ну, ок, они считают так, в этом есть доля истины, возможно это важно для них, то наверное было бы меньше конфликтов в разных сферах.

Есть VSCode. Или Theia возможно с более подходящей лицензией и большими возможностями расширения. Eclipse для некоторых задач норм. Это очень холиварная тема, но лично я не понимаю профита от коммерческих IDE

Менеджменту без разницы какая Java и какие фреймвоки используются, это техническое решение. Есть такая задача: нужно написать приложение, при этом у заказчика Java 11 и с этим сложно что-то сделать и ещё есть фреймвок, который упростит разработку приложения в сто раз, но он на Java 17. Написать транслятор кода - это самое простое решение на мой взгляд в данной ситуации. Они не на столько сложные, если интересно:

Причем первые три я закоммитил в репозиторий OpenRewrite и частично переложил на сообщество ответственность по их сопровождению :) Транслятор рекордов они к сожалению не взяли, потому что у них позиция что они наоборот переводят код на новые версии Java, а даунгрейд рекордов в классы не соответствует целям их проекта. Хотя для меня это спорный вопрос, я думаю, что могут быть разные причины для преобразования рекорда в класс. Хотя, блин, сейчас задумался какие, в принципе для рекордов можно реализовать кастомные геттеры, equals(), toString() и т.д. если нужно. Наверное основная причина - это если понадобилось сделать сущность мутабельной и возможно это не на столько частый сценарий.

Было бы очень круто, если бы код на Java 21 можно было скомпилировать таким образом, чтобы он запускался на Java 11. С одной стороны, возможно это какие-то дополнительные сложности для разработчиков языка. Но в JavaScript это ведь получилось через полифилы. Давно не писал под .NET, но если я правильно помню там тоже с этим проблем нет, можно выбрать предыдущую версию целевого фреймворка.

Что мешает обновиться?

Это приложение с повышенными требованиями к безопасности. У заказчика кастомная Java, из которой выпилены вещи типа изменения уровня доступа к методам с private на public через рефлексию и т.д. Вносить все эти изменения в JDK долго и сложно и технически, и организационно. Реально на порядок проще просто форкнуть проекты на Java 17 и написать транслятор кода на Java 11. С Java 21 это будет сложнее, но я надеюсь, что люди не побегут сразу переписывать весь код с использованием новых фич языка. Когда внутренний проект переводится на новую Java, то проблем вообще нет. Но я не понимаю зачем спешить с обновлением Java в фреймвоках, которые используются в куче проектов.

Самая жесть, что эти вещи с рефлексией зачем-то используют в достаточно популярных фреймвоках типа Spring Boot. Что очень затрудняет их применение в проектах с высокими требованиями к безопасности.

К тому же Java 11 не на столько древняя. Ей всего лишь 5 лет и поддержка ещё не закончилась.

В общем если вы думаете, что мешает обновиться лень или какие-то надуманные внутренние организационные причины, то точно нет. Например, недавно обновил на фронте React до 18-ой версии, хотя в части зависимостей используется React 17. Там конечно были танцы с бубнами, но всё получилось.

Если в целом говорить об обратной совместимости, то мне конечно больше всего нравится Lisp. Потому что в нём вообще толком нет синтаксиса. Там не нужно 10 лет ждать когда в языке наконец появится какой-то синтаксический сахар. Если он нужен, то можно просто самому его написать. Или наоборот если в каком-то фреймвоке этот синтаксический сахар используется, то чтобы использовать этот фреймвок у себя не нужно обновлять версию компилятора или виртуальной машины. Короче в Lisp просто в принципе проблемы с этим отсутствуют.

И на втором месте после Lisp - это JavaScript. Идея с полифилами просто отличная. Если какая-то фича в языке нужна уже сейчас, то ненужно ждать её релиза. И, наоборот, если эта фича уже есть в языке, но не поддерживается в браузерах у части клиентов, то тоже проблем нет. И это вменяемый нормальный подход. Для Java мне фактически приходится сейчас писать те же полифилы на OpenRewrite. Если бы их написали авторы этого синтаксического сахара, то всё было бы проще.

Да, это жестко, волею судеб мы используем на одном проекте Java 11. Но часть зависимостей перешли на Java 17 и пришлось на OpenRewrite писать транслятор рекордов в классы, транслятор instanceof с pattern-матчингом в обычные instanceof с отдельным объявлением переменной, транслятор многострочных литералов в обычные литералы и т.д. Я узнал много всего интересного, например, что можно писать так:

if (!(obj instanceof String str)) {
    throw new IllegalArgumentException();
}
System.out.println(str.length());

А ещё так (это два разных str):

if (!(obj instanceof String str)) {
    Integer str = null;
    System.out.println(str);
} else {
    System.out.println(str);
}

Спорим, вы не догадаетесь просто глядя на код какие варианты корректные (в каких вариантах str доступен в if, а в каких в else):

if (!(obj instanceof String str) || false) {
    System.out.println(obj);
} else {
    System.out.println(str);
}

if (!(obj instanceof String str) || true) {
    System.out.println(obj);
} else {
    System.out.println(str);
}


if (!(obj instanceof String str) && false) {
    System.out.println(obj);
} else {
    System.out.println(str);
}

if (!(obj instanceof String str) && true) {
    System.out.println(obj);
} else {
    System.out.println(str);
}

Если справились, то тут вообще без труда найдёте вариант с ошибкой:

if (!(obj instanceof String str) && obj instanceof String str) {
    System.out.println(str);
} else {
    System.out.println(obj);
}

if (obj instanceof String str || !(obj instanceof String str)) {
    System.out.println(obj);
} else {
    System.out.println(str);
}

if (!(obj instanceof String str) || obj instanceof String str) {
    System.out.println(obj);
} else {
    System.out.println(str);
}

Если это слишком просто для вас, то добавьте ещё условий, вложенных if'ов, с несколькими переменными и т.д. на свой вкус. Это как бы такая переменная Гейзенберга пока не скопируешь код в IDE нельзя быть точно уверенным какая у неё область видимости.

Мне пришлось написать тестов больше чем само преобразование кода. Рекорды - это просто кайф.

А теперь сбылась моя мечта и они соединили instanceof и record! Наконец-то! Я уже предчувствую сколько ещё увлекательной работы мне предстоит! Если вы разрабатываете какой-нибудь популярный фреймвок, то бросьте все дела и срочно переведите его на Java 21! Чтобы всякие ретрограды на Java 11 страдали.

Это конечно всё ирония. Вообще интересно когда люди добавляли pattern-matching в instanceof рассматривали ли они все эти случаи. Понятно что так лучше не писать код, но это открытый вопрос нужно ли добавлять такие конструкции в язык, чтобы потом обвешивать их правилами линтера. И ещё интересный вопрос есть ли теоретическая возможность добавлять в язык новый синтаксический сахар, но чтобы код мог выполняться и на предыдущих версиях JVM...

Вы дальше пройдите, выберите вход через ГосУслуги и увидите список сведений из 26 пунктов, которые будут запрошены. Весь список можно не читать, достаточно первого про билет :)

Disclaimer: я не топлю ни за Windows, ни за Linux. Каждому удобнее своё. Я просто попробую описать почему Linux для некоторых людей может быть удобнее.

У меня на днях был квест отключить Windows Defender. Комп достаточно слабый, он используется только для просмотра трех сайтов в Chrome, в антивирусе нет нужды. Я так и не осилил выполнение этого квеста. В инете много рекомендаций как это сделать через реестр, политики и т.д. Большая часть рекомендаций не работает. Как я понял, у части ключей в реестре владелец Trusted Installer и так просто эти ключи не изменишь. В гугле рекомендуют скачать стороннюю утилиту, которая позволяет запустить редактор реестра под этим пользователем. Вопрос на сколько этой утилите вообще можно доверять. В итоге я вроде что-то отключил, но только частично. Всё это выглядит как какое-то шаманство, штатной документации и штатных утилит на этот случай нет.

Дело не в крутости. Многие задачи в Linux решаются чтением документации, поиском подходящей утилиты, пусть и гуглением тоже. Если мне что-то не нужно, то я относительно легко могу это отключить или удалить. ОС не чинит мне искусственных препятствий.

Или, например, мне нужно найти все файлы по какому-то критерию, массово переименовать их, массово преобразовать svg в png с нужными параметрами и т.д. В Linux я ищу для этого подходящую утилиту, изучаю документацию. А в Windows в большинстве случаев ищу готовую программу, возможно проприетарную, возможно с рекламой, возможно с меньшими возможностями, возможно с не удобным ограниченным графическим интерфейсом, в котором ещё разобраться нужно.

В Linux унифицированный интерфейс для поиска и установки программ через пакетный менеджер, без визардов, без галочек "Установить до кучи ещё какой-нибудь браузер или антивирус". Унифицированный интерфейс у утилит (в виде командной строки), обычно с большим количеством возможностей, которые было бы сложно уложить в GUI. Унифицированная документация, которая одинаково открывается для большинства программ, одинаково оформлена. Относительно унифицированные конфиги, журналы работы и т.д., которые лежат в соответствующих каталогах и всегда знаешь где их найти. Для меня это банально удобнее.

Ещё мне последние версии Gnome визуально нравятся гораздо больше, чем интерфейс Windows. Но это очень субъективно, как и всё остальное перечисленное здесь.

Плюс, раз статья про образовательный процесс, то на мой взгляд всё это способствует приобретению знаний (по крайней мере для разработчиков и админов). Когда ты разбираешься с командами типа find, grep, sed, а не просто ищешь программу с GUI, которая решит узкую задачу, то явно обучаешься, узнаешь что-то новое.

Но, ещё раз, у меня такие запросы, поэтому мне это удобнее. У дизайнеров, например, другие запросы, им нужна куча специфических программ, которые есть только в MacOS. Другим людям нужны специфические программы, которые есть только под Windows.

Самая жесть - это шаблоны проектирования XML схем: Salami Slice, Venetian Blind, Russian Doll, Garden of Eden. Здесь собрано всё. И оскорбление чувств верующих, и пропаганда употребления животных в пищу, и ущемление людей с проблемами со зрением, и объективация женщин, тем более авторитарным режимом. Куда отправлять заявку на пополнение списка?

Прикольный курс, я "проходил" близкий по смыслу, даже пытался использовать в работе и сейчас разрабатываю IDE. Было бы круто, если бы у вас была заочная форма, чтобы можно было совмещать с full-time работой.

ООП - это одна парадигма программирования из множества. Есть клевая книга "Concepts, Techniques, and Models of Computer Programming" by Peter Van Roy and Seif Haridi, в которой это очень хорошо разложено по полочкам.

В каждом языке программирования акцент сделан на определенных парадигмах. В Java/C# - это изначально ООП, плюс немного параллельных вычислений, немного ФП, немного метапрограммирования (рефлексия) и т.д. В Prolog - основной акцент на логическом программировании. В Lisp - на метапрограммировании, языково-ориентированном программировании (макросы).

практически чистое ООП с классами

На мой взгляд в чистом ООП практически ничего нет: есть объекты, они друг с другом взаимодействуют, у объектов есть классы, которые образуют иерархию наследования.

Мне лично вообще чужд этот подход смотреть на всё через призму объектов. Когда-то давно прочитал статью Пола Грэма "Programming Bottom-Up". И мне ближе всего такой подход, при котором приложение по сути строится из множества микрофреймвоков. Например, я делал инструмент моделирования, в котором были такие микрофреймвоки: 1) для работы с коллекциями, всякие специфические итераторы, чтобы перебирать элементы в обратном порядке и т.д. 2) для работы с геометрическими фигурами 3) библиотечка с разными алгоритмами типа A* 4) для рендеринга UI 5) для парсинга строк 6) для стека команд и т.д.

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

А использование ООП в чистом виде вообще не гарантирует, что в итоге получится вменяемый код. Люди злоупотребляют использованием состояния объектов. Например, передают данные из одного метода в другой через поля. И не видят в этом никакой проблемы, типа это же внутреннее инкапсулированное состояние и с ним можно делать что угодно. Хотя реально это не многим лучше глобальных переменных. Злоупотребляют наследованием классов, которое нужно в очень специфических случаях.

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

Те же List<T>, HashSet<T> и т.д., которые упоминались выше - это скорее про алгебраические типы данных, чем про ООП.

В общем это достаточно спорные фичи ООП: мутабельное внутреннее состояние, наследование, взгляд на всё как на взаимодействующие объекты. А без этого от ООП толком ничего не остаётся, просто синтаксический сахар.

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

Это конечно такой себе пример:

class ArrayListAsFunctionTest {

    interface IList<T> {
        int size();
        void append(T item);
        T get(int i);
    }

    <T> IList<T> newArrayList(int capacity) {
        var data = new Object[capacity];
        var size = new int[1];
        return new IList<>() {
            public int size() { return size[0]; }
            public void append(T item) { data[size[0]++] = item; }
            public T get(int i) { return (T) data[i]; }
        };
    }

    @Test
    void test1() {
        IList<Integer> list1 = newArrayList(100);
        list1.append(1);
        list1.append(2);
        list1.append(3);
        for (int i = 0; i < list1.size(); i++) {
            System.out.println(list1.get(i));
        }
    }

}

В Java мы вынуждены объявить интерфейс. Плюс в newArrayList() создаётся анонимный класс. Ну, это язык такой, в нём даже Hello World без классов не напишешь.

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

А в Java/C# классы - это неотъемлемая часть языка, без них ничего не написать. Причём часто это приносит больше проблем, чем пользы. Люди хранят временное состояние в полях объекта: в одном методе что-то пишется в поле, потом вызывается другой метод, в котором это поле читается и т.д. Т.е. поля используются не для хранения долговременного состояния объекта, а просто для обмена данными между методами, типа глобальных переменных в Си, но ограниченных классом - понять что делает такой код очень сложно, плюс гарантированы проблемы с многопоточностью. Или делают какие-то безумные иерархии классов.

Основа ООП - это инкапсуляция, полиморфизм и наследование.

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

Полиморфизм в принципе тоже работает и без классов.

Наследование вопрос на сколько часто вообще нужно.

Окей, можете сделать функцию, аналогичную, скажем контейнеру List<T> (линейный список) или HashSet<T> (вырожденная хэш таблица, просто для поиска ключа), где есть общие данные, с которыми можно работать используя разные методы, Add, Get, Delete, Enumerate и т.д.?

Легко:

function ArrayList() {
  const data = [];
  return {
    size: () => data.length,
    append: item => data.push(item),
    get: i => data[i]
  };
}

const list1 = new ArrayList();
list1.append(1);
list1.append(2);
list1.append(3);
for (let i = 0; i < list1.size(); i++) {
  console.log(list1.get(i));
}

Примерно то же самое будет в каком-нибудь Lisp. Классы - просто синтаксический сахар.

Тема с роботами неисчерпаемая!

Я бы упал под стол, если бы случайно набрел на локацию с Супер Алисой и таким роботом

Или было бы интересно и мозговыносно внутри альтернативной истории читать (например, в разбросанных книгах) кусочки другой альтернативной истории по мотивам Complex Numbers

А потом внезапно наткнуться на грузовичок с роботами на 5:41 и об...ться от страха:

С одной стороны, конечно есть риск намешать всего и разрушить атмосферу. Но, блин, по-моему такими вещами игру не испортить. В том же Fallout было очень много отсылок, побочных квестов, которые только наполняли игру.

По ссылке Pattern: Database per service описаны преимущества такого подхода:

  • "Уменьшается связность между сервисами, можно независимо менять схему данных." - но это действительно хорошо, когда схемы данных для сервисов разрабатываются полностью независимо? В них могли бы использоваться общие справочники, общая схема именования таблиц, столбцов. Профит от того, что за всю схему данных отвечает один человек или группа людей мне понятен: потом эти данные проще анализировать, проще строить по ним отчеты, не нужно писать сложные ETL процедуры для приведения данных к единому виду, нет дублирования данных, схема данных достаточно устойчивая и не приходится всё переделывать при её изменении. Краткосрочный профит от распиливания схемы данных, ну, с натяжкой понятен: можно быстрее фигачить новые фичи в продакшен не парясь о схеме данных. Но в долгосрочной перспективе что потом с этими данными делать?

  • "Каждый сервис может использовать свою СУБД". Очень важный пункт (sarcasm), хипстеры в каждой команде смогут использовать свои любые MongoDB, Neo4j или даже каждый месяц переходить на новую СУБД. Если серьезно я думаю, что в 2023 году такой зоопарк скорее минус, чем плюс.

Недостатки:

  • "Сложнее реализовывать транзакции между микросервисами"

  • "Сложнее join-ить данные из разных СУБД"

  • "Сложнее админить разные СУБД" - если что-то упадёт и потом понадобится восстанавливать из бэкапов, то это выглядит просто страшным сном админов

Ну, ещё они забыли упомянуть:

  • Сложнее обеспечивать целостность данных (внешние ключи)

  • Сложнее реализовывать какие-то общесистемные вещи типа аудита, как вы описываете в статье

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

Если не требуется вообще, то я и не хожу :) Или если я основной докладчик, то, да, параллельно ревьювить задачи я точно не смогу. Но обычно какой-то промежуточный вариант: если основной докладчик - другой человек и на встрече ещё человек 10, то я стараюсь что-то комментировать только если это действительно необходимо. Не потому что мне нечего сказать, а потому что не хочется попусту растягивать встречи, часами что-то переливать из пустого в порожнее. Если я с большей частью пунктов в целом согласен, то какой смысл мне на протяжении двухчасовой встречи изображать внимание или вставлять какие-то реплики.

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

Наверное, да, для людей, которые привыкли к очным встречам, всё это звучит диковато.

Ну и в целом, 5 секунд — это даже не время на просмотр задачи.

Я могу описать алгоритм как оценить большинство задач за 5 секунд :)

  1. Читаем название задачи, скользим глазами по описанию. Обычно описание представляет собой следующее: а) ссылка на требования в confluence/xwiki, б) сценарий воспроизведения ошибки, в) пара абзацев текста без ссылки на требования, г) описания нет. По этим признакам сходу понятно что это за задача: на исправление бага, на реализацию новой функциональности, на исследование чего-то и т.д.

  2. Если задача уровня "изменить цвет кнопки" ставим оценку 1 день. Такие задачи сразу видны, там не во что вчитываться

  3. Если задача уровня что-то сломалось, а недавно работало или недавно что-то аналогичное уже чинили и причина сходу понятна - 2-3 дня

  4. Если пути решения задачи сходу не очевидны - 4-5 дней

  5. Если видно, что задача не укладывается в неделю или состоит из нескольких частей, например, доработать схему данных, доработать API, покрыть его тестами, сначала сделать простейшую формочку на фронте, потом её усложнить и т.д., то эту задачу оценивать не нужно. Ставится задача написать дизайн-документ или просто декомпозировать без дизайн-документа - в зависимости от сложности это 2-4 дня

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

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

Если требуется более масштабное планирование на месяцы и годы, то оценка делается примерно так же, только шкала другая, например, от 1 недели до 5 лет. Для таких задач либо сходу можно сказать 1 месяц на неё уйдёт или 1 год, либо если сходу не получается или такая точность не устраивает, то можно разбить на подзадачи и оценить их.

Очевидно, оно несколько сложнее и вариативнее, чем рационально делать генератором. Сложностей там, однако, по-прежнему особо нет.

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

У нас прямо противоположный опыт, в большей части задач нужно думать, искать варианты решения. Например, используем какой-нибудь фреймвок для отрисовки и редактирования моделей и в некоторых ситуациях коряво рисуются связи, не работает copy/paste или странно работает undo/redo. Фиг его знает почему, нужно сидеть дебажить, может это мы неправильно используем этот фреймвок, или может в нём баг, тогда нужно делать pull-request авторам или делать форк этого движка и т.д. Или это не баг движка, а в нём есть точки расширения, описанные в документации, и нам нужно использовать их.

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

Блин, и у нас большая часть задач такая. Умение думать, искать варианты решения, оценивать их и т.д. - это прямо самое главное требование. Хотя, я понимаю, что это звучит достаточно стрёмно, в идеале большая часть задач должна быть простой и понятной, делаться джуном по инструкции. Мы к этому стремимся, но пока с переменным успехом. Конечно же в xwiki остаются рекомендации по исправлению типовых багов, решению типовых задач и т.д. Но каждый раз возникает что-то новое и сложное. А вся рутина уже автоматизирована.

Также у компаний есть несколько метрик успешности — общая выручка/прибыль, рост предыдущих параметров и их значение на сотрудника. Где все эти организации с "креативными" сотрудниками в топе по любой из них?

В топе наверное в основном банки и другие крупные компании, у которых избыток денег, которые они могут тратить на найм тыщ джунов, которых нужно озадачивать работой. А потом в один момент взять и уволить 10% сотрудников без потери результативности.

Я полностью согласен с идеей, что компания не может строиться на каких-то "креативных гениях", которые решают исключительно уникальные задачи. В компании должны быть выстроены процессы, большая часть задач должна быть типовой, понятной, регламентированной. Но ИТ всё-таки не очень типичная сфера, потому что одна из задач ИТ - это автоматизация рутины, упрощение работы других людей. И когда создаются гигантские ИТ-подразделения, которые перекладывают JSON в формочки, то это выглядит немного парадоксально.

У меня в голове всегда была такая картинка, что есть какие-нибудь производственные подразделения, продажники, бухглатерия и т.д. Они вручную что-то считают, копируют данные из одной Excel таблички в другую. Допустим, у них уходит месяц на создание сметы на строительство дома. ИТшники всё это автоматизируют и смета делается за два дня. Профит. Или на каком-нибудь заводе устанавливается станок ЧПУ, конвейеры и т.д. - люди меньше времени тратят на рутину. Но когда работа самих ИТшников становится рутиной, то нафига они нужны?

Для тех же учетно-аналитических систем есть много готовых движков типа XAF и наверное есть много других. Я видел ситуации, когда ИТ подразделение годами пилит формочки вручную, а потом приходит один человек и делает всё это в 10 раз быстрее, лучше и больше. Потому что у ИТ подразделения 90% времени уходило на рутинные формочки. А у этого чела 10% времени уходит на описание схемы данных, 0% времени на запиливание формочек, потому что они генерятся автоматом, а 90% времени он может потратить на какие-то сложные вещи, которых в движке из коробки нет.

Или с теми же сайтами. Сначала они пилились вручную с нуля, потом появились готовые движки, сейчас есть конструкторы (и они реально закрывают значительную часть требований для простых сайтов), я не удивлюсь, если кто-нибудь уже прикрутил к ним ChatGPT. Наверное есть разные ИТшники: одни условно пилят типовые формочки или сайты-визитки по шаблону, другие - пытаются автоматизировать свою рутину.

И в остальных направлениях ИТ та же история. В машинном обучении всякие automl, mlflow. Например, несколько лет назад эти штуки были ещё не очень распространены, а нам нужно было делать много типовых моделей, вычислять для них метрики, подбирать параметры и т.д. Сначала каждый делал эти модели как ему казалось правильно, тратил кучу времени на рутину, но достаточно быстро у нас появился свой движок для подготовки входных данных, вычисления метрик и т.д. Существенную часть рутины он снял, можно было сосредоточиться на содержательной части модели.

Да, и везде так! Какой ИТшник не хочет автоматизировать свою работу и работать меньше?

В общем, извиняюсь за эти потоки сознания. Вы реально пошатнули мою картину мира :) Но теперь я снова спокоен, я объяснил себе, что просто это неэффективные компании с избытком денег, какой смысл им что-то оптимизировать если они просто могут накинуть на направление тыщу-другую джунов. А когда денег будет меньше и ИТ подразделение придётся сократить раз в 10, тогда возможно и рутинных задач станет меньше.

На плэннинг-митинге команда оценивает задачи.

На мой взгляд, совершенно бессмысленное занятие. У нас это делает техлид, на оценку одной задачи он тратит в среднем секунд 5.

Давайте реально взглянем на среднего разработчика: у него миллион рутинных задач, которые сводятся к нашлёпыванию бэк- или фронтенда крудов

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

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

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

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

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

А что в этом плохого? У меня бывает, что митингов часов 5 в день. Если бы я сидел со включенной камерой и изображал внимание, то осмысленной работой просто не занимался бы. Во время большинства митингов я делаю ревью задач, переписываюсь с другими коллегами, иногда участвую во втором митинге, делаю ещё какие-нибудь задачи в полмозга. Никого это не напрягает.

Он как бы доступен, но отвечает медленно. Формально "думал над задачей, не мог отвлечься, чтоб фокус не потерять", по факту — опять своими делами занят.

Что здесь плохого? У меня вообще 2 дня в неделю, когда я даже в дейли не участвую, люди стараются ничего мне не писать, а я стараюсь ничего не отвечать. И если это удаётся, то это супер-достижение и, уж, точно мне ни придётся за это оправдываться. Скорее, наоборот, придётся оправдываться, если я не сдержусь и потрачу полдня на болтологию. Если бы я мог, то распространил эту практику на всех, постепенно сокращая время для митингов и обсуждений. Например, если у меня раньше 3-6 часов каждый день уходило на митинги, очевидно что я каждый день особо не работал. А если освободить вторник и четверг, переместив все митинги на соседние дни, то понедельник, среду и пятницу всё равно не спасти, я как не работал в эти дни так и не работаю, но появляются два нормальных дня. Это невероятно (sarcasm), но большую часть вопросов вполне можно отложить на день или дольше, никакой катастрофы не будет. Или, например, у нас одно время был день без дейли и естественном образом в этот день самоорганизовалось обучение для сотрудников, разные семинары.

Это настолько очевидная и эффективная идея, что я не понимаю почему на хабре не пишется каждый день по 10 статей типа "мы запретили все митинги в один и из рабочих дней и наша эффективность выросла в 2 раза" или "мы сделали окно для митингов с 12 до 15 и даже у нашего РП не случился нервный срыв" или "мы сократили митинги до одного дня в неделю, а в остальные дни люди самоорганизовались, стали проводить разные полезные семинары, делиться опытом, появилась куча времени для генерации новых идей".

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

А что в этом-то плохого? Даже в некоторых офисах есть спортзал или совсем страшная вещь - комната для сна и отдыха! Что хорошего в том, что человек будет до упора сидеть за компом весь день? Под конец дня он будет никакущий, ну, типа, да, формально он сидит на рабочем месте, но думает скорее о том как он устал, а ведь ещё час до дома ехать по пробкам. А в долгосрочной перспективе то, что человек не будет ходить в спортзал или будет туда ходить в 6 утра, не высыпаясь - это совсем печаль.

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

Что в этом хорошего? У меня сильная убежденность в том, что у людей должно быть свободное время на работе, они не должны быть заняты на 100%. И дело даже не в том, что человек не может 8 часов концентрироваться на работе - на мой взгляд может и дольше, если ему это интересно. А в том, что когда эта бесконечная гонка заканчивается, что нужно срочно сделать то, сделать это, ответить на вопрос, а через 15 минут уже начинается митинг, а потом ещё один и т.д. То человек может наконец задуматься о таких вещах: "че-то у нас накопилось много треша в коде, было бы не плохо всё это покрыть тестами, зарефакторить", "мы неправильно используем такой-то фреймвок или у нас очень сложно и коряво собирается проект, хорошо бы почитать документацию и сделать нормально", "а что вообще за продукт мы делаем? почему это и то в нём неудобно и плохо? почему не сделать хорошо? и в чём это хорошо вообще могло бы заключаться?".

Information

Rating
1,027-th
Registered
Activity