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

Для связи 👉 @cherkalexander

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

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


Блог: https://cherkashin.dev
Download Telegram
Сегодня мне 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
function(): Promise 🆚 async function(): Promise

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

Пример

function fn(obj) {
const someProp = obj.someProp
return Promise.resolve(someProp)
}

async function asyncFn(obj) {
const someProp = obj.someProp
return Promise.resolve(someProp)
}

asyncFn().catch(err => console.error('Catched')) // => 'Catched'
fn().catch(err => console.error('Catched')) // => TypeError: Cannot read property 'someProp' of undefined


- при объявлении функции с ключевым словом async JavaScript гарантирует, что функция вернёт Promise, даже если в ней произошла ошибка
- если функция возвращает Promise, но объявлена без async то catch не поймает ошибку, если в функции произошла ошибка
- дело в том, что ошибки произошедшие внутри конструктора new Promise((resolve, reject) => { throw new ... }) промиса ловятся. Когда мы добавляем async, то по сути заворачиваем тело функции в new Promise((resolve, reject) ⇒ { })

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

function fn(obj) {
return new Promise((resolve, reject) => {
const someProp = obj.someProp;
resolve(someProp);
});
}


https://habr.com/ru/articles/475260/


#javascript #frontend
👍23🔥54
Как я обычно узнаю о новых фичах в C#

О новых фичах в C# я обычно узнаю с помощью подсказок Райдера — IDE для C# от JetBrains.

В общем, обновился, пишу код, и Райдер предлагает что-то исправить там, где раньше все было окей. Думаю — ну ок, давай исправим. Но ощущение, что он перепутал C# c JavaScript.

- string[] array = new [] { “a”, “b”, } предлагает заменить на string[] array = ["a", "b"]
- Array.Empty<string>() на []
- List<string> list = new (vowels) на List<string> list = [.. vowels]

Особенно интересен последний пример, очень уж напоминающий spread оператор из JS. И действительно, в C# его тоже завезли, правда по пути потеряли одну точку и назвали spread element.


int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];

int[] example1 = [..row0, ..row1, ..row2];
List<int> example2 = [..row0, row1[0]];


В общем, в C# 12 поднасыпали синтаксического сахара для работы с коллекциями. А ещё прихватили Primary конструктор из Scala. Это когда конструктор объявляется сразу после имени класса.


public class BankAccount(string accountID, string owner)
{
public string AccountID { get; } = accountID;
public string Owner { get; } = owner;

public override string ToString() => $"Account ID: {AccountID}, Owner: {Owner}";
}


Подробнее о релизе C# 12 здесь.

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

#csharp
👍4😁2👎1
Если бы вас спросили, что самое сложное в вашей работе, чтобы вы ответили?
Я думаю одна из самых сложных вещей - читать чужой код, или свой собственный, написанный пару лет назад.

👉 Сегодня статья о том, Как избежать когнитивной перегрузки: способы оптимизации кода для разработчиков.

Вот основные моменты из статьи, если вам лень читать всю статью в пятницу да ещё и летом 😅

- Когнитивная нагрузка – это объем умственной работы, необходимый разработчику для выполнения задачи. Нашим приоритетом должно быть максимальное снижение такой нагрузки в проектах.
- Типы когнитивной нагрузки:
- Внутренняя — изначальная сложность задачи, её нельзя уменьшить.
- Внешняя — создается способом представления информации. То есть то, как написан код, решающий задачу.
- Знакомая и простая вещь — не одно и то же. Они ощущаются одинаково — та же легкость перемещения по пространству без особых умственных усилий, но по совершенно разным причинам. Каждый «умный» и нестандартный прием приведет к трате времени на обучение для остальных разработчиков. После того, как они его освоят, им будет легче работать с кодом. Именно поэтому не так легко понять, как можно упростить уже знакомый код.
- Нет никакой «упрощающей силы», влияющей на базу кода, кроме вашего сознательного выбора. Упрощение требует усилий, а люди часто спешат.
- Отладка в два раза сложнее написания кода. Следовательно, если вы пишете код максимально хитроумно, вы по определению недостаточно умны, чтобы его отладить.

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

- DRY (Don’t repeat yourself) — хотя в целом это хорошее и фундаментальное правило, его чрезмерное использование приводит к непосильной когнитивной нагрузке. У DRY есть альтернатива AHA Programming
- Вы можете слишком рано извлечь общую функциональность, основываясь на предполагаемом сходстве, которого на самом деле в долгосрочной перспективе может не быть. Это может привести к ненужным абстракциям, которые будет непросто модифицировать или расширять.
- «Небольшое копирование лучше, чем небольшая зависимость».

https://habr.com/ru/companies/ncloudtech/articles/818643/

#fridayreading #essential
👍11💯4
Как инспектировать разметку попапов

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

Способ 1: Открываете DevTools ⇒ Вкладка Sources ⇒ Далее наводите мышкой на свой элемент ⇒ Нажимаете F8, чтобы приостановить выполнение скрипта

Способ 2: Открываете DevTools ⇒ Находите тег body или тот тег, внутри которого появляется попап и нажимаете на нём правой кнопкой ⇒ Выбираете “Break on ⇒ subtree modification” и дебажите до тех пор пока не появится попап.

Способ 3: Мой любимый. Вставляете скрипт в консоль и у вас есть 3 секунды чтобы показать попап. Именно этим способом пользовался пока не узнал про первый 😄

setTimeout(() => { debugger }, 3000)


#frontend #devtools
🔥22👍32😁2
source-map-explorer

На прошлой неделе анализировал размер главного бандла мобильной версии нашего приложения.

В спешке мы накосячили с импортами и бандл раздулся.

🤔 Как анализировать?

Для анализа использовал утилиту source-map-explorer.

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

К сожалению, почему именно это что-то попало в бандл утилита не говорит.

👉 В чём была проблема?

Иногда мы ленимся и в файле компонента кладём какую-нибудь утилитную функцию, enum или константу, а потом где-то в другом месте импортируем их.

Так вот, когда мы их импортируем, то в бандл “засасывает” не только импортируемую функцию, но и весь компонент, из-за чего размер бандла и увеличивается.

P.S. А какими инструментами пользуетесь вы?

#frontend #performance #tools
👍7🤡1
Со стороны может показаться, что у нас, у программистов, очень лёгкая работа. Как любит говорить мой тренер по теннису: “мол успешные айтишники сидят где-нибудь в эмиратах, птягивают кофе в кафешках и в ус не дуют”. В чем-то он может и прав, но почему-то не у всех получается “войти в айти”. А те, кто вошел, только и говорят о выгорании.


Года 3 назад я писал, что я делаю, чтобы не перегореть. С тех пор добавилось ещё несколько привычек.

🎾 Я начал играть в большой теннис. Пока бегаешь по корту и чуть ли не выплёвываешь свои лёгкие, совсем забываешь о работе.


🏃‍♂️ С нового года я начал делать зарядку, увидел пост у Евгения Шушкова и тоже решил попробовать. Не уверен, что я чувствую себя намного лучше, но зарядка определённо помогает проснуться. Но что гораздо лучше, она помогает на какие-то 15 минут немного избавиться от тревожности.

- Обычно я делаю вот этот комплекс на 15 минут
- Или этот на 5 минут, когда лень, но чтобы не потерять привычку


💪 В дополнение к зарядке стараюсь пару раз в неделю подтягиваться или отжиматься. Или же делаю вот этот комплекс на пресс, первые 4 минуты, потом пресс умирает.


📱В мае я отписался от новостных каналов.

---

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

P.S.

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

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

Я вообще считаю, программирование это не про “писать код”, это про людей. И мы можем сделать жизнь людей лучше не только написав очередные 1000 строчек кода.
26
Первый шок от последних событий начал проходить, поэтому вчера я немного разобрал инбокс и нашёл в нём статью, которой решил с вами поделиться “4 тысячи заметок?! Как я веду личную базу знаний в Obsidian”.

Автор рассказывает, как ему надоело забывать важную информацию и он решил завести личную базу знаний в Obsidian, вдохновившись Zettelkasten.

Zettelkasten – это такая система ведения личных заметок, в которой каждая заметка:

- Атомарна. То есть независима и содержит одну мысль.
- Имеет контекст. Например, размечена по тегам, темам.
- Связана с другими знаниями в системе.

Obsidian — это приложение для заметок на максималках. Главное преимущество перед тем же Notion — очень просто добавить новую связь между заметками и легко масштабировать базу (ну и данные все хранятся локально, насколько я помню). Автор использовал видео Виктора Теплова для настройки Obsidian.

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

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

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

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

---

А расскажите,

- чем пользуетесь вы для ведения заметок?
- какие подходы и практики используете?

Я пользуюсь Notion. Но вот на днях пришло письмо от Miro, о том, что они “не могут обслуживать клиентов, зарегистрированных в запрещённом регионе” с 12 сентября. И кто сказал, что скоро Notion не пришлёт такое же письмо, возможно стоит начинать искать альтернативы …

#obsidian #fridayreading
1👍6