Fail review: о проблемах в разработке и методах их решения

[«Fail review» — это сборник историй о рабочих провалах: что произошло, как исправляли и какие выводы сделали. Если есть, чем поделиться — приглашаем присылать свои истории на  Данный адрес e-mail защищен от спам-ботов, Вам необходимо включить Javascript для его просмотра. ]

Игорь Зенич, Frontend Developer в EPAM

В середине нулевых я участвовал в разработке сайта для онлайн-обучения. Основным контентом были видео-ролики с лекциями. Быстрого интернета тогда в Украине еще не было, и мы получали почтой DVD-диски, которые потом конвертировали в нужные форматы и заливали на сайт.

На тот момент я буквально месяц как пришел работать в компанию, которая занималась этим проектом. Кое-какой опыт работы с видео у меня был, и мне поручили задание — перекодировать видео из DVD в другие форматы. Задача была срочной, и в спешке я сделал ошибку в скрипте, в результате которой на видео исказились пропорции сторон. Лекторы стали выглядеть толще килограмм на 15 :)

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

Я задумался, как мне быть. Расскажу о баге — придется выслушивать от шефа, что опозорил компанию перед клиентом. Тем более, я сам еще на испытательном сроке. И не сказать — тоже не вариант, потому что рано или поздно все равно обнаружат, и будет еще хуже. Решил, что всё-таки надо признаваться. Подошел к шефу, говорю, так и так, такая вот штука. А он в ответ: «А, и фиг с ней, не парься. Исправим, найдем способ». У меня сразу гора с плеч.

Исправляли долго: часть видео перезаливали заново, для части писали костыли. Сидели ночами, но сделали.

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

Андрей Губский, CTO Торф

История № 1: Не работайте с клиентами, которые не осознают своих желаний

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

Слово «стартап» сейчас очень модное. И среди ваших друзей и знакомых точно есть кто-то, кто уже пробовал запустить свой проект или даже предлагал вам стать ко-фаундером. Такая же история произошла и с моим товарищем. Пришёл к нему потенциальный клиент и попросил разработать, ну, скажем, клон Facebook. Идея вроде неплохая. Выход на IPO спланирован, список, куда потратить миллиардные доходы, уже написан. Осталось дело за малым — заказать софт, который и позволит в считанные дни заработать эти самые миллиарды. Инвестиции в новый стартап клиент тоже подготовил — гигантскую сумму в 5000 евро. Ударили по рукам, закипела работа.

Вот только убийцу Facebook сделать не удалось ни через планируемые 3 месяца, ни через полгода. А когда для ускорения процесса разработки была привлечена дополнительная команда, и клиенту был выставлен счёт за проделанные работы — выдержке его пришёл конец. Мало того, что ожидаемые миллиарды не появились, Forbes не стал брать интервью, так ещё и затраты оказались в несколько раз выше, чем планировались. И если для тех, кто знаком cо спецификой рынка ИТ, данная история — одна из тысячи подобных, и каждый, кто довольно давно работает в этом бизнесе, понимает, что на один выстреливший продукт может приходится до сотни неудачных, то для нового человека это может быть шоком. Ведь именно он автор гениальной идеи, и именно он заработает завтра свой первый миллиард.

Выводов из этой истории два:

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

Вывод второй — не работайте с людьми, которые не осознают своих желаний. Мало прийти в компанию по разработке ПО и сказать: «Я хочу второй Facebook». Клиент должен понимать законы индустрии, в которую он входит, осознавать, что и для чего ему нужно.

История № 2: Не гонитесь за большим количеством фич

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

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

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

Стоит ли говорить, что большую часть времени и ресурсов мы потратили не на стабилизацию и отладку продукта, а на реализацию безумного количества возможностей, из которых больше половины никогда и никем не использовались?

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

Денис Резник, Data Architect в Intapp

Когда-то давно мне посчастливилось работать на одном интересном проекте. Проект представлял из себя доску объявлений, которая в то время входила в топ-10 по США и имела неплохой трафик. Вы удивитесь, сколько интересного было под капотом, казалось бы, обычного проекта, но история не об этом. История об IpBanner — одной из подсистем проекта, назначением которой была борьба со спамерами.

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

Вопросы были из разряда : «Как вас зовут?», «Где вы живете?», «Есть ли у вас машина?» и т.п., и так около 10 вопросов. В конце опросника показывалось сообщение, что хватит нас спамить, мы собрали о вас информацию и передали ее в ФБР, теперь вас разыскивают :) Не знаю, кто и когда это придумал и сделал, но я всегда находил эту фичу очень забавной. Ровно до того момента, когда как-то вечером в пятницу мы не выкатили код, который стал кидать всех пользователей из Индии (или вообще всех пользователей, уже не помню) на страницу /potsnewad :)

Было много звонков в службу поддержки, один человек (судя по слухам) даже позвонил в ФБР и спросил, почему его разыскивают. В понедельник утром владелец сайта попросил полностью выпилить из проекта IpBanner, что мы и сделали.

Мораль истории: не держите на сайте опасный функционал. Если он уже есть — избавьтесь от него, по возможности, быстро. Не искушайте судьбу.

Сергей Сыроватченко, SQL Server DBA

Когда меня попросили рассказать несколько историй из жизни, то немало времени было отдано на раздумья о том, в каком эмоциональном ключе это сделать. Чаще всего природа технических проблем на проекте возникает из-за плохо налаженной коммуникации между людьми или нежеланием отдельных коллег прислушиваться к мнению специалистов. Также может встречаться ситуация, когда нельзя заранее все предусмотреть вследствие стохастической природы R&D разработки, т.е. когда клиент сам не знает, что он хочет.

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

Первый показательный случай произошел еще на первом году моей работы. У нас был DEV сервер с SQL Server, в котором вся дисковая подсистема была завязана на одном RAID 0 (про то, что на серверную стойку капал конденсат, я умолчу). Резервные копии делались админом регулярно и складывались на удаленном сетевом диске. В один прекрасный момент одно из заданий стало завершаться с ошибкой, в котором делалось обращение к dm_db_index_physical_stats. Сделав выборку из этого DMV, я увидел, что один из некластерных индексов был поврежден.

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

Через неделю утром некоторые коллеги не могли подключиться к этому серверу. В список счастливчиков я не попал и смог разобрался в том, что побилась таблица sys.sysxlgns в базе master. Восстановление из резервной копии проблему не решило, поскольку дисковый массив периодически уходил на покой.

Последствия этой истории таковы: 4 часа down-time, за которые мы всей фирмой хорошо поиграли в теннис. За это время вспомнили про мое письмо с просьбой о новых дисках, и ко мне стали чуть больше прислушиваться. А еще через неделю у нас появился новый DEV сервер. Happy end...

Вторая история чуть веселее. Во всяком случае, мне это кажется забавным до сих пор. С коллегой мы сканировали зарубежные интернет-магазины. На очередном митинге клиент попросил делать на его iPhone почтовую рассылку и показывать основные ценовые тренды. Чтобы не нагружать коллегу, решил все быстро — генерировал HTML с помощью FOR XML PATH и отправлял письма через DatabaseMail.

Через пару недель клиент попросил к письму прикреплять файлы с Excel. В это время коллеге еще докинули работы, поэтому решил опять отделаться малой кровью — с помощью bcp генерировал Excel файлы и с помощью опять того же DatabaseMail доставлял нотификации клиенту. Потом был еще один интересный случай — клиент попросил, чтобы ячейки в Excel файлах были разукрашены в разные цвета. Вот так невинно был развернут SSRS, и через него начала делаться почтовая рассылка. Я думал, что на этом все... Но нет.

Хардкор на T-SQL начался после очередного реквеста: «А можно мне в письме еще и графики показывать?». Печаль в том, что не все почтовые клиенты (особенно мобильные) поддерживают JavaScript, поэтому пришлось использовать ImageChartsAPI от Google и генерировать особую ссылку, которая возвращала бы при открытии письма картинку с графиком.

Все всех устраивало, но потом данных для визуализации стало больше, и клиент попросил увеличить размер графиков. Размер возвращаемой картинки в ImageChartsAPI имеет строгое ограничение (сейчас точно не вспомню, сколько) и пришлось выкручиваться. На этот раз решили потратить больше времени на эту задачу и написали свой сервис, который подключался в качестве CLR библиотеки к SQL Server. Я передавал в виде XML, какой график мне нужно сгенерировать, и на выходе получал картинку в base64, которую затем вставлял в тело письма. Вот такой вариант почтовой рассылки работает до сих пор.

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

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

Можно было радоваться, но в плане поддержки этого кода программисты плавали и попросили все хранимые процедуры сделать более универсальными — вынести похожий код в функции. Есть хорошая фраза по этому поводу: «Универсальный код работает универсально плохо». Да... Сократили количество строк в отчётах и выиграли в сопровождении кода на T-SQL, но серьезно проиграли в скорости.

Все потому, что программисты часто проецируют свой опыт из ООП на работу с базами данных. Если говоришь, что скалярные функции — это зло, то зачем упираться? Бездумно использовать INSERT EXEC, если тебе уже сказали, что результаты выборки могут вначале временно материализоваться в tempdb, а уже только потом вставляются в целевую таблицу. Parameter sniffing и постоянная рекомпиляция плана — «Не, не слышал». Чего говорить про использование курсоров с поводом и без... Как мне сказал один коллега: «Мне просто так понятнее, чем WHILE и пакетная обработка».

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

Никита Галкин, System Architect в Ezetech

В СССР последний пункт в любой инструкции по сборке:
«Обработать напильником»

Обычная ситуация: в последний момент от заказчика прилетели новые требования. На первый взгляд простое требование изменить на фронтенде формат отображения дат в графиках с 26.01.2017 на 26 Jan. Проблема в том, что формат даты захардкоджен внутри библиотеки, которая имеет третий уровень вложенности. Инженеры спорят, как и с какой библиотекой переписывать. Уже рассматривается вариант отключить CI и залить костыль руками. PM пьет валерьянку и не знает, как объяснять клиенту, что тут сложного. В общем, атмосфера гнетущая.

Обычно в историях в комнату заходит консультант/менеджер/девушка/коллега-из-соседнего-отдела и дает совет. К нам пришел «Пофиг». Так появилось решение — после установки зависимостей в postinstall скрипте поправить код требуемой библиотеки. Так сказать, «обработать напильником».

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


Если есть желание рассказать свою историю — приглашаем присылать текст на  Данный адрес e-mail защищен от спам-ботов, Вам необходимо включить Javascript для его просмотра.

Похожие статьи:
У 2024 році резиденти Дія City сплатили понад 18 мільярдів гривень податків. Це майже вдвічі більше, ніж у 2023 році, коли сума становила...
П’ять років тому я закінчила бакалаврат механіко-математичного факультету КНУ. Хотіла займатися застосуванням математики...
Три роки тому на DOU вийшла стаття про DevOps Олександра Квятковського, на той момент системного адміністратора...
Меня зовут Гена, я занимаюсь автоматизацией тестирования с 2003 года (т. е. начинал ещё до того, как это стало...
In 2019, if you want to play free Nintendo DS games, which r4 3ds card will you choose? r4i sdhc 3ds rts? r4i gold pro? or r4i gold 3ds plus? we all known that r4i 3ds gold plus is a special...
Яндекс.Метрика