Прочитал забавную статью про mutation driven testing.
Прежде чем рассказать об этом подходе сначала в двух словах объясню, что такое мутационное тестирование вообще. Для тех, кто не в курсе.
Когда вы пишете тесты, по TDD или нет, даже с формальным 100% покрытием, вы никогда не будете уверены в том, что в коде на самом деле протестировано всё. Например, можно банально ошибиться в вызове assert в самом тесте. Или не учесть детали преобразования типов, что никак не повлияет на coverage.
Чтобы убедиться в том, что тесты реально тестируют, есть такой способ: самому вносить в код баги, и смотреть, валятся ли от этого тесты. Если тесты по-прежнему зелёные при явном баге, значит протестировано не всё.
Например, заменили плюс на минус, или добавили "не" к условию, и смотрите.
Обычно это делают в очень ответственных областях программирования, где ошибки вообще не допустимы. Например, софт марсохода или медицинское ПО.
Конечно в марсоходостроении это все делается автоматически: специальный инструмент уродует вашу программу и смотрит, слетели ли тесты.
Проблема в этом подходе в том, что это довольно муторно настраивается, много нюансов, как описать, что надо мутировать, что нет. И всё это потребляет дикое количество ресурсов: разбор кода в AST, мутирование и обратное преобразование.
Автор статьи предлагает подход, аналогичный TDD, но как бы наоборот и совсем другой 🙂
1) сначала добавляете новый код в проект
2) временно вносите в какие-то строки баг
3) пишете тест, который ловит этот баг
Для меня такой подход видится интересным тем, что можно ничего не настраивать в CI, не просить выделить доп ресурсы для обработки пайплайнов, а просто писать полностью покрытый код, даже если тимлиду или вообще никому в твоей команде в целом такой подход неинтересен.
Конечно, это не бесплатно, и пожирает ресурсы программиста. Имхо mutation driven testing можно и нужно применять только там, где есть ответственная логика. Работа с деньгами, медицинский софт и т.д. Понятно, что на эндпоинт, выдающий текущую погоду или прочую ерунду, можно не тратить ресурсы, как ручные, так и автоматические.
Прежде чем рассказать об этом подходе сначала в двух словах объясню, что такое мутационное тестирование вообще. Для тех, кто не в курсе.
Когда вы пишете тесты, по TDD или нет, даже с формальным 100% покрытием, вы никогда не будете уверены в том, что в коде на самом деле протестировано всё. Например, можно банально ошибиться в вызове assert в самом тесте. Или не учесть детали преобразования типов, что никак не повлияет на coverage.
Чтобы убедиться в том, что тесты реально тестируют, есть такой способ: самому вносить в код баги, и смотреть, валятся ли от этого тесты. Если тесты по-прежнему зелёные при явном баге, значит протестировано не всё.
Например, заменили плюс на минус, или добавили "не" к условию, и смотрите.
Обычно это делают в очень ответственных областях программирования, где ошибки вообще не допустимы. Например, софт марсохода или медицинское ПО.
Конечно в марсоходостроении это все делается автоматически: специальный инструмент уродует вашу программу и смотрит, слетели ли тесты.
Проблема в этом подходе в том, что это довольно муторно настраивается, много нюансов, как описать, что надо мутировать, что нет. И всё это потребляет дикое количество ресурсов: разбор кода в AST, мутирование и обратное преобразование.
Автор статьи предлагает подход, аналогичный TDD, но как бы наоборот и совсем другой 🙂
1) сначала добавляете новый код в проект
2) временно вносите в какие-то строки баг
3) пишете тест, который ловит этот баг
Для меня такой подход видится интересным тем, что можно ничего не настраивать в CI, не просить выделить доп ресурсы для обработки пайплайнов, а просто писать полностью покрытый код, даже если тимлиду или вообще никому в твоей команде в целом такой подход неинтересен.
Конечно, это не бесплатно, и пожирает ресурсы программиста. Имхо mutation driven testing можно и нужно применять только там, где есть ответственная логика. Работа с деньгами, медицинский софт и т.д. Понятно, что на эндпоинт, выдающий текущую погоду или прочую ерунду, можно не тратить ресурсы, как ручные, так и автоматические.
👀1
Через несколько дней заканчивается голосование по первой итерации реализации enum в PHP 8.1 (https://wiki.php.net/rfc/enumerations#voting ). Уже видно, что голосов “за” гораздо больше, так что давайте кратко пройдемся и посмотрим, что же нам приготовили авторы языка.
Зачем нужны enum?
Зачем вообще нужны enum? По сути они служат цели улучшенного описания типов. Давайте рассмотрим пример без енумов и с ними. Допустим, у нас продаются машины трех цветов: красные, черные и белые. Как описать цвет, какой тип выбрать?
class Car {
private string $color;
function setColor(string $color): void {
$this->color = $color;
}
}
Если мы опишем цвет машины как простой string, то во-первых при вызове $myCar->setColor(..) непонятно, что за строку туда писать. “red” или “RED” или "ff0000", а во вторых, легко ошибиться, просунув туда случайно что-то не то (пустую строку, к примеру). То же самое будет, если использовать не строки, а числа, например.
Это приводит к тому, что многие php-программисты заводят константы и объединяют их в одном классе, чтобы явно видеть все варианты.
class Color {
public const RED = "red";
public const BLACK = "black";
public const WHITE = "white";
}
и задавая цвет, пишут $myCar->setColor(Color::RED);
Уже лучше. Но если мы впервые видим метод $myCar->setColor(...), мы можем и не знать, что где-то есть константы для цветов. И мы всё еще можем сунуть туда любую строку без какого-либо сообщения об ошибке.
Поэтому здесь нужен не класс, а отдельный тип. Этот тип называется enum
Pure enum
В самом простом случае (pure enum), enum описывается так:
enum Color {
case Red;
case Black;
case White;
}
Описав такой тип, мы можем использовать его везде:
class Car {
private Color $color;
function setColor(Color $color): void {
$this->color = $color;
}
}
Из сигнатуры метода всё сразу видно, какие варианты есть. И метод setColor можно использовать только так: $myCar->setColor(Color::White), никаких строк и доморощенных списков констант. Ничего лишнего не сунешь. Читабельность и поддерживаемость кода стала выше.
Каждый из case-ов (Color::Red, Color::Black, Color::White) является объектом типа Color (можно проверить через instanseof ). Т.е. под капотом это не числа 0,1,2 как в некоторых языках, а именно объекты. Их нельзя сравнивать оператором >, например. У каждого такого объекта есть встроенное свойство $name:
print Color::Red->name; // вернет строку “Red”
Enum со скалярами
Но если бы это было всё, то было бы слишком просто. После названия enum можно указать скалярный тип, например string. И у каждого кейса указать скалярное значение. Это может быть полезно для некоторых целей, например для сортировки или записи в базу данных.
enum Color: string {
case Red = "R";
case Black = "B";
case White = "W";
}
Скалярное значение можно получить потом так:
Color::Red->value //вернет строку “R”
И наоборот, т.е. получить case через значение, тоже можно:
Color::from("R") // вернет объект Color::Red
Помимо полей "case" в enum может быть еще много всего. По сути это разновидность класса. Там могут быть методы, он может реализовывать интерфейсы или использовать трейты:
https://gist.github.com/anton-okolelov/f5e8787b6dfe9b28cbeef7bf5fa9e611
При этом $this будет тот конкретный объект case, для которого мы вызываем метод.
Лично я горячо одобряю введение enum в PHP, это очень удобно и читабельно, и в большинстве языков, где есть какие-никакие типы, enum уже давно есть (кроме, разве что Go).
Дальше - больше. Tagged Unions (тип-сумма)
Есть RFC, которые развивают идею enums дальше, чтобы можно было хранить в одном enum значения разных типов. Как в языке Rust, например. Тогда можно будет сделать, допустим, enum Result с двумя case-ами Result::Ok и Result::Err, причем эти объекты будут хранить данные: Ok будет хранить результат, а Err - ошибку, у каждого из этих значений будет свой тип. И всё это не в Расте, а в PHP!
Об этом мы расскажем в деталях в ближайших постах телеграм-канала Cross Join, не забудьте подписаться!
Зачем нужны enum?
Зачем вообще нужны enum? По сути они служат цели улучшенного описания типов. Давайте рассмотрим пример без енумов и с ними. Допустим, у нас продаются машины трех цветов: красные, черные и белые. Как описать цвет, какой тип выбрать?
class Car {
private string $color;
function setColor(string $color): void {
$this->color = $color;
}
}
Если мы опишем цвет машины как простой string, то во-первых при вызове $myCar->setColor(..) непонятно, что за строку туда писать. “red” или “RED” или "ff0000", а во вторых, легко ошибиться, просунув туда случайно что-то не то (пустую строку, к примеру). То же самое будет, если использовать не строки, а числа, например.
Это приводит к тому, что многие php-программисты заводят константы и объединяют их в одном классе, чтобы явно видеть все варианты.
class Color {
public const RED = "red";
public const BLACK = "black";
public const WHITE = "white";
}
и задавая цвет, пишут $myCar->setColor(Color::RED);
Уже лучше. Но если мы впервые видим метод $myCar->setColor(...), мы можем и не знать, что где-то есть константы для цветов. И мы всё еще можем сунуть туда любую строку без какого-либо сообщения об ошибке.
Поэтому здесь нужен не класс, а отдельный тип. Этот тип называется enum
Pure enum
В самом простом случае (pure enum), enum описывается так:
enum Color {
case Red;
case Black;
case White;
}
Описав такой тип, мы можем использовать его везде:
class Car {
private Color $color;
function setColor(Color $color): void {
$this->color = $color;
}
}
Из сигнатуры метода всё сразу видно, какие варианты есть. И метод setColor можно использовать только так: $myCar->setColor(Color::White), никаких строк и доморощенных списков констант. Ничего лишнего не сунешь. Читабельность и поддерживаемость кода стала выше.
Каждый из case-ов (Color::Red, Color::Black, Color::White) является объектом типа Color (можно проверить через instanseof ). Т.е. под капотом это не числа 0,1,2 как в некоторых языках, а именно объекты. Их нельзя сравнивать оператором >, например. У каждого такого объекта есть встроенное свойство $name:
print Color::Red->name; // вернет строку “Red”
Enum со скалярами
Но если бы это было всё, то было бы слишком просто. После названия enum можно указать скалярный тип, например string. И у каждого кейса указать скалярное значение. Это может быть полезно для некоторых целей, например для сортировки или записи в базу данных.
enum Color: string {
case Red = "R";
case Black = "B";
case White = "W";
}
Скалярное значение можно получить потом так:
Color::Red->value //вернет строку “R”
И наоборот, т.е. получить case через значение, тоже можно:
Color::from("R") // вернет объект Color::Red
Помимо полей "case" в enum может быть еще много всего. По сути это разновидность класса. Там могут быть методы, он может реализовывать интерфейсы или использовать трейты:
https://gist.github.com/anton-okolelov/f5e8787b6dfe9b28cbeef7bf5fa9e611
При этом $this будет тот конкретный объект case, для которого мы вызываем метод.
Лично я горячо одобряю введение enum в PHP, это очень удобно и читабельно, и в большинстве языков, где есть какие-никакие типы, enum уже давно есть (кроме, разве что Go).
Дальше - больше. Tagged Unions (тип-сумма)
Есть RFC, которые развивают идею enums дальше, чтобы можно было хранить в одном enum значения разных типов. Как в языке Rust, например. Тогда можно будет сделать, допустим, enum Result с двумя case-ами Result::Ok и Result::Err, причем эти объекты будут хранить данные: Ok будет хранить результат, а Err - ошибку, у каждого из этих значений будет свой тип. И всё это не в Расте, а в PHP!
Об этом мы расскажем в деталях в ближайших постах телеграм-канала Cross Join, не забудьте подписаться!
👀1
Когда нужно выделять абстракцию, а когда нет? Есть два похожих класса, нужно ли их обобщать? Или лучше поддерживать по отдельности (читай - местами это будет копипаста).
Язык Go говорит, что немного копипасты лучше, чем дополнительная абстракция.
Кто-то, из классических ООП-языков, скажет, что DRY священен, и нельзя повторяться.
На мой взгляд, тут всё просто. Если две сущности похожи не только внешне, но и по бизнес-логике должны быть похожи - можно выделять абстракцию при необходимости.
Если два класса похожи парочкой методов, но имеют разную суть, то ни в коем случае нельзя обобщать. Даже если сложно избавиться от дублирования кода другими способами. Лучше копипаста, ей богу.
Потому что в будущем такой код будет сложнее понять и сложнее поддерживать: с каждым изменением придется со скрипом натягивать такое обобщение, и всё будет становиться еще страннее
Язык Go говорит, что немного копипасты лучше, чем дополнительная абстракция.
Кто-то, из классических ООП-языков, скажет, что DRY священен, и нельзя повторяться.
На мой взгляд, тут всё просто. Если две сущности похожи не только внешне, но и по бизнес-логике должны быть похожи - можно выделять абстракцию при необходимости.
Если два класса похожи парочкой методов, но имеют разную суть, то ни в коем случае нельзя обобщать. Даже если сложно избавиться от дублирования кода другими способами. Лучше копипаста, ей богу.
Потому что в будущем такой код будет сложнее понять и сложнее поддерживать: с каждым изменением придется со скрипом натягивать такое обобщение, и всё будет становиться еще страннее
👀1
Семимониторный ноут уже можно заказать )
У майкрософт как-то были исследования, что размер экрана увеличивает производительность программиста, но тут чутка перебрали
https://m.habr.com/ru/company/selectel/blog/541472/
У майкрософт как-то были исследования, что размер экрана увеличивает производительность программиста, но тут чутка перебрали
https://m.habr.com/ru/company/selectel/blog/541472/
Хабр
Стартовали продажи ноутбука Aurora 7 с семью дисплеями
Разработчики этого чуда техники, создавая прототип, явно проговаривали про себя: «Маловато будет!», имея в виду количество экранов. Два дисплея? Банально и относительно часто встречается. Три? Ну нет....
Опубликовал статью про tagged unions в PHP (этот RFC еще не принят, и даже голосования не было, однако всё равно было любопытно).
https://habr.com/ru/post/541670/
https://habr.com/ru/post/541670/
Хабр
Tagged Unions в PHP (примерно как в Rust)
UPD. Во избежание путаницы по просьбам трудящихся хочу еще раз уточнить, что это только черновик, который еще пока что не был официально предложен В предыдущей с...
Proposal Go generics был только что принят. Это означает, что дженерики скоро попадут в язык. Ну как скоро, ожидается к 1.18beta, т.е. где-то в декабре.
ссылка на proposal: https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md
примеры использования: https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#examples
обсуждение на reddit: https://www.reddit.com/r/golang/comments/lh2158/proposal_43650_generics_by_type_parameters_just/
ссылка на proposal: https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md
примеры использования: https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#examples
обсуждение на reddit: https://www.reddit.com/r/golang/comments/lh2158/proposal_43650_generics_by_type_parameters_just/
Reddit
From the golang community on Reddit: Proposal 43650 (generics by type parameters) just got accepted!
Explore this post and more from the golang community
👀1
В подкасте "Цинковый прод" записали необычный выпуск. Не про языки и базы данных, а внезапно про правильное питание. Айтишники склонны работать круглые сутки за компом, зачастую мало двигаются, питаются черт знает чем, и тема еды всплывала в чате подкаста не раз.
Лишний вес, вредны ли энергетики, нужно ли голодать, что лучше - спорт или диета и так далее. Всё это мы обсудили в выпуске. Инет местами лагал, но гость жёг напалмом, очень веселый парень.
https://www.youtube.com/watch?v=9pyZcKv1hsg
Лишний вес, вредны ли энергетики, нужно ли голодать, что лучше - спорт или диета и так далее. Всё это мы обсудили в выпуске. Инет местами лагал, но гость жёг напалмом, очень веселый парень.
https://www.youtube.com/watch?v=9pyZcKv1hsg
YouTube
#099 Айтишники и еда. Диетолог Антоний Мальков в Цинковом проде
Сидишь скрюченный, не отрывая жопы, и ешь печеньки? Заработал лишние килограммы и изжогу? Или наоборот, дофига спортсмен, и хочешь более эффективно питаться?
00:00 Приветствие. В гостях Антоний Мальков
6:43 Типичный айтишник - как выработать полезные привычки…
00:00 Приветствие. В гостях Антоний Мальков
6:43 Типичный айтишник - как выработать полезные привычки…
Женя Антонов недавно писал, что сложные дела лучше делать с утра, на свежую голову. А вечер оставлять для рутины и ерунды. В целом я согласен, часто сам так и делал, но есть дополнение.
Когда работаешь из дома, а сейчас очень много, кто работает из дома, иногда появляется возможность полноценно отдохнуть днем. Можно даже изловчиться и поспать полчаса в обеденный перерыв. (Те, кто меня знают лично, видели, что я и в офисе (!) умудрялся поспать в сидячем положении).
Были исследования НАСА, что получасовой дневной сон увеличивает продуктивность на треть!
Не всегда удается заснуть, но даже просто полежать бездумно, выбросив из мозга текущие проблемы - это своего рода медитация, которая позволяет перезагрузить работоспособность.
Тут надо упомянуть, что есть люди, которые, засыпая днем, не могут остановиться и дрыхнут часа три. Я подозреваю, что зачастую так сказывается общий фоновый недостаток сна. Я бы посоветовал спать 8 часов в сутки, а не играть/смотреть сериалы по ночам.
Вывод
Лучше вовремя отдыхать, тогда работа будет эффективнее. И тогда можно будет приоритезировать задачи не по сложности, а по важности для бизнеса.
Когда работаешь из дома, а сейчас очень много, кто работает из дома, иногда появляется возможность полноценно отдохнуть днем. Можно даже изловчиться и поспать полчаса в обеденный перерыв. (Те, кто меня знают лично, видели, что я и в офисе (!) умудрялся поспать в сидячем положении).
Были исследования НАСА, что получасовой дневной сон увеличивает продуктивность на треть!
Не всегда удается заснуть, но даже просто полежать бездумно, выбросив из мозга текущие проблемы - это своего рода медитация, которая позволяет перезагрузить работоспособность.
Тут надо упомянуть, что есть люди, которые, засыпая днем, не могут остановиться и дрыхнут часа три. Я подозреваю, что зачастую так сказывается общий фоновый недостаток сна. Я бы посоветовал спать 8 часов в сутки, а не играть/смотреть сериалы по ночам.
Вывод
Лучше вовремя отдыхать, тогда работа будет эффективнее. И тогда можно будет приоритезировать задачи не по сложности, а по важности для бизнеса.
Telegram
Тимлид Очевидность
Делаю сложные дела утром
Часто замечаю, что многие люди (как и я раньше) попадают в ситуацию, когда надо бы сделать сегодня что-то сложное, но хочется сначала выполнить простенькое, разобраться с мелочами, вдохновиться легкими победами.
Я считаю это большой…
Часто замечаю, что многие люди (как и я раньше) попадают в ситуацию, когда надо бы сделать сегодня что-то сложное, но хочется сначала выполнить простенькое, разобраться с мелочами, вдохновиться легкими победами.
Я считаю это большой…
👍2
Меня попросили распространить новость о том, что скоро будет мегастрим, где будет обсжуждаться будущее и прошлое PHP с core-разработчиками, фреймворк-мейкерами и прочими инфлюенсерами: https://habr.com/ru/company/skyeng/blog/542070/
Ну и чтобы два раза не вставать, сразу добавлю свои 5 копеек.
Куда движется PHP?
С одной стороны, PHP становится всё круче и круче: еще больше возможностей для типизации (например, enums), еще выше скорость работы (куча оптимизаций движка + еще JIT), много хороших полноценных фреймворков (Symfony для чистоты кода, Laravel для скорости разработки + Yii еще есть). Засчет развития языка, говнокодеров на PHP все меньше и меньше, плохая репутация языка потихоньку уходит.
С другой стороны, в языке есть один гигантский недостаток, который перебивает многие достоинства.
Нет нормальной возможности для разработки асинхронных i/o-bound приложений.
Давайте посмотрим на ближайших конкурентов на этом поле:
В NodeJS - встроен event loop из коробки, есть async/await и т.д
В Go - есть goroutines, которые запускаются добавлением одного ключевого слова "go" перед вызовом функции
Можно перечислять долго, но в целом по-моему на данный момент чуть ли не все языки кроме PHP обзавелись какой-то такой штукой. Можно на уровне самого языка сделать сервер (без связки nginx+php-fpm) и обрабатывать одновременно и http, и общаться по вебсокетам, и слушать кафку и т.д.
В php есть AmPHP, swoole и т.д., но они являются сторонними решениями, а не first-class citizen, неизвестно их будущее (может, проекты закроют завтра), и самое главное - никто из пхпшников их толком не знает и не применяет на проде. Чуть ниже будет опрос на эту тему.
Более того, даже если бы в язык был встроен event loop и async/await, то стандартная библиотека к этому не готова. Например, PDO - сплошь синхронно (в AmPHP сделана своя асинхронная реализация подключения к Postgres). Чтение из сокета можно перевести в неблокирующий режим (socket_set_nonblock() ), но придется писать много обвязок, всё неудобно и не по-людски.
Но самое печальное, что Дмитрий Стогов, core-разработчик языка не считает это проблемой.
Итого, что мы имеем.
На php удобно писать, язык хороший, но нельзя или очень-очень неудобно писать современные вещи:
1) Микросервисы ( часто требуют асинхронной обработки сообщений и кроме того невыгодно тащить nginx+php-fpm для каждого микросервиса)
2) graphql. Хотя на php можно писать под graphql, но части запроса не будут отрабатывать параллельно без ReactPHP и его друзей
3) websockets
4) grpc-сервер
Затащив асинхронность, можно было бы всё это починить, и PHP начал бы отъедать рынок обратно.
попытка с Fibers
Есть RFC c добавлением Fibers. Но там же всё жутко сложно, и не предназначено для прямого использования. Это скорее для облегчения разработки Swoole и подобных решений; стандартизация подходов с самодельным event-loop
Вот пример приложения которое умеет читать и писать в сокет: https://github.com/amphp/ext-fiber/blob/master/examples/002-read-write.php
Там столько деталей, что сходу непонятно вообще, что программа делает.
Ну и стандартная библиотека всё равно нифига не готова.
Тем не менее то, что идет работа в этом направлении, уже радует, так как десятилетиями не было и этого. Возможно, это первый шаг, после которого плотину наконец-то прорвёт.
Если не будет поздно. Другие языки не стоят на месте и обрастают новыми подходами. ( Взять хотя бы React Server Components - адская клиент-серверная смесь. Неизвестно, выстрелит это или нет, просто пример).
Т.е. к тому моменту, когда PHP наконец пройдет этот путь (сделает конструкции в самом языке, перепишет стандартную библиотеку, адаптирует все фреймворки), javanoscript/typenoscript будет уже где-то в космосе по количеству новых интересных подходов.
Ну и чтобы два раза не вставать, сразу добавлю свои 5 копеек.
Куда движется PHP?
С одной стороны, PHP становится всё круче и круче: еще больше возможностей для типизации (например, enums), еще выше скорость работы (куча оптимизаций движка + еще JIT), много хороших полноценных фреймворков (Symfony для чистоты кода, Laravel для скорости разработки + Yii еще есть). Засчет развития языка, говнокодеров на PHP все меньше и меньше, плохая репутация языка потихоньку уходит.
С другой стороны, в языке есть один гигантский недостаток, который перебивает многие достоинства.
Нет нормальной возможности для разработки асинхронных i/o-bound приложений.
Давайте посмотрим на ближайших конкурентов на этом поле:
В NodeJS - встроен event loop из коробки, есть async/await и т.д
В Go - есть goroutines, которые запускаются добавлением одного ключевого слова "go" перед вызовом функции
Можно перечислять долго, но в целом по-моему на данный момент чуть ли не все языки кроме PHP обзавелись какой-то такой штукой. Можно на уровне самого языка сделать сервер (без связки nginx+php-fpm) и обрабатывать одновременно и http, и общаться по вебсокетам, и слушать кафку и т.д.
В php есть AmPHP, swoole и т.д., но они являются сторонними решениями, а не first-class citizen, неизвестно их будущее (может, проекты закроют завтра), и самое главное - никто из пхпшников их толком не знает и не применяет на проде. Чуть ниже будет опрос на эту тему.
Более того, даже если бы в язык был встроен event loop и async/await, то стандартная библиотека к этому не готова. Например, PDO - сплошь синхронно (в AmPHP сделана своя асинхронная реализация подключения к Postgres). Чтение из сокета можно перевести в неблокирующий режим (socket_set_nonblock() ), но придется писать много обвязок, всё неудобно и не по-людски.
Но самое печальное, что Дмитрий Стогов, core-разработчик языка не считает это проблемой.
Итого, что мы имеем.
На php удобно писать, язык хороший, но нельзя или очень-очень неудобно писать современные вещи:
1) Микросервисы ( часто требуют асинхронной обработки сообщений и кроме того невыгодно тащить nginx+php-fpm для каждого микросервиса)
2) graphql. Хотя на php можно писать под graphql, но части запроса не будут отрабатывать параллельно без ReactPHP и его друзей
3) websockets
4) grpc-сервер
Затащив асинхронность, можно было бы всё это починить, и PHP начал бы отъедать рынок обратно.
попытка с Fibers
Есть RFC c добавлением Fibers. Но там же всё жутко сложно, и не предназначено для прямого использования. Это скорее для облегчения разработки Swoole и подобных решений; стандартизация подходов с самодельным event-loop
Вот пример приложения которое умеет читать и писать в сокет: https://github.com/amphp/ext-fiber/blob/master/examples/002-read-write.php
Там столько деталей, что сходу непонятно вообще, что программа делает.
Ну и стандартная библиотека всё равно нифига не готова.
Тем не менее то, что идет работа в этом направлении, уже радует, так как десятилетиями не было и этого. Возможно, это первый шаг, после которого плотину наконец-то прорвёт.
Если не будет поздно. Другие языки не стоят на месте и обрастают новыми подходами. ( Взять хотя бы React Server Components - адская клиент-серверная смесь. Неизвестно, выстрелит это или нет, просто пример).
Т.е. к тому моменту, когда PHP наконец пройдет этот путь (сделает конструкции в самом языке, перепишет стандартную библиотеку, адаптирует все фреймворки), javanoscript/typenoscript будет уже где-то в космосе по количеству новых интересных подходов.
👍2
Опрос только для PHP-програмистов. Используете ли вы в реальной работе на проде ReactPHP, AmPHP или Swoole?
Просьба пошарить этот опрос, так как канал новый, и подписчиков здесь пока маловато.
Просьба пошарить этот опрос, так как канал новый, и подписчиков здесь пока маловато.
Anonymous Poll
5%
Да
50%
Нет
45%
Я не PHP-шник
Cross Join - канал о разработке pinned «Опрос только для PHP-програмистов. Используете ли вы в реальной работе на проде ReactPHP, AmPHP или Swoole?
Просьба пошарить этот опрос, так как канал новый, и подписчиков здесь пока маловато.»
Просьба пошарить этот опрос, так как канал новый, и подписчиков здесь пока маловато.»
Недавно Фил Ранжин написал в твиттере тредик, что мол все аджайл-практики и книги по ним - говно, и только мудрый руководитель на опыте может всё разрулить.
Естественно, без опыта руководства всё пойдет по пизде. Но и на одной практике далеко не уедешь. Классическая поговорка "Теория без практики - мертва, практика без теории - слепа" работает и в менеджменте. Я наблюдал такую картину не раз: когда опытные умные люди не могли справиться с хаосом.
Я согласен, что куча аджайл-практик - говно, а уж книги и подавно, но всё же далеко не все. Опишу то, что реально работает в нашей команде. Буквально в двух словах, чтобы не получилась очередная говнокнига.
Отсюда главная мысль: не давать большому количеству задач застревать в разработке.
Без грамотной разбивки задач на стадии, и без визуализации этой картины проще сдохнуть, чем управлять.
Если при работе над крупной доработкой продукта взаимодействуют сразу несколько команд, и у каждой команды свой цикл разработки, свой проект в жире и т.д. (что часто бывает при микросервисной архитектуре), нужно заводить отдельную доску под эту мега-задачу, чтобы суммарно понимать, что вообще происходит. Без этого - капец.
Также нужны диаграммы, показывающие, сколько времени занимает разработка задач в тех отделе. Если существенная часть в % задач висит месяцами, то звиздец. Долгая задача не просто расход, она может уже потерять бизнес-актуальность, то есть дохода никогда не принести!!!
Это может быть блокировка между командами (фронтенд ждет бекенд, бекенд ждет, когда отдуплятся админы, а админы заняты другой задачей). Это может быть блок внутри команды. Банально - задача долго-долго ожидает код-ревью, а когда код-ревью уже завершилось, то всё поросло конфликтами с рефакторингом из другой задачи.
Тут же автоматически напрашивается главная аджайл-практика. Вводить ограничение на количество задач в каждой из стадий. Например, в стадии написании кода может быть только x задач, на код ревью y задач, в тестировании z задач. x, y и z настраиваются опытным путем, с небольшим запасом на всякий случай. Потому что нет смысла делать 10 задач в неделю, если есть стадия тестирования, которая справляется лишь с двумя. Чем меньше задач в работе, тем меньше они друг друга блочат. Чем меньше задач в работе, тем яснее картина: понятно, что именно делать, чтобы протолкнуть зависшее.
Кстати, практика гугла по код ревью: если есть чего ревьювить, то ревьювить важнее чем делать свою (новую) задачу.
Естественно, без опыта руководства всё пойдет по пизде. Но и на одной практике далеко не уедешь. Классическая поговорка "Теория без практики - мертва, практика без теории - слепа" работает и в менеджменте. Я наблюдал такую картину не раз: когда опытные умные люди не могли справиться с хаосом.
Я согласен, что куча аджайл-практик - говно, а уж книги и подавно, но всё же далеко не все. Опишу то, что реально работает в нашей команде. Буквально в двух словах, чтобы не получилась очередная говнокнига.
Главное
Главная задача бизнеса: заработать деньги. Если посмотреть на это с точки зрения разработки софта, то фича, дошедшая до прода - это ценность, которая может принести доход. А фича, находящаяся в разработке - тупо расход. Отсюда главная мысль: не давать большому количеству задач застревать в разработке.
Визуализация
Зачем нужны канбан-доски и прочая аджайл-херота? Чтобы видеть, какая задача где застряла. Это прям очень важно. При хаотическом управлении без каких-либо практик (в начале моего пути руководителя так было) бывает так, что на 5 программистов, одного тестировщика и одного админа стоит 400-500 задач. Так исторически сложилось, постепенно наросло за годы.Без грамотной разбивки задач на стадии, и без визуализации этой картины проще сдохнуть, чем управлять.
Если при работе над крупной доработкой продукта взаимодействуют сразу несколько команд, и у каждой команды свой цикл разработки, свой проект в жире и т.д. (что часто бывает при микросервисной архитектуре), нужно заводить отдельную доску под эту мега-задачу, чтобы суммарно понимать, что вообще происходит. Без этого - капец.
Также нужны диаграммы, показывающие, сколько времени занимает разработка задач в тех отделе. Если существенная часть в % задач висит месяцами, то звиздец. Долгая задача не просто расход, она может уже потерять бизнес-актуальность, то есть дохода никогда не принести!!!
Ограничения
При ближайшем рассмотрении большинство зависших задач (мы их нашли на нашей визуализации) делаются долго не потому, что там много кода писать. А потому что они чего-то ждут. 90% времени задачи тупо чем-то заблочены. Это может быть блокировка между командами (фронтенд ждет бекенд, бекенд ждет, когда отдуплятся админы, а админы заняты другой задачей). Это может быть блок внутри команды. Банально - задача долго-долго ожидает код-ревью, а когда код-ревью уже завершилось, то всё поросло конфликтами с рефакторингом из другой задачи.
Тут же автоматически напрашивается главная аджайл-практика. Вводить ограничение на количество задач в каждой из стадий. Например, в стадии написании кода может быть только x задач, на код ревью y задач, в тестировании z задач. x, y и z настраиваются опытным путем, с небольшим запасом на всякий случай. Потому что нет смысла делать 10 задач в неделю, если есть стадия тестирования, которая справляется лишь с двумя. Чем меньше задач в работе, тем меньше они друг друга блочат. Чем меньше задач в работе, тем яснее картина: понятно, что именно делать, чтобы протолкнуть зависшее.
Проталкивание
Когда есть наглядная доска и выставлены ограничения, нужно на ежедневной основе пропихивать задачи, начиная с "правой" стороны. Т.е. то, что ближе всего к проду, должно быть рассмотрено под лупой, нужно выяснять, что именно там блочит задачу и кого пнуть, чтоб полетело (митинг на 10 минут в день). Кстати, практика гугла по код ревью: если есть чего ревьювить, то ревьювить важнее чем делать свою (новую) задачу.
Говно на входе - говно на выходе
Многие задачи зависают просто потому, что они изначально плохие. Не проработаны никак самим бизнесом, например, или не учитывают технические нюансы архитектуры. Поэтому ПЕРЕД тех отделом нужно поставить фильтр, особенно если задачи могут ставить много человек: нужна ли вообще задача, хватает ли информации для ее разработки, упирается ли в архитектуру
Вывод👍4
Вывод
То, что я описал выше - реально работает у нас. Зависших задач считай нет, блокировки решаются очень быстро, скорость поставки задач выросла. Предсказуемость тех отдела также увеличилась. При этом программисты не затраханы одновременным решением нескольких задач, и переработок тоже нет.
Теории не так много то и нужно, как видно из этого поста, но она экстремально важна.
Но и мудрость руководителей конечно же необходима. Как для разруливания нестандартных ситуаций, так и для более тонкой настройки процесса.
Кстати, подписывайтесь на этот канал, будет много мыслей, идей и горящих новостей.
То, что я описал выше - реально работает у нас. Зависших задач считай нет, блокировки решаются очень быстро, скорость поставки задач выросла. Предсказуемость тех отдела также увеличилась. При этом программисты не затраханы одновременным решением нескольких задач, и переработок тоже нет.
Теории не так много то и нужно, как видно из этого поста, но она экстремально важна.
Но и мудрость руководителей конечно же необходима. Как для разруливания нестандартных ситуаций, так и для более тонкой настройки процесса.
Кстати, подписывайтесь на этот канал, будет много мыслей, идей и горящих новостей.
👀1
Forwarded from Alyssa Martynova
Что ждет PHP в 2021?
Узнаем 27 февраля на большом стриме.
🎤 2 доклада: о WebRTC от Ильи Левина из Skyeng, о gRPC — от Антона Жукова из ManyChat.
🏄 Острые дискуссии, мнения о 2020, планы на 2021. В эфир придут:
- Никита Попов (PHP core team)
- Дмитрий Елисеев (ElisDN)
- Валентин Удальцов (Пых)
- Роман Пронский (PHP-дайджест)
- Александр Макаров (Yii)
- Сергей Жук (Между Скобок)
- Константин Буркалев (SDCast)
- Петр Мязин (Пятиминутка PHP)
- Антон Околелов (Цинковый прод)
- Николай Пучко (PHPToday)
🎁 Покажем итоги опроса про лучшее из мира PHP за 2020, разыграем фирменного слоника и целый пул других подарков.
Трансляции в 11:00 (Москва/Минск), 10:00 — Киев
Узнаем 27 февраля на большом стриме.
🎤 2 доклада: о WebRTC от Ильи Левина из Skyeng, о gRPC — от Антона Жукова из ManyChat.
🏄 Острые дискуссии, мнения о 2020, планы на 2021. В эфир придут:
- Никита Попов (PHP core team)
- Дмитрий Елисеев (ElisDN)
- Валентин Удальцов (Пых)
- Роман Пронский (PHP-дайджест)
- Александр Макаров (Yii)
- Сергей Жук (Между Скобок)
- Константин Буркалев (SDCast)
- Петр Мязин (Пятиминутка PHP)
- Антон Околелов (Цинковый прод)
- Николай Пучко (PHPToday)
🎁 Покажем итоги опроса про лучшее из мира PHP за 2020, разыграем фирменного слоника и целый пул других подарков.
Трансляции в 11:00 (Москва/Минск), 10:00 — Киев
👀1
Любимому подкасту "Цинковый прод" исполнилось 100 выпусков!
Для тех, кто никогда о нем не слышал, вот топовые выпуски:
https://youtu.be/slE11sPm8fQ (кубернетис: что, для чего, и где, и даже на Raspberry Pi)
https://youtu.be/aVVTNg_mI7U (Дмитрий Пацура продает nodejs и ругает php)
https://youtu.be/xI-VWPZ3XQQ (выпуск с Брагилевским)
Для тех, кто никогда о нем не слышал, вот топовые выпуски:
https://youtu.be/slE11sPm8fQ (кубернетис: что, для чего, и где, и даже на Raspberry Pi)
https://youtu.be/aVVTNg_mI7U (Дмитрий Пацура продает nodejs и ругает php)
https://youtu.be/xI-VWPZ3XQQ (выпуск с Брагилевским)
YouTube
#082 Про k8s в курилке с Дмитрием Столяровым и Василием Мармером из Флант
К нам в гости заглянули Дмитрий Столяров (CTO Flant) и Василий Мармер (Team Lead Flant)
В формате курилки мы обсуждали k8s
Ссылки на наших друзей:
https://flant.ru/mk8s
https://werf.io
0:00 Приветствие
1:10 Говорим про Kubernetes и знакомимся с гостями…
В формате курилки мы обсуждали k8s
Ссылки на наших друзей:
https://flant.ru/mk8s
https://werf.io
0:00 Приветствие
1:10 Говорим про Kubernetes и знакомимся с гостями…
👀1
Нужны ли созвоны?
Напишу свои мысли, а вы докиньте в коменты свои.
Раньше разработчиков часто раздражали бесконечные митинги с болтовней ни о чем, сейчас точно также раздражают созвоны. Разницы никакой. Двое говорят, пятеро тупят, трое выключили камеру и спят. "Позвиздели и забыли", результат - ноль
Минусов очного общения дофига. Многие сходу не могут вспомнить какие-то детали, и просто обещают потом посмотреть. Кто-то отложил важные дела ради митинга, а митинг оказался ни о чём. Кто-то из-за созвона потерял контекст. Кто-то просто устал, кто-то не пожрал.
Капец.
В целом, предпочтительнее, конечно, письменный формат. Но есть исключения.
1) Созвон для быстрого решения проблемы. В асинхронной текстовой коммуникации есть большая беда: скорость. Петя что-то написал, Вася ответил через час, Зоя ушла на обед, Криштиану вообще не заметил сообщения. В итоге можно целый день обсуждать проблему, хотя ушло бы 5 минут. Когда упал прод, круче всего собраться за одним компом вдвоем-втроём и быстро всё порешать.
2) Delivery sync. Когда взаимодействуют несколько команд, бывает полезно видеть картину происходящего в целом. Протолкнуть пару задач до прода, выяснить кто кого блокирует, прощупать подвисшие вопросы. Договориться о стратегии, чтобы никто никого не блокировал в будущем. Почему тут хорош созвон - к такому митингу не надо готовиться, чистый обмен информации о состоянии дел. Кроме того, присуствуют все ответственные люди, не надо отдельно каждому писать и ждать. На практике занимает 10 минут (!) в день, не больше. Польза огромная, из личного опыта говорю.
3) Обсуждение новой сложной задачи, особенно затрагивающей несколько команд. Даже если кто-то (архитектор, системный аналитик или тот, кто взял на себя эту роль) разобрался в задаче, продумал, кто с чем взаимодействует, и написал доку, всё равно сложно всё учесть. У людей неизбежно будут вопросы, вопросы будут зачастую одинаковые. Даже если кто-то будет есть пиццу и лишь фоном поприсутствует на таком созвоне, это уже будет полезно: в мозгу осядут необходимые термины, контекст.
4) Созвоны для общения команды. У нас стендапы по утрам больше нужны для того, чтобы люди не забыли, что они не сферические human resources, пообсуждали новости, пошутили, постебались друг над другом. Это важно.
Короче, как обычно, нет чёрного и белого, всё бывает нужно.
Если делаешь созвон, нужно проверить по чек листу:
- нужен ли он вообще, или можно отложить эти вопросы для разборок в текстовом виде
- есть повестка, чтобы можно было подготовиться, освежить в памяти; или убедиться, что обсуждаемые вопросы не требуют подготовки.
- нет лишних людей
- после созвона сделаны выводы и намечены какие-то действия. Иначе это просранный час и разочарованные люди
Ну и конечно, нельзя, чтобы созвоны постоянно рвали конекст. Дни без митингов и всё такое.
Я как лид, которого всё время дергают, вбил себе в календарь несколько часов подряд в день под названием "программирование", таким образом на эти часы никто не может меня забронировать.
Вообще, если считаете что созвон тупой, лучше его проигнорировать и попросить записать. Потом промотать на x3 скорости. Это экономит время.
Напишу свои мысли, а вы докиньте в коменты свои.
Раньше разработчиков часто раздражали бесконечные митинги с болтовней ни о чем, сейчас точно также раздражают созвоны. Разницы никакой. Двое говорят, пятеро тупят, трое выключили камеру и спят. "Позвиздели и забыли", результат - ноль
Минусов очного общения дофига. Многие сходу не могут вспомнить какие-то детали, и просто обещают потом посмотреть. Кто-то отложил важные дела ради митинга, а митинг оказался ни о чём. Кто-то из-за созвона потерял контекст. Кто-то просто устал, кто-то не пожрал.
Капец.
В целом, предпочтительнее, конечно, письменный формат. Но есть исключения.
1) Созвон для быстрого решения проблемы. В асинхронной текстовой коммуникации есть большая беда: скорость. Петя что-то написал, Вася ответил через час, Зоя ушла на обед, Криштиану вообще не заметил сообщения. В итоге можно целый день обсуждать проблему, хотя ушло бы 5 минут. Когда упал прод, круче всего собраться за одним компом вдвоем-втроём и быстро всё порешать.
2) Delivery sync. Когда взаимодействуют несколько команд, бывает полезно видеть картину происходящего в целом. Протолкнуть пару задач до прода, выяснить кто кого блокирует, прощупать подвисшие вопросы. Договориться о стратегии, чтобы никто никого не блокировал в будущем. Почему тут хорош созвон - к такому митингу не надо готовиться, чистый обмен информации о состоянии дел. Кроме того, присуствуют все ответственные люди, не надо отдельно каждому писать и ждать. На практике занимает 10 минут (!) в день, не больше. Польза огромная, из личного опыта говорю.
3) Обсуждение новой сложной задачи, особенно затрагивающей несколько команд. Даже если кто-то (архитектор, системный аналитик или тот, кто взял на себя эту роль) разобрался в задаче, продумал, кто с чем взаимодействует, и написал доку, всё равно сложно всё учесть. У людей неизбежно будут вопросы, вопросы будут зачастую одинаковые. Даже если кто-то будет есть пиццу и лишь фоном поприсутствует на таком созвоне, это уже будет полезно: в мозгу осядут необходимые термины, контекст.
4) Созвоны для общения команды. У нас стендапы по утрам больше нужны для того, чтобы люди не забыли, что они не сферические human resources, пообсуждали новости, пошутили, постебались друг над другом. Это важно.
Короче, как обычно, нет чёрного и белого, всё бывает нужно.
Если делаешь созвон, нужно проверить по чек листу:
- нужен ли он вообще, или можно отложить эти вопросы для разборок в текстовом виде
- есть повестка, чтобы можно было подготовиться, освежить в памяти; или убедиться, что обсуждаемые вопросы не требуют подготовки.
- нет лишних людей
- после созвона сделаны выводы и намечены какие-то действия. Иначе это просранный час и разочарованные люди
Ну и конечно, нельзя, чтобы созвоны постоянно рвали конекст. Дни без митингов и всё такое.
Я как лид, которого всё время дергают, вбил себе в календарь несколько часов подряд в день под названием "программирование", таким образом на эти часы никто не может меня забронировать.
Вообще, если считаете что созвон тупой, лучше его проигнорировать и попросить записать. Потом промотать на x3 скорости. Это экономит время.
❤2
Оформил мысли из некоторых предыдущих постов чуть подробнее, в виде статьи на хабре
https://habr.com/ru/post/543490/
https://habr.com/ru/post/543490/
Хабр
Радикальный перфекционизм в коде
Идея взята с постов telegram-канала Cross Join Представьте себе, что какой-то программист придет на работу в одних трусах. Или вообще голышом. Работа встала, все...
Сейчас гуляют по интернету красивые картинки про развитие БД (https://youtu.be/thuG2PXVbBU ), но непонятно, откуда данные.
По опросам разработчиков на stackoverflow, расклад совершенно другой: https://insights.stackoverflow.com/survey/2020#technology-databases
По опросам разработчиков на stackoverflow, расклад совершенно другой: https://insights.stackoverflow.com/survey/2020#technology-databases
YouTube
The Most Popular Databases - 2006/2021
In this video The Most Popular Databases. The data are updated to February 2021 and start from May 2006. In February 2021 the most used and popular databases are: Oracle, 30,2%, MySql 16.65% and SQL Server with 13.21%.
The graph was created using the data…
The graph was created using the data…
Можно ли наследовать класс Пингвин от класса Птица?
Anonymous Poll
45%
Да
26%
Нет
8%
Другое (укажу в коментах)
21%
- (посмотреть результат)
Итак, на вопрос, можно ли наследовать класс Пингвин от класса Птица, большая часть людей ответили "да" или "нет".
На самом деле, если вам зададут такой вопрос на собеседовании, знайте: тут есть подвох.
Дело в том, что когда мы пишем программу, мы не оперируем настоящими животными, мы лишь моделируем их, т.е. строим модель для решения определенных задач, а не для всего на свете.
Пингвин и птица в разных бизнес-контекстах могут быть описаны совершенно по-разному.
Для учета количества крыльев и клювов (или кала, как подсказали в коментах) на квадратный километр территории - можно наследовать, без проблем.
Для учета перемещений животных в пространстве так не получится, потому что метод "летать" вызовет проблемы и костыли.
Более того, в одном и том же софте могут присутствовать сразу оба варианта. В различных bounded context могут быть разные модели.
Другой пример: пользователь, использующийся для проверки логина и пароля, и пользователь, для которого считают зарплату - это совершенно разные сущности, даже если у них id один и тот же. Их свойства могут храниться в разных таблицах. Наследоваться от чего-то или нет - решается в каждом конкретном случае.
На самом деле, если вам зададут такой вопрос на собеседовании, знайте: тут есть подвох.
Дело в том, что когда мы пишем программу, мы не оперируем настоящими животными, мы лишь моделируем их, т.е. строим модель для решения определенных задач, а не для всего на свете.
Пингвин и птица в разных бизнес-контекстах могут быть описаны совершенно по-разному.
Для учета количества крыльев и клювов (или кала, как подсказали в коментах) на квадратный километр территории - можно наследовать, без проблем.
Для учета перемещений животных в пространстве так не получится, потому что метод "летать" вызовет проблемы и костыли.
Более того, в одном и том же софте могут присутствовать сразу оба варианта. В различных bounded context могут быть разные модели.
Другой пример: пользователь, использующийся для проверки логина и пароля, и пользователь, для которого считают зарплату - это совершенно разные сущности, даже если у них id один и тот же. Их свойства могут храниться в разных таблицах. Наследоваться от чего-то или нет - решается в каждом конкретном случае.
👀1