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

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

503

А тем, кто не поймет, он откусит ногу

Разрабатываем одну большую корпоративную систему - огромная база данных, большие нагрузки на сервера ну и веб-интерфейс, куда ж без него. Интерфейс этот пишется с использованием одной библиотечки, которая в свою очередь вовсю использует AJAX. Библиотека open-source, но как-то раз преподнесла совершенно неожиданный сюрприз.

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

/**

* @return

* @see #getPage()

* @deprecated

*/

public int getPageIndex() {

return getPageIndex();

}

Вот оказывается как надо объявлять метод устаревшим, чтобы его впредь больше никогда не использовали!

500

Глобально, на века!

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

Есть на одной из форм поле "Дата рождения". Во время тестирования было выяснено, что значения туда могут быть введены уж очень фантастические (люди столько не живут), крайней датой, которую можно сохранить, было 1 января 1573 года, после крайней даты система вываливала страшный ексепшен.

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

В следующей версии приходит фикс. Иду проверять, ввожу какую-то, совсем уж мохнатую дату, на что получаю "user friendly" сообщение:

"The date should be between January 1, 1753 and December 31, 9999"

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

495

Чтоб под руками не мешалось

Пришёл к нам парнишка на испытательный срок. Теория от зубов просто отлетает... А вот как садится что-то делать, вечно что-то отмочит: то в sql where код группы товаров с кодом площадки приравняет, то ещё чего.

Один раз такой случай был. Дали парню написать одну задачу. Сделал, значит, и несёт руководителю отдела на проверку (я рядом сижу). Написал что-то типа:

declare date_1 DATE; date_2 DATE;

...

select ... into date_1 from ......;

select ... into date_2 from ......;

select ... where some_date between date_1 and date_2;

Ему говорят: "Не мучай сервер несколькими запросами, заверни всё в один запрос, а переменные убери" (там это можно было сделать очень логичным образом). Парень подумал-подумал и уточнил: "Ну, одним запросом я сделаю... А куда мне переменные девать?"

Мы с нач.отдела не выдержали и почти хором ответили: "Ну удали, что ли?"

491

Клиент-серверная модель по-государственному

#482 навеяло...

Некоторая конторка подвизалась для одного из округов большого города сваять систему расчета коммунальных услуг населению. Умолчим про то, что она была написана на MS Visual Basic for Applications., а потому требовала на машинах Клиентов в обязательном порядке MS Office. Сама база лежала на MS SQL, клиенты цеплялись к базе напрямую. И как-то в том округе сложилось, что сервер был несколько слабее рабочих станций, и потому были написаны гениальные перлы. Загружаем, например, все на рабочую машину в память (SELECT * FROM) - потом считаем. Распечатать квитанции за месяц - да пожалуйста, тем же SELECT * FROM надергали из массива в шаблон отчета - печатайте!

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

А сервер с четырьмя гигами оперативами и двумя Xeona`ми по 3ГГц стоял в сторонке и спокойно отдыхал...

Русский деревенский код.

488

А это аппендикс, он не пролезет

Истории о гигабайтах мусора навеяли.

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

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

482

На том свете разберутся

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

До тех пор, пока делались сайты-визитки и прочая мура с ежедневным числом до ста человек, все было хорошо. Но тут нарисовался заказ на переделку движка одного тематического новостного сайта, на котором было от 15 до 30 тысяч посетителей в сутки и размер дампа базы новостей был около 300 мегабайт.

Движок переделали под требования заказчика, на стадии тестирования все прошло отлично — отправили в релиз. Через 10 минут после запуска — звонок с истошным воплем заказчика: "На вашем сайте вирус и он сломал нам сервер!!!". И действительно, минут через 10 после включения сервер с хостящимся сайтом переставал отзываться на внешние раздражители, разве что пинговался. top и ps, запущенный на серваке, показывали сумасшествие mysqld, который с потрясающей скоростью отбирал под себя проценты CPU и мегабайты памяти. my.cnf был перелопачен вдоль и поперек — без толку.

От безысходности залез в код движка — и вот тут волосы встали дыбом, стул подо мной сломался. Обращение к БД было реализовано весьма оригинальным способом — SELECT * FROM список_таблиц, а уже потом из такой вот 300-метровой глобальной переменной вычленялись необходимые компоненты.

473

Точное моделирование

В свое время был начальником отдела разработок в студии %studioname%. Делали браузерные игры. Дано: вероятность попадания в противника из лука (в процентах). Написать: скрипт, который бы выдавал — было ли попадание или нет.

Как в таких случаях действует обычный Coder Sapiens, если нет особых требований? Генерит случайное число от нуля до ста и проверяет, меньше оно вероятности или нет.

Но один эксцентричный паренек пошел другим путем. Одним циклом for он создал массив из десяти тысяч нулевых элементов (так как проценты с сотыми долями), вторым циклом он заменил первые надцать (т. е. процентов без точки) элементов единицами. Потом скормил массив шаффлу и взял первый элемент массива.

470

А вдруг его увидит браузер?!

Полгода назад работал в одной маленькой веб-студии.

Программистов было двое: я и ещё один юноша. Юноша - студент, но толковый и нелепых ляпов не допускал.

До поры.

Как-то раз сидит, пишет что-то, ругается сквозь зубы. В конце концов зовёт меня. Запрос, говорит, не работает. Я ему советую распечатать запрос - сразу, мол, поймёшь, что не работает. Распечатывает, вставляет в phpMyAdmin. Работает!

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

$query = "SELECT * FROM ..."

Зачем, спрашиваю? На что он мне так основательно отвечает: на всякий случай, мол, мало ли что...

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

забыв поменять в следующей строчке ">>" на ">"

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

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