Запомнилось из чего-то недавно прочитанного:
Если судьба больно бьет вас, значит вы заняли не удобное для нее положение.
:)))
Размышления и впечатления, которые не хочется держать в себе. О программировании в частности. Ну и о творчестве, и о жизни вообще.
Запомнилось из чего-то недавно прочитанного:
Если судьба больно бьет вас, значит вы заняли не удобное для нее положение.
:)))
Навеяно вот этим снимком (а так же вот этим, и вот этим, да и вообще на ZeissImages таких много). Снимки, кстати, сделаны отнюдь не дешевой камерой (Nikon D800) и еще более недешевым объективом (вроде как самым лучшим в своем классе Zeiss Otus 1.4/55). Как по мне, так вместо 7.5K USD можно было потратить 900USD на самый навороченный iPhone 5s и получать тоже самое...
Но мысля по поводу стрит-фото, все-таки такая: снимающие в жанре стрит-фото пытаются перевести количество в качество.
В большинстве своем, неудачно. Но у некоторых получается. Да так, что обзавидуешься. Автор -- Александр Петросян:
Есть такая штука в разработке ПО, как technical debt. Т.е. вещи, которые должны были быть сделаны, но по каким-то причинам не были. Иногда вы утешаете себя тем, что когда-нибудь в будущем, когда руки дойдут, вы таки расплатитесь по своим старым долгам, вернетесь к коряво написанному коду и, не смотря ни на что, все-таки перепишете его как надо. Излишне говорить, что это напрасные надежды, в большинстве случаев. Нет ничего более долговременного, чем временное. Чудеса, т.е. исключения, конечно, случаются. Но, на моей дырявой памяти это именно чудесные исключения, а не устоявшаяся практика...
Впрочем, от лирики пора переходить к физике. Заговорить о техническом долге заставила необходимость изучить некоторый кусок кода, дабы разобраться с возможностью минимальными усилиями адаптировать его под сильно изменившиеся условия задачи. В процессе изучения пришлось восстанавливать тексты SQL-запросов, которые были зашиты в код. И мне вспомнилась идея двух- или трехлетней давности о том, чтобы выносить тексты SQL-запросов в конфигурационные файлы. Идея эта не нашла своего воплощения, в очередной раз увеличив мой собственный технический долг. А, возможно, сейчас бы она сократила мне время на изучение чужого кода.
Суть идеи вот в чем. Мы для работы с РСУБД из C++ приложений (написанных с использованием SObjectizer, понятное дело) применяем отличную header-only библиотеку OTL. Ее особенностью является наличие т.н. потоков (реализуемых классом otl_stream). Поток связан с SQL-выражением. Если в SQL-выражение нужно подставлять параметры, то эти параметры специальным образом обозначаются в тексте SQL-запроса:
otl_stream s( 1, "INSERT INTO TMP_IDS( id ) " "SELECT " "message_id " "FROM DRS " "WHERE " "received_at < :1<TIMESTAMP> AND " "rownum <= :2<UNSIGNED> ", db_connect ); |
Выделенные жирным фрагменты ":1<TIMESTAMP>" и ":2<UNSIGNED>" -- это и есть параметры для SQL-запроса. Для них перед выполнением запроса нужно задать значения. Значения задаются в стиле C++ных потоков вывода: через operator<<():
s << make_otl_datetime( time_border ) << max_count; |
Вот такой примитивный, но вполне себе успешно работающий подход мы уже очень давно применяем в своих C++ проектах. Про различные ORM-инструменты, скрывающие от разработчика детали работы с БД, мы в курсе. Но, во-первых, C++ не Java, не Ruby и не C#. Как-то в C++ ORM-ов не густо. И, во-вторых, у многих ORM-ов, насколько я знаю, не все так гладко, когда нужно выжимать максимальную производительность из БД. Тут быстро выясняется, что SQL -- это не столько стандарт, сколько соглашение. А у каждой серьезной РСУБД есть свой вариант SQL-я и, если тебе за секунду нужно обработать тысячи строк в разных таблицах, то без задействования специфических для СУБД SQL-выражений далеко не уедешь. Вот и оказывается, что чем примитивнее инструмент, тем проще с его помощью выжимать нужную производительность.
При разработке и отладке приложений мы, естественно, профилируем свои SQL-запросы. Добавляем в них различные хинты для СУБД. Иногда существенно перерабатываем SQL-запросы, переходя от простых запросов над целевой таблицей, к более сложным комбинациям с временными таблицами, накапливающими промежуточные значения...
Однако, практика показывает, что как бы мы не старались на этапе разработки, в эксплуатации, на production-железе под реальной нагрузкой, когда разработчики не могут просто так взять и дотянуться до СУБД, возникают различные странные ситуации. Скажем, несколько дней программный компонент может работать с одной скоростью, а затем на несколько часов его производительность вдруг упадет в разы и проблема будет где-то в БД. В некоторых случаях служба эксплуатации обнаруживала проблемы и выдавала свои рекомендации. Иногда это были дополнительные хинты для SQL-запроса, актуальные для конкретной инсталляции СУБД на конкретном железе.
Отсюда и появилась идея о том, чтобы тексты SQL-запросов сохранялись в конфигурационных файлах приложений. Чтобы эксплуатация, решившая исправить проблемы производительности дополнительным хинтом, могла сделать это самостоятельно, без отвлечения разработчиков. К сожалению, идея не нашла своего воплощения. Хотя, думаю, идея эта здравая и не мешало бы изыскать время на ее воплощение.
Насколько я помню, главными препятствиями к ее реализации были две вещи:
s << named_parameter( "TimeBorder", make_otl_datetime( time_border ) ) << named_parameter( "MaxLines", max_count ); |
Вот такой пример технического долга. Вообще, технический долг -- непростая штука. Временами кажется, что это и не долг вовсе: ведь работает же все, а времени сделать нормально с самого начала никогда не хватает. Но, если речь идет о производстве компанией собственных продуктов, технический долг может стать реальной проблемой. Обуславливающей смерть продукта... Хотя это уже совсем-совсем другая история.