StringConcat - разработка без боли и сожалений
3.29K subscribers
77 photos
7 videos
3 files
187 links
Полезный блог от разработчиков для разработчиков. Наш сайт: howto.stringconcat.ru
Download Telegram
Сергей на связи! Не собеседуйтесь в Индию. Там вы будете конкурировать со специалистами по трудоустройству, которые специализируются на прохождении собеседований.

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

В Индии же наоборот: все учатся проходить собеседование, а не работать. Количество и качество резюме очень высокое, но по опыту скажу, что всё из индусского резюме можно смело делить на три. Как следствие, требования при наборе в Индии становятся жёстче, чтобы отсеивать Д'артаньянов, которые потом будут SQL-запросы из контроллеров делать. 

Вывод. Очевидно, что прохождение таких собеседований и навык работы — две разные вещи. Корреляции между ними интервьюеры не наблюдают, но и менять стиль собеседования не торопятся, так что реальные навыки у вас никто проверять не будет.
😁16🤔5😭3👍1
В комментариях к одной из наших заметок упоминали пассажиров. Мол, зачем нам люди, которые просто сидят и машут веслом, как велено. Они же не добавляют команде ценности. Хотелось бы немного развить эту мысль.
Мы выделяем три главных качества: адекватность, исполнительность и обучаемость. Есть и четвёртое — инициативность.

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

Самостоятельность — способность оценить результат своей или не своей работы и улучшить её, не дожидаясь таски. Например, такой человек увидел повторяющуюся проблему, взял — и решил. Или что-то работало на 80%, а он взял — и улучшил до 99%.

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

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

К сожалению, таких людей хорошо, если 10%. Это не плохо, кому-то нравится просто веслать и в ус не дуть (мы тоже так хотим на самом деле, но не разрешаем сами себе). Но если у вас на проекте одни пассажиры, быть беде. Придётся директивно управлять, решат все проблемы самостоятельно, и вы как руководитель выгорите в угли. Особенно печально, если среди пассажиров окажутся лиды. Такие способны угробить любое начинание.

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

Как обычно, это субъективное наблюдение меня, Сережи и других коллег, а поэтому не истина в последней инстанции. Можно приходить в комментарии и накидывать.
👍22🔥8🤔1
Наверное, самый частый вопрос нам задают про то, как продать команде всё, что мы тут рассказываем про подход, архитектуру и всё добро. И мы обычно отвечали занудно про наработку авторитета, бла-бла-бла. Но есть и альтернативный способ. Цитируем коллегу из внутреннего чата:

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

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

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


В общем, если у вас есть власть, иногда такой способ наиболее оптимален.
🔥24🤷5👍2😁2
Media is too big
VIEW IN TELEGRAM
Ну что, признавайтесь, у кого так же на работе?

И это было бы смешно, если бы «скрам мастера» не считали что это действительно так и должно работать
😁34🔥7💩4💯4😱3
На этой неделе, примерно в четверг вечером хотим разобрать одну известную статейку про тестирование микросервисов. Посмотрим, актуальна ли она на текущий момент и как все это работает на практике. Ссылку пришлем чуть позже
🔥25👍8
StringConcat - разработка без боли и сожалений
https://youtube.com/live/NUBvpA1Dqjo?feature=share погнали!
На стриме обещал поделиться статистикой и анализом по багам. В итоге, в нашем проекте типовой баг на бекенде стоит примерно 6,5 часов работы команды - описать баг, назначить исполнителя, поправить, перепроверить, etc. Добавьте сюда время на коммуникацию, переключение контекстов и выйдет почти один рабочий день. При этом тест, который бы предотвратил появление бага пишется/дорабатывается максимум 30 минут (конкретно в нашем проекте). Вот такая интересная математика
👍21🤔2💯1
StringConcat - разработка без боли и сожалений
https://youtube.com/live/NUBvpA1Dqjo?feature=share погнали!
На стриме был вопрос — можно ли заменить в e2e-тестах реальную зависимость на двойника (заглушку, мок и т.д.). Видимо, мы недостаточно подробно объяснили свою позицию, потому что от главного QA шлюпки, где я гребу пришел комментарий, что такой подход — харам. Давайте разбираться.

E2e-тесты действительно лучше проводить с реальными зависимостями, но в жизни бывают разные ситуации, например:
- Тестовых подключений может не быть. Провайдер не предоставляет такую возможность. Обычно демо-аккаунт существует, но не всегда. Приходится выводить в прод под фиче-флагом и отлаживаться на месте.
- Нет доступа к тестовым подключениям. Это подвид предыдущего случая. Бывают ситуации, когда тестовый контур изолирован от интернета, и вызовы вовне невозможны.
- Тестовые подключения нестабильны, и получить “зеленые прогоны” затруднительно. Иногда для демо-стенда выделяется слабый сервер, который подходит только для отладки подключения, но не для постоянного тестирования.
- E2e-тесты можно разделить на уровни. На одном уровне проверяется взаимодействие микросервисов А, Б и В, на другом — взаимодействие системы с внешним сервисом Д. Набор сценариев будет различаться между уровнями. Делается с целью возможности запуска тестов например на локальной машине, где внешние сервисы по какой-то причине недоступны
- Сложность или невозможность приведения внешней системы в нужное состояние. Например, для подтверждения заказа во внешнем сервисе требуется ручное воздействие оператора, а API для изменения состояния отсутствует.
- Высокая стоимость запросов к API. Тестовые запросы тоже могут тарифицироваться. В таких случаях можно разделить тесты на уровни и в некоторых сценариях использовать заглушки.

И в этих случаях использовать реальные подключения затруднительно. В идеале надо тестировать всё вместе, но если это невозможно, то можно использовать двойника. Его нужно поддерживать и дорабатывать, что требует затрат, но это лучше, чем ничего. Обычно двойник представляет собой отдельный сервис, который можно создать самостоятельно или использовать инструменты вроде Wiremock Standalone.
👍17
😁22😢6💯21👍1🔥1
Немножечко откровений от Капитана Очевидность.

Как вы наверное в курсе, существует 2 способа задания идентификаторов.
- Естественные идентификаторы, которые натурально идентифицируют объект. Н-р СНИЛС, SSN, номер паспорта.
- Суррогатные идентификаторы, которые вводятся для того, чтобы просто различать сущности друг от друга (вообще, некоторые деятели считают идентификаторы протекающей абстракцией, но сейчас не об этом).

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

На днях снова приключилась ситуация, когда натуральный идентификатор стал неуникальным. Суть такова. Есть устройство, его серийный номер глобально уникален. Отличный кандидат для естественного ключа. Но вдруг появляется сценарий, когда устройство нужно перенести в другую группу (юрлицо), при этом из старой оно исчезнуть не должно, ибо должна остаться отчетость и история, связаная с ним. И наш уникальный ключ становится уникальным только в пределах группы. Самое фиговое, когда в такой ситуации ключ уже протек в другие системы. Поэтому мое эмпирическое правило - всегда делай суррогатный, даже кажется, что есть отличный кандидат для естественного
👍61🔥5👌3💯32❤‍🔥1🤔1😎1
Когда-то мы пришли в разработку просто потому, что это было в кайф. Тогда зарплаты были копеечные, а работа — редкая удача. Максимум — стать админом или, в худшем случае, эникейщиком. Но нас это не пугало. Мы горели своим делом, даже если за него платили копейки. Это было время, когда всё только начиналось, а потом выяснилось, что мы таки купили бетховен за 2 доллара.

Потом индустрия разрослась: agile-коучи, покер-планнинги и другие шарады. Но за всей этой мишурой проекты всё так же страдали от старых, как мир, проблем. Мы с Сережей решили собрать их в кучу, найти общий знаменатель. Так родился проект StringConcat. Мы вложили в него кучу сил и времени и смогли помочь многим. Кто-то смог решить свои проблемы с проектом, кто-то поменял работу на более интересную и высокооплачиваемую, кто-то понял что говнокод — это не норма.

Но сейчас вести образовательную деятельность стало сложно. Мы не инфоцыганы, а практики, которые всё ещё в строю. Однако желание делиться знаниями никуда не делось. Поэтому мы набираем единственную в этом году группу на наш курс Разработка без боли и сожалений, который стартанет в июне. На нем мы с вами вместе
⁃ разберемся как удерживать код в читабельном состоянии автоматически 24/7
⁃ проведем сессию Event Storming на реальной предметке
⁃ узнаем как писать тесты так, чтобы они приносили пользу, а не бесили
⁃ увидим как выглядит реальный коммерческий проект, написаный по канонам DDD и чистой архитектуры
⁃ выясним, почему код-ревью работает не так, как бы нам хотелось
⁃ попробуем написать код по TDD
⁃ и многое другое
Записываться тут. Увидимся!
🔥24👍6😁2
Количество людей предсказывающих смерть Закона Мура удваивается каждые 2 года.

Эта шутка заставила меня задуматься а действует ли Закон Мура до сих пор.

Если кратко, то закон мура — империчесое наблюдение сделанное в 1975 году Гордоном Муром: “Число транзисторов на чипе удваивается приблизительно каждые 2 года”.

И график это подтверждает. Мы так и находимся в экспоненциальном росте числа транзисторов.

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

Но это не значит, что прогресс остановился. Инженеры находят обходные пути: многослойные чипы, новые материалы, специализированные архитектуры вроде GPU и TPU, развитие RISC-V. Вместо того чтобы просто «упаковывать» больше транзисторов, мы начали использовать их умнее.
🔥10👍51
Мнения об ИИ разделились: одни в восторге, другие разочарованы. Мы решили проверить сами. С подельниками взяли небольшой условно-заказной проект, чтобы на практике оценить потенциал ИИ. Бизнес-логика — среднего уровня: не примитивная, но и не запредельно сложная.

Что понравилось:
Скорость. Код писался в 5–7 раз быстрее, чем вручную.
Экономия когнитивных сил. Меньше рутины — больше внимания для сложных задач.
Сложные конструкции. ИИ хорошо работал с Either находил граничные случаи и правильно представлял их ошибками в sealed-классах (не все мои коллеги так умеют), даже объяснять ничего не нужно.
Декомпозиция. Четкая структура и инкапсуляция упростили генерацию. В анемичной модели это было бы кошмаром с непредсказуемым качеством.

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

Итог: ИИ — как смышленый джун: экономит время, но не заменяет экспертизу. Вцелом, получили то, чего и ожидали, а имеено ускорение этапа набора кода. Сходить к заказчику, добрым словом и пистолетом выяснить что ему нужно ИИ пока не может
🔥19👍7💯6
Так, вот вам свежее ночное прозрение, пока я пялился в браузер с ИИшкой:

А что если мы не будем просить ИИ написать программу, а попросим его самого стать программой и делать то что нам нужно? Чтобы было понятнее: допустим, вам нужен сервис продажи билетов. Вместо месяцев разработки вы просто говорите ИИ: «Вот схема зала, вот цены, вот эквайринг. Делай красиво, мути бабосики»
И он:
Отдает фронт (и даже адаптивный),
Коннектит базу (и не теряет данные),
Подключает оплату (и не отправляет деньги на свой личный счёт).

Без единой строчки кода, просто добавив ввод-вывод, а ИИ работает как бекенд. Чистая магия: «хочу → получи».

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

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

Что думаете, бред или будущее?

P.S.: уже сейчас можно попросить прикинуться линуксом и чятгпт исполнит линуксячьи команды. Попробуйте
🤔134👍4😭3😱1
Наконец-то стоящее обновление Intelij Idea в первые за много лет.

JetBrains, проснувшись в холодном поту от кошмаров про VSCode, наконец-то выкатил AI-агента в Idea 2025.1. Да-да, спустя тысячу лет после того, как VSCode уже съел, переварил и забыл об этой фиче.

Раньше их «AI» был обычным чатом-попрошайкой. Как будто вы сами не можете открыть ChatGPT в браузере и спросить, почему ваш код такой позорный. Агент в Idea до недавнего времени был просто декоративным собеседником — бесполезный, как лайк от бота в LinkedIn.

Теперь же у нас, внимание, настоящий AI-агент. Ну наконец-то.
Осведомлен о проекте. Он теперь реально шарит, что у вас в проекте. Можно спросить: «Где тут все контроллеры с POST?» — и он не начнёт молчать, как вы в неловком разговоре.
Он умеет редактировать код сам. Представьте, не нужно копировать с StackOverflow сообщение из 2012 года и вставлять его в слезах.
Он работает с несколькими ИИ-моделями: chat-gpt, claude, gemini. То есть, когда одна начнёт нести чушь, можно переключиться на другую, чтобы она несла другую чушь.

Но — держитесь за стул — плагин платный. 10–20 баксов в месяц, чтобы не страдать в одиночку, а страдать вместе с роботом. Правда, продуктивность от этого растёт. Ну или вы просто быстрее закончите работу и раньше начнёте страдать по другим поводам. Win-win.

Опрос
Вы вообще пользуетесь этим вашим AI, или ещё живёте в 2019?
❤️ Я раб ИИ: агенты, чаты, письма, тесты, код — всё на боте.
🙊Только чаты, но и на работе, и дома — GPT знает, когда я плачу.
😐 Иногда зову чат, когда всё совсем плохо.
😢 Никогда. ИИ — это какая-то секта.
😐78🙊25😢2116🤣3👍1
Вернемся с ИИ на землю

Как вы наверное знаете, мы с Сережей не очень жалуем библиотеки для мокирования, типа Mockito или mockk и предпочитаем использовать самопальные моки или фейки в качестве зависимостей. Почему так получилось? Есть несколько причин:

1. Не ломается компиляция. В стародавние времена была проблема с библиотечным API — при изменении сигнатуры ломается тест с сообщением вида «ну ваще-т хотели вернуть экземлпяр вот этого типа, но оказывается не подходит», а не компиляция. Сложнее отловить и поправить
2. Каша вместо теста. Из-за того же API тест становится замусоренным, тяжело уловить суть среди нагромождения doReturn-when-блаблабла. Особенно непонятно становится, если нужно эмулировать сложное поведение.
3. Баги в библиотеках. Натыкались неоднократно. Совсем недавно мы обнаружили что mockk не очень умеет в многопоточное окружение. При попытке использовать экземпляр мока по интерфейсу в разных тестах, запускающихся в разных потоках мы вдруг получили что-то вроде No answer found, хотя тесты не используют общее состояние и моки создаются отдельно для каждой функции тестов. В доке особо на этот счет ничего нет, а то что есть — не работает (если кто-то налетал на такое и победил — напишите в комментах)

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

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

Ни к чему не призываем, это как всего лишь наш опыт и мнение, но если есть возможность — попробуйте
🔥13👍63❤‍🔥3
В публичный доступ выложили видосы с конференции за прошлый год. Как всегда много интересных докладов. Для тех, кто хочет стать архитектором, обрести свободу и наконец-то сделать все правильно, рекомендую посмотреть доклад Жизнь архитектора: мечта и реальность (спойлер: вам не позволят) или как спроектантить поиск. Приятного просмотра!
19🔥13👍3
Тут еще мякотки подвезли. Ни для кого не секрет, что электронный мозг умеет галлюцинировать. В коде он делает это с особым изяществом — иногда выдумывает зависимости, которых в природе не существует. На первый взгляд — пустяк. Ну, подумаешь, ваш код дружит с воображаемыми друзьями. Но эти глюки бывают стабильными, то есть повторяются из раза в раз.

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

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

Источник
😁35🔥16🤔1
Евгений
Вернемся с ИИ на землю Как вы наверное знаете, мы с Сережей не очень жалуем библиотеки для мокирования, типа Mockito или mockk и предпочитаем использовать самопальные моки или фейки в качестве зависимостей. Почему так получилось? Есть несколько причин: 1.…
Небольшое пояснение

Вообще, мок — это общее название для тестового двойника, но не совсем точное. Потому что помимо моков (mock) существуют:
• Пустышки (dummy) — используются для заполнения параметров, которые обязательны, но не влияют на сам тест. По сути, это просто заглушки, чтобы код не жаловался, что ему чего-то не хватает. Типа как “пригласить на тусу бывшую, но игнорировать ее всё время”. Если ее дернуть, то получишь по-морде исключение, так как взаимодействие не предусматривалось.
• Заглушки (stub) — возвращают заранее заданные значения, которые нужны тесту. Они не записывают, что с ними происходило, а просто делают вид, что они настоящие.
• Шпионы (spy) — записывают, как с ними взаимодействовали: какие методы вызывались, с какими аргументами. Очень полезны, если ты параноик и хочешь знать, кто сколько раз что вызвал.
• Фальшивки (fake) — это полноценные рабочие реализации, но упрощённые. Например, база данных в памяти вместо реальной (H2 или вообще HashMap).

Настоящие моки пошли из этой статьи. Если коротко, то мок — это такой класс, который знает что он будет протестирован, а также содержит методы для верификации. Его можно получить из spy, прикрутив метод проверки чего было вызвано/сколько раз/с какими аргументами/etc. Примеры можете найти в нашем референсе в классах Mock<Something>

Определений можно услышать тысячи, главное понимать суть.
🔥20👍9