🤔 #Мысли
Какой раз замечаю, что проф. развитие и мотивация у меня всегда шли и идут “волнами”.
В школьные/универские годы это было в соотношении ~ 3:1 – 3 месяца активно штырит мотивация на изучение и развитие всего и вся, 1 месяц просто не могу и не хочу ничего связанного с IT.
А последние года 3-4 оно всё больше размазывается мелкими порциями: ~ недели активностей и ~ пару дней великая лень и отвержение.
Порой задумываюсь, это прогресс или деградация? С одной стороны я более предсказуем для себя и работадателя, но с другой этот проявляется всё чаще и может утащить на свою сторону.
Какой раз замечаю, что проф. развитие и мотивация у меня всегда шли и идут “волнами”.
В школьные/универские годы это было в соотношении ~ 3:1 – 3 месяца активно штырит мотивация на изучение и развитие всего и вся, 1 месяц просто не могу и не хочу ничего связанного с IT.
А последние года 3-4 оно всё больше размазывается мелкими порциями: ~ недели активностей и ~ пару дней великая лень и отвержение.
Порой задумываюсь, это прогресс или деградация? С одной стороны я более предсказуем для себя и работадателя, но с другой этот проявляется всё чаще и может утащить на свою сторону.
1👍2
💊 #Пост №4. Разбор инцидентов или Postmortem
Упал прод – починили и пообещали больше так не делать?
В современном мире этого недостаточно. Слова нужно подкреплять делом, а обещания тасками и их выполнением.
Если начать ретроспектировать на тему падения в том или ином кейсе, можно не только понимать произошедшее, но и научиться предвидеть и недопускать повторных ошибок в будущем, поднять культуру разработки в команде и даже заработать статус в лице коллег за бравое дело.
Postmortem в IT – это ретроспектива, направленная на тему “что нужно сделать сейчас, чтобы избежать подобной ошибки в будущем”.
Собрал мысли в порядок и написал пост. Текст опять не влез в одно сообщение телеграма, поэтому публикую в телеграфе: https://telegra.ph/Post-4-Razbor-incidentov-ili-Postmortem-12-01
Упал прод – починили и пообещали больше так не делать?
В современном мире этого недостаточно. Слова нужно подкреплять делом, а обещания тасками и их выполнением.
Если начать ретроспектировать на тему падения в том или ином кейсе, можно не только понимать произошедшее, но и научиться предвидеть и недопускать повторных ошибок в будущем, поднять культуру разработки в команде и даже заработать статус в лице коллег за бравое дело.
Postmortem в IT – это ретроспектива, направленная на тему “что нужно сделать сейчас, чтобы избежать подобной ошибки в будущем”.
Собрал мысли в порядок и написал пост. Текст опять не влез в одно сообщение телеграма, поэтому публикую в телеграфе: https://telegra.ph/Post-4-Razbor-incidentov-ili-Postmortem-12-01
Telegraph
Пост №4. Разбор инцидентов или Postmortem
Postmortem – это медицинский термин, который обозначает процесс вскрытия трупа для исследования причин смерти. Postmortem в IT – это ретроспектива, направленная на тему “что нужно сделать сейчас, чтобы избежать подобной ошибки в будущем”. Будет довольно странно…
2👍5
#оффтоп
Согласен с мнениями о вредности пустых моделей, но есть что дополнить ув. тов. Шароватову.
Если переложить пустые модели на кухню разработки, то порой вредно выделять класс ради класса, микросервис ради микросервиса, абстракцию ради абстракции.
Однако это вредно лишь тогда, когда оно наносит какой-то вред.
Например, если создать микросервис проще, быстрее и дешевле, чем интегрировать модуль в работающую систему, то определенно стоит создавать микросервис. Конечно, это чаще всего не так, но не нужно брать идею в максимализм и накладывать на неё весь мир.
В сравнении “иметь плохую модель vs не иметь модели”, всё конечно зависит от контекста, но чаще всего лучше иметь плохую модель. Ведь плохая модель приносит хоть какую-то пользу, по отношению к отсутствующей модели.
Любая абстракция позволяет выполнять меньше действий в каком-то направлении. Мы ведь не рисуем карту межсервисной коммуникации, включая туда все классы, методы, таблицы, колонки, фреймворки, библиотеки и т.п. для того, чтобы посмотреть лишь как сервисы взаимодействуют друг друга в первом приближении.
Лучше иметь плохуя карту сервисов, чем не иметь её и каждый раз вспоминать о всех коммуникациях. Лучше иметь плохую декомпозицию программных модулей, чем её не иметь. Лучше иметь плохую машину, которая вас довозит до работы за 40 минут, чем каждый раз кататься на автобусе, который делает это за полтора часа.
Даже когда модель перестала быть полезной, в какой-то момент польза от неё может вернуться и придется возвращаться к ней, чтобы иметь хоть какой-то бенефит.
Опять же, всё зависит от контекста и максимализировать явно не стоит.
Согласен с мнениями о вредности пустых моделей, но есть что дополнить ув. тов. Шароватову.
Если переложить пустые модели на кухню разработки, то порой вредно выделять класс ради класса, микросервис ради микросервиса, абстракцию ради абстракции.
Однако это вредно лишь тогда, когда оно наносит какой-то вред.
Например, если создать микросервис проще, быстрее и дешевле, чем интегрировать модуль в работающую систему, то определенно стоит создавать микросервис. Конечно, это чаще всего не так, но не нужно брать идею в максимализм и накладывать на неё весь мир.
В сравнении “иметь плохую модель vs не иметь модели”, всё конечно зависит от контекста, но чаще всего лучше иметь плохую модель. Ведь плохая модель приносит хоть какую-то пользу, по отношению к отсутствующей модели.
Любая абстракция позволяет выполнять меньше действий в каком-то направлении. Мы ведь не рисуем карту межсервисной коммуникации, включая туда все классы, методы, таблицы, колонки, фреймворки, библиотеки и т.п. для того, чтобы посмотреть лишь как сервисы взаимодействуют друг друга в первом приближении.
Лучше иметь плохуя карту сервисов, чем не иметь её и каждый раз вспоминать о всех коммуникациях. Лучше иметь плохую декомпозицию программных модулей, чем её не иметь. Лучше иметь плохую машину, которая вас довозит до работы за 40 минут, чем каждый раз кататься на автобусе, который делает это за полтора часа.
Даже когда модель перестала быть полезной, в какой-то момент польза от неё может вернуться и придется возвращаться к ней, чтобы иметь хоть какой-то бенефит.
Опять же, всё зависит от контекста и максимализировать явно не стоит.
1
Forwarded from Sharovatov (Vitaly Sharovatov)
> the essence of a model to be predictive
Ув. тов. Стафорд Бир считает, что любая модель создаётся исключительно для того, чтобы помогать в предсказании чего-то.
Я склонен согласиться с ним: ведь даже аналитические, учебные или там эвристические модели создаются так, чтоб с какой-то точностью представлять моделируемую систему, и представление это нужно исключительно для того, чтобы предсказывать изменение реальной системы.
Если модель не помогает в предсказании, то траты на её создание были оправданы лишь тогда, когда она выкидывается или изменяется так, чтобы таки начинать помогать в предсказании.
Если же модель не помогает предсказывать ничего и помочь не может, то она вредна. Вредна просто потому, что используя негодные модели, мы принимаем неоптимальные решения.
Получается, что "плохая" модель хуже отсутствия модели вообще, ведь в случае отсутствия модели вообще нам-таки придётся скорее всего подумать.
Я знаю такие примеры вредных моделей:
- DORA
- нумерология, френология
- юнгианские психотипы (DISC туда же)
- астрология и всякий human design
- theory x
а какие вредные модели знаете вы?
Ув. тов. Стафорд Бир считает, что любая модель создаётся исключительно для того, чтобы помогать в предсказании чего-то.
Я склонен согласиться с ним: ведь даже аналитические, учебные или там эвристические модели создаются так, чтоб с какой-то точностью представлять моделируемую систему, и представление это нужно исключительно для того, чтобы предсказывать изменение реальной системы.
Если модель не помогает в предсказании, то траты на её создание были оправданы лишь тогда, когда она выкидывается или изменяется так, чтобы таки начинать помогать в предсказании.
Если же модель не помогает предсказывать ничего и помочь не может, то она вредна. Вредна просто потому, что используя негодные модели, мы принимаем неоптимальные решения.
Получается, что "плохая" модель хуже отсутствия модели вообще, ведь в случае отсутствия модели вообще нам-таки придётся скорее всего подумать.
Я знаю такие примеры вредных моделей:
- DORA
- нумерология, френология
- юнгианские психотипы (DISC туда же)
- астрология и всякий human design
- theory x
а какие вредные модели знаете вы?
👍2
#оффтоп
🖼️ PHP Fart / gRPC / Protobuf
Посмотрел стрим ребят из PHP Fart про gRPC и Protobuf.
Как же я был счастлив, когда увидел нормальный генератор PHP классов по proto файлам: с нормальным конструктором, типизацией свойств, без лишних геттеров и сеттеров и без наследования огромного базового класса Message. Такие DTO теперь и не стыдно использовать, и прямых зависимостей от google/protobuf меньше, и вспомогательные инструменты будут считать класс “безпроблемным”.
Несколько лет назад было требование в одном из проектов работать с системой телефонии, которая предоставляла API только в protobuf формате. Тогда я и познакомился с этой штукой лицом к лицу.
Тоже бесили эти громоздкие файлы с кучей комментариев и отсутствием типизации, на которые вечно кричали различные линтеры и шторм. Если теперь и попадётся очередная интеграция с protobuf, то обязательно буду использовать их библиотеку, хоть она и не полностью независимая.
Советую и вам к использованию.
Кстати, надо бы в🖼️ Yii3 сделать поддержку этого генератора в Gii.
---
Теперь осталось, чтобы кто-нибудь написал нормальный генератор PHP классов по Open API спеке, а то там вообще мрак. Может когда-нибудь и сам доберусь до него, чтобы интегрировать в Yii Dev Panel и генерировать контракты несколькими кликами в UI.
---
Ссылка на стрим: https://www.youtube.com/watch?v=E61resEfgUE
Ссылка на канал: https://news.1rj.ru/str/php_fart
Когда досмотрел стрим увидел, что он был 3 месяца назад 😬
Посмотрел стрим ребят из PHP Fart про gRPC и Protobuf.
Как же я был счастлив, когда увидел нормальный генератор PHP классов по proto файлам: с нормальным конструктором, типизацией свойств, без лишних геттеров и сеттеров и без наследования огромного базового класса Message. Такие DTO теперь и не стыдно использовать, и прямых зависимостей от google/protobuf меньше, и вспомогательные инструменты будут считать класс “безпроблемным”.
Несколько лет назад было требование в одном из проектов работать с системой телефонии, которая предоставляла API только в protobuf формате. Тогда я и познакомился с этой штукой лицом к лицу.
Тоже бесили эти громоздкие файлы с кучей комментариев и отсутствием типизации, на которые вечно кричали различные линтеры и шторм. Если теперь и попадётся очередная интеграция с protobuf, то обязательно буду использовать их библиотеку, хоть она и не полностью независимая.
Советую и вам к использованию.
Кстати, надо бы в
---
Теперь осталось, чтобы кто-нибудь написал нормальный генератор PHP классов по Open API спеке, а то там вообще мрак. Может когда-нибудь и сам доберусь до него, чтобы интегрировать в Yii Dev Panel и генерировать контракты несколькими кликами в UI.
---
Ссылка на стрим: https://www.youtube.com/watch?v=E61resEfgUE
Ссылка на канал: https://news.1rj.ru/str/php_fart
Когда досмотрел стрим увидел, что он был 3 месяца назад 😬
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍6
#Пост №5. Про Open source
Open source – это идеология распространения программы таким образом, что любой желающий может увидеть её исходный код, внести изменения в исходный код и даже предложить это изменение авторам.
Open source – это место для тренировки коммуникативных и технических скиллов; место отдыха от рабочих проектов; место изучения новых технологий.
Open source – это желание улучшить мир.
Open source – это то, что ты можешь оставить после себя. Даже уйдя из IT.
Open source – это место обучения других.
Open source – это карма личности, популярность, уважение, открытые возможности.
Open source – это средство получить большую выгоду, жертвуя своей.
---
Как Open source может помочь Вам?
- Изучение новой технологии, с которой вы давно хотели поработать
- Изучение алгоритмов, которые используются в других проектах
- Изучение подходов и правил декомпозиции больших проектов, библиотек, фреймворков
- Подсмотреть лучшую версию компонента, который вы реализовали недавно
Архитектура? Шаблоны проектирования? Шаблоны программирования? Алгоритмы? Тесты? Документация? Системы сборки? Командные процессы? Внутренние договоренности? Всё это есть в открытом доступе, остается лишь дотянуться и начать становиться лучше.
Как вы можете помочь Open source?
- Ответ в Issue
- Проверка гипотезы
- Проверка бага
- Исправить баг
- Сделать Code review
- Написать фичу
- Поправить доку
- Добавить перевод
- Написать интеграцию
- Написать тест
- Предложить улучшения
- Добавить метрики
- Написать CI процесс
- Сделать замеры производительности
- Сделать инфографику
- Поддержите финансово
В Open source вы можете делать всё то, что вы умеете делать хорошо или всегда хотели начать делать.
Начните свою Open source жизнь прямо сейчас:
- Найдите репозиторий технологии / фреймворка / проекта, с которым чаще всего работаете
- Почитайте Issue, изучите проблемы или фича-запросы
- Углубитесь в кодовую базу, дайте ответ на проблему или подготовьте изменения в виде Pull Request
Сделав это несколько раз, могу предположить, вам однозначно понравится. Авторы будут вам благодарны за помощь, а комьюнити за развитие.
Open source – это не только про разработку непосредственно. Можно быть проджект менеджером, дизайнером, переводчиком, писателем документации, визионером или любой другой ролью
---
Если вы еще не знаете куда внести свой вклад, могу порекомендовать Yii3 😉
В Yii3 есть много репозиториев под различные цели. Если вы хотите сделать какую-то новую интеграцию и отдать её на поддержку в Yii, то напишите мне, я помогу вам это сделать.
Open source – это идеология распространения программы таким образом, что любой желающий может увидеть её исходный код, внести изменения в исходный код и даже предложить это изменение авторам.
Open source – это место для тренировки коммуникативных и технических скиллов; место отдыха от рабочих проектов; место изучения новых технологий.
Open source – это желание улучшить мир.
Open source – это то, что ты можешь оставить после себя. Даже уйдя из IT.
Open source – это место обучения других.
Open source – это карма личности, популярность, уважение, открытые возможности.
Open source – это средство получить большую выгоду, жертвуя своей.
---
Как Open source может помочь Вам?
- Изучение новой технологии, с которой вы давно хотели поработать
- Изучение алгоритмов, которые используются в других проектах
- Изучение подходов и правил декомпозиции больших проектов, библиотек, фреймворков
- Подсмотреть лучшую версию компонента, который вы реализовали недавно
Архитектура? Шаблоны проектирования? Шаблоны программирования? Алгоритмы? Тесты? Документация? Системы сборки? Командные процессы? Внутренние договоренности? Всё это есть в открытом доступе, остается лишь дотянуться и начать становиться лучше.
Как вы можете помочь Open source?
- Ответ в Issue
- Проверка гипотезы
- Проверка бага
- Исправить баг
- Сделать Code review
- Написать фичу
- Поправить доку
- Добавить перевод
- Написать интеграцию
- Написать тест
- Предложить улучшения
- Добавить метрики
- Написать CI процесс
- Сделать замеры производительности
- Сделать инфографику
- Поддержите финансово
В Open source вы можете делать всё то, что вы умеете делать хорошо или всегда хотели начать делать.
Начните свою Open source жизнь прямо сейчас:
- Найдите репозиторий технологии / фреймворка / проекта, с которым чаще всего работаете
- Почитайте Issue, изучите проблемы или фича-запросы
- Углубитесь в кодовую базу, дайте ответ на проблему или подготовьте изменения в виде Pull Request
Сделав это несколько раз, могу предположить, вам однозначно понравится. Авторы будут вам благодарны за помощь, а комьюнити за развитие.
Open source – это не только про разработку непосредственно. Можно быть проджект менеджером, дизайнером, переводчиком, писателем документации, визионером или любой другой ролью
---
Если вы еще не знаете куда внести свой вклад, могу порекомендовать Yii3 😉
В Yii3 есть много репозиториев под различные цели. Если вы хотите сделать какую-то новую интеграцию и отдать её на поддержку в Yii, то напишите мне, я помогу вам это сделать.
1👍4❤1🔥1
Не вспомню уже где услышал такую фразу, но звучит очень мотивирующе:
Компания каждый раз проводит перформанс ревью (360, 180 и прочие его подобия) – это некое тестирования тебя, насколько круто ты перформишь. Так почему ты не проводишь “Кеш ревью” – тестирование компании на предмет того, насколько по рынку она тебе платит?
Рост в IT – это не только в отметка CRM “Ваня – джун”, “Саша – мидл”, “Дима – сеньор”.
Рост в IT – это и ответственности, которые ты на себя берешь, и масштабы личности, которые ты растишь, и так же заработная плата, за которую ты тратишь своё личное время на развитие компании.
Развивать себя нужно самому и никогда не забывать про денежную составляющую. Личный рост отдельного человека никому не интересен, если он не придёт и не заберет его сам.
Please open Telegram to view this post
VIEW IN TELEGRAM
1💯2❤1
#оффтоп
Собеседование
Случайно в линке нашел пост, где человек на интервью "Senior React Developer" отказался решать задачки, комментируя тем, что "не знаю как решить".
Как оно там правда было не моё дело, но в комментах случайно зарубились с автором поста на тему следующего:
Я сказал, что считаю неуважением, когда тебе на позицию сеньора задают вопросы уровня джуна и дают соответствующие задачки на лайвкодинге.
Автор пытался меня убедить, что на интервью как раз такое и должно происходить, иначе "как понять, что ты сеньор разработчик, а не джун или сеньор gpt писатель промпта".
---
Бывает такое, что сеньоры валятся на сеньорских интервью, какие тут чат-гптшники уж.
Единственную мысль я бы хотел донести, что на процессе интервью нужно приходить с мыслью и целью партнёрства:
- Не вы должны компании, а вы нужны друг другу
- Не вы должны доказывать вашу компетентность, компания может подвергать её сомнению, а вы можете парировать.
Вы ведь не спрашиваете у компании о её годовых и квартальных доходах, количеству и качеству решенных задач за всё время. Спросить, конечно, вы можете, но ответ получите либо поверхностный, либо никакой.
Уйти с интервью, если вам не нравится общение или процесс интервью – это нормально. Так и нужно делать, если вас что-то не устраивает или вы считаете это неуважением к себе. Уважать нужно своё время, свои силы и навыки.
Если вы хотите пройти в компанию, о которой всегда мечтали, то можно и пожертвовать своим вкладом: и джуновские задачи порешать на интервью на сеньорскую позицию, и потратить ни один день на собесы, и на подготовку потратить месяц.
Не стоит возводить в максимализм это сообщение, но разделять тёплое и мягкое нужно научиться.
Собеседование
Случайно в линке нашел пост, где человек на интервью "Senior React Developer" отказался решать задачки, комментируя тем, что "не знаю как решить".
Как оно там правда было не моё дело, но в комментах случайно зарубились с автором поста на тему следующего:
Я сказал, что считаю неуважением, когда тебе на позицию сеньора задают вопросы уровня джуна и дают соответствующие задачки на лайвкодинге.
Автор пытался меня убедить, что на интервью как раз такое и должно происходить, иначе "как понять, что ты сеньор разработчик, а не джун или сеньор gpt писатель промпта".
---
Бывает такое, что сеньоры валятся на сеньорских интервью, какие тут чат-гптшники уж.
Единственную мысль я бы хотел донести, что на процессе интервью нужно приходить с мыслью и целью партнёрства:
- Не вы должны компании, а вы нужны друг другу
- Не вы должны доказывать вашу компетентность, компания может подвергать её сомнению, а вы можете парировать.
Вы ведь не спрашиваете у компании о её годовых и квартальных доходах, количеству и качеству решенных задач за всё время. Спросить, конечно, вы можете, но ответ получите либо поверхностный, либо никакой.
Уйти с интервью, если вам не нравится общение или процесс интервью – это нормально. Так и нужно делать, если вас что-то не устраивает или вы считаете это неуважением к себе. Уважать нужно своё время, свои силы и навыки.
Если вы хотите пройти в компанию, о которой всегда мечтали, то можно и пожертвовать своим вкладом: и джуновские задачи порешать на интервью на сеньорскую позицию, и потратить ни один день на собесы, и на подготовку потратить месяц.
Не стоит возводить в максимализм это сообщение, но разделять тёплое и мягкое нужно научиться.
1👍4
💾 Ретро 2023
#оффтоп
Этот год уже всё, давайте следующий.
Год подходит к концу и время подводить итоги: личная жизнь, здоровье, доходы, различные активности. Каюсь, в прошлом году было как-то лениво составлять планы, поэтому жил как жилось, но нажилось немало интересного. Расскажу урывками что случилось со мной за этот год:
✈️ Побывал в Турции, Грузии, России, Тайланде. Где-то несколько дней, где-то значительное время жил и живу
🦷 Вырвал зуб 6-ку, который года 3 был в ужасном состоянии
❤️ Завёл этот канал и нашел своих первых подписчиков
⭐ Начал больше времени уделять социальной части и медийки
🏍 Научился кататься на мотоцикле
📱 Купил экшен камеру и айфон
✂️ Научился делать резки и склейки в DaVinci
8️⃣ Поучаствовал в ~ 8-х разных проектах в качестве разработчика
📺 Посмотрел сотни фильмов
🎧 В Яндекс.Музыке прослушал почти 100 тысяч часов музыки
💲 Заработал десятки тысяч $$$
Ретроспектива состоит обычно из двух шагов, поэтому второй шаг будет с планами на новый 2024:
😬 Вставить зуб, а лучше 2
💯 Сделать тысячу подписчиков в телеграмме
📺 Запустить канал про IT мемы в Instagram / TikTok и набрать тысячу подписчиков там
👨🏫 Запустить серию обучающих уроков по приготовлению Yii3 на Youtube
🗺 Определиться с местом для постоянного места жительства
👫 Наладить личную жизнь
💪 Заменить пивное пузо спортивными кубиками пресса
🤑 Найти дополнительный источник заработка, помимо основной работы
🐈 Завести кота
🖼️ Зарелизить Yii3
🤑 Начать зарабатывать $10 000/month
Пока так, дальше буду делить подробнее, приоритезировать, фильтровать и ставить чекпоинты.
А вы ставите цели на год и следите за прогрессом время от времени? 😉
С наступающим новым 2024 годом!
——
Передаю эстафету ретро Александру Макарову и Олегу Мифле
#оффтоп
Год подходит к концу и время подводить итоги: личная жизнь, здоровье, доходы, различные активности. Каюсь, в прошлом году было как-то лениво составлять планы, поэтому жил как жилось, но нажилось немало интересного. Расскажу урывками что случилось со мной за этот год:
⭐ Начал больше времени уделять социальной части и медийки
🏍 Научился кататься на мотоцикле
✂️ Научился делать резки и склейки в DaVinci
8️⃣ Поучаствовал в ~ 8-х разных проектах в качестве разработчика
Ретроспектива состоит обычно из двух шагов, поэтому второй шаг будет с планами на новый 2024:
👨🏫 Запустить серию обучающих уроков по приготовлению Yii3 на Youtube
👫 Наладить личную жизнь
Пока так, дальше буду делить подробнее, приоритезировать, фильтровать и ставить чекпоинты.
А вы ставите цели на год и следите за прогрессом время от времени? 😉
С наступающим новым 2024 годом!
——
Передаю эстафету ретро Александру Макарову и Олегу Мифле
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍6🔥1
Хэндлим тему | Дерепко
💾 Ретро 2023 #оффтоп Этот год уже всё, давайте следующий. Год подходит к концу и время подводить итоги: личная жизнь, здоровье, доходы, различные активности. Каюсь, в прошлом году было как-то лениво составлять планы, поэтому жил как жилось, но нажилось…
This media is not supported in your browser
VIEW IN TELEGRAM
#мем
Пока я отдыхаю и снимаю тиктоки, как могу, нашел мем, который прям в тему.
Надеюсь мем соврет в этом году 😉
Пока я отдыхаю и снимаю тиктоки, как могу, нашел мем, который прям в тему.
Надеюсь мем соврет в этом году 😉
👍1😁1
Календарь, как смысл жизни
#пост №6.
Как-то случайно набрёл на статью одного из моих прошлых коллег про календарь. Статья занятная. Автор крутой.
Как обычно, телега не может засунуть больше 2 тысяч символов в мое сообщение, поэтому выкинул пост в телеграф: https://telegra.ph/Kalendar-kak-smysl-zhizni-01-23
#пост №6.
Как-то случайно набрёл на статью одного из моих прошлых коллег про календарь. Статья занятная. Автор крутой.
Как обычно, телега не может засунуть больше 2 тысяч символов в мое сообщение, поэтому выкинул пост в телеграф: https://telegra.ph/Kalendar-kak-smysl-zhizni-01-23
Telegraph
Календарь, как смысл жизни
Нет, это не мой календарь. Это календарь Миши Донского. С ним мне удалось поработать в Skyeng. Честно говоря, всеми прелестями календаря я начал пользоваться именно там. Тогда я и увидел, как Миша уже начинал это делать. Помимо Миши таким занимались большинство…
1👍4
Тестирования функций из стандартной библиотеки PHP и не только
#пост №7
Цель
Подмена (mock) функций, которые уже “загружены” в PHP еще до подгрузки Composer Autoloader, каких-либо include или других
Подмена не только из под не пустого namespace
Проблема
Если объявить функцию с именем, которая уже существует в стандартной библиотеке PHP, то получим ошибку, что такая функция уже существует и переопределить её нельзя.
Можно было бы “выгрузить” её из памяти, но увы, выгружать из памяти функции в PHP нельзя.
Можно лишь переопределить функцию до её непосредственного объявления. Но такой способ не подходит, потому что функция уже объявлена при лю
Ресерч
В php.ini можно
Если использовать это
Это и логичн
Если объявить функцию самостоятельно, то ошибки больше не будет:
```shell
❯ php -ddisable_functions=time -r "function time() { return 123; } echo time();"
123%
```
Бинго!
Помещаем объявление функции в библиотеку, создаем State manager, через которого сможем управлять возвращаемым значение “123” и делаем пользователю интерфейс взаимодействия с этим менеджером.
Теперь, если пользователь захочет протестировать
Но как быть, если нужно протестировать измененную фу
Можно так и сделать: State manager создает для всех тестов функцию, которая эмулирует станда
Вроде всё логично и понятно. Можно накодить и наслаждаться тестированием.
Однако, а как эмулировать системное время? Если с различными полифилами от symfony всё понятно: можно создать какую-то функцию, которая будет базировать на другой функции, преобразовывать результат под новый формат и отдавать его.
Но на какой функции нужно базировать вре
Bash! 🤪
PHP имеет возможность в любое время обратиться к своему старшему брату-башу простыми обратными кавыч
Для ан
Значит для State manager осталось написать только возможность использовать не статичное значение, а функцию, которая каждый раз будет выполняться.
Всё это и не только сделано в библиотеке xepozz/internal-mocker
Читаем доку по установке и первичной настройке, добавляем нужные файлы, вписываем следующую конфигурацию:
——
Если кто-то писал свои костыли или специально убирал
——
Описание disable-functions: https://www.php.net/manual/en/ini.core.php#ini.disable-functions
Internal mocker: https://github.com/xepozz/internal-mocker/
#пост №7
Цель
Подмена (mock) функций, которые уже “загружены” в PHP еще до подгрузки Composer Autoloader, каких-либо include или других
объвлений function name(){} Подмена не только из под не пустого namespace
, например App\Service\name , но и из корневого namespace: проще всего это сделать через use function name;Проблема
Если объявить функцию с именем, которая уже существует в стандартной библиотеке PHP, то получим ошибку, что такая функция уже существует и переопределить её нельзя.
Можно было бы “выгрузить” её из памяти, но увы, выгружать из памяти функции в PHP нельзя.
Можно лишь переопределить функцию до её непосредственного объявления. Но такой способ не подходит, потому что функция уже объявлена при лю
бом вызове php .Ресерч
В php.ini можно
найти флаг disable_functions , которая принимает список имен функций, которые нужно “не объявлять” в недрах PHP.Если использовать это
т флаг, то php -ddisable_functions=time -r "echo time();" выкинет ошибку:
❯ php -ddisable_functions=time -r "echo time();"
PHP Fatal error: Uncaught Error: Call to undefined function time() in Command line code:1
Stack trace:
#0 {main}
thrown in Command line code on line 1
Fatal error: Uncaught Error: Call to undefined function time() in Command line code on line 1
Error: Call to undefined function time() in Command line code on line 1
Call Stack:
0.0000 389568 1. {main}() Command line code:0
Это и логичн
о. Функции time больше нет. Но теперь ведь можно создать её самостоятельно?Если объявить функцию самостоятельно, то ошибки больше не будет:
```shell
❯ php -ddisable_functions=time -r "function time() { return 123; } echo time();"
123%
```
Бинго!
Помещаем объявление функции в библиотеку, создаем State manager, через которого сможем управлять возвращаемым значение “123” и делаем пользователю интерфейс взаимодействия с этим менеджером.
Теперь, если пользователь захочет протестировать
вызов time , то сможем самостоятельно указать требуемые значения. Время в будущем, в прошлом, 0, false, что угодно.Но как быть, если нужно протестировать измененную фу
нкцию time лишь в одном тесте, а в других местах оставить всё как есть?Можно так и сделать: State manager создает для всех тестов функцию, которая эмулирует станда
ртную time , а в нужном тесте наложить на общую эмуляцию частную. Вроде всё логично и понятно. Можно накодить и наслаждаться тестированием.
Однако, а как эмулировать системное время? Если с различными полифилами от symfony всё понятно: можно создать какую-то функцию, которая будет базировать на другой функции, преобразовывать результат под новый формат и отдавать его.
Но на какой функции нужно базировать вре
мя?
DateTime`* классы? `date() ? mktime ? hrtime ? А если их тоже отключить нужно?Bash! 🤪
PHP имеет возможность в любое время обратиться к своему старшему брату-башу простыми обратными кавыч
ками: `command` . Результат будет строкой, но всегда можно "кастануть". Для ан
алога time() команда `date +%s` .Значит для State manager осталось написать только возможность использовать не статичное значение, а функцию, которая каждый раз будет выполняться.
Всё это и не только сделано в библиотеке xepozz/internal-mocker
Читаем доку по установке и первичной настройке, добавляем нужные файлы, вписываем следующую конфигурацию:
$mocker = new Mocker();
$mocker->load([
[
'namespace' => '',
'name' => 'time',
'function' => fn () => `date +%s`,
],
]);
MockerState::saveState();
——
Если кто-то писал свои костыли или специально убирал
use function из файлов, чтобы подменять функции в нужном namespace, теперь можете избавиться от них и заменить это на подключение библиотеки и небольшой конфиг.——
Описание disable-functions: https://www.php.net/manual/en/ini.core.php#ini.disable-functions
Internal mocker: https://github.com/xepozz/internal-mocker/
1👍13
Хэндлим тему | Дерепко
Тестирования функций из стандартной библиотеки PHP и не только #пост №7 Цель Подмена (mock) функций, которые уже “загружены” в PHP еще до подгрузки Composer Autoloader, каких-либо include или других объвлений function name(){} Подмена не только из под…
Решил превратить пост дополнительно в статью на хабре: https://habr.com/ru/articles/797343/
Планирую еще один пост написать про Advanced Usage этой штуки. Понимаю, что читать огромную доку мало кому будет интересно, а разобрать примеры и найти свой кейс будет самое лучшее для читателя.
Посты на индексируемом пространстве: хабр, медиум и прочие большие ресурсы хорошо подходят для продвижения твоих статей:
- матч по ключевым словам из поисковиков
- cross-reference от статьи к статье, по ссылкам внутри статьи
- знакомство с “чужой” аудиторией
- большая ротируемость просмотров
Выкладывать один и тот же текст на разные ресурсы – это очень грамотное продвижение. Но мне пока лень 🙂
——
Кстати, этот инструмент помог в Jetbrains php stubs исправить пару недочетов: раз и два.
А еще он хорошо подошел для тестирования функции
Планирую еще один пост написать про Advanced Usage этой штуки. Понимаю, что читать огромную доку мало кому будет интересно, а разобрать примеры и найти свой кейс будет самое лучшее для читателя.
Посты на индексируемом пространстве: хабр, медиум и прочие большие ресурсы хорошо подходят для продвижения твоих статей:
- матч по ключевым словам из поисковиков
- cross-reference от статьи к статье, по ссылкам внутри статьи
- знакомство с “чужой” аудиторией
- большая ротируемость просмотров
Выкладывать один и тот же текст на разные ресурсы – это очень грамотное продвижение. Но мне пока лень 🙂
——
Кстати, этот инструмент помог в Jetbrains php stubs исправить пару недочетов: раз и два.
А еще он хорошо подошел для тестирования функции
flush() в Yii3.Хабр
Подмена функций стандартной библиотеки PHP с помощью xepozz/internal-mocker
Цель Подмена (mock) функций, которые уже “загружены” в PHP еще до подгрузки Composer Autoloader, каких-либо include или других объвлений function name() {} Подмена не только из под не пустого...
🔥9👍2
Параллельные вычисления на PHP
#пост
Как сделать 1 000 HTTP запросов за 8 секунд?
А отправить миллион писем за 2 минуты?
А если без брокеров очередей и баз?
Сначала думал, что
Пощупал
Но я нашел проблему – документация практически отсутствует.
Как обычно, много текста в пост не влезло, поэтому закинул в телеграф:
https://telegra.ph/Parallelnye-vychisleniya-na-PHP-03-05
Да, здесь не про параллельные вычисления, но я захотел так назвать пост 😉
Если понадобится, могу поделиться полными результатами сравнения работы
——
А пробовали ли вы асинхронные фреймворки?
@handle_topic
#пост
Как сделать 1 000 HTTP запросов за 8 секунд?
А отправить миллион писем за 2 минуты?
А если без брокеров очередей и баз?
Сначала думал, что
pcntl будет хорошим вариантом, но позже передумал. Пощупал
AMPHP и очень понравилось. Код выглядит максимально привычным, никаких расширений ставить не нужно, поддержка composer и всё типизировано. Но я нашел проблему – документация практически отсутствует.
Как обычно, много текста в пост не влезло, поэтому закинул в телеграф:
https://telegra.ph/Parallelnye-vychisleniya-na-PHP-03-05
Да, здесь не про параллельные вычисления, но я захотел так назвать пост 😉
Если понадобится, могу поделиться полными результатами сравнения работы
pcntl vs amphp: Генерировал 1 000 000 итераций, которые со случайной задержкой 1–10 сек. должны были выполнить операцию.——
А пробовали ли вы асинхронные фреймворки?
@handle_topic
Telegraph
Параллельные вычисления на PHP
Недавно попалась задача сделать параллельные расчеты без использования внешних сервисов вроде Redis, RabbitMQ, Database и прочие. PCNTL Первое решение, которое пришло в голову – форк процесса через pcntl расширение для PHP. На первый взгляд это выглядит очень…
1🔥12👍3
Управление форматом ответов
#пост
Недавно в чате Yii Флудилочная @Kutuzov_ska столкнулся с проблемой разных ответов в dev и prod окружениях приложения на фреймворке Symfony. О проблеме можно почитать здесь.
Development
Как правило, когда мы разрабатываем приложение, мы хотим видеть как можно подробнее причину поломки нашего кода:
- Текст сообщения
- Файл, строку и код, где произошла поломка
- Stacktrace от точки входа в приложения до этой самой строчки
- Значения переменных, аргументов функций и прочее.
Обычно приложения с обработчиком исключений и ошибок это и делают: рисуют красивый UI, рисуют сниппет с ошибой и подсвечивают нужную строчку.
Даже в JSON API многие приложения конвертируют всё в JSON представление и клиенты этого API могут увидеть полный текст ошибки, stacktrace и т.п.
Production
Однако, в продакшене такое делать непозволительно опасно:
- Тексты ошибки дают злоумышленникам возможно эксплуатировать ваше приложение и найти уязвимости
- Stacktrace может раскрыть вашу внутреннюю структуру приложения
- Значения переменных могут раскрыть ваши данные для доступа к тем или иным сервисам
Чтобы такого не происходило, хорошей практикой считается сокрытие всех подробностей ошибки или исключения в конечном ответе, а залогировать ошибку можно “как есть”, считая безопасным попадания в систему сбора логов.
О надежности последнего можно говорить много, однако я бы хотел сделать упор на текст ошибки, выводимый в тело ответа.
Для клиентов API порой удобно завязаться на текст ошибки и сделать какое-то конкретное действие:
- Подождать какое-то время и отправить запрос заново
- Показать текст ошибки пользователю
- Выполнить какую-то логику, основываясь на тексте ошибки
Конечно, можно завязаться на HTTP код ответа и выполнять нужное действия, основываясь на значении этого кода, но текст ошибки иногда тоже приходится задействовать.
Чтобы ваш клиент не показал пользователю ошибку
Стоит как-то разделять текст, который можно показать пользователю и текст, который стоит скрыть за стандартным текстом HTTP кода:
Обработчик ошибок
Такое разделение, как правило, делают на стороне формирования этой ошибки – в нашем случае на бекенде.
В Yii2 есть концепция HttpException: есть несколько базовых классов, отражающие соответствующий HTTP код исключения и возможность задать свой текст ошибки, который увидит клиент. Подробнее можно почитать здесь: ссылка на документацияю.
В Symfony приложениях тоже есть аналогичный подход.
Exception Mapper
В своих проектах я предпочитаю написать свой mapper исключений в выводимый ответ:
- Создаю класс, который встраивается в логику обработки исключений
- Сформирует нужный мне формат ответа с дополнительными кодами и текстами
- Будет заниматься прочими удобствами для development окружения
Похожая схема есть и в Yii3: ссылка на документацию.
В Yii3 http stack построен на базе PSR middleware, поэтому нужно лишь добавить middleware в стек и настроить класс формирования ошибок.
В Symfony http stack построен на событийной модели, и для похожего действия нужно написать свой обработчик события
В Symfony приложениях я создаю несколько интерфейсов-маркеров, который могут задавать кастомный текст ошибки, который сможет увидеть клиент. Все остальные ошибки скрывают все свои детали.
Выглядит такой обработчик примерно так: ссылка на gist.
Имея собственный обработчик, этого позволяет мне внедрять множество коротких путей в разработке, уменьшая boilerplate кодовой базы. Выглядит очень просто и всегда можно изменить массово под требования.
——
Полезные ссылки:
List of http status codes
Yii Флудилочная
@handle_topic
#пост
Недавно в чате Yii Флудилочная @Kutuzov_ska столкнулся с проблемой разных ответов в dev и prod окружениях приложения на фреймворке Symfony. О проблеме можно почитать здесь.
Development
Как правило, когда мы разрабатываем приложение, мы хотим видеть как можно подробнее причину поломки нашего кода:
- Текст сообщения
- Файл, строку и код, где произошла поломка
- Stacktrace от точки входа в приложения до этой самой строчки
- Значения переменных, аргументов функций и прочее.
Обычно приложения с обработчиком исключений и ошибок это и делают: рисуют красивый UI, рисуют сниппет с ошибой и подсвечивают нужную строчку.
Даже в JSON API многие приложения конвертируют всё в JSON представление и клиенты этого API могут увидеть полный текст ошибки, stacktrace и т.п.
Production
Однако, в продакшене такое делать непозволительно опасно:
- Тексты ошибки дают злоумышленникам возможно эксплуатировать ваше приложение и найти уязвимости
- Stacktrace может раскрыть вашу внутреннюю структуру приложения
- Значения переменных могут раскрыть ваши данные для доступа к тем или иным сервисам
Чтобы такого не происходило, хорошей практикой считается сокрытие всех подробностей ошибки или исключения в конечном ответе, а залогировать ошибку можно “как есть”, считая безопасным попадания в систему сбора логов.
О надежности последнего можно говорить много, однако я бы хотел сделать упор на текст ошибки, выводимый в тело ответа.
Для клиентов API порой удобно завязаться на текст ошибки и сделать какое-то конкретное действие:
- Подождать какое-то время и отправить запрос заново
- Показать текст ошибки пользователю
- Выполнить какую-то логику, основываясь на тексте ошибки
Конечно, можно завязаться на HTTP код ответа и выполнять нужное действия, основываясь на значении этого кода, но текст ошибки иногда тоже приходится задействовать.
Чтобы ваш клиент не показал пользователю ошибку
Fatal error: Uncaught TypeError: find(): Argument #1 ($id) must be of type int, string given
Стоит как-то разделять текст, который можно показать пользователю и текст, который стоит скрыть за стандартным текстом HTTP кода:
Internal server error, Bad request и другие.Обработчик ошибок
Такое разделение, как правило, делают на стороне формирования этой ошибки – в нашем случае на бекенде.
В Yii2 есть концепция HttpException: есть несколько базовых классов, отражающие соответствующий HTTP код исключения и возможность задать свой текст ошибки, который увидит клиент. Подробнее можно почитать здесь: ссылка на документацияю.
В Symfony приложениях тоже есть аналогичный подход.
Exception Mapper
В своих проектах я предпочитаю написать свой mapper исключений в выводимый ответ:
- Создаю класс, который встраивается в логику обработки исключений
- Сформирует нужный мне формат ответа с дополнительными кодами и текстами
- Будет заниматься прочими удобствами для development окружения
Похожая схема есть и в Yii3: ссылка на документацию.
В Yii3 http stack построен на базе PSR middleware, поэтому нужно лишь добавить middleware в стек и настроить класс формирования ошибок.
В Symfony http stack построен на событийной модели, и для похожего действия нужно написать свой обработчик события
onKernelException.В Symfony приложениях я создаю несколько интерфейсов-маркеров, который могут задавать кастомный текст ошибки, который сможет увидеть клиент. Все остальные ошибки скрывают все свои детали.
Выглядит такой обработчик примерно так: ссылка на gist.
Имея собственный обработчик, этого позволяет мне внедрять множество коротких путей в разработке, уменьшая boilerplate кодовой базы. Выглядит очень просто и всегда можно изменить массово под требования.
——
Полезные ссылки:
List of http status codes
Yii Флудилочная
@handle_topic
1👍5🔥2
Remap – гидрация результатов sql запросов с преобразованием
#пост
Довольно часто мне приходилось делать raw sql запросы в БД для получения данных. Причин тому было несколько:
- Так быстрее
- Не нужно писать длинные билдеры
- Запрос часто менялся, проще всего переносить as-is из требований в код
- Подсветка синтаксиса в IDE
- Удобная отладка: скопировал в DB Viewer и запускаешь
- И многое другое
Зачастую в проекте уже была какая-нибудь ORM или Active Record, где всегда результат запроса был объектом с необходимыми свойствами и типами.
Однако работа с raw sql обычно заканчивалась перегоном массивом из одного метода в другой.
Это неудобно:
- Нет типизации параметров функции –
- Нет типизации свойств –
- Нет понятия наличия свойства в массиве вообще –
Как-то давно общаясь в чате про Active Record в Yii3 ко мне пришло озарение, что AR – это всё еще сложно – нужно наследоваться от базового класса или подключать trait, где-то доставать фабрики и самое главное, всё равно raw sql не смапить в модельку.
К тому моменту hydrator из Yii3 был почти готов и я решил сделать Proof Of Concept обычного data-mapper, с использовать db и hydrator.
Вот что из этого вышло:
Remap
Библиотека содержит лишь 1 класс и делегирует работу по исполнению запроса в yiisoft/db. Создание объекта и его наполнение библиотека делегирует в yiisoft/hydrator.
Таким образом, логика выглядит линейной и понятной:
1. Выполняет raw sql запрос
2. Проходим построчно по результату запроса
3. Создаем DTO и наполняем его нужными полями
Всё это скрыто в методе
Пример работы с библиотекой:
Метод принимает первым аргументов класс, который нужно будет создать и наполнить.
Второй и третий аргументы – сам запрос и параметры для подстановки. Можно передать во второй параметр
Метод возвращает
Как вариант использования библиотеки я сразу подметил, что удобно было бы использовать класс, как AR и Query Builder, поэтому с легкостью вышеупомянутый пример можно превратить в следующее:
Использовать можно по-разному, поэтому для еще большего упрощения записи можно написать следующее:
Статические методы в
-
-
А использование yiisoft/hydrator позволило использовать Attributes для произведения дополнительных трансформаций. Например:
Таким образом, результат запроса можно преобразовать под нужные конвенции объектов и не зависеть от устройства внешнего хранилища.
Причесал библиотеку, написал тесты, подкрутил Psalm на 1 уровень, тегнул 1.0.
Надеюсь эта библиотека поможет и вам. Буду рад любым предложениям по улучшению.
——
Полезные ссылки:
Remap
Использование атрибутов yiisoft/hydrator
@handle_topic
#пост
Довольно часто мне приходилось делать raw sql запросы в БД для получения данных. Причин тому было несколько:
- Так быстрее
- Не нужно писать длинные билдеры
- Запрос часто менялся, проще всего переносить as-is из требований в код
- Подсветка синтаксиса в IDE
- Удобная отладка: скопировал в DB Viewer и запускаешь
- И многое другое
Зачастую в проекте уже была какая-нибудь ORM или Active Record, где всегда результат запроса был объектом с необходимыми свойствами и типами.
Однако работа с raw sql обычно заканчивалась перегоном массивом из одного метода в другой.
Это неудобно:
- Нет типизации параметров функции –
array $data- Нет типизации свойств –
$data['user_id'] – int/string?- Нет понятия наличия свойства в массиве вообще –
$data['unknown_prop'] – ошибка, которую найдешь только при выполнении кодаКак-то давно общаясь в чате про Active Record в Yii3 ко мне пришло озарение, что AR – это всё еще сложно – нужно наследоваться от базового класса или подключать trait, где-то доставать фабрики и самое главное, всё равно raw sql не смапить в модельку.
К тому моменту hydrator из Yii3 был почти готов и я решил сделать Proof Of Concept обычного data-mapper, с использовать db и hydrator.
Вот что из этого вышло:
Remap
Библиотека содержит лишь 1 класс и делегирует работу по исполнению запроса в yiisoft/db. Создание объекта и его наполнение библиотека делегирует в yiisoft/hydrator.
Таким образом, логика выглядит линейной и понятной:
1. Выполняет raw sql запрос
2. Проходим построчно по результату запроса
3. Создаем DTO и наполняем его нужными полями
Всё это скрыто в методе
Remap::map() Пример работы с библиотекой:
final class Todo
{
public int $id;
public string $noscript;
public int $status;
public int $created_at;
}
$sql = 'SELECT id, noscript, status, created_at FROM todo WHERE id = :id LIMIT 1';
$params = ['id' => 1];
$remap->map(Todo::class, $sql, $params);
Remap::map() Метод принимает первым аргументов класс, который нужно будет создать и наполнить.
Второй и третий аргументы – сам запрос и параметры для подстановки. Можно передать во второй параметр
string $sql , а в третий array $params , а можно сразу во второй передать [$sql, $params] Метод возвращает
\Generator объектов. Это позволит обрабатывать большие объемы результатов запроса и не падать с нехваткой памяти.Как вариант использования библиотеки я сразу подметил, что удобно было бы использовать класс, как AR и Query Builder, поэтому с легкостью вышеупомянутый пример можно превратить в следующее:
$remap->map(Todo::class, Todo::selectOne($id));
$remap->map(Todo::class, Todo::selectAll());
Использовать можно по-разному, поэтому для еще большего упрощения записи можно написать следующее:
$remap->map(...Todo::selectAll());
Статические методы в
Todo в текущих примерах будут возвращать массив из нужных значений:-
[$sql, $params] в первом примере-
[self::class, $sql, $params] во втором примереА использование yiisoft/hydrator позволило использовать Attributes для произведения дополнительных трансформаций. Например:
final class TodoModelHydrator
{
#[Data('id')] // В свойство $identifier запишется то, что лежит в id свойстве
public string $identifier; // дополнительно cast from int -> to string
#[Data('noscript')] // noscript -> text
public string $text;
public string $status; // int -> string
#[Data('created_at')] // created_at -> date_created
public string $date_created; // int -> string
}
Таким образом, результат запроса можно преобразовать под нужные конвенции объектов и не зависеть от устройства внешнего хранилища.
Причесал библиотеку, написал тесты, подкрутил Psalm на 1 уровень, тегнул 1.0.
Надеюсь эта библиотека поможет и вам. Буду рад любым предложениям по улучшению.
——
Полезные ссылки:
Remap
Использование атрибутов yiisoft/hydrator
@handle_topic
GitHub
GitHub - xepozz/remap: The library allows you to map data from the database to objects.
The library allows you to map data from the database to objects. - xepozz/remap
1👍11🔥7
#оффтоп
Хороший кейс, почему нужно писать свои программы быстро :)
Разбор, конечно, очень поверхностный, но сама история довольно интересная. Рекомендую к прочтению.
Хороший кейс, почему нужно писать свои программы быстро :)
Разбор, конечно, очень поверхностный, но сама история довольно интересная. Рекомендую к прочтению.
👍2
Forwarded from Авва
В мире компьютерной безопасности сегодня интересный день. Точнее, он начался вчера вечером, когда немецкий разработчик Андрес Фройнд опубликовал отчет о тайной лазейке (бэкдор), которую он обнаружил в новых версиях широко используемой библиотеки для сжатия liblzma (часть архиватора xz). Лазейка позволяет взломщикам заходить через SSH на системы, в которых установлены эти новые версии - к счастью, похоже, что это всего несколько дистрибутивов Линукса в их до-релизовых версиях.
Всех очень впечатлило, насколько эта лазейка была сделана хитро, и как взломщик или взломщики серьезно поработали над тем, чтобы замести следы:
- взломщик под именем/псевдонимом Jia Tan почти два года (!) участвовал в разработке опенсорсного пакета xz, завоевал доверие его мейнтейнеров и получил доступ к прямому коммиту в его репозиторию. Он сделал больше 700 коммитов, лишь малая часть которых медленно подготовила код для лазейки
- основной код лазейки спрятан в тестовых файлах проекта (примеры "плохих" и "хороших" архивов)
- исходный код, который включает лазейку в собственно библиотеку, вообще не является частью основной репозитории в Github. Он спрятан в тар-архивах двух последних релизов, которые обычно используются мейнтейнерами дистрибутивов. То есть есть таг релиза, есть архив, якобы собранный из репозитории в момент этого тага, но на самом деле в нем есть крохотная добавка; в самой репозитории ее нет
- эта добавка прячется в конфигурационной магии autoconf, которую все ненавидят лютой ненавистью и никто никогда не заглядывает внутрь
- она проверяет, когда исходники конфигурируют именно для постройки дебиан-пакета или RPM-пакета (т.е. то, что будут делать мейтейнеры дистрибутивов), и только в этом случае вынимает из тестовых файлов определенные куски и добавляет в код библиотеки
- внутри библиотеки код лазейки заменяет несколько функций, которые работают с символьными таблицами библиотек во время их подгружения. Затрачены специальные усилия, чтобы имена функций не появлялись в двоичном коде. Что именно дальше делает код лазейки, до конца еще не ясно, но он обрабатывает сам символьные таблицы библиотек, и видимо находит то, что имеет отношение к SSH серверу, и что-то там заменяет. Это еще проверяют сейчас.
- интересно, что openssh, стандартный SSH-сервер под линуксом, не использует библиотеку liblzma, в которую вставили эту лазейку, но несколько популярных дистрибутивов добавляют в него поддержку уведомлений системы, systemd, а библиотека libsystemd уже в свою очередь использует liblzma.
- после того, как вышли версии библиотеки с ошибкой, несколько разных людей с незамеченными до того именами (очевидно, альты взломщика или сообщники) стали открывать запросы в разных программах и пакетах сделать апгрейд на эти новые версии, и в некоторых случаях преуспели
Взломщик допустил только одну ошибку: код лазейки, когда он работает как часть openssh, довольно медленно обрабатывает эти символьные таблицы, или что он еще там делает, и даже неудачная попытка логина на такую систему занимает на полсекунды дольше, чем обычно. Андрес Фройнд заметил эти полсекунды задержки. Они его раздражали. Он решил найти, какой новый баг к этому приводит, и нашел эту лазейку.
Если бы все происходило быстро и не было задержки в полсекунды, очень может быть, что это не заметили бы месяцы и годы, и этот код попал бы в основные дистрибутивы, в версии Линукса, которые запускаются у основных облачных провайдеров итд. Они реально очень, ОЧЕНЬ хорошо замели следы.
Теперь все думают, что надо было/надо теперь делать по-другому, и как обнаружить следующую лазейку такого типа - или предыдущую, если она уже есть и никто не знает! - не опираясь на удачу и героическую занудливость Андреаса Фройнда.
Всех очень впечатлило, насколько эта лазейка была сделана хитро, и как взломщик или взломщики серьезно поработали над тем, чтобы замести следы:
- взломщик под именем/псевдонимом Jia Tan почти два года (!) участвовал в разработке опенсорсного пакета xz, завоевал доверие его мейнтейнеров и получил доступ к прямому коммиту в его репозиторию. Он сделал больше 700 коммитов, лишь малая часть которых медленно подготовила код для лазейки
- основной код лазейки спрятан в тестовых файлах проекта (примеры "плохих" и "хороших" архивов)
- исходный код, который включает лазейку в собственно библиотеку, вообще не является частью основной репозитории в Github. Он спрятан в тар-архивах двух последних релизов, которые обычно используются мейнтейнерами дистрибутивов. То есть есть таг релиза, есть архив, якобы собранный из репозитории в момент этого тага, но на самом деле в нем есть крохотная добавка; в самой репозитории ее нет
- эта добавка прячется в конфигурационной магии autoconf, которую все ненавидят лютой ненавистью и никто никогда не заглядывает внутрь
- она проверяет, когда исходники конфигурируют именно для постройки дебиан-пакета или RPM-пакета (т.е. то, что будут делать мейтейнеры дистрибутивов), и только в этом случае вынимает из тестовых файлов определенные куски и добавляет в код библиотеки
- внутри библиотеки код лазейки заменяет несколько функций, которые работают с символьными таблицами библиотек во время их подгружения. Затрачены специальные усилия, чтобы имена функций не появлялись в двоичном коде. Что именно дальше делает код лазейки, до конца еще не ясно, но он обрабатывает сам символьные таблицы библиотек, и видимо находит то, что имеет отношение к SSH серверу, и что-то там заменяет. Это еще проверяют сейчас.
- интересно, что openssh, стандартный SSH-сервер под линуксом, не использует библиотеку liblzma, в которую вставили эту лазейку, но несколько популярных дистрибутивов добавляют в него поддержку уведомлений системы, systemd, а библиотека libsystemd уже в свою очередь использует liblzma.
- после того, как вышли версии библиотеки с ошибкой, несколько разных людей с незамеченными до того именами (очевидно, альты взломщика или сообщники) стали открывать запросы в разных программах и пакетах сделать апгрейд на эти новые версии, и в некоторых случаях преуспели
Взломщик допустил только одну ошибку: код лазейки, когда он работает как часть openssh, довольно медленно обрабатывает эти символьные таблицы, или что он еще там делает, и даже неудачная попытка логина на такую систему занимает на полсекунды дольше, чем обычно. Андрес Фройнд заметил эти полсекунды задержки. Они его раздражали. Он решил найти, какой новый баг к этому приводит, и нашел эту лазейку.
Если бы все происходило быстро и не было задержки в полсекунды, очень может быть, что это не заметили бы месяцы и годы, и этот код попал бы в основные дистрибутивы, в версии Линукса, которые запускаются у основных облачных провайдеров итд. Они реально очень, ОЧЕНЬ хорошо замели следы.
Теперь все думают, что надо было/надо теперь делать по-другому, и как обнаружить следующую лазейку такого типа - или предыдущую, если она уже есть и никто не знает! - не опираясь на удачу и героическую занудливость Андреаса Фройнда.
1🔥6👍3😱3😁1