Archive for the 'Work' Category

Boost или что-то вроде того

Оказывается, аффтар этой библиотеки работает за соседним с моим столом.

Пикантности ситуации добавляет тот факт, что использование boost в конторе не поощряется.

ЭсТэЭльно сипласпласное

(Задумчиво глядит на свеженаписанный другими “мастерами” код)

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

Чтобы никаких доморощенных MySuperArray вместо стандартных контейнеров, никаких сортировок бубликом вместо std::sort и прочих заново изобретенных колес. За написание “потокобезопасных врапперов” поверх STL контейнеров должно следовать  немедленное отчисление.

Тем же, кто освоит нелегкое искусство неизобретательства велосипедов, можно будет давать бакалавра. А тем, кто после всего этого решит остаться еще немного поучиться, уже можно рассказывать про Кнута с прочими пряниками вроде Александреску и пугать lock-free алгоритмами.

А то ведь кошмар, что творится.

Программерское: Мой топ признаков плохого кода

Собрал тут свой собственный список признаков факапнутости кода.

На первом месте – классы со словом “Manager” в названии. Безоговорочный лидер в номинации “превратим любой код в страшные спагетти”. Самое ужасное в таких классах это то, что делаются они из самых лучших побуждений. Впрочем, так всегда – самые кошмарные деяния совершаются под прикрытием лозунга “мы же хотим тебе лучшего”. Я специально не пишу о внутренностях этих классов, само название “Manager” для меня уже достаточное основание к тому, чтобы код полетел в помойку.

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

class A;
class B: public A;

void DoSomething(A* ptr)
{
(B*)ptr->MethodOfB();
}

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

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

Четвертое место – преднамеренное нарушение энкапсуляции. Это когда в класс “бутылка пива” пытаются заодно вкрячить нечто, что вроде как должно научить экземпляры его автоматически упорядочиваться внутри класса “ящик пива”. Когда через неделю закономерно выяснится, что бутылки нужно упорядочивать в сикспаки, начинается любимый в народе аттракцион “аврал”. Есть вообще только один случай, когда объектам допустимо иметь какие-то знания о контейнере, в которые их будут складывать – это преднамеренно делается интрузивный контейнер. Во всех остальных случаях такой код – индикатор того, что code review можно прекращать прямо сейчас, иначе проблемы этот код начнет доставлять уже на следующей неделе. В общем случае – запихивание в классы внешних нерелевантных зависимостей есть большое зло.

Пятый признак – преднамеренное игнорирование или извращенное употребление паттернов программирования. Когда из-за страха перед великим и ужасным шаблоном “фабрика” образюутся иерархии, где один-единственный параметр конфигурации спускается каждым промежуточным классом вниз на десять уровней, чтобы там ему где-то делали if или switch..case, когда при программировании на C++ боятся использовать RAII или бьют по рукам за bind; или же, наоборот, пихают повсюду smart pointers (доморощенные, конечно же, бо boost – это слишком сложно), жди беды. Очень быстро кто-то посередине той иерархии забудет, зачем нужен этот мистический параметр, нигде в обозримых окрестностях не применяющийсяи “пофиксит” код, обеспечив остальных неделями отладки (ведь юнит-тесты для такого кода писать не принято – он же очень сложный!); неиспользование RAII рождает трудноуловимые дедлоки, а умные поинтеры дают вкусить циклических зависимостей по полной.

Шестой признак – использование наследования там, где нужна агрегация. Например, есть интерфейс классов, есть базовый класс, которые реализует 85% всей требуемой функциональности. Позднее выясняется, что функциональность реализована вообще на 100%, а единственное требуемое различие – это разное поведение в случае создания класса с определенными внешними параметрами. Например, в реальной жизни есть у нас автомобиль. Точнее, его кузов. Во всем мире все производители просто ставят разные двигатели на один и тот же кузов и обзывют это обидным словом “комплектация”. В мире программирования часто происходит закат разума за ум – вместо того, чтобы создать класс “автомобиль” со свойством “двигатель”, начинают городить иерархию “автомобиль А с двигателем Б”, автомобиль Б с двигателем А” и так далее, что вообще противоречит здравому смыслу. Еще бы, класс автомобиль оказывается наследником класса “двигатель”. Проблема тут в том, что разобраться во всем этом хитросплетении и потом поддерживать ее становится решительно невозможно. В то же время правильный вариант – создать нужный объект тпиа “двигатель” и передать его новому объекту типа “автомобиль” при инициализации- не только сэкономил бы пару тысяч строк кода, но и позволил бы унифицировать и протестировать все имеющиеся автомобили и двигатели отдельно друг от друга и даже попробовать впоследствии легко примерить движок от Мерседеса на Запорожец.

Пятисекундка ненависти

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

Кто такой senior developer?

Сегодня пришли к выводу, что

Senior developer – это обычный программер, научившийся успешно спихивать на других часть своей работы.

Тогда Team Leader – это  Senior Developer, достигший в этом деле совершенства.

Все очень просто, оказывается.

Рабоче-программерское

Дорогие соучаснеги программерского труда, помогите рассудить ситуацию. Вот если мне говорят

Паттерн “Фабрика” мы использовать не будем, потомушта это ойкаксложна и  один-единственный дополнительный интерфейс никто тут ниасилит; вместо этого мы наплодим три десятка базовых классов и пять десятков наследников (и потом будем ебаццо с багами в каждом из них), потомушта это просто и самый последний дятел с улицы это умеет

я охуеваю. Может зря? Может, я чего-то не догоняю?

Юнит-тестирование. Всем чтить!

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

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

ППКС.

MuthTV sluggish when buttons pressed on remote?

Recently I built myself a media center of old HP/Compaq computer and MythBuntu. It all worked as a top and I spent weeks learning about great features it has.

This week I was hoping to put some finishing touches on it. The last missing piece arrived – so-called “Vista Rock Remote”.

7.jpg

According to MythBunty HOWTO, this MCE-compatible remote should work out of box, despite some reviews saying it would only work with Vista. Don’t know if it works with Vista though, but it worked in MythBunty just fine. I only had to enable it in Mythbuntu control center. And restart MythTV frontend, of course.

Funnily enough, I noticed the big problem straight away. Every time I put recorded TV show on and tried to use volume up/down buttons on remote, the picture was getting sluggish and jumpy for noticeable time. Actually, it felt so weird I even thought that I might be only one who had that problem. I was not right – there were plenty of similar reports on Internet. And there was a workaround proposed also.

The root cause of the problem is that MythTV pokes X screensaver every time button on remote is pressed. It does not have to do so when you use keyboard, but must do it when you use remote as screensaver has no idea about it. MythTV kicks the screensaver by invoking “gnome-screensaver-command” with parameter –poke, and there are reports it does it twice every time you press the button. It isn’t itself a problem, the problem is that when this command is called often (and it exactly what happens when you try to put volume up or down) XOrg CPU usage jumps to 100%, which causes that unwanted “special effect” in your video.

This bug, however, has already been reported (here and here)  and the fix will probably be included in next MythTV release. For now, the only workaround was to disable screensaver and create a symbolic link to /bin/true with name gnome-screensaver-command somwehre in one of PATH’s directories that comes in front of where the original program resides. Say, if your PATH looks like

/usr/sbin;/usr/bin;/usr/local/bin

and gnome-screensaver-command is in /usr/local/bin, you can stop it from being called by creating link to /bin/true in either/usr/sbin or /usr/bin:

ln -s /bin/true /usr/bin/gnome-screensaver-command

But it would only work if you decide to disable the screensaver. You can try not to, but once display goes to sleep, you won’t be able to wake it up by using remote. So I decided to invent something more sophisticated.

Of course, I could  download sources, fix the bug and build MythTV myself, but I decided to leave it to mythbuntu team. Instead, I written small program that simply does not allow screensaver to be poked more often than once in a minute, which fixed the problem.

The good news: you can download it from this site: Mythtv screensaver proxy

The bad news: you must build it yourself. So, installing build-essentials first would be a good idea.

Download cpp file above somewhere in your home directory and then follow simple steps described in file header:

/*
 * Usage:
 *      1. execute "which gnome-screensaver-comand"
 *      If output is different from what you find below in
 *      DEF_PROGRAM, modify this macro accordingly.
 *
 *      2. build the program:
 *      g++ myth-screensaver-proxy.cpp -o gnome-screensaver-command
 *
 *      3. Find what directory original gnome-screensaver-command is in
 *              (/usr/bin/ by default).
 *
 *      4. Look at your PATH settings (printenv | grep PATH).
 *
 *      5. copy binary buld on step 2 to any of the directories that
 *      come in PATH before original gnome-screensaver-command directory.
 *
 */

КЫВТ.

Читал с утра RSDN. Наткнулся на спор не знающих C++ с не знающими .NET

Перестал читать потому, что поп-корн в своей окрестности напрочь закончился.

Код: до и после н.э. Зачем на самом деле нужны юнит-тесты.

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

БОльшая половина кода нашего проекта на первый взгляд выглядит очень хардкорно. Если опустить пару моментов, где я вдоволь оттянулся с белой и черной шаблонной магией, то бросится в глаза, что остальная часть этой половины идет вразрез с заветами секты “ООП”  и ее течения “многоэтажные иерархии классов” (да, я редко сажаю леса вроде приведенного на картинке ниже). В глаза бросится, да не долетит, а упадет и стечет (может быть даже прямо в ботинки).

Многоэтажная иерархия
При ближайшем рассмотрении




6 visitors online now
6 guests, 0 members
Max visitors today: 8 at 01:20 pm MST
This month: 13 at 03-09-2010 02:06 am MST
This year: 41 at 01-23-2010 03:43 am MST
All time: 41 at 01-23-2010 03:43 am MST