Thursday, December 29, 2011

Аутсорсинг и продуктовая разработка

Очень часто приходится слышать как программисты сравнивают и противопоставляют продуктовую и аутсорсинговую (outsourcing) разработку. И часто при этом говорят, что аутсорсинг - это ерунда и неинтересные проекты, а вот если разрабатывать продукты или начать стартап, то сразу будет счастье. Если быть до конца точными, то все это разделение не совсем корректно, т.к. сравниваются метры с килограммами.

Кстати, само слово “стартап” также часто используется неверно среди IT-шников. Стартап - это любой начинающийся бизнес, не только IT, просто наибольшее распространение он получил именно в нашей сфере в эпоху доткомов.

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

Итак, компании, так или иначе занимающиеся разработкой ПО, можно условно разделить на 2 группы:

  1. производящие ПО для собственных нужд или с целью самостоятельного распространения (продукты и услуги)
  2. предоставляющие услуги по разработке ПО для сторонних заказчиков

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

С точки зрения рынка разработки ПО, это самое ПО, в свою очередь, также можно разделить на 2 группы:

  1. продукты (в основном настольные, мобильные и embedded, реже - веб), а также веб-решения, предоставляющие пользователям различные услуги, но предназначенные для использования большим количеством сторонних пользователей, а не самой компанией
  2. custom solutions - индивидуальные решения, предназначенные для внутреннего использования одним потребителем, например, внутри компании или организации

Если и другие классификации ПО, но нам они сейчас не очень интересны.

Понятно, что custom solutions могут разрабатываться как внутри самой компании (in-house), так и на заказ у какого-нибудь вендора. Но ведь и продукты со “стартапами” не всегда разрабатываются внутри компании, которая потом эти продукты продает.

Если скрестить это все, то получим следующую картинку:

Custom_vs_products

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

Поймите меня правильно, я ни в коем случае не хочу сказать, что разработка ПО на заказ (по сути, продажа труда, знаний и времени разработчиков) - лучше, чем разработка и продажа собственных продуктов или услуг на базе собственных решений. Разрабатывать продукты сложнее, потому что лишь 20-30% этого процесса - непосредственно разработка, остальное - анализ рынка и конкурентов, работа с пользователями, и самое главное - продажи. И после всех усилий и вложенных средств еще неизвестно - взлетит или не взлетит. Продавать услуги по разработке ПО в этом отношении намного проще и гораздо менее рискованно. В то же время и возможности заработка в аутсорсинговой модели ограничены рейтами, а разница между доходами и расходами невелика, в то время как в случае успеха продукта или стартапа доход может быть в разы, десятки и сотни раз выше, чем расходы. Но, как известно, кто не рискует, тот не пьет шампанского.

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

Monday, December 26, 2011

Распределенные транзакции (Distributed Transactions) и их настройка

Каждый программист, работающий с данными, сталкивался с обычными транзакциями той или иной базы данных. Основная задача транзакций – обеспечить consistency данных после завершения операции: изменения либо успешно сохраняются от начала и до конца, либо полностью откатываются, если что-то пошло не так. Даже если вы ни разу не писали в SQL коде ключевые слова BEGIN TRAN, COMMIT TRAN или ROLLBACK TRAN или нечто подобное, это еще не значит, что вы их не использовали. Все ORM, реализующие паттерн unit of work (Entity Framework, NHibernate и др.) объединяют операции по изменению данных в транзакцию перед сохранением.

Транзакции хорошо работают в рамках одной базы данных, но если у вас распределенная система, которая требует сохранения данных в разных базах на разных серверах, а иногда и платформах, то нужна более тяжелая артиллерия – распределенные транзакции (distributed transactions, DT).

Перед тем, как начать работать с распределенными транзакциями, нужно изучить механизм их работы, протоколы и особенности, которые не так просты. Очень хорошее описание темы есть в этой статье, где дается отличное общее понимание и практические примеры, просто must read:

Truly Understanding .NET Transactions and WCF Implementation

Работа вложенных транзакций отлично расписана здесь:

Understanding nested transaction scopes

Также не забывайте про MSDN:

http://msdn.microsoft.com/en-us/library/w97s6fw4(v=VS.90).aspx

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

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

1) Сконфигурировать WCF для поддержки DT

Распределенные транзакции не поддерживаются в режиме basicHttpBinding, поэтому нам нужно использовать хотя бы на wsHttpBinding, в binding которого нужно прописать атрибут transactionFlow=”true”:

<wshttpbinding>
    <binding name="wsConfig" transactionflow="true">
         <security mode="None" />
    </binding>
</wshttpbinding>

2) Установить специальные атрибуты в интерфейсе сервиса и его методов

Необходимо добавить атрибуты TransactionFlow для метода в контракте и свойства атрибута OperationBehavior TransactionScopeRequired и опционально TransactionAutoComplete в реализации метода:

[ServiceContract] 
public interface IServiceContract 
{ 
    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.Allowed)] 
    string ServiceMethod(string param1, string param2); 
}

public class Service : IServiceContract 
{ 
    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] 
    public string ServiceMethod(string param1, string param2) 
    { 
      // some server-side operations with database 
    } 
}

Атрибут TransactionFlow принимает несколько опций: Allowed обозначает, что метод сервиса может вызываться как из кода, обернутого в TransactionScope, так и из обычного. Mandatory требует наличия TransactionScope, а NotAllowed (по умолчанию) заставит сервис игнорировать транзакции на клиенте вообще.

3) Создать на стороне клиента транзакцию, внутри которой вызвать метод WCF сервиса

Выглядит это приблизительно так:

public static string DoSomethingWithRemoteCall(string param1, string param2) 
{ 
    string result = null; 

    TransactionOptions options = 
        new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TimeSpan.FromSeconds(300) }; 
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, options)) 
    { 
        // some client-side database actions 

        using (var ecommerceFactory = new ChannelFactory("Staging")) 
        { 
            ecommerceFactory.Open(); 

            var proxy = ecommerceFactory.CreateChannel(); 
            bool success = false; 

            try 
            { 
                result = proxy.ServiceMethod(param1, param2); 
                success = true; 
            } 
            catch (Exception ex) 
            { 
                // log exception 
                return;

            } 
            finally 
            { 
                if (success) 
                    ecommerceFactory.Close(); 
                else 
                    ecommerceFactory.Abort(); 
            } 
        } 

        // other possible client-side database actions
        scope.Complete(); 
    } 

    return result; 
}

Безусловно, в вашем коде вызов сервиса должен находиться в отдельном классе, это лишь пример.

TransactionOptions позволяет задать некоторые параметры транзакции. В нашем случае это уровень изоляции (значение по умолчанию Serializable не рекомендуется из-за опасности возникновения дедлоков) и таймаут операции (5 минут).

При создании TransactionScope мы указываем параметр TransactionScopeOption.RequiresNew, что не позволит никакому другому коду обернуть наш метод в свою транзакцию. Подробнее вложенные транзакции описаны здесь.

Внутри TransactionScope в случае, если мы действительно хотим закоммитить транзакцию, мы делаем вызов scope.Complete(). Если нам нужно транзакцию откатить (как в случае с catch в примере), мы просто не вызываем Complete(). Вызывать Complete() нужно после всех клиентских операций с базой данных, которые происходят внутри транзакции, иначе у вас случится ошибка, что connection или provider уже закрыт.

Обратите внимание, что в коде сервиса из предыдущего пункта нет никакого намека на TransactionScope, кроме атрибутов TransactionFlow и OperationBehavior. Он там и не нужен, для стандартного сценария атрибутов достаточно. Однако никто вам не мешает создавать свои вложенные транзакции, как с опцией Required (используем родительскую транзакцию), так и с опциями RequiresNew (новая независимая транзакция) и Suppress (код не будет выполнятся в родительской транзакции).

4) Запустить сервис и клиент

И вуаля – все работает. Или не работает? Говорите, полезли странные ошибки выполнения?

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

1) Убедиться, что на всех клиентах и серверах (здесь и далее - включая сервера баз данных и веб-сервера) установлена и запущена служба Distribution Transactions Coordinator. Именно эта служба отвечает за координацию ваших распределенных транзакций.

2) Убедиться, что на всех клиентах и серверах включена поддержка распределенных транзакций. Для этого запускаем Control Panel –> Administrative Tools –> Component Services, идем в Computers –> My Computer –> Distributed Transaction Coordinator –> Properties (контекстное меню) и устанавливаем на вкладке Security следующие параметры:

  • Network DTC Access
  • Allow Remote Clients
  • Allow Inbound
  • Allow Outbound

Component_Services

3) Разрешить работу Distributed Transactions Coordinator во всех установленных брандмауэрах, включая Windows Firewall:

Firewall

4) Убедиться, что все ваши клиенты и сервера находятся в одной локальной сети. В большинстве случаев так оно и есть, но есть исключения, и если вы тот самый счастливчик, то вам придется немного попотеть, реализовывая поддержку протокола WS-Atomic Transaction (WS-AT), который упоминается в общей статье. Если вы тот самый счастливчик, которому надо начинать настраивать WS-AT, то вот еще пара полезных статей:

Configuring WS-Atomic Transaction support (MSDN)

Building transactional Web services with WebSphere Application Server and Microsoft .NET using WS-AtomicTransaction

5) Для работы DTC по локальной сети: все машины должны пинговаться по netbios-имени.

6) Важно: Если вы пошли по нашему пути и запустили тестовую конфигурацию на виртуальных машинах, запущенных с одного образа: переустановить DTC. DTC не работает с одинаковыми CID, а переустановка их сбрасывает. Это проблема, с которой мы столкнулись и которую смогли найти лишь запустив утилиту DTCPing.

Больше деталей здесь: Warning: the CID values for both test machines are the same

7) Если ничего не помогло: поставить и запустить DTCPing и посмотреть, что она говорит. Очень хороший способ, когда ничего другое не помогает:

Troubleshooting MSDTC issues with the DTCPing tool

Saturday, December 3, 2011

Paypal: работа с 3rd party merchant accounts

Интеграция с Paypal – вещь не сложная. Paypal поддерживает два типа API: Name-Value pairs (URL-based) и стандартный SOAP, а также несколько сервисов для работы, из которых самые распространенные Website Payments Standard и Website Payments Pro (Express Checkout и Direct Payments). Paypal также предоставлят Sandbox для тестирования и достаточно подробную документацию по каждому продукту и типу интеграции. Это если вкратце.

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

Для того, чтобы ecommerce сайт работал с Paypal, необходимо иметь Paypal merchant аккаунт, на который идет вся оплата за товары и услуги, продаваемые на сайте. Для авторизации на Paypal для аккаунта генерируются т.н. API Credentials: Username, Password и Signature/Certificate (лучше использовать Signature). Как это делается, в деталях рассказывается в документации. То есть механизм простой: веб-приложение передает запросы на Paypal, используя три параметра API Credentials, а Paypal таким образом “знает”, с каким merchant аккаунтом идет работа, грубо говоря, кому перечислять деньги за товары.

Все это замечательно работает, когда у вас в приложении “хостится” один продавец, и так работает наверно 95% всех ecommerce-сайтов, от простейших шаблонных электронных магазинов до более серьезных решений. Но в случае реализации сложной торговой площадки, на которой может работать множество торговцев, вроде Amazon.com, eBay.com или etsy.com, этого становится недостаточно. Есть два способа решения этой задачи.

Первый способ очевидный: пусть каждый merchant сгенерирует себе API Credentials и укажет их в своем профиле торговой площадки. Тогда при работе с выбранным Paypal API нужно будет всего лишь подставлять нужные credentials – и вуаля. Однако если посмотреть на профили того же Amazon или eBay для торговцев, то можно увидеть, что они просят ввести только Merchant account email. И никаких паролей или API credentials! Это и есть второй способ интеграции, не так хорошо задокументированный.

Упоминание об этом способе почему-то достаточно хорошо скрывается в документации к функциям API и фактически встречается лишь в описании работы с Name-Value pairs API и на форумах (кстати, форумы Paypal очень полезны, но гуглом не индексируются, поэтому лучше искать прямо там). Вот оно:

image

То есть можно сгенерировать API Credentials для всего приложения и динамически подменять лишь SUBJECT поле для каждого запроса, таким образом говоря Paypal, с каким merchant сейчас идет работа. И все бы хорошо, да только NOTE там указан не просто так. Paypal API достаточно мощный и дает возможность обращаться к некоторой внутренней информации merchant аккаунта, поэтому необходимо, чтобы merchant дал разрешение на определенные операции. Эти разрешения merchant может задать в Profile –> API Access –> Grant API Permissions. Далее нужно ввести API account username торговой площадки, которой даются разрешения и в появившемся списке выбрать те разрешения, которые нужны. Например, для работы с Express Checkout нужно выбрать как минимум:

  • Use Express Checkout to process payments

Также полезными могут оказаться:

  • Authorize and capture your PayPal transactions – если оплата проходит в 2 этапа: авторизация и захват/списание денег
  • Refund a transaction on your behalf – для возврата денег в случае возврата товара
  • и некоторые другие (полный список есть здесь)

Дальше – больше. Процесс разрешения прав можно упростить для торговцев еще сильнее, если использовать т.н. Paypal Permissions Service. Этот сервис предоставляет возможность интеграции торговой площадки со специальными страницами разрешения прав на Paypal. То есть пользователю-торговцу достаточно лишь кликнуть ссылку или кнопку на сайте торговой площадки, и он будет автоматически переброшен на страницу Paypal с уже выбранным набором прав для разрешения, необходимых вашему приложению. Пользователю останется лишь подтвердить разрешение.

Тестирование этого процесса также заслуживает внимания, так как там притаилась еще одна небольшая засада. Вам необходимо создать 2 (!) различных sandbox-аккаунта, один из которых будет использоваться для создания API Credentials веб-приложения, а второй – для создания тестовых merchant-аккаунтов, которые будут якобы продавать товары. И неважно, что merchant (или seller) аккаунты можно создать и на основном sandbox аккаунте, вам не удастся сконфигурировать нужные права и Paypal будет возвращать непонятные ошибки.

Надеюсь, для кого-то эта информация окажется полезной и сэкономит время.

Saturday, November 19, 2011

Онлайн-курсы от Стэнфорда

Многие программерские ресурсы уже раструбили эту новость, но, может, кто-то еще не слышал. Полтора месяца назад Стэнфордский университет запустил бесплатные онлайн-курсы по Artificial Intelligence и Machine Learning. Эксперимент оказался довольно удачным (хотя отзывы по курсу AI и хуже, чем по ML) и с января по март запускается вторая волна курсов, 8 9 по Computer Science и 2 по Enterpreneurship:

1. Machine Learning — jan2012.ml-class.org
2. Introduction to Computer Science — www.cs101-class.org
3. Natural Language Processing — www.nlp-class.org
4. SaaS and Software Engineering — www.saas-class.org
5. Human-Computer Interaction — www.hci-class.org
6. Game Theory — www.game-theory-class.org
7. Probabilistic Graphical Models — www.pgm-class.org
8. Cryptography — www.crypto-class.org
9. Design and Analysis of Algorithms — http://www.algo-class.org/
10. Technology Entrepreneurship — www.entrepreneur-class.org
11. The Lean Launchpad — www.launchpad-class.org

Курсы проводят в основном преподаватели Стэнфорда, многие из которых являются признанными экспертами в своих областях и авторами книг.

Курсы можно проходить в одном из двух режимов: Basic или Advanced track. В Basic треке вы просматриваете лекции и отвечаете на еженедельные тесты. При этом никто ничего от вас не требует. В Advanced треке в дополнение нужно делать лабораторные работы, которые будут проверяться преподавателями. Работы оцениваются, их нужно сдавать вовремя, за опоздание начисляются штрафные баллы. В конце курса в случае Advanced трека будут подведены итоги, и вы получите письмо от преподавателя с вашими результатами. Никаких сертификатов и прочего – все знания, что успели ухватить – все ваше.

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

Я решил записаться на 3 курса: Machine Learning, Natural Language Processing и Game Theory. По первому очень хорошие отзывы, да и просто любопытно сравнить с тем, чему нас учили, вторым я немного занимался в университете, а третий просто интересно прослушать – на нашей специальности (ПОАС) теории игр не было, но встречаюсь с ней все чаще. Не уверен, что хватит времени пройти все по Advanced треку, но во-первых, всегда можно перейти на Basic или вообще отказаться, а во-вторых, я думаю начать проходить Machine Learning сейчас с первой группой, включая лабораторные работы, чтобы в январе-марте сэкономить себе время на этом курсе.

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

PS. Кстати, кому интересно, до середины декабря проходит AI Challenge. В этом году, к сожалению, совсем нет времени участвовать, а жаль.

PPS. Курсы добавляются как грибы после дождя. Появился еще один курс, на этот раз по дизайну и анализу алгоритмов: http://www.algo-class.org/

Tuesday, June 28, 2011

Будущее Silverlight

Очень странно наблюдать поднявшуюся в последний месяц истерию по поводу того, что Microsoft якобы “разочаровался в WPF/Silverlight” и планирует смену курса в сторону набирающего популярность HTML5. Тема вовсю обсуждается на форумах MSDN, в комментариях серьезных блоггеров, на Хабре и даже в твиттере. Несмотря на явную невозможность нативной разработки под Windows при помощи ыHTML5/JS, у этой истерии, безусловно, есть корни. Осенью прошлого года официальные лица Microsoft уже обронили несколько фраз о переосмыслении стратегии развития Silverlight, а в начале июня подлили масла в огонь, показав Windows 8 с возможностью разработки на HTML5/JS и ни словом не обмолвившись о Silverlight. Если погуглить по фразе “Windows 8 silverlight”, то можно найти кучу криков о смерти Silverlight и плач тысяч разработчиков, которые выбрали Silverlight своей основной платформой для разработки и теперь считают себя брошенными на произвол судьбы. Добил фанов технологии .NET Community Manager Pete Brown, который высказался ясно и в то же время очень неопределенно:

“You all saw a very small technology demo of Windows 8, and a brief press release. We’re all being quiet right now because we can’t comment on this. It’s not because we don’t care, aren’t listening, have given up, or are agreeing or disagreeing with you on something. All I can say for now is to please wait until September. If we say more before then, that will be great, but there are no promises (and I’m not aware of any plans) to say more right now. I’m very sorry that there’s nothing else to share at the moment. I know that answer is terrible, but it’s all that we can say right now. Seriously.”

Сентябрь, о котором идет речь – это конференция Build, на которой ожидается релиз Silverlight 5, Windows Phone 7 Mango, а также первые настоящие презентации Windows 8 с объяснениями дальнейшей стратегии компании.

Безусловно, можно подождать еще 2.5 месяца и узнать, какую роль Microsoft отводит для Silverlight в своей новой концепции. Но ждать еще долго, а некоторые решения нужно принимать уже сейчас. Попробуем разобраться сами.

Итак, что у нас есть из не очень хорошего:

  1. Microsoft, безусловно, немного разочарована скоростью распространения Silverlight и его положением на рынке. И хотя процент установки Silverlight в браузерах уже достаточно высок (на данный момент около 75%, http://www.riastats.com/), но он все равно еще недостаточен и не дает технологии стать по-настоящему популярной.
  2. Другая проблема Silverlight – его неполная кроссплатформенность. Поддержка Windows и Mac – это, конечно, где-то 90-95% рынка десктопов (а, может, и больше, если верить http://gs.statcounter.com/#os-ww-monthly-201005-201105), но с точки зрения разработки широкопользовательских веб-приложений остается непокрытым весь Linux’овый зоопарк. Не добавляет очков и слабая поддержка SEO.
  3. На мобильных платформах подержка Silverlight вообще стремится к нулю. Ни iOS, ни Blackberry, ни Android не поддерживают Silverlight и вряд ли будут стремиться к этому. Единственная платформа, где он поддерживается – это WP7, правда, не в браузере. Но доля WP7 на рынке мобильных устройств (http://itc.ua/news/gartner_android_yavlyaetsya_samoj_populyarnoj_os_dlya_smartfonov_53536) и количество заказов на разработку WP7 приложений пока настолько малы, что серьезно раздумывать о карьере разработчика мобильных приложений пока не получается.

В то же время несмотря на все эти недостатки Silverlight уже занял свою определенную нишу, где он очень силен, в первую очередь благодаря скорости разработки и возможностям, недоступным стандартному HTML/JS клиенту:

  1. Enterprise и LOB RIA приложения (нивелируются проблемы слабой кроссплатформенности и распространенности)
  2. веб-приложения, в которых пользователи готовы установить плагин ради получения доступа к продвинутым возможностям, а не уйти к конкурентам (не e-commerce)
  3. мультимедиа-приложения с красивой и сложной анимацией, поддержкой video streaming
  4. кроме того, Silverlight пока остается основной платформой для разработки под Windows Phone 7

С чем же связано то, что Microsoft, вложившая 4 года и миллионы долларов в разработку и продвижение кроссплатформенной .NET-технологии, потихоньку смотрит в сторону HTML5/JS? И что же все-таки будет с Silverlight дальше?

Во-первых, любой компании, которая производит ОС, важно привлекать как можно большее количество разработчиков на свою сторону. Silverlight и WPF требуют от не .NET-разработчиков изучения слишком многого. А возможность сделать пусть и простое, но все же приложение под Windows 8 на HTML5/JS – это шанс. Тем более, что Windows 8 позиционируется и как операционка для планшетов – а это очень перспективный рынок. Уверен на 99%, что в сентябре на Build будет сказано о полной поддержке WPF (а куда ж он денется?), а также Silverlight как минимум на уровне разработки таких же приложений, которые будут разрабатываться на HTML5/JS.

Во-вторых, есть ощущение, что Microsoft пойдет на еще один непопулярный, но очень важный с точки зрения развития своей мобильной платформы шаг – даст возможность разрабатывать нативные приложения на HTML5/JS в Windows Phone. Думаю, начиная с восьмой версии, чтобы поддержать версионирование, но, может, и в Mango (7.5) добавят. Криков о помощи будет еще больше, но Microsoft нужно догонять убегающие iOS и Android. Разработчики мобильных приложений под iOS и Android не торопятся переносить свои приложения под WP7 в том числе и потому, что это требует совсем других навыков. Если бы у Microsoft было хотя бы 40% рынка, они могли бы закрыть глаза на простоту разработки, но с текущими 6% им некуда деваться.

В-третьих, Silverlight никуда не уйдет из web’а в ближайшие 3-5 лет. Его доля будет по-прежнему неуклонно расти, приложения будут разрабатываться, но вот из своей ниши он вряд ли выйдет. Этому будет мешать развитие HTML5 и рост рынка веб-приложений под мобильные устройства. Конечно, Microsoft может попробовать разработать Silverlight-плагины для мобильных операционных систем и браузеров, но это огромные деньги, а эффекта практически не будет.

В поддержку Silverlight на нативном уровне верится еще меньше. Такое возможно лишь на Android, и то лишь благодаря Mono, который и сам находится в непонятном статусе. Еще возможно продвижение Silverlight на Symbian, благо с Nokia есть договор, но какой смысл? Ведь есть готовый WP7, который можно ставить на устройства. На фоне же прогнозов о росте использования мобильных веб-приложений и снижения нативной разработки (это банально намного проще и дешевле!) смысла вкладываться в эту сферу вообще нет.

Ну, и в-четвертых, отдельно стоит сказать пару слов о Silverlight vs. HTML5, вернее даже plugins (Flash/Silverlight) vs. HTML5 (это отдельная фишка: под угрозой HTML5 сейчас объединяются даже ранее враждовавшие разработчики Flash/Flex и Silverlight :)). На эту тему сломано уже очень много копий (почитайте отдельно, если вам интересно), но ясно одно: HTML5 не покрывает всех возможностей Silverlight и Flash/Flex, поэтому их рано списывать со счетов. Кроме того, как все правильно отмечают, плагины пополняются новой функциональностью быстрее, чем развивается HTML и обновляются версии браузеров. Если же отвечать на вопрос: что лучше использовать в качестве клиента в каждый конкретный момент времени, то советую почитать два отличных поста:

Лично я себя намного комфортнее чувствую в разработке обычных ASP.NET MVC приложений, чем Silverlight, но это не значит, что нет приложений, для которых использование Silverlight будет более выгодным или дешевым. Особенно если мы говорим о портировании WPF-приложений в веб.

А вы что думаете по всему этому поводу?

Tuesday, June 21, 2011

Итальянские впечатления – 4. Кухня

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

IMG_0741.1IMG_0859 

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

Паста в Италии считается первым блюдом (!). Привычных нам жидких супов в Италии почти нет, а то, что они называют супом, мы скорее можем назвать пюре. Паста – это общее название макаронных изделий, которые, как правило, подаются с различным соусом. Видов макарон в Италии очень много: кроме привычных нам maccheroni, vermicelli и spaghetti, есть еще пара десятков неизвестных bigoli, tagliatelli, tortiglioni, penne, fusilli, flocchi, fertalle, lasagne, raviolli, gnocci и т.д. Немного больше об итальянской пасте можно почитать в вики. Паста очень вкусная, но здесь важно подобрать подходящий соус. Мы пару раз ошибались. К пасте почти всегда подают тертый пармезан в отдельной посуде.

Основные блюда сильно зависят от региона. В Тоскане, например, больше мясной кухни, в Венеции и других “морских” городах – морепродуктов.

Отдельно стоит упомянуть итальянский сыр. Наш сыр по своей сути весь одинаков, отличаются лишь вкусовые добавки и содержание молока, есть оно там или нет ;). В Италии же типов сыра очень много: старый, молодой, мягкий, средний, твердый, на вкус они все отличаются. Сыров с плесенью почти нет, но несмотря на это в сырном отделе супермаркетов и на рыночных лотках глаза разбегаются. Кстати, в Италии много сыра, который производится фермерами по старым технологиям – почти все головки обернуты в солому с неким подобием земли или даже навоза. В общем, все натурально.

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

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

Ну, и напоследок о сладостях. Мы перепробовали большое количество “итальянского” мороженого (продается шариками), которое на удивление стоит дешевле, чем у нас. В основном очень вкусно. Также пробовали несколько пирожных и традиционные сиенские сладости.

На этом итальянская серия заканчивается и начинаем снова писать серьезные вещи :)

Sunday, June 19, 2011

Итальянские впечатления – 3. Венеция

После недели в Тоскане у нас еще оставалось неполных 2 дня на то, чтобы познакомиться с Венецией. Я поначалу был настроен очень скептически по отношению к этому городу. Венецию называют самым романтическим городом мира, но в нем также слишком много проблем. Здания потихоньку уходят под воду, морская соль разъедает архитектурные памятники, есть проблемы с качеством воды в каналах, недвижимость дорожает, что приводит к тому, что все больше венецианцев переселяется на материк. В общем, город потихоньку умирает.

Однако реальность оказалась все-таки не такой страшной. Несмотря на все эти проблемы город просто невероятно красив. У Венеции очень богатая история, и в наследство от предков современным венецианцам досталась восхитительная архитектура, уйма достопримечательностей и красочные традиции.

IMG_0982IMG_0968IMG_1041

Венецианская республика была одной из самых сильных морских и торговых держав Средневековья. Ее островное местоположение давало ей защиту от экспансии с суши, а со штапелей судостроительных верфей каждый день спускался на воду новый торговый или военный корабль. Венеция славно поживилась в IV Крестовом походе, когда в хитростью направила усилия крестоносцев на православную Византию с целью возврата власти свергнутому императору Исааку II Ангелу. В результате похода республике отошло больше трети территории бывшей Византийской империи, власть в Константинопольской гавани, торговая монополия на территории свежесозданной на руинах Византии Латинской империи, а также огромное количество богатств и предметов искусства, которые были вывезены в Венецию после разграбления Византии. Такой вот ход конем. Венецианская республика (которая на деле была аристократическим государством), по сути сидела между западом и востоком, зарабатывая на этом. Торговля и промышленность процветали, а народ постоянно богател. Однако это было начало конца.

Уничтожив Византию, которая защищала Европу от мусульманского Востока, Венеции пришлось самой столкнуться с турецкой экспансией после падения Константинополя в 1453 году. Европейские страны стали искать другие торговые пути и нашли их, открыв морской путь в Ост-Индию, а также заодно Америку. Великие географические открытия сместили акцент торговли в сторону Атлантики и Индийского океана, а постоянные войны с Османской империей ослабили республику. За два века османы отняли у Венеции значительную часть ее владений. Добил Венецию Бонапарт, захватив ее без сопротивления в 1797 году и уничтожив республику.

IMG_0857IMG_1136IMG_0983

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

Сердце города, без сомнения – площадь Сан-Марко, наверно, самое “голубиное” место Европы. Почти каждый турист считает своим долгом покормить здесь голубей (которых тут просто дофига) и сфотографироваться с ними. В остальном же площадь, хоть и красива, но слишком многолюдна.

IMG_0817IMG_0822

На площади находится без преувеличения один из красивейших соборов Европы – Собор Святого Марка. Собор назван в честь апостола Марка, мощи которого были тайно вывезены из Александрии венецианскими купцами. Внутри Собор смотрится очень красиво и наверно даже слишком богато. Глаза разбегаются, чтобы осмотреть мозаики на стенах и куполах, иконы, колонны, порталы и ниши. Преобладают желтые (даже золотые) и голубые цвета. Вход в алтарную зону, Сокровищницу и некоторые другие места платный.

IMG_0809IMG_0903IMG_0917

Рядом с Собором находится Дворец Дожей – шедевр итальянской готической архитектуры, в котором отчетливо видно влияние Востока – стрельчатые окна и арки. Мы не заходили внутрь из-за недостаточного количества времени, предпочтя этому прогулку по городу.

IMG_0811IMG_0815

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

IMG_0802IMG_0804IMG_1045

Поэтому большую часть времени мы гуляли по узким городским улочкам в стороне от центра – это намного интереснее. Венеция усыпана старинными домами и изрезана кривыми узкими улочками и канальчиками. Каждый мостик – это новая смотровая площадка: вдоль канала открывается какой-то новый интересный вид, внизу проплывают лодочки и гондолы. Нетуристическая Венеция – это контраст: обшарпанные стены домов, сгнившие двери, белье на шворках, застоянная вода в каналах. Это небольшие площади, на которых вечерами собираются взрослые, а дети играют катаются на роликах, бегают и играют в футбол, буцая мяч в стену храма. А еще это настоящий лабиринт. Ни в одном другом городе мы ничего не теряли и не терялись сами. Здесь же сначала потеряли супермаркет, который видели по пути в гостиницу, потом минут 30 искали саму нашу гостиницу (ну, здесь не наша вина, а привет муниципалитету, который неправильно нумерует дома), а в довершение безобразия влезла в Австралию Малая Азия мы потеряли классную тратторию, в которую мы забрели поздно вечером в поисках места для ужина. Нам так понравилась местная кухня, что мы захотели туда вернуться на следующий день, но так и не смогли ее найти :(.

IMG_1134IMG_0959IMG_1147 

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

 IMG_0841IMG_0990IMG_0993IMG_1023

И самое главное – не забудьте прокатиться на гондоле вапоретто по Гранд-Каналу! Вапоретто – это венецианский морской трамвай, единственный вид общественного транспорта в островной Венеции, где нет и намека на автомобили или автобусы. На один из маршрутов можно сесть на площади Сан-Марко и доехать до ж/д вокзала и Пьяццале Рома (автобусная станция), или наоборот. Вапоретто двигается медленно, останавлиясь по очереди на каждом берегу канала, давая возможность рассмотреть дворцы и мосты с таких ракурсов, которые недоступны с берега. Поездка занимает около часа. Насчет гондол – решайте сами. Удовольствие стоит 100 евро за 40 минут, в гондолу может сесть 5-6 человек. У нас не было компании, и мы посчитали, что 100 евро на семью – оно того не стоит.

IMG_1079IMG_1081IMG_1068

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

Monday, May 30, 2011

Итальянские впечатления – 2. Тоскана

Тоскана – это регион в Италии, центром которого является Флоренция. Кроме Флоренции, в нее входят такие известные города как Сиена, Пиза, Лукка и Гросетто. Тоскана считается самой красивой областью, это место происхождения итальянского Возрождения, на территории которого сосредоточены около половины всего культурного наследия Италии.

За свой короткий отпуск мы смогли посетить лишь два тосканских города: Сиену и Лукку, а также покататься на велосипедах по северо-западным пригородам Флоренции.

Фьезоле, Бивильяно

Фьезоле и Бивильяно – это небольшие городки возле Флоренции. Фьезоле расположен совсем рядом, буквально на соседнем холме и разобрать, где между ними граница, невозможно. Бивильяно находится где-то в 15 км от Фьезоле на север. И если во Фьезоле еще есть что посмотреть, то Бивильяно интересен лишь тем, что туда, извиваясь по холмам, ведет живописная дорога. Именно туда мы и съездили на арендованных велосипедах.

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

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

IMG_9540 IMG_9535

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

IMG_9555 IMG_9647 IMG_9656

По дороге постоянно гоняют байкеры на крутых мотоциклах. А еще через несколько километров мы приезжаем в Бивильяно. Бивильяно – это небольшой симпатичный городок, но по большому счету делать там нечего. Зато дорога назад – это просто сказка! Стоило вкручивать педали в горку столько километров, чтобы потом оставить ноги в покое и просто катиться назад. Хорошая погода, ветер в лицо, любимый человек рядом и прекрасные виды вокруг – что еще нужно для счастья?

IMG_9607 IMG_9621

Из Фьезоле стоит возвращаться другой дорогой – через Вивильяно. Дорога идет по настоящему лесному серпантину, а потом выходит в сельскую местность западнее Флоренции. Здесь очень много красивых вилл и сочных лугов, в общем, красиво.

IMG_9670 IMG_9720 IMG_9737

Лукка

Поезда в Лукку отправляются из Флоренции каждый час. Итальянские поезда – это отдельная тема для разговора. Чистые и удобные вагоны, никакой тряски во время движения, хотя крейсерская скорость – 130-140 км/ч. При поворотах поезд наклоняется как самолет, чтобы плавнее войти в поворот. Разница между междугородними поездами и пригородными “электричками” невелика. Последние даже комфортнее, чем украинские экспрессы типа Харьков-Киев.

IMG_8791

Лукка – небольшой городок на запад от Флоренции, всего около 85 тысяч жителей. В нем уникальная планировка: центральная историческая часть ограничена крепостными стенами, причем диаметр внутренней части – больше 4 км. В Лукке есть что посмотреть, на довольно небольшом участке – куча площадей, соборов, статуй и других достопримечательностей. Порадовало, что туристов намного меньше, чем во Флоренции, и в то же время кафешек и магазинчиков вполне достаточно, чтобы хорошо отдохнуть.

IMG_9468IMG_9384IMG_9418 

Город лучше всего осматривать на велосипеде. Его можно арендовать во многих местах возле крепостной стены. 2.5 евро – час, 7.5 евро – 5 часов. Кататься можно не только по центру города, но и по крепостным стенам, которые служат для прогулок и отдыха горожан и гостей города. По стене шириной 10-20 метров проходит вело-пешеходная дорожка, по краям которой посажены деревья и разбиты лужайки. Бастионы используются как парки и смотровые площадки. На дорожке постоянное движение – гуляют семьи с детьми, бегают трусцой молодые и пожилые люди, катаются на велосипедах туристы и даже спортсмены. Вообще, итальянцы очень спортивны, занимаются своим здоровьем, все сухощавы и подтянуты, никакого ожирения, несмотря на обилие теста в национальной кухне.

IMG_9461IMG_9465IMG_9469

Мы прокатались почти по всей стене и объехали все основные достопримечательности города. Жителям города очень повезло. Центр – привычные для средневековых итальянских городов каменные джунгли, деревьев и зелени мало или вообще нет. Зато это с лихвой компенсируется возможностью выйти на стену и там погулять, поваляться на траве или покатать детей в коляске. Детей вокруг очень много, мы часто видели пап с колясками – итальянцы традиционно трепетно относятся к семье и семейным обязанностям.

IMG_9492IMG_9422IMG_9347

Вообще, если ехать жить в Италию, то Лукка – превосходный выбор. Есть исторический центр, где радуется глаз, места отдыха, зеленая парковая зона, спортивная культура. Недалеко – Флоренция и Пиза, можно съездить на море. Вокруг – горы, наверняка есть трекинговые маршруты и зимние курорты.

IMG_9386IMG_9394

Сиена

До Сиены мы тоже добирались на поезде. Сиена – городок еще меньший, чем Лукка, всего 55 тыс. человек. Трудно поверить, что в Средние века Сиена по-настоящему боролась с Флоренцией за господство в регионе и вела кровопролитные бои на протяжении нескольких столетий (Гфельфы и Гиббелины).

IMG_0680IMG_0688IMG_0716IMG_0540

Сиена известна своим Палио. Палио – это традиционное соревнование в конных скачках на главной площади города между представителями 10 из 17 контрад (районов) города, которые постоянно меняются. Сами скачки проходят очень быстро, но гуляния длятся до недели, а приготовления начинаются за несколько месяцев.

IMG_0662IMG_0709IMG_0711

На Палио мы не попали, но приехать в Сиену можно и просто так – это очень красивый город с узкими улочками и арками между домами, стоящий на холмах. Можно без преувеличения сказать, что в Сиене находится одна из самых красивых площадей Европы – Пьяцца дель Кампо, и один из самых красивых соборов Италии – Сиенский собор.

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

IMG_0547IMG_0622IMG_0595

Пьяцца дель Кампо – это и площадь, и амфитеатр одновременно. Площадь построена в виде раковины, центром и жемчужиной которой является Палаццо Публико – городская ратуша с настоящим произведением искусства – башней Торре дель Манджа. Площадь вымощена сиенским кирпичем, на котором очень приятно сидеть и лежать. Здесь отдыхают туристы и жители города: одна девушка недалеко от нас пришла, намазалась кремом для загара, и начала загорать, читая книжку. Европейцы вообще не парятся по поводу того, где посидеть в парке или на площадях – просто усаживаются на брусчатку или землю, и все.

IMG_0535IMG_0765IMG_0538

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

IMG_0745IMG_0748IMG_0758

Все фотографии из Тосканы можно посмотреть на пикасе: Фьезоле-Бивильяно, Лукка и Сиена. В следующий раз я расскажу о Венеции и итальянской кухне.