Применение теории на практике
Иногда ко мне приходят ребята, которые сталкиваются с проблемами в коде. Буквально: “не знаю, как сделать эту фичу”, “мой код не работает, но я не знаю, почему”. Это обычно называют практикой, но, на мой взгляд, это всё ещё теория — человек не освоил инструмент и не понимает, как получить нужный результат.
Однако бывает и по-другому: инструмент освоен, но используется нецелесообразно. Например, пишутся хрупкие или тривиальные юнит-тесты. Или все подряд функции в компонентах заворачиваются в useCallback. На мой взгляд, это ошибка применения теории на практике.
Чем вообще отличается теория от практики? Я считаю, теория включает в себя освоение принципов работы какого-нибудь инструмента или подхода. Вы изучаете его возможности, логику и принципы. А практика — это приложение этих знаний к реальному бизнес-процессу. Практика обязательно включает в себя выбор инструмента, а для того, чтобы выбрать, надо знать свойства разных подходов. Если у вас есть завод и вы хотите, скажем, понять, делать вам фрезы из стали или из карбида, вам же нужно понимать свойства обоих сплавов? Вот и здесь также: чтобы выбрать инструмент и подход, нужно знать свойства каждого.
〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️
Критерий выбора — целесообразность.
〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️
Это означает, что у вас есть:
1️⃣ Цель (бизнес-задача)
2️⃣ Набор инструментов с известными свойствами
3️⃣ Выбор инструмента, соответствующего цели.
Из этого логически вытекает, что серебряной пули не существует. Одни популярные инструменты не лучше и не хуже сами по себе, в вакууме. Они либо целесообразны, либо нет.
В ближайших постах разберу популярные тезисы вида «X лучше Y» и покажу, в каких условиях выигрывает каждый вариант.
〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️ 〰️
P.S. Внимательные читатели наверняка помнят, что я писала отдельный пост о связи теории и практики, и,вероятно, запутала всех терминологией. Хотела бы уточнить, что в в этих двух постах я использовала термины по-разному: в прошлый раз под “практикой” я подразумевала написание кода, а сегодня — исключительно решение бизнес задач и в дальнейшем планирую придерживаться такой терминологии. Таким образом, если вы пишете туду лист на курсах -- то этот проект корректнее назвать теорией, потому что он не решает реальную бизнес потребность. Наверное, рано или поздно надо будет делать словарь, как в DDD.
Иногда ко мне приходят ребята, которые сталкиваются с проблемами в коде. Буквально: “не знаю, как сделать эту фичу”, “мой код не работает, но я не знаю, почему”. Это обычно называют практикой, но, на мой взгляд, это всё ещё теория — человек не освоил инструмент и не понимает, как получить нужный результат.
Однако бывает и по-другому: инструмент освоен, но используется нецелесообразно. Например, пишутся хрупкие или тривиальные юнит-тесты. Или все подряд функции в компонентах заворачиваются в useCallback. На мой взгляд, это ошибка применения теории на практике.
Чем вообще отличается теория от практики? Я считаю, теория включает в себя освоение принципов работы какого-нибудь инструмента или подхода. Вы изучаете его возможности, логику и принципы. А практика — это приложение этих знаний к реальному бизнес-процессу. Практика обязательно включает в себя выбор инструмента, а для того, чтобы выбрать, надо знать свойства разных подходов. Если у вас есть завод и вы хотите, скажем, понять, делать вам фрезы из стали или из карбида, вам же нужно понимать свойства обоих сплавов? Вот и здесь также: чтобы выбрать инструмент и подход, нужно знать свойства каждого.
Критерий выбора — целесообразность.
Это означает, что у вас есть:
Из этого логически вытекает, что серебряной пули не существует. Одни популярные инструменты не лучше и не хуже сами по себе, в вакууме. Они либо целесообразны, либо нет.
В ближайших постах разберу популярные тезисы вида «X лучше Y» и покажу, в каких условиях выигрывает каждый вариант.
P.S. Внимательные читатели наверняка помнят, что я писала отдельный пост о связи теории и практики, и,вероятно, запутала всех терминологией. Хотела бы уточнить, что в в этих двух постах я использовала термины по-разному: в прошлый раз под “практикой” я подразумевала написание кода, а сегодня — исключительно решение бизнес задач и в дальнейшем планирую придерживаться такой терминологии. Таким образом, если вы пишете туду лист на курсах -- то этот проект корректнее назвать теорией, потому что он не решает реальную бизнес потребность. Наверное, рано или поздно надо будет делать словарь, как в DDD.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍7🔥4🤮4💩3👎2
Женя Кучерявый написал гайд, как программировать без интернета. Эта статья вызывала у меня широкий спектр эмоций, начиная от смеха со слезами и заканчивая ностальгией по университетским годам, когда быстрый интернет в корпусе был скорее исключением, чем правилом (что, впрочем, нас не останавливало). Поскольку сегодня среда, мои чюваки, не могу лишить вас возможности насладиться гайдом!
https://kucheriavyi.ru/articles/coding-without-internet
P.S. Этот пост не предназначен для того, чтобы его восприняли слишком серьезно. Он здесь шутки ради.
https://kucheriavyi.ru/articles/coding-without-internet
P.S. Этот пост не предназначен для того, чтобы его восприняли слишком серьезно. Он здесь шутки ради.
1😁10❤5🔥5🤮5🤡4👎3👍1🌚1
Forwarded from zede code
Ситуация в найме ахтунг. Все и так все понимают.
Но я хочу сделать очередное напоминание. Когда где-то возникает большой спрос, то скаммеры всегда найдутся. Случаи нередкие и происходят уже со знакомыми с определенной частотой
Поэтому напоминание:
НИЧЕГО не ставьте на комп связанное с работой до последнего.
- ни для тестового задания!
- ни для интервью!
- ни для работы в первый день (если работаете неофициально)!
Ни приложения, ни установки "пакетов содержащих апи" НИ ЧЕ ГО.
Если вас вынуждают, то используйте:
- дев окружения: CodeSandbox, Stackblitz и тп
- если все же нужно со своего и хоть какое-то доверие есть, то используйте Dev Container или как самый минимум просто докер
- для выхода на новой работе тоже лучше соблюсти меры предосторожности, особенно если никаких реальных документов вы не заключали. Докер, в идеале отдельная система и отдельный пользователь, чтобы даже в случае проблемы вы не потеряли доступ к устройству и данным.
Также рассказали о новом виде скама с логином в iCloud. Со своего ПК не лезьте и не логиньтесь никуда. Если дают какой-то сервис, то лучше зайти с инкогнито + сгенерировать рандомный пароль (понимаю, что это базовая сейчас рекомендация по безопасности, но пароли многие все еще пишут руками по паттерну).
Но я хочу сделать очередное напоминание. Когда где-то возникает большой спрос, то скаммеры всегда найдутся. Случаи нередкие и происходят уже со знакомыми с определенной частотой
Поэтому напоминание:
НИЧЕГО не ставьте на комп связанное с работой до последнего.
- ни для тестового задания!
- ни для интервью!
- ни для работы в первый день (если работаете неофициально)!
Ни приложения, ни установки "пакетов содержащих апи" НИ ЧЕ ГО.
Если вас вынуждают, то используйте:
- дев окружения: CodeSandbox, Stackblitz и тп
- если все же нужно со своего и хоть какое-то доверие есть, то используйте Dev Container или как самый минимум просто докер
- для выхода на новой работе тоже лучше соблюсти меры предосторожности, особенно если никаких реальных документов вы не заключали. Докер, в идеале отдельная система и отдельный пользователь, чтобы даже в случае проблемы вы не потеряли доступ к устройству и данным.
Также рассказали о новом виде скама с логином в iCloud. Со своего ПК не лезьте и не логиньтесь никуда. Если дают какой-то сервис, то лучше зайти с инкогнито + сгенерировать рандомный пароль (понимаю, что это базовая сейчас рекомендация по безопасности, но пароли многие все еще пишут руками по паттерну).
Telegram
Стародубцев x IT-ХОЗЯЕВА
Очень важная инфа!
У нас в хозяевах @erikcodev рассказал неприятную историю, на которую они наткнулись с другом, ситуация максимально мерзкая, поэтому репощу чтобы вы не встряли.
Как работает скам: пишет типо hr и зовет на собес
в процессе говорит установить…
У нас в хозяевах @erikcodev рассказал неприятную историю, на которую они наткнулись с другом, ситуация максимально мерзкая, поэтому репощу чтобы вы не встряли.
Как работает скам: пишет типо hr и зовет на собес
в процессе говорит установить…
👍18❤8🔥3👎2🤮2💩2🤡1
Начала писать для вас стопку технических постов и пока все лежит в драфтах. Чтобы вы сильно не скучали, приношу вам плейлист стримов где мы с ребятами из @moscowqa обсуждаем #typescript. Я рассказываю про базовую и продвинутую типизацию, немного потрогали загадочный тип never, а также ковариантность и контрвариантность. Все вопросы можете написать прямо сюда, я постараюсь как можно детальнее на все ответить.
❤15🔥6👍4💩2👎1🤮1
А вы тоже иногда путаетесь в куче логов в консоли?
Чтобы облегчить себе жизнь, логи можно раскрашивать. Например, вот так:
Чтобы облегчить себе жизнь, логи можно раскрашивать. Например, вот так:
console.log('%cSESSION_START', 'background-color: red; color: white; padding: 10px 30px');
console.log('%c[User] Get data...', 'color: yellow');
console.log('%c[Products] Я точно не пропущу этот лог', 'font-size: 25px;');
console.log('%cSESSION_END', 'background-color: red; color: black; padding: 10px 30px');
❤20👍11🔥4🤮4🤡3💩2👎1
Императивное vs декларативное программирование
Это — две разные парадигмы программирования. Разберемся, чем они отличаются и когда удобно использовать первую, а когда вторую.
😊 Императивное программирование — это пошаговое описание алгоритма, который должен выполнить компьютер:
В этом нехитром фрагменте кода описан императивный алгоритм получения и вывода в консоль квадрата числа:
1️⃣ Возьми пользовательский ввод
2️⃣ Приведи к числу
3️⃣ Если число валидное, вычисли квадрат и выведи в лог.
😊 Декларативное программирование — это описание желаемого результата. Язык/фреймворк/движок должен сам определить, как его достичь. Например:
В этом фрагменте кода на React мы говорим фреймворку: я хочу получить форму с лейблом, инпутом и кнопкой и еще лог после отрисовки. Мы не указываем фреймворку, как и в какой последовательности он будет создавать html элементы, и даже не можем на это влиять. Мы описываем только то, что хотим получить на выходе.
⚠️ Важно понимать, что под капотом любое декларативное обязательно превращается в императивные инструкции. React код, например, превращается в императивный вызов
🔖 Императивное программирование удобно применять, когда у вас есть конкретный алгоритм или формула получения необходимого результата из входных параметров. Например, вы хотите рассчитать финальную цену продукта исходя из исходной цены и размера скидки. Здесь важно явно управлять логикой вычислений.
🔖 А вот декларативное программирование удобно, когда вы хотите описать что должно быть получено и переложить реализацию на другую систему — библиотеку, фреймворк, модуль кода. При этом следует участь, что разные реализации могут по-разному воспринять вашу декларацию по-разному в зависимости, например, от своей версии =)
Например, вы пишете декларативную разметку HTML (не является языком программирования). Императивный процесс отрисовки страницы переложен на другую программу — браузер. Поскольку HTML сам по себе не содержит инструкций, как рисовать страницу, HTML верстальщику приходится мириться с тем, что каждый браузер отображает страницу немного по-разному :)
🤩 🤩 🤩 🤩 🤩
Подведем итоги.
📌 Императивное программирование удобно, когда вы хотите получить жесткий контроль над процессом выполнения программы.
📌 Декларативное программирование удобно, когда вы хотите снизить сложность участка программы за счет передачи управления в другой модуль/библиотеку/фреймворк/программу.
Это — две разные парадигмы программирования. Разберемся, чем они отличаются и когда удобно использовать первую, а когда вторую.
const input = process.argv[2];
const x = Number(input);
if (!isNaN(x)) {
const y = x * x;
console.log(y);
}
В этом нехитром фрагменте кода описан императивный алгоритм получения и вывода в консоль квадрата числа:
const Panel = () => {
useEffect(() => console.log("Panel rendered"), []);
return (
<form action="/login.php" method="POST">
<label htmlFor="user">Username:</label>
<input type="text" id="user" name="username"/>
<button type="submit">Login</button>
</form>
)
}В этом фрагменте кода на React мы говорим фреймворку: я хочу получить форму с лейблом, инпутом и кнопкой и еще лог после отрисовки. Мы не указываем фреймворку, как и в какой последовательности он будет создавать html элементы, и даже не можем на это влиять. Мы описываем только то, что хотим получить на выходе.
React.createElement(…). Низкоуровнево компьютер вообще не умеет работать с декларативностью, под капотом всегда императивный процесс. Данные и операции сохраняются в виде последовательности битов в памяти, затем компьютер вычисляет (compute) результат операции и записывает данные в соответствующий регистр. Чтобы запустить вычислительный процесс, необходим набор конкретных инструкций. Именно поэтому декларативный код в конце концов превращается в императивный.Например, вы пишете декларативную разметку HTML (не является языком программирования). Императивный процесс отрисовки страницы переложен на другую программу — браузер. Поскольку HTML сам по себе не содержит инструкций, как рисовать страницу, HTML верстальщику приходится мириться с тем, что каждый браузер отображает страницу немного по-разному :)
Подведем итоги.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍6🤮5🔥3💩3👎2
Сегодня на консультации обсуждали резюме.
— Ну, вообще, в этом проекте у меня были вебсокеты, и еще я делал вот такую классную задачу.
— Но почему этого нет в резюме?
— Посмотрел резюме ребят, которые крутят опыт, многие пишут в резюме такого рода задачи и вебсокеты. Поэтому убрал, чтобы не думали, что я тоже накрутил.
Выводы из этой истории делайте сами.
— Ну, вообще, в этом проекте у меня были вебсокеты, и еще я делал вот такую классную задачу.
— Но почему этого нет в резюме?
— Посмотрел резюме ребят, которые крутят опыт, многие пишут в резюме такого рода задачи и вебсокеты. Поэтому убрал, чтобы не думали, что я тоже накрутил.
Выводы из этой истории делайте сами.
😢21🤡14💩5😁3🤮2👎1
Тип-пересечение (Intersection Types)
Тип-пересечение, как следует из названия, соответствует пересечению множеств, которые его образуют. Декларируется при помощи оператора &.
Это видно на картинке: у нас есть два множества, которые пересекаются, и их пересечение образует подмножество. Если два множества не пересекаются, мы все равно можем получить тип-пересечение, но оно будет пустым (never).
Важно понимать, что использование типа-пересечения в коде целесообразно тогда, когда составляющие его типы используются по отдельности. Например:
Типы в коде выше имеют смысл, когда в нашем проекте могут быть заведены товары без цены (например, только поступили на склад и цена еще не определена). Если же в нашей системе товары всегда содержат цены, то в этом случае подобная конструкция типов нам не нужна, целесообразнее использовать вот такой тип:
#typescript
Тип-пересечение, как следует из названия, соответствует пересечению множеств, которые его образуют. Декларируется при помощи оператора &.
type C = A & B
Это видно на картинке: у нас есть два множества, которые пересекаются, и их пересечение образует подмножество. Если два множества не пересекаются, мы все равно можем получить тип-пересечение, но оно будет пустым (never).
type X = string & number // never
Важно понимать, что использование типа-пересечения в коде целесообразно тогда, когда составляющие его типы используются по отдельности. Например:
type Product = { id: number; name: string; }
type Priced = { price: number; }
type PricedProduct = Product & PricedТипы в коде выше имеют смысл, когда в нашем проекте могут быть заведены товары без цены (например, только поступили на склад и цена еще не определена). Если же в нашей системе товары всегда содержат цены, то в этом случае подобная конструкция типов нам не нужна, целесообразнее использовать вот такой тип:
type Product = { id: number; name: string; price: number; }#typescript
👍18🔥8👏4🤮3😭2❤1👎1💩1
Один принцип, который делает разработчика middle+
Заголовок кликбейтный, но я собираюсь его оправдать.
В разработке самое главное понимание касается не того, как написать код, а того, как он должен работать. То есть — нужно понять, как должна работать система в целом и на корнер кейсах, и как она будет развиваться дальше. Чтобы разобраться в сложных кейсах, разработчики обычно смотрят, как сделано в других местах или ориентируются на лучшие практики, но самый правильный путь — понять, какова бизнес цель ваших действий, тогда сразу станет понятно, как следует сделать.
Приведу пример.
Недавно мой менти делал
На вопрос, зачем здесь string, он ответил, что где-то читал, что так лучше.
Давайте подумаем. Мы делаем компонент, который будут использовать другие разработчики нашей системы. В таком случае мы можем потребовать, чтобы строка конвертировалась в число до передачи в компонент. Таким образом мы делаем нашу границу более строгой. Что нам это дает?
1. В Input меньше кода => легче поддержка
2. Меньше потенциальных багов и возможностей ошибиться
3. Унификация кода
Получится, что мы должны затипизировать так:
Если развить эту мысль, то мы можем прийти к выводу, что ограничение длины должно быть обязательным. Например, для расчета ширины. И тогда получится
Следует ли из этого, что нам всегда следует типизировать пропс именно так? Нет. Можно легко найти сценарии, где решение моего менти будет более подходящим. Например, если вы делаете библиотеку для JavaScript-разработчиков. JS не подскажет корректный тип, и им слишком легко ошибиться — с нашей стороны логично будет их подстраховать.
📌 Таким образом, когда вы принимаете решения, ориентируйтесь на целесообразность и бизнес-потребность. Не бывает никакого “хорошего” и “плохого” кода в вакууме, бывает хорошее решение конкретной задачи и плохое.
Заголовок кликбейтный, но я собираюсь его оправдать.
В разработке самое главное понимание касается не того, как написать код, а того, как он должен работать. То есть — нужно понять, как должна работать система в целом и на корнер кейсах, и как она будет развиваться дальше. Чтобы разобраться в сложных кейсах, разработчики обычно смотрят, как сделано в других местах или ориентируются на лучшие практики, но самый правильный путь — понять, какова бизнес цель ваших действий, тогда сразу станет понятно, как следует сделать.
Приведу пример.
Недавно мой менти делал
Input с ограничением длины ввода и задал максимальную длину ввода пропсом max?: number | stringНа вопрос, зачем здесь string, он ответил, что где-то читал, что так лучше.
Давайте подумаем. Мы делаем компонент, который будут использовать другие разработчики нашей системы. В таком случае мы можем потребовать, чтобы строка конвертировалась в число до передачи в компонент. Таким образом мы делаем нашу границу более строгой. Что нам это дает?
1. В Input меньше кода => легче поддержка
2. Меньше потенциальных багов и возможностей ошибиться
3. Унификация кода
Получится, что мы должны затипизировать так:
max?: number. Если развить эту мысль, то мы можем прийти к выводу, что ограничение длины должно быть обязательным. Например, для расчета ширины. И тогда получится
max: number.Следует ли из этого, что нам всегда следует типизировать пропс именно так? Нет. Можно легко найти сценарии, где решение моего менти будет более подходящим. Например, если вы делаете библиотеку для JavaScript-разработчиков. JS не подскажет корректный тип, и им слишком легко ошибиться — с нашей стороны логично будет их подстраховать.
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤15👍12🔥5👎4🥱4🤮3💩2🤔1
Как я на go в продакшн писала
История была год назад. Нашей команде достался проект с жестким дедлайном. Я уже заканчивала фронтенд, а бекендеры все сдвигали свои сроки и, в конце концов, признались, что не успевают — слишком много задач помимо этого проекта. Тогда я сказала, что я все сделаю сама, только дайте доступ. Лид удивился и возразил мне тем, что в моем резюме написано “frontend-разработчик”. Как вы, наверное, помните, мне в целом не очень импонируют все эти надуманные ограничения вроде “фронтендер не может закрывать таски на бекенде”, тем более я не на лиспе писать собралась, а на еще одном c-like языке. Доступ мне дали. Бекенд оказался на go.
В выходные я потыкала курс по базовому синтаксису go на хекслете и почитала книгу, которую мне посоветовала подруга. Работа над проектом началась непросто: я никак не могла скачать корпоративные модули, несмотря на (вроде бы) правильную настройку конфигов и переменных окружения. Пришлось мучать лида (кажется, он был не очень доволен). Мы провозились пару часов, и в конце концов оно как-то заработало (я точно не поняла, что именно помогло с этой проблемой).
После этого меня ждал новый сюрприз: абсолютно пустой readme и огромный makefile с богатым разнообразием команд. Я решила не гадать на кофейной гуще и спросить у лида, как стартануть проект. А никак, — ответил лид, — он локально не запускается, в CI можно стенд собрать. На этом моменте я на все плюнула и пошла в спортзал тягать железки.
День два. Я решила, что даже если я не могу проверить свой код, написать-то я его все равно могу, логично? Начала читать таску и обнаружила, что аналитик любезно все описал, включая таблицы БД, которые нужно добавить/изменить, и какие поля добавить в эндпойнты. Осталось всего лишь перевести это все в код, что, как вы понимаете, изян задача.
Еще несколько дней я убила на миграции и тесты. Стало понятно, почему ребята не парились из-за невозможности локального запуска — тесты и CI/CD проверки хорошо покрывали кодовую базу, и у меня несколько дней реально ушло на то, чтобы добиться прохождения тестов и пайплайна. Попутно я разобралась, как это правильно делать.
По итогу выяснилось, что я использовала неправильные строковые константы для сообщений об ошибках и накосячила в одном месте из-за плохого знания домена (надо было фильтровать сущности по определенному полю, кто ж знал). Но в целом нормально.
Ну а потом я перешла в другую команду и моя славная карьера go-разработчика закончилась. В новой команде я уже больше полугода пишу на Svelte. Позже расскажу, с какими сложностями я столкнулась после того, как перешла с React на Svelte (спойлер: ни с какими, две недели немножко неудобно, а потом привыкаешь).
История была год назад. Нашей команде достался проект с жестким дедлайном. Я уже заканчивала фронтенд, а бекендеры все сдвигали свои сроки и, в конце концов, признались, что не успевают — слишком много задач помимо этого проекта. Тогда я сказала, что я все сделаю сама, только дайте доступ. Лид удивился и возразил мне тем, что в моем резюме написано “frontend-разработчик”. Как вы, наверное, помните, мне в целом не очень импонируют все эти надуманные ограничения вроде “фронтендер не может закрывать таски на бекенде”, тем более я не на лиспе писать собралась, а на еще одном c-like языке. Доступ мне дали. Бекенд оказался на go.
В выходные я потыкала курс по базовому синтаксису go на хекслете и почитала книгу, которую мне посоветовала подруга. Работа над проектом началась непросто: я никак не могла скачать корпоративные модули, несмотря на (вроде бы) правильную настройку конфигов и переменных окружения. Пришлось мучать лида (кажется, он был не очень доволен). Мы провозились пару часов, и в конце концов оно как-то заработало (я точно не поняла, что именно помогло с этой проблемой).
После этого меня ждал новый сюрприз: абсолютно пустой readme и огромный makefile с богатым разнообразием команд. Я решила не гадать на кофейной гуще и спросить у лида, как стартануть проект. А никак, — ответил лид, — он локально не запускается, в CI можно стенд собрать. На этом моменте я на все плюнула и пошла в спортзал тягать железки.
День два. Я решила, что даже если я не могу проверить свой код, написать-то я его все равно могу, логично? Начала читать таску и обнаружила, что аналитик любезно все описал, включая таблицы БД, которые нужно добавить/изменить, и какие поля добавить в эндпойнты. Осталось всего лишь перевести это все в код, что, как вы понимаете, изян задача.
Еще несколько дней я убила на миграции и тесты. Стало понятно, почему ребята не парились из-за невозможности локального запуска — тесты и CI/CD проверки хорошо покрывали кодовую базу, и у меня несколько дней реально ушло на то, чтобы добиться прохождения тестов и пайплайна. Попутно я разобралась, как это правильно делать.
По итогу выяснилось, что я использовала неправильные строковые константы для сообщений об ошибках и накосячила в одном месте из-за плохого знания домена (надо было фильтровать сущности по определенному полю, кто ж знал). Но в целом нормально.
Ну а потом я перешла в другую команду и моя славная карьера go-разработчика закончилась. В новой команде я уже больше полугода пишу на Svelte. Позже расскажу, с какими сложностями я столкнулась после того, как перешла с React на Svelte (спойлер: ни с какими, две недели немножко неудобно, а потом привыкаешь).
3❤29👏8😁8🤣3🔥2🤮1👨💻1
Помните, я писала о том, как делать сопроводительные на hh? В общем, можно больше не тратить на это время, смысл сопроводительных окончательно утрачен.
😁5🤡4🤣1
Forwarded from HR-эксперт
Кхэ-Кхэ ру выкатил обновление для соискателей и представил новую функцию "AI-генерация сопроводительного письма"🤦🏻♂️
Вот теперь точно AI будет отбирать AI... а работать-то кто потом будет?🫣
Вот теперь точно AI будет отбирать AI... а работать-то кто потом будет?🫣
🥴13🤣2👀2
Forwarded from SOERDEV | клуб инженеров-программистов
Дублирование на уровне кода - один из основных источников технического долга. Говоришь себе "ну сейчас быстро сделаю копи-паст, а потом на этапе рефакторинга раскидаю как надо".
Обычно этап рефакторинга так и не наступает, поэтому в коде остается несколько источников правды, которые в будущем создают проблемы.
Хуже всего то, что спустя время ты успешно забываешь, какие правки нужно было сделать, дополнительно успеваешь накидать на старый код еще пяток другой патчей, которые усложняют рефакторинг и тем самым закрепляют плохие практики, превращая кодовую базу в дремучее легаси.
Легаси неизбежно, поэтому хорошего кода в мире очень мало, а плохого сколько угодно много. Получается, что с большой вероятностью код, который был использован при обучении LLM, был не самого лучшего качества, а значит, это мы с вами, ленясь выполнять своевременный рефакторинг, научили ИИ "плохому".
Может быть, это и к лучшему, потому что мы с вами еще можем научиться красиво и грамотно писать код, проектировать и продумывать наши системы, а ИИ будет продолжать плодить легаси.
Воистину, лень оказалась лучшей инвестицией, которая поможет нам конкурировать с ИИ.
Обычно этап рефакторинга так и не наступает, поэтому в коде остается несколько источников правды, которые в будущем создают проблемы.
Хуже всего то, что спустя время ты успешно забываешь, какие правки нужно было сделать, дополнительно успеваешь накидать на старый код еще пяток другой патчей, которые усложняют рефакторинг и тем самым закрепляют плохие практики, превращая кодовую базу в дремучее легаси.
Легаси неизбежно, поэтому хорошего кода в мире очень мало, а плохого сколько угодно много. Получается, что с большой вероятностью код, который был использован при обучении LLM, был не самого лучшего качества, а значит, это мы с вами, ленясь выполнять своевременный рефакторинг, научили ИИ "плохому".
Может быть, это и к лучшему, потому что мы с вами еще можем научиться красиво и грамотно писать код, проектировать и продумывать наши системы, а ИИ будет продолжать плодить легаси.
Воистину, лень оказалась лучшей инвестицией, которая поможет нам конкурировать с ИИ.
👏4🔥1😁1
Составила чек-лист подготовки к собеседованию на позицию frontend-разработчика. Забирайте себе и шерьте друзьям🫶
🔘 HTML & CSS
- Семантическая верстка
- Box Model
- Специфичность селекторов
- Как отцентрировать div
- Position, display, box-sizing
- Opacity, visibility
- Браузерный рендеринг: layout /paint /composition
- Flexbox, grid
🔘 JavaScript
- Типы данных
- Виды функций (arrow, function declaration, function expression)
- Event loop
- Промисы, async/await
- Замыкания, лексические окружения
- This
- Область видимости, hoisting
- Сборщик мусора
- Утечки памяти, способы их обнаружения и устранения
🔘 Браузеры
- Всплытие и перехват событий
-
- Хранилища: localStorage, sessionStorage, IndexDB, cookie
- Что происходит, когда вы вводите адрес сайта и нажимаете Enter
🔘 HTTP
- HTTP 1.1 vs HTTP 2.0
- Вебсокеты, SSE
- Методы HTTP
- Rest API
- Статусы HTTP ответов
- CORS
🔘 Безопасность
- XSS
- CSRF
🔘 React
- Архитектура Fiber, Virtual DOM, Reconciliation
- Ключи (
- Мемоизация
- useLayoutEffect, useEffect
- useRef
- Почему компонент рендерится
🔘 TypeScript
- Чем отличается type от interface
- Утилитарные типы (перечислить несколько)
- Type guards
🔘 Git
- Merge vs rebase
- Git flow
- Trunk bases development
🔘 Архитектура
- Микрофронтенды, module federation
- Стейт менеджеры
- FSD
#чеклист #собеседования
- Семантическая верстка
- Box Model
- Специфичность селекторов
- Как отцентрировать div
- Position, display, box-sizing
- Opacity, visibility
- Браузерный рендеринг: layout /paint /composition
- Flexbox, grid
- Типы данных
- Виды функций (arrow, function declaration, function expression)
- Event loop
- Промисы, async/await
- Замыкания, лексические окружения
- This
- Область видимости, hoisting
- Сборщик мусора
- Утечки памяти, способы их обнаружения и устранения
- Всплытие и перехват событий
-
preventDefault, stopPropagation- Хранилища: localStorage, sessionStorage, IndexDB, cookie
- Что происходит, когда вы вводите адрес сайта и нажимаете Enter
- HTTP 1.1 vs HTTP 2.0
- Вебсокеты, SSE
- Методы HTTP
- Rest API
- Статусы HTTP ответов
- CORS
- XSS
- CSRF
- Архитектура Fiber, Virtual DOM, Reconciliation
- Ключи (
key)- Мемоизация
- useLayoutEffect, useEffect
- useRef
- Почему компонент рендерится
- Чем отличается type от interface
- Утилитарные типы (перечислить несколько)
- Type guards
- Merge vs rebase
- Git flow
- Trunk bases development
- Микрофронтенды, module federation
- Стейт менеджеры
- FSD
#чеклист #собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
❤19👍9🔥6🤡2❤🔥1👎1
Вот такую вакансию увидела на канале Леси и хочу немного прокомментировать.
За DE не скажу, буду говорить о моей профессиональной сфере — веб-разработке.
“Нужен человек полностью соответствующий нашим ожиданиям, а НЕ который учится на ходу.” — довольно популярная мечта у работодателей. Многих раздражает, что новый сотрудник какое-то время онбордится в проект и разбирается во всех его нюансах, и только потом начинает предлагать какие-то здравые идеи. Отчасти пожелания к годам опыта связаны с этим фактором: работодателям кажется, что если придет опытный специалист, он телепатически разберется в нюансах проекта и вытащит его из кризиса прямзавтра (или ещевчера). По этой же причине не очень любят нанимать джунов: “нужен сотрудник, который сразу приносит пользу, а не которого надо обучать” (с).
К сожалению, это несбыточные мечты. Основная сложность коммерческой разработки не заключается в самом программировании. Большую часть времени на новом месте занимает изучение проекта: его архитектуры, бизнес-логики, ограничений, процессов и исторически сложившихся решений.
Самое сложное в коммерческой разработке — это разобраться в нюансах конкретного проекта. Написать код может кто угодно при условии, что известно, как он должен работать. Проблема в том, что в коммерческой разработке никогда не известно, как именно код должен работать и какие ограничения необходимы. Это зависит от конкретного проекта, то есть от особенностей бизнеса, которые определяются текущим законодательством, экономической ситуацией, решением руководства и отношениями между отделами. Разобраться в этом и есть самое сложное, с чем сталкивается рядовой разработчик, приходя на новое место. Именно поэтому, кстати, для разработчиков имеют такое большое значение документация к проекту и читаемость кода.
Неприятная для работодателей новость состоит в том, что при смене проекта все эти знания приходится осваивать заново.Таким образом, вы всегда нанимаете джуна, даже если у него 10 лет опыта. Возможно, для некоторых нанимающих это новость. Придется с этим смириться.
Во фронтенде человек, прошедший обучение по современных технологиям (HTML, JavaScript, TypeScript, какой-нибудь фреймворк) с хорошим знанием CS (профильной вышкой) и математическим мышлением (умением выделять абстракции и оперировать ими) становится полноценным бойцом (то есть миддлом) спустя 3-6 месяцев работы. Что касается ребят, которым программирование дается сложнее (ну, скажем условно, “гуманитариев”) и у которых нет профильной вышки, то такой человек станет полноценным миддлом спустя год, максимум полтора года работы. Я видела десятки таких примеров. И не только я: до повсеместной моды на накрутку опыта большинство компаний искали фронтендеров миддлов с опытом от 1 года, потому что большинству моих коллег известно, что после года опыта 99% фронтендеров становятся полноценными бойцами, даже если у них нет вышки и “математического склада ума”.
Таким образом, для того, чтобы быстро свитчиться между технологиями и проектами, вам не нужно много опыта. Надеюсь, я смогла проиллюстрировать выше, что в коммерческом программировании нет ничего сложного и набивать “опыт” в этом — это то же самое, что набивать опыт в ходьбе по улице. Мы же не говорим, что 30-летние люди лучше ходят по улице, чем 20-летние? Это абсурд. И те и другие вроде не падают :)
Для того, чтобы быстро свитчиться между технологиями и проектами, вам нужна база CS (алгоритмы и структуры данных, паттерны проектирования, операционные системы, сети) и архитектурные навыки. Это научит вас быстро и точно соображать, а это в нашем деле — самое главное.
За DE не скажу, буду говорить о моей профессиональной сфере — веб-разработке.
“Нужен человек полностью соответствующий нашим ожиданиям, а НЕ который учится на ходу.” — довольно популярная мечта у работодателей. Многих раздражает, что новый сотрудник какое-то время онбордится в проект и разбирается во всех его нюансах, и только потом начинает предлагать какие-то здравые идеи. Отчасти пожелания к годам опыта связаны с этим фактором: работодателям кажется, что если придет опытный специалист, он телепатически разберется в нюансах проекта и вытащит его из кризиса прямзавтра (или ещевчера). По этой же причине не очень любят нанимать джунов: “нужен сотрудник, который сразу приносит пользу, а не которого надо обучать” (с).
К сожалению, это несбыточные мечты. Основная сложность коммерческой разработки не заключается в самом программировании. Большую часть времени на новом месте занимает изучение проекта: его архитектуры, бизнес-логики, ограничений, процессов и исторически сложившихся решений.
Самое сложное в коммерческой разработке — это разобраться в нюансах конкретного проекта. Написать код может кто угодно при условии, что известно, как он должен работать. Проблема в том, что в коммерческой разработке никогда не известно, как именно код должен работать и какие ограничения необходимы. Это зависит от конкретного проекта, то есть от особенностей бизнеса, которые определяются текущим законодательством, экономической ситуацией, решением руководства и отношениями между отделами. Разобраться в этом и есть самое сложное, с чем сталкивается рядовой разработчик, приходя на новое место. Именно поэтому, кстати, для разработчиков имеют такое большое значение документация к проекту и читаемость кода.
Неприятная для работодателей новость состоит в том, что при смене проекта все эти знания приходится осваивать заново.Таким образом, вы всегда нанимаете джуна, даже если у него 10 лет опыта. Возможно, для некоторых нанимающих это новость. Придется с этим смириться.
Во фронтенде человек, прошедший обучение по современных технологиям (HTML, JavaScript, TypeScript, какой-нибудь фреймворк) с хорошим знанием CS (профильной вышкой) и математическим мышлением (умением выделять абстракции и оперировать ими) становится полноценным бойцом (то есть миддлом) спустя 3-6 месяцев работы. Что касается ребят, которым программирование дается сложнее (ну, скажем условно, “гуманитариев”) и у которых нет профильной вышки, то такой человек станет полноценным миддлом спустя год, максимум полтора года работы. Я видела десятки таких примеров. И не только я: до повсеместной моды на накрутку опыта большинство компаний искали фронтендеров миддлов с опытом от 1 года, потому что большинству моих коллег известно, что после года опыта 99% фронтендеров становятся полноценными бойцами, даже если у них нет вышки и “математического склада ума”.
Таким образом, для того, чтобы быстро свитчиться между технологиями и проектами, вам не нужно много опыта. Надеюсь, я смогла проиллюстрировать выше, что в коммерческом программировании нет ничего сложного и набивать “опыт” в этом — это то же самое, что набивать опыт в ходьбе по улице. Мы же не говорим, что 30-летние люди лучше ходят по улице, чем 20-летние? Это абсурд. И те и другие вроде не падают :)
Для того, чтобы быстро свитчиться между технологиями и проектами, вам нужна база CS (алгоритмы и структуры данных, паттерны проектирования, операционные системы, сети) и архитектурные навыки. Это научит вас быстро и точно соображать, а это в нашем деле — самое главное.
1❤16👍10🔥4👎1🤬1💩1
Forwarded from Набока орёт в борщ | 🌋
🎯 КОГО ИЩЕМ:
1. Data Engineer с опытом работы с инфраструктурой AI на AWS и GCP.
2. Нужны «рабочие руки», а НЕ технический менеджер.
3. Нужен человек полностью соответствующий нашим ожиданиям, а НЕ который учится на ходу.
4. Со знанием разговорного английского языка (English-speaking team).
⛔️ КТО НЕ ПОДОЙДЁТ:
1. Кандидаты с преобладающим или последним опытом в роли технических менеджеров: Team Lead, CTO и т.п. – это нерелевантный данной позиции опыт работы. Мы ищем «рабочие руки», а НЕ технического менеджера.
2. Кандидаты с преобладающим или последним опытом работы на фрилансе.
3. Кандидаты с низким уровнем разговорного английского языка.
🏅 ТРЕБОВАНИЯ:
1. Опыт работы 6+ лет в роли Data Engineer.
2. Опыт работы 2+ года с AI-инфраструктурой на GCP и AWS.
3. Опыт работы 4+ года с ML.
4. Опыт работы 3+ года с GCP Vertex AI (GEAP).
5. Опыт работы 2+ года с Amazon SageMaker.
6. Опыт работы 5+ лет с Kubernetes.
7. Опыт работы 8+ лет с Python.
8. РАЗГОВОРНЫЙ английский язык на уровне C1+.
🧑🏽💻 ОСНОВНАЯ ЗАДАЧА:
Обеспечить бесшовные интеграции (сотни интеграций) в сфере AI, их надёжность и быстродействие.
⭐️ МЫ ПРЕДЛАГАЕМ:
1. Конкурентоспособную заработную плату.
2. Полностью remote.
3. Гибкий график работы: одна команда в Казахстане работает по UTC+5, вторая команда в UK – по UTC+1. Взаимодействие с обеими командами.
4. Работа в продуктовой компании.
🔎 ЭТАПЫ ОТБОРА ВКЛЮЧАЮТ:
1. Real-time coding сессия с расшариванием экрана.
2. Due diligence.
Наше любимое, а еще гибкий график подразумевает 12-часовой рабочий день для взаимодействия с обеими командами ☺️
Чтобы научиться видеть ред флаги еще на этапе прочтения вакансии — переходите сюда @nabokapro_bot
🤣4😭2❤1
Infer
Infer для многих конструкция поистине инфернальная.
Infer объявляет переменную типа, в которую тип будет выведен позже. Чтобы понять, как работать с infer, нужно учесть, что он выводит тип исходя из соответствия шаблону. Поэтому в большинстве случаев нужно написать шаблон, куда вы подставите infer вместо интересующего вас типа.
Например, вы хотите вывести тип результата функции. Для примера возьмем функцию без аргументов, чтобы они нас не путали, они нам сейчас не нужны. Такой тип может быть описан вот так:1️⃣ ). Вот этот U нам и нужен и как результат type alias (2️⃣ ).
Далее наш шаблон, который мы получили на шаге1️⃣ , мы подставляем после extends, а в true кейс подставляем желаемый результат, который мы получили на шаге 2️⃣ . Получается
Надо что-то записать в false-кейс, это будет тип, который мы получаем, если параметр типа не будет соответствовать нашему условию. Нам не сильно интересен этот тип, нам интересны только те, которые соответствуют нашему условию. Поэтому здесь используем never. Итого получаем
#typescript
Infer для многих конструкция поистине инфернальная.
Infer объявляет переменную типа, в которую тип будет выведен позже. Чтобы понять, как работать с infer, нужно учесть, что он выводит тип исходя из соответствия шаблону. Поэтому в большинстве случаев нужно написать шаблон, куда вы подставите infer вместо интересующего вас типа.
Например, вы хотите вывести тип результата функции. Для примера возьмем функцию без аргументов, чтобы они нас не путали, они нам сейчас не нужны. Такой тип может быть описан вот так:
() => number. Или так: () => { x: string }. Мы не знаем, что вернется из функции, и нас именно это как раз и интересует. Поэтому получается () => infer U (Далее наш шаблон, который мы получили на шаге
type ReturnType<T> = T extends () => infer R ? R :
Надо что-то записать в false-кейс, это будет тип, который мы получаем, если параметр типа не будет соответствовать нашему условию. Нам не сильно интересен этот тип, нам интересны только те, которые соответствуют нашему условию. Поэтому здесь используем never. Итого получаем
type ReturnType<T> = T extends () => infer R ? R : never;
#typescript
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍2🔥2
И снова Infer
По вашим просьбам сегодня разберем еще пример с infer. Я покажу, какие умозаключения я делаю, когда описываю типы при помощи этого ключевого слова.
▶️ Задача: вывести тип первого аргумента функции.
Заметим, что в функции может быть сколько угодно аргументов, но нас интересует только первый. Поэтому имеет смысл разбить аргументы на две группы: первый и все остальные, которые нас не интересуют. В JavaScript есть очень удобный оператор rest, который позволяет нам собрать все неинтересные нам аргументы в кучу.
Давайте для примера попробуем описать тип Func, которым можно описать все наши функции из примера выше, и пока будем использовать везде any. Наша задача — просто побить сигнатуру на логические группы. В параметрах выделим сначала первый x (он-то нам и интересен), затем все остальные аргументы соберем в параметр rest. Вернем any — мы договорились пока что везде использовать any. У меня получилось так:
Теперь, глядя на этот шаблон, легко поставить infer туда, куда нам интересно. Псевдокодом получится вот так:
Осталось написать наш тип-дженерик по общему алгоритму: проверяем, соответствует ли параметр типа нашему шаблону, если да, возвращаем интересный нам U, иначе never.
#typescript
🔜 Канал в MAX
По вашим просьбам сегодня разберем еще пример с infer. Я покажу, какие умозаключения я делаю, когда описываю типы при помощи этого ключевого слова.
const logUser = (user: 'user' | 'admin', lastLogin: Date) => {...} // 'user' | 'admin';
const repeatChat = (count: number, char: string) => {...} // number
const getStringLength = (str: string) => {...} // stringЗаметим, что в функции может быть сколько угодно аргументов, но нас интересует только первый. Поэтому имеет смысл разбить аргументы на две группы: первый и все остальные, которые нас не интересуют. В JavaScript есть очень удобный оператор rest, который позволяет нам собрать все неинтересные нам аргументы в кучу.
Давайте для примера попробуем описать тип Func, которым можно описать все наши функции из примера выше, и пока будем использовать везде any. Наша задача — просто побить сигнатуру на логические группы. В параметрах выделим сначала первый x (он-то нам и интересен), затем все остальные аргументы соберем в параметр rest. Вернем any — мы договорились пока что везде использовать any. У меня получилось так:
type Func = (x: any, ...rest: any) => any;
Теперь, глядя на этот шаблон, легко поставить infer туда, куда нам интересно. Псевдокодом получится вот так:
type Func = (x: infer U, ...rest: any) => any;
Осталось написать наш тип-дженерик по общему алгоритму: проверяем, соответствует ли параметр типа нашему шаблону, если да, возвращаем интересный нам U, иначе never.
type FirstArg<T> =
T extends (x: infer U, ...args: any) => any
? U
: never;
#typescript
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥4👍3😁1
Я уже писала про то, как частые запросы на сервер (например, при вводе поисковой строки) могут вызывать race conditions. Однако мы тогда не говорили о том, что сигнал аборт контроллера может сработать после успешного запроса, но до установки данных. Это возможно за счет того, что движок вызывает асинхронные функции не сразу, а только после завершения некоторого события (например, получения ответа от сервера).
Поэтому, когда вы пишете await или then, помните про то, что между кодом до await и после может вклиниться какой-то другой код, который может заабортить ваш сигнал 🙂 Например, в примере ниже до
await(loadAsyncWork(data)); наш сигнал, который мы получаем снаружи, может быть еще не aborted, а вот после await(loadAsyncWork(data)); — уже да:
async function loadData({signal, setData}) {
const res = await fetch(`/api/data?query=${query}`, { signal }) // здесь сигнал еще не aborted
const data = await res.json();
await loadAsyncWork(data); // операция выполняется долго, движок в это время может выполнять другие функции
setData(data) // а вот здесь уже aborted
}
Если для нас важна актуальность данных (мы всегда хотим отображать только самые актуальные данные с сервера), то в этом случае мы должны дополнительно проверить сигнал перед вставкой:
async function loadData({signal, setData}) {
const res = await fetch(`/api/data?query=${query}`, { signal })
const data = await res.json();
await loadAsyncWork(data);
if (!signal.aborted) {
setData(data)
}
}
#raceconditions
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Кодовая база
🏎Что такое race conditions в React хуках?
Хуки эффектов, в которых есть запросы с последующей установкой ответа в state могут приводить к race conditions. Race conditions возникает, когда хук выполняется слишком часто, и поскольку очередность ответов от…
Хуки эффектов, в которых есть запросы с последующей установкой ответа в state могут приводить к race conditions. Race conditions возникает, когда хук выполняется слишком часто, и поскольку очередность ответов от…
❤6👍6🔥4
Ситуации, когда разработчики с хорошим опытом и сильными навыками не проходят собеседование, встречаются гораздо чаще, чем кажется. Обычно проблема заключается в коммуникации.
Кандидаты почему-то думают, что на собеседовании они должны поразить интервьюера своими энциклопедическими знаниями и феноменальной памятью. Из-за этого, забыв какую-нибудь мелочь, вроде порядка аргументов у стандартной функции или точное название метода, начинают паниковать и надолго застревают. В итоге получают фидбек “застрял на мелочи и не смог продвинуться дальше”.
В большинстве случаев интервьюер оценивает совсем не это. Ему важно увидеть, что вы умеете программировать, рассуждать и решать технические задачи. Ниже опишу некоторые сложности, с которыми часто сталкиваются кандидаты:
Проговорите условие устно: “я правильно понимаю, что в этой задаче требуется сделать текстовый инпут, получать данные с сервера по поисковой строке и отображать их в списке ниже”? Вы синхронизируетесь с интервьюером, поймете лучше, чего от вас хотят, а интервьюер, в свою очередь, поймет, что вы смогли понять задание и это ваш плюсик в карму 🙂
Спросите у интервьюера! Прямо говорите: блин, есть метод, который позволяет свернуть массив в одно значение-аккумулятор, не помню, как называется… Интервьюер подскажет, а если не подскажет, смело просите погуглить. И гуглите. Только экран шарьте, чтобы интервьюер понимал, что вы делаете.
Например, вы привыкли, что запросы на сервер вынесены в хук, а тут обычная функция. Или наоборот. Решение: просто скажите интервьюеру, что вас смущает! Вроде: хм, я вижу, тут запрос сделан функцией, а я обычно использую хук, сейчас попробую понять, как использовать функцию, а не хук… Так интервьюер по крайней мере поймет, что у вас происходит в данный момент, с какой сложностью вы столкнулись и на чем застряли.
Интервьюеры часто реджектят не слабых, а непонятных кандидатов: пришел, потупил, помолчал, на чем-то застрял, ничего не сделал, хз что за чел. Или пришел, помолчал, все решил, но ничего не объяснил, мутный какой-то, наверное списал все. Что происходит? Что именно не получается? Он вообще знает или нет? Затащит продакшн таски? Может да, а может нет. Непонятно. Ваша задача — быть ПОНЯТНЫМ на собеседовании. Интервьюер должен понять, что вы делаете и как вы делаете. Для этого надо коммуницировать и быть искренним.
Всем удачных собеседований!
#собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
❤18🔥4👍3