Wednesday, September 16, 2009

Отдых: Ради этого стоит работать

Вернулся с отдыха в Анталии. “Честные” 5*. Понял, что стоит таки год работать чтоб так отдохнуть – отличное питание, отличное море, минимум кричащих детей и пьяных компаний (не хочу явно “пиарить” отель, хотя он стоит того. Кому интересно – пишите в комментарии)

Оказалось что в Турции закрыто очень много ресурсов – твиттер, частично блоггер, ютуб. Хорошо, что работал скайп.

По приезде гугл-ридер радостно сообщил о “1000+” непрочитанных.

Снова таки начали приходить о выборе – что лучше: продолжать фрилансить (пару более или менее постоянных клиентов есть), или все-таки вернутся на “регулярную” работу…  С одной стороны “свобода” фриланса, с другой – работа в коллективе, обмен опытом. Навеяно "Подготовка к собеседованию на должность программиста".

ПС. Никогда не понимал как люди могут работать без хорошего отдыха :)

Friday, August 28, 2009

Google Apps Engine: все еще слишком экспериментальный

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

Основные причины отказа:

  1. Достаточно низкие лимиты на процессорное время, при этом довольно низкая производительность (то что на локальной машине выполняется 1секунду, в “реальном” окружении может выходить за пределы лимита в 30 секунд)
  2. Наличие серьезных открытых issues, которые фактически сильно усложняют разработку
    1. Невозможно очистить хранилище (только кодом, но если классы не совместимы, то полная очистка невозможно вообще)
    2. Невозможно удалить приложение (что в совокупности с предидущим пунктом и наличием лимита в 10 приложений дает серьёзную “ложку дёгтя”)
    3. Ошибки при построении индексов и невозможность управлять ими при ошибках (например, если индекс находится в состоянии построения, и возникла ошибка, только работники Гугл могут помочь очистить индексы)
  3. Позднее оповещение об неподдерживаемых библиотеках (фактически можно довольно долго разрабатывать локально, задеплоить, и только при какой-то операции получить сообщение что какая-то библиотека юзает “запрещенный” класс, что заставляет фактически полностью переписывать некоторые блоки). Мне кажется, что зная список разрешенных JRE классов, могли бы написать небольшой анализатор, который скажет есть ли использование плохих классов).
  4. Отсутствие  агрегационных функций при работе с хранилищем. Конечно, это не проблема для некоторых проектов, но в том, над которым я работал, анализ данных был чуть ли не основной задачей. И если у Амазона есть их Amazon Elastic MapReduce, то у Google нет адекватной альтернативы.

Сейчас прорабатываем вариант перехода на Amazon Web Services. Пока выглядит очень и очень привлекательно.



P.S.: Небольшая анти-статья про Amazon SimpleDB и чуток GAE - тут

Wednesday, August 12, 2009

MS Office 2007: Необходимое место без компонент

В процессе инсталляции офиса решил посмотреть сколько же места занимает офис, если не устанавливать вообще никаких компонент. Результат просто поразил меня:


Piccy.info - Free Image Hosting

Т.е. фактически чтоб не устанавливать ничего, требуется 800 мб+.

Monday, March 16, 2009

Новая работа: поиск во время кризиса

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

Не буду особо сильно раскрывать причины моего решения, но после беседы с “начальством” мы пришли к выводу, что нам будет лучше разойтись. Основная причина – это нежелание или невозможность дать нормальные условия работы в офисе. Хотя лично для меня это очень тяжелое решение – все-таки сблизился с командой, с проектами.

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

Так что, если кто может порекомендовать хорошую компанию, которая может заинтересоваться вот таким вот резюме, и лояльно относится к своим сотрудникам – прошу писать.

К сожалению к проблеме с поиском работы добавилась проблема с получением своего же депозита в банке “Надра” (это отдельная тема, про которую тоже можно было бы написать – вдруг есть те, кто тоже наступил на те же грабли). Если кого интересует – пишите, обменяемся опытом.

Tuesday, February 3, 2009

Функциональное программирование в “не функциональных” языках: ленивые вычисления

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

Один из элементов ФП, позволяющих эффективно его использовать являются “ленивые вычисления”. Принцип такой – зачем вычислять то, что возможно нам не понадобится.

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

Допустим у нас есть задача: написать функцию, принимающую три числовых параметра  (a, b, c), и возвращающую сумму a+b если a>0 и a+c если a<0.

Простейшая реализация (C#):

int function(int a, int b, int c) 
{
return a+a>0?b:c;
}


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



Вот тут то и приходит на помощь идея ФП. А точнее то, что основным объектов является функция. Можно просто передать как параметр не значение, а функцию, которая возвращает это значение.



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



Теперь небольшой пример из совсем почти не функционального языка – C# 2.0:



Для начала перепишем функцию так, чтоб она оперировала с функциями (“делегатами”):



        private delegate int IntFunction();
private static IntFunction funct(IntFunction a, IntFunction b, IntFunction c)
{
return delegate
{
int aValue = a(); return aValue > 0 ? aValue + b() : aValue + c();
};
}


Далее, допустим есть функция,  которая очень долго работает. Для примера, пусть она возвращает число, переданное в качестве параметра:



        private static IntFunction CreateInt(int a)
{
return delegate
{
Console.WriteLine("Computing for long..long time, resulting "+a);
return a;
};
}


Ну а теперь сам вызов:



Console.WriteLine("Result is {0}",funct(CreateInt(1), CreateInt(2), CreateInt(3))());


В результате получим:



Computing for long..long time, resulting 1
Computing for long..long time, resulting 2
Result is 3


Как видно,  функция, возвращающая “3” даже не была запущенна.



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



Console.WriteLine("Result is {0}", funct(funct(CreateInt(1), CreateInt(2), CreateInt(3)), CreateInt(4), CreateInt(5))());


В результате которых будет  реально толь3о 3 раза вызвана наша “долгая” функция, вместо 5, как было бы при обычном подходе.



Вот такой простой и имхо понятный пример того, как можно понять смысл использования “ленивых вычислений”, и использовать в “не функциональных” языках.

Friday, August 29, 2008

GWT 1.5 Released

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

 

Итак, позволю себе сделать вольный перевод списка того, что изменилось с небольшими комментариями (оригинал):

Поддержка Java 1.5 и расширенная эмуляция JRE

  1. Теперь можно спокойно использовать “генерики”. И не только для более комфортной работы на клиентской стороне, но и для реализации более “тесного” RPC между клиентом и сервером (теперь можно возвращать клиенту List<MyClass> не беспокоясь о @gwt.typeArgs)
  2. Синтаксический сахарок: for-each loops, autoboxing, static import, enum
  3. Переработана архитектура подсистем (RPC, image bundles, benchmarking, интернационализация). Так же стало допустимо использование “левых” аннотаций, что позволяет повторное использование кода для других систем.
  4. Добавлена реализация разных вспомогательных классов, к которым так привыкли ява-девелоперы (StringBuilder, TreeMap, LinkedHashMap)
  5. Теперь Assertion-ы можно отключить (фактически появилась возможность делать более “релиз” версию).

 

Производительность и связь с JavaScript

  1. Компилятор более тщательно проводит “инлайнинг” функций – т.е. вместо вызова функции, код функции вставляется прямо в то место, откуда был бы вызов.
  2. Дерево переработано полностью. В результате на ИЕ прирост скорости работы от 5 до 10 раз.
  3. Добавлены типы JavaScript overlay. Это позволяет интегрировать уже написанные JavaScript библиотеки без дополнительных издержек. А так же более “прямую” конвертацию JSON данные в GWT объекты.
  4. Система “линкеров” позволяет генерировать различные варианты окончательных сборок для разных контейнеров, которые могут выполнять JavaScript (привет Google Gadgets, Filefox расширения, Greasemonkey скрипты, Gears но и … Flex и Android)

Красивые виджеты, лучшая поддержка DOM, доступность, и bi-di.

  1. Переделали демку
  2. Добавили дефолтные “темы” (раньше были только в примерах)
  3. Добавили функционал для обеспечения “доступности” (WAI-ARIA) и вывод “наоборот” (для арабских локалей например)
  4. Новый DOM package покрывает полностью спецификацию W3C – т.е. можно использовать “нативные” элементы вместо виджетов для простоты реализации.

 

…и многое другое :)

 

В общем, GWT продолжает довольно активно развивается, и этот релиз – ещё один сильный и уверенный шаг вперёд.

Tuesday, July 8, 2008

(Old) How to shoot yourself in the foot

Попалась старая ссылка о том, как стрелять себе в ногу на разных языках. Много забавного и поучительного: How to shoot yourself in the foot in any language

 

Для себя сделал выборку из самых забавных вариантов:

SQL

You spend 10 minutes figuring out how to join your hand to the gun, and then accidentally fire all bullets at all feet in the room.

PHP

You Google for "shoot self in foot" and come up with 397 howto guides. After copying and pasting the source code from each of the articles you've managed to: make a gun, shoot a gun at random passers-by, jam a gun, throw a gun, distribute guns to the poor, shoot yourself in the face, and finally: shoot yourself in the foot.

Outsourced Programming Language

You've heard of guns and bullets, but you end up just posting "kind sir, please email me the guns and bullets" to every developer forum and mailing list on the planet.

Any .NET Language: You try to use the built in ShootSelfInFootWithGun() function which looks like it does exactly what you need from the documentation but when you try to run it it complains that your foot is the wrong sort of foot.

Win32
LRESULT CALLBACK stGunProc(HGUN hGun, HGUN hGunParent, UINT uId, TPARAM tParam, UPARAM uParam, DWORD uTarg, DWORD aAmmTyp, BOOL bSaf, UNIT nCal, LPCTSTR mMfg, HANDLE hHand, LPCTSTR sErt, UINT nDist, UINT nBear, UINT nEle, UINT nMuzVel, HTARG hTarg, LPVOID lpParam);

Regular Expressions: ^((?&gt;[a-zA-Z\d!#$%&foot;'*+\-/=?^_`{|}~]+\x20*|&bullet;((?=[\x01-\x7f])[^&trigger;\\]|\\[\x01-\x7f])*&trigger;\x20*)*(?&lt;angle&gt;&lt;))?((?!\.)(?&gt;\.?[a-zA-Z\d!#$%&hole;'*+\-/=?^_`{|}~]+)+|&trigger;((?=[\x01-\x7f])[^&trigger;\\]|\\[\x01-\x7f])*&trigger;)@(((?!-)[a-zA-Z\d\-]+(?&lt;!-)\.)+[a-zA-Z]{2,}|\[(((?(?&lt;!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)&gt;)$