Вы наверняка встречали советы использовать 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.message);
}
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❤23🔥3❤🔥1👍1
Про оценку сроков
Мы ужасно умеем оценивать сроки. Подкидывание монетки или бросание кубика даст верную оценку с той же вероятностью, что и команда опытных программистов. Но бизнесу необходимы сроки, и каждый спринт нам приходится оценивать задачи, надеясь на удачу и на то, что не возникнет непредвиденных проблем.
Однако непредвиденные проблемы возникают практически всегда. Внезапно выясняется, что часть системы, куда нужно интегрировать новую фичу, работает с багами, или наше решение не вписывается в существующую архитектуру. Разумеется, все эти моменты становятся известны уже в процессе решения задачи, но никак не на этапе планирования. Мы сталкиваемся со сложным выбором: провалить сроки или овертаймить.
Каждый из нас решает эту проблему по-своему. Один мой бывший коллега всякий раз очень долго извинялся, когда факапил сроки, и обещал обязательно все сделать сегодня. Но он снова не успевал, и снова извинялся. Другой мой бывший коллега оставался допоздна перед дедлайном, а как-то раз и вовсе заночевал на офисном диване.
В защиту программистов скажу, что проблема оценок существует не только в айти: любой сложный процесс практически невозможно спрогнозировать. Один мой менеджер как-то сказал: представь, что твой врач не может назвать, сколько времени уйдет на лечение, что ты будешь чувствовать? Это был очень плохой пример: как раз в это время я проходила стоматологическое лечение, которое заняло на год больше ожидаемого и оказалось в 2,5 раза дороже изначально планируемой суммы.
Разработка - это сборка конструктора из мелких деталей: никогда не знаешь, подойдёт ли новая деталь к уже собранной части. Это напоминает известную проблему остановки Тьюринга: для любых двух функций F и G мы никогда не можем определить, что их суперпозиция остановится (= заработает как надо). Алан Тьюринг доказал неразрешимость этой проблемы еще 90 лет назад, однако менеджеры по сей день продолжают пытать программистов на очередном дейли вопросом “так, сколько тебе еще делать эту задачу?”.
Однако можно сделать ровно противоположное: не угадывать срок, который уйдет на разработку, а зафиксировать время, которое вы готовы уделить на фичу. Например: “Мы готовы потратить на эту фичу 2–5 дней. Обязательно - чтобы работало вот это. Всё остальное сделаем по возможности”. Тогда вы не будете зависеть от точных оценок, и при любом раскладе сделаете главное.
Первый раз я применила этот способ еще в 2019 году. Я прикинула, что мне нужно около двух недель на задачу. Однако менеджер вернулась ко мне со словами - “бизнес не дал тебе две недели, бизнес дал тебе неделю”. “Хорошо, я могу сшить семь шапок из этой шкурки,” - подумала я. Я сделала каркас фичи за неделю, но не успела добавить несколько удобных штук в свое решение, плюс пропустила некоторые корнер кейсы. Менеджер осталась довольна. А затем попросила доработать решение и учесть корнер кейс. “Хорошо,” - сказала я, - “на это мне нужна еще неделя”. На том и порешили.
Если вы разработчик и от вас требуют конкретные сроки - попробуйте так и сказать: “Я точно успею сделать вот это, а остальное - постараюсь, если не вылезем за дедлайн”. Тогда вы точно сможете рассчитывать на то, что критическая функциональность будет готова в срок, а опциональной можно пренебречь.
Мы ужасно умеем оценивать сроки. Подкидывание монетки или бросание кубика даст верную оценку с той же вероятностью, что и команда опытных программистов. Но бизнесу необходимы сроки, и каждый спринт нам приходится оценивать задачи, надеясь на удачу и на то, что не возникнет непредвиденных проблем.
Однако непредвиденные проблемы возникают практически всегда. Внезапно выясняется, что часть системы, куда нужно интегрировать новую фичу, работает с багами, или наше решение не вписывается в существующую архитектуру. Разумеется, все эти моменты становятся известны уже в процессе решения задачи, но никак не на этапе планирования. Мы сталкиваемся со сложным выбором: провалить сроки или овертаймить.
Каждый из нас решает эту проблему по-своему. Один мой бывший коллега всякий раз очень долго извинялся, когда факапил сроки, и обещал обязательно все сделать сегодня. Но он снова не успевал, и снова извинялся. Другой мой бывший коллега оставался допоздна перед дедлайном, а как-то раз и вовсе заночевал на офисном диване.
В защиту программистов скажу, что проблема оценок существует не только в айти: любой сложный процесс практически невозможно спрогнозировать. Один мой менеджер как-то сказал: представь, что твой врач не может назвать, сколько времени уйдет на лечение, что ты будешь чувствовать? Это был очень плохой пример: как раз в это время я проходила стоматологическое лечение, которое заняло на год больше ожидаемого и оказалось в 2,5 раза дороже изначально планируемой суммы.
Разработка - это сборка конструктора из мелких деталей: никогда не знаешь, подойдёт ли новая деталь к уже собранной части. Это напоминает известную проблему остановки Тьюринга: для любых двух функций F и G мы никогда не можем определить, что их суперпозиция остановится (= заработает как надо). Алан Тьюринг доказал неразрешимость этой проблемы еще 90 лет назад, однако менеджеры по сей день продолжают пытать программистов на очередном дейли вопросом “так, сколько тебе еще делать эту задачу?”.
Однако можно сделать ровно противоположное: не угадывать срок, который уйдет на разработку, а зафиксировать время, которое вы готовы уделить на фичу. Например: “Мы готовы потратить на эту фичу 2–5 дней. Обязательно - чтобы работало вот это. Всё остальное сделаем по возможности”. Тогда вы не будете зависеть от точных оценок, и при любом раскладе сделаете главное.
Первый раз я применила этот способ еще в 2019 году. Я прикинула, что мне нужно около двух недель на задачу. Однако менеджер вернулась ко мне со словами - “бизнес не дал тебе две недели, бизнес дал тебе неделю”. “Хорошо, я могу сшить семь шапок из этой шкурки,” - подумала я. Я сделала каркас фичи за неделю, но не успела добавить несколько удобных штук в свое решение, плюс пропустила некоторые корнер кейсы. Менеджер осталась довольна. А затем попросила доработать решение и учесть корнер кейс. “Хорошо,” - сказала я, - “на это мне нужна еще неделя”. На том и порешили.
Если вы разработчик и от вас требуют конкретные сроки - попробуйте так и сказать: “Я точно успею сделать вот это, а остальное - постараюсь, если не вылезем за дедлайн”. Тогда вы точно сможете рассчитывать на то, что критическая функциональность будет готова в срок, а опциональной можно пренебречь.
❤23❤🔥8👍7
В тему оценки.
Сейчас взяла в работу задачу по починке скриншотных тестов. Ситуация: локально и в ci тесты проходят с разным результатом. Докер образ один и тот же. Честно говоря, я даже не представляю, в чем может быть проблема - я специально настраивала прогон в докере, чтобы добиться консистентности результата.
И ведь мне это нужно как-то оценить 😊
Сейчас взяла в работу задачу по починке скриншотных тестов. Ситуация: локально и в ci тесты проходят с разным результатом. Докер образ один и тот же. Честно говоря, я даже не представляю, в чем может быть проблема - я специально настраивала прогон в докере, чтобы добиться консистентности результата.
И ведь мне это нужно как-то оценить 😊
🤯7👍4😨2👌1
Говорила то же самое, когда это еще не было мейнстримом 😊
Брутфорсить собесы - это очень плохая идея.
Брутфорсить собесы - это очень плохая идея.
💯2👍1🤮1
Forwarded from Стародубцев x IT-ХОЗЯЕВА
Сейчас я расскажу неприятный, но важный факт 👮
Не ходи на собеседования, если не готов к ним.
У большинства компаний есть кд по найму, если кандидат не подошёл. В свете последних событий, когда найти работу стало сложнее, провалить собеседование - плохая идея.
Поэтому не стоит выходить на рынок:
С сырым резюме (получишь меньше денег).
Без базового знания алгоритмов.
Без понимания предметной области, в которую идёшь.
Без осознания того, что ты хочешь делать на работе.
Без базовых софтов (очень много отлетают на собесе с командой).
Как подготовиться?
Пробные собеседования (моки). Смотреть, как другие плавают по реке - круто, а самому поплавать — совсем другое дело.
Резюме. В нашем сообществе есть отдельный чат с разборами резюме, можно спросить совета и исправить ошибки. Ну и получить ответ сколько денег просить, многие до сих пор не знают настоящие вилки. Или спроси у знакомого из другой компании!
Всё это необходимый минимум. В нынешней ситуации приходить неподготовленным - неуважение к себе и работодателю. Ты не только потратишь время, но и получишь «фриз» на полгода в этой компании. А ведь этот оффер мог бы помочь в переговорах с компанией "мечты" где ты мог бы поторговаться.
Не ходи на собеседования, если не готов к ним.
У большинства компаний есть кд по найму, если кандидат не подошёл. В свете последних событий, когда найти работу стало сложнее, провалить собеседование - плохая идея.
Поэтому не стоит выходить на рынок:
С сырым резюме (получишь меньше денег).
Без базового знания алгоритмов.
Без понимания предметной области, в которую идёшь.
Без осознания того, что ты хочешь делать на работе.
Без базовых софтов (очень много отлетают на собесе с командой).
Как подготовиться?
Пробные собеседования (моки). Смотреть, как другие плавают по реке - круто, а самому поплавать — совсем другое дело.
Резюме. В нашем сообществе есть отдельный чат с разборами резюме, можно спросить совета и исправить ошибки. Ну и получить ответ сколько денег просить, многие до сих пор не знают настоящие вилки. Или спроси у знакомого из другой компании!
Всё это необходимый минимум. В нынешней ситуации приходить неподготовленным - неуважение к себе и работодателю. Ты не только потратишь время, но и получишь «фриз» на полгода в этой компании. А ведь этот оффер мог бы помочь в переговорах с компанией "мечты" где ты мог бы поторговаться.
Please open Telegram to view this post
VIEW IN TELEGRAM
💯13❤8😁5👎1
Во времена “сломанного найма” многие задаются вопросом, стоят ли сопроводительные письма потраченного на них времени. Я считаю, что сопроводительные полезны, однако занимают много времени. Я придумала способ, как делать сопроводительные быстро и качественно.
Многие пишут резюме в духе “работу работал”. Одна из главных проблем нанимающих менеджеров - это программисты, которые пишут код, не приходя в сознание и не имея понятия, что и для чего они делают (потом еще часто выясняется, что они таки сделали не то, что от них требовалось). Если у вас есть опыт работы 2-3 года, то вы наверняка на чем-то специализируетесь. Возможно, вы все это время работали в аутсорсе и умеете быстро делать шаблонные проекты. Или же вы много работали с интерактивными картами. Или у вас хорошо получаются сложные css анимации. Дайте ответ на вопрос, какие задачи вами можно закрыть и чем вы можете быть полезны бизнесу. Этот ответ должен быть подтвержден вашим резюме.
Я использую для этого “Заметки” в макбуке. Эти тезисы станут составными блоками вашего конструктора сопроводительных писем. Допустим, последние три года вы работали в аутсорсе и разрабатывали на React и Next.js. Тогда ваши тезисы могут выглядеть так:
- “У меня есть опыт работы в аутсорсе, я умею закрывать проекты точно в срок”
- “У меня три года опыта коммерческой разработки на React”
- “У меня три года опыта коммерческой разработки на React и Next.js”
- “Я уже занимался разработкой интернет-магазина ShopName - реализовал X, Y, Z”
- “Последние два года я использую FSD”
- “У меня есть опыт работы с Redux и Mobx”
- “Я умею делать анимации на React Motion”
- “Я умею применять паттерны проектирования и принципы SOLID, KISS, DRY”
Обратите внимание, что опыт работы на Reaсt и опыт работы на React+Next.js вынесен в разные тезисы: это связано с тем, что на одни вакансии нужен только React, а на другие - React и Next.js.
Некоторые блоггеры советуют откликаться на все подряд. Я с этим не согласна: в кризис у вас почти нет шансов “вхолодную” пройти на нерелевантную вакансию.
Говорят, что эйчары тратят 30 секунд на чтение одного резюме. Вы можете сделать то же самое, но с вакансиями. Не поленитесь потратить 30 секунд на чтение вакансии и понять, подходит ли вам вакансия по навыкам и опыту. Откликайтесь только на подходящие.
В 99% процентах случаев по тексту вакансии можно хотя бы примерно понять, чего от вас хотят. Даже если вакансия составлена так, словно ее писал бредогенератор, то в ней, как минимум, указана сфера деятельности компании (а если нет, то ее можно погуглить😉) и стек. Если повезет, то в вакансии будет подробный портрет идеального кандидата.
Соотносим ваши сильные стороны с требованиями в вакансии и простым копипастом получаем релевантное сопроводительное. Например, в вакансии ищут разработчика в интернет-магазин и ожидают навыки Next.js, FSD и базовое понимание архитектурных принципов. Получаем:
“Добрый день! Заинтересовала вакансия frontend разработчика.
У меня три года опыта коммерческой разработки на React и Next.js. Я уже занимался разработкой интернет-магазина ShopName - реализовал X, Y, Z. Последние два года я использую FSD, умею применять паттерны проектирования и принципы SOLID, KISS, DRY.
Готов ответить на любые ваши вопросы”.
На ручной сбор одного такого письма из блоков уходит приблизительно 5-8 секунд. При этом письмо получается минимум на 90% релевантным.
Можно загрузить тезисы в ИИ и в тот же чат скидывать описание вакансии: ИИ неплохо пишет сопроводительные по составленным тезисам 😉
#резюме #сопроводительное
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤16🔥6👍5👎1
Как быть программистом (особенно фронтендером) и не сойти с ума 🤯
Разработка, особенно фронтенд разработка - невероятно динамичная область. Не успел выучить старый фреймворк, уже появился новый, а к нему пять библиотек в придачу. Все это учить - сойдешь с ума. Забить - останешься без работы на дистанции пяти лет. Что делать?
Ответ простой: не учите технологии, учите идеи, которые за ними стоят. Например, современные фронтенд фреймворки (React, Vue, Angular) используют идеи реактивной архитектуры и шаблоны MVC, MVVM. Стейт менеджеры используют идеи flux, FSD использует идеи DDD. Поймите ключевые идеи - и вы сможете молниеносно изучать новые фреймворки и библиотеки, достаточно увидеть, какие идеи они реализуют.
Приведу пример из своей жизни: в 2019 году я свитчнулась с Vue на React, выучив основы за несколько часов, сидя в аэропорту. Это возможно за счет того, что они используют одни и те же базовые идеи. Последние две недели я и вовсе пишу код на go. Я прошла короткий бесплатный курс по языку на Хекслет и поняла, что основные идеи я уже видела раньше в других языка, поэтому смена языка не доставила мне особых хлопот.
Для того, чтобы легко переключаться между фреймворками и языками, нужно знать всего несколько вещей:
1️⃣ Конструкции структурного программирования: условия, циклы, подпрограммы.
2️⃣ Структуры данных: числа, строки, булеаны, стеки, очереди, массивы, хеш-таблицы, кортежи, списки, деревья. В большинстве языков программирования они ведут себя схожим образом и имеют схожие методы.
3️⃣ Основы ООП: абстракция, инкапсуляция, наследование, полиморфизм. Эти идеи неявно используются в современных фронтенд фреймворках.
4️⃣ Паттерны проектирования: фабрика, строитель, шаблонный метод, фасад, итератор, стратегия, синглтон, обсервер. Эти идеи используются во многих современных библиотеках.
5️⃣ Архитектурные шаблоны уровня приложения: MV*, реактивные, луковые, гексагональные архитектуры, event sourcing и CQRS.
Разработка, особенно фронтенд разработка - невероятно динамичная область. Не успел выучить старый фреймворк, уже появился новый, а к нему пять библиотек в придачу. Все это учить - сойдешь с ума. Забить - останешься без работы на дистанции пяти лет. Что делать?
Ответ простой: не учите технологии, учите идеи, которые за ними стоят. Например, современные фронтенд фреймворки (React, Vue, Angular) используют идеи реактивной архитектуры и шаблоны MVC, MVVM. Стейт менеджеры используют идеи flux, FSD использует идеи DDD. Поймите ключевые идеи - и вы сможете молниеносно изучать новые фреймворки и библиотеки, достаточно увидеть, какие идеи они реализуют.
Приведу пример из своей жизни: в 2019 году я свитчнулась с Vue на React, выучив основы за несколько часов, сидя в аэропорту. Это возможно за счет того, что они используют одни и те же базовые идеи. Последние две недели я и вовсе пишу код на go. Я прошла короткий бесплатный курс по языку на Хекслет и поняла, что основные идеи я уже видела раньше в других языка, поэтому смена языка не доставила мне особых хлопот.
Для того, чтобы легко переключаться между фреймворками и языками, нужно знать всего несколько вещей:
Please open Telegram to view this post
VIEW IN TELEGRAM
4❤🔥32👍21❤10🔥3👎1👏1
Часто слышу, что задания на собеседованиях не имеют ничего общего с реальной работой. Это не совсем так. Да, в продакшн коде вам наверняка не потребуется проверять, является ли строка палиндромом, но такие задачи проверяют куда более фундаментальные навыки.
Это можно сравнить с тренировкой в спортзале: в реальной жизни вам не требуется делать становую тягу или подъем штанги на бицепс, однако мышцы, которые вы нарабатываете, помогут вам и сумку с продуктами донести, и коробку с техникой поднять, и просто держать осанку.
〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️
Основная цель собеседования - понять, умеет ли человек программировать.
〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️
Этот навык включает в себя набор разных умений:
🔴 Абстрактное мышление: умение видеть за конкретными примерами общие закономерности и принципы.
🔴 Дедукция и индукция: навык сводить ряд фактов воедино, а от общего принципа переходить к частному.
🔴 Алгоритмическое мышление: умение понять, при помощи каких шагов можно достичь цели.
〰️ Например, алгоритмические задачи по типу задач с leetcode отлично показывают:
🔴 Знаете ли вы структуры данных и их методы - без этого не получится никакого программирования
🔴 Умеете ли внимательно читать и, главное, понимать условие задачи
🔴 Способны ли составить план решения
🔴 Можете ли «прокрутить» код в голове и предсказать результат на разных входных данных
〰️ Теоретические вопросы (те самые набившие оскомину “100 вопросов по Javanoscript”) проверяют базовое понимание архитектуры приложений. Представьте, что вам прилетел баг - после установки фильтров в query параметры страница перезагружается.
С чего начать? Вам помогут базовые знания:
🔴 Архитектура веб-приложений (помните вопрос “что происходит, когда пользовать переходит на сайт google.com” ? Это оно самое)
🔴 SPA архитектура
🔴 Методы Javanoscript для работы с адресной строкой (window.history, window.location)
Да, вы можете сказать, что в этом случае вы не взаимодействуете с объектом window напрямую, вы используете react router, но он имеет те же принципы работы, что и нативное апи. Разные технологии часто строятся на одних и тех же идеях, просто используют их по-разному - поэтому важно понимать эти фундаментальные идеи. Подробнее об этом писала здесь.
Поэтому учите базу - она поможет вам в любой ситуации: и пройти собеседование, и в новом поекте быстро разобраться, и свитчнуться на новый фреймворк или даже язык❤️
#база
Это можно сравнить с тренировкой в спортзале: в реальной жизни вам не требуется делать становую тягу или подъем штанги на бицепс, однако мышцы, которые вы нарабатываете, помогут вам и сумку с продуктами донести, и коробку с техникой поднять, и просто держать осанку.
Основная цель собеседования - понять, умеет ли человек программировать.
Этот навык включает в себя набор разных умений:
С чего начать? Вам помогут базовые знания:
Да, вы можете сказать, что в этом случае вы не взаимодействуете с объектом window напрямую, вы используете react router, но он имеет те же принципы работы, что и нативное апи. Разные технологии часто строятся на одних и тех же идеях, просто используют их по-разному - поэтому важно понимать эти фундаментальные идеи. Подробнее об этом писала здесь.
Поэтому учите базу - она поможет вам в любой ситуации: и пройти собеседование, и в новом поекте быстро разобраться, и свитчнуться на новый фреймворк или даже язык
#база
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Фронтенд кухня🥘
Как быть программистом (особенно фронтендером) и не сойти с ума 🤯
Разработка, особенно фронтенд разработка - невероятно динамичная область. Не успел выучить старый фреймворк, уже появился новый, а к нему пять библиотек в придачу. Все это учить - сойдешь…
Разработка, особенно фронтенд разработка - невероятно динамичная область. Не успел выучить старый фреймворк, уже появился новый, а к нему пять библиотек в придачу. Все это учить - сойдешь…
❤16👍13🤡6❤🔥3
Небольшое объявление для тех, кто планировал прийти ко мне на менторство или консультации - из-за сильной загруженности как минимум до конца октября такой возможности не будет :(
Это не относится к тем, с кем уже работаю или с кем есть договоренности.
Upd. Если вам нужна моя помощь и дело не терпит до конца октября, на данный момент смогу уделить вашему кейсу 10-15 минут и ответить на ваш вопрос в личке. Пишите в личку. Это бесплатно😊
Это не относится к тем, с кем уже работаю или с кем есть договоренности.
Upd. Если вам нужна моя помощь и дело не терпит до конца октября, на данный момент смогу уделить вашему кейсу 10-15 минут и ответить на ваш вопрос в личке. Пишите в личку. Это бесплатно😊
1😭9✍5👍4👎1
Кодовая база pinned «Небольшое объявление для тех, кто планировал прийти ко мне на менторство или консультации - из-за сильной загруженности как минимум до конца октября такой возможности не будет :( Это не относится к тем, с кем уже работаю или с кем есть договоренности. Upd.…»
Прошлый пост вызвал жаркую дискуссию о том, нужны ли алгоритмы.
Для меня знание алгоритмов - как личный автомобиль: без него можно прожить, но с ним гораздо удобнее. Самое главное, что дает их изучение - это умение думать. Казалось бы, зачем в повседневной работе помнить DFS или бинарный поиск? Не лучше ли сразу учиться на реальных задачах?
Я считаю так: если вы учитесь на реальных задачах, то вам постоянно придется учиться каким-то новым реальным задачам. На старой работе вы привыкли хранить данные в редаксе, приходите на новую, опа, а тут используется контекст. Приходится постоянно переучиваться.
Так получается потому, что реальных задач невероятно много. А вот фундаментальных задач, частными случаями которых являются реальные, на порядки меньше. Понимая фундаментальные задачи, можно с их помощью решить частные случаи. А вот наоборот, увы, не работает (ну а если у вас работает, значит, вы уже шарите в алгоритмах😎).
Для меня знание алгоритмов - как личный автомобиль: без него можно прожить, но с ним гораздо удобнее. Самое главное, что дает их изучение - это умение думать. Казалось бы, зачем в повседневной работе помнить DFS или бинарный поиск? Не лучше ли сразу учиться на реальных задачах?
Я считаю так: если вы учитесь на реальных задачах, то вам постоянно придется учиться каким-то новым реальным задачам. На старой работе вы привыкли хранить данные в редаксе, приходите на новую, опа, а тут используется контекст. Приходится постоянно переучиваться.
Так получается потому, что реальных задач невероятно много. А вот фундаментальных задач, частными случаями которых являются реальные, на порядки меньше. Понимая фундаментальные задачи, можно с их помощью решить частные случаи. А вот наоборот, увы, не работает (ну а если у вас работает, значит, вы уже шарите в алгоритмах😎).
👍15🔥9❤4🤡2
This media is not supported in your browser
VIEW IN TELEGRAM
Бинарный поиск
Сегодня поговорим о бинарном поиске.
Бинарный поиск нужен для того, чтобы быстро что-то найти. Для того, чтобы можно было легко что-то найти, нужен порядок (прямо как в шкафу). Проще говоря, данные, где вы ищите, должны быть отсортированы по какому-нибудь признаку.
Алгоритм бинарного поиска заключается в том, что мы делим кучу данных на две равные кучки данных поменьше и затем пытаемся понять, какая из двух кучек нам подходит. После того, как мы это поняли, мы продолжаем поиск в нужной кучке. Вот и весь Великий и Ужасный Алгоритм, которым пугают джунов, как бабайкой.С вас три тыщи.
В классическом варианте вы наверняка увидите массив чисел, в котором ищется числовластвуй сравнивай” - очень полезная.
В повседневной работе идея делить кучу на две поменьше пригождается в самых разных ситуациях. Например, конструкция
Можно пойти дальше в своих размышлениях и додумать до идеи делить кучу не на две, а на три. Такие задачи иногда дают младшеклассникам на олимпиадах по математике. Мне впервые попалась такая в подготовительных материалах, когда мне было 8 лет, и решение дошло до меня только на следующий день.
Удачных вам разделений и сравнений!
#алгосы
Сегодня поговорим о бинарном поиске.
Бинарный поиск нужен для того, чтобы быстро что-то найти. Для того, чтобы можно было легко что-то найти, нужен порядок (прямо как в шкафу). Проще говоря, данные, где вы ищите, должны быть отсортированы по какому-нибудь признаку.
Алгоритм бинарного поиска заключается в том, что мы делим кучу данных на две равные кучки данных поменьше и затем пытаемся понять, какая из двух кучек нам подходит. После того, как мы это поняли, мы продолжаем поиск в нужной кучке. Вот и весь Великий и Ужасный Алгоритм, которым пугают джунов, как бабайкой.
В классическом варианте вы наверняка увидите массив чисел, в котором ищется число
x, равное, ну скажем для примера, 17. Мы делим кучку на две части пополам, и смотрим, чему равна середина. Если середина больше 17, то нам нужно искать в левой кучке (там, где числа поменьше). Если середина меньше 17, то наша кучка - правая. Искать таким образом числа в массиве вам, скорее всего, не потребуется никогда, но вот сама идея - “разделяй и В повседневной работе идея делить кучу на две поменьше пригождается в самых разных ситуациях. Например, конструкция
if else тоже позволяет поделить данные на две кучки по какому-нибудь признаку. А еще та идея полезна для дебага. Допустим, вы внесли много изменений в код и в какой-то момент все сломалось (прямо как у меня сегодня). Как быстро найти проблемный файл? Очень просто: убираем половину ченжей (например, в stash) и проверяем, как это отразилось на баге. Если баг все еще воспроизводится, то делим эту кучку еще на две. Эту же идею использует для дебага git bisect. Можно пойти дальше в своих размышлениях и додумать до идеи делить кучу не на две, а на три. Такие задачи иногда дают младшеклассникам на олимпиадах по математике. Мне впервые попалась такая в подготовительных материалах, когда мне было 8 лет, и решение дошло до меня только на следующий день.
Удачных вам разделений и сравнений!
#алгосы
1❤10👍7🥱4🔥3
Абстракция - это упрощение объекта до его ключевых характеристик. Благодаря абстракции мы можем пользоваться объектом, не вдаваясь в детали его реализации. Несмотря на кажущуюся сложность этого определения, абстракция нужна, чтобы облегчить нам жизнь. Абстракция заставляет объекты и функции соблюдать контракт (т.е. интерфейс), благодаря чему мы можем пользоваться ими, не разбираясь, как они этот контракт реализуют.
Работу абстракции можно сравнить с работой сеньора-программиста. Если вы даете задачу сеньору, то (упрощенно говоря) вас не волнует, каким именно образом он ее реализует, какие технологии выберет и какую архитектуру. Вы специально наняли сеньора, чтобы он решил все эти проблемы и избавил вас от головняка. То же самое с абстракциями: если у меня есть, скажем, функция, которая называется
sendRequest, я ожидаю, что она будет отправлять запросы, а уж как она это делает, меня не волнует.Работа абстракций во многом похожа на работу программистов. Во-первых, она должна делать то, что от нее ожидается (иначе это плохая абстракция, ее надо
Чтобы создать хорошую абстракцию, необходимо:
И да, сходство работает и в обратную сторону: пока программист делает то, что от него ожидается, мало кто интересуется, как именно он это делает 🙂
#ооп
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍7🥱7🔥2
Если вы понимаете, что такое рекурсия и когда её применять — можете пропускать этот пост 🙂
Рекурсия во фронтенде встречается чаще, чем кажется. Например:
Не всем программистам очевидно, когда именно стоит применять рекурсию. И здесь нам приходит на помощь понимание, что такое абстракция, о котором я писала в предыдущем посте. Абстракция даёт нам контракт, которым мы можем пользоваться, при этом нам не нужно знать ни детали реализации, ни даже быть уверенным в том, что эта реализация уже готова. То есть: при написании любой функции мы можем использовать ее саму, потому что ее контракт гарантирован.
Допустим, вы пишете функцию, которая вычисляет факториал - произведение всех чисел от
x до 1. Поможет ли результат этой же функции с каким-нибудь другим аргументом? Да - ведь нам надо вычислить произведение x на произведение всех предыдущих чисел, а это как раз факториал предыдущего числа x - 1. Значит, мы можем легко вычислить факториал следующим образом:const factorial = (x) => x * factorial(x - 1)
Затем нужно учесть корнер кейсы. Мы вычитаем 1 из
x и очевидно, что лучше не делать это до минус бесконечности. Нужно выбрать какое-то конкретное число, на котором мы остановимся. Логично выбрать число 0, потому что это наименьшее число, для которого определена функция факториала. Получаем финальное решение: const factorial = (x) => x ? x * factorial(x - 1) : 1
Задача: есть дерево, где каждая нода содержит id и массив children. Нужно собрать все id.
Заметим, что задача сильно упрощается, если нам не нужно думать про
id дочерних элементов. Предположим, что уже существует функция getChildrenIds, которая возвращает id дочерних элементов. Останется добавить id текущей ноды. Получаем решение:const getIds(node) => […getChildrenIds(), node.id]
Теперь реализуем
getChildrenIds. Она должна вернуть все id дочерних элементов. Но у нас уже есть функция getIds, которая вернет id элементов поддерева. Если вызвать ее для каждого потомка, то она вернет все id всех поддеревьев. Итого:const getIds = (node) => {
let result = [node.id];
node.children.forEach((child) => result = result.concat(getIds(child)))
return result;
}Желаю вам удачного выхода из рекурсивного цикла! 🔄 Еще про рекурсию можно почитать в этом посте.
#алгосы
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Фронтенд кухня🥘
🎯Рекурсия
Если вы понимаете, что такое рекурсия и когда её применять — можете пропускать этот пост 🙂
〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️
Рекурсия во фронтенде встречается чаще, чем кажется. Например:
🔘 вычисление коэффициентов…
Если вы понимаете, что такое рекурсия и когда её применять — можете пропускать этот пост 🙂
〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️
Рекурсия во фронтенде встречается чаще, чем кажется. Например:
🔘 вычисление коэффициентов…
🔥8🥱5
Forwarded from fedos dot com
…
За последние десятилетия программисты видели массу инструментов, которые предположительно должны были устранить необходимость программирования. Сначала это были языки третьего поколения, потом — четвертого. Потом — автоматическое программирование. Потом — CASE-средства. Потом — визуальное программирование. Каждое из этих достижений привносило значительные улучшения, и общими усилиями они сделали программирование абсолютно неузнаваемым для тех, кто изучал его до этих нововведений. Но ни одна из этих инноваций не устранила программирования как такового.
Причина в том, что программирование — принципиально сложный процесс даже при наличии хорошего инструментария. Дело не в инструментах — программистам приходится бороться с несовершенством реального мира; нам нужно досконально продумывать последовательности, зависимости и исключения, иметь дело с конечными пользователями, которые никак не могут ничего решить. Нам всегда придется бороться с плохо определенными интерфейсами с другими программными и аппаратными средствам и всегда принимать во внимание инструкции, бизнес-правила и другие источники сложных проблем, возникающие вне мира программирования.
Нам всегда будут нужны люди, способные заполнить брешь между задачей реального мира, которую нужно решить, и компьютером, предназначенным для решения этой задачи. Эти люди будут называться программистами независимо от того, манипулируют они машинными регистрами на ассемблере или диалоговыми окнами в Microsoft Visual Basic. Пока у нас есть компьютеры, нам будут нужны люди, которые говорят компьютерам, чтó делать, и эта деятельность будет называться программированием.
Когда вы слышите заявления о том, что «новый инструментарий устранит необходимость компьютерного программирования», бегите! Или хотя бы посмейтесь про себя над этим наивным оптимизмом.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7💯3❤1👎1🤔1
Решила проверить, как обстоят дела с поиском работы для фронтендеров на hh. Создала максимально дефолтное резюме максимально дефолтного миддла на React, указала 3 года опыта работы в ноу нейм компания. Сделала 30 откликов (на большее не хватило времени).
Результаты:
▫️ Отказов: 10 (один автоматический спустя минуту, в бигтех)
▫️ Предложений от hr перейти общаться в телеграмм: 2
▫️ Тестовое: 1
▫️ Звонок (на hh появились звонки?...): 1
Что лично я считаю неплохим результатом.
Результаты:
Что лично я считаю неплохим результатом.
Please open Telegram to view this post
VIEW IN TELEGRAM
1🤗14💩8👍6✍1🤡1
🚀 Как делать задачи быстрее
Самый простой способ ускорить работу, если вы фронтенд-разработчик - это использовать жоский typenoscript. То есть не ограничиваться стандартными типами
Например,
📌 Чем жестче ваш typenoscript, тем быстрее вы будете работать.
На первый взгляд это звучит парадоксально: почему скорость работы увеличится, если жесткая типизация добавит работы? А вот почему:
1️⃣ Меньше ручных проверок
Большинство из нас пишет код так: написал, сохранил, перезагрузил браузер, проверил, поправил. Больше всего времени тратится на пересборку приложения, перезагрузку браузера и прохождение юзер флоу. Когда типы заданы строго, достаточно убедиться, что код скомпилировался. Проверить всю работу новой фичи можно один раз в самом конце, перед ревью.
(Это, конечно, работает, когда вы пишете логику, а не верстаете.)
2️⃣ Меньше багов и возвратов из тестирования
Основная задача typenoscript как инструмента - снизить количество ошибок в рантайме, перенеся их в compile-time. Чем жестче ваша типизация, тем меньше багов будет в результате🔜 меньше доработок и возвратов фичи из тестирования
3️⃣ Типы выполняют роль документации и делают код более читаемым.
Для тех, кто хочет попрактиковаться в написании типов, есть классный репозиторий https://github.com/type-challenges/type-challenges - в нем собраны задачи от самого легкого до продвинутого уровня.
Самый простой способ ускорить работу, если вы фронтенд-разработчик - это использовать жоский typenoscript. То есть не ограничиваться стандартными типами
string/number/boolean и объектами из них, а реально ограничить тип только возможными значениями. Например,
email - это не любой string, а только составленный по определенному правилу, содержащий символы @ и .. Пин-код, - это тоже не любой string, а строка ровно из 4 цифр.На первый взгляд это звучит парадоксально: почему скорость работы увеличится, если жесткая типизация добавит работы? А вот почему:
Большинство из нас пишет код так: написал, сохранил, перезагрузил браузер, проверил, поправил. Больше всего времени тратится на пересборку приложения, перезагрузку браузера и прохождение юзер флоу. Когда типы заданы строго, достаточно убедиться, что код скомпилировался. Проверить всю работу новой фичи можно один раз в самом конце, перед ревью.
(Это, конечно, работает, когда вы пишете логику, а не верстаете.)
Основная задача typenoscript как инструмента - снизить количество ошибок в рантайме, перенеся их в compile-time. Чем жестче ваша типизация, тем меньше багов будет в результате
Для тех, кто хочет попрактиковаться в написании типов, есть классный репозиторий https://github.com/type-challenges/type-challenges - в нем собраны задачи от самого легкого до продвинутого уровня.
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge
Collection of TypeScript type challenges with online judge - type-challenges/type-challenges
1❤18🔥9👍4👎3❤🔥2🌚2✍1💯1🤝1
Дискуссия про применимость алгоритмических задач с собеседований в реальной работе получила новый виток. Сегодня в комментариях подкинули вот такую задачу с собеседования:
*️⃣ *️⃣ *️⃣
Вы хотите набрать строку s, состоящую из строчных латинских букв, в вашем любимом текстовом редакторе Notepad#.
Notepad# поддерживает два типа операций:
дописать любую букву в конец строки;
скопировать непрерывную подстроку уже напечатанной строки и вставить эту подстроку в конец строки.
Можно ли набрать строку s за число операций, меньшее длины строки?
canBeTypedFaster("tbank") => false
canBeTypedFaster("mama") => true
*️⃣ *️⃣ *️⃣
Задача несложная, мне потребовалось примерно двадцать секунд на подумать и еще пару минут на закодить. Вот что у меня получилось:
Как я рассуждала: для того, чтобы воспользоваться опцией копипаста, нужно, чтобы в целевой строке повторялась хотя бы одна группа из двух символов. Тогда эту группу можно будет скопировать и вставить. Можно и больше, но двух символов хватит. Следовательно, задача сводится к тому, чтобы понять, есть ли в строке повторяющиеся группы из двух элементов. Дальше все просто: я прохожусь по строке и запоминаю все группы из двух подряд идущих символов, а также проверяю, встречалась ли мне такая группа раньше. Если встречалась, то значит, эту группу можно скопировать и для такой строки ответ будет true. В противном случае ответ будет false.
Обратите внимание, для решения этой задачи мне не потребовались никакие Ужасные Алгоритмы вроде бинарного поиска, обхода дерева или хотя бы рекурсии. Вот, что я использовала:
🟣 Логическую редукцию: свела задачу поиска строк, которые можно набрать быстрее, к поиску строк, у которых есть группа из двух повторяющихся элементов.
🟣 Логическую дедукцию: свела задачу поиска повторяющихся групп к перебору всех возможных групп и сохнанению встреченных групп.
🟣 Логический синтез: собрала все вместе.
Именно навык рассуждать логически и проверяют на собеседованиях подобные задачи. Для того, чтобы решать такие задачи, необязательно задротить литкод (хотя это хорошая идея), достаточно научиться рассуждать логически. У меня на литкоде дайбох если штук 10 решенных задач есть, однако на собеседованиях я решаю 90% задач. Литкод - это не цель и не поэма, которую нужно выучить наизусть, это всего лишь тренажер для отработки навыков логического мышления.
#алгоритмы
Вы хотите набрать строку s, состоящую из строчных латинских букв, в вашем любимом текстовом редакторе Notepad#.
Notepad# поддерживает два типа операций:
дописать любую букву в конец строки;
скопировать непрерывную подстроку уже напечатанной строки и вставить эту подстроку в конец строки.
Можно ли набрать строку s за число операций, меньшее длины строки?
canBeTypedFaster("tbank") => false
canBeTypedFaster("mama") => true
Задача несложная, мне потребовалось примерно двадцать секунд на подумать и еще пару минут на закодить. Вот что у меня получилось:
function canBeTypedFaster(str) {
const set = new Set();
for (let i = 0; i < str.length - 1; i++) {
const substring = str.substring(i, i + 2);
if (set.has(substring)) {
return true;
}
set.add(substring);
}
return false;
}Как я рассуждала: для того, чтобы воспользоваться опцией копипаста, нужно, чтобы в целевой строке повторялась хотя бы одна группа из двух символов. Тогда эту группу можно будет скопировать и вставить. Можно и больше, но двух символов хватит. Следовательно, задача сводится к тому, чтобы понять, есть ли в строке повторяющиеся группы из двух элементов. Дальше все просто: я прохожусь по строке и запоминаю все группы из двух подряд идущих символов, а также проверяю, встречалась ли мне такая группа раньше. Если встречалась, то значит, эту группу можно скопировать и для такой строки ответ будет true. В противном случае ответ будет false.
Обратите внимание, для решения этой задачи мне не потребовались никакие Ужасные Алгоритмы вроде бинарного поиска, обхода дерева или хотя бы рекурсии. Вот, что я использовала:
Именно навык рассуждать логически и проверяют на собеседованиях подобные задачи. Для того, чтобы решать такие задачи, необязательно задротить литкод (хотя это хорошая идея), достаточно научиться рассуждать логически. У меня на литкоде дайбох если штук 10 решенных задач есть, однако на собеседованиях я решаю 90% задач. Литкод - это не цель и не поэма, которую нужно выучить наизусть, это всего лишь тренажер для отработки навыков логического мышления.
#алгоритмы
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤10👍6👎5❤🔥3🤮1🍌1
Скормила эту задачу чату гпт. Вот что он мне выдал:
*⃣ *⃣ *⃣
Думал на протяжении 16s
Короткий ответ: да — ровно тогда, когда в строке s существует фрагмент длины ≥ 2, который в какой-то момент встречается снова так, что его второе вхождение начинается в позиции, когда префикс до этой позиции уже напечатан. Формально: существует i (1 ≤ i ≤ n-1) и L ≥ 2 такие, что i + L ≤ n и s.substring(i, i+L) встречается в s.substring(0, i). В этом случае можно одну или несколько таких копий использовать и получить число операций < n.
Ниже — простая и надёжная реализация на JavaScript:
Сложность приведённого кода в худшем случае O(n³) в naive JS (из-за indexOf внутри двойного цикла), но на строках обычной длины это проходит быстро. Если нужна оптимизация для больших строк — можно применять суффиксный массив/дерево, Z-функцию или KMP/rolling hash, чтобы сократить до O(n²) или O(n).
*⃣ *⃣ *⃣
По-моему, какая-то лажа. Чат гпт решил искать не только группы из двух элементов, но и более длинные, хотя достаточно групп из двух элементов - они входят в более длинные. Еще и сложность кубическая.
Думал на протяжении 16s
Короткий ответ: да — ровно тогда, когда в строке s существует фрагмент длины ≥ 2, который в какой-то момент встречается снова так, что его второе вхождение начинается в позиции, когда префикс до этой позиции уже напечатан. Формально: существует i (1 ≤ i ≤ n-1) и L ≥ 2 такие, что i + L ≤ n и s.substring(i, i+L) встречается в s.substring(0, i). В этом случае можно одну или несколько таких копий использовать и получить число операций < n.
Ниже — простая и надёжная реализация на JavaScript:
// Возвращает true, если строку s можно набрать за число операций < s.length
function canBeTypedFaster(s) {
const n = s.length;
if (n <= 1) return false; // невозможно сократить
// для каждой позиции i — попробовать найти любую длину L>=2,
// такую что s[i:i+L] содержится в префиксе s[0:i]
for (let i = 1; i < n; i++) {
// максимальная длина, которую можем попытаться скопировать отсюда
const maxL = n - i;
// интересуют только L >= 2
for (let L = 2; L <= maxL; L++) {
const chunk = s.substring(i, i + L);
if (s.substring(0, i).indexOf(chunk) !== -1) {
return true;
}
}
}
return false;
}
// Примеры
console.log(canBeTypedFaster("tbank")); // false
console.log(canBeTypedFaster("mama")); // true
Сложность приведённого кода в худшем случае O(n³) в naive JS (из-за indexOf внутри двойного цикла), но на строках обычной длины это проходит быстро. Если нужна оптимизация для больших строк — можно применять суффиксный массив/дерево, Z-функцию или KMP/rolling hash, чтобы сократить до O(n²) или O(n).
По-моему, какая-то лажа. Чат гпт решил искать не только группы из двух элементов, но и более длинные, хотя достаточно групп из двух элементов - они входят в более длинные. Еще и сложность кубическая.
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Фронтенд кухня🥘
Дискуссия про применимость алгоритмических задач с собеседований в реальной работе получила новый виток. Сегодня в комментариях подкинули вот такую задачу с собеседования:
*️⃣*️⃣*️⃣
Вы хотите набрать строку s, состоящую из строчных латинских букв, в вашем…
*️⃣*️⃣*️⃣
Вы хотите набрать строку s, состоящую из строчных латинских букв, в вашем…
❤🔥8👎2🖕2❤1🤮1
Друг скинул еще одну задачу с собеседования: https://leetcode.com/problems/isomorphic-strings/. На ее решение у меня ушло около 7 минут. Решение:
Меня огорчило, что я не попала в 10% самых быстрых решений (beats 89.81%). Закинула чат гпт и он решил гораздо хуже (beats 32.05%).
Вот так этим вечером внезапно выяснилось, что чат гпт решает алгозадачи так себе - по крайней мере, те две, которые мы разбирали сегодня в канале, он решил хуже меня.
Для меня это еще один повод использовать алгозадачи на собесах 😎
var isIsomorphic = function(s, t) {
const dictS = {};
const dictT = {};
for (let i = 0; i < s.length; i++) {
const sChar = s[i];
const tChar = t[i];
if (!check(sChar, tChar, dictS) || !check(tChar, sChar, dictT)) {
return false;
}
}
return true;
};
function check(origin, replacer, map) {
if (map[origin]) {
return map[origin] === replacer
}
map[origin] = replacer;
return true;
}Меня огорчило, что я не попала в 10% самых быстрых решений (beats 89.81%). Закинула чат гпт и он решил гораздо хуже (beats 32.05%).
Вот так этим вечером внезапно выяснилось, что чат гпт решает алгозадачи так себе - по крайней мере, те две, которые мы разбирали сегодня в канале, он решил хуже меня.
Для меня это еще один повод использовать алгозадачи на собесах 😎
LeetCode
Isomorphic Strings - LeetCode
Can you solve this real interview question? Isomorphic Strings - Given two strings s and t, determine if they are isomorphic.
Two strings s and t are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced…
Two strings s and t are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced…
👎23🔥14👍6🤮3✍1🖕1
Мне интересно, дизлайк на предыдущий пост поставил человек, который попал в 10% самых быстрых решений? 🤔
👎21💩6🐳3🦄3🤣1🖕1