Истории с тегом: программизмы

Всего историй: 896

12340

Жемчужина в куче фейспалмов

Жить или нет в чумном бараке — каждый решает для себя. Это не какое-то свойство конкретной профессии, а скорее свойство возраста. И для меня в IT всё ровно наоборот.

Во-первых, IT — это одна из немногих сфер, где ты можешь быть уверен в своём профессионализме. После освоения основного объёма информации по какой-то теме достаточно изредка читать новости и апдейты, чтобы сохранять навык. Зачастую знания, полученные 20 лет назад, оказываются актуальными и поныне (или, как минимум, сильно облегчают освоение темы).

Во-вторых, IT — это чуть ли не единственная сфера, где почти всё можно попробовать и проверить, прежде чем пускать в ход. Это не хирургия, где пациент реально может оказаться трупом. Да что там, даже у водителя автобуса больше риска, потому что он не может посреди движения отвлечься, а в случае ошибки — откатить автобус на пять минут назад.

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

В-четвёртых, ни 13-летний, ни даже 23-летний никогда не сравнятся с разработчиком с 20-летним стажем. И совершенно плевать, что они могут знать больше о чём-то новом: получить технические знания нетрудно, а вот опыт дебаггинга и разработки, особенно командной, развивается годами. Тут как у любых инженеров: «Опыт прямо пропорционален количеству испорченного оборудования».

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

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

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

Удачи!

12284

Пять лет байторубки строгого режима

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

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

Для этого придётся отказываться от мешающих факторов. Сторонники линуксовой консоли предложат отказаться от GUI. Сторонники «Менуэтов» и «Колибри» — от ЯВУ. Вначале эти концепции будут работать по отдельности. Затем требования к производительности возрастут настолько, что придётся отказаться от того и другого одновременно. Потом — вернуться от алфавитно-цифрового ввода-вывода информации к чисто цифровому. И, наконец, от чисто цифрового перейти к тумблерно-светодиодному, как в MITS Altair и микротренажёре МТ1804.

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

Постепенно у населения выработается чёткая ассоциация: компьютер — принудительные работы. И держать машину дома, а уж тем более добровольно подходить к ней и включать, никто не захочет: «Мы что, мазохисты? Пусть этим приговорённые занимаются». Поборники же авторского права исчезнут сами собой, потому что и без них все будут любую свободную минуту тратить на посещение театров, дабы отдохнуть от мигающе-щёлкающего мира, где буквально всё управляется светодиодно-тумблерными монстрами с каторжниками за пультами.

12239

Сингулярность своими руками

Создавая собственный мод к игре X²: The Threat, я задумывался над тем, что изюминкой моей модификации должны стать не только графические изыски, дотягивающие игру 2000 года до уровня почти современной графики, или, к примеру, скрипты, создающие уникальные события или миссии для игрока. Хотелось внести в игру ещё и какой-нибудь совсем уж нереальный элемент вроде черной дыры.

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

Графически планета должна выглядеть соответственно общим представлениям о прожорливом брюшке вселенной. Нарисовал в 3ds max модель — вернее, составил её из уже имеющихся в игре стандартных элементов, несколько модифицировав их размеры и список текстур. Получил вполне смачную сингулярность с тёмным ядром, аккреционным диском из пыли и падающими к ядру облаками газа. Удовлетворившись визуальным результатом, решил сразу поэкспериментировать, как это будет смотреться в игре.

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

Я никогда не декомпилировал ядра игр. А это возможно, и многие это делают — честь им и хвала! Мои же модификации всегда опираются больше на возможности простой подстановки или скриптового программирования.

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

Вот здесь я, собственно, и споткнулся. Забыл, что, в отличие от всех прочих объектов вселенной Х², помещаемых в игру по цепочке «INI-файл — сцена — модели в сцене», планеты помещаются иначе: INI-файл ссылается на головную модель самой планеты, к которой привязывается сцена, состоящая из нескольких слоёв: модели с текстурой ночных городов, полусферы тумана и ночного затенения, слоя облаков, слоя свечения атмосферы.

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

Игра благополучно запустилась, проглотив изменения.

Наученный опытом прошлых внедрений в игру всяческих объектов, я не стал устанавливать сингулярность в секторе присутствия. Для начала читерским скриптом открыл для пользователя всю карту вселенной, а затем, написав новый скрипт в одну строку, внёс объект «чёрная дыра» в соседний сектор.

Неладное я заподозревал в момент создания объекта. Резкие броски корабля по крену и дифференту были обусловлены не то торможением программы, пропихивающей сбойный объект в математику ядра, не то заранее заданными создателями эффектами. Но через несколько секунд всё успокоилось. Забыв о том, что можно в другом секторе просто создать корабль или станцию игрока и за счёт внешнего контроля за собственностью осмотреть окружающее пространство, я решил сунуться туда сам. Разогнался, прошёл врата… Грандиозный «бабах» был ответом на мои изыски.

То, что клюкнула сцена, понятно. Но почему ядро игры вместо красивой сияющей сингулярности поставило по координатам просто чёрный шар, а заодно разнесло все рукотворные объекты сектора, для меня пока загадка. Однако, когда та же самая математическая сила разнесла в щепу и мой кораблик, а игра, продолжая правильно отрабатывать, вывела на экран надпись «The End» и корректно завершила работу, я вдруг вспомнил Оппенгеймера:

— Какая интересная физика!

12139

А не дурак ли я?

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

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

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

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

Незнание об автоматическом приведении типов в используемом языке (скорее всего, C). Функция det() может возвращать значение не double, а более ёмкого типа, который компилятор приводит в double при присвоении в double и, наоборот, до которого расширит double при сравнении. С учётом этого факта никаких странностей в приведённом коде нет вообще — всё вполне логично. Перед тем как кидаться с обвинениями в адрес разработчиков компилятора, стоило открыть определение функции det() и посмотреть на тип результата, потом внимательно почитать описание стандарта языка программирования и сравнить реализацию на соответствие; наконец, почитать описание компилятора на тему особенностей реализации на той или иной аппаратной платформе и возможных отклонений от стандартов.

Морали в этой истории две.

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

Вторая: когда сталкиваетесь со странным поведением кода, всегда ищите проблему с мыслью «а не дурак ли я?». Это куда чаще оказывается правильным, чем поиск с мыслью «где-то налажали разработчики компилятора и ОС». Не то чтобы их пишут непогрешимые — это не так, ошибки в них действительно встречаются. Но это происходит значительно реже, чем ошибки начинающих и даже опытных программистов в их собственном коде.

12133

С оглядкой на хвост

Вздумалось кому-то (не мне) проверять, что матрица между вычислениями не поменялась. Проверять решил просто: считал определитель, сохранял значение и в нужный для проверки момент вычислял определитель опять. Если определитель не изменился, то можно спать спокойно.

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

В результате отладки дохожу до такого кода:

double a = det(M);
assert(a == det(M));

Ассерт срабатывает. Ладно, добавляю строчку:

assert(det(M) == det(M));

Ассерт не срабатывает. Функция всегда возвращает одно и то же значение. Добавляю:

double diff = a - det(M);

Результат равен нулю. Причём строго нулю, посмотрел побайтово. Та-ак… Похоже, что имеем вещественное число, в общем случае не равное самому себе. Уже интересно…

double a = det(M);
double b = det(M);
assert(a == b);

Ассерт не срабатывает. Пора в дурку…

Ларчик открывался просто. В сопроцессоре все числа обрабатываются в 10-байтовом формате, а double, как известно, 8 байт. Разработчики самого безглючного компилятора возвращали значение в голове стека сопроцессора и забыли нормализовать его до 8 байт. Нормализация происходила только в случае сохранения значения в переменной. Хвост в 2 байта добавлял несколько знаков к мантиссе и вызывал все эти спецэффекты.

12105

Я не наркоман, я программист

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

Утро пятого дня. Вид у меня соответствующий: красные щёлки глаз, оплывшее заросшее лицо со следами насильственной смерти, взъерошенные волосы и полное отсутствие эмоций во внешнем виде. Сознание в похожем состоянии. Если быть точнее, то его нет вообще — оно аварийно отключено. Подсознание работает хрен пойми как, а за адаптацию в обществе отвечает резервная система на базе шаблонов. Шаблонов мало, они примитивны, и вообще система проста до безобразия и тоже начинает давать сбои.

6:30. Тушу комп, как-то одеваюсь, иду на остановку. На остановке народ подозрительно на меня косится. Пропускаю автобус с цифрами 292 на номерах. Мысль: «Переполнение, я на нём не поеду». Понимание приходит минут через десять, следующий автобус — через тридцать.

Гружусь в автобус, сажусь. Пацан лет четырнадцати просит передать на проезд за двоих. Я поворачиваюсь к нему и говорю: «Переполнение буфера, попробуй разбить пакет на два». На меня странно смотрит пацан и пол-автобуса.

Краем уха слышу, как меня матерят на чём свет стоит три бабки: «За#$@ли наркоманы, до чего уроды страну довели!» — и недвузначно тыкают в меня пальцами. Сознание делает робкую попытку проснуться, и я говорю: «Я не наркоман, я программист». Сознание падает в процессе загрузки; последнее, на что я обращаю внимание, это слова бабки: «Зомби компьютерные, б#я».

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

Через двадцать минут я всё же вспоминаю, что мне надо на работу, и начинаю свой путь. Его я не помню.

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

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

Программисты, берегите своё здоровье. Его вам никто не вернёт.

12098

Красноглазый полтинник

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

Ответ всплыл уже по приезде, когда я снова заглянул в калькулятор. Я вдруг обратил внимание, что использовалось шестнадцатеричное счисление, которое я однажды забыл поменять обратно. Более того, разница в суммах между DEC и HEX действительно составила всего несколько рублей. Долго смеялись над этим. Так-то вот, будьте внимательны при использовании программистских калькуляторов в быту!

12086

Как за неделю написать трёхмесячный проект

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

А теперь — собственно, рецепт.


Стадия планирования. Планировщики строят какие-то планы. Менеджмент эти планы утверждает, планы передаются отделу разработки.

Стадия разработки. Все работают согласно приготовленным планам.

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

Две недели до выхода Release Candidate. Приходит крутой спец из отдела продаж и говорит: «А я тут был на презентации конкурента, у них такая классная фича есть! Давайте, чтобы быть конкурентоспособными, мы забацаем вот эдакую фичу? Продаваться наш продукт будет в …дцать раз лучше! А без неё этот наш продукт вообще никто не купит».

«У-у-у… Без продаж нам будет туго. А давайте!» — соглашается менеджмент.

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

QA, скрупулёзно следуя планам, добираются до только что вписанного куска. Описанная в нём функциональность, естественно, не работает, потому что её никто не писал. Открывается баг на тему «Мегаважная фича не работает!!111»; ему присваивается экстравысшая категория важности.

Только тут разработчики офигевают от бага, смотрят в планы (которые не должны были меняться ни при каких условиях), офигевают ещё раз и интересуются: «Это ваще что было?! А нас кто-нибудь спрашивал?»

Всё это сопровождается беготнёй, мейлами через три континента, криками, воплями и инфарктами. Менеджмент убеждает разработчиков поднапрячься. Кого-нибудь делают крайним и спихивают весь проект на этого бедолагу. Он выполняет задачу, держась исключительно на кофе и на мотивирующих пинках начальства. Ну, как «выполняет»… За неделю трёхмесячный проект не написать. Поэтому пишется только good path, и новая фича будет работать, если пользователь ни в коем случае не попытается отойти от описанной в документах процедуры. Всё остальное (а 80% работы обычно занимает обработка граничных и нестандартных значений) закрывается заглушками — иногда прочными, иногда не очень. Поведение программы в том случае, если пользователь всё-таки отошёл от good path, вообще никем не гарантируется. Если повезёт, заглушка сработает, и пользователь ничего не заметит. Если не повезёт… Значит, не повезет. Программист сдаёт проект, получает премию и уходит спать.

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

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

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

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

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


Резюме № 1: инициативных дураков из отдела продаж надо убивать-убивать-убивать Ржавой Секирой Ужоса, желательно сразу после их трудоустройства.

Резюме № 2: с момента начала разработки у планировщиков надо забрать физическую возможность менять планы этой версии.

Резюме № 3: менеджмент, который этого не понимает, ведёт компанию к краху.

12076

Поезд следует до станции NULL

Работаю недалеко от дома, хожу каждый день через железную дорогу.

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

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

12057

Пока корона не рассосётся

Все, наверное, слышали золотое правило: работает — не трогай! Это действительно хорошее правило, проверенное жизнью.

Но есть и другое, так сказать, серебряное: если сломалось, ты полез в чужой код и не понял, зачем оно там так было сделано — подумай ещё раз. А потом ещё раз. И ещё — пока не поймёшь, зачем и почему. И только потом, может быть, переделывай.

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

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

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

Ты увидел, но не понял зачем? Подумай ещё раз, пока корона на голове не рассосётся: возможно, это не мусор на полу, а кто-то более опытный просто заранее подстелил соломки?