cherkashin.dev
2.11K subscribers
251 photos
15 videos
277 links
Александр Черкашин. Бойскаут, Борец с перфекционизмом.

Для связи 👉 @cherkalexander

Фулстек разработчик в decisions.com. Работаю со стеком TypeScript, React, C#

Пишу о программировании и не только.


Блог: https://cherkashin.dev
Download Telegram
Несмотря на то, что с балетом у меня натянутые отношения (предыдущие пару раз я еле досидел до конца и грозился, чтобы я ещё раз?!), жена уговорила меня поехать в Москву в Большой театр на Лебединое озеро.

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

Если кто-то не знает — Teamly, это 🇷🇺 российский аналог Notion и Confluence. Каждые пол года компания организовывает бесплатную конференцию, где рассказывает о новой версии продукта и о важности управления знаниями в целом. Конференция была на уровне, что в принципе видно по качеству записи трансляции.

ℹ️ Вот некоторые тезисы, из докладов спикеров:

- Чем больше компания — тем больше пользы от системы управления знаниями.
- Если в вашей компании много департаментов — внедрение можно начать с «департаментов-энтузиастов», которые любят внедрять что-то новое. Так будет легче начать внедрение.
- Проект нужно разрабатывать не с конца, а с начала. Например, сначала следует убедиться, что вы можете получить данные для системы, до того как приступить к её разработке. Иначе вы рискуете потратить много времени, денег и сил.
- Всем нам сложно делиться своими провалами, поэтому важно в компании выстраивать культуру так, чтобы сотрудники могли безболезненно о них говорить. Тут поможет встреча Fails nights, на которой, например, раз в квартал сотрудники могут рассказать о своих факапах, а остальные бы могли учиться на чужих ошибках. Подробнее в статье Miro.
- Если благодаря работе у сотрудников закрываются их потребности, например, они выступают на внутренних митапах или делятся знаниями, то они более лояльны компании и не захотят уходить к конкурентам.
- В Teamly можно реализовать поиск сотрудника по компетенциям. У каждого сотрудника есть личная страница, на ней указываются навыки, а система позволяет искать по этим навыкам. Например, если вам нужен эксперт по Google Sheets и MongoDB, то вы можете легко его найти. Основное преимущество в том, что вся информация хранится в одном месте. Буквально на прошлой неделе в нашей компании решили составить подобный список в Google Sheets, и я уверен, со временем он потеряется и никто его не найдёт.

🔥 Отдельного внимания заслуживает Гарретт Джонстон, его выступление рекомендую посмотреть полностью. Оно может показаться своеобразным, но внимания точно заслуживает.

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

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

P.S.
От балета удовольствия я особо не получил, а обзор новых функций Teamly вы можете посмотреть здесь.

#conference #teamly
👍4🔥43
📖 Cohesion и Coupling: отличия

Сегодня посоветую короткую статью, чтобы наконец-то разобраться что есть что.

🛑 Основные моменты

- Нужно стремиться к достижению low coupling (низкой связанности) и high cohesion (высокого сцепления)
- Cohesion — степень, в которой часть кодовой базы образует логически единую атомарную единицу — блок.
- Coupling — степень взаимосвязи между этими блоками.
- Блок здесь необязательно является классом. Это может быть метод, класс, группа классов или даже модуль: понятия cohesion и coupling применимы на разных уровнях.
- Высокий cohesion означает хранение связанных друг с другом частей кода в одном месте.
- Например, мы храним код работы с пользователями в одном месте, и это может быть как стандартный MVC контроллер, так и отдельный микросервис.
- В то же время низкий coupling заключается в максимально возможном разделении несвязанных частей кодовой базы.
- Например, react и react-dom хранятся в разных пакетах, благодаря чему мы можем использовать react-native вместо react-dom и писать нативные приложения.
- В отличие от такого показателя, как цикломатическая сложность, степень cohesion  и coupling не может быть измерена напрямую.


ℹ️ Понятие cohesion похоже на Принцип единственной ответственности, который утверждает, что у класса должна быть одна ответственность, что аналогично тому, что делает код с высоким cohesion. Разница здесь в том, что высокий cohesion необязательно означает, что код должен иметь только одну ответственность. Можно сказать, что Принцип единственной ответственности в этом смысле более строгий.

#essential #fridayreading
👍94🔥3
🧑‍💻 Giga Code

Месяц назад я отключил Codeium и честно начал тестировал GigaCode (альтернативу Copilot от Сбера). Но похоже придётся переключаться обратно, GigaCode ещё сыроват…

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

Но пока то и дело (ну очень часто) возникает ощущение, что GigaCode путается под ногами, и мешает писать код, а вовсе не помогает (карточка 4):

- Он то и дело вставляет ненужные закрывающие скобки и кавычки, которые VS Code уже вставил за меня.
- Другая надоедливая ситуация — он не может уследить, что я уже написал часть слова и предлагает вставить её ещё раз.

В общем, пока ждём улучшенной версии …

@cherkashindev

#ai
👍143🔥2🤡1
Сегодня мне 2️⃣8️⃣, примерно как седых волос на моей голове. С недавних пор у нас в компании дают выходной на ДР, поэтому сегодня я гуляю по Сочи, пью пока что только кофе, спокойно пишу этот пост и смотрю как работает моя жена 😃.

Можете начинать желать мне счастья, здоровья, а если бустанёте канал или порекомендуете какой-нибудь курс по программированию, то будет вообще замечательно 😉.

---

Одной из моих целей на год было набрать 1000 подписчиков в этом канале, и вот вчера Виталий Зюзин легким движением руки выполнил мою цель на год. Он создал папку с телеграмм каналами о фронтенде, которая завирусилась и вот нас уже 1300+, обязательно забирайте папку себе и выбирайте каналы, которые вам по душе.

Всем с кем ещё не знакомы — привет, меня зовут Саша 👋, живу в маленьком и уютном Курске. В разработке я примерно 8 лет и почти 7 из них я работаю в американской компании Decisions.

📝 Время от времени пишу на Хабр:

- Интегрируем Яндекс Музыку в Visual Studio Code
- Бессильный сборщик мусора или неуправляемая память в .NET
- Система личного планирования в Notion. Эпизод 1 — Инбокс

✏️ На канале в основном пишу о своём опыте, а по пятницам рекомендую доклады и статьи #fridayreading. Вот некоторые посты, которые могут быть полезны:

- Проверка именования файлов и папок с помощью плагина eslint-plugin-import
- React – Compound Components
- Именование юнит тестов
- Обязан ли разработчик развиваться
- Где проводить live-coding

Если у вас будут вопросы или просто хочется поболтать — обязательно пишите 👋.

@cherkashindev

#about_me
Please open Telegram to view this post
VIEW IN TELEGRAM
🎉21👍16🔥31
🎉 Шорт-листы "Технотекста 2023" на Хабре

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

Сегодня хабр опубликовал список финалистов куда попало порядка 300 статей. Если не знаете, что почитать пока гоняются ваши тесты, переходите сюда и выбирайте понравившуюся статью.

В этом году, в финал попала и мою статья Интегрируем Яндекс Музыку в Visual Studio Code, обязательно прочтите, если ещё этого не сделали.

#habr
🎉7👍4🔥2
🏗️ Паттерн “Простая фабрика”

Ранее я писал:
- об абстракции
- и о полиморфизме

Логическое продолжение этой “базы” — паттерн “простая фабрика”. Он является более простой альтернативой для порождающих паттернов:

- фабричный метод
- абстрактная фабрика

По ощущению, используется гораздо чаще, чем его старшие братья (на нём держится весь полиморфизм 😄).

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

Выглядит следующим образом:

function createGitService(type: string, host: string, token: string): GitService | null {
switch (type) {
case 'Gitlab':
return new GitlabService(host, token);
case 'Gitea':
return new GiteaService(host, token);
default:
return null;
}
}


💡 Что нам это даёт?
- Упрощает код, когда нужно избежать прямых зависимостей от конкретных классов;
- Позволяет инкапсулировать логику создания объектов, ведь логика может быть сложнее, чем простая передача параметров в конструктор.

Этот же паттерн используется внутри хорошо известного вам document.createElement("div") метода. Мы передаём название тега, а метод создаёт тег нужного нам типа.

Как-нибудь расскажу, как он работает под капотом в Хроме.

#patterns #essential #oop

@cherkashindev
👍17🔥4
Сегодня посоветую одну довольно интересную статью (не зря же она была написана в мой день рождения).

Как обхитрить мозг и заставить его полюбить сложные задачи [Дофаминовый детокс]

Если кратко: перестать баловаться лёгким дофамином.

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

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

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

💡 Ответ прост: проведите дофаминовую детоксикацию.

- Выделите день, в течение которого никаких «высокодофаминовых» активностей происходить не будет. Избегайте интернета, любых гаджетов, например, смартфона или компьютера. Ну или постарайтесь лимитировать такие активности.
- Вознаграждайте себя «высокодофаминовыми» активностями, после выполнения «скучных» дел. Например, за каждый час работы позвольте себе 10-15 минут «высокодофаминового» отдыха в конце дня.

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

---

А я пока пробую такие способы:
- Отписался от всех новостных каналов (третья попытка за 2 года)
- Первый час после пробуждения не беру в руки телефон

Теперь бы ещё пиво пореже пить, но не всё же сразу 🍻)

#fridyareading #burnout
👍223😁2🙉2
Уже давно поймал себя на мысли, что стал редко посещать конференции. Поэтому решил всю эту неделю провести на Podlodka React Crew.

👉 Для тех кто ни разу не был — формат следующий:

- С понедельника по пятницу: — один доклад утром в 11:00, один вечером в 19:00
- Разные форматы: доклады, собесы, круглые столы
- Отдельное спасибо организаторам за рандом кофе, это когда вы созваниваетесь со случайны человеком и болтаете о чём вашей душе угодно.

Узнал много нового:

- В реакте одни проблемы и лучше переходить на другой фреймвор. Правда но на какой, так никто и не рассказал, так что остаёмся
- У Effector’а давние тёрки с Reatom’ом 🔥
- При открытии собственного бара — самое сложное договориться с поставщиками
- Для создания классных интерактивных презентации можно использовать:
- reveal.js
- shower.js
- sli.dev
- gamma.app
- У JQuery вышла бета мажорной 4-ой версии 😅

💡 Ну а если серьёзно, то было много интересных докладов. Вот некоторые заметки, которые сделал за время конференции:

- Архитектура программного обеспечения — совокупность важнейших решений об организации программной системы
- В стартапе при выборе архитектуры — главное принять поменьше плохих решений.
- Если вы что-то не успели отрефакторить — новые разработчики быстро растащат этот код по всему проекту.
- Если вы хотите мигрировать на новую технологию, но это не влияет на показатели бизнеса — возможно эта миграция и не нужна.
- В императивном подходе мы описываем, откуда что поменять. А в реактивном — откуда что взять.
- Function as a child component (FACC) — паттерн схожий с Compound Components.
- Astro — движок для блогов.
- Скоро в Feature-Sliced Design вот вот появится плагин, для файловой структуры проекта и не только 🔥

Ещё хотел подать заявку на открытый микрофон и рассказать, как мы мигрируем с JQuery на React. Даже накидал 20% доклада, но понял, что подготовиться не успею и вовремя остановился, может в следующий раз 😅.

А вообще атмосфера очень зашла. Я работаю по большей части удалённо, поэтому было приятно почувствовать себя частью сообщества. Организаторам спасибо ♥️

#about_me #conference
🔥19👍84💩2
zustand и redux-devtools

Я всё ещё пытаюсь доделать свой пет-проект для построения графиков на основе данных из пул реквестов и комментариев.

В качестве стейтменеджера использую zustand. Своих девтулзов у него нет, но разработчики реализовали middleware для отображения данных в redux-devtools.

При использовании zustand’а часто создают много маленьких сторов, поэтому чтобы не оборачивать каждый вызов create в middleware — пишем небольшой утилитный метод createStore:


import { create } from 'zustand';
import { devtools } from 'zustand/middleware';

export const createStore = <T>(fn: Parameters<typeof devtools<T>>[0], name: string) => {
return create<T>()(devtools(fn, { name, enabled: process.env.NODE_ENV !== 'production' }));
};



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

Нашёл 2 проблемы:

1. Стандартная. Весь контент страницы был в одном компоненте, поэтому при обновлении локального стейта перерендеривались все компоненты.

 Решение простое — вынес все 20+ графиков в отдельный компонент и обернул его в React.memo.

2. Работает быстрее, но всё ещё есть небольшая задержка. Девтулзы реакта ничего не показывают — запускаю стандартные девтулзы хрома. Вижу, что большую часть времени занимает не обновление стейта, а какой-то левый скрипт. Перехожу в его исходники и вижу там слово “Redux”.

ℹ️ Отключаем redux-devtools и всё работает очень быстро.

Всё дело в том, что у меня в сторе хранятся все пулреквесты (4000) и комментарии (5200) за год, из-за такого количества данных redux-devtools подтормаживает.

В общем, проблема не всегда в вашем коде, но это в любом случае — это ваша проблема 😄.

#zustand #react #statemanagement
👍114🔥3
peerDependencies

Недавно делал код ревью и заметил, что в pnpm-lock.yaml (альтернатива yarn.lock в pnpm) добавлена 17-я версия реакта, хотя на проекте мы используем 18-ю. Нам не нужно тянуть в проект 2 версии реакта — поэтому идём разбираться.

Дело в том, что в библиотеке react-cheetah-grid, которую мы используем для рендера длинных таблиц, реакт указан в секции dependencies вместо peerDependencies.

dependencies vs peerDependencies

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

Чтобы быстро исправить проблему — можно переопределить версию реакта для определённого пакета в pnpm с помощью метода readPackage. Также нужно откатить изменения в pnpm-lock.yaml и запустить pnpm install .


// .pnpmfile.cjs

const package = require('./package.json');

function readPackage(pkg, context) {
if (pkg.name === "react-cheetah-grid") {
pkg.dependencies['react'] = package.dependencies['react'];
pkg.dependencies['react-dom'] = package.dependencies['react-dom'];
}

return pkg;
}

module.exports = {
hooks: {
readPackage,
},
};


Но затем лучше создать ишью в репозитории библиотеки или отправить пул реквест.

#react #pnpm
👍20🔥4
На прошлой неделе проверял почту и наткнулся на рассылку от Я.Практикума “Что нельзя делать хорошему менеджеру”. Одна из упоминаемых проблем – “Срезание углов” или экономия времени на продумывании ТЗ. Чтобы избежать проблемы понимания требований исполнителем – нужно научиться смотреть на ТЗ глазами новичка. Такое же правило я применяю при написании кода:

Нужно смотреть на код глазами новичка.

Представьте, что вы новый сотрудник и ничего не знаете кроме того, что написано в коде.

- Поймёт ли он, что именно происходит в коде?
- Почему это реализовано именно так?
👍123👏1
Мемоизация селекторов в Zustand

Если вы используете Zustand, то знаете, что computed значения реализуются с помощью селекторов.


const userPrs = useChartsStore((state) => {
return state.pullRequests.filter(pr => pr.author.id === state.user.id);
});


В примере выше:

- при каждом обновлении стейта значение селектора будет вычисляться заново
- это приведёт к ре-рендеру компонента, так как каждый раз мы постоянно возвращает новый массив по ссылке, а по-умолчанию используется строгое сравнение (old === new).

Чтобы решить эту проблему в Zustand есть хук useShallow , который сделает “поверхностное” сравнение предыдущего и нового значения. Если они равны — ре-рендер не произойдёт.


const userPrs = useChartsStore(useShallow((state) => {
return state.pullRequests.filter(pr => pr.author.id === state.user.id);
}));


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

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

Также он отмечает, что для этих целей можно использовать метод memoize из его библиотеки proxy-memoize (для redux есть reselect).

Аналогично immer’у proxy-memoize работает на основе Proxy. memoize запоминает предыдущий параметр функции и свойства к которым обращались в селекторе (для этого и нужен Proxy). При следующем выполнении функции, он проверит изменились ли используемые свойства, если нет — вернёт значение, вычисленное в прошлый раз.


const authorSelector = memoize((state) => state.pullRequests.filter(pr => pr.author.id === state.user.id));

const userPrs = useChartsStore(authorSelector);


Конечно, нужно помнить, что мемоизировать можно только “чистую” функцию — если она возвращает одни и те же значения в ответ на одни и те же аргументы

Так, обернув пару селекторов в memoize, я ускорил фильтрацию пул-реквестов в более чем 20 раз (900мс ⇒ 40мс).

#react #zustand #statemanagement #frontend
👍14🔥3🥴2🥱1
Generic React-компоненты

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

И тогда я впервые задумался, поддерживает ли React дженерики в связке с TypeScript (а почему бы ему их не поддерживать?).

Каркас компонента выглядит так

export interface SearchBoxProps<T> {
search: (text: string) => T[] | Promise<T[]>;
renderItem: (item: T) => React.ReactNode;
// ...
}

export function SearchBox<T>(props: SearchBoxProps<T>) {
// ...
}


А использование так

<SearchBox
search={() => [1, 2, 3]}
renderItem={(item) => <div>{item}</div>}
/>


TypeScript отлично выводит типы, но недавно я узнал, что их можно указать и в JSX. Раньше думал, что будут проблемы из-за угловых скобок < > в дженериках

<SearchBox<number>
search={() => [1, 2, 3]}
renderItem={(item) => <div>{item}</div>}
/>


💡 Когда использовать дженерики для реакт-компонентов?

Когда компонент может принимать:

- данные разных типов
- и рендер-пропсы/слоты, чтобы преобразовать эти данные в UI

Ещё один пример можете посмотреть вот в этом видео

#react #frontend #typescript
👍11🔥42
Сегодня принёс вам одну из лучших статей по код ревью.

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

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

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

Также ещё одна мысль, которую доносит автор — “код ревью не должно быть одинаковым для всех изменений”.

🐌 Проблемы медленных ревью

- Они медленные 🤷‍♂️  — замедляют релиз на несколько часов или дней
- Поверхностные — не улучшают качество кода, не происходит обмен знаниями.
- Если ревью происходит медленно — разработчики начинают создавать большие пул реквесты, что увеличивает нагрузку на ревьюера и делает код ревью ещё медленнее.

Подходы, которые описываются в статье

Автор долго придерживался принципа Ship / Show / Ask

- 🚢 Ship. Изменения простые, нет знаний, которыми стоит поделиться — льём в прод без ревью.
- 🔍 Show. Если изменения простые, но в них есть что-то полезное и ими стоит поделиться (например вы написали новую функцию или компонент), то — сливайте изменения, а потом просите о код ревью. Код ревью — не блокирующий. Я обычно называю это постревью.
- Ask. Если вы вносите сложные изменения — дождитесь код ревью и только потом сливайте изменения. Тут код ревью блокирующий.

Со временем он его немного перефразировал в Automate / Defer / Pair

- 🤖 Automate. Если в изменениях нет знаний, которыми стоило бы поделиться, а в коде особо нечего улучшить — пропускаем ревью и полагаемся на линтеры, статические анализаторы и тесты.
- ↪️ Defer (отложить). В зрелом и проверенном процессе разработки большинство изменений нужно ревьюить, но ревью не должно быть блокирующим. Это особенно хорошо работает, когда новая фича деплоится за фича флагом и можно спокойно получить фидбек после деплоя.
- 👯 Pair. Если корректность изменений очень важна: их сложно откатить или изменения связаны с оплатой, или же изменения достаточно сложные — то вам нужно работать в паре с ревьюером, созвониться и объяснить ему изменения, чтобы он был в контексте и смог сделать ревью быстрее и качественнее.

#codereview #fridayreading #weekphrase
🔥11👍62