Forwarded from PiterJS (Наталья)
✨ На грядущем PiterJS для вас выступит Маргарита Лукина с докладом:
Эволюция SSR в React приложениях
Появление серверных компонентов внесло путаницу в React сообществе.
🔸Чем серверные компоненты отличаются от клиентских?
🔸В чем преимущества тех и других?
🔸Как они работают под капотом?
Доклад ответит на этот и другие вопросы
Важно! На территорию университета можно пройти только при подтверждении личности! Регистрируйтесь под своим именем и фамилией и возьмите на мероприятие паспорт! 🔥
✨ Регистрируйтесь под своим именем и фамилией, если допустили ошибку => отмените регистрацию и сделайте корректную.
До встречи 😊
Эволюция SSR в React приложениях
Появление серверных компонентов внесло путаницу в React сообществе.
🔸Чем серверные компоненты отличаются от клиентских?
🔸В чем преимущества тех и других?
🔸Как они работают под капотом?
Доклад ответит на этот и другие вопросы
Важно! На территорию университета можно пройти только при подтверждении личности! Регистрируйтесь под своим именем и фамилией и возьмите на мероприятие паспорт! 🔥
✨ Регистрируйтесь под своим именем и фамилией, если допустили ошибку => отмените регистрацию и сделайте корректную.
До встречи 😊
🔥12
Композитная структура фронтенд проекта
Многие мои знакомые в курсе, что я недолюбливаю FSD. В целом, мне не импонируют любые достаточно плоские методологии структурирования проектов - как раз из-за своей плоскости. “Плоским” я называю структуру, в которой у нас существуют директории, предполагающие наличие большого количества содержимого. Например, папочка components, в которой может быть 100 и более компонентов. В таком количестве очень сложно найти то, что тебе нужно. Сегодня поделюсь рецептом структуры, которой пользуюсь я сама. Дисклеймер: возможно, он уже был где-то и кем-то описан - но я про это не в курсе 😊 Я называю такую структуру композитной, потому что она напоминает мне паттерн “компоновщик” (Composite). Итак:
1️⃣ На верхнем уровне я располагаю основные директории - app (главный файл, конфиги приложения), pages (страницы), components (компоненты), helpers (хелперы), store (стор). Важно: в components мы кладем не любые компоненты, а только глобальные - то есть такие, которые используются повсюду в нашем приложении. Аналогично используем хелперы и стор - только для глобальных сущностей.
2️⃣ В pages создаем страницы.
3️⃣ В страницах повторяем верхнюю структуру:
4️⃣ Внутри компонентов структура может снова повторяться: например, компонент
5️⃣ Для каждой страницы действуем по аналогичному принципу.
Таким образом, общий принцип: кладем сущность туда, где она непосредственно используется. Если сущность используется в нескольких местах, кладем на общий уровень для мест использования. На примере компонентов:
🔵 Компонент
🔵 Компонент
🔵 Компонент
#архитектура
Многие мои знакомые в курсе, что я недолюбливаю FSD. В целом, мне не импонируют любые достаточно плоские методологии структурирования проектов - как раз из-за своей плоскости. “Плоским” я называю структуру, в которой у нас существуют директории, предполагающие наличие большого количества содержимого. Например, папочка components, в которой может быть 100 и более компонентов. В таком количестве очень сложно найти то, что тебе нужно. Сегодня поделюсь рецептом структуры, которой пользуюсь я сама. Дисклеймер: возможно, он уже был где-то и кем-то описан - но я про это не в курсе 😊 Я называю такую структуру композитной, потому что она напоминает мне паттерн “компоновщик” (Composite). Итак:
1️⃣ На верхнем уровне я располагаю основные директории - app (главный файл, конфиги приложения), pages (страницы), components (компоненты), helpers (хелперы), store (стор). Важно: в components мы кладем не любые компоненты, а только глобальные - то есть такие, которые используются повсюду в нашем приложении. Аналогично используем хелперы и стор - только для глобальных сущностей.
2️⃣ В pages создаем страницы.
3️⃣ В страницах повторяем верхнюю структуру:
components
, helpers
, store
. Сразу уточню, что папочки добавляем по мере создания файликов - пустые папки нам не нужны :) Но на этом уровне кладем сюда только те компоненты/хелперы/стор, которые используются на этой странице. То есть в pages/Home/components
может лежать, например, компонент Hero
- если он используется на главной странице и больше нигде.4️⃣ Внутри компонентов структура может снова повторяться: например, компонент
Hero
может содержать дочерние компоненты, а также может содержать хелперы.5️⃣ Для каждой страницы действуем по аналогичному принципу.
Таким образом, общий принцип: кладем сущность туда, где она непосредственно используется. Если сущность используется в нескольких местах, кладем на общий уровень для мест использования. На примере компонентов:
🔵 Компонент
Card
используется только на странице Catalog
- кладем компонент в src/pages/Catalog/components/Card
🔵 Компонент
CardHeader
используется только внутри компонента Card
- кладем компонент в src/pages/Catalog/components/Card/components/CardHeader
🔵 Компонент
Button
используется везде - кладем в src/components
.#архитектура
1🔥15👍7❤4
В наше время только ленивый не делает гипотез о том, как ИИ изменит нашу профессию. Я не ленивая, поэтому впишусь в общий тренд и тоже выскажу свою гипотезу относительно того, какие навыки фронтенд разработчиков будут востребованы через 5 лет:
1️⃣ DDD
ИИ умеет писать код, но ему необходим контекст. DDD - отличный способ донести контекст вашего проекта до машины.
2️⃣ Архитектура на уровне кода (SOLID, GRASP, etc)
Как правило, мы закидываем в ИИ какую-то часть нашего проекта. ИИ может отредактировать код таким образом, что он будет работать для выбранной части контекста, но сломается на том, что осталось за скобками. На днях видела такую картину: знакомый при помощи ИИ пофиксил баг в модалке, не особо вчитываясь, что там ему ИИ сгенерировал. В итоге модалка успешно починилась для того кейса, который знакомый закинул в ИИ, но, как оказалась, эта модалка использовалась еще и в других местах, и вот там новые правки все сломали. Необходимо будет понимать, как разделять ответственность между компонентами таким образом, чтобы ИИ было удобно модифицировать получившиеся куски.
3️⃣ Продвинутая верстка
Если вы когда-нибудь пробовали десятком промптов уточнить чату гпт картинку, которую нужно сгенерировать, вы поймете, в чем проблема. Объяснить человеку, какую картинку хочется получить, все еще намного проще. То же самое касается анимаций. Кроме того, продвинутые навыки верстки вам потребуются, если вы захотите сделать что-нибудь эдакое, что редко встречается и, соответственно, ИИ не имел возможности обучиться делать это на большом количестве случаев.
1️⃣ DDD
ИИ умеет писать код, но ему необходим контекст. DDD - отличный способ донести контекст вашего проекта до машины.
2️⃣ Архитектура на уровне кода (SOLID, GRASP, etc)
Как правило, мы закидываем в ИИ какую-то часть нашего проекта. ИИ может отредактировать код таким образом, что он будет работать для выбранной части контекста, но сломается на том, что осталось за скобками. На днях видела такую картину: знакомый при помощи ИИ пофиксил баг в модалке, не особо вчитываясь, что там ему ИИ сгенерировал. В итоге модалка успешно починилась для того кейса, который знакомый закинул в ИИ, но, как оказалась, эта модалка использовалась еще и в других местах, и вот там новые правки все сломали. Необходимо будет понимать, как разделять ответственность между компонентами таким образом, чтобы ИИ было удобно модифицировать получившиеся куски.
3️⃣ Продвинутая верстка
Если вы когда-нибудь пробовали десятком промптов уточнить чату гпт картинку, которую нужно сгенерировать, вы поймете, в чем проблема. Объяснить человеку, какую картинку хочется получить, все еще намного проще. То же самое касается анимаций. Кроме того, продвинутые навыки верстки вам потребуются, если вы захотите сделать что-нибудь эдакое, что редко встречается и, соответственно, ИИ не имел возможности обучиться делать это на большом количестве случаев.
1❤11🔥4👍1
В последнее время очень много вопросов в личку про оформление резюме. Только сегодня мне с этим вопросом написали трое - а ведь люди должны в это время жевать шашлыки 😊 В этом посте поделюсь с вами подробным рецептом приготовления хорошего резюме. Дисклеймер: информация актуальна для РФ.
0️⃣ Предварительные условия
Помните, что серебряной пули не существует. Единственный способ составить действительно идеальное резюме - это соврать в нем. Реальный человеческий опыт всегда имеет какие-то слабые места, несоответствие портрету “идеального кандидата”. Чем лучше ваш реальный опыт, тем лучше будет ваше резюме (при условии, что вы его не выдумываете). Если какой-то ментор обещает вам составить 100% рабочее резюме и при этом ничего в нем не придумывать - он вас обманывает.
Общие рекомендации
1️⃣ Помните, что вы составляете резюме в первую очередь для ATS и только во вторую очередь для HR и технических специалистов
Поэтому, если вам в голову пришла идея использовать какой-нибудь необычный шаблон для резюме - оставьте ее. У ATS могут возникнуть проблемы с тем, чтобы его распарсить. Придерживайтесь лаконичной структуры, чтобы и человек, и робот сразу мог понять, где какая информация.
2️⃣ Не указывайте свой возраст
Компании часто имеют представление о том, какого возраста должен быть их идеальный кандидат, и по этой причине фильтруют как слишком “молодых”, так и слишком “возрастных”. По ТК РФ работодатель не имеет права дискриминировать вас на основании возраста - с вашей стороны вы можете не давать ему лишнего соблазна этого сделать, просто убрав возраст из резюме. На hh убирается в разделе “Профиль -> Основная информация”
3️⃣ Укажите свой telegram в контактах
Эйчары часто используют телеграмм для связи с кандидатами. Укажите свой телеграмм в контактах. Зайдите “Резюме -> Контакты” и добавьте свой телеграмм в раздел с телефоном или “другой сайт”.
Сделайте ваше резюме понятным
Для того, чтобы вас позвали на собеседование, эйчар по вашему резюме должен понять, что вы за специалист и сможете ли вы решить необходимые задачи. В следующих пунктах - подробнее о том, как сделать свое резюме понятным.
4️⃣ Описывайте процесс работы, а не результат
Разработчики очень часто описывают в резюме не результаты, а обязанности, и, кроме того, делают это размыто. Пример: “реализовывал фронтенд приложения с нуля для заказчиков”. Что это были за проекты, что они умели делать? Например, я ищу разработчика, чтобы он сделал мне личный кабинет пользователя - как по такому описанию я должна понять, справитесь вы с задачей или нет? Акцент должен быть на результат и пользу ваших действий. Пишите результаты своей работы так, чтобы они были понятны даже человеку, который не знаком с вашей компанией, вашими проектами и вообще в первый раз о них слышит. Например: “разработал модуль корзины, интегрировал его с бекендом, добавил аналитику действий пользователя”. Благодаря такому описанию работодатель сможет понять, какие задачи вы можете решать. Вы можете проверить ваше резюме, дав его прочитать другу- если он поймет, чем вы занимались, то опыт работы описан верно.
5️⃣ Для каждого проекта укажите стек, с которым вы работали
Это важно, чтобы работодатель понимал, насколько вы опытны в работе с той или иной технологией.
6️⃣ Укажите сферу деятельности компаний, в которых вы работали
Если работали в аутсорсе - укажите сферу деятельности заказчиков. Это важно, потому что разработчики со знанием доменной области быстрее погружаются в проект. Если компания занимается разработкой интернет-магазинов, то опыт работы с похожими системами будет существенным плюсом.
7️⃣ Для каждого проекта кратко укажите размер команды
Например: “2 бекенд разработчика, 3 фронтенд разработчика, 2 qa”
Это нужно для того, чтобы эйчар понимал, с какими специалистами вы привыкли коммуницировать.
#резюме
0️⃣ Предварительные условия
Помните, что серебряной пули не существует. Единственный способ составить действительно идеальное резюме - это соврать в нем. Реальный человеческий опыт всегда имеет какие-то слабые места, несоответствие портрету “идеального кандидата”. Чем лучше ваш реальный опыт, тем лучше будет ваше резюме (при условии, что вы его не выдумываете). Если какой-то ментор обещает вам составить 100% рабочее резюме и при этом ничего в нем не придумывать - он вас обманывает.
Общие рекомендации
1️⃣ Помните, что вы составляете резюме в первую очередь для ATS и только во вторую очередь для HR и технических специалистов
Поэтому, если вам в голову пришла идея использовать какой-нибудь необычный шаблон для резюме - оставьте ее. У ATS могут возникнуть проблемы с тем, чтобы его распарсить. Придерживайтесь лаконичной структуры, чтобы и человек, и робот сразу мог понять, где какая информация.
2️⃣ Не указывайте свой возраст
Компании часто имеют представление о том, какого возраста должен быть их идеальный кандидат, и по этой причине фильтруют как слишком “молодых”, так и слишком “возрастных”. По ТК РФ работодатель не имеет права дискриминировать вас на основании возраста - с вашей стороны вы можете не давать ему лишнего соблазна этого сделать, просто убрав возраст из резюме. На hh убирается в разделе “Профиль -> Основная информация”
3️⃣ Укажите свой telegram в контактах
Эйчары часто используют телеграмм для связи с кандидатами. Укажите свой телеграмм в контактах. Зайдите “Резюме -> Контакты” и добавьте свой телеграмм в раздел с телефоном или “другой сайт”.
Сделайте ваше резюме понятным
Для того, чтобы вас позвали на собеседование, эйчар по вашему резюме должен понять, что вы за специалист и сможете ли вы решить необходимые задачи. В следующих пунктах - подробнее о том, как сделать свое резюме понятным.
4️⃣ Описывайте процесс работы, а не результат
Разработчики очень часто описывают в резюме не результаты, а обязанности, и, кроме того, делают это размыто. Пример: “реализовывал фронтенд приложения с нуля для заказчиков”. Что это были за проекты, что они умели делать? Например, я ищу разработчика, чтобы он сделал мне личный кабинет пользователя - как по такому описанию я должна понять, справитесь вы с задачей или нет? Акцент должен быть на результат и пользу ваших действий. Пишите результаты своей работы так, чтобы они были понятны даже человеку, который не знаком с вашей компанией, вашими проектами и вообще в первый раз о них слышит. Например: “разработал модуль корзины, интегрировал его с бекендом, добавил аналитику действий пользователя”. Благодаря такому описанию работодатель сможет понять, какие задачи вы можете решать. Вы можете проверить ваше резюме, дав его прочитать другу- если он поймет, чем вы занимались, то опыт работы описан верно.
5️⃣ Для каждого проекта укажите стек, с которым вы работали
Это важно, чтобы работодатель понимал, насколько вы опытны в работе с той или иной технологией.
6️⃣ Укажите сферу деятельности компаний, в которых вы работали
Если работали в аутсорсе - укажите сферу деятельности заказчиков. Это важно, потому что разработчики со знанием доменной области быстрее погружаются в проект. Если компания занимается разработкой интернет-магазинов, то опыт работы с похожими системами будет существенным плюсом.
7️⃣ Для каждого проекта кратко укажите размер команды
Например: “2 бекенд разработчика, 3 фронтенд разработчика, 2 qa”
Это нужно для того, чтобы эйчар понимал, с какими специалистами вы привыкли коммуницировать.
#резюме
🔥13❤2👍2
Жизнь - это постоянный выбор из довольно большого числа альтернатив. В работе (и ее поиске) нам обычно важно получить наибольший профит с наименьшими затратами. Исходя из этого, мы пытаемся понять, выгодно ли нам, скажем, проводить время на литкоде или красиво оформлять гитхаб или эта работа не принесет нам достаточного профита, чтобы тратить на это свое ценное время. Я придерживаюсь точки зрения, что важно учитывать не только прямую, но и косвенную пользу наших действий.
В комментариях к предыдущему посту мы обсуждали, стоит ли заниматься “причесыванием” проектов на гитхабе для поиска работы. Комментаторы справедливо заметили, что очень небольшой процент работодателей вообще смотрит на гитхаб, а те, кто смотрит, делают это бегло. Означает ли это, что разработкой проектов на гитхаб невыгодно заниматься? Отнюдь. Помимо прямой пользы (то есть повышения привлекательности для того небольшого процента работодателей, которые таки гитхаб смотрят) вы получаете очень много косвенной пользы. Смотрите сами:
1️⃣ Когда вы разрабатываете проекты для своего гитхаба, вы качаете скиллы. Я думаю, нет необходимости объяснять, почему скиллы имеют ГЛАВНОЕ значение в вашей карьере. Вы получаете навыки, которые помогут вам: 1. Пройти собеседование 2. Решать ваши рабочие задачи 3. Получать меньше негативных комментариев на ревью 4. Отстаивать свою точку зрения.
2️⃣Когда вы “причесываете” проекты (выстраиваете архитектуру, рефакторите) вы тоже качаете скиллы. В коммерческой разработке вам тоже придется постоянно “причесывать” ваш код перед ревью, так что вы не просто тратите время впустую, а получаете очень ценный навык. Кроме того, это - опыт, про который можно поговорить на собеседовании.
3️⃣ И как вишенку на торте, вы получаете дополнительные очки в глазах того процента работодателей, которые на этот гитхаб таки смотрят.
Таким образом, заниматься проектами на гитхабе выгодно, чтобы получить все эти плюшки, а не только для поиска работы.
В комментариях к предыдущему посту мы обсуждали, стоит ли заниматься “причесыванием” проектов на гитхабе для поиска работы. Комментаторы справедливо заметили, что очень небольшой процент работодателей вообще смотрит на гитхаб, а те, кто смотрит, делают это бегло. Означает ли это, что разработкой проектов на гитхаб невыгодно заниматься? Отнюдь. Помимо прямой пользы (то есть повышения привлекательности для того небольшого процента работодателей, которые таки гитхаб смотрят) вы получаете очень много косвенной пользы. Смотрите сами:
1️⃣ Когда вы разрабатываете проекты для своего гитхаба, вы качаете скиллы. Я думаю, нет необходимости объяснять, почему скиллы имеют ГЛАВНОЕ значение в вашей карьере. Вы получаете навыки, которые помогут вам: 1. Пройти собеседование 2. Решать ваши рабочие задачи 3. Получать меньше негативных комментариев на ревью 4. Отстаивать свою точку зрения.
2️⃣Когда вы “причесываете” проекты (выстраиваете архитектуру, рефакторите) вы тоже качаете скиллы. В коммерческой разработке вам тоже придется постоянно “причесывать” ваш код перед ревью, так что вы не просто тратите время впустую, а получаете очень ценный навык. Кроме того, это - опыт, про который можно поговорить на собеседовании.
3️⃣ И как вишенку на торте, вы получаете дополнительные очки в глазах того процента работодателей, которые на этот гитхаб таки смотрят.
Таким образом, заниматься проектами на гитхабе выгодно, чтобы получить все эти плюшки, а не только для поиска работы.
❤8👍7
Пользователи часто (и небезосновательно) упрекают нас в том, что наши приложения тормозят. Фронтенд приложения не React могут тормозить из-за избыточных ререндеров. Написала небольшую заметку о том, как отслеживать ререндеры React компонентов с помощью девтулзов:
https://devmargooo.notion.site/React-devtools-1e9a1781152280e69e1cc6f84fa20f9d
#перфоманс
https://devmargooo.notion.site/React-devtools-1e9a1781152280e69e1cc6f84fa20f9d
#перфоманс
devmargooo on Notion
Контроль рендеринга при помощи React devtools | Notion
1. Отслеживание рендеров при помощи опции
🔥18
Ошибка, из-за которой вы не проходите собеседование
Частая ошибка на собеседовании/скрининге - кандидату непонятен вопрос и он не пытается его уточнить, а отвечает, что не знает, или отвечает не то. Например, спрашивают про опыт работы с css библиотеками, кандидат отвечает, что не работал, а на самом деле имелись ввиду css фреймворки (bootstap, etc), с которыми кандидат работал. Или, например, спрашивают про css фреймворки, кандидат называет бутстрап, а на самом деле интервьюер хотел услышать БЭМ (css методология). Поэтому, если вам задают вопрос, на который вы не знаете ответа и при этом вы миддл и выше - попробуйте для начала уточнить, о чем идет речь. К сожалению, в айти часто происходит путаница терминов (чего только стоят баталии по поводу именования какой-нибудь вещи “библиотекой” или “фреймворком”!). Скорее всего, вы знаете ответ на этот вопрос, а если даже точно на этот вопрос не знаете, знаете что-то аналогичное. Уточнение, что вы говорите об одном и том же - важный софт скилл, потому что, к сожалению, в айти командах довольно часто происходят ошибки из-за банальных недопониманий.
Например, вас спрашивают принципы работы redux, а вы работали только с mobx. Не спешите отвечать, что вы не знаете, как работает redux: расскажите про ваш опыт с mobx, как вы его использовали, какая у него архитектура и юзкейсы. В айти СЛИШКОМ МНОГО технологий и вы точно не сможете поработать со всеми. Профессионализм программиста определяется тем, насколько хорошо он умеет разбираться с новыми вещами на основании опыта работы с похожими. Поэтому на вопрос о какой-то вещи, которую вы не знаете, вполне валидно рассказать о вещи, которую вы знаете: интервьюер поймет, что вы сможете быстро разобраться с тем, что нужно будет ему. А если вы ответите “не знаю”, тогда, к сожалению, интервьюер не сможет этого понять.
#собеседования
Частая ошибка на собеседовании/скрининге - кандидату непонятен вопрос и он не пытается его уточнить, а отвечает, что не знает, или отвечает не то. Например, спрашивают про опыт работы с css библиотеками, кандидат отвечает, что не работал, а на самом деле имелись ввиду css фреймворки (bootstap, etc), с которыми кандидат работал. Или, например, спрашивают про css фреймворки, кандидат называет бутстрап, а на самом деле интервьюер хотел услышать БЭМ (css методология). Поэтому, если вам задают вопрос, на который вы не знаете ответа и при этом вы миддл и выше - попробуйте для начала уточнить, о чем идет речь. К сожалению, в айти часто происходит путаница терминов (чего только стоят баталии по поводу именования какой-нибудь вещи “библиотекой” или “фреймворком”!). Скорее всего, вы знаете ответ на этот вопрос, а если даже точно на этот вопрос не знаете, знаете что-то аналогичное. Уточнение, что вы говорите об одном и том же - важный софт скилл, потому что, к сожалению, в айти командах довольно часто происходят ошибки из-за банальных недопониманий.
Например, вас спрашивают принципы работы redux, а вы работали только с mobx. Не спешите отвечать, что вы не знаете, как работает redux: расскажите про ваш опыт с mobx, как вы его использовали, какая у него архитектура и юзкейсы. В айти СЛИШКОМ МНОГО технологий и вы точно не сможете поработать со всеми. Профессионализм программиста определяется тем, насколько хорошо он умеет разбираться с новыми вещами на основании опыта работы с похожими. Поэтому на вопрос о какой-то вещи, которую вы не знаете, вполне валидно рассказать о вещи, которую вы знаете: интервьюер поймет, что вы сможете быстро разобраться с тем, что нужно будет ему. А если вы ответите “не знаю”, тогда, к сожалению, интервьюер не сможет этого понять.
#собеседования
5🔥13❤5👍4💯3
Неочевидный тренд в найме в 2025 году
В конце 2024 и 2025 году я стала замечать новый тренд в найме программистов: компании стали обращать много внимания на опыт с аналогичной доменной областью. Проще говоря, маркетплейсы отдают предпочтение кандидатам с опытом работы в маркетплейсах, видеостриминговые платформы - кандидатам с опытом работы в аналогичных платформах, и т.д. Это довольно логично, однако многие из нас могут вспомнить, как несколько лет назад компании при найме обращали главное внимание на стек, а опыт с аналогичной доменной областью был делом десятым. Считалось, что если кандидат владеет стеком, то сможет быстро “переучиться” работе с новой доменной областью. Я думаю, что тренд на внимание к опыту работы со схожим доменом связан со следующими факторами:
1️⃣ Больше программистов на рынке => есть из кого выбрать
2️⃣ Распространение ИИ => теперь гораздо важнее понимать, ЧТО ты хочешь запрограммировать, а не КАК
Что это значит для кандидатов? Тренд подсказывает нам, что лучше выделить в своем резюме, чтобы повысить шансы на трудоустройство:
1️⃣ Делайте акцент на профите от вашей работы, а не на деталях реализации (на том, ЧТО сделали, а не КАК)
2️⃣ Откликаясь на вакансию, подсветите в резюме релевантные вакансии задачи. Откликаетесь в маркетплейс? Напишите про страницы каталогов, которые вы делали, с фильтрами и сортировками, и тд.
#резюме
В конце 2024 и 2025 году я стала замечать новый тренд в найме программистов: компании стали обращать много внимания на опыт с аналогичной доменной областью. Проще говоря, маркетплейсы отдают предпочтение кандидатам с опытом работы в маркетплейсах, видеостриминговые платформы - кандидатам с опытом работы в аналогичных платформах, и т.д. Это довольно логично, однако многие из нас могут вспомнить, как несколько лет назад компании при найме обращали главное внимание на стек, а опыт с аналогичной доменной областью был делом десятым. Считалось, что если кандидат владеет стеком, то сможет быстро “переучиться” работе с новой доменной областью. Я думаю, что тренд на внимание к опыту работы со схожим доменом связан со следующими факторами:
1️⃣ Больше программистов на рынке => есть из кого выбрать
2️⃣ Распространение ИИ => теперь гораздо важнее понимать, ЧТО ты хочешь запрограммировать, а не КАК
Что это значит для кандидатов? Тренд подсказывает нам, что лучше выделить в своем резюме, чтобы повысить шансы на трудоустройство:
1️⃣ Делайте акцент на профите от вашей работы, а не на деталях реализации (на том, ЧТО сделали, а не КАК)
2️⃣ Откликаясь на вакансию, подсветите в резюме релевантные вакансии задачи. Откликаетесь в маркетплейс? Напишите про страницы каталогов, которые вы делали, с фильтрами и сортировками, и тд.
#резюме
2❤12👍6💯4🤔2💅2
Конкурентный режим в React
Не далее как вчера меня угораздило пожаловаться в одной из соцсетей на диффузность современных технических статей и документации, приведя в пример статью о конкурентном режиме в React, после чего меня попросили изложить свое понимание этого режима. Постараюсь избежать недостатка, который я вчера критиковала, и быть предельно четкой в своих определениях.
🟢 Конкуретный режим в React - это режим, который позволяет нескольким задачам одновременно иметь состояние “в работе”. Таким образом, для того, чтобы начать делать следующую задачу, нам необязательно завершать текущую. При этом конкурентный режим не означает, что React будет выполнять задачи одновременно: он отложит выполнение одной задачи, чтобы начать другую, и потом вернется к ней. Это происходит, когда во время выполнения задачи появляется более высокоприоритетная: React приостанавливает работу над менее приоритетной задачей, чтобы сделать более приоритетную.
Конкурентный режим включается, когда мы используем ReactDOM.createRoot вместо ReactDOM.render для рендера нашего приложения. В React приложениях с клиентским рендером конкурентный режим предоставляет нам две возможности в виде хуков useTranstiion и useDefferedValue. Первый позволяет пометить нам экшен, меняющий какое-то состояние, как низкоприоритетный, чтобы сделать наш интерфейс более отзывчивым. Второй с той же целью позволяет пометить нам наше значение как “низкоприоритетное”, что приведет к тому, что React понизит приоритет обновления этого значения.
От теории к делу: Ваша покорная слуга извращалась с React и так, и сяк, пытаясь найти кейс, в котором useTranstion и useDefferedValue сработают лучше, чем обычный setState. Я ставила счетчики, увеличивающиеся каждую милисекунду, загружала компоненты с огромными джейсонами, добавляла на страницу видео. Визуально мне не удалось найти никакой разницы между обновлением данных через setState и useTransition/useDefferedValue. Но если мне наконец удастся найти такой кейс, вы будете первыми, кто об этом узнает❤️
#react
Не далее как вчера меня угораздило пожаловаться в одной из соцсетей на диффузность современных технических статей и документации, приведя в пример статью о конкурентном режиме в React, после чего меня попросили изложить свое понимание этого режима. Постараюсь избежать недостатка, который я вчера критиковала, и быть предельно четкой в своих определениях.
Конкурентный режим включается, когда мы используем ReactDOM.createRoot вместо ReactDOM.render для рендера нашего приложения. В React приложениях с клиентским рендером конкурентный режим предоставляет нам две возможности в виде хуков useTranstiion и useDefferedValue. Первый позволяет пометить нам экшен, меняющий какое-то состояние, как низкоприоритетный, чтобы сделать наш интерфейс более отзывчивым. Второй с той же целью позволяет пометить нам наше значение как “низкоприоритетное”, что приведет к тому, что React понизит приоритет обновления этого значения.
От теории к делу: Ваша покорная слуга извращалась с React и так, и сяк, пытаясь найти кейс, в котором useTranstion и useDefferedValue сработают лучше, чем обычный setState. Я ставила счетчики, увеличивающиеся каждую милисекунду, загружала компоненты с огромными джейсонами, добавляла на страницу видео. Визуально мне не удалось найти никакой разницы между обновлением данных через setState и useTransition/useDefferedValue. Но если мне наконец удастся найти такой кейс, вы будете первыми, кто об этом узнает
#react
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍19❤4🤡1
🍝 Готовим React Context
React Context - полноценный инструмент для хранения и чтения глобального состояния. Обычно в контексте хранится набор значений и их методов. Однако он имеет проблему с производительностью: когда меняется любое поле в контексте, все подписчики контекста ререндерятся. Так происходит потому, что объект контекста сравнивается по ссылке, и если меняется поле в контексте, то потребитель получает новую ссылку на контекст, что приводит к ререндеру - даже в том случае, если поле, которое поменялось, не используется в этом компоненте вообще.
✍️ Несколько рецептов, которые помогут вам использовать удобно контекст и снизить проблемы с производительностью:
1️⃣ Разделяйте один контекст на несколько маленьких. Например, вместо одного
2️⃣ Кешируйте через useCallback и useMemo значения, которые возвращаете из контекста - в таком случае в компоненте-потребителе вы сможете безопасно передавать их в дочерние компоненты, не опасаясь, что каждое изменение контектста приведет к замене ссылки и перерендеру дочерних компонентов.
3️⃣ Создавайте хук для взаимодействия с контекстом. Вместо того, чтобы в каждом компоненте писать
#react
React Context - полноценный инструмент для хранения и чтения глобального состояния. Обычно в контексте хранится набор значений и их методов. Однако он имеет проблему с производительностью: когда меняется любое поле в контексте, все подписчики контекста ререндерятся. Так происходит потому, что объект контекста сравнивается по ссылке, и если меняется поле в контексте, то потребитель получает новую ссылку на контекст, что приводит к ререндеру - даже в том случае, если поле, которое поменялось, не используется в этом компоненте вообще.
✍️ Несколько рецептов, которые помогут вам использовать удобно контекст и снизить проблемы с производительностью:
1️⃣ Разделяйте один контекст на несколько маленьких. Например, вместо одного
AppContext
с множеством свойств создайте отдельные контексты UserContext
, ThemeContext
и т.д. В таком случае при изменении свойства в UserContext
будут перерендерены только те подписчики, которые подписаны на UserContext
, а те, которые подписаны на ThemeContext, не будут - ведь он не изменился.2️⃣ Кешируйте через useCallback и useMemo значения, которые возвращаете из контекста - в таком случае в компоненте-потребителе вы сможете безопасно передавать их в дочерние компоненты, не опасаясь, что каждое изменение контектста приведет к замене ссылки и перерендеру дочерних компонентов.
3️⃣ Создавайте хук для взаимодействия с контекстом. Вместо того, чтобы в каждом компоненте писать
const mydata = useContext(MyContext)
, сделайте такой простой хук:export const useMyContext = (): MyContextProps => {
const context = useContext(MyContext);
if (!context) {
throw new Error(‘MyContext not found :(’);
}
return context;
};
#react
🤗10👍4🔥4😱2
Лексическое окружение
Начну серию постов, связанную с замыканиями, утечками памяти через замыкания, stale state и stale props в React. В Javascript есть три основные концепции, связанные с замыканиями:
🔹 Lexical environment
🔹 Environment record
🔹 Execution context
Сегодня поговорим о первой из них, а именно - о лексическом окружении.
🔶 Лексическое окружение - это структура, которая определяет, какие идентификаторы (т.е. переменные) доступны в данном фрагменте кода. Создается в момент вызова. Фрагментами кода, которые создают новое лексическое окружение, являются:
🔹 Js файлы. Когда мы запускаем код из js файла, создается глобальное лексическое окружение, и переменные из него будут доступны в любом месте в этом файле
🔹Функции. Вызов функции создает новое лексическое окружение для нее, повторный вызов создаст новое лексическое окружение
🔹Блок кода (то, что внутри
Каждое лексическое окружение имеет ссылку на внешнее лексическое окружение. Для глобального лексического окружения ссылка на внешнее будет равна null.
На картинке выше вы можете увидеть код и схематичное изображение его лексического окружения. Лексическое окружение foo содержит в себе идентификатор
#javascript #замыкание #lexical_environment
Начну серию постов, связанную с замыканиями, утечками памяти через замыкания, stale state и stale props в React. В Javascript есть три основные концепции, связанные с замыканиями:
🔹 Lexical environment
🔹 Environment record
🔹 Execution context
Сегодня поговорим о первой из них, а именно - о лексическом окружении.
🔶 Лексическое окружение - это структура, которая определяет, какие идентификаторы (т.е. переменные) доступны в данном фрагменте кода. Создается в момент вызова. Фрагментами кода, которые создают новое лексическое окружение, являются:
🔹 Js файлы. Когда мы запускаем код из js файла, создается глобальное лексическое окружение, и переменные из него будут доступны в любом месте в этом файле
🔹Функции. Вызов функции создает новое лексическое окружение для нее, повторный вызов создаст новое лексическое окружение
🔹Блок кода (то, что внутри
{}
). Когда интерпретатор доходит до блока кода, он создает новое лексическое окружение, в котором могут находиться переменные, объявленные через let и const. Каждое лексическое окружение имеет ссылку на внешнее лексическое окружение. Для глобального лексического окружения ссылка на внешнее будет равна null.
На картинке выше вы можете увидеть код и схематичное изображение его лексического окружения. Лексическое окружение foo содержит в себе идентификатор
c
и ссылку на внешнее лексическое окружение, которое является глобальным. Глобальное лексическое окружение содержит в себе два идентификатора, а его ссылка на внешнее лексическое окружение равна null.#javascript #замыкание #lexical_environment
👍10❤7
⚡️ Что такое замыкание и как оно приводит к утечкам памяти
В прошлый раз мы с вами говорили о лексическом окружении и причинах его создания, а сегодня поговорим о замыканиях. Термином “замыкание” в javascript обозначает функцию и ее лексическое окружение. Как вы помните, лексическое окружение в javascript содержит в себе ссылку на внешнее лексическое окружение - таким образом, все внешние лексические окружения для функции будут доступны ей через цепочку ссылок.
Что происходит с лексическим окружением функции после того, как она завершила свою работу? Довольно часто оно больше не нужно и уничтожается, однако бывает и иначе. Рассмотрим пример:
Функция
В данном случае
#замыкание #javascript
В прошлый раз мы с вами говорили о лексическом окружении и причинах его создания, а сегодня поговорим о замыканиях. Термином “замыкание” в javascript обозначает функцию и ее лексическое окружение. Как вы помните, лексическое окружение в javascript содержит в себе ссылку на внешнее лексическое окружение - таким образом, все внешние лексические окружения для функции будут доступны ей через цепочку ссылок.
Что происходит с лексическим окружением функции после того, как она завершила свою работу? Довольно часто оно больше не нужно и уничтожается, однако бывает и иначе. Рассмотрим пример:
function makeCounter() {
let count = 0;
const increment = () => count++;
return increment;
}
let counter = makeCounter();
counter();
counter();
Функция
makeCounter
завершила свою работу, однако лексическое окружение, которое она создала - с идентификатором count в нем - осталось в памяти. Почему так? Потому что лексическое окружение функции makeCounter
- внешнее для лексического окружения функции increment, которая в нем создается. Когда мы вернули из makeCounter
функцию increment
, прицепом к ней мы вернули все ее лексическое окружение. Поскольку на это лексическое окружение ссылается increment
(ниже counter
- это две переменных указывают на одну область памяти), то лексическое окружение вместе с переменной count
надежно зависло в памяти до тех пор, пока counter остается ссылочно доступен. В данном случае
makeCounter
у нас “зависло” совсем маленькое лексическое окружение с переменной count
- однако бывают и гораздо более серьезные утечки памяти, связанные с замыканиями. Такая ситуация происходит, если “зависшее” лексическое окружение занимает много места в памяти и/или ссылается на другие “тяжелые” лексические окружения. Вот здесь я писала об одной из таких утечек в Promise.race
, а в следующий раз поговорим с вами о том, как “зависшее” лексическое окружение приводит к ситуациям, которые мы называем stale props
и stale state
.#замыкание #javascript
Telegram
Фронтенд кухня🥘
Promise.race
Всем привет, на связи Марго @devmargooo и сегодня я расскажу вам про Promise.race.🏎 Promise.race принимает в качестве аргумента массив промисов и возвращает результат того промиса, который завершится первым. Значит ли это, что после завершения…
Всем привет, на связи Марго @devmargooo и сегодня я расскажу вам про Promise.race.🏎 Promise.race принимает в качестве аргумента массив промисов и возвращает результат того промиса, который завершится первым. Значит ли это, что после завершения…
⚡11❤7👍3
Stale props и stale state
📌 Stale state — это ситуация, когда внутри замыкания используется устаревшее значение состояния. Stale props - то же самое, но для пропсов. Рассмотрим на примере, как это происходит.
Мы имеем React компонент
1. Состояние
В анонимной функции-колбеке, которую планирует таймер, никакого идентификатора
#react
📌 Stale state — это ситуация, когда внутри замыкания используется устаревшее значение состояния. Stale props - то же самое, но для пропсов. Рассмотрим на примере, как это происходит.
export const Example = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
console.log(count);
}, 1000);
}, [])
return (
<button
onClick={() => setCount((c) => c + 1)}
>
{count}
</button> // кликнем несколько раз
)
}
Мы имеем React компонент
Example
, в котором имеется: 1. Состояние
counter
. 2. Эффект, который единожды сработает после монтирования и который выводит наше состояние в лог. Что будет, если за секунду мы уже успеем кликнуть по кнопке несколько раз и counter изменится? Выведется исходное состояние - то, которое было на момент срабатывания эффекта и установки таймера. Вы можете увидеть это на скриншоте выше. Давайте посмотрим подробнее, как так происходит.В анонимной функции-колбеке, которую планирует таймер, никакого идентификатора
counter
не существует. Откуда javascript возьмет его при вызове? Он возьмет его из родительского лексического окружения, то есть из лексического окружения функции Example
, которая одновременно является реакт компонентом. Клик на кнопке приведет к изменению состояния, а это, в свою очередь, вызовет ререндер - то есть новый вызов функции Example. Каждый новый вызов создаст свой объект лексического окружения. Однако нашей анонимной функции с логом до этого нет дела - она надежно запомнила, из какого лексического окружения ей нужно брать counter: из того объекта лексического окружения, которое было создано на момент вызова useEffect. Таким образом, когда наш таймер сработал и вывелся лог, мы увидели там устаревшее состояние.#react
🔥7❤2🤡1
🪄Как применять S из SOLID
Про принцип единственной ответственности написаны тонны статей, но как, чёрт возьми, применять его в реальной разработке? Для того, чтобы успешно применить этот и другие принципы, необходимо осознать одну вещь: наш код не существует сам по себе в сферическом вакууме, это модель реального мира. Связи между компонентами/классами/функциями в нашем коде должны быть такими же, как в реальном мире.
Например, вам нужно сделать формы авторизации и регистрации. На макете они выглядят одинаково, и вы задумываетесь: сделать один универсальный компонент или два отдельных. Для того, чтобы ответить на этот вопрос, вспомните, как проходят эти процессы в реальной жизни. Например, в моем фитнес клубе они существенно отличаются: для регистрации в клубе я заполняла договор с паспортными данными, а для ежедневной регистрации в клубе мне достаточно приложить браслет к турникету. Совершенно разные действия, разные цели, разные сценарии. То же самое и в вебе: регистрация и авторизация - это два разных бизнес-процесса. Даже если сегодня их формы выглядят одинаково, эти компоненты живут своей независимой жизнью: например, на форме авторизации в какой-то момент может появиться галочка “мне уже есть 18”, а на форме регистрации - нет. Или поменяются поля, логика валидации, поведение при ошибках.
Другой пример: вы реализуете карточки товаров, и в разных разделах они имеют разные цвета. Использовать один компонент или делать разные? Давайте подумаем, как бы мы действовали бы в реальном мире. Представьте, что вы печатаете ценники на принтере. Шаблон один и тот же - вы просто вставляете бумагу нужного цвета: белую, жёлтую, синюю. Цвет меняется, но структура остаётся прежней.Если вы решите изменить размер ценника, например, сделать его больше - это уже изменение шаблона, которое повлияет на все ценники сразу. Точно так же в вебе: если мы хотим поменять структуру или размер карточек, то, как правило, мы хотим сделать это у всех карточек сразу. Таким образом, карточка - это один компонент с настраиваемым цветом.
#solid #srp
Про принцип единственной ответственности написаны тонны статей, но как, чёрт возьми, применять его в реальной разработке? Для того, чтобы успешно применить этот и другие принципы, необходимо осознать одну вещь: наш код не существует сам по себе в сферическом вакууме, это модель реального мира. Связи между компонентами/классами/функциями в нашем коде должны быть такими же, как в реальном мире.
Например, вам нужно сделать формы авторизации и регистрации. На макете они выглядят одинаково, и вы задумываетесь: сделать один универсальный компонент или два отдельных. Для того, чтобы ответить на этот вопрос, вспомните, как проходят эти процессы в реальной жизни. Например, в моем фитнес клубе они существенно отличаются: для регистрации в клубе я заполняла договор с паспортными данными, а для ежедневной регистрации в клубе мне достаточно приложить браслет к турникету. Совершенно разные действия, разные цели, разные сценарии. То же самое и в вебе: регистрация и авторизация - это два разных бизнес-процесса. Даже если сегодня их формы выглядят одинаково, эти компоненты живут своей независимой жизнью: например, на форме авторизации в какой-то момент может появиться галочка “мне уже есть 18”, а на форме регистрации - нет. Или поменяются поля, логика валидации, поведение при ошибках.
Другой пример: вы реализуете карточки товаров, и в разных разделах они имеют разные цвета. Использовать один компонент или делать разные? Давайте подумаем, как бы мы действовали бы в реальном мире. Представьте, что вы печатаете ценники на принтере. Шаблон один и тот же - вы просто вставляете бумагу нужного цвета: белую, жёлтую, синюю. Цвет меняется, но структура остаётся прежней.Если вы решите изменить размер ценника, например, сделать его больше - это уже изменение шаблона, которое повлияет на все ценники сразу. Точно так же в вебе: если мы хотим поменять структуру или размер карточек, то, как правило, мы хотим сделать это у всех карточек сразу. Таким образом, карточка - это один компонент с настраиваемым цветом.
#solid #srp
👍19🔥2🤡1
Хуки эффектов, в которых есть запросы с последующей установкой ответа в state могут приводить к race conditions. Race conditions возникает, когда хук выполняется слишком часто, и поскольку очередность ответов от сервера не гарантирована, то более ранние запросы могут завершиться после более поздних и тогда в state будут записаны неверные данные.
Например, вот такой код может привести к проблеме:
useEffect(() => {
fetch(`/api/data?query=${query}`)
.then((res) => res.json())
.then((data) => setData(data));
}, [query]);
Этот эффект будет выполняться при каждом изменении query. Таким образом, при вводе query отправится несколько вопросов, но порядок ответа от сервера и тем самым вызов setState не гарантирован.
Вот здесь я собрала песочницу для демонстрации проблемы.
В этом примере мы видим строку поиска товаров. Я добавила искусственную задержку: чем короче строка поиска, тем дольше выполняется запрос. Попробуйте ввести в поиск слово “dog”. Вы увидите, что сначала отображается один результат (”dog food”), а затем больше и больше результатов.
Почему? Потому что при вводе слова “dog” мы отправляем подряд целых три запроса: запрос с поиском значения “d”, запрос с поиском значения “do” и наконец запрос с поиском значения “dog”. Я реализовала искусственную задержку - чем больше букв в поисковой строке, тем быстрее выполнится запрос. Поэтому ответы нам будут приходить в обратном порядке: сначала ответ для “dog”, потом для “do” и наконец для “d”. Хук setData сработает в порядке возвращения ответов от сервера: сначала установятся значения для “dog”, потом для “do” и наконец для “d”. В этом примере задержка искусственная, но реальный сервер тоже не гарантирует порядок ответов и более ранний запрос может завершится после более позднего. В таком мы установим в state устаревшее состояние.
🪄Как предотвратить race conditions?
Проблему решает AbortController: с его помощью можно отменить предыдущий ответ таким образом, что браузер будет дожидаться ответа только для последнего запроса. Это нативное решение и оно подходит в абсолютном большинстве случаев.
useEffect(() => {
const controller = new AbortController();
fetch(`/api/data?query=${query}`, { signal: controller.signal })
.then(res => res.json())
.then(data => setData(data))
.catch(err => {
if (err.name !== 'AbortError') {
console.error(err);
}
});
return () => controller.abort(); // отменяем прошлый запрос
}, [query]);
#react
Please open Telegram to view this post
VIEW IN TELEGRAM
❤21
Вы наверняка встречали советы использовать useReducer вместо useState, когда состояние компонента становится "слишком большим и сложным". Но на самом деле дело не только в размере.
Я использую useReducer, когда разные части состояния зависят друг от друга. В таких случаях удобно моделировать поведение компонента как конечный автомат - где редюсер отвечает за допустимые переходы между состояниями.
Представим форму с таким поведением:
- При отправке показывается лоадер.
- Сервер отвечает либо ошибкой, либо успешными данными.
- Ошибка или данные отображаются на странице.
- Повторная отправка формы сбрасывает старое состояние (ошибку и данные)
Интуитивно многие используют следующий код для хранения состояния:
const [error, setError] = useState(false);
const [data, setData] = useState("");
const [loading, setLoading] = useState(false);
const reset = () => {
setError("");
setData("");
};
const onSubmit = (e) => {
reset();
setLoading(true);
sendData(value).then((result) => {
if (result.type === "error") {
setError(result.iss.onessage);
}
if (result.type === "success") {
setData(result.data);
}
setLoading(false);
});
};
Полный код примера можно посмотреть здесь
Вот так можно переписать это при помощи useReducer:
function reducer(state: FullState, action: Action): FullState {
switch (action.type) {
case "SET_LOADING":
return { loading: true, error: "", data: "" };
case "SET_SUCCESS":
return { loading: false, error: "", data: action.payload };
case "SET_ERROR":
return { loading: false, error: action.payload, data: "" };
}
}
Полный код примера смотреть здесь
Теперь все переходы управляются единой централизованной системой, а в коде компонента нам остается только вызвать нужный экшен - о том, чтобы привести систему в консистентное состояние, позаботится редюсер.
#react
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤19🔥3❤🔥1👍1
Про оценку сроков
Мы ужасно умеем оценивать сроки. Подкидывание монетки или бросание кубика даст верную оценку с той же вероятностью, что и команда опытных программистов. Но бизнесу необходимы сроки, и каждый спринт нам приходится оценивать задачи, надеясь на удачу и на то, что не возникнет непредвиденных проблем.
Однако непредвиденные проблемы возникают практически всегда. Внезапно выясняется, что часть системы, куда нужно интегрировать новую фичу, работает с багами, или наше решение не вписывается в существующую архитектуру. Разумеется, все эти моменты становятся известны уже в процессе решения задачи, но никак не на этапе планирования. Мы сталкиваемся со сложным выбором: провалить сроки или овертаймить.
Каждый из нас решает эту проблему по-своему. Один мой бывший коллега всякий раз очень долго извинялся, когда факапил сроки, и обещал обязательно все сделать сегодня. Но он снова не успевал, и снова извинялся. Другой мой бывший коллега оставался допоздна перед дедлайном, а как-то раз и вовсе заночевал на офисном диване.
В защиту программистов скажу, что проблема оценок существует не только в айти: любой сложный процесс практически невозможно спрогнозировать. Один мой менеджер как-то сказал: представь, что твой врач не может назвать, сколько времени уйдет на лечение, что ты будешь чувствовать? Это был очень плохой пример: как раз в это время я проходила стоматологическое лечение, которое заняло на год больше ожидаемого и оказалось в 2,5 раза дороже изначально планируемой суммы.
Разработка - это сборка конструктора из мелких деталей: никогда не знаешь, подойдёт ли новая деталь к уже собранной части. Это напоминает известную проблему остановки Тьюринга: для любых двух функций F и G мы никогда не можем определить, что их суперпозиция остановится (= заработает как надо). Алан Тьюринг доказал неразрешимость этой проблемы еще 90 лет назад, однако менеджеры по сей день продолжают пытать программистов на очередном дейли вопросом “так, сколько тебе еще делать эту задачу?”.
Однако можно сделать ровно противоположное: не угадывать срок, который уйдет на разработку, а зафиксировать время, которое вы готовы уделить на фичу. Например: “Мы готовы потратить на эту фичу 2–5 дней. Обязательно - чтобы работало вот это. Всё остальное сделаем по возможности”. Тогда вы не будете зависеть от точных оценок, и при любом раскладе сделаете главное.
Первый раз я применила этот способ еще в 2019 году. Я прикинула, что мне нужно около двух недель на задачу. Однако менеджер вернулась ко мне со словами - “бизнес не дал тебе две недели, бизнес дал тебе неделю”. “Хорошо, я могу сшить семь шапок из этой шкурки,” - подумала я. Я сделала каркас фичи за неделю, но не успела добавить несколько удобных штук в свое решение, плюс пропустила некоторые корнер кейсы. Менеджер осталась довольна. А затем попросила доработать решение и учесть корнер кейс. “Хорошо,” - сказала я, - “на это мне нужна еще неделя”. На том и порешили.
Если вы разработчик и от вас требуют конкретные сроки - попробуйте так и сказать: “Я точно успею сделать вот это, а остальное - постараюсь, если не вылезем за дедлайн”. Тогда вы точно сможете рассчитывать на то, что критическая функциональность будет готова в срок, а опциональной можно пренебречь.
Мы ужасно умеем оценивать сроки. Подкидывание монетки или бросание кубика даст верную оценку с той же вероятностью, что и команда опытных программистов. Но бизнесу необходимы сроки, и каждый спринт нам приходится оценивать задачи, надеясь на удачу и на то, что не возникнет непредвиденных проблем.
Однако непредвиденные проблемы возникают практически всегда. Внезапно выясняется, что часть системы, куда нужно интегрировать новую фичу, работает с багами, или наше решение не вписывается в существующую архитектуру. Разумеется, все эти моменты становятся известны уже в процессе решения задачи, но никак не на этапе планирования. Мы сталкиваемся со сложным выбором: провалить сроки или овертаймить.
Каждый из нас решает эту проблему по-своему. Один мой бывший коллега всякий раз очень долго извинялся, когда факапил сроки, и обещал обязательно все сделать сегодня. Но он снова не успевал, и снова извинялся. Другой мой бывший коллега оставался допоздна перед дедлайном, а как-то раз и вовсе заночевал на офисном диване.
В защиту программистов скажу, что проблема оценок существует не только в айти: любой сложный процесс практически невозможно спрогнозировать. Один мой менеджер как-то сказал: представь, что твой врач не может назвать, сколько времени уйдет на лечение, что ты будешь чувствовать? Это был очень плохой пример: как раз в это время я проходила стоматологическое лечение, которое заняло на год больше ожидаемого и оказалось в 2,5 раза дороже изначально планируемой суммы.
Разработка - это сборка конструктора из мелких деталей: никогда не знаешь, подойдёт ли новая деталь к уже собранной части. Это напоминает известную проблему остановки Тьюринга: для любых двух функций F и G мы никогда не можем определить, что их суперпозиция остановится (= заработает как надо). Алан Тьюринг доказал неразрешимость этой проблемы еще 90 лет назад, однако менеджеры по сей день продолжают пытать программистов на очередном дейли вопросом “так, сколько тебе еще делать эту задачу?”.
Однако можно сделать ровно противоположное: не угадывать срок, который уйдет на разработку, а зафиксировать время, которое вы готовы уделить на фичу. Например: “Мы готовы потратить на эту фичу 2–5 дней. Обязательно - чтобы работало вот это. Всё остальное сделаем по возможности”. Тогда вы не будете зависеть от точных оценок, и при любом раскладе сделаете главное.
Первый раз я применила этот способ еще в 2019 году. Я прикинула, что мне нужно около двух недель на задачу. Однако менеджер вернулась ко мне со словами - “бизнес не дал тебе две недели, бизнес дал тебе неделю”. “Хорошо, я могу сшить семь шапок из этой шкурки,” - подумала я. Я сделала каркас фичи за неделю, но не успела добавить несколько удобных штук в свое решение, плюс пропустила некоторые корнер кейсы. Менеджер осталась довольна. А затем попросила доработать решение и учесть корнер кейс. “Хорошо,” - сказала я, - “на это мне нужна еще неделя”. На том и порешили.
Если вы разработчик и от вас требуют конкретные сроки - попробуйте так и сказать: “Я точно успею сделать вот это, а остальное - постараюсь, если не вылезем за дедлайн”. Тогда вы точно сможете рассчитывать на то, что критическая функциональность будет готова в срок, а опциональной можно пренебречь.
❤20❤🔥7👍5
В тему оценки.
Сейчас взяла в работу задачу по починке скриншотных тестов. Ситуация: локально и в ci тесты проходят с разным результатом. Докер образ один и тот же. Честно говоря, я даже не представляю, в чем может быть проблема - я специально настраивала прогон в докере, чтобы добиться консистентности результата.
И ведь мне это нужно как-то оценить 😊
Сейчас взяла в работу задачу по починке скриншотных тестов. Ситуация: локально и в ci тесты проходят с разным результатом. Докер образ один и тот же. Честно говоря, я даже не представляю, в чем может быть проблема - я специально настраивала прогон в докере, чтобы добиться консистентности результата.
И ведь мне это нужно как-то оценить 😊
🤯7👍3😨2👌1
Говорила то же самое, когда это еще не было мейнстримом 😊
Брутфорсить собесы - это очень плохая идея.
Брутфорсить собесы - это очень плохая идея.
👍1💯1
Forwarded from Стародубцев x IT-ХОЗЯЕВА
Сейчас я расскажу неприятный, но важный факт 👮
Не ходи на собеседования, если не готов к ним.
У большинства компаний есть кд по найму, если кандидат не подошёл. В свете последних событий, когда найти работу стало сложнее, провалить собеседование - плохая идея.
Поэтому не стоит выходить на рынок:
С сырым резюме (получишь меньше денег).
Без базового знания алгоритмов.
Без понимания предметной области, в которую идёшь.
Без осознания того, что ты хочешь делать на работе.
Без базовых софтов (очень много отлетают на собесе с командой).
Как подготовиться?
Пробные собеседования (моки). Смотреть, как другие плавают по реке - круто, а самому поплавать — совсем другое дело.
Резюме. В нашем сообществе есть отдельный чат с разборами резюме, можно спросить совета и исправить ошибки. Ну и получить ответ сколько денег просить, многие до сих пор не знают настоящие вилки. Или спроси у знакомого из другой компании!
Всё это необходимый минимум. В нынешней ситуации приходить неподготовленным - неуважение к себе и работодателю. Ты не только потратишь время, но и получишь «фриз» на полгода в этой компании. А ведь этот оффер мог бы помочь в переговорах с компанией "мечты" где ты мог бы поторговаться.
Не ходи на собеседования, если не готов к ним.
У большинства компаний есть кд по найму, если кандидат не подошёл. В свете последних событий, когда найти работу стало сложнее, провалить собеседование - плохая идея.
Поэтому не стоит выходить на рынок:
С сырым резюме (получишь меньше денег).
Без базового знания алгоритмов.
Без понимания предметной области, в которую идёшь.
Без осознания того, что ты хочешь делать на работе.
Без базовых софтов (очень много отлетают на собесе с командой).
Как подготовиться?
Пробные собеседования (моки). Смотреть, как другие плавают по реке - круто, а самому поплавать — совсем другое дело.
Резюме. В нашем сообществе есть отдельный чат с разборами резюме, можно спросить совета и исправить ошибки. Ну и получить ответ сколько денег просить, многие до сих пор не знают настоящие вилки. Или спроси у знакомого из другой компании!
Всё это необходимый минимум. В нынешней ситуации приходить неподготовленным - неуважение к себе и работодателю. Ты не только потратишь время, но и получишь «фриз» на полгода в этой компании. А ведь этот оффер мог бы помочь в переговорах с компанией "мечты" где ты мог бы поторговаться.
Please open Telegram to view this post
VIEW IN TELEGRAM
💯10❤5😁4