четверг, 26 ноября 2009 г.

10 простых правил, чтобы лучше писать приложения на ASP.NET

При создании приложений на ASP.NET, мы, как правило, тратим множество усилий на проектирование и изоляцию различных слоев приложения, с упором на предметную область и тому подобное. Однако, как только мы приближаемся к программированию пользовательского интерфейса, код становится более грязным. Я могу объяснить это тем, что чем ближе мы к пользовательскому интерфейсу, тем меньше шансов того, что код используется повторно, или, по крайней мере, предназначен для многократного использования. Несмотря на то, что это может быть правдой (что код не предназначен для повторного использования), UI-код должен быть чистыми и легким для сопровождения.

Код UI должен использовать такие принципы ООП, как наследование и инкапсуляция, ровно как код любого другого слоя. Кроме того, некоторые принципы SOLID, могут и должны быть применены при разработке наших юзер-контролов и веб-страниц. Так как ASP.NET WebForms по-прежнему широко используется, и я полагаю, что так продлится еще долгое время, в этой статье, я предлагаю тот набор правил для программирования и проектирования, который я использую в своих ASP.NET проектах. Надеюсь, что следующие правила помогут вам сделать ваш UI код более чистым и и облегчат его поддержку в дальнейшем.

1. Используйте собственный базовый класс для классов пользовательского интерфейса


Начинайте проект со создания крайней мере двух базовых классов BasePage и BaseUserControl и наследовать от них все ваши веб-формы и юзер-контролы. Это считается хорошим стилем. Причина в том, что у вас непременно возникнет необходимость реализовать общий код для всех или части ваших веб-форм или юзер-контролов.
К примеру, все страницы вашего сайта должны иметь название и, в дальнейшем, некоторым мета-теги. Добавление свойства PageID, а также метода, который вернет название страницы и ее мета-теги будет довольно легко достигнуть при помощи наследования, а поддерживать код, очевидно, станет намного легче.
Другим распространенным случаем является необходимость показать / скрыть элементы веб-формы, в зависимости от определенного условия. Добавив виртуальный метод в базовый класс, который вызывается при возникновении события OnPreRender, вы сможете реализовать механизм скрытия и отображения элементов веб-формы. И весь этот код будет удобно расположен в одном методе и работать для всех классов-наследников, пока вы не переопределите его. Следующий код демонстрирует все вышесказанное, используя дизайн-паттерн "Шаблонный метод"

Пример:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Specialized;
using System.Data;
public class BasePage : System.Web.UI.Page
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
DoEnableDisableControls();
SetTitleFromCMS();
SetMetaTagsFromCMS();
}
public string PageID
{
get;
set;
}
/// <summary>
/// Overwrite this method to enable or disable controls
/// depending on the state of the page.
/// </summary>
protected virtual void DoEnableDisableControls()
{
}

private void SetTitleFromCMS()
{
if (String.IsNullOrEmpty(PageID))
return;
//Queries the CMS for the page title
this.Title = "Whatever we got from the CMS";
}
private void SetMetaTagsFromCMS()
{
//Queries the CMS for the MetaTags
//add the meta tags
}
}


Странице, которая наследуется от базового класса, будет просто необходимо установить свойство PageID – и она будет иметь заголовок и мета-теги (обратите внимание на возможность задать PageID непосредственно в директивах .aspx файла страницы).

<% @ Page Language = "C #" PageID = "DefaultPage" AutoEventWireup = "True" CodeBehind = "Default.aspx.cs" Inherits = "% ExtRefWebApp._Default">


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

2. Скрывайте переменные сессии


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

  • Переменные сессии широко используется в веб-приложениях. Они очень полезны, но мы не должны забывать, что переменная Session, с точки зрения ООП – это ничто иное, как глобальная переменная.
  • При отладке или поддержке веб-приложений, мы часто сталкиваемся с участками кода, которые используют значения, хранящиеся в Session, и нам необходимо проверить, где эти значения были установлены. И это не легко выяснить.
  • Session может содержать любой тип. Если мы заменим тип значения, хранящегося в определенном ключе Session, нам придется проверить весь код и изменить все приведения типов (мы делаем это с помощью поиска/замены текста в коде).
  • Конкретного ключа Session может не существовать, либо он может иметь значение null. Не существует способа для того, чтобы получить по умолчанию для несуществующего ключа Session и, таким образом, всякий раз, когда мы используем переменную сессии, мы должны проверить ее значение (на null) перед использованием.

Лучший способ избежать этих проблем – создать набор классов, по средствам установки свойств которых мы и будем изменять значения Session. При помощи функции Visual Studio "Find all references"/"Find Usages", из контекстного меню при клике на сеттере свойства, вы найдете все объекты, которые устанавливают переменную сеанса. С другой стороны, если мы изменим тип значения в переменной Session, то код, использующий старый тип просто выдаст ошибку компиляции, следовательно, эти ошибки будет очень легко найти и сделать все изменения или оценить объем работы, необходимой, чтобы сделать изменения. Это ужесточает контроль типов и делает наш код более безопасным.
Доступ к значениям Session должен быть инкапсулирован в разных классах, и если их будет слишком много, то, желательно, чтобы они принадлежали одному пространству имен и находились в одной папке, это облегчит их поддержку.

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

3. Не создавайте глубокой иерархии UI-контролов


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

Обычно, это хорошая привычка ограничить дерево максимум на 2 или 3 уровня. Страница содержит элементы управления, которые могут содержать другие элементы управления. Но внутренние элементы должны содержать только базовые элементы управления .NET Framework (или элементы управления веб-сервером). И даже на одном уровне, мы должны ограничивать число юзер-контролов, включенных в родительский юзер-контрол. В том смысле, что создание одного большого юзер-контрола, который содержит множество внутренних юзер-контролов – это не всегда хорошая идея. Имейте в виду, что сама страница может содержать столько контролов, сколько вы пожелаете: я заметил, что очень часто разработчики не используют базовые контролы ASP.NET, а встраивают все в пользовательский Сверх-элемент управления, который в свою очередь, содержит дочерние элементы. Зачем нам добавлять этот уровень косвенности и сложности? Страница – это прекрасный контейнер для элементов управления.

4. Не все должно быть включено в отдельный пользовательский элемент управления


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

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

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

5. Используйте события для обмена данными между юзер-контролами и их контейнерами


Использование свойств пользовательских элементов управления, чтобы сообщить о своем состоянии своему контейнеру – это типичная схема, которую мы видим в веб-разработке. В большинстве случаев разработчики устанавливают переменную сессии, когда что-то случается в пользовательском элементе управления, и контейнер (будь то страница или другой пользовательский элемент управления) проверяет значение переменной сессии для того, чтобы определить, действительно ли что-то случилось или нет. Это обычно делается в событие "OnLoad". Наверное, вы заметили, что очень быстро, мы, в итоге, получаем довольно беспорядочный код в этом обработчике событий.
Во-первых, мы должны гарантировать, что код, который устанавливает переменную сессии выполняется перед кодом, который проверяет ее значение. Кроме того, мы должны гарантировать, что значение переменной сбрасывается: в противном случае, в следующий раз, когда мы попадаем на ту же страницу, мы можем спровоцировать событие, без всяких на то причин.
Один элегантный способ уведомить об изменение статуса одного элемента другому – это создать событие, на которое можно будет подписаться (прим.: public event в C#). Есть много преимуществ такого подхода:

  • Чистый код, который реагирует на конкретные события с внутренних контролов,
  • Один и тот же механизм может быть использован для стольких контролов, сколько мы пожелаем,
  • Мы будем уверены в том, что наш контрол будет извещен только в том случае, если событие действительно произошло; в то время как использование переменных сессии добавляет неопределенности, поскольку мы не знаем, какой код выполняется первым: код, который установил значение Session, или код, который проверяет его.
  • Мы не должны заботиться о переменной сессии и сбрасывать его после событий, поскольку мы больше не используем их.
  • Мы не используем значения Session просто для того, чтобы поставить/считать флаг (а это экономия памяти и уважение основных принципов ООП).


6. Избегайте встраивания C#/VB кода в файлах ASPX


Лучшее место, чтобы добавить программный код в веб-формы – это code-behind файл. Внедрение кода в файлы ASPX делает его грязным и очень трудно поддерживаемым, как в старые времена ASP.

7. Используйте декларативный стиль программирования как можно чаще


Если вам необходимо настроить пользовательский или любой другой серверный элемент управления – сделайте это по средствам свойств в ASPX-файле вместо code-behind. Конечно же, бывают ситуации, когда у нас нет выбора, где настроить элемент управления (условные значения, например), но, в общем, это делает код HTML более четким и облегчает его поддержку, поскольку мы знаем многое о контроле, просто взглянув на один ASPX файл (и нет необходимости смотреть в code-behind файл).

8. Будьте осторожны при использовании статических переменных


Статические члены являются общими и сохраняют свое значение до тех пор, пока работает процесс ASP.NET. Это означает, если вы используете статические члены, вы потребляете память, которая не будет освобождена, пока вы не сделаете это явно.

Один пример я видел в прошлом, проект хранил пользовательскую информацию в виде статического словаря (между прочим, это может быть любой тип коллекции). При нагрузочном тестировании, использование памяти приложения выросло до 12 ГБ на пару сотен пользователей. Так как словарь хранился в статической переменной, ее размер увеличивался при добавлении новых пользователей и, в конце концов, мы получили исключение "Out of memory".

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

9. Рассматривайте производительность с точки зрения клиента


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

Существуют различные средства и способы, чтобы сделать производительность страницы лучше на клиентской стороне (хорошей отправной точкой, будет эта статья: http://www.codeproject.com/KB/aspnet/PeformanceAspnet.aspx).

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

Другой проблемой является количество Javascript файлов, которые загружаются вместе со страницей. Мы должны объединить их с помощью ScriptManager (см. http://bellouti.wordpress.com/2008/09/14/combining-javascript-files-with-ajax-toolkit-library/ ).

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

10. Используйте кэширование, где это только возможно


Пользовательские элементы управления можно кэшировать с помощью директивы OutputCache. При создании пользовательских элементов управления, которые должны показываться содержание, взятое из БД или внешних источников, следует рассмотреть возможность использования этой директивы.
Мы также можем кэшировать данные в статических членах или пользования объектами кэширования EnterpriseLibrary. Если мы сделаем это, мы должны гарантировать, что мы создаем кэш в форме, ближайшей к той, что будет выводиться в интерфейсе пользователя. Например, если вы получаете XML из базы данных и трансформируете его по правилам XSLT в HTML, который и будет отображаться, то кэшировать следует результирующий HTML, а не XML. Кэширование HTML позволит избежать повторных преобразований XML в следующий раз, когда будет запрошена страница.



Автор статьи: Samir Bellouti
Оригинал: 10 simple rules to write better ASP.NET applications
Перевод: Дмитрий Жарий

суббота, 24 октября 2009 г.

10 типов программистов, с которыми вы обязательно столкнетесь

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

#01: Гендальф

Такой тип программиста может успешно сыграть роль Гэндальфа во "Властелине колец". У него (или у нее! :) длинная борода по колено, глупая шляпа; может носить плащ или накидку зимой. К счастью для команды, на рабочем месте, это адепт белой магии, прямо как Гэндальф. К несчастью для команды, они должны будут терпеть часы рассказов Гэндальфа о том, как он или она шел в гору, по снегу, чтобы доставить перфокарты в далекий вычислительный центр. Гэндальф ¬¬– это ваш наилучший ударник IT-шного труда, но если вы попробуйте оставить его позади команды – это вызовет отчаяние.



#02: Мученик

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

#03: Фанатик

Следите за Фанатиком. Если он или она настигнет вас врасплох, и прижмет в угол, то вы будете обречены, прослушать трехчасовую лекцию о превосходстве Opera по сравнению с Firefox, или почему Playstation 3 лучше, чем XB 360. На рабочем столе Фанатика разложены плакаты, фигурки и другие безделушки, связанные с его навязчивыми идеями, скорее всего, привезенные из Японии. С фанатиками невозможно иметь дело, они тратят настолько много времени на свою одержимость (внутри и вне офиса), что они совершенно не понимают, когда нужно выполнять работу, для которой их наняли.


#04: Винс Нил

Это человек около сорока лет, который живет в далеком к 1984 году. Длинные волосы, потертые стираные джинсы и бандана. На протяжении рабочего дня, Винс сидит в офисе, напевая мелодии Bon Jovi и Def Leppard. И, в принципе, все не так уж и плохо, если бы песня "Pour Some Sugar On Me" не была бы так чертовски заразительной.

Винс – веселый человек и работать с ним – одно удовольствие, и на самом деле он очень опытный человек, но просто... никогда не взрослеет. Но Винс доставляет хлопоты, когда он или она пытается жить в стиле Rock-n-Roll; с длинными волосами на голове, и с берцами на ногах. И… достаточно сложно работать с теми, кто приходит на работу с похмелья каждый день.

#05: Ниндзя

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

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

#06: Теоретик

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

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

#07: Ковбой

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

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

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

#08: Десантник

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

#09: Посредственный Человек

"Достаточно хорошо" это лучшее, что вы можете получить от Посредственного Человека. Он или она всегда тратят больше времени для создания худшего кода, чем у кто-либо в команде. "Тише едешь – дальше будешь" – так можно описать проекты П.Ч. Но П.Ч. всегда просто "достаточно хорош" чтобы не быть уволенным.

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


#10: Евангелист

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

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



Оригинал статьи: 10 types of programmers you'll encounter in the field
Автор: Justin James

Перевод: Дмитрий Жарий

воскресенье, 16 августа 2009 г.

C# и Java – это языки будних дней, а Python и Ruby для выходных?

Результаты интересного эксперимента опубликовал Ден Лоренц в своем блоге. Используя официальный дамп базы данных сайта StackOverflow, он подсчитал с какой интенсивностью задаться вопросы по C#, Java, Ruby и Python.

Как оказалось, на протяжении всей рабочей недели, лидируют C# и Java, в то время, как на выходных активность идет на спад. В тоже время, на выходных активность вопросов по Ruby и Python возрастает.

Прочитать пост можно здесь:
StackOverflow Experiment Results

вторник, 21 июля 2009 г.

Perl, C# и регулярные выражения

Казалось бы, Perl и C# -- языки очень разные, но как оказывается, C# поддерживает стандарт де-факто регулярных выражений – Перл совместимые регулярные выражения.

Конечно же, для Perl регулярные выражения родные, и сними намного удобней работать именно в Перле, но, для того чтобы регулярные выражения заработали в C# -- достаточно просто взять и скопировать их из перлового скрипта.

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

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

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

Следующий код выводит дату и время из строчек массива variants:

#!perl
my @variants =
(
q~^92(28/10/2002)**&[19:10:50]@Comment: Text String"~,
q~^-06/02/2002*$21:55:45~,
q~^*13/08/2002*DX145&[22:50:20]@Comment: Text String~,
);

foreach my $variant ( @variants ) {

if ( $variant =~ m!([0-3][0-9]/[0-1][0-9]/[1-2]\d\d\d).+?
                       ([0-2][0-9]:[0-5][0-9]:[0-5][0-9])!x )
{
print "Date: $1; Time: $2\n";
}
else {
print "Failed to parse string: $variant\n";
}
}


И пример на C#:

using System;
using System.Text.RegularExpressions;

namespace RegexTest
{
class Program
{
static void Main(string[] args)
{
string[] variants = {
@"^92(28/10/2002)**&[19:10:50]@Comment: Text String""",
@"^-06/02/2002*$21:55:45",
@"^*13/08/2002*DX145&[22:50:20]@Comment: Text String",
};
Regex veriantRegex = new Regex(@"(?<date>[0-3][0-9]/[0-1][0-9]/[1-2]\d\d\d).+?" +
@"(?<time>[0-2][0-9]:[0-5][0-9]:[0-5][0-9])" );
foreach (var variant in variants)
{
Match match = Match.Empty;
if ((match = veriantRegex.Match(variant)) != Match.Empty)
{
Console.WriteLine("Date: {0}; Time: {1}", match.Groups["date"].Value,
match.Groups["time"].Value);
}
else
{
Console.WriteLine("Failed to parse string: {0}", variant);
}
}
}
}
}


Output:

Date: 28/10/2002; Time: 19:10:50
Date: 06/02/2002; Time: 21:55:45
Date: 13/08/2002; Time: 22:50:20

воскресенье, 17 мая 2009 г.

Ссылка. Tell me about your work / life balance, Are you happy?

Интересная дискуссия о жизни программиста и о счастье. Меня особенно зацепил первый комментарий в топике, который я привожу в цитате.
Читать оригинал: Tell me about your work / life balance, Are you happy?

I go into work, screw off for a few hours, get some programming done after lunch, go home, work on code well into the night fueled by vault. 4 AM rolls around, I go to bed, wake up at 10, go back into work...

Weekend comes, I wake up at 5 or 6 PM on Saturday (have to make up for the lost sleep during the week), I play some games, do some work, maybe go out and play pool or hang out with friends, or get drunk, go to bed at noon. Wake up at 5 or 6 PM Sunday, get to a good stopping point on work.

Each of these days I pretty much eat fast food and my body hates me for it. I drink way too much soda, smoke way too many cigarettes. Each week I work 40 (reported) hours because no overtime is allowed, but in reality I work closer to 70 hours just to give everyone the idea that I'm this amazing programmer who can get things done.

I used to weigh 155 before I started programming again, I was lifting weights regularly and I lived for the outdoors. Now I stay inside all the time, I'm 25 lbs heavier - which is still ok (but not great) for a 5'11 guy, but I have absolutely no energy and I always feel tired.

I'm enjoying the programming immensely, but since where I work is staffed 99% male with all the females in another area, I don't get many opportunities for meeting women. It blows. I go to a bar and all of the women there are mid to late 30's and I'm only 28.

I make decent money, maybe not for a programmer, but pretty good compared to all of my friends from high school, but I sock 75% of it away and drive a car that costs less in total than most people's yearly insurance premium.

My life is severely dysfunctional. There is no order to it whatsoever, it's entirely chaotic. I am well past the stage of burnout, I'm missing out on life. I've never gotten laid; though I talk to some girls regularly and I can't really push myself to try for more than friendship.

My social life is pathetic. I know of only 3-4 people I hang out with who aren't from work. All in all, I'm happy with the work, but I find the rest of my life deeply unsatisfying.

I don't know if this is a typical programmer experience, but there you have it.

среда, 6 мая 2009 г.

Наследие от MS-DOS. Какой ваш логин [%_username_%], случайно не COM1?

Интересную багу сегодня нашли. Наверное, все знают, что имя пользователя не должно содержать таких символов как <, ?, >, * и т.д., потому что при регистрации профиля пользователя, для него может создаваться папка, куда будет складываться различный файлы по типу музыки, фоток и т.д.
Но, наверное не все знают, что имена папок, такие как com1, com2 … com9, lpt, con, nul, aux и другие запрещены, потому что эти имена зарезервированы MS-DOS и Windows. Это имена устройств.

А как поведет себя ваше приложение, если пользователь с именем com1 будет создан в БД, но при создании папки для его профиля произойдет ошибка? Хорошо еще, если все неприятности закончатся на 404-й ошибке при попытке запросить данные из папки его профиля. Вы проверяли?

вторник, 5 мая 2009 г.

Учишь? Меня? Но я ведь Эксперт!

Ты был кодером на протяжении нескольких лет, возможно, даже десятилетий. Ты нашел успешную работу, зарабатываешь достаточно денег. Ты знаешь «респектабельные» технологии, которые так востребованы на рынке труда: C++, C#, Java и т.д. И тебе без надобности учить что-то новое. Оставайся в своей зоне комфорта. Бери пример с этих парней:
"Я думаю, что весь мировой рынок состоит приблизительно из 5 компьютеров."
- Thomas J. Watson, Председатель Совета, IBM, приблизительно 1948

"Кажется, что мы достигли пределов того, чего возможно достигнуть в компьютерной технологии, хотя нужно быть осторожным с такими утверждениями, поскольку они имеют тенденцию казаться довольно глупыми через 5 лет."
- Джон Von Neumann, приблизительно 1949

"Но, где это можно будет использовать?"
- Инженер в Advanced Computing Systems Division of IBM, комментируя микрочип, 1968

"Нет никакой причины для любого человека иметь компьютер в своем доме."
- Кен Olson, президент, Digital Equipment Corporation, 1977

В самом деле, мудрые слова.
Ты должен учится, когда ты знаешь, что не знаешь достаточно. Легко взять книгу, когда ты чувствуешь неуверенность в собственных знаниях. Но, опасней всего, когда ты действительно думаешь, что знаешь достаточно. Программирования (как и вся компьютерная наука) походит на бег Красной Королевы: ты должен бежать с такой скоростью, с которой только можешь для того, чтобы оставаться на своем прежнем месте.

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

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

Если вам понравились цитаты, то их можно почитать еще и это: A Double Handful of Programming Quotes

Оригинальная статья: Learning? Me? But I’m An Expert
Перевод: Дмитрий Жарий

среда, 29 апреля 2009 г.

Silverlight: Открываем Насыщенные Интернет Приложения для мира Open Source


Silverlight: Enabling Rich Internet Applications for the Open Source World.
Да, вот скачал себе туториал на 44 странички с таким вот громким названием. В общем то, туториал не плохой, поэтому его и рекомендую. Рассказывает, как создавать приложения на Silverlight без Visual- и прочих студий, а на родном, для Java-разработчиков, Eclipse.

Книга бесплатна. Скачать вы ее можете вот отсюда, но пройдется пройти процедуру регистрации на сайте. Поэтому, скачать книгу можно также с моего Яндекс.Диска.

воскресенье, 26 апреля 2009 г.

Английский язык, как же его fucking сложно изучить

Когда я учился в школе, я любил уроки английского языка. Сравнительно с другими предметами, я почти всегда делал домашние задания и, следовательно, мог похвастаться своими оценками, начиная с 5-го класса. В общей сложности, как обычный школьник, а потом и в колледже, я изучал английский на протяжении 10 лет. Тогда было много свободного времени, часть которого можно было посвятить на чтение англоязычной книги, мануалы по какой-нибудь технологии в программировании и т.д.
Но, когда я устроился на работу, понял, что нихрена то я и не знаю английского языка.
По крайней мере, очень сложно понять разговорный английский, общаясь с американскими заказчиками. Я понимал слово через десять, и приходилось связывать эти 10% распознанного текста какой-нибудь своей логикой, чтобы ответить что-то в тему.

Через год, я понял, что, в принципе все не так сложно. По работе мы, как оказалось, общаемся шаблонами. Когда слышишь или читаешь одну и ту же шаблонную фразу несколько раз, то поневоле запоминаешь ее, и уже используешь самостоятельно:
“This bug is reproduced…”, “An exception has occurred”, “At this point [%some behavior here%]”.
Проработав уже более 3-х лет над одним и тем же проектом, я хорошо понимал устный английский заказчика, мог вести электронную переписку и иногда вставить свои 5 копеек в устной форме, при разговоре по Skype, например.

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

Проблемы


  1. Основная проблема в том, что на изучение английского не хватает желания, если хотите, то не хватает грубого пинка под зад. Кто сказал что я не понимаю английского? Я прекрасно понимаю, что там написано на MSDN или на CPAN. Я отлично ориентируюсь в том чего от меня хотят, и могу объяснить, что я буду делать в переписке по ы-мейлу. В устной форме я могу связать 3 слова, и помочь себе жестикуляцией. Кроме того, устным английским мне приходится пользоваться очень редко.
  2. Не хватает времени. С одной стороны, тут все таки больше желания опять таки не хватает. Ну не могу я посвятить кучу времени на изучение английского. Лучше я какую-нибудь книгу умную почитаю, или разберусь с какой-нибудь интересной технологией, или напишу что-то свое. Не могу я выделить время и в будние дни, чтобы ходить на курсы по английскому – мне работать надо.
  3. Не хватает практики. Ну, хорошо, вот изучу я английский, и с кем я буду общаться? А если не буду общаться, то деградирую нафиг и забуду все.


Решения


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

Что же касается нехватки времени, тут все очень просто. Ну, по крайней мере, я считаю, что все очень просто.
Дело в том, что у нас, обычных людей, есть целая мусорного времени:
  • Когда мы едем в поезде/метро/маршрутке на работу и с работы. Сколько времени теряем? Я теряю 1 час в день, т.е. 5!!! часов в неделю.
  • Когда ничего не хочется делать, когда просто устал и развалился перед телевизором или лег отдохнуть.
  • Когда делаешь тупую рутинную работу, не требующую полного вмешательства мозга.

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

При этом, все те аудио материалы которые я слушаю, можно разделить на следующие категории:

ESL – English as a Second Language, рассчитаны специально на слушателей, изучающих английский:

English as a Second Language Podcast
Самый известный ресурс. Обновляются очень часто. Аудио материалы бесплатны и очень хорошего качества.
Слушать: ESL Podcast 472 – Feeling Nervous About Public Speaking


Fun English Lessons
Это действительно веселые подкасты. Очень рекомендую. Слушаю их обычно утром, чтобы поднять настроение перед работой.
Слушать: 119 - E-Commerce


Преимущество этих подкастов в том, что они не устаревают, я скачал себе весь архив и слушаю каждый подкаст.
Характерной чертой ESL подкастов является то, что на «простом» английском объясняется более сложный английский. Кроме того, в ненавязчивой форме рассказывается про культуру и жизнь американцев, что, несомненно, помогает понять их лучше.

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

SE-Radio
Слушать: Episode 133: Continuous Integration with Chris Read


The Command Line Podcast
Слушать: TCLP 2009-04-22 Interview: Jonathan Zittrain


Deep Fried Bytes
Слушать: Episode 30: New Ideas for the Web with Thomas Krotkiewski


Herding Code
Слушать: Herding Code 43: Javier Lozano on the "M" in MVC


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

В первую очередь, это Будам. Этот человек живет в Америке, и очень много рассказывает про американский образ жизни в своей ленте За cool жизнь.
Слушать: #85 American Woman


И рекомендую ленту career_english Влада Воробьева.
Слушать: Russian-english typical phrases and expressions - THINK


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

Секретное, самое мощное и самое сложное оружие


Это перевести какую-нибудь англоязычную статью. На самом деле на перевод небольшой по объему статьи, можно потратить кучу времени. Основную сложность тут составляют так называемые идиомы, ведь дословно каждое слово переводить нельзя! Вот и тратишь время на распознавание этих идиом и гугление значений, чтобы не получилось, как в старом анекдоте:
В российской глубинке фестивальный показ зарубежных фильмов.
На экране идет американский фильм...
Герой на экране:
- How do you do
переводчик:
- Как вы это делаете?
Ответ:
- It's all right
переводчик:
- да все правой,правой.

понедельник, 20 апреля 2009 г.

Красота string.Empty или скорость“”?

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

static void Main(string[] args)
{
string token = " ";
switch (token.Trim())
{
case string.Empty:

break;
}
}


Я очень удивился, когда компилятор выдал ошибку, что в строке
case string.Empty:
требуется констанотное вырожение.
Лезем в Object Browser и смотрим декларацию string.Empty:

public static readonly string Empty в классе String.

Почему не константа?! Может быть, есть какое-то сверх объяснение, связанное со сверх оптимизациями и прочей магией?
Погуглив на это тему, обнаружил замечательную статью:
string.Empty Example and Issues in C#
Оказывается, что даже при использовании в конструкции if, сравнение со string.Empty работает в два раза медленнее, чем с константной пустой строкой "":

=== string.Empty benchmarked code ===

if (string.Empty == null)
{
throw new Exception();
}

=== Constant string benchmarked code ===

if ("" == null)
{
throw new Exception();
}

=== Benchmark results ===
Second loop was completely compiled out before runtime.
1000000000 iterations.

string.Empty loop: 637 ms
"" loop: 319 ms [faster]


Я не отказываюсь от использования string.Empty, но теперь призадумаюсь о том, стоит ли использовать такую запись пустой строки на конкретном участке кода.

среда, 15 апреля 2009 г.

Слушаем C Sharp ;)

Так вот, какой ты, C Sharp ;)

Кстати, таки не плохо поют ;) Послушать: C-Sharp Band

понедельник, 13 апреля 2009 г.

Строки в C# и внутренний пул

Я не знаю, почему это людей так беспокоит вопрос о том, где формируются строки с C# и так радует ответ, что они формируются во внутреннем пуле(Intern pool). Но, видимо это очень важно, так как такие вопросы присутствуют в большинстве статей по подготовки к собеседованию по C# и такой вопрос, я сам на него отвечал, есть в тесте BrainBench.

Мне, честно говоря, было пофигу, где эти строки формируются и хранятся, главное, что это все работает. Я воспринимал это как аксиому, которую, точнее, нужно сформулировать так: «Все строковые литералы компилятор C# помещает во внутренний пул».

Но, когда я писал код, похожий на следующий код, то немного призадумался:

string name = textReader.ReadLine();
switch (name)
{
case "Bob":
Console.WriteLine("Hello, Bob!");
break;
case "Vasya":
Console.WriteLine("Privet, Vasya!");
break;
default:
Console.WriteLine("O_o Vasya!");
break;
}


Ведь в переменной name содержится строка, прочитанная из файла в момент выполнения, так как же эти строковые кейсы работают? Они же, по идеи, должны сравнивать ссылки. А чтобы моя переменная name совпала хотя бы с одним этим кейсом, то она тоже должна быть интернирована (помещена в пул), как и строковые литералы.

Оказывается, что да. И в каком месте это происходит, я пока еще не знаю. Но, строковые литералы помещаются в пул в момент компиляции, а новые, динамические строки взаимодействуют с этим пулом в момент выполнения. Получается, что каждая новая строка сравнивается со всеми уже существующими, что может влиять на производительность кода.

Я наивно пытался похачить это дело, но все-таки ничего не получилось:

using (TextReader tr = File.OpenText(@"C:\temp\strings.txt "))
{
string string1 = tr.ReadLine(); // This is a string
string string2 = tr.ReadLine(); // This is a string
string string3 = tr.ReadLine(); // This is another string

Console.WriteLine("First try:");
Console.WriteLine(" string1={0}\n string2={1}\n string3={2}", string1.GetHashCode(),
string2.GetHashCode(),
string3.GetHashCode());
StringBuilder sb = new StringBuilder();
string internPool = "Intern Pool";
sb.Append("Intern ").Append("Pool");
Console.WriteLine("Second try:\n string1={0}\n string2={1}", internPool.GetHashCode(),
sb.GetHashCode());

Console.WriteLine("Third try:\n string1={0}\n string2={1}", internPool.GetHashCode(),
sb.ToString().GetHashCode());

}


Текстовый файл:

This is a string
This is a string
This is another string


Вывод первой попытки, как не странно string1 и string2 равны:
First try:
string1=2035671784
string2=2035671784
string3=164170943


Вывод второй попытки! Ага все таки не равны! Но, на самом деле и типы тут разные:
Second try:
string1=-1024490162
string2=58225482


Вывод третий попытки. Приведем-ка это это добро .ToString. :( Все таки ссылки равны:
Third try:
string1=-1024490162
string2=-1024490162



Upd. Вот что значит дописывать код в 2 часа ночи :) На самом деле, ссылки не равны, а .GetHashCode это не правильный способ. Спасибо, Alex, за комментарий.

Если добавить следующие строки кода, то выясняется, что ссылки действительно не равны:

Console.WriteLine("Ref Eq string1 and string2 = {0}", object.ReferenceEquals(string1, string2));
Console.WriteLine("Ref Eq string2 and string3 = {0}", object.ReferenceEquals(string2, string3));
// и...
Console.WriteLine("Ref Eq internPool and sb.ToString() = {0}", object.ReferenceEquals(internPool, sb.ToString()));


Результат:

Ref Eq string1 and string2 = False
Ref Eq string2 and string3 = False

Ref Eq internPool and sb.ToString() = False

вторник, 7 апреля 2009 г.

Экономим байты исходного кода. Реализация алгоритма QSort

Однажды, когда я проходил трейнинг по C#, нам было задано домашние задание, одним из пунктов которого было реализовать алгоритм быстрой сортировки(QSort) на C#. По достаточно хорошему описанию алгоритма на страницах Википедии, я все-таки реализовал алгоритм по-своему, но решил продолжить поиск наиболее «короткого» решении. И я его нашел. Следующий код написан на языке Perl, и это то, к чему нужно стремиться:

sub qsort {
return () if !@_;
return (qsort(grep { $_ < $_[0] } (@_)[1..$#_]), $_[0],
qsort(grep { $_ >= $_[0] } (@_)[1..$#_]));
}


Превосходно! Реализация алгоритма наглядна и прекрасно запоминается. Я попытался переписать исходный код с Perl на C#, и вот что у меня получилось:

public static List<T> QSort<T>(List<T> sourceArray)
where T : IComparable<T>
{
if ( sourceArray.Count == 0 )
{
return new List<T>();
}
T firstItem = sourceArray[0];
sourceArray.RemoveAt(0);

List<T> greaterList = new List<T>();
List<T> lessList = new List<T>();
List<T> sortedArray = new List<T>();


foreach (T item in sourceArray)
{
if (item.CompareTo(firstItem) < 0) lessList.Add(item);
}

foreach (T item in sourceArray)
{
if (item.CompareTo(firstItem) >= 0) greaterList.Add(item);
}

sortedArray.AddRange(QSort(lessList));
sortedArray.Add(firstItem);
sortedArray.AddRange(QSort(greaterList));

return sortedArray;
}


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

public static IEnumerable<T> QuickSort<T>(this IEnumerable<T> list)
where T : IComparable
{
if (!list.Any())
{
return Enumerable.Empty<T>();
}
var pivot = list.First();
var smaller = list.Where(item => item.CompareTo(pivot) <= 0).QuickSort();
var larger = list.Where(item => item.CompareTo(pivot) > 0).QuickSort();

return smaller.Concat(new[] {pivot}).Concat(larger);
}


Кто короче?! ;)

воскресенье, 5 апреля 2009 г.

10 навыков, которые потребуются разработчикам в ближайшие 5 лет

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

1. Один из «Большой Тройки» (.NET, Java, PHP)

Если в мире разработки не произойдет радикальных изменений (скажем, на Редмонд упадет астероид), то разработчикам будет необходимо знать по крайней мере один, из «Большой Тройки» языков программирования и платформ разработки: .NET (VB.NET or C#), Java, или PHP в самом ближайшем будущем. И недостаточно знать одного лишь синтаксиса языка программирования. Поскольку проекты охватывают самые разнообразные функциональности, вам будет просто необходимо знать Фреймворки и библиотеки, связанные с необходимым функционалом, более углубленно.

2. Насыщенные Интернет Приложения (RIA)

Любили вы RIA, или ненавидели, но Flash используется сейчас не только для создания мультфильмов про политиков, которые поют глупые песенки. Flash нарастил дополнительную функциональность по для создания приложений, используя такие технологии как Flex и AIR. Конкуренты Flash, такие как JavaFx и Silverlight, также разрабатывают подобные фичи и повышают производительность. И чтобы укрепить связь между этими вещами, HTML5 объединит себе всю функциональность RIA, включая соединение с базами данных, и ставя этим официальную печать W3C на технологии AJAX. И это значит, что в ближайшем будущем, различия RIA платформ будут очень сильно сглажены.

3. Веб-разработка

Веб-разработка никуда не уйдет, по крайней мере в ближайшее время. Многие разработчики игнорируют Веб, или по крайней мере знакомы лишь с теми основами, которые предоставляют им фреймворки. Но, компаниям требуется все больше и больше людей, умеющих работать с теми технологиями, которые лежат ниже уровня фреймворка. Так что JavaScript, CSS, и HTML будут успешны на протяжении еще 5-ти лет.

4. Веб-службы

REST или SOAP? JSON или XML? То, что выбор решения зависит от проекта, сложность работы разработчика возрастает без использования технологии Веб-служб. Даже те сферы, где раньше использовались ODBC, COM, или RPC, постепенно переходят на использование Веб-служб. Разработчики, которые не умеют работать с Веб-службами, найдут себя в сфере поддержки и баг-фикса старых проектов.

5. Социальные навыки

Все что сейчас происходит, движется к увеличению видимости IT внутри и снаружи предприятия. Разработчики постепенно вовлекаются в сферы, не связанные непосредственно с разработкой, для получения от них ответов на существующие вопросы. Скажем, финансовый директор не может изменить правила бухгалтерского учета, без помощи IT для внесения изменений в необходимые системы. Точно так же, как нельзя изменить работу кол-центра, без внесения необходимых изменений в CRM-систему предприятия. Также, клиентам часто необходимо работать с разработчиками напрямую, чтобы убедится в том, что их требования были учтены. Пойдут ли разработчики изучать ораторское искусство, или начнут изучать книгу по типу «Как завоевать друзей и влиять на людей»? Нет. Но, разработчики, которые все-таки сделают так, будут более ценны для своего начальства и высоко ценится на рынке труда.

6. Один динамически и/или функциональный язык

Такие языки, как Ruby, Python, F#, Perl и Groovy это не совсем мейнстрим, но хорошие идеи в них есть. Скажем, LINQ из .NET Framework – это прямой потомок функциональных технологий программирования. Python и Ruby стают более востребованы в некоторых областях, благодаря фреймворку Ruby on Rails и хорошей поддержки программирования под Silverlight. Изучение одного из этих языков не просто улучшит ваше резюме, но и расширит ваш кругозор. Каждый признанный и уважаемый разработчик, рекомендует изучить по крайней мере один динамический или функциональный язык программирования, чтобы познать новые способы мышления и решения задач. И из личного опыта, могу сказать вам, что это действительно работает.

7. Гибкие методологии

Когда Agile только появилось в мейнстрим разработке, я и много других людей, которых я знаю, отнеслись к этому скептично. Это скорее всего был рефлекс по защите традиционного подхода, отбрасывая прочь все инструменты, которые бы привели к анархии. Но, время шло, и идеи, лежащие в основе Agile стали лучше определены и четче выражены. И многие команды уже используют и экспериментируют с Agile. Конечно же, Agile не является той панацеей, которая спасет проект от провала, но гибкие методологии действительно успешно используются во многих проектах.
Разработчики с пониманием Agile и успешной работы с инструментами гибкой разработки будут востребованы на рынке труда. И этот спрос будет расти в ближайшие 5 лет.

8. Знание предметной области

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

9. «Гигиена» разработки

Несколько лет назад, много коллективов разработчиков не использовали такие инструменты как: баг-трекинговые системы, системы контроля версия и другие подобные инструменты. Они просто работали со своей IDE и все. Но, благодаря новым подходам по интеграции, и новым инструментам, таким как Microsoft Visual Studio Team System и появлению высококачественных инструментов с открытым исходным кодом, коллективов не использующих такие инструменты стает все меньше. Но, разработчикам уже недостаточно знать только то, как можно залить код в репозиторий, или забрать его оттуда, или как использовать виртуальные машины для создания тестовой среды. Они должны быть аккуратны, и уверены в том, что они надлежащим образом координируют свои действия с действиями команды. Те люди, которые копируют все на свою персональную флешку, не документируют то, каким элементам задачи соостветсвуют изменения кода и тому подобное, не приветствуются в традиционных коллективах, и еще больше не приветствуются в Agile-командах, полагающихся на тесную координацию и коммуникацию между членами команды.

10. Разработка для мобильных устройств

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


От себятинка:
Одиннадцатым пунктом я бы добавил в этот список «знание английского языка», этот скилл был востребован и раньше и будет востребован еще и через пять и пять десятков лет. Если, конечно же, на Редмонд не упадет огромный астероид ;)
Подобные переводы, отнимают кучу моего времени, но вместе с тем, они прокачивают мой уровень английского языка, и просто приносят удовольствие.
Поэтому, могу посоветовать тебе, Читатель, ищи что-то интересное на английском, и переводи на свой родной язык.

Оригинал статьи:
10 skills developers will need in the next five years

Про автора оригинальной статьи:
Justin James is an employee of Levit & James, Inc. in a multi-disciplinary role that combines programming, network management, and systems administration.

суббота, 4 апреля 2009 г.

.NET, NHibernate, Castle ActiveRecord и генераторы кода. В поисках истины

Я работал раньше с ORM’ами на других языках программирования, и должен сказать, что я, как человек ленивый и стремящейся всеми возможными способами упростить свою работу, уже прочно привык к их использованию. Так что, вместо того, чтобы писать деревянные и тривиальные запросы для CRUD-операций и кучу JOIN’ов для реализации связей между таблицами, я предпочитаю заюзать хороший ORM и не париться по этому поводу.
Так как проект пишется на ASP.NET с возможной поддержкой Mono, то мне было необходимо, чтобы этот ORM работал с MySQL, чтобы был хороший генератор кода для классов записей, и чтобы он был как можно проще для изучения. Ну, не хочу я месяц тратить на изучение какой-нибудь технологии, без которой, я в принципе, могу и обойтись.

NHibernate


Первое, что мне бросилось в глаза для .NET – это NHibernate (рус. http://nhibernate.ru/). Очень мощный ORM, используемый достаточно большим количеством людей. На то, чтобы разобраться в азах этой штуковины, я потратил целый вечер, и понял, что это вещица это действительно мощная, но не такая уж и простая и содержит кучу нюансов. Это я понял, пролистав «купленную» книгу NHibernate In Action и просмотрев несколько отрывков из скринкастов по NHibernate. Слишком сложно. В топку :(

ActiveRecord


Бороздя необъятные просторы Интернета, я все-таки нашел то, что мне нужно. Это Castle ActiveRecord. Хорошо, что он построен на базе NHibernate, так что мне не пройдется отказываться от функционала NHibernate. Но, это проще чем NHibernate! И это то, что нужно для моего проекта. Ура! Меня не пугает то, что последний релиз (точнее релиз кандидат) был полтора года назад, я смотрю на то, что в Сети есть много позитивных отзывов по поводу Castle ActiveRecord. Кроме того, я немного работал с ActiveRecord в Ruby, и уверен, что для меня не составит труда быстро изучить, как использовать реализацию ActiveRecord на C#.

Генераторы кода


Уйму времени потратил на то, чтобы найти тулзу, которая бы сгенерировала мне код для моих ActiveRecord классов. Ситуацию осложняло то, что мне нужно было сгенерировать классы, по готовой БД, под управлением MySQL. Перепробовал кучу генераторов кода, но одни отказывались работать с MySQL, другие отказывались работать с MySQL. Хотел уже впасть в панику, и перегнать БД из MySQL в SQL Server, и уже от туда сгенерировать нужные классы. Но, проблема разрешилась. Нашел вот это:
Caragen Tool - the Castle Active Record Autonomous GENerator tool, которое прекрасно поддерживает работу с MySQL.

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

вторник, 24 марта 2009 г.

Крик души ;)

public static Testplan ParseFile(string filePath)
{
ApplicationClass excel = new ApplicationClass();
excel.Visible = true;
excel.Workbooks.Open(filePath, false, false, null, null, null,
true, null, null, null, null, null, null,
null, null);

// А все таки фигово, что в 3-м Сишарпе нет именованных аргументов
// и аргументов по умолчанию. Ждем-с 4-го Сишарпа :(

return new Testplan(null, null, null);
}


Тоже самое, только на Perl:

my $Book = $Excel->Workbooks->Open( {
FileName => $FILE_NAME,
UpdateLinks => 0,
ReadOnly => 1,
IgnoreReadOnlyRecommended => 1,
}
) or die("Cannot open file $FILE_NAME");


UPD:

На самом деле, пропущенные параметры нужно заполнять при помощи значения Missing.Value, которое описано в System.Reflection. В противном случае (если использовать null), можно нарваться на Exception.



excel.Workbooks.Open(filePath, false, false, Missing.Value, Missing.Value, Missing.Value,
true, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value);

воскресенье, 22 марта 2009 г.

Архивы журнала Playboy открытом доступе

Сводка недоступна. Нажмите эту ссылку, чтобы открыть запись.

вторник, 17 марта 2009 г.

Культура красивого кода на C#

Стандартов и правил кодирования придумано море. В следующем документе, в краткой форме описываются, пожалуй, самые обобщенные правила относительно кодирования на C# 3.

Aviva Solutions C# 3.0 Coding Guidelines (pdf)
Aviva Solutions C# 3.0 Coding Guidelines Quick Reference Guide (pdf)

воскресенье, 15 марта 2009 г.

sealed классы работают быстрее... не намного, но быстрее!

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

В следующем примере я создал 10 виртуальных методов в базовом классе BaseClass. И эти функции переопределяются в классах DerSealedClass и DerNotSealedClass. DerSealedClass – это sealed класс, а DerNotSealedClass – нет.
Каждую итерацию цикла, вызываются все эти 10 методов у обоих классов.
Вот результаты теста для 100 000 000 итераций. Чем меньше времени потрачено – тем лучше!

Iterations: 100000000;
DerNotSealedClass: 357 ms;
DerSealedClass: 345 ms;

Как видите, разрыв небольшой, но все таки sealed классы работают быстрее.

Вот код теста:
using System;
using System.Diagnostics;

namespace TestTime
{
class Program
{

public class BaseClass
{
public virtual int Op0() { return 1; }
public virtual int Op1() { return 1; }
public virtual int Op2() { return 1; }
public virtual int Op3() { return 1; }
public virtual int Op4() { return 1; }
public virtual int Op5() { return 1; }
public virtual int Op6() { return 1; }
public virtual int Op7() { return 1; }
public virtual int Op8() { return 1; }
public virtual int Op9() { return 1; }
}

public sealed class DerSealedClass : BaseClass
{
public override int Op0() { return 2; }
public override int Op1() { return 2; }
public override int Op2() { return 2; }
public override int Op3() { return 2; }
public override int Op4() { return 2; }
public override int Op5() { return 2; }
public override int Op6() { return 2; }
public override int Op7() { return 2; }
public override int Op8() { return 2; }
public override int Op9() { return 2; }
}


public class DerNotSealedClass : BaseClass
{
public override int Op0() { return 3; }
public override int Op1() { return 3; }
public override int Op2() { return 3; }
public override int Op3() { return 3; }
public override int Op4() { return 3; }
public override int Op5() { return 3; }
public override int Op6() { return 3; }
public override int Op7() { return 3; }
public override int Op8() { return 3; }
public override int Op9() { return 3; }
}

private static void perfTest()
{

const int iterations = 100000000;

Stopwatch sw1;
Stopwatch sw2;

DerNotSealedClass notSealed = new DerNotSealedClass();
DerSealedClass Sealed = new DerSealedClass();

sw1 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
notSealed.Op0();
notSealed.Op1();
notSealed.Op2();
notSealed.Op3();
notSealed.Op4();
notSealed.Op5();
notSealed.Op6();
notSealed.Op7();
notSealed.Op8();
notSealed.Op9();
}
sw1.Stop();

sw2 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
Sealed.Op0();
Sealed.Op1();
Sealed.Op2();
Sealed.Op3();
Sealed.Op4();
Sealed.Op5();
Sealed.Op6();
Sealed.Op7();
Sealed.Op8();
Sealed.Op9();
}
sw2.Stop();
Console.WriteLine("Iterations: {0};", iterations);
Console.WriteLine("DerNotSealedClass: {0} ms;", sw1.Elapsed.Milliseconds);
Console.WriteLine("DerSealedClass: {0} ms;", sw2.Elapsed.Milliseconds);
}

static void Main(string[] args)
{
perfTest();
}
}
}
 

.NET ate my MOSK;. Powered By Blogger © 2009 Bombeli | Theme Design: ooruc