Шаблон проектирования: Стратегия
Пожалуй один из самых полезных шаблонов, который связан с объективной сложностью задач программирования, а не ооп, красивым кодом и так далее.
Расскажу про него на примере задачи. Предположим, что у вас есть страница на сайте, на которой отображается список пользователей. В зависимости от того, кто смотрит на эту страницу, список может быть очень разным. Например по дефолту выводятся только активные за последние 10 дней, админ видит вообще всех с пейджингом, какой-нибудь менеджер смотрит активность за месяц, при этом видит только своих подчиненных и так далее.
Эту задачу логично начинать решать обычным набором ифов, которые проверяют тип пользователя и дальше формируют правильный запрос. В большинстве случаев для подобной задачи нам хватит, но если сложность выборки вырастет до определенного уровня за счет доп. условий и/или количества новых ролей, то анализировать такой код станет крайне затруднительно. Это связано с тем, что сложно вычленить конкретную роль и то что будет выведено для нее с одной стороны, а с другой, любое изменение потребует постоянного анализа “а как это скажется на остальных”. Вероятность ошибки тут крайне высокая и через такие решения проходил не мало в своей жизни, когда делаешь изменение для одной ветки, а ломаются другие.
Вся проблема заключается в большом количестве состояний системы, что косвенно показывает цикломатическая сложность (количество возможных путей программы, то есть веток в ифах).
Выпутаться из этой ситуации можно двумя способами. Первый это просто вынос кусков кода в отдельные функции, что как будто-бы уменьшает цикломатическую сложность основного кода. Но в данном случае это иллюзия, нам все равно надо понимать логику на всех уровнях, чтобы увидеть что произойдет для конкретной роли. Поэтому здесь лучше подойдет второй способ. Нужно изолировать логику составления запроса для каждой роли в свой собственный кусок кода, например функцию. Общее количество кода и ифов в таком случае вырастет, так как появится дублирование если некоторые роли хотят одного и того же. Но, с другой стороны, сложность логики под каждую конкретную роль значительно снизится. Станет и легко анализировать и легко править конкретный кейс не боясь сломать остальное. Итого здесь мы получаем баланс между сложностью и дублированием которым можно управлять.
Именно это называется стратегией. Как правило, стратегия это разделение логики вычисления на независимые блоки, по какому-то одному общему ключевому признаку. Выше это роль пользователя. В других ситуациях ключом может быть что-то совершенно другое.
p.s. Расскажите про свои ситуации, где стратегия помогала снизить сложность?
Пожалуй один из самых полезных шаблонов, который связан с объективной сложностью задач программирования, а не ооп, красивым кодом и так далее.
Расскажу про него на примере задачи. Предположим, что у вас есть страница на сайте, на которой отображается список пользователей. В зависимости от того, кто смотрит на эту страницу, список может быть очень разным. Например по дефолту выводятся только активные за последние 10 дней, админ видит вообще всех с пейджингом, какой-нибудь менеджер смотрит активность за месяц, при этом видит только своих подчиненных и так далее.
// ChatGPT
async function fetchUserData(userRole, userId = null) {
let queryOptions = {};
if (userRole === 'admin') {
// Admin gets access to all users
queryOptions = {};
} else if (userRole === 'user') {
// Regular user gets only their data
queryOptions = {
where: {
id: userId
}
};
}
try {
const users = await User.findAll(queryOptions);
console.log(users);
} catch (error) {
console.error('Error fetching user data:', error);
}
}
// Example usage
fetchUserData('admin'); // Fetches all users for admins
fetchUserData('user', 1); // Fetches data for user with id 1
Эту задачу логично начинать решать обычным набором ифов, которые проверяют тип пользователя и дальше формируют правильный запрос. В большинстве случаев для подобной задачи нам хватит, но если сложность выборки вырастет до определенного уровня за счет доп. условий и/или количества новых ролей, то анализировать такой код станет крайне затруднительно. Это связано с тем, что сложно вычленить конкретную роль и то что будет выведено для нее с одной стороны, а с другой, любое изменение потребует постоянного анализа “а как это скажется на остальных”. Вероятность ошибки тут крайне высокая и через такие решения проходил не мало в своей жизни, когда делаешь изменение для одной ветки, а ломаются другие.
Вся проблема заключается в большом количестве состояний системы, что косвенно показывает цикломатическая сложность (количество возможных путей программы, то есть веток в ифах).
Выпутаться из этой ситуации можно двумя способами. Первый это просто вынос кусков кода в отдельные функции, что как будто-бы уменьшает цикломатическую сложность основного кода. Но в данном случае это иллюзия, нам все равно надо понимать логику на всех уровнях, чтобы увидеть что произойдет для конкретной роли. Поэтому здесь лучше подойдет второй способ. Нужно изолировать логику составления запроса для каждой роли в свой собственный кусок кода, например функцию. Общее количество кода и ифов в таком случае вырастет, так как появится дублирование если некоторые роли хотят одного и того же. Но, с другой стороны, сложность логики под каждую конкретную роль значительно снизится. Станет и легко анализировать и легко править конкретный кейс не боясь сломать остальное. Итого здесь мы получаем баланс между сложностью и дублированием которым можно управлять.
Именно это называется стратегией. Как правило, стратегия это разделение логики вычисления на независимые блоки, по какому-то одному общему ключевому признаку. Выше это роль пользователя. В других ситуациях ключом может быть что-то совершенно другое.
p.s. Расскажите про свои ситуации, где стратегия помогала снизить сложность?
PHP работы пост: Ищу Laravel-разработчика с фронтенд опытом на проектную работу для нашего колледжа https://mokevnin.notion.site/a62fc9b140df44609ee2b365d70f4e90?v=ecb6fa57cfe84022add265b6b574c2d1&p=a0195e34c32c4c6fb622662cdfe4b83a&pm=c стоимость проекта будет считаться исходя из 2000 руб/час, ориентировочно месяц на разработку, дедлайн 15 мая. Я соучаствую, помогаю с архитектурой, инфрой и ревью
Personal (Kirill Mokevnin) on Notion
Laravel-разработчик | Notion
Задача
Ребят, прощу прощения, на этой неделе выпал, то ребенок родился, то день рождения (хаха). Но вы можете посмотреть прикольное, как мне кажется, видео, где я с яндексоидами обсуждаю их процесс найма: https://www.youtube.com/watch?v=YAmDCi4J2dw
YouTube
Вся правда о собеседованиях в Яндекс: как пройти секции и что сейчас с алгоритмами | №29
Правда ли, что чтобы устроиться разработчиком в Яндекс, нужно пройти длинное многоэтапное собеседование? Как изменился подход к найму и что на самом деле сейчас в 2024 году спрашивают на интервью? Какие задачи решают на лайвкодинг секциях? Кирилл Мокевнин…
Внезапно мегавакансия в Хекслет. Ищу лида для нашей команды разработки https://hh.ru/vacancy/94992025 Почитайте описание, возможно оно вас тронет)
hh.ru
Вакансия Team Lead / Руководитель команды разработки (Ruby on Rails) в Москве, работа в компании Хекслет (вакансия в архиве c 15…
Зарплата: от 250000 до 300000 ₽ за месяц. Москва. Требуемый опыт: 3–6 лет. Полная занятость. Дата публикации: 14.04.2024.
Редактор Хекслета: JS => TS
На днях, после двух месяцев работы, мы зарелизили новую версию редактора. Про эту историю я расскажу на holyjs, а сейчас хочется поделиться вот каким наблюдением.
Переписывание редактора было больше рефакторингом, так как с последнего обновления все нехило ушло вперед, поэтому там много чего поменялось и местами архитектура и библиотеки и собственно js поменялся на ts. Кое какие фичи, я все же улучшил и впилил, просто потому что это было сделать легко. При этом по пути, были временно или случайно удалены вещи, которые раньше работали и были важны для пользователей, например, перетягивание панелей для изменения их размера. Такое происходит при большом рефакторинге, так как не всегда понятно зачем был нужен тот или иной код, что-то просто откладывается на потом.
За это всегда прилетает и нам тут же прилетело. Любые изменения людей напрягают если они ломают стандартные пути работы. Пользователям сложно, а порой невозможно объяснить, что движение вперед невозможно без ломания того, что было раньше. Если все время поддерживать статус кво (как было), то мы в какой-то момент не сможем вносить изменения и молодая шпана снесет нас с лица земли.
Каждая компания выбирает где она находится на этой шкале, кто-то ближе к движению вперед, кто-то к сохранению того что было. Я всегда был в рядах тех, кто может ломать что-то по пути, но главное двигаться вперед с максимальной скоростью. За это приходится огребать, но люди быстро остывают и принимают, если это действительно движение вперед.
p.s. Все нужные фиксы мы внесли в течении дня, щас редактор уже лучше чем был и готов к расширению без боли
На днях, после двух месяцев работы, мы зарелизили новую версию редактора. Про эту историю я расскажу на holyjs, а сейчас хочется поделиться вот каким наблюдением.
Переписывание редактора было больше рефакторингом, так как с последнего обновления все нехило ушло вперед, поэтому там много чего поменялось и местами архитектура и библиотеки и собственно js поменялся на ts. Кое какие фичи, я все же улучшил и впилил, просто потому что это было сделать легко. При этом по пути, были временно или случайно удалены вещи, которые раньше работали и были важны для пользователей, например, перетягивание панелей для изменения их размера. Такое происходит при большом рефакторинге, так как не всегда понятно зачем был нужен тот или иной код, что-то просто откладывается на потом.
За это всегда прилетает и нам тут же прилетело. Любые изменения людей напрягают если они ломают стандартные пути работы. Пользователям сложно, а порой невозможно объяснить, что движение вперед невозможно без ломания того, что было раньше. Если все время поддерживать статус кво (как было), то мы в какой-то момент не сможем вносить изменения и молодая шпана снесет нас с лица земли.
Каждая компания выбирает где она находится на этой шкале, кто-то ближе к движению вперед, кто-то к сохранению того что было. Я всегда был в рядах тех, кто может ломать что-то по пути, но главное двигаться вперед с максимальной скоростью. За это приходится огребать, но люди быстро остывают и принимают, если это действительно движение вперед.
p.s. Все нужные фиксы мы внесли в течении дня, щас редактор уже лучше чем был и готов к расширению без боли
Что такое полимофризм?
В одном из комментариев в постах про паттерны, кто-то сказал что совсем не въезжает в полиморфизм. Тогда я понял что надо немного откатиться и рассказать, так как концепция важна и без нее понимание многих вещей, например, тех же паттернов, будет нереальным. Так что садитесь по удобнее и слушайте)
Сначала договоримся что под словом полиморфизм здесь мы понимаем полиморфизм подтипов или сабтайпинг, это то что называется полиморфизмов в ооп. Кроме него есть и другие, о которых, может быть, в другой раз (например, дженерики это пример параметрического полиморфизма)
Если в двух словах, то полиморфизм позволяет нам подменять реализацию без необходимости переписывать код. Проявляется это по разному в разных ситуациях и чтобы увидеть картинку целиком, нужно разобрать эти типовые ситуации.
Но есть проблема, если у бекендеров полиморфизм по всюду хотят оно того или нет, то у фронтендеров его мало если это не angular, где он вшит через контейнер во фреймворк. Попробуем, все же, зайти через фронтенд, надеюсь будет понятно.
Допустим мы работаем с беком по апи и для этого используется спец либа, а не просто fetch запросы. У гитхаба есть подобная либа: https://github.com/octokit/rest.js Дальше вы решили написать тесты к своему коду и столкнулись с проблемой, что в тестах улетают запросы на реальный github, что не правильно. В тестах во внешние системы не ходят (кстати вы знаете почему?). Как выйти из этой ситуации?
• Либа может сама содержать такую функциональность. Ставится какой-нибудь флаг и она не шлет запросы
• Подход, который довольно популярен в JavaScript (и Ruby) это манки патчинг. С помощью либы https://github.com/nock/nock которая патчит низкоуровневый код и подменяет его фейком, который не делает никаких запросов.
• С помощью ифов
• Как развитие предыдущего пункта, с помощью полиморфизма
Поговорим о последних двух. Мы легко могли бы расставить по коду проверки на окружение:
Однако, этот код ведет к двум проблемам. Во-первых вызов кода по условию скрывает возможные ошибки и делает код сложнее. Тут легко напортачить и получить работающий тест, но не работающий код. Во-вторых, представьте что у вас таких вызовов десятки, а то и сотни. Во что превратиться код?
Выйти из этой ситуации можно с помощью применения полиморфизма. Для этого понадобится продублировать библиотеку octokit/rest.js но внутри, вместо реальных запросов, например, складывать данные в свойства объекта-библиотеки. Дальше, в отдельном файле пишем:
Вуаля, импортируем файл где надо и используем его не думая ни про какую тестовую среду. Конечно при этом фейковый объект должен иметь возможность настраиваться снаружи, чтобы возвращать нужные данные в нужных условиях.
В итоге мы получаем единообразный способ работы, с точки зрения приложения не существует никакого фейкового варианта либы. И если что-то меняется, то код приложения не меняется, изменения идут либо в либах, либо в этом отдельном файле. Это и есть полиморфизм подтипов (а объяснение последнего слова требует отдельного погружения в системы типов).
p.s. Мастхев для чтения: https://guides.hexlet.io/ru/usefull-twitter-threads/#мифы-вокруг-ооп
p.s.s. Требуется ли для полиморфизма подтипов наличие ооп?)
В одном из комментариев в постах про паттерны, кто-то сказал что совсем не въезжает в полиморфизм. Тогда я понял что надо немного откатиться и рассказать, так как концепция важна и без нее понимание многих вещей, например, тех же паттернов, будет нереальным. Так что садитесь по удобнее и слушайте)
Сначала договоримся что под словом полиморфизм здесь мы понимаем полиморфизм подтипов или сабтайпинг, это то что называется полиморфизмов в ооп. Кроме него есть и другие, о которых, может быть, в другой раз (например, дженерики это пример параметрического полиморфизма)
Если в двух словах, то полиморфизм позволяет нам подменять реализацию без необходимости переписывать код. Проявляется это по разному в разных ситуациях и чтобы увидеть картинку целиком, нужно разобрать эти типовые ситуации.
Но есть проблема, если у бекендеров полиморфизм по всюду хотят оно того или нет, то у фронтендеров его мало если это не angular, где он вшит через контейнер во фреймворк. Попробуем, все же, зайти через фронтенд, надеюсь будет понятно.
Допустим мы работаем с беком по апи и для этого используется спец либа, а не просто fetch запросы. У гитхаба есть подобная либа: https://github.com/octokit/rest.js Дальше вы решили написать тесты к своему коду и столкнулись с проблемой, что в тестах улетают запросы на реальный github, что не правильно. В тестах во внешние системы не ходят (кстати вы знаете почему?). Как выйти из этой ситуации?
• Либа может сама содержать такую функциональность. Ставится какой-нибудь флаг и она не шлет запросы
• Подход, который довольно популярен в JavaScript (и Ruby) это манки патчинг. С помощью либы https://github.com/nock/nock которая патчит низкоуровневый код и подменяет его фейком, который не делает никаких запросов.
• С помощью ифов
• Как развитие предыдущего пункта, с помощью полиморфизма
Поговорим о последних двух. Мы легко могли бы расставить по коду проверки на окружение:
if (process.env.NODE_ENV === ‘testing’) {
// ничего не делаем
} else {
// реальный запрос
}
Однако, этот код ведет к двум проблемам. Во-первых вызов кода по условию скрывает возможные ошибки и делает код сложнее. Тут легко напортачить и получить работающий тест, но не работающий код. Во-вторых, представьте что у вас таких вызовов десятки, а то и сотни. Во что превратиться код?
Выйти из этой ситуации можно с помощью применения полиморфизма. Для этого понадобится продублировать библиотеку octokit/rest.js но внутри, вместо реальных запросов, например, складывать данные в свойства объекта-библиотеки. Дальше, в отдельном файле пишем:
let octokit;
if (process.env.NODE_ENV === ‘testing’) {
octokit = new OctokitFake();
} else {
octokit = new Octokit();
}
export octokit;
Вуаля, импортируем файл где надо и используем его не думая ни про какую тестовую среду. Конечно при этом фейковый объект должен иметь возможность настраиваться снаружи, чтобы возвращать нужные данные в нужных условиях.
В итоге мы получаем единообразный способ работы, с точки зрения приложения не существует никакого фейкового варианта либы. И если что-то меняется, то код приложения не меняется, изменения идут либо в либах, либо в этом отдельном файле. Это и есть полиморфизм подтипов (а объяснение последнего слова требует отдельного погружения в системы типов).
p.s. Мастхев для чтения: https://guides.hexlet.io/ru/usefull-twitter-threads/#мифы-вокруг-ооп
p.s.s. Требуется ли для полиморфизма подтипов наличие ооп?)
GitHub
GitHub - octokit/rest.js: GitHub REST API client for JavaScript
GitHub REST API client for JavaScript. Contribute to octokit/rest.js development by creating an account on GitHub.
В этом году Хекслет стал партнером конференции TechTrain 2024 Spring, которая пройдет 6 апреля онлайн (бесплатно, без смс). Я выступлю спикером с темой использования конечных автоматов в прикладном коде на бизнес задачах. После этого доклада ваша жизнь не будет прежней. Не пропустите https://techtrain.ru/?utm_source=partner&utm_medium=hexlet&utm_campaign=announce
TechTrain 2024 Spring. Фестиваль по профессиональному росту в IT
TechTrain 2024 Spring — фестиваль по профессиональному росту в IT. О том, как пройти путь Junior → Middle → Senior и выбрать направление своего развития.
Организованное программирование | Кирилл Мокевнин pinned «В этом году Хекслет стал партнером конференции TechTrain 2024 Spring, которая пройдет 6 апреля онлайн (бесплатно, без смс). Я выступлю спикером с темой использования конечных автоматов в прикладном коде на бизнес задачах. После этого доклада ваша жизнь не…»
Часто встречаюсь со мнением, что раз у нас есть гит, то старый код никогда не надо держать в репозитории, лучше все удалять, мы всегда можем вернуться в истории и увидеть что происходит. У меня на этот счет сложилось другое мнение.
При рефакторинге, я комментирую и не удаляю любой не тривиальный код. Это очень помогает, когда нужно постоянно возвращаться назад или извлекать куски кода, которые ты вроде уже удалил, а оказалось что оно надо. Особенно это актуально если рефакторинг идет не один день и приходится постоянно возвращаться. К тому же если прошло время, то не всегда вспомнишь где был какой код если не будешь постоянно смотреть в историю гита. Вроде бы мелочь, а удобно.
При рефакторинге, я комментирую и не удаляю любой не тривиальный код. Это очень помогает, когда нужно постоянно возвращаться назад или извлекать куски кода, которые ты вроде уже удалил, а оказалось что оно надо. Особенно это актуально если рефакторинг идет не один день и приходится постоянно возвращаться. К тому же если прошло время, то не всегда вспомнишь где был какой код если не будешь постоянно смотреть в историю гита. Вроде бы мелочь, а удобно.
Ребят, мы тут проходим в техорду (проект астаныхаба по обучению) и там для заявки нужно подтверждение выпускников из Казахстана. Если вы такой человек, напишите пожалуйста в комментариях. Я с вами свяжусь.
Forwarded from 23derevo (18+)
Смотрю доклад Кирилла Мокевнина на TechTrain, и охреневаю от качества звука и картинки. Непосвященные не догадаются, что это прямой эфир со спикером, который находится на другом конце земного шара.
Я не супер часто хвалю своих, но тут прямо заслуженно :)
Спасибо:
– Кириллу Мокевнину — за ответственный подход к докладу и своему оборудованию;
– командам OK/VK — за отличную реализацию видеозвонков;
– нашим ребятам — за SpeakerRoom;
– эфирным командам — за четкость процессов и профессионализм.
Да, ребят, хороший онлайн это долго, потно и дорого. Но оно того стоит.
Я не супер часто хвалю своих, но тут прямо заслуженно :)
Спасибо:
– Кириллу Мокевнину — за ответственный подход к докладу и своему оборудованию;
– командам OK/VK — за отличную реализацию видеозвонков;
– нашим ребятам — за SpeakerRoom;
– эфирным командам — за четкость процессов и профессионализм.
Да, ребят, хороший онлайн это долго, потно и дорого. Но оно того стоит.
Open Source и рабочее время
На днях Сергей Андреев (Привет!) написал твит по поводу того что он смотрит на гитхаб https://twitter.com/DragorWW/status/1776456741175066801 и, как в таких случаях водится, получил в тачанку, что нет времени/не интересно/не важно заниматься опенсорсом. Среди разных доводов был один про то, что и так на работе пашем, времени на заниматься опенсорсом после работы нет.
Не могу не пройтись по этому пункту. Если брать типовую прикладную разработку, то мы как разработчики каждый день используем большое количество разных библиотек для своих задач. Некоторые из них большие и страшные, как rails, react или spring boot, другие совсем маленькие, созданные вот такими же простыми разработчиками по всему миру.
Опытные разработчики, которые много с этим работали, не могли не наткнуться на недостатки этих либ или баги, которые возникают то тут то там. И когда это происходит, есть разные варианты развития событий. Кое кто не делает ничего, кое кто придумывает обходные пути в своем коде, кто-то меняет библиотеку. Но есть те, кто понимают, что в конкретной ситуации библиотека хороша и ее можно немного поправить. Они делают как миним ишьюс, а максимум пулреквест, который с высокой долей вероятности потом примут. Так программист и рабочие задачи решает и растит свой уровень (участие в опенсорсе влияет на уровень как разработчика), плюс качает свой публичный профиль, для некоторых работодателей это важно.
Звучит логично, но на этом этапе появляются следующие возражения.
Я не встречал багов в библиотеках.
Для меня это означает две вещи, либо человек слишком мало работал, либо есть вопросы к квалификации. Опытный разработчик может часами говорить про проблемы своего стека, фреймворка и инструментов.
У меня нет времени коммитить в опенсорс (после работы), бизнесу нужны решения
Для меня вот эта штука все же культурная. Мы часто пишем свои абстракции в коде (чем не библиотеки?), мы часто копаемся в исходниках чужих либ. Исправление ошибок, которые возникают в коде либ, которые мы используем, это тоже часть рабочего процесса. И здесь фактически речь идет про культуру как компании, так и конкретного человека. В моей практике, в тех компаниях где я работал и которые я создавал, быть частью сообщества открытых проектов это не история на посидеть после работы. Это часть работы. Если есть баг и он в либе, то давайте его поправим если в этом есть смысл (А он часто есть). Если мы видим что у нас абстракция, которая может стать либой, давайте ее вынесем и сделаем либой.
При этом все равно кто-то будет утверждать, что это невозможно/меня не поймет работодатель и так далее. Вполне возможно, но это культура, которая мне не подходит.
У меня есть пулреквесты, которые были приняты через годы после того как я их отправлял (а я про них просто забыл). А еще разок приняли пулреквест в рельсу, после чего меня завалили предложениями о работе в международных компаниях.
p.s. Сколько у вас принятых пулреквестов в опенсорс?
На днях Сергей Андреев (Привет!) написал твит по поводу того что он смотрит на гитхаб https://twitter.com/DragorWW/status/1776456741175066801 и, как в таких случаях водится, получил в тачанку, что нет времени/не интересно/не важно заниматься опенсорсом. Среди разных доводов был один про то, что и так на работе пашем, времени на заниматься опенсорсом после работы нет.
Не могу не пройтись по этому пункту. Если брать типовую прикладную разработку, то мы как разработчики каждый день используем большое количество разных библиотек для своих задач. Некоторые из них большие и страшные, как rails, react или spring boot, другие совсем маленькие, созданные вот такими же простыми разработчиками по всему миру.
Опытные разработчики, которые много с этим работали, не могли не наткнуться на недостатки этих либ или баги, которые возникают то тут то там. И когда это происходит, есть разные варианты развития событий. Кое кто не делает ничего, кое кто придумывает обходные пути в своем коде, кто-то меняет библиотеку. Но есть те, кто понимают, что в конкретной ситуации библиотека хороша и ее можно немного поправить. Они делают как миним ишьюс, а максимум пулреквест, который с высокой долей вероятности потом примут. Так программист и рабочие задачи решает и растит свой уровень (участие в опенсорсе влияет на уровень как разработчика), плюс качает свой публичный профиль, для некоторых работодателей это важно.
Звучит логично, но на этом этапе появляются следующие возражения.
Я не встречал багов в библиотеках.
Для меня это означает две вещи, либо человек слишком мало работал, либо есть вопросы к квалификации. Опытный разработчик может часами говорить про проблемы своего стека, фреймворка и инструментов.
У меня нет времени коммитить в опенсорс (после работы), бизнесу нужны решения
Для меня вот эта штука все же культурная. Мы часто пишем свои абстракции в коде (чем не библиотеки?), мы часто копаемся в исходниках чужих либ. Исправление ошибок, которые возникают в коде либ, которые мы используем, это тоже часть рабочего процесса. И здесь фактически речь идет про культуру как компании, так и конкретного человека. В моей практике, в тех компаниях где я работал и которые я создавал, быть частью сообщества открытых проектов это не история на посидеть после работы. Это часть работы. Если есть баг и он в либе, то давайте его поправим если в этом есть смысл (А он часто есть). Если мы видим что у нас абстракция, которая может стать либой, давайте ее вынесем и сделаем либой.
При этом все равно кто-то будет утверждать, что это невозможно/меня не поймет работодатель и так далее. Вполне возможно, но это культура, которая мне не подходит.
У меня есть пулреквесты, которые были приняты через годы после того как я их отправлял (а я про них просто забыл). А еще разок приняли пулреквест в рельсу, после чего меня завалили предложениями о работе в международных компаниях.
p.s. Сколько у вас принятых пулреквестов в опенсорс?
X (formerly Twitter)
Андреев Сергей (@DragorWW) on X
Это я, я блин смотрю эти GitHub, и знаете что:
Тут недавно отсматривал кандидатов на backend, выбирать как-то надо, у некоторых есть ссылка на GitHub, по этому так же смотрел
Но там зачастую жесть
- ладно пустой аккаунт
- иногда по истории смотришь, там…
Тут недавно отсматривал кандидатов на backend, выбирать как-то надо, у некоторых есть ссылка на GitHub, по этому так же смотрел
Но там зачастую жесть
- ладно пустой аккаунт
- иногда по истории смотришь, там…
Мой подход в работе с зависимостями и их устареванию
Если посмотреть на кодовую базу Хекслета, то ей уже 11 лет, что довольно не хило. При этом большая часть библиотек там последних версий. Подобное встречается далеко не в каждом взрослом проекте, достаточно часто, со временем, начинает копиться отставание и переход на новые версии становится невозможен без выделения большого куска времени на рефакторинг.
То что я расскажу это не какой-то рокет сайнс да и подходит не всем, но вот так случилось, что я выработал для себя тактику и придерживаюсь ее. Каждую неделю, а иногда каждый рабочий день (если проект небольшой) я начинаю с того, что обновляю все зависимости в проекте. Так как проекты в которых я участвую покрыты тестами, то быстро становится видно, если какой-то пакет сломал функциональность, поэтому конкретно этот пакет можно откатить. В первую очередь я все же пробую увидеть насколько сложное изменение требуется сделать и если оно не заставит меня сидеть целый день, то как правило я делаю такое изменение и остаюсь на новых версиях пакетов.
На короткой дистанции это может замедлить процесс, так как раз в неделю тратится небольшое время на апдейт, которое иногда вырастает если происходят мажорные изменения в ключевых либах. Но на дистанции этот подход выигрывает, потому что никогда не возникает ситуации накопленного долга, где переход становится почти невозможным. Это позволяет пользоваться новыми возможностями, да и команда чувствует себя лучше, когда понимает что не застряла в мамонтовом легаси.
Что еще важно, чтобы такой подход работал:
• Использовать дефолты там где это возможно. Любая кастомизация мешает обновлениям. Вплоть до невозможности его выполнить
• Использовать только проверенные библиотеки, которые не умрут потому что их забросит основной мейнтенер
• Менять зависимости если их забрасывают (во фронте этого очень много)
Ошибки, при этом, конечно же случаются, не все протестировано, какие-то особые кейсы и так далее. И команда иногда на меня за это криво смотрит) С другой стороны, я вижу достаточно плюсов в этом подходе чтобы продолжать его придерживаться в тех местах, в которых я пишу код. Плюс конечно же, эти проекты не настолько огромные, где черт ногу сломит, поэтому можно себе позволить.
p.s. Как часто вы обновляете зависимости?
Если посмотреть на кодовую базу Хекслета, то ей уже 11 лет, что довольно не хило. При этом большая часть библиотек там последних версий. Подобное встречается далеко не в каждом взрослом проекте, достаточно часто, со временем, начинает копиться отставание и переход на новые версии становится невозможен без выделения большого куска времени на рефакторинг.
То что я расскажу это не какой-то рокет сайнс да и подходит не всем, но вот так случилось, что я выработал для себя тактику и придерживаюсь ее. Каждую неделю, а иногда каждый рабочий день (если проект небольшой) я начинаю с того, что обновляю все зависимости в проекте. Так как проекты в которых я участвую покрыты тестами, то быстро становится видно, если какой-то пакет сломал функциональность, поэтому конкретно этот пакет можно откатить. В первую очередь я все же пробую увидеть насколько сложное изменение требуется сделать и если оно не заставит меня сидеть целый день, то как правило я делаю такое изменение и остаюсь на новых версиях пакетов.
На короткой дистанции это может замедлить процесс, так как раз в неделю тратится небольшое время на апдейт, которое иногда вырастает если происходят мажорные изменения в ключевых либах. Но на дистанции этот подход выигрывает, потому что никогда не возникает ситуации накопленного долга, где переход становится почти невозможным. Это позволяет пользоваться новыми возможностями, да и команда чувствует себя лучше, когда понимает что не застряла в мамонтовом легаси.
Что еще важно, чтобы такой подход работал:
• Использовать дефолты там где это возможно. Любая кастомизация мешает обновлениям. Вплоть до невозможности его выполнить
• Использовать только проверенные библиотеки, которые не умрут потому что их забросит основной мейнтенер
• Менять зависимости если их забрасывают (во фронте этого очень много)
Ошибки, при этом, конечно же случаются, не все протестировано, какие-то особые кейсы и так далее. И команда иногда на меня за это криво смотрит) С другой стороны, я вижу достаточно плюсов в этом подходе чтобы продолжать его придерживаться в тех местах, в которых я пишу код. Плюс конечно же, эти проекты не настолько огромные, где черт ногу сломит, поэтому можно себе позволить.
p.s. Как часто вы обновляете зависимости?
Кроме телеги я еще переодически веду твиттер канал, но не совсем понимаю насколько пересекается аудитория. Напишите плс смотрите ли вы его или нет? Потому что в основном это разный контент. Как пример https://twitter.com/mokevnin/status/1778514285917778078
X (formerly Twitter)
Kirill (hexlet.io) (@mokevnin) on X
Тред с вопросами, которые имеет смысл задать на собесах, чтобы проверить уровень разработчика и навык решения прикладных задач (типовых для веба) Поехали =>
Разбор “твиттер собеседования”
На днях я сделал тред в твиттере про вопросы, которые можно задать на собесе опытным девелоперам, чтобы понять их уровень решения прикладных задач. Тред круто разошелся и часть людей в ответах стала проходить это “собеседование”. Большая часть ответов там в тему, но кое что можно подать по другому, поэтому я хочу сейчас здесь разобрать некоторые из этих вопросов.
Сразу скажу, что это вопросы на пообсуждать, на них нет правильных ответов, есть только какие-то области, в рамках которых лежит ответ на вопрос.
> Предположим что вы реализуете редакцию журнала, где редактора могут в админке править статьи. Как предотвратить ситуацию, когда два редактора могут начать одновременно редактировать одну статью и перетирать изменения друг друга?
Если коротко, ответ это использование либо оптимистической либо пессимистической блокировки. Их даже не придется делать самостоятельно, потому что такая функциональность есть в любой хорошей ORM.
> Каких принципов разработки нужно придерживаться, для обеспечения механизма zero downtime deployment, это подход при котором приложение деплоится без простоя сервиса. Как это достигается?
То что конкретно касается разработчика, это то как надо работать с интерфейсами. Структура сообщений в очередях, api, структура базы данных, все это должно быть обратно совместимым так как ZDD подразумевает одновременный запуск прошлой и новой версии приложений.
> Что может произойти, если ваша крон задача, которая запускается раз в минуту, стала выполняться больше 1 минуты? Как это можно предотвратить?
Может быть нужно перейти на событийную систему и очереди/джобы, может быть увеличить таймауты, а может поставить лок.
> Если вы пишите тесты, то как вы обходите проблему того, что код который вы тестируете, делает внешние вызовы? Доп условие, говорим о том, что на CI внешние вызовы запрещены (почему так правильно?)
VCR (кассеты) или стабы
> Предположим что в вашей системе реализована смена емейла. При этом этот емейл хранится еще и во внешней системе, например эквайринге, который шлет пользователю свои письма (но пользователь им напрямую не пользуется). Как бы вы реализовали синхронизацию емейла с внешней системой?
Тут главное что у нас конечный автомат который надо контролировать. А логика простая, подтверждается смена емейла, фигачим джобу, которая делает внешний вызов и меняет стейт.
> Как вы узнаете об ошибках, которые происходят на продакшене? От пользователей или это автоматизировано?
Самое простое это коллекторы ошибок типа sentry, остальное по требованиям/вкусу
> Как обеспечивается изоляция тестов друг от друга если они ходят в базу и меняют ее (дефолт в большинстве фреймворков)? Если в вашем фреймворке этого нет, то как вы это делаете или сделали бы?
Кстати удивительно, что никто не назвал самый простой вариант реализованный во всех бек фреймворках по умолчанию, это транзакционные тесты. В начале теста транзакция стартует, в конце откатывается. Так работает в laravel, django, rails, spring boot и других фреймворках без доп настроек.
На днях я сделал тред в твиттере про вопросы, которые можно задать на собесе опытным девелоперам, чтобы понять их уровень решения прикладных задач. Тред круто разошелся и часть людей в ответах стала проходить это “собеседование”. Большая часть ответов там в тему, но кое что можно подать по другому, поэтому я хочу сейчас здесь разобрать некоторые из этих вопросов.
Сразу скажу, что это вопросы на пообсуждать, на них нет правильных ответов, есть только какие-то области, в рамках которых лежит ответ на вопрос.
> Предположим что вы реализуете редакцию журнала, где редактора могут в админке править статьи. Как предотвратить ситуацию, когда два редактора могут начать одновременно редактировать одну статью и перетирать изменения друг друга?
Если коротко, ответ это использование либо оптимистической либо пессимистической блокировки. Их даже не придется делать самостоятельно, потому что такая функциональность есть в любой хорошей ORM.
> Каких принципов разработки нужно придерживаться, для обеспечения механизма zero downtime deployment, это подход при котором приложение деплоится без простоя сервиса. Как это достигается?
То что конкретно касается разработчика, это то как надо работать с интерфейсами. Структура сообщений в очередях, api, структура базы данных, все это должно быть обратно совместимым так как ZDD подразумевает одновременный запуск прошлой и новой версии приложений.
> Что может произойти, если ваша крон задача, которая запускается раз в минуту, стала выполняться больше 1 минуты? Как это можно предотвратить?
Может быть нужно перейти на событийную систему и очереди/джобы, может быть увеличить таймауты, а может поставить лок.
> Если вы пишите тесты, то как вы обходите проблему того, что код который вы тестируете, делает внешние вызовы? Доп условие, говорим о том, что на CI внешние вызовы запрещены (почему так правильно?)
VCR (кассеты) или стабы
> Предположим что в вашей системе реализована смена емейла. При этом этот емейл хранится еще и во внешней системе, например эквайринге, который шлет пользователю свои письма (но пользователь им напрямую не пользуется). Как бы вы реализовали синхронизацию емейла с внешней системой?
Тут главное что у нас конечный автомат который надо контролировать. А логика простая, подтверждается смена емейла, фигачим джобу, которая делает внешний вызов и меняет стейт.
> Как вы узнаете об ошибках, которые происходят на продакшене? От пользователей или это автоматизировано?
Самое простое это коллекторы ошибок типа sentry, остальное по требованиям/вкусу
> Как обеспечивается изоляция тестов друг от друга если они ходят в базу и меняют ее (дефолт в большинстве фреймворков)? Если в вашем фреймворке этого нет, то как вы это делаете или сделали бы?
Кстати удивительно, что никто не назвал самый простой вариант реализованный во всех бек фреймворках по умолчанию, это транзакционные тесты. В начале теста транзакция стартует, в конце откатывается. Так работает в laravel, django, rails, spring boot и других фреймворках без доп настроек.
Какие вопросы стоит задать работадателю если вы разработчик?
Честно говоря, хрен его знает. Жизнь показывает, что даже если люди произносят правильные слова, это ничего не означает. Вы пишите тесты? Да пишем. По факту там может быть все что угодно, вплоть до того, что лучше бы вообще не писали, чем писали то что пишут.
Если исходить из задачи, найти адекватное место с возможностью вырасти профессионально (но не факт что по карьерной лестнице), то я бы выбирал компанию по таким критерию:
• Компания работает на свои деньги. Инвестиции или бесконечный ресурс (банки), очень сильно влияют на восприятие реальности. В таких местах можно заработать, но часто, это овер-все. Нанимаем любое количество тестировщиков, делаем сколь угодно сложный процесс и так далее. Расхолаживает и отрывает от принятия разумных решений.
• Команда ориентируется на деньги, понимает свой вклад, свое влияние и связывает свою работу с тем, что компания зарабатывает и на что тратит. Встречается редко, но с моей колокольни, это значительный фактор. В таких компаниях разработчики воспринимают тот же маркетинг не как назойливых людей, которые мешают работать, а как тех людей, с которыми у нас общие задачи, для того чтобы компания процветала и у всех была возможность развиваться нанимать и так далее.
• Во время разговора (на собесе и внутри) люди много уделяют времени бизнесовой стороне вопроса, решению задач, которые влияют на продуктово-маркетинговые метрики. В противположность есть команды, которые большую часть времени создают абстракции, спорят о паттернах и спрашивают всех про SOLID.
• В компании практикуется фулстек разработка. Многие со мной не согласятся, но мне кажется это показателем того, что в компании нет изоляции и перекладывания ответственности, которая может быть в тех местах где “я это не знаю, это девопсы делают”.
• Разработка использует стандартные инструменты, а не пилит свои фреймворки и инструменты. Да бывает что пилить свое надо, но в типовых проектах, это явно перебор.
• Разработчики пишут тесты сами, при этом в компании нет толп ручных и автоматизированных тестировщиков. Да и в целом отношение к пайплайну без фанатизма, типа мы щас тут сделаем три предпрод стадии, чтобы все было ух наверняка.
• Деплой это рядовая процедура, которую делают абсолютно все, желательно по необходимости. В некоторых компаниях это удел избранных и даже одного конкретного человека.
• В собеседовании не прозвучало слово “микросервисы” :)
Все эти пункты ничего не гарантируют, плюс они очень сильно связаны с моим личным опытом. Уверен у многих все по другому. Поделитесь в комментариях с чем вы не согласны и что по вашему мнению важно и в идеале можно проверить на собесе (не обманут).
Честно говоря, хрен его знает. Жизнь показывает, что даже если люди произносят правильные слова, это ничего не означает. Вы пишите тесты? Да пишем. По факту там может быть все что угодно, вплоть до того, что лучше бы вообще не писали, чем писали то что пишут.
Если исходить из задачи, найти адекватное место с возможностью вырасти профессионально (но не факт что по карьерной лестнице), то я бы выбирал компанию по таким критерию:
• Компания работает на свои деньги. Инвестиции или бесконечный ресурс (банки), очень сильно влияют на восприятие реальности. В таких местах можно заработать, но часто, это овер-все. Нанимаем любое количество тестировщиков, делаем сколь угодно сложный процесс и так далее. Расхолаживает и отрывает от принятия разумных решений.
• Команда ориентируется на деньги, понимает свой вклад, свое влияние и связывает свою работу с тем, что компания зарабатывает и на что тратит. Встречается редко, но с моей колокольни, это значительный фактор. В таких компаниях разработчики воспринимают тот же маркетинг не как назойливых людей, которые мешают работать, а как тех людей, с которыми у нас общие задачи, для того чтобы компания процветала и у всех была возможность развиваться нанимать и так далее.
• Во время разговора (на собесе и внутри) люди много уделяют времени бизнесовой стороне вопроса, решению задач, которые влияют на продуктово-маркетинговые метрики. В противположность есть команды, которые большую часть времени создают абстракции, спорят о паттернах и спрашивают всех про SOLID.
• В компании практикуется фулстек разработка. Многие со мной не согласятся, но мне кажется это показателем того, что в компании нет изоляции и перекладывания ответственности, которая может быть в тех местах где “я это не знаю, это девопсы делают”.
• Разработка использует стандартные инструменты, а не пилит свои фреймворки и инструменты. Да бывает что пилить свое надо, но в типовых проектах, это явно перебор.
• Разработчики пишут тесты сами, при этом в компании нет толп ручных и автоматизированных тестировщиков. Да и в целом отношение к пайплайну без фанатизма, типа мы щас тут сделаем три предпрод стадии, чтобы все было ух наверняка.
• Деплой это рядовая процедура, которую делают абсолютно все, желательно по необходимости. В некоторых компаниях это удел избранных и даже одного конкретного человека.
• В собеседовании не прозвучало слово “микросервисы” :)
Все эти пункты ничего не гарантируют, плюс они очень сильно связаны с моим личным опытом. Уверен у многих все по другому. Поделитесь в комментариях с чем вы не согласны и что по вашему мнению важно и в идеале можно проверить на собесе (не обманут).