*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

среда, 26 января 2011 г.

Fossil - контроль версий, баг-трекер и wiki в одном флаконе

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

Лично я люблю git для UNIX и mercurial для Windows. Каждая система имеет пачку удобных хостингов, как говорится, выбирай на вкус.

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

Начал я его вести в mercurial, но когда начал утопать в письмах и документации, то осознал необходимость баг-трекера и wiki. Настраивать все это локально (на публичные готовые хостинги выложить не могу) как-то лень. И тут я вспомнил по fossil.

Fossil - это распределенный контроль версий, баг-трекер и wiki в одном флаконе. Более того, его автор -- ни кто иной, как автор SQLite, борец за минимализм, простоту и надежность. Как и в случае с небезызвестной базой данных, которую кто уже только не использует, все, что вам нужно - это один единственный файл -- fossil[.exe].

Для командной строки - это просто SCM, а будучи запущенной с параметром "ui", превращается в локальный веб-сервер, в котором есть "морда" для просмотра репозитория, баг-трекера и wiki. Более того, все данные живут также в одном единственном файле-репозитории, который по сути является SQLite-базой. Для переноса его в другое место, другую операционную систему или резервного копирования, нужно просто скопировать один файл.

fossil умеет импортировать и экспортировать в git, поэтому я сначала перегнал существующий репозиторий из mercurial в git, а потом импортировал из git в fossil.

В целом, fossil хорош. Вылизанный и минималистичный. Говорят, что из-за использования SQLite в качестве хранилища, с одной стороны получаешь надежность и транзакционность любых изменений (понятно, что хоть остальные системы работают просто с файлами, у них с целостностью тоже все в порядке), но с другой стороны, по скорости может радикально проигрывать git или mercurial на больших проектах. Но для небольших "домашних", но секретных проектов - сложно представить удобнее утилиты.

Даже в рамках компании, можно личный проект в два счета превратить в общий, просто запустив fossil в режиме сервера и дав коллегам его адрес. Домашняя страничка fossil по сути является сервером, работающим на fossil (там можно увидеть живой трекер и wiki). Не самое плохое доказательство уверенности автора fossil'а в своем детище.

Да, лицензия у fossil, конечно, BSD.

Итак, для дома для семьи -- очень удобно.

вторник, 25 января 2011 г.

Баг в компиляторе LCC

Благополучно нарвался на баг в компиляторе LCC.

c:\lcc\bin\lcc -v

Logiciels/Informatique lcc-win32 version 3.8. Compilation date: Dec  4 2010 13:14:58

Файл: t.c

1
2
3
4
int main() {
    char* p;
    char* s[1] = { p };
}
c:\lcc\bin\lcc t.c
Error t.c 3 Compiler error (trap). Stopping compilation

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

Баги же типа этого, проявляющиеся на тривиальном примере - это всегда событие.

Из недавнего:

четверг, 20 января 2011 г.

Вопросы на интервью, на которые нельзя не знать ответы

Так сложилось, что за последние полгода, я активно участвовал в процессе интервьирования программистов в компании Bloomberg.

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

К сожалению, отказывать приходится порой из-за радикально тривиальных вещей, незнание которых просто несовместимо с профессией.

У меня накопилось несколько вопросов, незнание ответа на которые является почти стопроцентной причиной, когда я в своем отчете писал отказ.

Интервьюирование было на позицию "Senior C/C++ developer”.

Ответы приведу тут же, так как они очевидны.

  1. Сколько примерно будет 2^32? (обычно задается по телефону)

Ответ "Около четырех миллиардов" является исчерпывающим.

Я вообще и не могу понять, как человек, в названии профессии которого есть слово "программист" может этого не знать. Увы, это далеко не единичные случаи.

  1. Как сравнить две переменные типа double или float на равенство? (обычно задается по телефону)

Ответ "Вычесть одно из другого и сравнить результат на больше/меньше с каким-то малым числом, например 10E-6" является исчерпывающим. Конечно, много зависит от используемой библиотеки работы с числами с плавающей точкой, но смысл, в целом, одинаков.

Увы, количество неотвечающих тоже весьма значительно.

  1. (Хит!) Что распечатает данная программа? (не забываем, что собеседование на позицию разработчика на C/C++). В принципе, его тоже можно задать по телефону.
char* f() {
  char buf[100];
  strcpy(buf, "TEST”);
  return buf;
}

int main() {
  char* s = f();
  /* (1) */
  printf("%s\n", s);
}

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

Почему "почти"? Потому что обычно за ним дополнительный вопрос: "Что именно может с высокой вероятностью затирать заветное слово TEST и приводить к выводу мусора? Для конкретности: платформа x86, 32-bit, компилятор Visual Studio. Если остановить программу отладчиком в точке (1) и посмотреть, на что указывает указатель "s", то очень высока вероятность, что там будет таки "TEST", а вот printf() таки с высокой вероятностью распечатает мусор. Почему?".

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

Фактически, произнесенные слова "стек" и "параметры функции" являются достаточным ответом на вопрос.

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

Но все же есть такая черта, ниже которой уже нельзя.

А у вас есть вопросы, "неответы" на которые вы лично можете считать поводом для практически однозначного отказа?

Самые глупые ответы на интервью, что я когда-либо давал

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

  1. Как-то яростно пытался доказать, что тип int является за 100% атомарным без каких-либо гвоздей на платформе x86. Не доказал (и вот почему).
  2. Вопрос: «При множественном виртуальном наследовании в С++, кто и как должен заботиться о правильном однократном вызове конструктора базового класса (подразумевается, что у этого конструктора есть параметр)?». Я сказал, что это компилятор, и вдобавок еще не смог объяснить почему.
  3. Ну и лидер нашего хит-парада. Вопрос: «В С++ таблица виртуальных функций принадлежит классу или экземпляру класса?» Барабанная дробь: я сказал, что каждый экземпляр одного класса имеет собственную копию таблицу. Почему я так сказал, я до сих пор не знаю.

Все это еще раз подтверждает факт того, что на нервах можно сморозить такое, что потом сам будешь думать о причинах сказанного.

вторник, 18 января 2011 г.

Алгоритмы на C++ и Java

Не побоюсь повториться -- две совершенно волшебные, на мой взгяд, ссылки на реализации множества алгоритмов на C++ и Java.

Если у вас есть в заначке ссылка на ресурс подобного качества, поделитесь пожалуйста.

Компилятор языка С: LCC-WIN32

Потребовалось мне тут прикрутить к замечательной программе putty подсветку синтаксиса на лету в терминальной сессии. И так вышло, что на новом рабочем ноутбуке я пока еще не успел поставить Студию. У putty есть makefile’ы для Visual Studio, Borland’а, Cygwin’а и LCC. Первых двух у меня не было, и взять их было негде, Cygwin недолюбливаю из-за необходимости таскать с собой потом dll’ки, и чудом выбор пал на LCC. До этого я никогда этот компилятор не использовал.

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

Про библиотеку хочу сказать отдельно. Помимо стандартного набора libc и Win32 API, там полно всего остального. Лично я был несказанно удивлен простой, и порой столь нужной функцией ping() (и не надо больше вызывать ping.exe в скрытом окне).

В общем, с помощью также идущих в комплекте регулярных выражений, я быстро подхачил putty как мне было нужно. Попутно проронил ностальгическую слезу от программирования оконного интерфейса на чистом Win32 API и ощутил некоторые приятности С99. Например, объявление переменных не в начале блока, а где удобно, и размер автоматических массивов задавать не статически, а из переменной. C99 однозначно стоит внимательного изучения.

Приведу небольшую выжимку из идущих в комплекте библиотек (кроме стандартных libc и Windows API, конечно). Думаю, названия говорят сами за себя.

gl.h OpenGL
sqlite.h  
bignums.h Работа с числами произвольной точности
bitstring.h  
bluetoothapis.h  
d3d.h  
d3dx.h  
dynloader.h Работа с DLL’ками
gc.h Сборщик мусора (требует запуска, конечно)
getopt.h  
icmpapi.h  
int128.h  
matrix.h Работа с векторами и матрицами
mq.h IBM MQ
msi.h  
netmon.h  
netsh.h  
pcre.h Регулярные выражения в стиле Perl
ping.h PING!
ras.h  
regexp.h Простой API для регулярных выражений (regcomp() и regexec())
snmp.h  
sqlite3.h  
str.h Работа со строками в стиле C99
tapi.h  

Итак, если вам быстро нужен небольшой компилятор (дистрибутив всего шесть мегабайт), для написания программы на С99 под Windows (для графического интерфейса придется все делать на чистом Win32 API), имеющий в комплекте в дополнение к libc и Win32 API приличный набор разнообразных библиотек, то LCC – это очень сильный кандидат.

Кстати, отдельно можно скачать и 64-битную версию компилятора.

Единственное, чего я не пробовал – это линковать объектники LCC с другими компиляторами. Кто имеет опыт – поделитесь.

воскресенье, 16 января 2011 г.

Учет рабочего времени

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

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

Например, типичный отчет за день:

2 часа встреча по проекту Х
1 час недельная летучка всего отдела
4 часа работа над багфиксом #ААААА
1 час телефонное интервью
1 час работа над проектом Y

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

Но есть тут одно "но". Лично на моем опыте могу сказать, что у программиста ничего кроме нервотрепки обязанность делать такие отчеты не вызывает. Обычно это кончается решением задачи поиска дырки, куда бы приткнуть лишнее время, так как на проект биллить неохота из-за уже зашкаливающего коэффициента «Забиллено/Запланировано».

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

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

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

А у вас в компании есть "биллинг" времени?