пятница, декабря 29, 2006

Русский бiзнесЪ, или Очарованный by Majors

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

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

  • У вас есть крыша. Это не те, кто будет отстреливать конкурентов и не допускать поджога ваших 30кв. м в хер-знает-где. Сейчас в нашей отрасли этим не занимаются (ну, так, колёса порежут, коробок спичек на сиденье кинут, но никакого насилия - все всё понимают с первого раза, как правило). Крыша будет вам нужна для оперативного решения вопросов. Например. Наступает новый, 2007й год, а ваш контрагент не проплатил, для определённости N000000 рублей. Что вы можете предпринять? Так как ваш контрагент - довольно крупная организация, название ей пусть будет Войти, то максимум того, что вы можете - это потрепать им нервы по телефону в бессильной злобе: "ну как же так! у нас же договор! это ведь исключительно благодаря нам вы вообще закрылись!". Васька слушает и Ваське похер эти сопли. Что в смысле научения жить правильно и вообще - caveat emptor. Но это неуважение. А его нельзя прощать. Поэтому крыша, до тех пор тихонько громыхавшая на других фронтах, ставится в известность относительно вопиющего случая с одной из ведущих IT-компаний. Суть мероприятия - в доведении до виновных информации об их неправоте. Вам не надо знать, как это будет делаться. Важно, чтобы это было сделано, а дебиторка превратилась в живые деньги. Если в вышеприведённой сумме число N достаточно мало, не стесняйтесь, скажите контрагенту, что нельзя долго прожить, если постоянно обманывать людей. При беседе с глазу на глаз вы сможете лично убедиться, что истории про изменение цвета хамелеона - это не сказка, а по телефону у вас получится насладиться жалобным блеянием: "как это понимать?" и "это что, угроза?" Не вдавайтесь в детали: "Швило, это доброе предостережение". Ваша задача - получить деньги, за которые ваши ребята как проклятые вкалывали последние X месяцев. А для выполнения этой, безусловно, благородной, задачи - все средства хороши.
  • У вас есть своя, пусть и небольшая, команда специалистов реагирования на эксцессы, которая умеет хорошо ориентироваться в городе, налаживать связи с консьержками и использовать источники типа "База данных ГИБДД", "БД Прописка" и пр. Очень помогает ускорить процесс выплат внезапный звонок какому-нибудь директору Войти домой с вопросом, хорошо ли ему спится. На утро вам перезвонят и все вопросы начнут решаться.

Может показаться, что это какой-то мелкоуголовный бред, который просто не может "иметь места". Но это не так. Если вы и правда считаете, что это так, не надо вам начинать своё дело. Прогорите к херамЪ.

Дальше.
  • Убедитесь, что вы умеете читать договора. Не поддавайтесь на уговоры, напирание на человеческие отношения. Помните. Речь идёт о деньгах, а в таком деле никаких друзей не может быть. Вы можете быть карасём, который ещё не понял, что его уже проглотили. Никогда не заключайте договора, в котором нет слов "выплата 30% аванса". Лучше всего - потренируйтесь нагло требовать своих законных 50%. А когда заматереете - настаивайте на безотзывных депозитарных аккредитивах. Тогда всё, что нужно сделать для получения денег - подписать акт сдачи-приёмки и предъявить его банку. Старайтесь держаться подальше от наличных, если это не абсолютно надёжные люди. Сегодня дядя - сам мёд, а завтра - ... не дай бох. Кругом чуть не сплошь негодяи.

Ну и пара советов. Я имею на это право.

  • Не входите в дружеские отношения с контрагентами. Ни-ког-да. Определитесь сразу, или вы делаете бизнес, или вместе ездите на рыбалку. Двум богам служить нельзя, а потому и дружбы не выйдет и бизнеса.
  • И наконец. Вы всегда правы. Всегда. С этой точки зрения и разговаривайте. Вас интересуют отношения только на паритетных условиях. 50 на 50. Если на вас давят массой своей конторы - нагло смейтесь в рожу: "ну так а чего вы нас зовёте?". Если предлагают поработать "чтобы заработать имя" - не забывайте, что на йух - это прямо и маленько направо. Если предлагают поработать "пока" забесплатно, но "потом - обязательно расплатятся" - разворачивайтесь и домой.

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

четверг, декабря 28, 2006

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

Всех с наступающим.

воскресенье, декабря 24, 2006

Кю

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

Бтвмть!

среда, декабря 20, 2006

Кое-какие выводы

Всё-таки миллион в договорах - это не то же самое, что миллион на счету. Как-то надо уже скорее собирать долги и нанимать человек 10 одарённых ребят, чтобы они вместо меня писали этакое вот:

public partial class QuotaPropertySheet: CAbstractPropertySheet
{
private Hashtable m_Quotas = new Hashtable();
private AutoCompleteStringCollection m_AutoCompleteList = new AutoCompleteStringCollection();

public QuotaPropertySheet()
{
InitializeComponent();
}

public override void Init()
{
ParameterlessDelegate pd = ReadList;
pd.BeginInvoke(delegate(IAsyncResult ar)
{
AsyncResult res = (AsyncResult)ar;
((ParameterlessDelegate)res.AsyncDelegate).EndInvoke(ar);
}, null);
}

public Hashtable Quotas
{
get
...



И это в то самое время, когда чёртова куча по-настоящему сложных задач висит над душой и похмыкивает: "ну что, тело, не успеваешь? ггг"

понедельник, декабря 18, 2006

воскресенье, декабря 17, 2006

Про "интернетизацию"

Я уверен, что если бы хотя бы в областных центрах по стране ситуация с интернетом была такая же, как в Москве, то проигравших не было бы.

В 2007м почти году подключаться по dial-up это нонсенс и дикий анахронизм. При отсутствии интернета совершенно меняется ритм и рисунок жизни - я это вижу в своих командировках. Скорость получения новостей, возможность почти мгновенно получить ответ на вопрос, позвонить за сущие копейки на другую сторону планеты, не вставая из-за компьютера и т.п - я стал к этому чувствителен. Поэтому тарифы типа таких я кроме как за издёвку ни за что иное принять не могу.

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

Расслоение среди нормальных людей 20-35ти лет в наше время проходит не по количеству денег на счету или в кармане, а по скорости доступа в интернет. И если эта скорость меньше, чем постоянный 256/128, то, полагаю, можно говорить о том, что человек живёт за чертой информационной бедности. Особенно учитывая ангажированность СМИ определёнными кругами отечественного политического вакуума.

пятница, декабря 15, 2006

Переводы

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

В Спольском:

  • Кермит - это у них протокол
  • по мнению тех. редактора перевода "Спольский впадает в крайности", причём эти комментарии прямо на полях книжки

У Коуплэнда в "Рабах Microsoft" (с какого, кстати, икса такой перевод названия Microserfs?)

  • Ксерокс "Парк"
  • Компьютер MS Works
  • Ада (защитный контрактный кодЪ)

На тему этого перевода хорошо прошёлся пару лет назад dixi.

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

В главе "Bad smells in Code" (Признаки плохого кода) из книги Refactoring, Мартин Ф. и Кент Б. представляют дополнительное руководство по определению проблем в проектах. Уподобляя проблемы проектов не очень приятным запахам, они объясняют... (и т.д.)

Наверное, вас уже насторожил новый вариант перевода термина "Вонючий код"? "А теперь - ракета": примечание переводчика на той же 67й странице

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

Круто! Нет слов. Переводчик решил, что мы (с какой стати этот мудак записал меня в одну с ним группу "мы"?) не будем. После этого мне довольно трудно дочитать эту книжку до конца.

Всё это наводит меня на мысли о том, что некомпетентность в области перевода в РФ приобретает признаки катастрофы. Не далее, как недавно увидел отрывок "Друзей", где Фиби сменила имя с Фиби Буфэ на Принцессу Мопед, после чего её муж, Майк, по всей видимости, обладающий бесконечным терпением, выбрал себе имя "Чан Дерьма" (Crap Tank), чтобы Фиби взяла своё имя обратно. И что же? Наши переводчики снова оказались на высоте. Майк, бедолага, и не знал, что его радикальный "Чан Дерьма"превратится в "Бак Мусора". Зачем эта самодеятельность? Почему каждый бездарь лезет "улучшать", когда его задача - с максимальной точностью перевести автора?

среда, декабря 13, 2006

Каждый день знакомлюсь и знакомят с новыми людьми. Почему-то все они очень неприятны.

понедельник, декабря 11, 2006

DeriveParameters для OleDbProvider. Часть II

По итогам краткого энергического совещания было принято решение: несмотря на всю подлость со стороны авторов Jet4.0 на провокации не поддаваться и привести инфраструктуру к виду, в которой вызов виртуального метода DeriveParameters в нашем драйвере для MS Access будет работать так же, как и для MS SQL Server, и для Oracle. Я, признаться, уже стал забывать ADOX, да и неудобно использовать его в .NET, медленно. Пораскинув, решение нашёл.

Решение заключается в использовании OleDbConnection.GetOleDbSchemaTable. Последовательно получая текст сохранённого запроса и выполняя отображение имён параметров на поля таблиц (а для Jet4.0 параметр OleDbSchemaGuid.Procedure_Parameters не поддерживается тоже), получаем типы и имена параметров. То есть, в точности то, что делает DeriveParameters для нормальных систем управления базами данных.

В итоге получается примерно так:

public override void DeriveParameters(IDbCommand Command)
{
using (OleDbConnection conn = new OleDbConnection(BaseSolutionProperties.ConnectionString))
{
conn.Open();
DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Procedures, new object[]{null, null, Command.CommandText});

if (dt.Rows.Count != 1)
throw new IndexOutOfRangeException(Command.CommandText);

DataRow row = dt.Rows[0];
Regex regex = new Regex(@"\[\@(?<param>[A-Za-z]+)\]");
string text = (string)row.ItemArray[4];

MatchCollection matches = regex.Matches(text);
if (matches.Count > 0)
{
Command.Parameters.Clear();

foreach (Match match in matches)
{
string paramName = match.Groups["param"].Value;
Triple<string, OleDbType, int> typeAndSize = GetParamInfo(row, paramName, conn);

OleDbParameter param;

if (typeAndSize.Third == 0)
param = new OleDbParameter(String.Format("[@{0}]", paramName), typeAndSize.Second);
else
param = new OleDbParameter(String.Format("[@{0}]", paramName), typeAndSize.Second, typeAndSize.Third);

Command.Parameters.Add(param);
}
}
}
}

...

private static Hashtable m_TableDefs = Hashtable.Synchronized(new Hashtable());
private static object m_HashSync = new object();

private static Triple<string, OleDbType, int> GetParamInfo(DataRow Row, string ParamName, OleDbConnection Conn)
{
string procName = (string)Row.ItemArray[2];
string tabName = null;
const string ins = "sp_Insert";

if (procName.Contains(ins))
tabName = procName.Substring(procName.LastIndexOf(ins) + ins.Length);
else
{
string upd = "sp_Update";
if (procName.Contains(upd))
tabName = procName.Substring(procName.LastIndexOf(upd) + upd.Length);
else
{
string del = "sp_Delete";
if (procName.Contains(del))
tabName = procName.Substring(procName.LastIndexOf(del) + del.Length);
}
}

if (String.IsNullOrEmpty(tabName))
return null;

List<Triple<string, OleDbType, int>> cache;
lock(m_HashSync)
if (m_TableDefs.Contains(tabName))
cache = (List<triple<string, OleDbType, int>>)m_TableDefs[tabName];
else
{
cache = new List<triple<string, OleDbType, int>>();
DataTable dt = Conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[]{null, null, tabName, null});

foreach (DataRow row in dt.Rows)
cache.Add(new Triple<string, OleDbType, int>((string)row["COLUMN_NAME"], (OleDbType)row["DATA_TYPE"],
Convert.ToInt32(
(row["character_maximum_length"] is DBNull ? 0 : row["character_maximum_length"]))));

m_TableDefs.Add(tabName, cache);
}

foreach (Triple<string, OleDbType, int> triple in cache)
{
if (triple.First == ParamName)
return triple;
}

return null;
}

воскресенье, декабря 10, 2006

Перегибы на местах

SqlCommandBuilder.DeriveParameters для SQL Server - работает, как надо.
OracleCommandBuilder.DeriveParameters для Oracle - тоже работает.
OleDbCommandBuilder.DeriveParameter для Jet4.0 - не работает! Причём с замечательным текстом исключения: "Retrieving procedure parameter information is not supported by the 'Microsoft.Jet.OLEDB.4.0' provider."


Нам требуется выпустить "карманную" однопользовательскую версию, которая использовала бы MDB. Написали драйвер, адаптер, всё есть. Кроме самой малости (см. выше).
Зачем им это надо было делать именно так? Что, трудно получить список параметров из сохранённых запросов Access? Или люди всерьёз опасаются, что кому-то так понравится Microsoft Access, что этот человек перестанет ориентироваться на SQL Server?


Несколько успокаивает только одно: в своей библиотеке работы на уровне, работающем с БД мы предусмотрели такую подлость и можно вручную указать параметры для команды. Но это нихера не для слабонервных занятие - почти 100 запросов вручную проинициализировать. Придётся воевать до утра, я так чую.

четверг, декабря 07, 2006

Сегодняшние обыски в IBM и их сателлитах

Я удовлетворён деятельностью МВД, начавшего разбираться с IBM, R-Style, Ланитом и прочими организациями. Пусть это происходит для того, чтобы иметь компромат на Грефа, Зурабова и прочих деятелей, пусть. Но это хотя бы начало происходить.

IBM, Oracle, SUN, масса более мелких "интеграторов" ведут свой "бизнес", полагаясь исключительно на волшебную силу подкупа чиновников. Именно так в госструктуры просачивается IBM Tivoli, Oracle 10 в диких, никак не связанных с потребностями государства, количествах, железо SUN для развёртывания "катастрофоустойчивых" (давно ли на Москву или там Хабаровск падал метеоритЪ?) решений.

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

На заметку прокурору: знаете такую организацию, "Восход"? От неё так неприлично много ниточек во все стороны ползёт, что даже удивительно, как это вы их не замечаете.

вторник, декабря 05, 2006

Профессионалы и любители

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


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

  1. Алгоритмы поиска и сортировки
  2. Опыт работы с графами
  3. Понимание внутренней структуры используемого хранилища
  4. Смысл и ограничение рекурсии

То есть, твёрдо оперировать в пределах хотя бы трети каждого тома Кнута.

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

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

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

Вот что я об этом думаю.

--
* - а если это происходит, то не мешало бы задуматься об объёме своих знаний

суббота, декабря 02, 2006

Запуск 1.1

Вчера днём мы наконец-то запустили то, над чем последние полтора месяца каждый день по 12-14 часов, в эксплуатацию. Версия 1.1а внутри мне нравится куда как больше, чем 1.0. Во-первых, сняты все ограничения на скорость работы с БД. Полоса пропускания почти точно совпадает с каналом, связывающим сервер БД с сервером приложения (ради этого пришлось выпустить 2 серьёзных обновления к нашей библиотеке ядра). Во-вторых, найдено простое и эффективное решение задачи ручной репликации в распределённой среде. Оно не потребовала никакого изменения логики процесса и это не может не радовать. Ещё много чего по мелочи.

Всё это вместе тянет на то, чтобы завтра выпить чего-нибудь этакого.

вторник, ноября 28, 2006

Читают, что ли?

Стоило написать, что Microsoft - бригада толстожопых уродов, как уважаемый человек оттуда позвонил и сказал, что они получили сертификаты ФСТЭК и ФСБ для Windows и Windows теперь - единственный заморский продукт, имеющий все необходимые сертификаты для использования в госсекторе.

понедельник, ноября 27, 2006

"Par avion"

За "принцип общей пользы" некто Дж. Нэш получил Нобелевскую премию в середине 90х. Про эту история был снят "Прекрасный разум". Это все знают. Но вот не все знают, что Нобелевские премии дают за вещи, которые имеют практический смысл. Лазер - расширение полосы пропускания канала передачи, открытие геликобактера - рак желудка, прецизионные инструменты - для соотв. измерений. Бывает, конечно, что смысл от неподготовленного человека ускользает, но если его видно, то видно. Как в случае с Нэшем. Кратко: "если каждый будет стремиться к пользе для себя и других, то выиграют все". Я это вот к чему.

В сентябре-октябре аэропорт Гумрак (Волгоград) начал войну с "Сибирью". Якобы та занимается демпингом и выживает базовую а/к "Волгаавиаэкспресс". Ну и волгоградские начали гадить: рейсы не выпускать, не принимать, отказываться заправлять и т.п. мелкую подлость. "Сибирь" всё с негодованием отмела и, как несравненно более тяжёлый сумоист, начала разбираться по-крупному. Итог: у аэропорта отняли лицензию на спец. свет. оборудование (самолёты можно принимать/выпускать только в светлое время суток), самолёты "Волгаавиаэкспресс" вообще не летают. Цены на билеты в Москву выросли с минимальных 2900 у Сибири до 3812 у Аэрофлота (туда-обратно). Вот что бывает, когда люди думают, что современная наука сама по себе, а человеки - сами по себе. Не-е-е-е-т!

Ну что, руководству Гумрака было трудно посмотреть "Игры разума" в русском переводе? Фильму, славтехосподи, 5 лет. Можно было бы уже приобщиться. Глядишь, и косяка такого не упороли бы. Да и летать было бы на 25% подешевле.

воскресенье, ноября 26, 2006

Умрёт ли Microsoft?

OS/2 сожрана при помощи Windows'95 и NT 4.0. IBM рассталась с грандиозными планами иметь собственную ОС и устанавливать правила. Это пошло ей на пользу.

Теперь - очередь Microsoft. Вне зависимости от того, сколько умных людей работают внутри этой организации и сколько прекрасных идей воплощаются вот в этот самый момент - этому монстру в том виде, в котором мы его знаем, приходит конец. Это будут безусловно мучительные и длительные судороги. Думаю, они ещё выпустят парочку версий Windows, не считая Vista, но это и всё. Почему? А вот примеры.

Звонят мне: вы хотите заняться распространением (distribution) нашего ПО?
- Да *а у нас в одной из коробок есть большой кусок, использующий Visio 2007*
- О! А вы уже обращались к нам?
- Да
- Каков результат?
- Ваши люди отправили нас в обычные каналы продаж.
- Хм... Я разберусь с этим вопросом и перезвоню
- *лениво* Буду ждать

Перезванивает уже месяц. Заснула, наверное. На такой напряжённой работе.

Ещё одни. Мы "совещались" (просто просиживали штаны и мычали ни о чём - они там не могли врубиться, чего нам надо) раза 3 или 4. Последний раз в середине июня. Скоро полгода, как ждём решения. Если бы я с такой скорость принимал решения, меня бы лишили всех гражданских прав, как полностью недееспособного. А тут - уважаемая, динамичная (хехехе) компания. От слова "динамить", наверное.

четверг, ноября 23, 2006

Открытия чудныя

Сегодня услышал прекрасное. "Если определить view так:

CREATE VIEW v_Abc
AS
SELECT Id, Data FROM Abc

то при вызове типа

SELECT * FROM v_Abc WHERE Id = XXX

не будет выполняться полное сканирование таблицы, а планировщик сам поймёт(!!!), что надо выполнить команду SELECT Id, Data FROM Abc WHERE Id = XXX
"

Вот, думаю, куда пойти. В монастырь или за патронами.

* Abc не имеет никаких индексов

вторник, ноября 21, 2006

Не умею отдыхать

На неделю ездил в город-герой Волгоград. Там пытался наладить процесс отдыха: рестораны, стенд, прогулки. Ничего не получилось. До среды удалённо дирижировал и так же удалённо завывал на тему выпуска пилота одного из проектов. В субботу прилетел обратно, проспал сутки и вот - первый день сразу 14 часов.

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

четверг, ноября 09, 2006

Про "гуру"

В одном из комментариев товарищ пейсатель меня подколол (как он думает), что, мол, если уж гуру-Fawler не рассматривает случай cо смертельными блокировками в транзакции, то куда уж практикующим программистам (что, очевидно, надо читать, как "ханурикам"). Меня всегда удивляла страсть людей найти себе идола и ходить за ним, ловя каждое слово. Когда-то я тоже был таким. Купил в 92м году чёрную книжку Буча, изданную в отвратительном переплёте, со странным переводом и отчаянно пытался понять, о чём базар. А летом 93го потратил полтора месяца на то, чтобы разобраться с борландовским Turbo Vision и это рассказало мне об объектном программировании много больше, чем все книжки всех бучей в мире, вместе взятые. Тогда мне показалось, что это случайность, но спустя несколько лет (может, 5, может, 7, я не помню) случилось разбираться с ПО компании Rational. Если вы читаете это, то не можете не знать, что это такое, как выглядит и как работает. А между тем, один из ведущих, если не главный у них был тогда Буч. Первая икона порублена. Дальше. В 93м же, Макконнелл издал свой дидактический труд Code Complete. Это хорошая книжка. Я читал оригинал, я читал перевод, могу сказать, что перевод ничего не потерял. А всякий, кто имеет глаза, может подтвердить, что CC2 (то, что вышло в прошлом году после моего ему письма, между прочим) - это полное собрание компьютерных банальностей. Просто их много и количество переросло в качество. Вот прямо сейчас открываю на произвольной странице этот кирпич, читаю (стр. 397):

чтобы переписать пример, используя подход с try-finally,
поместите код, который должен проверять возможные ошибки, в блок try,а код
очистки - в блок finally.
Гениально и непостижимо! Кто бы мог подумать, что finally именно для этого. Закрываю и открываю снова. Стр. 700
Управление версиями. Справиться с быстро растущим количеством версий ПО
позволяют инструменты управления версиями...
Ниже там же.

Компиляторы преобразуют исходный код в исполняемый

Всякий может это проверить, а кроме того (мне уже лень) - найти нечто подобное, открыв Макконнелловский опус на любой любимой странице. Тем более, что это так нетрудно. Как человек, изрекаюший такие банальности на протяжении 13 лет может считаться гуру? По-моему, никак. Хороший дидактический труд, для студентов, не серьёзней. Там нет ничего такого, до чего любой "практикующий программист" (с которого взять нечего, как мы все уже знаем) не дошёл бы сам через пару лет нормальной работы.

Дальше. Икона архитектурных астронавтов - Фоулер. Не поленюсь, открою и его. Увы, не открою. Книжка ушла в макулатуру. Ну, попробую по памяти. Раздел "корпоративные приложения":
вы можете реализовывать шаблоны так и эдак, но вам всё равно придётся их
реализовывать.
А кто в этом сомневался? Когда люди придумывают шаблоны ради того, чтобы попасть в неизвестную мне книгу рекордов, это вызывает смех и раздражение, если некий поклонник хочет научить кого-то. Доведение обычного вызова метода до метафоры некой абстрактной команды - это очень круто, но для меня - совершенно бесполезно. В точности так, как расписывать девиации в реализации фабрики классов. Я ваще-т не первый год в шоу-бизнесе, мне не надо втирать о модных подходах к инстанцированию (почему-то почти все доморощенные переводчики очень любят использовать этот "глагол"). Лучше покажите, что вы написали, где оно работает и насколько им довольны клиенты. Это единственный критерий. И другого нет. А все эти "Банды Четырёх" (из четырёх пузато-близоруких гангстеров) ---.

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

Люди, которые могут претендовать на техническое превосходство, глубоко законспирированы и чужды публичности. Как правило. Много ли вы слышали про Дэвида Катлера? А в его ОС вы сейчас читаете этот текст. Знакомы ли с мировоззрением и предпочтениями в шаблонах проектирования Алана Купера? Сомневаюсь. А этот человек сделал Visual Basic и всё, что это повлекло за собой. Вот это -люди. Но я что-то сомневаюсь в том, что у них есть какие-то поползновения на "поучить практикующих программистов". Потому что они сами программисты. В отличие от.

Дыбр

Битвы на стенде продолжаются.

Есть таблица A(Id bigint not null identity, Data varchar(max))

Есть процедура sp_Abyrvalg, содержащая строки:
INSERT INTO A(Data) VALUES('Some data')
DECLARE @x bigint
SET @x = SCOPE_IDENTITY()

Вдобавок к этому есть многопроцессорный сервер, на котором процедура sp_Abyrvalg выполняется одновременно сразу на двух процессорах.

Внимание, вопрос.
Если последнее значеие Id в A было X, то чему будут равны значения @x после выполнения вставки на первом и втором процессоре соответственно?

вторник, ноября 07, 2006

Как читать требования

Заказчик на объекте принимает работу у подрядчика. Тот подводит его к выкопанной шахте диаметром 3 метра и глубиной 50 метров, заглядывают туда, на дне горит прожектор.
Заказчик - что за херня???
Подрядчик - вот же чертеж!! по нему и сделали.
Заказчик -



(переворачивая чертеж на 180 градусов) - это маяк!!!

Что ни говори, а требования надо уметь читать.
"Обеспечить формирование произвольных отчётов" - это что значит? Произвольных из списка? Или надо дать возможность конструировать отчёты самостоятельно?
"Работать под управлением любых современных операционных систем". Включая QNX, MorphOS и AmigaOS?
"Не содержать интерпретируемого кода". Компиляция из MSIL в native код во время выполнения считается в вашем клубе за интерпретацию или только reflection? А если я внутри кода сам компилирую вызовы getters и setters, чтобы не связываться с reflection - это тоже интрепретация? Как нет? Я же получаю имена с помощью

GetType().GetProperties()[0].PropertyType
И таких нюансов каждый может придумать с десяток за минуту. Как же быть, чтобы не построить маяк?

Мы перепробовали много методик. В том числе и заказчик on-site, как это практикуется в XP. Трудно сказать, каков должен быть идеальный путь выяснения настоящего смысла требований, но я могу рассказать про тот, который работает у нас.

  1. Как это ни смешно, но требования надо получить в письменном виде с расстановкой приоритетов.
  2. Взять таймаут на составление вопросов по требованиям. В зависимости от проекта это может занять как 1, так и 14 дней (говорю о типичных величинах для обычных проектов; если вам заказали написание сервера баз данных или компилятор для операционки новейшего автономного пылесоса с функцией барокамерного холодильника - я пас). Все вопросы, от серьёзных (полное непонимание), до ерундовых (почти всё понятно - и это самое опасное) тщательно запротоколировать.
  3. С блокнотом вопросов, диктофоном, ангельским терпением и колодой визиток выдвинуться в расположение заказчика, заранее предупредив его о том, что есть вопросы. В наши цели не входит беседовать с парнем, который только второй день работает или которого пригнали отдуваться из-за того что он не успел спрятаться.
  4. Объясните, чего вы хотите и непременно убедитесь, что сидящий напротив понимает, о чём идёт речь. А то будет как с полотёром Басова в "Шагаю по Москве". Это сильно портит настроение и плюс к тому это зря потраченное время: придётся то же самое спрашивать повторно.
  5. Делайте, что хотите, но обязательно расположите к себе собеседника. Учтите, что в то время, пока вы выполняете одну работу, интервьюируете, он - две. Отвечает вам и по-прежнему обязан делать то, за что ему платят в организации деньги: заниматься основными средствам, ругаться по поводу капитального ремонта труб или обеспечивать выборы своего директора в местную думу. Нам везло и особых сложностей не возникало - достаточно было за сутки узнать номер телефона выделенного человека, чтобы фазу знакомства сделать менее жёсткой.
  6. Задайте кумулятивный вопрос ("для чего вам нужна эта программа?")и слушайте, включив диктофон. Не перебивайте. Некоторые люди обладают настоящим даром - объяснить сложнейший процесс, такой, как остановка и запуск котельной, своими словами так, что всё поймёт и ребёнок.
  7. Уйдите на перерыв.
  8. Вцепитесь в человека, обрушив на него все вопросы, которые только у вас есть.
  9. Повторяйте пункт 8, пока вопросов больше не останется. Если это длится больше пары дней - дело нечисто. Или требования не соответствуют тому, что нужно сделать, или вы не в состоянии понять, чего от вас хотят. Первое - очень плохо. Второе - ужасно. Попросите в таком случае себя заменить.
  10. Ответы у вас есть, можно согласовывать план реализации требований

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

И ради бога, помните про маяк!

Расползание классов

Однажды на протяжении почти двух лет я участвовал в превращении симпатичного и аккуратного кода в бесформенный ужас. Происходило это медленно и потому незаметно. Только когда код готовился к передаче заказчику (женщина по имени Amber не захотела поднимать ставку), я осознал. COM-компонент с функциональностью однопроходного разбора PST-файла. Несколько потоков для обеспечения асинхронной работы подсистемы уведомлений, элегантные вызовы функций чтения данных из PST (100% reverse engineering, выполненный одним насколько умным, настолько же и странным парнем из Волжского, Волг. обл). При передаче я обнаружил, что этот же самый класс с некогда весьма высокоуровневой функциональностью содержал:

  1. Методы работы со строками
  2. Методы выбора временного имени
  3. Постоянно расширяемый if, в котором определялись имена папок-исключений
  4. Методы формирования сообщений в формате eml

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

Сейчас я больше всего боюсь именно этого эффекта в коде. Если класс начинает расширяться не свойственной ему функциональностью, я начинаю заметно нервничать. Вот только что закончил ревизию пары классов базовой библиотеки, которые ни с того, ни с сего обогатились новыми свойствами и специальной обработкой в методе set свойства, которые используются в одном единственном месте в другом (!!) проекте. Бывает, что устаёшь, пишешь абы как, расставляя комментарии и предупреждения для исправления безобразия завтра же. Я считаю, что это нормально: концепция подтверждена, можно подчистить. Но когда явно временная затычка, появившаяся в результате лени, начинает жить - код начинает умирать.

Почему об этом стоит думать? В самом деле, не один ли хрен, что там внутри, если оно работает. Это я слышал много раз на разные лады, вплоть до "пусть пока побудет так, в следующей версии поправим". Если слышите такое - не стесняйте себя в выражениях. Лучше один раз поругаться, чем потом неделями сталкиваться с последствиями неисправленной кривизны (если есть один архитектурный косяк, то непременно будут и другие, можно не сомневаться). Я считаю, что быстрое превращение структуры класса в тесто является очень плохим признаком, обнаружив который, надо бить во все колокола.

понедельник, ноября 06, 2006

Какие программисты нам нужны

С годами я заметил, как стал менее нетерпимым к компьютерным болванам. То есть, я по-прежнему отмечают их наличие, но сейчас я склонен их жалеть, а не издеваться. Ну, не дано человеку, тут ничего не поделаешь. Я даже благодарен им за то, что они чётко осознают, что им это не дано и не лезут занимать чужие места (одно время это было очень популярно - я помню "ускоренные курсы подготовки программистов на C++"). Мне пришлось поработать в коллективе, состоящем из практикующего буддиста-битломана, паренька, который любой работе предпочитал разговор о своих галстуках (он был любитель джаза и коллекционировал галстуки диких расцветок) и пары приходящих энтузиастов, которые любили играть в Wolfenstein и не очень любили работать (это было очень давно в одном институте, где я только набирался ума). С тех пор я всегда старался осмотреться перед тем, как сунуть голову в петлю. Сейчас у меня есть возможность самому принимать людей. Я не в восторге от этой обязанности. Во-первых, потому, что это отнимает много времени. Оказывается, очень трудно найти даже час на то, чтобы поговорить с человеком по телефону. Во-вторых, потому что очень трудно выслушивать одни и те же глупости и не подать виду, как это раздражает; некоторые просто не понимают, когда им говоришь, что собеседование окончено - продолжают угадывать, что же я могу захотеть услышать?... В-третьих, начав собеседовать, я внезапно увидел, как мало людей подходят. Я знал, что трудно найти нужного человека, но что настолько! Про указатели я говорил уже как-то... Ощущение, что разговариваешь со стеной. Ну и в-четвёртых, - у ряда товарищей получается, как в фильме "Высота": "Потребности у тебя большие, а способностей совсем нет". Когда человек начинает разговор с денег - это не наш человек, потому что они или ничего не умеет, или очень мало, или точно не то.

Отталкиваясь от того, кто нам не нужен, я могу сказать, кто нам нужен. Пол и возраст значения не имеют.

  1. Человек должен что-то знать достаточно глубоко для того, чтобы во время интервью у меня закончились вопросы по этой теме раньше, чем у него закончатся ответы
  2. Он должен уметь программировать на С.
  3. Он должен уметь объяснить, как работает процессор в деталях, которые я захочу услышать
  4. Этот человек в своей жизни должен написать хотя бы один многопоточный компонент COM
  5. У него должен быть ответ на вопрос, почему, несмотря на компиляцию во время выполнения, Java и C# постоянно увеличивают свою долю рынка.

Вот если всё это будет продемонстрировано, то можно будет побеседовать и по существу вопроса, то есть, о работе.

пятница, ноября 03, 2006

Пара слов об экономике

Первый раз я создал организацию без малого 10 лет назад. Мы успели проработать около двух лет, правда бурно и с успехом: о нас писал и тогдашний PC Week, и отраслевая пресса. Но если занимаешься чем-то одним и не занимаешься другим - накрывается сразу всё. "Главный по тарелочкам" ушёл в структуры Газпрома, а мне одному было не вытянуть и новый web-проект (96й год, напоминаю!) и presale. В итоге, ввиду отсутствия наличия пришлось демонтировать вывеску. Сейчас, кажется, я могу поставить точный диагноз. А поскольку таких, как я - сотни и тысячи, и кто-то, возможно, прямо сейчас марширует под откос, то считаю своим долгом изложить.

Все организации умирают от одного и того же: недостаток средств. Можно писать фантастически эффективный код для задач управления производством и не получать от этого дополнительного притока денег. Можно писать кривой по меркам индустрии код для консалтинговых проектов и сносно при этом существовать. Проблема заключается в том, что редко кто правильно с самого начала выбирает уровень качества. Качество - это другое название для того, что называется трудозатратами. В 97м году мы написали ПО для создания виртуальных институтов. Использовали для этого VC++ 97 (ActiveX для страниц), VB5 (управление) и ASP. Сделано было хорошо. Всё заработало через 4 месяца после начала работы и заработало неплохо. Мы знали, что то, что делается - будет востребовано. Должно быть востребовано. Но - нет. Было сделано всего лишь несколько продаж. В академию СБ РФ, в пару институтов. Эти деньги не покрыли ничего. Мы, кажется, отпразновали первую продажу пиццей с пивом и это всё, ради чего 4 месяца работали, как проклятые. Наша беда тогда была в том, что, понадеявшись на глупую теорию "хороший товар продаёт себя сам", мы вообще не уделяли никакого внимания предпродажной работе. В самом деле. Если мы пишем отличный продукт, который мало кто может сделать - зачем нам все эти глупости толстожопых монстров: реклама там какая-то, переговоры. Да как только они услышат - нас завалят заказами! Но как они услышат?! Мы, кучка полусумасшедших молодых ребят, верили, что технология и качество решают все проблемы. Прошло 10 лет и я понимаю, что это не так.

Как-то сам не заметил, что увлёкся стендовой стрельбой. Пока что полное отсутствие времени мешает заняться этим серьёзно, но когда-нибудь... В начале мая, когда я пошёл на стенд первый раз, у меня случился запоминающийся разговор с инструктором.
- Саша, скажи, а вот прямо сразу надо покупать спортивное ружьё, экипировку?..
- Да ну, ты чё.
- Я просто смотрю - тут люди со специализированными вёслами ходят.
- Вот смотри. У тебя нормальный аппарат. На охоте - самое оно. И тут, чтобы понять смысл этих мероприятий - тоже вполне ничего. С ним ты сможешь стать КМС. А вот когда ты им станешь и твоими соперниками на соревнованиях будут одни и те же 10 человек, я имею в виду - на всех соревнованиях приличного уровня, вот тут тебе потребуется уже скачок в качестве инструмента. Он много не даст. 1-2 дополнительных попадания в серии. Но это та разница, которая отделяет 4е место от 1го. Понял?
- Вполне

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

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

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

Бета

Похоже, что в течение недели выйдет бета и я со спокойной совестью скатнусь на недельку в отпуск. Осталось:
2 инцидента 2го приоритета
3 - третьего
7 - четвёртого
3 - пятого

Общим временем исправления 33.5 часов

вторник, октября 31, 2006

О самонадеянности

Мне просто нравятся загрузочные экраны Windows. Всё взято с http://www.guidebookgallery.org/screenshots/splash. Версия 1.0 у меня была. Я запустил её на компьютере с 386м процессором. Она поработала секунд 10 и сдохла с неясной диагностикойПишешь что-нибудь на пару раз попользоваться, оно разрастается, начинает использоваться людьми и теряешь возможность внести какие-то исправления, потому что, оказывается, на базе этого уже построили свою функциональность. Но это ещё не самое плохое. Владелец кода in-house разработки может сказать: всё, меня пробило на улучшения: всё поноют, но сделать ничего не смогут. Главное - не смогут помешать изменять. И, в зависимости от количества дипломатических оборотов, которые хочет и может потратить программист, замена лучшего на более лучшее (слышал я такой оборот как-то от барана неместного) пройдёт более или менее безболезненно.

2.0 у меня не было, врать не буду.Но если программа (пусть это даже и целая система) писалась в сумерках разума (не важно, по какой причине) и эта программа ушла в production!.. Чтобы умилостивить богов, 90% участников проекта просто обязано застрелиться на рабочих местах (в оригинале - в кабинетах). В самом деле. Допустим, что есть некая вполне тонкая библиотека, абстрагирующая пользователя от того, как выполняется работа с базой данных. Она берёт на себя управление транзакциями, соединениями и прочее всякое. Работает. При тестировании работает just fine. Все вызовы абстрактного сервера данных надёжно защищены критическими секциями, железобетонная корректность открытия и закрытия транзакций также не вызывает никаких сомнений. Работает. Казалось бы.

А теперь посмотрим.

public virtual object SelectScalar()
{
lock(m_CommitSync)
{
int threadId = ThreadId.Value;
object result = null;
try
{
GenericConnection.Open(SQLDataAdapter, threadId);
result = SQLDataAdapter.SelectCommand.ExecuteScalar();
}
catch (Exception ex)
{
DumpException(ex, SQLDataAdapter.SelectCommand.CommandText);
}
finally
{
GenericConnection.Close(threadId);
}

return result;
}
}

А вот с 3.0 я натешился. Нестабильность, в которую я сейчас даже не верю, явно обозначенная прожорливость, но при этом - работает! Первая моя программа для Windows была написана и собрана на 3.0То есть, шансов нарушить выполнение нет (см. lock в начале метода). + соединение всегда закроется, это с гарантией. Всё, в общем, работает отлично. Но заметили: если выпустить программу в дикую природу, то начинаются проблемы c deadlocks, "timeout expired prior to completion" и т.д. Библиотеку протестировали вдоль и поперёк. Трудно придумать, какой тест я не написал, чтобы удостовериться, что всё ok. Но оно не работает.

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

  1. Процессор
  2. SQL Server
  3. Данные

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

  1. Неправдоподобно длинные методы для Insert, Update, Delete
  2. Для чего-то производятся постоянные выборки всех записей (ок. 600000) из одной популярной таблицы

Да, и ещё ThreadId.Value возвращало Thread.CurrentThread.ManagedThreadId;

Почти день я прозанимался этой проблемой, свалившейся на меня (всё время всё сваливается на меня) из FB (приоритет 1, конечно). Что я могу на её счёт сказать? Раз уж сегодня всё пронумеровано, то вот:

  1. Длинные методы писались без понимания того, как это будет работать. Всё-таки один клоун Вася (Петя, Коля, Вова и пр.), запуганный своим кодом до того, что боится даже лишний раз нажать на кнопку в готовой (по его мнению) программе - это одно, а толпа тёток, которые без прелюдий ошибаются (кто бы мог подумать) и закрывают окна, когда они начинают скрывать их пасьянс (не говоря уж о том, что им просто обязательно провести собственный обезьяний тест) - это нечто радикально другое. Когда тётки наваливаются на несчастную чахлую тушку программы и начинают её накрячивать вдесятером - тут и выясняется, что у программиста ваще не было представлений о том, что он пишет, для чего и кто использует.
  2. Излишняя, преступная и вредительская самонадеянность ("такого никогда не может случиться"). Тут и расшифровывать даже не хочу.

Код нельзя просто написать, скомпилировать и дальше неделю пить пиво и пялиться по выходным в телек на новую серию "The Sopranos". Это так примитивно, что неловко даже писать: код должен развиваться. Его надо пересматривать. Он не должен отражать ваше понимание проблемы двухмесячной или двухгодовой давности. Для историй у нас есть SourceOffSite, а для ностальгических соплепусканий ("ах, как всё было просто много лет тому назад"- хрена с два! просто никогда не было!) - http://www.guidebookgallery.org/screenshots/

суббота, октября 28, 2006

Снова про ошибки

Мне нравится, как исчезают ошибки из FogBUGZ. Сначала на мне их было 20 (и это только в одном проекте), сейчас их 3. И к понедельнику их будет 0. Некоторые исправлять очень трудно, но после исправления появляется труднопередаваемое ощущение, что что-то стало лучше. Я успел поработать во многих организациях, некоторые из них были сертифицированы по ISO9000 и CMMI 4 и нигде, ни в одной я не видел методического, систематического или какого угодно ещё подхода к исправлению ошибок. Даже к исправлению ошибок. Организация с сертификатом ISO9000 занималась бесконечными совещаниями на тему что лучше: .NET или J2EE (при этом я работал в команде, которая писала огромный кусок системы на C++, использовала DCOM и MSSQL2000 - куда тут засунуть J2EE?). Контора с CMMI 4 не имела ни одной спецификации, на которую новый человек мог бы посмотреть, чтобы понять, что от него ждут. В этой же организации мне пришлось принимать уже заваленный проект, который сдох потому, что у менеджера и "руководителя департамента" не было никакого образования: 1 курс литинститута, 1 курс меда, профессиональный опыт: 1 (одна!) база данных для сайта (можно себе представить, что это было такое) и сколько-то там форм на php (до сих пор не жалею, что не знаю, что это такое). В итоге $60,000 мы заработали, но ещё 20 тысяч долларов пришлось подарить, поскольку команда (на 90% состоящая из студентов) никак уже не могла решить проблем, которые на неё наваливались.

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

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

Группа разработчиков бортового ПО для космических кораблей "Shuttle"... Там нет гор коробок из-под пиццы, пирамид банок из-под кока-колы, отвесных стен для альпинистов, площадок для катания на роликовых досках или подобных элементов пейзажа "продвинутых" организаций-разработчиков ПО. Там не в игрушки играют, а стремятся создавать безукоризненное ПО
Иногда любители качественно отдохнуть в рабочее время настаивают на том, что всё должно быть весело и "клёво". Мне почему-то кажется, что они отдыхают и раскайфовываются в рабочее время по единственной причине: работа завалена и никакого просвета в ней не видно; как ни вкалывай, только дети и получаются хорошими. Ну, в таком случае у ребят и правда нет выбора, кроме как отдыхать.

среда, октября 25, 2006

Анонс

Пока одним "не хватает времени" просто для того, чтобы работать и делать то дело, за которое они получают деньги, другие готовят цикл статей по безопасности (включая криптографию) в .NET, новым, проверенным на себе, возможностям ASP.NET и .NET 2.0 как такового.

понедельник, октября 23, 2006

SMO

Предыдущую блестящую, конгениальную и отточенную версию этого поста сожрал не то сам гугл, в лице своего агента blogger.com, не то microsoft посредством http404 в ie, а так как мне не достичь повторно такого просветления, то скажу просто, в одно предложение.

С DMO работать в .NET 2.0 невозможно, SMO не умеет правильно расставлять GO при скриптовании ограничений и ключей, а наша программа для записи живой копии БД (в виде 3х скриптов .sql) для включения в состав дистрибутива - чихать на это хотела и прекрасно работает.

суббота, октября 21, 2006

Мне не хватает указателей


Больше трёх лет я не работаю с указателями. И мне их не хватает. Java, C# и прочее - хорошие языки, но это не то, что требуется для получения удовольствия. Ну, какое удовольствие, в самом деле, от того, что не нужно писать delete или delete[]? А если при этом учесть, что сильные ссылки от событий надо разрывать вручную, через -=, то и вовсе задумаешься - для чего.
Мне нравилось писать многопоточные COMпоненты в ATL, выделять и забирать память. Мне нравилось то, что я знаю, для чего нужно выравнивание по границе, что компилятор создавал очень быстрый код по моим текстам и то, что указателями я был надёжно ограждён от проффесоров, которые не в курсе, что такое TLS, EAX и DMA.

пятница, октября 20, 2006

Отступники

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

Написана и давно работает библиотека, позволяющая рассматривать хранилище данных, например, базу MS SQL Server или Oracle, или набор XML-файлов, как совокупность объектов со связями. Это удобно, просто и понятно. Все обычно понимают суть спустя минут 5 после начала объяснения. Ну, к тому же мы написали генератор кода по определениям, как это сделали в своё время ребята из ThoughtWorks для библиотеки QuickFIX - для создания 5 классов, 3х процедур, одного view и таблицы требуется написать xml с описанием объекта и сгенерировать нужное. Итого - примерно минута or so. В общем, плодим сущности при всяком признаке надобности быстро и весело. И нам за это почти ничего не бывает, если только мы не отступаем от генеральной линии использования. Но некоторые случаи, такие, как тот, на исправление которого ушло 30 часов вместо 1го запланированного, вызывают у меня депрессию. Смотрите.

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

Отложенная загрузка выполняется так:


public Channel AssociatedChannel
{
get
{
if (m_Channel == null)
{
if (!IsNew)
{
IAdvancedRelationMining m = new RelationEngine();
m_Channel = m.GetOwners(this, null).First;
}
else
m_Channel = new Channel();
}
return m_Channel;
}
set
{
m_Channel = value;
MakeDirty();
NotifyPropertyChanged("AssociatedChannel");
}
}


То есть, при получении свойства надо удостовериться в том, что 2 условия выполняются:
1. Получаемое поле - null, т.е., к нему ещё не обращались
2. Объект, содержащий поле - не новый (он у нас новый, если его Id < 0)

Если нарушить вышеприведённые правила, например, позволить объекту-контейнеру деградировать с инверсией Id, то получить то же самое значение свойства, которое было у этого объекта с ешё не инвертированным Id - не получится: поведение становится недетерминистическим, как GETDATE() в T-SQL или сумма на чеке, который я приношу из магазина. Последствия отступления от правил:
1. Из отведённого на поиск и исправление ошибки 1(одного) часа потрачено 30 (тридцать)
2. Проблема заключалась в инверсии, применявшейся к объекту, у которого ещё не вызывалось это свойство, и соответствующее поле объекта было равно null.

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

среда, октября 18, 2006

"Разработка через тестирование"?

Александр зимой презентовал мне "Разработку через тестирование". Хорошая, с чувством написанная, я перечитал её пару раз, наверное. Ну и так, акцидентально, обращаюсь. Уже несколько лет мы стараемся применять тесты для получения дополнительных гарантий качества кода и иногда это неплохо получается. Всё, что может помочь упростить код или уменьшить его количество - применяется. Тесты не исключение. Но поскольку много лет назад, как и многие другие, я прочитал Мифический человеко-месяц, а после него - "... Серебряную пулю", то верить в то, что тесты - это то самое я не мог. И не зря. На днях была выпущена большая новая версия: много нового кода, много исправлений, в том числе и базы данных. Перед выпуском всё проверялось и неоднократно. Код проверялся тестами, интерфейс - протыкиванием, обновления базы данных - нашими утилитами обновления рабочих баз. После сборки msi мы проверили и его(её?). Версия под панфары была отправлена по адресу.

Утро следующего дня началось с письма:

После загрузки последного обновления вся моя работа пропала. Что делать?
Как она могла пропасть, если мы всё проверяли?! Правда, пользователь попался умный и не вредный - дал нашему автоматическому отчёту о сбое отправить состояние стека. 5 минут изучения, проверка обновления БД и вот: отсутствие обратной совместимости в очередном исправлении БД. У нас оно работало потому что база заполнялась-стиралась-заполнялась. Перед применением исправления она всякий раз оказывалась пустой и после того, как patcher её обновлял - программа работала как ни в чём не бывало. А у пользователя там были данные. Всё тоже обновилось, без ошибок, правильно. И умерло.

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

понедельник, октября 16, 2006

Об асинхронности в asp.net 2.0

Чуть больше года назад мы выпустили первую версию нашего продукта для сектора госуправления. По итогам опытной эксплуатации была добавлена функция, позволившая сэкономить пользователями сотни и даже, может быть, тысячи часов рабочего времени. Некоторые страницы содержали (и продолжают содержать) списки, состоящие из тысяч записей, с тенденцией к постоянному расширению. Загрузить такой список через web и тем более - найти в нём что-то это задача для людей, которые уже сделали все распоряжения на случай своего самовозгорания на работе. Мне лично трудно возиться со списком, в котором есть хотя бы 20 элементов, а если больше, то эту и такую программу я стараюсь больше не открывать. Очевидно, что наши пользователи не более терпеливы, чем я. Поэтому было решено пойти по пути гугла, а ещё раньше - программы, разработанной неизвестными героями в дебрях ФНС, которая подсказывала варианты по мере набора пользователем слова. Набрал пользователь "у", ему предложили в качестве варианта страны: "УГАНДА, УКРАИНА...". В списке, реализованном как div поверх текста, пользователь стрелками или мышью выбирает то, что ему нужно. Хорошо, удобно, быстро. Отвечал за эту часть общей работы я и сделал так:
1. В HTML указал, что буду использовать webservice.htc
2. Написал свой htc, в котором определил клиентский HTML-элемент управления, который умеет цепляться к строке ввода, получать оттуда данные, отправлять их веб-сервису, получать от него отклик и выводить в таком типа списке элементов с подсветкой.
3. Само собой, надо написать WS
Проверили, всем понравилось.

Ситуация с развёртыванием этой инсталляции была неидеальной, высокая текучесть администраторских кадров на объекте внедрения, общая суматоха, в общем, в результате многочисленных несанкционированных изменений конфигурационного файла веб-сервис стал работать через раз. Мы, поддавшись на обещания одной компании, решили использовать механизм асинхронных вызовов из ASP.NET 2.0 В самом деле, если это такой революционный, радикальный и драматический прорыв, то почему бы не воспользоваться.

Надо сказать, что в эту болтовню я с некоторых пор не верю - очень мало есть компаний, если они вообще есть, в которых маркетологи и рекламисты понимают, что делают технические люди
Целью, которую мы преследуем, является исключение веб-сервиса из списка компонентов, так как в каждой точке расширения какой-нибудь гений администрирования всё сделает и настроит обязательно не так; функциональность WS передаётся обратно в ASPX. Переделка на самом деле проста.
1. В списке наследования страницы указывается ICallbackEventHandler
2. Реализуются 2 его метода, public void RaiseCallbackEvent(string eventArgument) и public string GetCallbackResult()
3. В первом методе выполняется разбор строки, сформированной в браузере, во втором браузеру асинхронно отдаётся ответ.

Сделать это было всё несложно и вообше - дело пяти минут, я дольше вспоминал, как получить поля из web-формы c использованием JavaScript: работа велась автоматически и бессознательно. Когда всё было сделано, я осмотрелся и память услужливо предложила свой вариант увиденного: 1998й год, лето. Я пишу на asp маленькую задачу с получением результата поиска билетов без перерисовки страницы у клиента. RSExecute, RSEnableRemoteScripting и прочее, кто понимает. Прошло 8 лет, даже 8 с половиной и ничего не изменилось, всё то же самое. Клиентские скрипты, серверные скрипты, один шлёт, другой слушает... Где радикальная новь?

Поэтому приходится признать, что в плане асинхронности 2.0 предлагает не больше, чем ASP 9 лет назад. Это не хорошо, и не плохо. Это - правда.

суббота, октября 14, 2006

Категории ПО

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

Он говорит, что невыгодно тратить время на доводку программы (назову это для простоты так) с одной инсталляцией, что это дорого. Жизнь смеётся над любой выдумкой и такие обобщения вызывают у меня сомнения. И вот почему.

У нас в работе находится несколько проектов. Часть из них (если быть точным, то 3)- коробочные. Два - то, что он называет корпоративным или то, что я называю - одной инсталляции. Для определённости посчитаю прибыль в спичках, учитывая, что в коробке примерно их 40 штук. Первые мы продаём (все суммы условные, отражающие только порядки) или будем продавать по цене от половины (гравицапа поспички стоит!) до трёх спичек. Вторые меньше, чем за три коробка мы продавать не намерены. При этом, несмотря на исследование рынка, которое проводилось перед началом работ над приложениями из первой группы, мы можем с равной вероятностью продать 10 и 1000 копий. Вторые мы уже продали. 40 спичек * 3 * 2 = 240 спичек. Значит, для того, чтобы получить столько же, сколько мы получили от двух инсталляций в организациях, нужно в среднем продать 240 коробок с программами первой группы. Стоит ли ради этого привести эти 2 инсталляции в состояние, сравнимое по качеству и удобству с коробочным ПО? Ведь над коробочными решениями мы стараемся, как в последнем бою, даже не зная ещё, сколько продадим. Спольский говорит, что это не выгодно, так как это не отобьётся. Возможно, что в Америке это так. Программисты по 100 тысяч в год, дикое по сравнению с нашим налогообложение и пр. Но у нас - я могу спорить на деньги - отдавать качественное ПО даже в случае единичных инсталляций --это выгодно.

Пробиться на рынок корпоративных продаж архисложно. Уж не сравнить, во всяком случае, с типичным путём зарабатывания денег на shareware:
а) Выложить на shareware.ru свою программу
б) ждать поступления денег на счёт.
Деньги могут повалить тоннами, если ты угадал или не поступить на счёт никогда, если программа оказалась не нужна никому или проигрывает по набору функций уже имеющемуся. Но, скорее всего, сумма будет невелика в любом случае. Потому что во-первых, $19.99, а во-вторых - Асталависта (и это просто удивительно, насколько плохо программисты защищают свою прибыль). Да, я отвлёкся. Пробиться на корпоративный рынок трудно, но если пробился, то можно существенно увеличить норму прибыли, с обычных 20-30 до сотен процентов. Я помню, как в одном проекте, ещё когда я работал не в нынешней своей компании, за баннер одна американская корпорация заплатила $500. За один единственный баннер. И этих баннеров были десятки. Такой же баннер для малобюджетного сайта Клуба любителей вислоухих кроликов обойдётся дай бог чтоб хотя бы в $5 и то, на условиях его бесплатной переделки по требованию пользователей любое количество раз в течение полугода. Выгодно ли делать в условиях финансового дождя негодное по качеству ПО? Ведь обе стороны понимают, что то, что предлагается, просто не стоит своих денег. Другой вопрос, конечно, откуда берутся такие суммы. Но я никогда не заседал в советах директоров и совершенно без понятия, почему на крупных заводах нет бесплатных автобусов для рабочих, обед стоит для них денег, а $600000 за базу данных из двадцати таблиц и Java-интерфейс для редактирования некоторых полей - не считается безумной тратой огромных денег. Может ли быть в таких условиях невыгодным шлифовать этот интерфейс до идеального состояния? Каковы могут быть причины этого? Я считаю, что не может. Как и причин для этого. Потому что получая большие деньги и не давая пользователю ощущения качества, надёжности и стабильности продавец роет себе яму и вкапывает в её дно острые колья. О том, что паршивое нестабильное и подверженное сбоям ПО - признак некомпетентности и важный знак необходимости ухода с рынка - я уж и не говорю.

понедельник, сентября 25, 2006

Я нашёл ролик от Windows 98

У меня это \CDSAMPLE\VIDEOS\INTRO.AVi

Лучшие 58 секунд рекламы, которые я видел в своей жизни

Добрые люди через год с небольшим прислали ссылку на yourtube

воскресенье, сентября 03, 2006

Отклонения в поведении

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

В России в целом неоткуда взяться культуре geeks, так как героями нашего времени последовательно были:
Чапаев, Стаханов, Чкалов, Жуков, Гагарин, Сахаров и Ельцин

а не

Термен, Поликарпов, Марчук, Булычёв, Басов и Гинзбург.

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

Заебали фальшивые девианты. Они как-будто кругом.

воскресенье, августа 20, 2006

Связывание 1:*

Возникла интересная задача связывания объектов БД общей таблицей связей. Стыдно сказать, но количество таких просветлений в уму, какое случилось при написании этого кода, я могу у себя пересчитать по пальцам. А получилась просто конхветка.

суббота, августа 12, 2006

Чёрт его знает...

... но мне кажется, что мы всё-таки прорвёмся. Должны. И выбора нет.

понедельник, июля 24, 2006

Прощай, OvisLink

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

4 часа времени потеряно и это ещё не конец, я так чую.

Сейчас переключился на встроенный 11b. Для терминала хватит.
А погань эту я приговорил к ликвидации и привёл приговор в исполнение, как видно из.

пятница, июля 21, 2006

ЕГАИС

Тема хорошего алкоголя мне не чужая. Я курю, пью (мало, но тем не менее) и хотел бы заниматься этим и дальше. Но не получается. Потому что EГАИС.

Смотрю я на этот несчастный Атлас при ФСБ и думаю: какие вы ушлёпки, ребята. Думали, что всю жизнь можете осваивать бюджеты, не выдавая на гора ни единой полезной строчки кода (это у них обычное дело; такого количества напыщенных баранов и лохов, как во всяких силовых информационных центрах я не видел нигде. Называя вещи своими именами - это воры. Не все ("лосёнок маленький, на всех не хватит"), но ощутимо). Но вот не свезло. Пришёл день М, когда всех берут за худенькие ягодицы и заставляют сдавать работу. А работы-то и нет. Почему? Да потому что наше прекрасное гойсударство только тем и занимается, что крадёт само у себя.

Вот лежит у меня сейчас перед носом смета на 670 миллионов рублей работы по госзаказу. Эх, коллеги мои, братья программисты, архитекторы и аналитики, знали бы, что предлагается сделать за эти деньги и кто!! на них претендует. Срам и позор. Так что впереди нас ждут не просто проблемы с очередным егаисом, а полный паралич в серьёзнейших отраслях. Синька ещё покажется пустяком.

четверг, июля 20, 2006

Сейчас почему-то вспомнил

Много лет назад, по окончании института, я раздумывал, чем бы заняться?.. К тому времени у меня был уже стаж, 5 лет - не комар чихнул, из них - 4 инженером-программистомЪ. Думал я не один, а с тем самым человеком, который интересовался влиянием одной программы на регистры другой во многозадачной ОС. И тогда додумался до видеоконференций, как раз только-только первые железки под это пошли. Но рутина и более приземлённые проблемы не дали (а точнее -тогдашняя неуверенность в результате).

А сейчас я думаю - как бы я поступил тогда - сейчас?

среда, июля 12, 2006

О качестве

Мне понадобился ADSL-модем-маршрутизатор-Wi-fi-AP. Я его купил. Лучше б я этого не делал. OvisLink и их дерьмовая WL-8064ARM это уже второе попадание на продукцию этого "концерна". Первым был 802.11g dongle, который по причине кривых драйверов некорректно впадает в анабиоз (с синим экраном). А тут - просто не работает ADSL-модем. Даже через делитель я слышу высокочастотный шум попытки установления соединения. Ну что это, если не дерьмо?! "Не покупай китайского!!"

вторник, июля 11, 2006

401й способ

Только что вернулся из длительной Псковской командировки. Человек, к которому я туда ездил, хорошо понимает выгоды быстрого и постоянного интернета и недостатки медленного и эпизодического. Короче, его организация подключена к "Северо-Западному Телекому" и имеет восблагоупромыслять ADSL, раздавая его сотрудникам по wi-fi. Словом, человек прогрессивный и "всё правильно сделал". Я очень радовался тому, что в Пскове всё в порядке с интернетом (по крайней мере, на рабочих местах) примерно два дня. Это преамбула. Теперь амбула.

Моя почта перестала уходить. По логам определил, что какой-то деятель закрыл 25й порт у этого самого СЗТ. Звоню. Мне долго рассказывают, что я должен переустановить у себя ПО (чуть не по Windows вклчтлн), после чего перезвонить. С негодованием отмёл. Ещё 20 минут объяснения проблемы. Меня переключают с человека на человека (даже не переключают, а просто диктуют номера, куда я должен перезвонить), пока я не добираюсь до директора этой всей шараги. Звать его Владимир. Воффка. "Вова", - говорю - "в чём дело? Вчера почта уходила, сейчас - нет". Он спрашивает у меня логин (а я вообще-то гостем в той сети и логин знал только потому, что пришлось перенастраивать маршрутизатор после того, как сломал его), думает, сообщает... "О! Да у вас же динамический IP".
Я: Ну?
Он: Вот и всё!
Я: Что - всё? У меня в Москве тоже динамический, диапазон, и как-то не случалось сталкиваться с запретом на отправку почты
Он: Ну, то в Москве
Я насторожился: А у вас?
- А у нас нету такого оборудования, чтобы определять, кто что куда кому и в каких количествах шлёт. Поэтому, чтобы не было спама - мы вобще запрещаем для динамических адресов связываться с кем бы то ни было по 25му порту.
Я: Вова, ну ты просто учудил. Нету слов.
Он: Такая политика. Исключительно ради безопасности.

Вова врал. Не исключительно. Стоимость аренды выделенного ip-адреса в месяц составляет 400 рубликов у этих уродов. 400 рублей x 12 мес x 1000 организация(я так думаю; 200000 в городе всего) ~~ 4800000 руб. с НДС. За эти деньги вполне можно было бы написать (и не одну!) программу и следить за спамерами с удоствами для остальных, а отнюдь не отпугивать клиентов, гоняясь за метафизическими крокодилами.

вторник, июля 04, 2006

Антитрестовское законодательство ЕС

Не могу понять, почему Mittal Steel, который становится производителем 7 тонн стали из 10 в мире, получает одобрение европейского антимонопольного комитета, а Microsoft, что вряд ли имеет долю в 35% - должен выплачивать по 2'000'000 евро в день за мифическое "нарушение"? Что бы это значило?

понедельник, июня 26, 2006

Шутки

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

Откат

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

воскресенье, июня 25, 2006

Ищу промо-ролик к Windows 98

Свои диски MSDN от 98го года за давностию лет - не нахожу (штук пять нашёл, но всё не то), а ролик нужен. Помню, что диск был зелёный, windows 98 назывался, вышел летом (как бы не в мае).

Если кто сможет подсказать/прислать/передать его - моя благодарность не будет знать границ, разумеется, в р.п.

пятница, июня 16, 2006

Сбылась мечта всех идиотов в мире

Гейтс уходит из Microsoft. Сдулся. Последствия этого очевидны. Пора начинать перебираться в соседний окоп.

Это автоматический перевод?

Получил себе account на www.beeonlive.ru
Потом решил зайти на "веб-журнал группы Messenger". Ткнул на "русский" и стало веселее.

понедельник, июня 12, 2006

UI

Я люблю задачки, но когда их становится чересчур много, то я начинаю нервничать.

пятница, июня 02, 2006

Ну вот, ещё один столб проехали...

И ни одна сволочь!... Тоже мне, друзья.

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

вторник, мая 30, 2006

IE 7 и заикание

Установил себе 7й. При этом появилось 2 эффекта:
1. Невозможно переключить раскладку клавиатуры иначе как мышью в панели языка
2. При отправке комментариев методом ПОСТ первый съедается с ошибкой. Приходится отвечать повторно, но после второго ответа обнаруживается, что первый ПОСТ всё же прошёл. Не буду дубли удалять.

воскресенье, мая 28, 2006

Office 12

Эпопея с Visio 2003 закончилась победой человека. Всё это время я надеялся, что V12 будет написана на .NET (уж если Vista не пишется на нём). Однако нет.

---------------------------
ERROR
---------------------------
error : 'C:\Program Files\Microsoft Office\OFFICE12\VISIO.EXE' has no valid CLR header and cannot be disassembled
---------------------------
OK
---------------------------

По-моему, это совершенно бесславные конец идеи Болмера - .net. Я понимаю, что в Microsoft ещё помнят, как они 5 лет компостировали людям мозг с Windows, но времена те ушли безвозвратно. А если к этому присовокупить ещё и вот это, то возникает вопрос. А нахуа это всё? Получается так, что надо просто заключать с жирными крысами договор на продажу их коробок, а свою бизнес-стратегию пусть хоронят сами. Без нас.

суббота, марта 25, 2006

Visio

У меня сложилось впечатление, что в одной компании не очень-то рады тому, что купили в своё время Visio. Это продукт с наиболее дебильной объектной моделью и такими странными ходами, что становится немного не по себе. Моя задача была обеспечить разбор нарисованного пользователем графа и сообщить пользователю о допустимости либо недопустимости выбранной конфигурации.

Эта работа состоит из большого числа полубессмысленных либо сложных и запутанных шагов и всё потому, что платформой для рисования был(о?) выбрано Visio. Для того, чтобы приступить к обходу графа, необходимо:
1. Построить stencil, определив geometries, custom property sets и прочие behaviors. Эти операции не так очевидны, потому мало иметь под рукой Visio SDK. Надо ещё под носом держать постоянно открытый Shapesheet для уточнения того, что соблаговолили написать в SDK. А кроме этого object inspector из VBA от Visio тоже не помешает: определять, к каким перечислениям и классам относятся странноватые константы вроде visRowXForm1D - откуда-то надо.
2. Внутри своего кода (в моём случае это C# 2.0) потребуется выполнять такие многозначительные операции, как получение точек соединения для фигур и отрезков, соединяющих фигуры. Интересно, что коллекции ConnectionPoints нет как класса, а вместо этого предлагается использовать что-то вроде


x = Shape.get_CellsSRC((short)Visio.VisSectionIndices.visSectionConnectionPts,
a,
(short)Visio.VisCellIndices.visCnnctX).get_Result(Visio.VisMeasurementSystem.visMSMetric);
y = Shape.get_CellsSRC((short)Visio.VisSectionIndices.visSectionConnectionPts,
a,
(short)Visio.VisCellIndices.visCnnctY).get_Result(Visio.VisMeasurementSystem.visMSMetric);


То есть, visio's shape нужно рассматривать как таблицу со строками и полями специального значения. Ну, ладно, бывало и хуже.
3. Оказывается, при повороте вокруг точки вращения Visio не учитывает изменения координат точек соединения. И если я попытаюсь соединить одну фигуру с другой (а признак соединения - совпадение начала или конца отрезка соединения с точкой соединения фигуры) - то мне потребуется самостоятельно выполнять перенос оси координат и поворот. Это, конечно, мелочь, чего там:

double x1 = x*cos - y*sin;
y = x*sin + y*cos;


Почему программисты Visio не стали делать этих вычислений самостоятельно я не могу понять.

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

вторник, марта 14, 2006

Книги

Я с удивлением обнаружил, что не могу пользоваться бумажными книгами; только теми, в которых возможен быстрый поиск. Кстати. http://www.poiskknig.ru/

пятница, марта 10, 2006

Microsoft

Несмотря на их BFS, к этой компании я испытываю очень тёплые чувства. Объективно - непонятно, почему. А субъективно - сегодня встречался с ними по делу, такое ощущение, как дома побывал.

воскресенье, февраля 26, 2006

История изменения

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

Предусловия.
1. Ничто не попадает в хранилище иначем, чем через адаптер.
2. Допустимо использование контекстов

Тогда.
Всю эту работу можно сделать довольно аккуратно при помощи атрибутов и контекстов.


[AttributeUsage(AttributeTargets.Class)]
public sealed class ReplicationTracingAttribute: ContextAttribute
{
public ReplicationTracingAttribute(): base("ReplicationTracing")
{
}
public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
ctorMsg.ContextProperties.Add(new ReplicationTracingProperty());
}
}

при этом
ReplicationTracingProperty
выглядит так:

public class ReplicationTracingProperty: IContextProperty, IContributeObjectSink
{

Если теперь метод
GetObjectSink
интерфейса
IContributeObjectSink
определить так:
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
return new ReplicationAspect(nextSink, obj);
}
то можно воспользоваться такой удобной вещью, как доступ к свойствам метода до того, как сам этот метод выполняется.

Смысл тут простой. На требуемые методы адаптеров навешиваются атрибуты отслеживания (см. выше), при вызове методов классов, реализующих адаптеры, поток выполнения заходит сначала в приёмник вызова. Этот самый приёмник что-то вроде пазухи, потайного кармана, расположенного между внутренней и наружной частью одежды. Если мы рассматриваем обычную модель работы со стеком, то между вызовом команды CALL процессора и снятием первого аргумента со стека в самой команде ничего нет. Вызвали - сняли со стека аргумент. А здесь, с приёмником, ситуация такая: закинули в стек аргументы, вызвали, а перед вызовом выполняется некий специальный код (это неинтересно объяснять, лучше один раз глянуть в MSDN), заворачивающий вызов метода в спец. оболочку, дающую доступ как к параметрам до вызова, так и к параметрам и возврату после вызова. Это чем-то похоже на генерирование защитного кода для тестирования обращения за пределы стека в Rational Purify, но гораздо более общо.

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

public IMessage SyncProcessMessage(IMessage Msg)
{
bool logOperation = Preprocess(Msg);
IMessage ret = m_NextSink.SyncProcessMessage(Msg);

if (logOperation)
PostProcess(Msg, ret);

return ret;
}

Не все операции надо протоколировать (например - можно протоколировать и SELECT, но зачем? Это задача аудита БД, мне нужно только протоколировать изменения и обеспечить откаты[в хорошем смысле]). Но если нужно протоколировать изменения, то метод PostProcess, вызываемый после собственно метода - то самое место, где будет выполняться запись протокола. В методе PostProcess для вызванного метода получаем перечень наших атрибутов, ну а дальше понятно. Единственное, что тут может потребоваться - это пояснить, как применяются и зачем тут атрибуты.

У меня они применяются так:

public interface IDataStorageAdapter
{
[AdapterReplication(SqlAction.Insert)]
long Insert(BaseItem Param);

[AdapterReplication(SqlAction.Update)]
int Update(BaseItem Param);

[AdapterReplication(SqlAction.Delete)]
int Delete(long Param);
...
}

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

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

среда, февраля 22, 2006

Microsoft Battle Flight Simulator 3

Неделю назад наконец-то мне привезли из Америки эту игру. Авиасимуляторы я люблю, решил вот попробовать заморского... Что я могу сказать? Погань. Стоит в моём игровом 9600XT. Это, конечно, не сегодняшний день, но с Ил-2 нет ни малейших проблем. Всё на самом деле летает: быстрая анимация, натуральное сглаживание, тени, видимость, метеоусловия. А эта заморская херня? Сходное ощущение у меня было только однажды, когда я попытался на карте S3 Virge погонять в Carmageddon, году не то в 98м, не то в 99м.

Что тут можно ещё сказать? Я разочарован дважды. В первый раз тем, что вместо гражданских самолётов мне привезли симулятор боёв, во второй раз - убогостью исполнения. Что им нужно? X800? Почему Медоксу это не нужно?...

воскресенье, февраля 19, 2006

Ни о чём

Зашли поужинать в Тратторию. Заказы напоминали эпициклоиду. А последующая поездка домой - кардиоиду.

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

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

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

вторник, февраля 14, 2006

Переделки

У нас начата миграция на .NET 2.0, удачно совпавшая с началом нового проекта. То есть, не то, чтобы он был совсем новым, но нужно так много сделать и столько переделать, что можно считать его новым.

Переделки начались "издаля". Сначала была подвергнута жестокой вивисекции рабочая библиотека, что уже пару лет помогает нам смотреть на объекты через призму ЕСС. Потом начали изменение кода самого приложения, чтобы технологическая сборка (как мы называем то, что делается для удостоверения в синтаксической корректности кода). Это заняло уже 5 дней и ещё займёт дня 3-4. Сегодня, говорят, удалось даже запустить этого гидроцефала и он пару минут работал :-). Хорошо, что есть люди, которые берутся за такую работу...

пятница, февраля 10, 2006

Прикладная нумерология

Только что в Sent Items упало письмо с порядковым номером 8888. Столько писем я отправил 12:20 25го мая 2002года. Теперь я знаю, как вечером развлекусь: закачаю в несчастную громоптицу все письма с 96года.

среда, февраля 08, 2006

Наборы разрешений

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

Возможно, это потому, что сделано не очень понятно. Я бы сделал проще. Вообще, ситуация мне напоминает год эдак 94й, когда все знали, что есть OLE2, но мало кто мог внятно изложить, что такое связывание, при чём там DDE и зачем нужны ConnectionPoints.

Материала по безопасности вокруг много, но не очень много я вижу связного. Не начать ли систематизировать и публиковать?...

суббота, января 21, 2006

Перешли на круглосуточную работу

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

четверг, января 12, 2006

Если ты выдохся...

Если

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

среда, января 11, 2006

Вчера был в Троицке, МО

Забрал двое binary watches (красные и синие) для друга. Завтра к нему и поеду.

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

понедельник, января 09, 2006

Закончена переделка репликатора

Новостей, собственно, 2.
1. Код переписан почти полностью, но все тесты срабатывают на 100%
2. У нас есть настраиваемый стек обмена произвольной информацией.

Завтра, если и QA не найдёт слабых мест, будем запускать в production. ПоглядимЪ.

пятница, января 06, 2006

Производственное

Двое суток были посвящены разработке модели Репликатора, который позволил бы выполнять произвольные двусторонние преобразования данных, которые берутся из нашей гранд-базы (для выгрузки) и почты/диска/etc. (для загрузки). В процессе создания "бумажного прототипа" было написано 1500 строк кода, изрисовано схемами почти 7 бумажных страниц А4 и 2 страницы текста в Microsoft Word.

Результат мне очень нравится.

  • Все внутренности вроде событий синхронизации аккуратно упрятаны вглубь кода.
  • Интерфейсы взаимодействия почти невесомы и на 100% очевидны и ожидаемы
  • Для приёма и выдачи данных используются контейнеры.
  • Исключено использование БД для хранения промежуточных и конфигурационных данных (а в первой версии это предполагалось)
  • Стек преобразователей настраивается простым копированием в каталог на диске
  • Исключительно простая схема обработки неизвестных данных позволяет разгрузить объект "Координатор" от сложной аналитики
  • Убить мусором преобразователь невозможно
  • Одно из самых главных достоинств: в этой модели действительно можно преобразовывать что угодно во что угодно
Это стоило двух дней напряжённых размышлений. Сейчас вот немного посплю и начну воплощать.