пятница, декабря 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 серьёзных обновления к нашей библиотеке ядра). Во-вторых, найдено простое и эффективное решение задачи ручной репликации в распределённой среде. Оно не потребовала никакого изменения логики процесса и это не может не радовать. Ещё много чего по мелочи.

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