bash.im ithappens.me zadolba.li

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

468

В незнакомой ситуации - убиться

Сопровождал я как-то в компании АРМ на 16 машинах.
Сделано там все красиво и правильно - весь софт крутится на nix'ах, восемь машин рабочие, восемь в горячем резерве.
Есть полный набор документации и даже весь исходный программный код.

Ну и в один прекрасный момент падает рабочая часть АРМа - все машины вываливаются в командную строку в которой что-то пишется по-английски. Электрики паникуют, технологи паникуют, а начальство зовет специалистов из отдела ИТ.
Мы возвращаем все на место.
Все работает.
А через полтора месяца - опять ломается!

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

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

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

398

Веселые ляпы

Как то раз, в последний день месяца, нашего директора посетила мысль. И так она ему понравилась, что он решил немедленно воплотить ее в жизнь, а именно - дал мне задание написать скрипт, рассылающий по email всем нашим клиентам статистику работы за прошедший месяц. Так как дело было в конце рабочего дня, то я слепил скрипт за несколько минут, особо не заморачиваясь на "придание товарного вида".

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

Получилось что-то вроде следующего (на shell):

for i in `ls /billing`
do
echo "Статистика работы в интернет за май 1998г." > shapka.tmp
cat /billing/$i >> shapka.tmp
cat shapka.tmp | mail -s "Statistic" $i
echo $i
done

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

В конце следующего месяца история повторилась с той лишь разницей, что я тупо запустил этот скрипт и получил втык от директора, за то, что в заголовке фигурировал "май", а не "июнь", В июле я полез было исправлять скрипт, но меня вдруг осенило, что в самой таблице статистики дата уже присутствует, и шапка в общем-то не нужна, поэтому я просто стер из скрипта строчку:
echo "Статистика работы в интернет за май 1998г." > shapka.tmp
забыв поменять в следующей строчке ">>" на ">"

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

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

396

Поворот небинарной сосны

Два часа ночи.
В могучем Гугле пытаюсь найти функцию поворота бинарного дерева.
Ввожу в строку поиска: «поворот дерева».

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

Любопытство все-таки берет верх, захожу по ссылке и читаю «НОВЫЙ ЛЕСНОЙ КОМБАЙН».

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

391

Лучшее - враг хорошего

Дело было в 95 году. Учился я в ПТУ на гордую профессию "оператор ЭВМ".
Как раз тогда я начал увлекаться программированием, что и сыграло со мной злую шутку.

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

Моя программа могла работать в режиме редактора тестов, тесты сохраняла в отдельные файлы на диске и т.д. Сдали работы. Меня очень похвалили (я был доволен) и... попросили сделать листинг программы для потомков. А поскольку принтера у нас не было - пришлось сидеть и переписывать ручкой код в тетрадь.

Никогда я так больше не страдал.

374

А делать-то нам нечего!

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

Итак, нужно было сделать курсовую, иллюстрирующую, как несколько потоков разделяют общей ресурс – очередь. Одновременно потоки добавляют в очередь данные, а затем считывают из нее то, что добавили. Реализовал на C в Knoppix с использование pthread. Но веселье началось, когда я понял, судя по выводу проги, что потоки выполняются не одновременно, а поочередно.

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

После добавления аналога: for(i = 0; i < 100000000; i++) в поток, я заплакал над убитыми впустую выходными...

367

Собрать по кирпичику

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

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

$res = $DB->getData($query); //считывает данные с ДБ и загоняет в пронумерованный массив
$data = new array();
foreach ($res as $key=>$value)
{
if (!$data[$key])
$data[$key] = $value;
};

Все это вместо простого $data = $res;
Что имел ввиду кодер, родивший это чудо, так и осталось загадкой.

365

Какое страшное самоубийство!..

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

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

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

Кто ж знал, что программа подкинет нам такой сюрприз!
На узкой горной тропе встретились неудовлетворенный желудочно ТБаран и неудовлетворенный сексуально ТСлон. Как объекты для удовлетворения своих потребностей они друг друга совершенно не интересовали, поэтому представляли друг для друга просто препятствие. Всемогущий Рандом решил, что в этот раз слону придется полежать немного в качестве элемента интерьера, а баран пойдет дальше. Скрипт бодро превратил ТСлона в квадратный метр свежей зеленой травы, радостный ТБаран сожрал ее, навалил кучу и там же рухнул спать. Несчастного слона поминали всей бригадой, включая преподавателя.

361

Переучивать не будем.

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

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

Потом этим железом испытывали ракетные двигатели...

358

Симметричный мультикомпьютинг

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

Препод довольно кивает - студент закончил лить воду и сейчас начнет рассказывать, как он распараллеливал потоки, искал узловые точки алгоритма и т.д.
- Так как же вы организовали это параллельное вычисление?
В ответ студент показывает на четыре компа в аудитории:
- Компьютер №4 проверяет значения от нуля до миллиарда, компьютер №5 - от миллиарда до двух...