В свое время был начальником отдела разработок в студии %studioname%. Делали браузерные игры. Дано: вероятность попадания в противника из лука (в процентах). Написать: скрипт, который бы выдавал — было ли попадание или нет.
Как в таких случаях действует обычный Coder Sapiens, если нет особых требований? Генерит случайное число от нуля до ста и проверяет, меньше оно вероятности или нет.
Но один эксцентричный паренек пошел другим путем. Одним циклом for он создал массив из десяти тысяч нулевых элементов (так как проценты с сотыми долями), вторым циклом он заменил первые надцать (т. е. процентов без точки) элементов единицами. Потом скормил массив шаффлу и взял первый элемент массива.
Полгода назад работал в одной маленькой веб-студии. Программистов было двое: я и ещё один юноша. Юноша - студент, но толковый и нелепых ляпов не допускал. До поры.
Как-то раз сидит, пишет что-то, ругается сквозь зубы. В конце концов зовёт меня. Запрос, говорит, не работает. Я ему советую распечатать запрос - сразу, мол, поймёшь, что не работает. Распечатывает, вставляет в phpMyAdmin. Работает!
Я, немного офигевши, иду смотреть на это чудо. Действительно, в скрипте запрос сбоит, а в phpMyAdmin'е работает за милую душу. Лезу в исходник. Смотрю на строку, где формируется запрос, и начинаю сползать под стол. Строка выглядит следующим образом:
$query = "SELECT * FROM ..."
Зачем, спрашиваю? На что он мне так основательно отвечает: на всякий случай, мол, мало ли что...
Сопровождал я как-то в компании АРМ на 16 машинах. Сделано там все красиво и правильно - весь софт крутится на nix'ах, восемь машин рабочие, восемь в горячем резерве. Есть полный набор документации и даже весь исходный программный код.
Ну и в один прекрасный момент падает рабочая часть АРМа - все машины вываливаются в командную строку в которой что-то пишется по-английски. Электрики паникуют, технологи паникуют, а начальство зовет специалистов из отдела ИТ. Мы возвращаем все на место. Все работает. А через полтора месяца - опять ломается!
Нашим начальством выдан приказ - разобраться! Читать документацию, звонить разработчикам, делать что угодно, но чтобы такого больше - не было. Разобрались, что уж. Перелопатили исходники.
Оказалось, что в одном месте там идет система case, причем с многократными вложениями. Проверяется состояние оборудования, запущенные задачи и все это в виде кода пишется в одну переменную. А переменная эта до момента кейса нигде не инициализируется.
Как выяснилось, все стандартные режимы - проверенные и перепроверенные разработчиками - работали как положено, но прочие, да ещё и запущенные в нестандартном режиме, в необычных условиях и в некорректное время вызывали у оборудования ступор. Ответ программе не возвращался в принципе и (а проверки ведь никакой не стояло, так как оборудование всегда, ну совсем всегда должно было возвращать хоть что-то!) программа шла дальше, прогоняла состояние оборудования через эту хитрую систему кейсов, ответа не получала и закономерно падала с ошибкой "переменная не определена".
Как то раз, в последний день месяца, нашего директора посетила мысль. И так она ему понравилась, что он решил немедленно воплотить ее в жизнь, а именно - дал мне задание написать скрипт, рассылающий по 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 забыв поменять в следующей строчке ">>" на ">"
Запустив скрипт , я как-то не сразу обратил внимание, что список клиентов выводится с прогрессирующим замедлением, а когда сообразил, то сразу же бросился удалять эти письма из почтовых ящиков, но какая-то часть писем, все же просочилась, и пришлось несколько дней объясняться с клиентами.
Но самое забавное произошло уже в конце следующего месяца, когда к нам в офис пришла бухгалтер одной клиентской фирмы с толстенной распечаткой на матричном принтере и с просьбой "помочь разобраться".
Два часа ночи. В могучем Гугле пытаюсь найти функцию поворота бинарного дерева. Ввожу в строку поиска: «поворот дерева».
Получаю результат : «Поворот дерева осуществляется таким способом, что центр массы дерева не выходит за габариты машины по ширине, что снижает динамические нагрузки и положительно сказывается на устойчивости самой машины.». Минуту пытаюсь уловить связь между программированием и устойчивостью машины.
Любопытство все-таки берет верх, захожу по ссылке и читаю «НОВЫЙ ЛЕСНОЙ КОМБАЙН».
Внезапно, с деревьями работают не только программисты...
Дело было в 95 году. Учился я в ПТУ на гордую профессию "оператор ЭВМ". Как раз тогда я начал увлекаться программированием, что и сыграло со мной злую шутку.
Дали задание написать на паскале программу - тест. Требовалась простейшая линейная программа, которая задает вопрос, дает варианты ответов, а потом подсчитывает и выдает результат. Конечно мне показалось это жутку скучным, и я решил немного усовершенствовать задание.
Моя программа могла работать в режиме редактора тестов, тесты сохраняла в отдельные файлы на диске и т.д. Сдали работы. Меня очень похвалили (я был доволен) и... попросили сделать листинг программы для потомков. А поскольку принтера у нас не было - пришлось сидеть и переписывать ручкой код в тетрадь.
Наверняка вы знаете, что часто причиной тормозов некоторых коммерческих программ являются закладки в коде типа: for(i = 0; i < 100000000; i++); на самых часто используемых операциях: отрисовка окна, реакция на событие и т.д. Но иногда бывают случаи, когда подобная закладка несет полезную нагрузку.
Итак, нужно было сделать курсовую, иллюстрирующую, как несколько потоков разделяют общей ресурс – очередь. Одновременно потоки добавляют в очередь данные, а затем считывают из нее то, что добавили. Реализовал на C в Knoppix с использование pthread. Но веселье началось, когда я понял, судя по выводу проги, что потоки выполняются не одновременно, а поочередно.
Два дня и две ночи разбирался в чем дело. Поставил вывод промежуточных результатов после каждого добавления в очередь. Смотрю в логи – работают потоки одновременно, в очередь кидают как надо данные – все в порядке. К слову, семафоры у меня стояли правильно и никаких потерей указателя на очередь не было. Вырубаю ведение логов – потоки упрямо идут друг за дружкой. После 5-часовой медитации и курения исходников до меня дошло – ведение логов и заставляло прогу работать правильно! При операциях ввода-вывода между добавлением данных в очередь теряется часть времени достаточная, чтобы хоть немного потоки поработали вместе.
После добавления аналога: for(i = 0; i < 100000000; i++) в поток, я заплакал над убитыми впустую выходными...
Работал над одним проектом, который до меня делали другие. Проект достаточно большой, и одна из его частей считывает некоторые данные с базы. Есть возможность регулировать дату от и до при считывании. Возникла проблема, из-за которой клиент очень ругался. Если промежуток от и до очень большой, к примеру кто-то захочет считать данные за несколько лет, то скрипт работает нереально медленно, а иногда даже выдаёт таймаут.
Бились над проблемой 3 дня, перелопатили кучу кода, даже нашли некоторые другие баги, которые не имели отношения к проблеме. В итоге наткнулся на кусок кода в том месте, где искать никто просто не додумался:
$res = $DB->getData($query); //считывает данные с ДБ и загоняет в пронумерованный массив $data = new array(); foreach ($res as $key=>$value) { if (!$data[$key]) $data[$key] = $value; };
Все это вместо простого $data = $res; Что имел ввиду кодер, родивший это чудо, так и осталось загадкой.
Делали мы как-то в институте модель какого-то мирка, по которому бродят дикие звери и удовлетворяют свои потребности: едят, пьют, спят, размножаются. В общем, кривенькая такая моделька, но зачем-то она нам понравилась.
И вот по мере наполнения нашего мира существами перед нами встала проблема коллизий. Проявилась она совершенно архетипично - в узком перешейке, соединявшем какой-то полуостровок с каким-то континентиком, встретились два барана (точнее, как мы их тогда называли, "экземпляры класса ТБаран"), каждый из которых шел к какой-то своей, одной ему понятной цели, уперлись друг в друга и мало-помалу померли с голода.
До нас дошло, что надо делать механизм обхода динамического препятствия, поскольку наша модель данных была построена так, что на одной клетке два существа поместиться не могли. Ходы они делали тоже поочередно, поэтому взаимный телепорт друг на друга тоже был невозможен. Решили пойти "индийским способом" - один из встречных превращался в случайный элемент ландшафта, через который можно было пройти, а после перехода деревце или пенек превращались обратно в кролика или льва и шли по своим делам. В таком виде мы и представили программу преподавателю.
Кто ж знал, что программа подкинет нам такой сюрприз! На узкой горной тропе встретились неудовлетворенный желудочно ТБаран и неудовлетворенный сексуально ТСлон. Как объекты для удовлетворения своих потребностей они друг друга совершенно не интересовали, поэтому представляли друг для друга просто препятствие. Всемогущий Рандом решил, что в этот раз слону придется полежать немного в качестве элемента интерьера, а баран пойдет дальше. Скрипт бодро превратил ТСлона в квадратный метр свежей зеленой травы, радостный ТБаран сожрал ее, навалил кучу и там же рухнул спать. Несчастного слона поминали всей бригадой, включая преподавателя.