SmartHead – Telegram
SmartHead
167 subscribers
17 photos
27 links
Привет! Здесь мы делимся подходами и практиками в менеджменте и разработке. Опытом компании, tips and tricks.

Послушать наши голоса можно в подкасте — https://news.1rj.ru/str/smarthead_space
Download Telegram
#management

Agile — это не «гибкий»

Agile корректнее переводить не «гибкий», а «ловкий» или «проворный». Это лучше передаёт идею быстроты, природной гибкости и умения быстро адаптироваться к изменяющимся условиям. К сожалению, когда мы используем перевод «гибкий», мы упускаем эту важную суть. Гибкость — не самоцель в agile.

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

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

Можно сформулировать принципы agile (например, тут классические), но нельзя дать полный их набор в качестве исчерпывающего определения. Зато можно сказать что эджайлом не является.
Когда ритуал важнее цели — это не agile. Поэтому любой формально описанный способ работы — не agile, даже если он подразумевает реагирование на изменяющиеся требования (гибкий). Scrum — не agile, хотя часто считают наоборот.

Важно, что быть agile — это не значит совсем не знать, куда идти, и что получится в результате. Мы должны представлять, что мы делаем и ради чего (иначе зачем мы это делаем?)

Быть agile — быть ловким, в том числе проявлять твёрдость, а не гибкость (в смысле податливость) в определённых условиях. Гибкость в agile — это не готовность во что бы то ни стало подстроиться под внешние обстоятельства, а способность снять лишние оковы строгого процесса («мы же так привыкли», «так же правильно действовать»), найти более эффективный путь, даже если он не соответствует привычному или навязанному снаружи образу деятельности. Тогда можно не только подстраиваться под обстоятельства, но и влиять на них для достижения цели.
👍4❤‍🔥3🔥2💯1
Программирование типов в TypeScript
#development

TypeScript избавляет нас от многих проблем с безопасностью типов, которые могут возникать в JavaScript-коде.
Но часто его используют не на полную мощность.
Система типов в TypeScript — отдельное поле для проектирования и программирования, которое позволяет на порядки улучшить безопасность и Developer Experience прикладного кода.

21 июня в 11:00 наш CTO Рамиль проведет познавательный завтрак «Программирование типов в TypeScript».

Рассмотрим примеры магии, которую можно сделать на типах своими руками.

Принимайте участие интерактивно в Zoom или смотрите трансляцию на нашем YouTube-канале.
🔥13
#development

Якорные ссылки в SPA

Одностраничные приложения (SPA) являются популярным подходом при создании современных веб-сайтов. И это не только модный тренд: SPA обладают рядом преимуществ по сравнению с традиционными приложениями.

Минусы подобного подхода также известны. Например, у SPA могут возникать проблемы с оптимизацией для поисковых систем (SEO), приложения могут долго открываться при первом запуске и нагружать устройства пользователей.

Но есть менее очевидные проблемы, с которыми можно столкнуться при разработке SPA. Одна из таких — это нерабочие якорные ссылки.

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

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

Почему так происходит?

При прямом переходе по якорной ссылке из внешних ресурсов браузер прокручивает страницу к нужному разделу сразу после того, как произойдет событие DOMContentLoaded. Это значит, что документ проанализирован, DOM готов, а синхронные и отложенные (defer) скрипты загружены и только начали выполняться. По крайней мере так работают якорные ссылки в Chrome и Safari. В этот момент может получиться так, что нужный элемент попросту отсутствует в документе, так как еще не все ресурсы загружены и не все скрипты успели выполниться.

А при переходах между страницами внутри одного приложения (то есть, когда используется например react-router в одностраничном приложении) браузер пытается перейти к секции по смене URI до того, как новая страница успевает отрисоваться.

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

Чтобы решить эту проблему, можно написать скрипт, который прокрутит страницу к нужному элементу уже после того, как DOM претерпит все изменения.

Также можно взять готовый пакет, например, react-router-hash-link для react-router. Он исправляет ряд проблем связанных с работой якорей в SPA на React. Подобные реализации есть и для других популярных фреймворков.

Однако лучшим вариантом будет отдавать полностью готовую HTML-страницу с сервера используя серверный рендеринг (SSR) или генератор статических сайтов (SSG). Это можно реализовать при помощи Next.js, Gatsby и др. В таком случае, когда браузер попытается перейти к нужной секции, DOM уже будет готов, а целевой элемент доступен.

Этот способ выглядит более естественным. Мы не выдумываем ничего нового, а используем уже существующие механизмы, реализованные в браузерах задолго до одностраничных приложений. А благодаря современным решениям мы можем «восстановить» изначальный принцип работы наших веб-сайтов, сохранив при этом преимущества SPA.
👍4🔥41
#development

Фронтенд на сервере

Когда-то веб-приложения были «бэкендоцентричны»: HTML-страницы генерировались на сервере, а для добавления динамических данных использовались шаблоны.

Со временем требования к интерактивности страниц стали выше, и фронтенд-технологии начали активно развиваться, в частности — подход Single Page Application (SPA). Фреймворки развивались так, что со временем фронтенд стал отдельным приложением, которое отдельно проектируется, разрабатывается отдельными людьми и хостится тоже отдельно.

Это разделение, при своих преимуществах, приводит к нескольким проблемам.

🔹 Код, отправляемый в браузер, становится тяжёлым и растёт при увеличении функциональности приложения.

🔹 Много логики переносится на клиент. Например, роутинг, который реализован заново и «в обход» механизмов браузера.

🔹 Много логики дублируется на фронтенде и бэкенде. Например, валидация и ограничение доступа.

🔹 Необходимо проектировать и разрабатывать API — дополнительный слой синхронизации фронтенда и бэкенда — даже там, где бэкенд выполняет только функции обслуживания интерфейса.

🔹 Разделение специалистов на фронтенд и бэкенд-разработчиков в командах создаёт накладные расходы, размывает понимание итоговой задачи и ответственности.

При этом принципы работы сети и браузеров не изменились: веб-сервисы с точки зрения пользователя — это всё так же цельные приложения. Для такой «цельной» разработки хорошо подходят фреймворки типа Next.js. Их возможности были сильно ограничены до недавнего времени, но последние версии Next.js и React меняют правила игры.

React представил серверные компоненты, а Next.js их реализовал вместе с новым подходом к роутингу — App Router. По сути, теперь часть React-компонентов выполняются на клиенте, а часть — на сервере, вместе формируя единую веб-страницу. Серверные компоненты могут напрямую работать с базой данных, и слой API становится необязательным — его заменяют механизмы роутинга Next.js. Полноценное веб-приложение становится возможно сделать вообще без бэкенда в старом смысле.

Интересно, что, например, Ruby On Rails — чисто бэкендовый фреймворк — тоже двигает границу разделения, но немного по-другому. Его авторы предлагают подход Hotwire — декомпозицию и стриминг отдельных частей HTML — в качестве альтернативы SPA.

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

История развивается по спирали. Больше кода снова выполняется на сервере, но теперь мы можем строить клиентские приложения любой сложности и красоты меньшими усилиями и с меньшими побочными эффектами.
🔥53👍3
Сложный выбор

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

Было два проекта. Мы планировали их делать друг за другом. Оба одновременно взять не смогли, не хватало рук. И вот когда первый уже подходил к концу, мы получили дополнительные задачи по нему и новые сроки, к которым не были готовы. По второму проекту формальных договорённостей не было, но мы обещали второму заказчику начать в определенный момент.

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

Стали думать, как преподнести второму заказчику неприятные новости в виде факта, что мы задерживаемся на 2 недели. При длительности проектов в 2-4 недели это существенно.

Можно ли было поступить иначе? Разбор кейса получился объёмным, прочитать его можно здесь.

Интересно узнать ваше мнение. Что ещё можно предпринять или как не допустить подобной ситуации?

#management
👍112👏1
#development

AI и Prompt engineering

Проектирование системы, основанной на LLM (Large Language Model), например, GPT, по большей части заключается в проектировании цепочек промптов. Промпт — текстовый запрос на естественном языке — по сути единственный интерфейс к LLM. И чтобы получить нужные результаты, нужно научиться строить корректные и точные запросы.

При этом важно учитывать особенности работы LLM.

🔹 Общение с LLM не хранит состояния и контекста. Всю «историю переписки» нужно передавать каждый раз.

🔹 Размер сообщения и ответа ограничен.

🔹 Результаты могут быть нестабильны. С одной стороны, это нестабильность формата и типа ответа — тут может помочь промпт-инжиниринг. С другой стороны — нестабильность ответов по сути: и к этому нужно готовить пользователей, чтобы они это понимали и правильно относились к результатам. Это задача проектирования UX.

🔹 Модель ограничена данными обучения.

🔹 Галлюцинирование. Без специальных указаний модель попытается дать ответ в любом случае: даже если данных не хватает, она его «придумает». Модель нужно явно инструктировать о том как получить ожидаемый результат. Показывать примеры или давать конкретные инструкции. Иначе может получиться результат, напоминающий требуемый по форме, но некорректный по сути.

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

Несмотря на это, есть ряд техник, который позволяют достичь достаточно хороших результатов. Например, суммировать историю переписки в короткий текст, чтобы экономить токены или использовать внешние агенты для того чтобы предоставлять данные или заведомо верные решения в модель. Рекомендуем начать с изучения некоторых источников, чтобы сэкономить время на экспериментах:
https://www.promptingguide.ai/
https://www.pinecone.io/learn/langchain/
А часть из техник уже реализованы в фреймворке LangChain.
👍7
#management

Формальное управление vs Реальность


Когда в обсуждении проектов появляются термины «риск», «стратегия минимизации», «ответственность», запал от интересной задачи угасает. Если мы ещё и реестры по шаблону составляем и ответственных за риски назначаем, то совсем 🤢

Причина не в отсутствии желания заниматься управлением. Просто такие разговоры кажутся чем-то искусственным, оторванным от реальности. Мы не говорим в обычной жизни «займёмся планированием» или «надо минимизировать риск». В итоге качество планирования страдает, потому что этим не интересно заниматься всем кроме рук.проекта. Может и ему неинтересно, но так надо.

А ещё формальные рассуждения и применение шаблонов из теории могут легко увести планы от реалистичности. Шаблон заполнили — всё правильно 🫣

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

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

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

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

«Начинаем согласование дизайна за неделю, а 14 ноября запускаем разработку по имеющимся макетам. Все последующие изменения добавляем в общий бэклог до запуска, согласуем приоритеты и двигаемся дальше. Иначе мы можем не успеть гораздо больше» 👍

С таким планом адекватные люди спорить не будут. Они не скажут: «Нет, не запускаете без согласования». Всем нужен результат в срок. Это целеориентированный подход с разделением ответственности за получение результата, а не перекладыванием её за каждый отдельно взятый риск 🤝

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

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

Как вам такой подход?
👍93🔥1
#development

v0

v0.dev — хорошее прикладное применение генеративного AI.

Это экспериментальный генератор интерфейсов на React от Vercel.

Инструмент может помочь небольшими усилиями создать функциональные интерфейсы типа форм и личных кабинетов.
Сгенерированные компоненты вполне можно взять за основу просто скопировав код — за счет атомарного подхода Tailwind CSS. UI строится на базе shadcn/ui и выглядит современно и приятно.
🔥111
#development

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

Наш QA-инженер Наташа написала статью о варианте решения этой проблемы с помощью интеграции Qase с Playwright и GitLab CI

https://habr.com/ru/articles/826008/
🔥8👍53
#management

Что не так с грейдами?

Описали, почему мы решили отказаться от грейдов специалистов в небольшой статье: https://vc.ru/dev/1392053-u-nas-v-kompanii-net-greidov-i-eto-prekrasno

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

А как вы относитесь к грейдам? Считаете, что они помогают вам лично и вашей компании? Или больше похоже на карго-культ?
🔥9👍2
Please open Telegram to view this post
VIEW IN TELEGRAM
7
Запустили наш pet project — onbalance (https://onbalance.app)

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

Фишки:
— Конфиденциальность by design — как в пассворд-менеджерах и крипто-кошельках. Данные только у вас.
— Нет обязательных полей (кроме суммы:)),
— Оффлайн-first и mobile native 😎 Быстро и приятно пользоваться.

📢 Мы только что вышли на Product Hunt и нам очень поможет ваша поддержка 🙌
https://www.producthunt.com/products/onbalance?utm_source=telegram&utm_medium=social
🔥134