вторник, 30 декабря 2014 г.

[business] Рекламный ролик сервиса PayUP

Появился ролик проекта, стартовавшего во время моего краткосрочного возвращения в Интервэйл в начале 2014-го:

Поскольку от этого предприятия зависит благосостояние дорогих мне людей, оставшихся в Интервэйл-Гомель, то желаю проекту удачи и успешного развития.

Не могу, тем не менее, не отметить, что:

  • сценарий работы сервиса в итоге оказался таким, каким изначально предлагал гомельский офис, и который позволят применить данный сервис и для оплаты в совершенно других условиях (например, при доставке товара из Интернет-магазина курьером). К сожалению, первоначально этот сценарий активно отвергался креативной частью московского офиса, а споры на этот счет, в итоге, свелись к "Ты начальник -- я дурак";
  • сроки запуска проекта довольно точно были предсказаны оценками специалистов гомельского офиса;

[life.cinema] Очередной кинообзор (2014/12)

Подошло время очередного кинообзора. Вот список засмотренных в декабре фильмов, который начинают наиболее понравившиеся, а закрывают -- наименее.

Исчезнувшая (Gone Girl, 2014). Хороший фильм. Правда, мне показалось, что создатели местами перемудрили, местами оставили неувязки. Но все это компенсируется отличной игрой Розамунд Пайк, которая нравится мне все больше и больше :)

Superнянь (Babysitting, 2014). Нечто среднее между “Мальчишником в Вегасе” и “Горько”. Ни до первого, ни до второго, на мой взгляд, не дотягивает, но смотрел с удовольствием.

Разделитель (The Divide, 2011). Довольно своеобразный и мрачный фильм, мне понравилось, но рекомендовать не буду -- очень уж на любителя может оказаться. Тем не менее, это одна из лучших ролей Майкла Бина со времен “Чужих”.

Занесло (Redirected, 2014). Очень мне нравятся криминальные фильмы, в которых затейливым образом пересекается несколько историй, приводящих к неожиданному финалу. Вроде “Карты, деньги, два ствола”, “Большой куш” и “Рок-н-рольщик”. Фильм “Занесло” хоть и не дотягивается до перечисленных фильмов Гая Ричи, но достойным образчиком жанра является. Винни Джонс опять блеснул в наиболее подходящем для себя амплуа.

Молодая кровь (Son of a Gun, 2013). Не шедевр, но добротный и крепкий криминальный фильм. Зачастую именно что-то такое и хочется посмотреть. Так что мне понравилось.

Стрингер (Nightcrawler, 2014). Фильм довольно предсказуем. Но вот то, как Джейк Джилленхол сумел справится с ролью главного героя, прощает немудренность и прямолинейность сюжета.

В финале Джон умрет (John Dies at the End, 2012). Хорошее сочетание укуренности, примитивизма, запутанности и стеба. Посмотрел с удовольствием. А может просто был в должном настроении.

Общак (The Drop, 2014). Хороший сценарий, хорошие актеры. Но результат получился очень уж тягомотным.

Отмороженные (Freezer, 2014). Смотрел с некоторым предубеждением из-за неважных отзывов о фильме. Но оказался вполне себе средний, старательно сделанный фильм. Не шедевр, но посмотреть можно.

Шпион (Spy, 2012). Корейские фильмы уже начинают приедаться, после просмотра некоторого их количества начинает казаться, что все они довольно однотипные и далеко не всегда толковые. Но вот в этом есть хорошая доля иронии, что положительно выделяет фильм из общей массы.

Гость (The Guest, 2014). Начало было многообещающим, но финальная разборка все испортила.

Великий уравнитель (The Equalizer, 2014). Еще по трейлеру было понятно, что главный герой будет настолько крутым, что с ним не смогут сравниться ни горы, ни яйца, а Рембо будет нервно курить в сторонке. Но реальность превзошла все опасения. Плюс ко всему фильм получился на редкость скучным, растянутым и занудным.

Достань меня, если сможешь (Reach me, 2014). Так и не понял, что же это было. Как мне показалось, халтура.

Репортаж 4: Апокалипсис ([REC] 4: Apocalipsis, 2014). Любителям первого фильма можно глянуть ради интереса, к чему же все пришло. Но с первым не сравнится.

В изгнании (Outcast, 2014). Удивительно, но после последнего шлака Николас Кейдж умудрился сняться в чем-то смотрибельном. Только вот фильм предназначен для детской аудитории :)

Я - начало (I Origins, 2014). Во-первых, совершенно не торкнула общая идея фильма. Во-вторых, не понравилось техническая сторона (работа оператора и игра актеров). Посему остался в совершенном недоумении, почему у фильма такой высокий рейтинг.

[life.economic] Сюрприз от БПС-Сбербанка: отказ покупать USD за RUB

БПС-Сбербанк сегодня отказался пополнять долларами карточку со счетом в российских рублях. У них сегодня вообще не было курсов конверсии USD в RUB.

В качестве рабочего варианта предложили украсть ящик водки, водку вылить, бутылки сдать, а вырученные деньги пропить продать доллары за BYR, на BYR купить RUB и уже RUB внести на карточку. Пикантность ситуации в том, что курс продажи RUB был 250 (при курсе покупки 200(!)), да еще к этому и 20% комиссии. Т.е. один RUB мне бы обошелся в 300 BYR.

Было бы интересно услышать объяснение такого феномена, как отказ покупать USD за RUB, от людей, лучше меня разбирающихся в экономике и финансах.

Лично у меня есть мнение, что происходящее связано со случившимся вчера вторым всплеском курса USD по отношению к RUB:

Особенно интересен разрыв между курсом продажи и покупки USD (в цифрах это выражено в столбце "Средн. маржа"). В обычное время средняя маржа находится в районе рубля, а то и меньше.

Возможно, банк считает, что курс доллара к рублю сейчас слишком завышен и покупать доллары по такому курсу сейчас не выгодно, т.к. продать их затем с прибылью не получится.

PS. НБ РБ фактически начал официальную девальвацию BYR. Десять дней назад ввели 30% комиссию при покупке валюты, оставив официальный курс без значительных изменений. Вчера размер комиссии снизили до 20%, но официальный курс USD вырос с 11030 до 11800. Вероятно, еще дней через десять комиссия снизится до 10% при официальном курсе в районе 12700, а еще дней через десять комиссию уберут, при курсе в районе 13700, если не больше.

[prog.c++] libcds обновился до версии 2.0.0

Состоялся первый после переезда на github релиз обновленной версии библиотеки CDS (Concurrent Data Structure) -- вышла версия 2.0.0.

Увидеть ChangeLog новой версии можно здесь. Взять новую версию можно на github или, в виде архива, на SourceForge.

Для тех, кто про libcds слышит впервые: libcds -- это хорошая C++ная библиотека с большой кучей всякого разного для lock-free под вменяемой лицензией. Если нужно что-то C++ное из этой области, то имеет смысл начинать поиски именно отсюда. Тем более, что ее разработчик -- это очень толковый и вменяемый человек из России, с которым можно конструктивно общаться на русском языке (я пробовал, знаю о чем говорю).

понедельник, 29 декабря 2014 г.

[prog.c++] Хороший доклад "Writing robust code"

Доклад "Writing robust code" от David Stone с "Meeting C++ 2014":

Что особенно здорово, так это хороший и неторопливый английский, так что даже я на слух почти все из доклада воспринимал (а вот с секцией вопросов уже было сложнее).

Значительная часть из того, что было рассказано в докладе было усвоено и неоднократно испробовано на практике еще много лет назад. В связи с этим вспоминается такая немного грустная история. В 2003-м нужно было реализовать библиотеку для сериализации и десериализации данных в одном самодельном протоколе передачи данных. Причем использовать ее должны были и мы на своей стороне, и заказчик на своей. Написал я эту библиотеку в соответствии со многими озвученными в докладе принципами (в частности, со строгой типизацией параметров путем введения новых типов данных), снабдил примерами, документаций и отослал заказчику. Заказчик поднял волну, мол что вы для такой простой операции, как парсинг и формирование маленьких PDU на ровном месте целую кучу классов и типов нагородили, да еще и с использованием STL-я в полный рост. Пришлось разработчика заказчика учить использованию библиотеки, а потом еще и на целую кучу тупых вопросов отвечать. Однако, за последующие 6 или 7 лет ее использования у заказчика не было ни одного бага, который бы породила данная библиотека. Зато там, где разработчики заказчика сами работали с сырыми данными, проблем хватало. А так как обычная их практика была свалить всю вину на нас, то разбираться с этими ошибками сначала приходилось нам. Иногда довольно в экстремальных условиях.

Так что в докладе очень правильные и работающие вещи рассказаны. Только вот культура многих разработчиков не позволяет им подняться выше голых указателей и strcpy(). Это неприятие нужно преодолевать, пусть даже это дорого обходится, на уровне разборок между менеджерами, включая топовых. Потом все окупается.

[prog.thoughts] В каких ситуациях полезны дедлайны доставки сообщений?

Думаю, что вопрос о том, в каких ситуациях полезно ограничивать время доставки сообщения от одного агента к другому, интересен не только пользователям конкретных фреймворков (будь то Akka, CAF или SObjectizer). Но и вообще разработчикам, которые используют механизм message-passing для разработки своих приложений. А этот механизм весьма актуален, как для утилизации современных многоядерных процессоров, так и для разработки распределенных приложений, компоненты которых располагаются на разных узлах сети, но должны общаться между собой.

Непосредственная же необходимость данной заметки возникла для пояснения некоторых моментов, затронутых в одной из предыдущих заметок и в обсуждении на SourceForge.

Итак, сходу в памяти всплывает две ситуации, когда было бы желательно ограничивать время жизни сообщения m, отосланного агентом S агенту R.

среда, 24 декабря 2014 г.

[prog.c++] В склерозник: C++ фреймворки для разработки Web-приложений

Попалось сегодня на глаза упоминание нескольких C++ инструментов для разработки Web-приложений, решил собрать все разрозненные ссылки в одном месте, дабы проще было искать, если потребуется.

Примечание. Сам ничем из этого не пользовался, так что дать какую-то характеристику каждому из инструментов не могу.

CppCMS:

CppCMS is a Free High Performance Web Development Framework (not a CMS) aimed at Rapid Web Application Development. It differs from most other web development frameworks like: Python Django, Java Servlets in the following ways:

1. It is designed and tuned to handle extremely high loads.
2. It uses modern C++ as the primary development language in order to achieve the first goal.
3. It is designed for developing both Web Sites and Web Services.

It is available under open source LGPLv3 license and alternative Commercial License for users who needs an alternative license for proprietary software development.

Pion:

C++ framework for building lightweight HTTP interfaces

The Pion Network Library is published under the Boost Software License

Tntnet:

Tntnet is a web server which allows users to develop web applications using C++. It has a template language ecpp where C++ code can be embedded into html similar to php or jsp. The pages are compiled and linked into a shared library. The result is a native web application which is compact and fast.

Features
    Template engine for HTML
    SSL support
    Url mapping
    API for http, http upload, authentifikation,
    Setting for http headers and cookies
    Automatical session management

License

All software published under tntnet.org is licensed under the LGPL with template extension. It is explicitly allowed to use the software in commercia products as closed source (although we always recommend to publish source code with all software).

TreeFrog Framework:

TreeFrog Framework is a full-stack Web application framework. Written in C++, it is lightweight (low resource demands), and allows extremely fast working.

With the aim of reducing development costs while producing a C++ framework, a policy of "convention over configuration" has been followed. The configuration file has been made as small as possible. Because it provides help in automatic generation of code for template systems (scaffolding), O/R mapping and ORM, developers are free to focus on logic.

TreeFrog Framework is open-source software, under the new BSD license (3-clause BSD License).

Wt:

Wt (pronounced as witty) is a C++ library for developing web applications.

The API is widget-centric and uses well-tested patterns of desktop GUI development tailored to the web. To the developer, it offers abstraction of many web-specific implementation details, including client-server protocols (HTTP, Ajax, WebSockets), and frees the developer from tedious JavaScript manipulations of HTML and dealing with cross-browser issues. Instead, with Wt, you can focus on actual functionality with a rich set of feature-complete widgets.

Wt may be used using either an Open Source (GPL) or a Commercial License.

Silicon:

The Silicon Web Framework.

Silicon is a high performance, middleware oriented, C++14 http web framework. It brings to C++ the high expressive power of other web frameworks based on dynamic languages without introducing run-time overhead. Its compile-time static metaprogramming paradigm allows to match the performances of servers written in C.

The MIT License.

Cutelyst:

Cutelyst! The Qt Web Framework

Cutelyst has a plugin for uWSGI which give us support for HTTP, FastCGI, uWSGI protocols. It also features a WSGI server written in Qt which can deliver even faster HTTP or FastCGI responses. Running standalone or behind a web server is really easy.
With your application logic written in C++ your application get's really small, a full CMS (like this one) uses around 4 MB which can be shared with other instances of the same application. You save your RAM and CPU while offering your users with faster response times.

GNU LGPL v.2.1

Так же в POCO, Boost (Asio) и ACE (не в самом ACE, а в дополнительных модулях) есть что-то вроде HTTP-серверов, на базе которых можно делать что-то вроде Web-приложений/Web-сервисов.

Так же можно посмотреть на ULib C++ Library, которая позволяет реализовывать разные типы серверных приложений.

вторник, 23 декабря 2014 г.

[prog.c++] Хорошая серия статей Б.Страуструпа "Five Popular Myths about C++"

Уже давал ссылки на эти статьи в G+, но по завершении серии имеет смысл собрать их все вместе:

Part 1.
Part 2.
Part 3.

понедельник, 22 декабря 2014 г.

[life] Да все будет хорошо, тем более, что в кризис хорошо работается

Тяжелая штука кризис, изматывающая. Вчера доллар по столько, сегодня по столько, и если бы вчера... А сегодня...

Еще более страшная и изматывающая штука -- это гражданская война. Если кто-то из испражняющихся в соцсетях на тему ватников и бандеровцев еще не понял, то проснитесь: вы уже воюете! Хотите вы того или нет, но сегодня вы уже стреляете в своего соседа, а то и близкого родственника, пока еще только словом. И если будете продолжать в том же духе, то завтра-послезавтра вам придется стрелять уже по-настоящему. Или в вас.

Поток негатива вокруг такой, что очень остро осознаешь, что "смерть есть смерть и до нее какое-то время" (с) Глупо тратить это время на попытки предугадать ход кризиса или отфренживание знакомых в соцсетях за очередной пост, с которым не согласен.

Почему?

Потому, что очень здорово сказал герой Папанова в х/ф "Холодное лето 53-го года": "Как хочется пожить по-человечески и поработать. Да, да, поработать".

Вот именно по-человечески поработать и хочется. Кому-то нравится путешествовать. Кому-то развлекаться. Кому-то проверять себя на прочность в экстремальных условиях. А мне нравится работать, "женат на работе" -- это про таких, как я.

Тем более, что потраченное на обучение и приобретение профессионального опыта время не прошло даром. Могу брать задачи, вычленять самую суть, находить или придумывать решения, воплощать их в жизнь. Могу программировать, могу проектировать, могу документировать. Могу связно излагать свои мысли, как в устном, так и в письменном виде, будь то начальству или подчиненным. Могу объяснять, показывать, требовать и получать на выходе именно то, что нужно. Могу подбирать людей, могу увольнять. Могу учиться и учусь постоянно, могу учить. Могу брать ответственность на себя, могу помогать лидерам. Думаю, что пока в этом мире есть потребность в людях, которые могут "взять и сделать", без дела не останусь.

Ну а раз так, то фиг с тем, что будет дальше. Пока есть возможность работать, нужно просто работать. Тем более, как правильно сказал Сергей Лукьяненко, "в кризис очень хорошо работается". Все остальное приложится.

Своим читателям хочу пожелать максимально полно использовать все возможности, которые есть здесь и сейчас. Ибо фиг знает, что будет завтра. Так что развлекайтесь, путешествуйте, проверяйте себя на прочность в экстремальных условиях, стройте дома, растите деревья... Ну и, конечно же, играйте в дартс -- это здорово! ;)


PS. На данный момент работу не ищу, занимаюсь своим проектом. Не важно, выстрелит он или нет -- это дело случая. Дело в другом. Аркадий Евгеньевич Косарев, к сожалению, уже покойный, в середине 90-х собрал в гомельском КБСП уникальную команду и заразил нас общей идеей. Тогда мы не смогли завершить начатое и сказать "Мы сделали это!". Теперь у меня есть уникальная возможность исправить это. Хочется получить продукт с интересными идеями, с хорошим качеством, с нормальной документацией, с полезными примерами. Чтобы не стыдно было. Этим и занимаюсь. Ну а если это кому-то пригодится, то тогда точно все будет хорошо ;)

воскресенье, 21 декабря 2014 г.

[life.sport.darts] Только что Борис Кольцов открыл новую страничку в истории российского дартса

Если не ошибаюсь, такое происходит впервые: российский игрок попадает в основную сетку Чемпионата Мира по версии PDC. Победив в очень нервном матче отборочного раунда японца Харуки Мураматсу, россиянин Борис Кольцов вышел в первый круг ЧМ-2015 и через пару часов будет играть против Кевина Пайнтера.

Upd. 1-3 проигрыш Кевину Пайнтеру :( Имхо, не смотря на взятый лег, матч у Бориса не задался. Возможно, это объективно уровень отечественного дартса на данный момент. Но, зато у нас стало чуть больше людей, которые на своем опыте знают, что такое матчи с такими звездами на такой сцене.

PS. Наверное, далеким от дартса людям это мало о чем говорит, но вообще-то это просто афигенно круто! Что-то вроде возможности для российского игрока попасть на ЧМ по снукеру.

PPS. Зимой 2013 мне довелось играть против Бориса Кольцова (понятное дело 4-0 не в мою пользу). Так что ощущение такое, как будто это мой приятель на ЧМ мира сейчас играет :)

суббота, 20 декабря 2014 г.

[prog.c++] Механизм registered_delivery для сообщений в SObjectizer

Во вчерашней заметке про message-passing я сказал, что есть идея еще одного способа взаимодействия между агентами. Эта идея начинает приобретать вполне конкретные очертания.

Смысл в том, что сейчас отсылка сообщения -- это никаким образом не контролируемая операция. Т.е. агент a1, отославший сообщение m1 агенту a2 никак не может узнать, дошло ли сообщение m1 до a2 или нет. Может оно потерялось, потому, что агента a2 нет или он не успел еще подписаться на m1? Может оно потерялось, потому, что агент a2 находился в состоянии, в котором обработка m1 невозможна? Может агент a2 выбросил исключение, когда обрабатывал m1?

пятница, 19 декабря 2014 г.

[prog.thoughts] Message-passing: чем примитивнее, тем лучше?

Нижеследующий текст является чем-то вроде рефлексии вокруг механизмов взаимодействия между агентами в SObjectizer. Но, полагаю, изложенный материал будет интересен более широкому кругу читателей, которые разрабатывают собственные инструменты на основе message-passing-а или же используют подобные инструменты в своей работе.

четверг, 18 декабря 2014 г.

[prog.thoughts] FiniteStateMachines vs Coroutines

Со времени общения с Григорием Демченко в комментариях к заметке про "асинхронность без телепортации" не оставляет вопрос о том, как провести хороший водораздел между подходами на основе конечных автоматов и на основе сопрограмм. С одной стороны, сопрограммы нонче -- это модно и молодежно. Причем сейчас я совершенно серьезен. Примеры того, как сопрограммы сокращают объем кода можно увидеть как в статье Григория Демченко на Хабре, так и, например, в документации к Asio.

Но, с другой стороны, уже лет двадцать как использую подход на основе конечных автоматов и получаю вполне себе нормальные результаты. Конечно же, никто не признает себя плохим программистом, поэтому и мне кажется, что в моих проектах все было нормально, а как оно на самом-то деле... Ряд LOR-овских экспертов твердо убежден, что программировать я не умею от слова совсем ;) Тем не менее, проекты выполнялись, программы работали, прибыль приносили. Посему далее считается, что конечные автоматы могут успешно использоваться в concurrent programming.

Поэтому-то и интересен вопрос: действительно ли FiniteStateMachines и Coroutines объективно имеют разные области применения? Или же я из-за старперства застрял на конечных автоматах и мне просто уже не хватает гибкости ума для того, чтобы оценить и перейти на использование более передового подхода на основе сопрограмм (хотя самим сопрограммам уже сто лет в обед, т.к. впервые о них заговорили в 1958 году).

Мне кажется, что есть, как минимум, один объективный критерий, который позволяет указать, в каких случаях подход на основе конечных автоматов будет выгоднее сопрограмм (и наоборот).

среда, 17 декабря 2014 г.

[life.photo] Свершилось: многопиксельная среднеформатная беззеркалка

То, о чем уже давно говорили аналитики, свершилось: PhaseOne выпустил среднеформатную беззеркалку под названием ALPA.

На официальном сайте PhaseOne пока отдельного раздела для этой камеры не видно, но можно скачать PDF-ку с некоторыми подробностями.

Как я понял, там совсем новая серия оптики (!), а вот цифровой задник используется обычный, PhaseOne-овский IQ. Соответственно, можно получить 50-ти, 60-ти или 80-мегапиксельную камеру.

В общем, ситуация на рынке среднеформатных камер должна измениться. И кто знает, может уже скоро можно будет всерьез выбирать между среднеформатной беззеркалкой и топовой DSLR, вроде Nikon D810. И не факт, что D810 окажется по совокупности всех факторов дешевле.

[prog.memories] Помнится, обрабатывал когда-то большие объемы данных на Ruby...

Вот эта запись в FB навеяла воспоминания об одной из задачек, которую мы решали в "Интервэйле" сначала с помощью Ruby, а затем C++.

Суть была в том, что один из программных комплексов писал на диск множество "протокольных файлов", т.е. файлов, в которых фиксировались следы обработки транзакций. Вроде такого: начали фазу #1, получили результат фазы #1, начали фазу #2, получили результат фазы #2 и т.д. По мере накопления информации в протокольных файлах ее нужно было извлекать и записывать в большую историческую БД. А уже по содержимому БД затем строилась всяческая статистика и отчеты.

Где-то в 2005-м или 2006-м для решения задачи импорта протокольных файлов в историческую БД был использован язык Ruby. Что казалось разумным. Код короткий, не сложный, основное время тратится на парсинг текста из файла и операции с БД. Т.е. в основном должны были работать низкоуровневые процедуры, написанные на C (либо в дебрях работы с регулярными выражениями, либо внутри ODBC-драйверов), так что общая тормознутость Ruby препятствием не должна была быть.

Поначалу все работало как задумывалось, но и объемы данных были небольшими, всего несколько миллионов записей за сутки. Но время шло, росли размеры протокольных файлов и где-то к концу 2009-го, когда нужно было перелопачивать уже десятки, а то и сотни миллионов записей в сутки, стало очевидно, что недалек тот день, когда Ruby-скрипту для импорта в БД информации, собранной за 24 часа работы программного комплекса, потребуется больше 24-х часов работы.

Нужно сказать, что сам скрипт импорта работал по крайне примитивному алгоритму. И можно было бы получить заметный выигрыш за счет смены алгоритма. Но предварительные разбирательства с узкими местами показали, что огромное количество времени тратится внутри Ruby-библиотеки для работы с СУБД. Причем тормозит именно Ruby-новый код, который формирует обращения к ODBC-слою. Т.е. здесь тормоза Ruby показали себя во всей красе.

Соответственно, ребром стал совсем не праздный вопрос: а имеет ли смысл реализовывать на тормозном Ruby более изощренный алгоритм импорта, если часть выигрыша все равно будет съедена неповоротливостью Ruby-нового рантайма?

К этому добавилась еще одна проблемка -- динамическая типизация. Динамическая типизация очень хороша в маленьких скриптах, написанных на выброс. Но когда приложение живет и развивается годами, когда разные его куски переписывают/дописывают разные люди, когда в течении месяцев в работающий код никто вообще не заглядывает, то динамическая типизация начинает играть против разработчика. Слишком много времени уходит на то, чтобы восстановить детали работы того или иного куска кода. Особенно, когда там задействуются более-менее сложные структуры данных. В статически-типизированном языке довольно просто -- сразу видно, что вот здесь список из объектов, внутри которых словари, элементами которых являются мультимножества, ключом в которых вот это, а значением -- вектор вот таких структур. Тогда как в Ruby-коде такие вещи нужно как-то по-другом раскапывать. Даже при наличии хорошего кода и комментариев в нем.

В общем, году в 2010-м мы все это дело переписали на C++. Заодно и применив более хитрый алгоритм, в котором часть данных предварительно накапливалась и обрабатывалась в ОП, тем самым, существенно уменьшалось количество последующих запросов к СУБД. Здесь было довольно много работы в ОП, и мне даже сложно представить, насколько все это было бы медленнее в Ruby. В итоге, новая C++ная версия импорта оказалась, как минимум, на порядок быстрее предыдущей или даже более быстрой, но этого я уже не помню, склероз... :) Может бывшие коллеги меня поправят. (Upd. Очевидцы подсказали, что время обработки было снижено с двух десятков часов до десятка минут.)

Эта история стала для меня еще одним подтверждением того, что скриптовые языки и серьезные задачи -- это плохо совместимые вещи. Огромное достоинство программ на скриптовых языках для меня -- это возможность поправить что-то прямо на целевой машине. Со скомпилированным в бинарник C++ кодом так не получится, а вот в Ruby-коде учесть какую-то особенность целевой платформы прямо на месте -- запросто. Однако, как только появляется намек на то, что программа должна работать быстро и в течении длительного времени, то от скриптов и динамики лучше сразу уйти. Тем более, что современные мейнстримовые компилируемые языки (C++, Java, C#) уже обзаводятся конструкциями, позволяющими писать меньше кода, но не терять ни в читабельности, ни в скорости работы.

вторник, 16 декабря 2014 г.

[life.humour] Вчерашним падением RUB навеяло

Прошу прощения, что опять пишу о том, в чем не разбираюсь. Но, имхо, с таким курсом валют РФ смело может снять все запреты на поставку продукции, которые были введены в качестве ответа на западные санкции. Например, на поставку польских яблок. Смысла продавать их в РФ, пересчитав стоимость из USD в RUB не будет. Но и винить за это РФ не получится -- невидимая рука рынка, ёптыть.

Походу, правительству РФ нужно только приветствовать рост USD/EUR и всячески поддерживать эту тенденцию. Тогда за голову схватятся не только польские фермеры. Но вообще все, кто импортирует что-то свое в РФ, начиная от запчастей для авто и заканчивая сложной техникой и технологиями. Или живет за счет туристов из РФ...

PS. Уважаемые читатели из России, простите за этот стеб. Меня падение RUB тоже касается, хоть в меньшей степени, но тоже чувствительно. Так что это просто попытка встречать неотвратимо надвигающийся звиздец с юмором :)

понедельник, 15 декабря 2014 г.

[life.sport.darts] Мои личные впечатления от прошедшего Кубка Гомеля

Вчера мы провели первый настоящий городской турнир "Кубок Гомеля 2014". Разговоры о чем-то подобном велись на протяжении последних 4-х лет, как внутри неформального дартс-клуба "Интервэйл-Гомель", так и на официальном форуме БПФД, где время от времени всплывала тема "местечковых турниров". Но воплотить в жизнь мы смогли это только сейчас.

суббота, 13 декабря 2014 г.

[life.sport.darts] Кубок Гомеля 2014

14-го декабря 2014 в СШ№66 г.Гомеля состоится розыгрыш Кубка Гомеля по дартс. Приглашаются все желающие игроки из Гомеля и Гомельской области. Участие бесплатное. Начало регистрации и разминки в 11:30.

Цель турнира -- это популяризация дартса в Гомеле и консолидация игроков, которые в городе есть, но которые не знают друг о друге. Лучшие игроки получат памятные призы: победитель будет награжден кубком и медалью, призеры -- медалями.

Более подробная информация о турнире на официальной страничке мероприятия.

В этот раз анонс турнира сделан так же на городском новостном портале "Сильные новости". Если у кого-то из читателей есть контакты с порталами onliner.by и tut.by, пожалуйста, подскажите, куда нужно постучаться, чтобы и там тоже сделать подобный анонс. Да и вообще любые идеи о том, где еще можно разместить эту информацию, будут с благодарностью выслушаны.

пятница, 12 декабря 2014 г.

[management] Лень русского человека -- это...

Лень русского человека - это естественная реакция на кипучую деятельность руководящих им идиотов.

Отсюда.

четверг, 11 декабря 2014 г.

[life.photo] Возможность пофотографировать диких орланов под Речицей

Информация для любителей фотоохоты: недалеко от поселка Глушец Речицкого района есть полузаброшенная деревенька Красный Октябрь. Там обосновался интересный человек -- Дмитрий Янков.

Неподалеку от Красного Октября обитают орланы. И Димитрий ищет возможности организовать что-то вроде "насиженных мест" для фотоохотников, из которых можно было бы заниматься фотографированием птиц не тревожа их, но получая хорошие, интересные снимки.

Для этого Дмитрию нужна помощь одного-двух фотографов-энтузиастов. Может быть кто-нибудь захочет подъехать в Красный Октябрь на день-два-три и поучаствовать в размещении и обустройстве скрадков для съемки птиц? Место для проживания и нормальные условия быта Дима обеспечит.

Желающие могут связаться с Дмитрием по телефону (+375(44)512-12-20 или +375(33)361-62-12) или через его страничку в ВКонтакте.

PS. Для интересующихся вот фоторепортаж из Красного Октября от Алексея Голубева.

PPS. Мопед не мой, просто дал объяву :) На самом деле, я сейчас сам жалею о том, что не увлекаюсь фотоохотой, нет у меня ни соответствующего фотооборудования, ни экипировки. А возможность, вообще-то говоря, классная. Очень надеюсь, что все сложится хорошо и у нас неподалеку от Гомеля появится место, где можно будет пофотографировать настоящих, диких орланов.

вторник, 9 декабря 2014 г.

[blog] Проверка отображения фрагментов кода

Как выясняется, у некоторых читателей, которые следят за моим блогом через RSS, есть проблемы с отображением раскрашенных фрагментов кода. Например, если открыть в браузере ленту фида http://feeds2.feedburner.com/Eao197, то тексты заметок в ленте должны отображаться в тех же цветах, что и в самом блоге. Но, скажем, Firefox может терять цвет фона в примерах кода.

Поэтому ниже приведены несколько фрагментов, в которых цвет фона задается разными способами. Если у кого-то из читателей будут проблемы в RSS-ленте, то сообщите в комментариях подробности (какой фрагмент, какой браузер и т.д.)

#1 (табличка внутри div, цвет фона для div задан через атрибут style)

if __FILE__ == $0
  include TournamentBasket
  include TournamentBasket::SingleElimDetails

#2 (табличка сама по себе, цвет фона для нее задан через атрибут style)

if __FILE__ == $0
  include TournamentBasket
  include TournamentBasket::SingleElimDetails

#3 (табличка сама по себе, цвет фона для нее задан через атрибут bgcolor)

if __FILE__ == $0
  include TournamentBasket
  include TournamentBasket::SingleElimDetails

понедельник, 8 декабря 2014 г.

[prog.flame] ФП приходит в мейнстрим и... занимает нишу COBOL?

Просматривая свежий пост про пример использования парсинга XML в Scala на eax.me, поймал себя на неожиданной мысли: где-то что-то отдаленно похожее я уже видел. Кстати говоря, пост хороший. Имхо, именно так нужно привлекать внимание людей к языкам/технологиям/подходам/парадигмам. Небольшой, но практичный пример, вполне себе самоценный и самодостаточный. Собственно, пупуляризаторам чего бы то ни было (в том числе и ФП), на заметку.

Довольно симпатично выглядят некоторые фрагменты кода в примере, скажем, вот этот:

val postsMap =
  postsXml.map{
    n => ( (n \ "thread" \ dsqid).text.toLong,
           (n \ "createdAt").text,
           (n \ "author" \ "name").text,
           (n \ "message").text,
           n
         )
  }.filter{
    case t =>
      (! (t._5 \ "isDeleted").text.toBoolean ) &&
        (! (t._5 \ "isSpam").text.toBoolean )
  }.groupBy(_._1).filter{
    case (k,v) => threadsMap.get(k).isDefined
  }.map{
    case (k,v) =>
      ( threadsMap(k),
        v.map(t => (t._2, t._3, t._4) ).toArray.sortBy(_._1)
      )
  }

Сперва подумалось, что, блин, обработка данных посредством конструкций из ФП выглядит весьма привлекательно. Хотя какая-то доля лишнего "синтаксического оверхеда" (с) таки присутствует. И что от него можно было бы избавиться. Но, если синтаксис будет сильно заточен под манипуляции над данными, то....

...то в памяти всплывают отрывочные воспоминания о такой штуке, как CODASYL. Был когда-то такой мертворожденный стандарт для работы с данными, представленными в иерархической и сетевой моделях данных. Базировавшийся на COBOL-е. А COBOL -- это же как раз язык для обработки данных.

Конечно, если сравнивать примеры кода на COBOL/CODASYL с современными примерами на Scala, на первый взгляд будет казаться, что это совершенно разные вещи. Но мне представляется, что по сути, это лишь очередная попытка записать что-то подобное:

      PROCEDURE DIVISION.
       CONTROL-PARA.
      *
      * CONTROL PARAGRAPH. DATABASE IS INVOKED AND PRIVACY
      * KEYS SPECIFIED. READS FIRST RECORD FROM INPUT FILE
      * AND CALLS MAIN PROCESSING ROUTINE UNTIL A DATABASE
      * ERROR OCCURS OR AN END OF FILE CONDITION IS SIGNALLED.
      * WHEN AN ERROR OCCURS THE ENTIRE TRANSACTION IS
      * ABORTED OTHERWISE IT IS SECURED.
      *
           OPEN INPUT CARINP.
      #    INVOKE DBMS.
      #    PRIVACY KEY FOR UPDATE OF ALL AREAS IS 'CAR-LOCK'.
      #    PRIVACY KEY FOR STORE OF RECORD DEPOT IS 'NEW-DEPOT'.
      #    PRIVACY KEY FOR INSERT OF SET DEPOT-CARS IS 'CAR-INPUT'.
      #    PRIVACY KEY FOR INSERT OF SET MECHANICS IS 'MECH-AMEND'.
      #    OPEN AREA CAR-AREA USAGE-MODE IS UPDATE.
      #    START TRANSACTION TRAN-ID, UPDATE.
           PERFORM DATA-INPUT.
           PERFORM PROCESS-TRANS UNTIL EOF OR DB-ERR.
           IF DB-ERR PERFORM ABORT-TRANS
           ELSE PERFORM END-TRANS.
      #    CLOSE ALL AREAS.
      #    EXIT DBMS.
           CLOSE CARINP.
           STOP RUN.

Но только в современном, модном и молодежном, ФП-шном стиле :)

PS. Ну и раз уж в кои-то веки затронул тему ФП, то чтобы два раза не вставать. Посмотрел видео доклада Сергея Зефирова (aka thesz) с недавней конференции f(by). Повеселил ответ Зефирова на вопрос про использование Haskell-я в mission critical приложениях (приблизительно на 48:00). Типа, напишу на Haskell-е генератор, который сгенерирует уже прикладной код на низкоуровневом языке приложения из Haskell-евского DSL-я. Ну, может в моделировании процессоров этот подход разумен. Однако, для какого-нибудь OZON-а или Pleer.Ru (не говоря уже про eBay и Amazon) их система онлайн-торговли есть самое что ни есть mission critical приложение. Забавно было бы посмотреть на попытку реализовать что-то подобное на Haskell-евском DSL-е, из которого бы генерировался PHP или Java, или даже C-шный код :) Понятно, что вопрос задавали про несколько другие mission critical приложения, но, AFAIK, современные системы управления сложным оборудованием, разрабатываемые с использованием стандарта DDS, это тоже очень и очень объемные задачки (например).

PPS. На счет COBOL-а, давным-давно достигшего "состояния бессмертности": #1 и #2.

воскресенье, 7 декабря 2014 г.

[life.craftsmanship] Красивый видеоролик про изготовление ножа

Кстати, вопрос к читателям из Гомеля (да и Минска, пожалуй): а у нас есть такие мастера? Я бы с удовольствием пофотографировал такого умельца за работой. По типу вот такой вот серии, только с учетом того, что за прошедшие два года я чуть побольше поднаторел в фотографии (например, из не очень давнего).

пятница, 5 декабря 2014 г.

[soft] Хорошее интервью с Мартином Пилецки

С подачи Славы Костина прочел интервью Мартина Пилецки, руководителя блока "Информационные технологии" "Альфа-Банка": «ИТ-стратегия должна стать ДНК компании».

Имхо, очень толково. Некоторые фрагменты по своей точности просто разрывают на кусочки. Вот, например:

Невозможно аутсорсить бардак. А многие совершают ту ошибку, что аутсорсят свой бардак. В результате получается бардак и внутри компании, и вовне ее.

И о причинах бардака и неудач (в том числе и с аутсорсингом):

...Аутсорсинг — это высший пилотаж. Если ты не способен управлять «кукурузником», как ты собираешься управлять Boeing-747? Я видел много проектов аутсорсинга, которые закончились очень неудачно. Видел много попыток создания банками своих дочерних ИТ-компаний, которые закончились очень неудачно. Видел много светлых идей, которые привели к плачевным результатам, поскольку их реализовывали безграмотные и трусливые менеджеры...

...Некоторые думают, что могут перейти на аутсорсинг, чтобы топ-менеджеры не были вовлечены в решение вопросов, а CIO мог в 17.00 уходить на свой гольф или на очередную конференцию, где он будет рассказывать о своих успехах. Так не получится...

...С моей точки зрения, в России будут успешны те, кто сможет объединить в этом топ-менеджмент, бизнес и ИТ. Обычно много говорят о проблемах отношений бизнеса и ИТ. Но есть и третий участник — это топ-менеджмент. Это треугольник: бизнес, топ-менеджмент и ИТ. Без топ-менеджмента невозможно никакое продвижение... Многие топы здесь думают, что они находятся где-то на вершине, и то, что происходит внизу, им «по барабану». Но это их личная ошибка.

Ну и в завершении очень правильные слова:

Нужны те, кто понимает бизнес. Те, кто умеет работать своими руками. Нам не нужны высокооплачиваемые звезды, за которых все делали их команды. К сожалению, те, кто может сам что-то построить своими руками, — это самая редкая категория специалистов.

В 2001-м году я оказался в компании, состоящей из людей, способных построить что угодно своими собственными руками. Это было непросто, но очень круто. Но по-настоящему непросто стало тогда, когда компания начала их терять, не имея возможности найти адекватную замену. Так что Мартин Пилецки совершенно прав -- умеющие что-то строить своими руками встречаются крайне редко.

понедельник, 1 декабря 2014 г.

[economic.politic] Из непонятого про падение RUB

Не люблю писать про то, в чем не разбираюсь, но временами приходится. Вот как сейчас про падение курса RUB.

Некоторые авторы в Интернетах пишут про то, что нынешнее падение RUB -- это следствие внешнего воздействия (понятно чьего) на РФ. Перекрыли источники кредитования. Снизили цены на нефть. Кредиты нужно возвращать, а долларов внутри мало, поэтому при увеличении спроса на них естественным образом увеличивается их стоимость, т.е. рубль падает.

Эта часть как бы понятна. Хотя картинка наверняка не такая простая, но для неспециалистов в финансовых вопросах пойдет. Недоумение вызывает другой момент. При падении внутренней валюты импорт становится все менее и менее привлекательным. Т.е., грубо говоря, если произведенная в России бутылка водки стоила 100р., то она и будет стоить 100р. А вот ввезенная из Великобритании бутылка виски будет стоить уже не 1000р., а 1500р. Соответственно, ввозить виски в РФ в таких же количествах, как и раньше, смысла нет, не раскупят, затраты не отобьются. И ладно бы речь шла о таких мало кому нужных вещах, как шотландский виски. Ведь изрядная доля практически любой высокотехнологичной продукции Россией импортируется.

Посему возникает вопрос: а какой интерес западным странам в снижении курса рубля, если изрядную часть своей продукции они как раз поставляют в РФ, даже не смотря на введенные Россией санкции? Куда они будут девать свои технологии, производственные линии, станки, инструменты и комплектующие, если поставлять их в РФ будет экономически не выгодно? Вряд ли в Китай или в США :)

Так что закрадывается у меня смутная мысль, что если у кого-то в РФ была идея инициировать в стране реальное импортозамещение, то вот такой поворот событий с серьезным обвалом курса рубля -- это просто сказочно удобный случай претворить данную идею в жизнь. Соответственно, зачем удерживать рубль и, тем более, пытаться вернуть его к предыдущим отметкам? Наоборот, 60р за доллар в этом случае даже лучше, чем 52 :) Ну а там уже такие вещи, как российский iPhone, российский Windows и российский Office перестают казаться такими уж фантастическими и смешными вещами.

PS. Практический вопрос. Может кто знает: цены на аренду офисных помещений в крупных российских городах вроде Москвы, Питера и Новосибирска в связи с ростом доллара тоже растут?

PPS. В качестве шутки юмора. Ведь доступ к кредитам перекрыли России, а не Белоруссии. Так почему бы белорусским банкам не начать кредитовать российские банки? ;) По слухам, Белоруссия уже стала эксклюзивным поставщиком в Россию таких продуктов, как свежайшие устрицы и нежнейшие сыры. Почему бы не воспользоваться ситуацией и на рынке кредитования? :)))

воскресенье, 30 ноября 2014 г.

[life] Чье-то средневозрастнокризнесное про жизнь

Вот в этой статье есть несколько фрагментов, точность которых отлично осознается при прохождении через разные стадии кризиса среднего возраста. Утащу их к себе в блог, убрав привязку к сегодняшним политическим реалиям:
...Кстати, о жизни.

А как бывает, собственно, в жизни?

А в жизни бывает обычно так.

Сначала ты думаешь, что все у тебя будет просто и прекрасно. Ты будешь долго учиться на одни пятерки, а потом будешь долго работать с большим интересом и за большие деньги, и любовь у тебя будет взаимная, и на всю жизнь, и волосы длинные, густые, и окно с видом на крыши и колокольню, и Париж, и Венеция, и вся мировая география в загранпаспорте, и двое детей – мальчик и девочка, и родители будут жить до ста лет, и все прочее, к чему принято стремиться и о чем мечтать...
...Так ты думаешь.

Ну а потом всегда оказывается, что...
Сначала ты, злой и усталый, раз за разом штурмуешь что-нибудь, что для тебя так желанно, а тебе каждый раз отказывают, и каждый раз что-то мешает. Наконец ты своего уже добился, но тут у тебя начинаются другие проблемы, болит и требует внимания уже что-то другое.

А потом в твоей жизни и вовсе начинает разваливаться все одновременно.

Ты надеялся, что устроишься на ту работу – и не получилось.

Ты надеялся, что тебя полюбит Дуся – и не получилось.

Ты надеялся быть богатым, здоровым и веселым – и не получилось. А получилась – странная и местами страшная чересполосица, когда тут вроде бегаешь, и стараешься, и деньги платят, а здесь уже нужно платить самому еще больше, и еще долги, и родственники-пенсионеры, болеют, и хочется уехать, а уже не можешь, а туда смотришь – и впереди ничего, кроме бедности и безнадежности, и еще толстеешь, и нога не ходит, а тут вроде и ничего, и настроение почему-то хорошее, и мягкий снег валит, и выпить хочется, но не с горя, а так просто, потому что жить хорошо.
Но в целом все равно не очень хочется иметь со всем этим дело.

Не хочется даже на расстоянии смотреть на этот не имеющий смысла, развития и хэппи-энда поток из утренней суеты, вечерней тупости, пробок, похмелья, врачей, мужского вранья, женской истерики, детского крика, старческих капризов, и многих других мелочей жизни, которая то ли не складывается, и ты сам во всем виноват, то ли тебе еще повезло, и все пока еще благополучно, а то ли просто не повезло, но ты все равно виноват, не понять; когда долго живешь, то уже ничего не понять, повторяю...
PS. Когда накрывает первая волна кризиса среднего возраста, от таких мыслей реально хреново становится. Потом ничего, привыкаешь, начинаешь смотреть на это как-то отстраненно и философски.

[life.cinema] Очередной кинообзор (2014/11)

Подошло время очередного кинообзора. Как обычно, в начале списка идут наиболее понравившиеся мне фильмы, в конце -- наименее.

Патруль времени (Predestination, 2014). Отличная фантастика. Хорошо сыграно. Хорошо снято. А музыкальное сопровождение заслуживает самых лучших похвал, по крайней мере, от меня.

Обитель проклятых (Eliza Graves, 2014). Очень понравилось.

Горько! 2 (2014). До первого фильма чуть-чуть не дотянули. Но и не испортили.

Кино про Алексеева (2014). Поставил бы этот фильм на первое место в ноябрьском рейтинге, если бы не его неспешность. Однако, если смотреть на скорости в 1.2-1.3 раза быстрее нормальной, то очень здорово. Маленький спойлер: смотреть нужно обязательно до самого конца.

Связь (Coherence, 2014). Замечательный пример, как хорошая фантастика получается без многомиллионных бюджетов, крутых режиссеров и мегазвездных актеров.

Интерстеллар (Interstellar, 2014). Фильм, конечно, крутой. И, наверное, это одна из лучших фантастических лент последних лет. Но меня лично не зацепил. Так что посмотреть его нужно, но не следует ждать чего-то выдающегося.

Дурацкое дело нехитрое (Kraftidioten, 2014). Очень своеобразный криминальный фильм. Просто удивительно, как в результате такого неспешного повествования в фильме образовалось столько трупов. Ну а финальный эпизод с незадачливым парашютистом вообще порвал на кусочки.

Джон Уик (John Wick, 2014). Динамичный олдскульный боевик. Но это чистое развлекалово и при просмотре мозги нужно выключать полностью, иначе смотреть будет невозможно ;)

Мисс Медоуз (Miss Meadows, 2014). Фильм так себе. Но вот насколько точно Кэти Хомлс попала в роль очень странной главной героини -- вот это впечатляет.

Ноль Часов (La hora cera, 2010). Показательный пример того, что при наличии хорошего сюжета, нормальный фильм может быть снят не только в Голливуде, но и в Венесуэле.

Гарри Браун (Harry Brown, 2009). Очень неоднозначные впечатления. Актерская игра Майкла Кейна выше всяких похвал. Но вот в пожилого мстителя, отстреливающего английскую шпану, поверить не удалось. Тогда как атмосфера ужаса и безысходности из-за этой самой шпаны в фильме передана на пять с плюсом.

Ярость (Fury, 2014). Фильм слишком нудный и затянутый, чтобы быть хорошим. Но к точности исторической реконструкции отнеслись очень тщательно. В общем, снято достойно, но в целом мне не понравилось.

Прежде чем я усну (Before I Go to Sleep, 2014). Снято хорошо, но до уровня “Помни” (Memento, 2000) не дотягивает.

Выпускной (2014). Конечно, это не “Горько”, но получилась неплохая комедия. Нормально сняли, без перекоса в пошлятину.

Катастрофа (Blue Ruin, 2013). Блин, суровый фильм. Нудный, бессмысленный и беспощадный, но суровый.

Париж: Город мертвых (As Above, So Below, 2014). Это, конечно, не “Спуск” (The Descent, 2005), но местами страшненько :)

Дракула (Dracula Untold, 2014). Во-первых, это фильм для любителей темы Дракулы. Во-вторых, лично мне не хватило батальных сцен. Те немногие разборки на мечах показались какими-то неубедительными и слишком короткими. От такого фильма хочется кровавого мочилова… А нетути :) Впрочем, сделано все на уровне, не проходная халтура.

Расплата (The Debt, 2010). Не зацепил.

Услуга (Favor, 2013). К хорошим сторонам фильма можно отнести отличный сценарий и хорошо подобранного на одну из главных ролей актера (собственно, он и тянул все на себе). А вот на остальное просто не хватило денег и получилось посредственно.

Судья (The Judge, 2014). Лично мне (повторюсь, лично мне) не понравился. Показалось, что авторы снимали фильм не для зрителей, а для “Оскара”.

Фонтан (The Fountain, 2006). Посмотрел по “рекомендации” одного известного в Рунете критика, мол, уникальное сочетание видеоряда с музыкой. Меня не торкнул ни видеоряд, ни музыка. В отличии от упомянутого выше Патруля времени. Хотя, наверное, фильм не рядовой. Особенно для любителей фильмов Даррена Аронофски.

Бегущий в лабиринте (The Maze Runner, 2014). Как мне показалось, это фильм для младшего подросткового возраста.

пятница, 28 ноября 2014 г.

[life.sport.darts] Осенний этап Кубка Гомеля -- 30 ноября 2014

Осенний этап Кубка Гомеля по дартс назначен на 30 ноября 2014 года. Место проведения турнира: СШ№66 г.Гомеля (ул.Макаенка, д.19).

Личное первенство. Игра в 501 single-in/double-out.

Приглашаются все желающие игроки из Гомеля и Гомельской области. Для тех, кто будет играть с нами в первый раз, участие бесплатное.

Победитель и призеры (1-3 места) награждаются памятными медалями.

Вся информация по турниру собрана на официальной странице.

PS. Это, вероятно, предпоследний турнир в Гомеле в 2014-м году. Далее будет еще Финал Кубка Гомеля в декабре, на который, судя по всему, будут допущены только те игроки, которые принимали участие в квалификациях и этапах Кубка Гомеля. Так что это крайняя возможность заработать право побороться за Кубок Гомеля 2014. Не пропустите! ;)

PPS. Этот пост специально будет висеть вверху блога до конца ноября 2014.

четверг, 27 ноября 2014 г.

[business] Почему G+/Facebook/VK/etc не хотят становится нормальным площадками для текстового контента?

Регулярные проблемы с G+ комментариями навели меня на вот такой простой вопрос: "Почему Facebook не позволяет писать полноценные посты?"

Понятно, что все идет от родовых травм социальных сетей, которые изначально затачивались под цели распространения информации вида "Я сегодня обедал в ... и там подавали ..." или ссылок на материалы "Поступок ... растрогал ... до слез". Но времена меняются. То, что было хорошо для сети с десятком миллионов пользователей-тинейджеров может быть уже не совсем адекватно, когда число пользователей под миллиард и некоторым из них специально платят деньги за сбор и распространение информации в социальной сети.

Но оставим в стороне тех, кто сидит в соцсети full-time за деньги. Возьмем простого блоггера вроде меня. С одной стороны, мне интересно, чтобы меня читало все больше и больше людей. С другой стороны, мне не интересно публиковать ссылку на очередной блог-пост в десятке разных соцсетей. Тем более, что ситуация сейчас такова, что порядка 80-90% читателей уже являются пользователями либо Facebook, либо G+ (либо и того, и другого сразу). А дальше будет еще больше. Все идет к тому, если если я есть в Facebook, то мне становиться безразлично, что кого-то из моих читателей в Facebook-е нет. Как говорили в рекламе в 90-х: "Если вас нет на желтых страницах, вас нет вообще" :)

Следовательно, если подавляющее большинство читателей уже находятся вместе со мной внутри соцсети, то зачем мне писать что-то вне этой соцсети, а затем размещать ссылку на свой материал? Почему бы мне не написать его прямо внутри Facebook? Или Google+, или VK?

Имеющиеся сейчас возможности для оформления текста заметок, насколько я могу судить, слабо подходят для написания чего-то более-менее серьезного. Да, рассказать какой-нибудь бородатый анекдот или скопипастить пару цитат откуда-нибудь вполне можно. Но вот сделать небольшую статью на специализированную тему, с табличками, картинками, примерами кода (хотя бы вот как эту) -- это уже вряд ли.

Т.е. если бы сейчас Facebook дал бы мне возможность писать тексты настолько же удобно, насколько это позволяет Blogger, я бы спокойно полностью ушел бы в Facebook и не парился.

И да, я ленивый, мне в лом заводить где-то свою площадку, разворачивать какой-то движок для публикаций, прикручивать движок для комментариев и т.д. Здесь разница как между рабочим ноутбуком и личным. Рабочий ноутбук в любой момент могут отобрать и ты не можешь просто так укатить с ним в отпуск. Зато если с ним что-то случается, ты не тратишь собственное время и деньги на его ремонт.

Какой интерес соцсетям становиться площадками для текстового контента? Да точно такой же, как и другие способы привлечения и удерживания пользователей внутри своего сервиса. Чем больше пользователей, чем больше времени они проводят, тем более рекламы и услуг им можно подсунуть.

В конце-концов, с чего живут какие-нибудь сетевые издания? С рекламы, с проплаченных постов и т.д. Ну так пусть живут прямо внутри соцсети. Какая разница, кому платит рекламодатель: сетевому журналу "Кольчатые черви средней полосы России" или VK? Может даже VK платить выгоднее, т.к. там аудитория побольше будет.

В связи с этим я не очень понимаю Google, который со всеми своими мощностями не может решить проблему G+ комментариев. Ведь, в принципе, стартовые позиции у Google классные: крупнейший поисковик, крупнейший почтовый сервис, крупнейший видео-сервис, собственный блог-сервис, Google+ как лента новостей да еще и Google Drive. Увязать все это должным образом и получится нечто большее, чем просто социальная сеть для обмена впечатлениями об очередном бизнес-ланче.

Еще одна штука, которая меня немного удивляет, это почему Facebook не сделает свой собственный почтовый сервис. Система обмена сообщениями у них есть, работает надежно, информация о лайках и комментариях не теряется. Теперь отмасштабировать это и приделать удобный интерфейс и можно было бы получить убийцу Google Mail :) Тогда вообще, заходишь с утра в Facebook, и сидишь там весь день никуда не выходя. Не это ли цель владельцев соцсетей?

среда, 26 ноября 2014 г.

[prog.flame] Вынесу из комментариев про ООП

Написал большой комментарий к предыдущей заметке. Но, думаю, его имеет смысл пустить отдельным постом, чтобы не повторять потом по нескольку раз в разных обсуждениях:

ООП -- это сложная тема. На базе принципов она более-менее понятна, а вот когда опускаешься к деталям, обнаруживается большое количество белых пятен. Ситуация усугубляется еще и тем, что из широкоизвестных ОО языков чисто ОО языками являются всего два -- Java и Eiffel. Все остальные из тех, что приходят на ум, гибридные. Даже SmallTalk и Ruby несут в себе следы функциональщины (что не удивительно, т.к. Алан Кей сам признавался, что Lisp на него очень повлиял во время работы над SmallTalk-ом). Поэтому, скажем, при работе на C++ или Ruby можно не сталкиваться с ОО-граблями потому, что в этих языках они обходятся совсем другими способами. Тогда как в Java их, что называется, не обойти и не объехать.

Тут выше в комментариях дали ссылку на фрагмент книги о Haskell-е. Там хороший пример приведен. Когда класс требует наличия operator<, а тип, который имеет такой метод, автоматически становится принадлежащим этому классу. В C++ такая штука присутствует в чистом виде при работе с шаблонами. В Ruby/Python/SmallTalk -- благодаря динамической утиной типизации.

А вот статически-типизированных ОО-языках как это выражать? Там ведь очень редко где поддерживается структурная эквивалентность (т.е. тот же duck typing, но статический). Простейший вариант, который и был реализован в Java -- это наследование: либо реализации (поэтому в базовом Object-е собрано столько всякого хлама), либо интерфесов. Но при этом интерфейсы не могут иметь реализаций методов. Т.е. в Java (по крайней мере той, с которой я когда-то работал) нельзя сделать интерфейс Comparable с одним абстрактным методом lessThan и неабстрактными equal, lessEqual, greaterThan, greaterEqual, notEqual, которые были бы реализованы на основе единственного абстрактного lessThan. Вот поэтому Java, хоть и является чистым ОО языком, но это ублюдочно убогий ОО язык.

Тогда как второй чистый ОО-язык, да еще и статически-типизированный, Eiffel, эти проблемы решает на раз за счет того, что в нем есть нормальное множественное наследование. Т.е. нарезать в Eiffel-е "интерфейсов" вроде Comparable можно множество, и не страшно если в каждом будет всего один-два абстрактных метода. Не страшно даже, если методы будут иметь одинаковые названия и разные сигнатуры -- все это решается на уровне подмешивания посредством специальных языковых инструментов. Т.е. авторы Eiffel прекрасно понимали проблемы ООП в статически-типизированном языке и постарались их должным образом решить.

К сожалению, в массы пошел язык Java. Поэтому огромное число программистов знает об ООП из Java. Т.е. не о нормальном ООП, а о сильно кастрированном. Отсюда и наезды, потому что проблем не меньше, чем достоинств.

Однако, стоит только поработать с более-менее приличной реализацией ООП (скажем в Eiffel) или с ООП в гибридном языке (скажем в C++ или Ruby), так ситуация меняется: да ООП не всегда ложиться на предметную область, ну и не страшно, в языке есть другие инструменты.

вторник, 25 ноября 2014 г.

[prog.flame] Когда же АлгТД круче ООП и наоборот? ;)

Фактически послесловие к закрытой дискуссии на eax.me. Прям сейчас возник пример ситуации, в которой алгебраические типы данных (АлгТД) удобнее объектно-ориентированного подхода.

Допустим, я делаю приложение, которое в одном рабочем потоке выгребает запросы из какого-то MQ-сервиса (не важно, будет это MQTT, AMQP или DDS), после чего обрабатывает их в этом же потоке. Прочитанные из MQ сообщения могут приводить к одному или нескольким прикладным событиям в приложении, в том числе к отложенным на какое-то время или повторяющимся с каким-то интервалом событиям. Например, поступила команда запустить электродвигатель и разогнать его до определенной скорости, нужно записать специальную команду в специальный I/O-порт, затем периодически опрашивать другие I/O-порты дабы проверять скорость вращения и, при необходимости, выдавать дополнительные команды. И так до тех пор, пока из MQ не придет команда на выключение двигателя.

В общем, на верхнем уровне в рабочем потоке будет что-то вроде вот такого цикла обработки событий (с прицелом на MQTT и libmosquittopp):

mosqpp::mosquittopp mosq(...);
auto so_env = so_5::launch_single_threaded_env(...);
...
while(true)
{
   // Process any MQTT-related events.
   auto r = mosq.loop(
      // Wait no more time than next timer event.
      to_milliseconds( so_env.timeout_before_next_event( millisecons(1000) ) ) );
   if( r != MOSQ_ERR_SUCCESS )
      ... // Some error handling.
   else
      // Application events can be processed.
      so_env.process_events();
}

Вроде бы все просто, но возникает маленький вопросик: а что, если нужно ограничить длительность работы process_events?

Сходу придумываются три типа ограничений: выполнение не более N событий (не важно сколько времени это займет), выполнение событий в течении M миллисекунд (не важно сколько именно событий будет выполнено), комбинированный -- либо N событий, либо не менее M миллисекунд.

Ok, как эти ограничения передать в метод process_events? Не делая при этом перегрузки process_events для разных списков параметров.

В случае АлгТД решение лежит на поверхности (в Scala-синтаксисе):

abstract class EventsConstraints
case class NoMoreThan(limit: Intextends EventsConstraints
case class NoLongerThan(limit: Durationextends EventsConstraints
case class NoMoreNoLonger(maxEvents: Int, maxTime: Durationextends EventsConstraints

Соответственно, вызов so_env.process_events мог бы быть записан, например, как process_events(NoMoreThan(100)) или process_events(NoMoreNoLonger(100,10ms)).

Ну теперь представьте, во что бы все это вылилось, если бы пришлось обходиться чистым, да еще и убогим, как в Java, ООП :)

Кстати, почему нельзя создавать разные варианты process_events? Потому, что это в данном примере process_events такой простой и получает всего один аргумент. В реальной жизни это может быть метод с несколькими параметрами. Например: process_events(exception_handling_policy, logging_parameters, events_constraints). Соответственно, у каждого параметра могут быть свои варианты. И на каждую комбинацию значений аргументов свой вариант process_events не напишешь.

АглТД здесь хороши еще и тем, что если со временем появится еще один тип ограничений (например, выполнение событий до тех пор, пока заполненность очереди сообщений не упадет ниже некоторого порога), то внутренности process_events не скомпилируются, если там нет должной обработки нового типа ограничения или их явного игнорирования (т.к. нормально реализованный паттерн-матчинг полноту вариантов проверяет).

Но этот же пример показывает ситуацию, в которой ООП выгоднее АлгТД. Например, насколько удобно посредством алгебраических типов представлять тип объекта so_env? Что это вообще будет за тип, какие у него внутренности, как именно он работает?

На начальных стадиях проектирования об этом мало что можно сказать. Можно разве что определить его интерфейс, вроде вот такого:

class single_threaded_environment
{
public :
   virtual ~single_threaded_environment();

   virtual void
   process_events() = 0;

   virtual std::chrono::steady_clock::duration
   timeout_before_next_event(
      const std::chrono::steady_clock::duration & default_timeout ) = 0;
};

Для дальнейшей разработки в ОО-подходе этого уже достаточно. Детали работы реализаций интерфейса single_threaded_environment будут выяснены позже и там, где это нужно. А в других местах об этом ничего знать не следует. Более того, таких реализаций может быть несколько (скажем, под конкретные платформы или же отдельная реализация для release-режима, отдельная для debug). Как эти реализации будут устроены, будут ли они иметь какие-то общие части или уж тем более, будут ли они наследовать реализацию друг друга -- это уже дело десятое, по большому счету.

Кстати, если у кого-то уже появилось желание написать в коментариях про то, что наследование реализации (а не интерфейса) -- это зло и что за это нужно отрывать руки/гнать ссанными тряпками/читать блог вот того крутого чувака (нужное подчеркнуть), то крайне рекомендую сначала прочитать "Повторное использование против сжатия". Это глава из книги Ричарда Гэбриеля, одного из авторитетнейших Lisp-еров, которого нельзя заподозрить в любви к ООП. Лучше чем он вы вряд ли сможете высказаться на эту тему.

Кстати, в упомянутом обсуждении на eax.me некоторые альтернативно одаренные личности ставили в вину ООП одно из его главных достоинств -- сокрытие данных, т.е. инкапсуляцию, по сути. Что, на мой взгляд, уже вообще далеко за гранью здравого смысла. Ну глупо же инструменту, главная черта которого инкапсуляция, ставить в вину именно инкапсуляцию.