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👍10🔥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❤17👍11🔥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🔥5
Ситуации, когда разработчики с хорошим опытом и сильными навыками не проходят собеседование, встречаются гораздо чаще, чем кажется. Обычно проблема заключается в коммуникации.
Кандидаты почему-то думают, что на собеседовании они должны поразить интервьюера своими энциклопедическими знаниями и феноменальной памятью. Из-за этого, забыв какую-нибудь мелочь, вроде порядка аргументов у стандартной функции или точное название метода, начинают паниковать и надолго застревают. В итоге получают фидбек “застрял на мелочи и не смог продвинуться дальше”.
В большинстве случаев интервьюер оценивает совсем не это. Ему важно увидеть, что вы умеете программировать, рассуждать и решать технические задачи. Ниже опишу некоторые сложности, с которыми часто сталкиваются кандидаты:
Проговорите условие устно: “я правильно понимаю, что в этой задаче требуется сделать текстовый инпут, получать данные с сервера по поисковой строке и отображать их в списке ниже”? Вы синхронизируетесь с интервьюером, поймете лучше, чего от вас хотят, а интервьюер, в свою очередь, поймет, что вы смогли понять задание и это ваш плюсик в карму 🙂
Спросите у интервьюера! Прямо говорите: блин, есть метод, который позволяет свернуть массив в одно значение-аккумулятор, не помню, как называется… Интервьюер подскажет, а если не подскажет, смело просите погуглить. И гуглите. Только экран шарьте, чтобы интервьюер понимал, что вы делаете.
Например, вы привыкли, что запросы на сервер вынесены в хук, а тут обычная функция. Или наоборот. Решение: просто скажите интервьюеру, что вас смущает! Вроде: хм, я вижу, тут запрос сделан функцией, а я обычно использую хук, сейчас попробую понять, как использовать функцию, а не хук… Так интервьюер по крайней мере поймет, что у вас происходит в данный момент, с какой сложностью вы столкнулись и на чем застряли.
Интервьюеры часто реджектят не слабых, а непонятных кандидатов: пришел, потупил, помолчал, на чем-то застрял, ничего не сделал, хз что за чел. Или пришел, помолчал, все решил, но ничего не объяснил, мутный какой-то, наверное списал все. Что происходит? Что именно не получается? Он вообще знает или нет? Затащит продакшн таски? Может да, а может нет. Непонятно. Ваша задача — быть ПОНЯТНЫМ на собеседовании. Интервьюер должен понять, что вы делаете и как вы делаете. Для этого надо коммуницировать и быть искренним.
Всем удачных собеседований!
#собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
❤19👍4🔥4
Мои давние друзья знают, что к разговорам про софт скиллы я отношусь скептически. Причина в размытости этого понятия (никто толком не знает, что такое эти самые софт скиллы и что в них входит) и в отсутствии понятной шкалы, которой их можно измерить. С хард скиллами все проще: я могу пройти тест по JavaScript и получить, скажем, 7 из 10, а с софт скиллами так не получится.
Лично я считаю, что почти половина из того, что почему-то называют “софт скиллами”, относится к воспитанию человека, а еще почти половина — к характеру. Например, ответственность. Не знаю, почему ответственность вдруг стала “навыком”, в мои времена ответственность прививали родители и она была частью взросления и воспитания. Или, скажем, “нетоксичность”. Люди “токсично” реагируют на те или иные раздражители и, на мой взгляд, это зона компетенции психологов, но никак не “навык”, который можно развивать.
Но есть “софт скиллы”, которые я считаю полезными. Например, навык презентовать свои мысли и идеи.
Проект — результат работы команды. Чтобы делать проект командой, необходимо, чтобы все понимали, что мы, собственно, делаем. Поэтому, если возникает какая-то идея, ее надо объяснить коллегам. Давайте посмотрим на этот мягкий навык повнимательнее.
Предположим, я придумала архитектуру фронтенд приложения. Я решила, что у меня будет слой данных, который будет синхронизироваться с апи, слой UI, библиотека переиспользуемых компонентов, шина и сервисы, которые обновляют данные. Прекрасно. Теперь мне надо донести свои идеи до коллег, чтобы они поняли, за что отвечает шина, за что отвечают сервисы, какой код должен быть в каждом месте и что именно из этого надо использовать в разных местах UI.
Чтобы донести свою идею, мне необходимо:
Во-первых, определить существенные признаки придуманных мной элементов системы. То есть, с точки зрения формальной логики — выделить понятия.
Во-вторых, определить связи между элементами системы.
Поскольку определение понятия — процесс трудоемкий, проще всего этого сделать, опираясь на плечи атлантов, то есть предшественников. С одной стороны, мы собираем все свои мысли в кучу и формируем понятие, а с другой стороны — само понятие позволяет нам формировать наши идеи, отшлифовать их, так как понятие уже содержит идеи. Процесс обоюдный. Сравните: “нам нужен компонент, через который все части системы смогут обмениваться информацией и получать сообщения, чтобы как-то на них отреагировать, и это будет общий компонент, ну потому что эээээ…. я так вижу” и “нам нужна шина”. Второй тезис гораздо более емкий, он быстрее и точнее позволяет доносить свои идеи до коллег и окружения. Если первое объяснение более расплывчатое и позволяет каждому члену команды понять его в силу своих желаний и возможностей, то второе — гораздо более точное.
Однако для того, чтобы пользоваться идеями предшественников как фундаментом своих собственных идей, необходимо эти идеи предшественников знать. Получается, что для того, чтобы объяснить коллеге Васе, как работает код в твоем пулл реквесте, полезно читать книги о разработке, особенно известных авторов (потому что их идеи известны широкому кругу лиц), а это в нашем комьюнити уже считается хардами.
Вот так и получается, что этот софт скилл — это на самом деле хард скилл. Если у вас сильные харды, то вы легко отделяете одни паттерны и одни понятия от других и сможете ясно и четко объяснить свои идеи коллегам. А если харды слабые, то вы сами видите эту картину как через мутное стеклышко и никому ничего объяснить не сможете.
#softskills
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍4💯4👎2🦄1
Дядюшка Боб не читает код AI-агентов. Я тоже.
В сети хайпит твит дядюшки Боба, в котором он признается, что вовсе не читает код, который пишут его агенты. Многие пишут, что таким образом он теряет контроль над кодом. Это не так: в том же твите он пишет, что использует много тестов и другие quality gates. Таким образом, он просто меняет способ контроля: автоматические проверки вместо привычного “метода пристального взгляда”.
Я тоже не читаю код, который пишут мои агенты. Сразу уточню, что далеко не весь код я пишу при помощи агентов и довольно много кода пишу руками. Но если уж я решила отдать задачу агенту, то не читаю каждую строчку, иначе во всем этом нет никакого смысла.
Строго говоря, использование кода, написанного агентом, мало чем отличается от использования сторонней библиотеки. Вы же не читаете исходники библиотеки, которую добавляете в свой проект? (Я, по правде, иногда читаю, но только тогда, когда что-то странно работает, и только ту часть, с которой проблемы). Такой подход использует идеи ООП: код, написанный агентом, является черным ящиком, а нас интересует его контракт (делает то, что заявлено), а не внутренняя реализация.
Ниже опишу воркфлоу и ограничения, которые я использую.
1️⃣ Только задачи с уже принятыми решениями
Я отдаю агенту только те задачи, с которыми нет неопределенности: я абсолютно точно знаю, что я сама бы написала, если бы писала это руками. Если я сама точно не знаю, что конкретно надо сделать и нужно решать по ходу, то это не тот случай.
2️⃣ Только мой стек
Агент пишет код только в том стеке, которым я хорошо владею, в моем случае это фронтенд. Мои навыки в бекенд разработке у меня гораздо слабее, поэтому бекенд я пишу самостоятельно, осмысляя каждую строчку.
3️⃣ Не отдаю core часть
Основные части системы я пишу вручную.
Агент хорошо подходит для изолированных утилит, плагинов, вспомогательных модулей и прочих локальных задач.
4️⃣ Спецификацию пишу в виде тестов
Для меня это оказалось более удобным, чем md файлы. В тестах я на естественном языке определяю, как должна работать та часть кода, которую я делаю.
5️⃣ Тесты генерирую агентом
Код тестов генерирую при помощи агентов. Затем читаю и убеждаюсь, что он меня устраивает.
6️⃣ Генерирую код
После генерации тестов я приступаю непосредственно к генерации самого кода.
Затем запускаю тесты, сборку и автоматические проверки (линтер, etc).
Если все ок, тогда смотрю, какие конкретно файлы изменил агент (git status).
Смотрю общий объем сгенерированного кода при помощи git diff.
Если выглядит ок, то делаю commit и push.
Этот воркфлоу, конечно, не идеален, но удобен для меня. Кроме того, как я уже сказала, большую часть кода я по-прежнему пишу руками (там, где нужно по ходу понять, что именно нужно сделать, и core часть).
Всем удачного вайб-кодинга🥹
🔜 Канал в MAX
В сети хайпит твит дядюшки Боба, в котором он признается, что вовсе не читает код, который пишут его агенты. Многие пишут, что таким образом он теряет контроль над кодом. Это не так: в том же твите он пишет, что использует много тестов и другие quality gates. Таким образом, он просто меняет способ контроля: автоматические проверки вместо привычного “метода пристального взгляда”.
Я тоже не читаю код, который пишут мои агенты. Сразу уточню, что далеко не весь код я пишу при помощи агентов и довольно много кода пишу руками. Но если уж я решила отдать задачу агенту, то не читаю каждую строчку, иначе во всем этом нет никакого смысла.
Строго говоря, использование кода, написанного агентом, мало чем отличается от использования сторонней библиотеки. Вы же не читаете исходники библиотеки, которую добавляете в свой проект? (Я, по правде, иногда читаю, но только тогда, когда что-то странно работает, и только ту часть, с которой проблемы). Такой подход использует идеи ООП: код, написанный агентом, является черным ящиком, а нас интересует его контракт (делает то, что заявлено), а не внутренняя реализация.
Ниже опишу воркфлоу и ограничения, которые я использую.
Я отдаю агенту только те задачи, с которыми нет неопределенности: я абсолютно точно знаю, что я сама бы написала, если бы писала это руками. Если я сама точно не знаю, что конкретно надо сделать и нужно решать по ходу, то это не тот случай.
Агент пишет код только в том стеке, которым я хорошо владею, в моем случае это фронтенд. Мои навыки в бекенд разработке у меня гораздо слабее, поэтому бекенд я пишу самостоятельно, осмысляя каждую строчку.
Основные части системы я пишу вручную.
Агент хорошо подходит для изолированных утилит, плагинов, вспомогательных модулей и прочих локальных задач.
Для меня это оказалось более удобным, чем md файлы. В тестах я на естественном языке определяю, как должна работать та часть кода, которую я делаю.
Код тестов генерирую при помощи агентов. Затем читаю и убеждаюсь, что он меня устраивает.
После генерации тестов я приступаю непосредственно к генерации самого кода.
Затем запускаю тесты, сборку и автоматические проверки (линтер, etc).
Если все ок, тогда смотрю, какие конкретно файлы изменил агент (git status).
Смотрю общий объем сгенерированного кода при помощи git diff.
Если выглядит ок, то делаю commit и push.
Этот воркфлоу, конечно, не идеален, но удобен для меня. Кроме того, как я уже сказала, большую часть кода я по-прежнему пишу руками (там, где нужно по ходу понять, что именно нужно сделать, и core часть).
Всем удачного вайб-кодинга
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍8🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
Досмотрела нашумевшее интервью с CTO Skyeng.
Коротко: будущее наступило, мы уволим всех тех, кто не хочет адаптироваться к переменам и делать одновременно 10 задач стаей агентов.
Полминуты спустя: операционная система? Ну конечно мак! Я по-другому не умею. Я всю жизнь на маке.
Еще чуть ранее она же говорит, что отказалась от использования open claw, потому что оказалось неудобно. То есть, внезапно оказывается, некоторые вещи неудобно делать LLM-кой.
Позже напишу о том, что я думаю про то, что “нас всех заменят”.
Коротко: будущее наступило, мы уволим всех тех, кто не хочет адаптироваться к переменам и делать одновременно 10 задач стаей агентов.
Полминуты спустя: операционная система? Ну конечно мак! Я по-другому не умею. Я всю жизнь на маке.
Еще чуть ранее она же говорит, что отказалась от использования open claw, потому что оказалось неудобно. То есть, внезапно оказывается, некоторые вещи неудобно делать LLM-кой.
Позже напишу о том, что я думаю про то, что “нас всех заменят”.
🤣22👍13❤6😁5🔥3🤡3👎1🙈1
Что заберет у нас ИИ
В сети разгораются нешуточные дискуссии на тему замены разработчиков искусственным интеллектом.
Какой-то сын маминой подруги пишет, как его харнесс (если что, это приличное слово, погуглите) помогает ему делать всю свою работу за два часа, а остальное время пить смузи на пляже. Другой отвечает, что единственное, что создает ИИ — боль, техдолг и проблемы. Пока обыватели пытаются разобраться, пора ли выкинуть на помойку свое резюме программиста и переучиваться на электросварщика, самые умные изучают историю.
Отчетливые попытки заменить человека на машину были еще в середине прошлого века. Во время Второй Мировой войны Норберт Винер пытался автоматизировать управление зенитными установками. Ему не вполне удалось достичь поставленных целей, однако его работы послужила началом новой науки — кибернетики. Кибернетика изучает общие механизмы управления — как в машинах, так и в обществе. Кибернетика обрела широкую популярность в советском союзе: создавались новые институты и кафедры, которые пытались автоматизировать работу человека. На одну из таких кафедр, кафедру АСУ (автоматизированных систем управления), я поступила учиться много лет тому назад, благодаря чему вы сейчас имеете возможность читать этот пост.
Ближе к концу XX веке интерес к кибернетике в СССР постепенно стал угасать. Бюджеты были потрачены немалые, а каких-то впечатляющих результатов достичь не удалось. С критикой кибернетики выступал, например, Г.П. Щедровицкий, который говорил о том, что кибернетики изучают процессы управления сами по себе, безотносительно человеческой деятельности и целеполагания:
Те же кибернетические идеи были использованы для создания перцептрона, а затем и нейросетей, которые сейчас бурно развиваются, а про кибернетику все как будто забыли.
Нейросети действительно позволяют очень быстро генерировать много кода.
Однако тот ли этот код, который нам нужен? Тот ли это код, который соответствует нашим целям?
Зависит от целей.
Если вам в принципе все равно, какой там код у вас написан, то тогда шансов “попасть в яблочко” у LLM предостаточно. Для какой ситуации это справедливо? Я уже писала и повторюсь: я считаю, это вполне справедливо для ситуации, когда вы пишете не core часть приложения, а также легко заменяемые плагин.
А что насчет core части?
LLM может хорошо написать любой код при условии достаточно подробной входной спецификации. Здесь кроется проблема: самая подробная спецификация — это… и есть код.
То есть в ситуациях, где важно точное соответствие, кпд LLM-ки стремится к нулю.
Соответственно, наша задача, как разработчиков, сводится к следующему: отделить части системы, которые нам важны, от тех, которые не принципиальны (основной и второстепенный домены в DDD), для вторых организовать процесс агентской разработки, он же харнесс (боже мой, слово-то какое!), а дальше управлять агентами, то есть поправлять агентов в ситуациях, когда их действия расходятся с нашими целями. Управлять при помощи другого агента не получится по определению процесса управления:
Ну а core часть придется писать самостоятельно, иначе нашим целям она будет отвечать очень приблизительно, а легко это изменить мы не сможем.
ИИ заберет у нас самую скучную и рутинную работу. Настоящее проектирование, которое обязательно включает в себя целеполагание, все еще остается за нами.
В сети разгораются нешуточные дискуссии на тему замены разработчиков искусственным интеллектом.
Какой-то сын маминой подруги пишет, как его харнесс (если что, это приличное слово, погуглите) помогает ему делать всю свою работу за два часа, а остальное время пить смузи на пляже. Другой отвечает, что единственное, что создает ИИ — боль, техдолг и проблемы. Пока обыватели пытаются разобраться, пора ли выкинуть на помойку свое резюме программиста и переучиваться на электросварщика, самые умные изучают историю.
Отчетливые попытки заменить человека на машину были еще в середине прошлого века. Во время Второй Мировой войны Норберт Винер пытался автоматизировать управление зенитными установками. Ему не вполне удалось достичь поставленных целей, однако его работы послужила началом новой науки — кибернетики. Кибернетика изучает общие механизмы управления — как в машинах, так и в обществе. Кибернетика обрела широкую популярность в советском союзе: создавались новые институты и кафедры, которые пытались автоматизировать работу человека. На одну из таких кафедр, кафедру АСУ (автоматизированных систем управления), я поступила учиться много лет тому назад, благодаря чему вы сейчас имеете возможность читать этот пост.
Ближе к концу XX веке интерес к кибернетике в СССР постепенно стал угасать. Бюджеты были потрачены немалые, а каких-то впечатляющих результатов достичь не удалось. С критикой кибернетики выступал, например, Г.П. Щедровицкий, который говорил о том, что кибернетики изучают процессы управления сами по себе, безотносительно человеческой деятельности и целеполагания:
“…Однако вскоре Винер, который был аналитиком, увидел, что в этой схеме отсутствует главный момент; и незадолго до своей смерти написал об этом, повернув против всех, кто бросился разрабатывать кибернетику: выпало самое главное, а именно цель, которая есть у наводчика орудия. Цель схватить не удалось….”
Те же кибернетические идеи были использованы для создания перцептрона, а затем и нейросетей, которые сейчас бурно развиваются, а про кибернетику все как будто забыли.
Нейросети действительно позволяют очень быстро генерировать много кода.
Однако тот ли этот код, который нам нужен? Тот ли это код, который соответствует нашим целям?
Зависит от целей.
Если вам в принципе все равно, какой там код у вас написан, то тогда шансов “попасть в яблочко” у LLM предостаточно. Для какой ситуации это справедливо? Я уже писала и повторюсь: я считаю, это вполне справедливо для ситуации, когда вы пишете не core часть приложения, а также легко заменяемые плагин.
А что насчет core части?
LLM может хорошо написать любой код при условии достаточно подробной входной спецификации. Здесь кроется проблема: самая подробная спецификация — это… и есть код.
“Наиболее совершенной моделью кота является такой же кот, а лучше — он сам.” (Н. Винер)
То есть в ситуациях, где важно точное соответствие, кпд LLM-ки стремится к нулю.
Соответственно, наша задача, как разработчиков, сводится к следующему: отделить части системы, которые нам важны, от тех, которые не принципиальны (основной и второстепенный домены в DDD), для вторых организовать процесс агентской разработки, он же харнесс (боже мой, слово-то какое!), а дальше управлять агентами, то есть поправлять агентов в ситуациях, когда их действия расходятся с нашими целями. Управлять при помощи другого агента не получится по определению процесса управления:
“Управление возникает тогда, когда есть отклонение фактического процесса от заданной нормы или траектории, и задача управления — вернуть процесс в нормативное русло.” (Г.П. Щедровицкий)
Ну а core часть придется писать самостоятельно, иначе нашим целям она будет отвечать очень приблизительно, а легко это изменить мы не сможем.
ИИ заберет у нас самую скучную и рутинную работу. Настоящее проектирование, которое обязательно включает в себя целеполагание, все еще остается за нами.
"Отдайте же человеку - человеческое, а вычислительной машине - машинное." (Н. Винер, 1964г)
❤19👍10🔥6
Как я с React на Svelte перешла
Бытует мнение, что фронтенд-фреймворк — как факультет в Хогвартсе, выбирается один раз и на всю жизнь. Потому что разный синтаксис, разная экосистема, и вообще переходить с одного фреймворка на другой якобы очень сложно.
Сложность перехода между фрейморками — вредный миф. Подозреваю, что придумали его ребята, которые в 2021 году говорили “я не буду учить JavaScript, я же пишу на React”. Фреймворк — это инструмент, который берет часть задач JavaScript-разработчика на себя, а не отдельная профессия, которую надо месяцами учить. Учить надо программирование и основные концепции разработки, а конкретный фреймворк можно освоить за неделю-две.
Я совершала переход между фреймворками дважды. В 2019 я, имея опыт только на Vue, получила оффер в проект на React, а в прошлом году пришла в команду, которая пишет на Svelte. Где-то между делом года четыре назад я немного соприкасалась с Angular, так что, в целом, у меня есть опыт со всеми популярными фронтенд фреймворками.
Современные фронтенд-фреймворки имеют схожие концепции:
Реактивность. Вы перезаписываете данные, а UI обновляется сам. Не нужно редактировать DOM-элементы.
Код делится на переиспользуемые компоненты: кнопки, таблицы, панели, формы и т. д.
Внутреннее состояние (state/signal), входные данные (props/input), эффекты.
Написание кода на фронтенд фреймворках сводится к следующему: вы разбиваете код на компоненты, в которых храните состояние аналогично проперти классов в ООП, используете эффекты для подписок на изменение состояния (Оbserver), пропсы для передачи данных вниз и события для передачи данных наверх. Интерфейс будет обновляться самостоятельно — таким образом, вам нужно следить только за организацией данных.
Когда вы переходите на другой фреймворк, вы не начинаете обучение с нуля, вы используете уже знакомые концепции.
Конечно, к фреймворку привыкаешь. Когда я начала писать на Svelte, первые пару недель мне было немного неудобно. Потом я поняла, в чем дело: в React единица реактивности — это компонент, он ререндерится весь целиком. В Svelte единица реактивности — это сигнал. В компоненте может быть много сигналов и они все будут перевычисляться независимо. Поэтому привыкаешь мыслить более мелкими абстракциями. Но каждый раз при смене фреймворка я не училась программировать заново — я всего лишь читала документацию и привыкала к новому инструменту.
Кстати, документацию можно прочитать за один вечер 🙂
🔜 Канал в MAX
Бытует мнение, что фронтенд-фреймворк — как факультет в Хогвартсе, выбирается один раз и на всю жизнь. Потому что разный синтаксис, разная экосистема, и вообще переходить с одного фреймворка на другой якобы очень сложно.
Сложность перехода между фрейморками — вредный миф. Подозреваю, что придумали его ребята, которые в 2021 году говорили “я не буду учить JavaScript, я же пишу на React”. Фреймворк — это инструмент, который берет часть задач JavaScript-разработчика на себя, а не отдельная профессия, которую надо месяцами учить. Учить надо программирование и основные концепции разработки, а конкретный фреймворк можно освоить за неделю-две.
Я совершала переход между фреймворками дважды. В 2019 я, имея опыт только на Vue, получила оффер в проект на React, а в прошлом году пришла в команду, которая пишет на Svelte. Где-то между делом года четыре назад я немного соприкасалась с Angular, так что, в целом, у меня есть опыт со всеми популярными фронтенд фреймворками.
Современные фронтенд-фреймворки имеют схожие концепции:
Реактивность. Вы перезаписываете данные, а UI обновляется сам. Не нужно редактировать DOM-элементы.
Код делится на переиспользуемые компоненты: кнопки, таблицы, панели, формы и т. д.
Внутреннее состояние (state/signal), входные данные (props/input), эффекты.
Написание кода на фронтенд фреймворках сводится к следующему: вы разбиваете код на компоненты, в которых храните состояние аналогично проперти классов в ООП, используете эффекты для подписок на изменение состояния (Оbserver), пропсы для передачи данных вниз и события для передачи данных наверх. Интерфейс будет обновляться самостоятельно — таким образом, вам нужно следить только за организацией данных.
Когда вы переходите на другой фреймворк, вы не начинаете обучение с нуля, вы используете уже знакомые концепции.
Конечно, к фреймворку привыкаешь. Когда я начала писать на Svelte, первые пару недель мне было немного неудобно. Потом я поняла, в чем дело: в React единица реактивности — это компонент, он ререндерится весь целиком. В Svelte единица реактивности — это сигнал. В компоненте может быть много сигналов и они все будут перевычисляться независимо. Поэтому привыкаешь мыслить более мелкими абстракциями. Но каждый раз при смене фреймворка я не училась программировать заново — я всего лишь читала документацию и привыкала к новому инструменту.
Кстати, документацию можно прочитать за один вечер 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21❤🔥7💯3😁1