bash.im ithappens.me zadolba.li

Программизмы

696

Действительно простые числа

Учился я тогда в восьмом классе, однако ещё в шесть лет родители купили мне «букашку» (БК-0010-01) со встроенным Бейсиком, на котором по тоненькой брошюрке я учился ваять простенькие программы.

На контрольной по ИВТ дали задание вывести на экран простые числа от 1 до 100 через запятую. Предполагалось, что надо задать массив, а потом в цикле выкидывать из него составные числа. На выполнение задания давалось два часа.

Через 10 минут подзываю преподавателя, показываю вывод программы, получаю пять и у всех на глазах с гордостью покидаю класс. Листинг выглядел следующим образом:

10 CLS
20 PRINT "2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97"
30 END

666

Скучаете? Тогда мы идем к вам!

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

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

Когда полезли в код ковырять - удивлению не было прeдела! Мало того, что разработчиком на момент запуска была добавлена непонятно зачем "закладка" вида:
for(i = 0; i < 100000000; i++);
так еще и в момент запуска, инициализировалось "пасхальное яйцо", которое наш товарищ наваял во время обеденного перерыва.

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

649

Наплодили тут сущностей

#639 напомнило.

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

Тут меня посещает мысль, что, возможно, эта последовательность (хоть она и не слишком типичная, да и не короткая) может встретиться в коде несколько раз. Проверяю - точно! Всего нашел 11 таких последовательностей. Удивлению моему небыло предела, пока я не включил отображение хекс-кодов "буквами" - 10 раз из 11 эта последовательность была частью слова "Button1", и только один раз - исполняемым кодом.

627

Тупой платит дважды

Писал сервис для проверки состояния заказов на корпоротивном сайте.

Какое-то время всё нормально работало, а потом руководству вздумалось перетащить сервис на другую хостинг-площадку, причём сделать это с помощью очень крутой сторонней фирмы "не в зуб ногой", чтобы там всё было "ещё круче". Заодно поставили им задачу - чтобы ссылка была в виде status.php, а не status.php?name=...&code=...&office=...

Разумеется, ошибки переноса файлов пришлось исправлять мне. Как и ошибки при выполнении дополнительной задачи - клиенты были бы слегка недовольны, зайди они на страничку "от крутой фирмы" и увидь там: "Здравствуйте, Джинсы SWEATHOSE AJC: артикул №....".

Заменил $name в конце программы на $itemname, стало нормально. Начальнику про "крутую фирму" ничего не сказал - хочет он за неумелый и весьма медлительный плагиат с меня же платить мою зарплату за полгода - его право.

593

Зависание с песней

Когда мобильные игры достигли запредельной жирности, "сверху" появилось требование: игра должна работать из-под браузера. То есть загружаешь её через WAP, на вопрос "Запустить?" отвечаешь: "Да", и она должна запускаться и не зависать. Впоследствии опомнились: браузер отъедает столько памяти, что игра получится кастрированной! Но делать что-то надо...

Программисты придумали вот что. Появляется заставка: "Если игра зависла, выйдите из браузера и закройте ненужные программы". Затем выделяется большой блок памяти. И только если память удачно выделилась, возвращаем её и загружаем собственно игру: графику, звуки и всё остальное. А если нет - игра зависает на этой самой заставке.

573

Нет, пойдешь ты!

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

Первый писал её на Паскале, второй проверял. Запустили. Программка (под DOS ещё в те времена) писала быстро-быстро фамилии обоих попеременно, пока не будет нажата any key. Мусор идёт выносить тот, чья фамилия окажется последней. Any key жал я, как незаинтересованное лицо.
Ясное дело, что мусор пошёл выносить тот, что проверял, а не тот, кто писал.

Когда он вернулся, второй ему продемонстрировал за правой границей экрана с позиции эдак 100-й некий читерский код, пропускающий проверку any key для понятно какого случая. Второй посуровел, но ведь сам же проверял, так что винить некого. Поэтому сказал, что в следующий раз он сам будет программку писать.

На "следующий раз" он её писал на С. Второй её как только не проверял, только что не дизассемблировал. И пошёл выносить мусор. Когда вернулся, понял, что не диссамблировал напрасно: этот ему отомстил редактированием <conio.h>, пересборкой библиотек и восстановлением <conio.h>

559

Долговременная память

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

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

Причина нашлась, как это часто бывает, слишком поздно и почти случайно. Исследуя документацию к библиотеке, которую мы использовали для работы с пересылаемыми XML-пакетами, я случайно нашёл метод reset. Стоило добавить в наш код вызов этого метода, как требования упали в 10 раз! Оказалось, что пока этот reset не вызван, клиент помнит все DOM-модели всех полученных с сервера пакетов...

557

Что-то ищем где-то не там

Очередной проект по доделке и переделке авторских недоделок в программе заказчика.
Угу.

Заявлена кроссплатформенность - используется Qt, есть клиенты для Windows и никсов. Клиентов беспокоит, как Гондурас странная особенность: под никсами программа уверенно работает отовсюду, кроме каталогов, расположенных в /home (например - на рабочем столе, что должно быть интуитивно понятно и привычно для пользователей Windows). Угу.

Авторы грешили на особенности сборки Qt, на примечания к документации QFileSystemWatcher "о зависимых от системы лимитах на количество одновременно наблюдаемых путей". Но почему-то программистов заказчика не обеспокоила такая особенность систем, под которые портировалась изначально виндозная программа, как чувствительность к регистру путей файловой системы. Аффтары нечувствительно приводили путь к lowercase, а потом проверяли существование каталогов типа Desktop или "Рабочий стол" для пользователей типа Vasya_Pupken.

А метод проверки QDir::exists(), спроектированный с учетом особенностей *nix, имел их всех в виду.

554

Инициализируй это

Был у нас в универе один вредный препод. Не любили его, так как предмет свой он преподавал просто отвратно. И вот однажды надо было сдать ему на зачет какую-то программу. Мой друг написал ее. Сдал. Со второго раза получил допуск к экзамену. Мне стало интересно. Запускаю - работает. Обрадованный беру код, смотрю. Спустя пару секунд падаю под стол от такой строчки:

for (int i=0; i<N; i++) M[i]=M[i]+0;

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