Как стать автором
Обновить

Самые позорные ошибки в моей карьере программиста (на текущий момент)

Время на прочтение8 мин
Количество просмотров125K
Всего голосов 152: ↑142 и ↓10+132
Комментарии119

Комментарии 119

Я конечно не работал в этих ваших микрософтах с гуглами, но мне кажется самое ужасное в последнем примере это boolean originAtCenter.


ИМХО, надо либо не делать origin point вообще (как она и сделала), либо делать уже кастомным значением. Для полного ублажения пользователей можно сделать процентным :)


А так — ни то, ни сё и если кому-нибудь понадобится делать взаимодействие шарика с origin в центре и кубика с origin не в центре — он убьется.




Пока писал, вспомнил что моей самой позорной ошибкой было сделать неверный расчет цены на определенные штуки в некой билетной системе на день (из-за чего потом базу откатывали), так что может она и права, а мне ей советы давать не пристало, хз хз

Как можно «не делать ориджин вообще» мы же указываем координаты объекта в любом случае. Это и есть ориджин. Но он либо в центре, либо в верхнем левом углу
И зачем убиваться — играешь чисто с шарами все ориджины в центре. Играешь с шарами и кубиками, при этом тебе достаточно представлять их описывающими прямоугольники — у всех ориджины в углу. Играешь с шарами и кубиками и при этом нужно обрабатывать углы у кубиков — все равно убиваться. Убивайся по вкусу, хоть через разные ориджины, хоть через ориджин в центре и у кубика тоже.
НЛО прилетело и опубликовало эту надпись здесь
С триггером меньше считать. Могу предположить вариант автора оптимизирован.
Второе — банальная опечатка. Странно, что попало в топ ошибок. Такое случается со всеми и потом может жить в проде годами незамеченным, не то, что пройти ревью и тесты.

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

А можно подробности? Ни разу не видел подобного эффекта.

Странно, никаких письменных свидетельств не удается найти.
Специально сейчас ради такого дела задал вопрос на стриме профессионального геройщика и получил ответ, что да, было такое дело в ранних версиях то ли Возраждения Эрафии, то ли Клинка Армагеддона.
Баг касался только битв без участия игрока, поэтому прожил достаточно долго

Я рассчитывал, что в выводах она хотя бы упомянет, что не стоит называть переменные i, j, особенно, если речь в коде не про математику.

for (int i = 0; i < user->interests->length(); i++) {
  for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
      keywords->add(user->interests(i)->keywords(i)) {
  }
}


И там ошибки в синтаксисе


Где? Если ты про скобочки, то там может быть перегружен оператор круглых скобочек.
Когда пишешь реальный код для реального применения, то нужно зарубить на носу и всегда, повторяю, ВСЕГДА, писать так:
for (int interest = 0; interest < user->interests->length(); interest++) {
  for (int keyword = 0; keyword < user->interests(interest)->keywords.length(); keyword++) {
      keywords->add(user->interests(interest)->keywords(interest)) {
  }
}


Думаю, понятно, почему?
так я не топлю за i, j, k, я спрашивал, где синтаксические ошибки. Тогда уж лучше range based for, читабельнее и, в зависимости от реализации interests(), может быть быстрее
Надо полагать что в те времена range based for в С++ не было и в помине. Ведь она пишет еще про MySpace…

Такая схема именования всех запутает. interest должен быть элементом коллекции interests, а не индексом в ней.

+1. А индекс я обычно называю interestCounter
У меня самая страшная ошибка это когда я 2 ночь подряд писал API на сервак и дошло дело до файлов. Так как время поджимало перешел на продакшн, что делать конечно нельзя. И перешел в папку с помощью cd где остались от тестирования папки, которые хотел удалить и прописал rm -rf / Более я на продакшн не ходил.
НЛО прилетело и опубликовало эту надпись здесь

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

Консольный mc или WinSCP. С WinSCP плохо, что можно случайно нажать удаление (вроде в настройках правится)
У WinSCP были проблемы с производительностью, если в директории много файлов. При этом тот же Far с NetBox справлялся на ура. Ну и вообще там полно косяков было, когда в одной из сессий проблема с подключением (например, хост не отрезолвился) — блокировалась работа приложения полностью, и кнопка отмены не работала. Рекурсивная раздача прав/смена овнера чудесным образом пропускала часть файлов.
Но это у меня опыт с версией года 13-14 был, так что уже не актуально, скорее всего.

Не выношу консольную имитацию GUI. Консоль хороша для ввода команд и скриптов, а пытаться имитировать GUI сеткой из одинаковых символов — не лучшая идея. Настоящий GUI выглядит лучше, позволяет использовать шрифты разных размеров, лучше управляется мышью, поддерживает Ctrl + C/Ctrl +V, итд.


Плюс, в mc какие-то сочетания клавиш из каменного века и не работает нормально кнопка Esc.

За что минусы? Не труЪ линуксоид?
> поддерживает Ctrl + C/Ctrl +V

Так и консольная имитация GUI поддерживает.
Если вспомнить историю, то всё было ровно наоборот. Сначала появилась эта самая «консольная имитация GUI» — операторам первых ЭВМ были доступны физические кнопки и сетка из однотипных индикаторов сгруппированных по назначению.

Именно из-за таких случайностей переучиваю себя работать под обычным юзером с беспарольным sudo (на ввод пароля, все-таки много конуентрации уходит). Как минимум пару раз выручало.


А вообще из подобных косяков, хотел поменять права для скрытых файлов, начинающихся с точки командой типа: cd /var/myfolder; chown -R usr:usr .*
Команда быстренько пробежалась по всем папкам, включая "..".
Хорошо что это была чистая ОС и сервер только готовился к использованию — сервис не пострадал, но вот ssh вырубился намертво, и пришлось подрывать инженеров в ДЦ ехать (у самого пропуска не было). На следующий день задарил им по ананасу в качестве извинения.

Не вижу чем вам это поможет.
rm -f все делают пару раз в жизни. А локальные файлы и без судо можно удалить без проблем.
Это поможет тем, что потерять локальные файлы и потерять удаленный доступ к удаленному серверу, с его одновременным падением — немного другой уровень проблемы.
И да, если для вас является проблемой потерять локальные файлы, то задумайтесь о бэкапах, если это в вашем ведении.
У меня такая же хрень была — сделал chown root:root / на проде.

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

А, самое эпичное было то, что это была ночь перед моей свадьбой, и сидели с шефом примерно до 2 ночи, пытаясь что-то сделать (у меня была незавершенная сессия в WinSCP), но в итоге ничего не добились.
Прочитав ваш коммент, вспомнил еще одну историю, когда редактировал вручную /etc/passwd и в начале первой строки «root:root:...» поставил нечаянно какой-то символ.
В итоге юзера root не стало и sudo перестало работать. На сервер под user заходить мог, но никаких изменений вносить, естественно, не получалось. И в ближайшие сутки все обещало обрушиться.
Но в этом случае сервер был виртуальный, и удалось удаленно через гипервизор загрузиться с live cd, замаунтить раздел и вернуть root:root. Это был мой лучший урок «чем виртуальные машины отличаются от железных».

А для железных тоже есть аналогичные решения. Если только их безопасники не запретили...

переучиваю себя работать под обычным юзером с беспарольным sudo

Эм, а где вы научились работать под рутом? Сколько я помню Linux (с года этак 2006-го), открывать root-сессию без жёсткой на то необходимости, всегда считалось чем-то от чего в мире умирает один котёнок. Как, впрочем, и беcпарольный sudo.

Парольный sudo не очень сочетается с аутентификацией по ключам в ssh.
rm -rf /


Я когда с каким-то ембедедом работал, хотел снести с SD карты xloader с u-boot (чтобы залить свежепересобранный) и вместо sudo rm -rf ./boot (что было бы папкой /mount/boot) написал sudo -rf /boot

Потом полдня продолбал на то, чтобы все вернуть… так чтобы еще и пакетный менеджер не афигевал.
пол дня разве это время?
Я мог бы потратить это время на что-то полезное, ну или хотя бы на видео с котиками. А вместо этого занимался бесполезной работой. Уж не говоря о том, что то, что было бы готово через 30 минут было в итоге готово только в конце дня.
hahaha, classic

у меня на клавиатуре не всегда пропечатывалась точка
несложно догадаться, что в один раз вместо
rm -rf ./
в консоли оказалось
rm -rf /
Можно было писать
rm -rf .
, тогда ничего страшного не случилось бы
Привет яндекс.диск
интересно было почитать, особенно понравилось второе место, с этой ошибкой столько проблем было при изучении с++, эх времена

Это традиционная описка, проверку на которую должны делать все ide

Кстати, почему принято для счётчиков использовать i и j? Их же во многих шрифтах легко перепутать и не заметить.
Из математики еще пошло.
А шрифты — это как раз хороший тест, если можно перепутать, шрифт не подходит для записи кода.
Может всё-таки не подходят однобуквенные переменные, которые легко перепутать?)
Одно другому не мешает же.
Дело не в количестве букв, какой-нибудь оhfcjlocmpqw ситуацию не улучшит. Правильнее будет рекомендовать использовать термины предметной области, а там как раз зачастую те самые i да j и использованы.
Правильнее использовать логичные названия, типа keywordIndex, а не i или j
НЛО прилетело и опубликовало эту надпись здесь

Чем там гордиться? Тем, что такую специализированную оптимизацию поддерживать — запредельное зло?


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


Смотришь на такое и понимаешь: "работает — не трожь". Слишком долго и дорого это менять

Тю.


Ни выливания новой версии софта с крешем на старте и поломанным обновлением.


Ни забытого where в delete на проде


Ни "ой, я удалил settings.php на проде, никто доступ к базе не помнит?"


Ни "а давайте закомментим эти 50 тестов, потому что все совсем поменялось, а времени их править нет"


Какие-то ошибки в стране единорогов, блюющих радугой.


Тю

Просто она — старый опытный сотрудник, сменивший множество организаций с очень высокой конкуренцией (профессор — это тоже пример такой должности). Она прекрасно понимает, что и рассказ о собственных ошибках должен быть таким, чтобы её не в чем было упрекнуть. Одна овероптимизация в юности, один непродуманный интерфейс (зато похвасталась тем, что в итоге этим интерфейсом пользовались миллионы) и одна дурацкая опечатка, какие мы делаем чуть ли не каждый день. Учитесь правильной самокритике у успешных профессионалов.
Да Федор Михайлович еще когда…

— Надули Фердыщенка! Вот так надули! Нет, вот это уж так надули! — вскричал плачевным голосом Фердыщенко, понимая, что можно и должно вставить словцо.
— А вам кто велел дела не понимать? Вот и учитесь у умных людей! — отрезала ему чуть не торжествующая Дарья Алексеевна (старинная и верная приятельница и сообщница Тоцкого).
Напоминает анекдот о сотруднике, который в анкете в графе «недостатки» написал «очень много работаю и слишком доверяю начальству».
Хмм, анекдот. Примерно так в реальности и отвечают на вопрос «какие у вас недостатки» на англоязычных интервью. Другой вариант ответ «на должность старшего разработчика — фальшивю, когда пою в душе»
Только вот описанные ошибки могли помешать или даже помешали миллионам людей.
А ваши примеры — ни о чем, ну может кроме первой. Да и первая ни о чем.
Как говорится, если тебе не стыдно за свой старый код, значит, ты не растешь как программист — и я согласна с таким мнением.
Как же так, вы прожили жизни в написании кода и получается что теперь вам за него стыдно? Мне кажется «стыдно» тут не правильное слово. Или вы на работе дурака валяли, поэтому за такой код вам стыдно? Мне НЕ стыдно за свой старый код, поскольку я знаю сколько труда в него вложено. Даже если я сейчас знаю как сделать лучше — это еще одна возможность приложить свои усилия к работе. А вот стыдно пускай будет (должно быть) тем кто на govnokod.ru выкладывает чужой код и стебется над ним.
А вот стыдно пускай будет (должно быть) тем кто на govnokod.ru выкладывает чужой код и стебется над ним.
Серьёзно? Идея говнокода вовсе не в том, чтобы просто стебаться.
PS: О, его отмодерировали
Претензии не к идеи govnokod.ru, а к тому как его используют. И по статье разница между, «у тебя стиль кода невыдержан» или «глаза кровоточат глядя на это» все таки существенная. Тем кого устраивает такой нравственный облик, сложно что либо объяснять.
Были случаи когда туда «заготовку с листочка» выкладывали.
Странно что ошибку в апи не поправили сразу же, когда по идее юзеры должны были бы начать жаловаться неудобное управление кругом.
Ну и по идее можно было бы запатчить просто создав новый тип УстаревшийКруг и присвоить в него все уже созданные круги, и новый создать нормальным.

Вообще странный баг, если софтом пользуется большое количество пользователей, то первая линия была-бы завалена feature request'ами, а тут только через 10 лет фикс...

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


В отличие от моих прошлых ошибок, от этой пострадали не только мои коллеги, но и миллионы пользователей App Inventor. Многие из них были детьми или совсем новичками в программировании.


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

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

for (int i = 0; i < user->interests->length(); i++) {
  for (int j = 0; j < user->interests(i)->keywords.length(); j++) {


Давно отказался от i/j/k для счетчиков, и тем более, всяких s/l/n для переменных. Только осмысленные названия, вроде interestCount и interestIndex.
Всё-таки не на бумаге пишем, и мониторы давно не 40 и даже не 80 колоночные. Читаемость важна, и если не делать 150 уровней вложенности и 20 операторов в строке, места для человекочитаемых названий хватает. А после компиляции или минификации вообще все равно, какая длина имени была.

Кстати, насчет вложенности. На самой заре программерской жизни, написал как-то вложенные циклы — for i, for j, for k, а потом, когда начало верхнего цикла уже было тремя экранами выше, снова for i. Вот это было веселье для новичка отлаживать! Поведение совершенно дикое получилось. На всю жизнь запомнил, что так глубоко циклы вкладывать не стоит.

P.S. Хотя, это же упрощенный пример, вполне возможно, в коде автор совсем по-другому называла переменные.
Как-то раз попалась такая рекомендация (которй сейчас и пользуюсь при необходимости)
for(i..)
   for(ii..)
      for(iii..)

От опечаток, конечно, не спасёт, но сразу видеть глубину цикла удобно.

А после iii идет iiii или iv?

Дело вкуса. Если нет слишком большой глубины, то по мне — проще iiii. Или сразу i0..i3. Но больше 3 — это уже обычно очень хитрые случаи. Даже 3 попадалось только для работы с 3D-текстурами. Для разных задач проще разделить. Например i..iii для итерации по масиву и j..jjj для вычислений по конкретной ячейке. При большой разнице в грубине перепутать становится сложнее.
Например i..iii для итерации по масиву и j..jjj для вычислений по конкретной ячейке.

Да уж. Это настолько толсто, что даже кажется тонким xD

ix4
Ну фиг его знает, я вижу тут массу способов отстрелить себе что-нибудь простой опечаткой. Стоит случайно вместо iii написать ii, как жизнь заиграет новыми красками.
Их в любом случае хватает. Доводилось по запаре путать даже длинные и совершенно разные названия. Тут же разница заметна даже просто по длинне, что достаточно неплохо бросается в глаза.
Тут же разница заметна даже просто по длинне, что достаточно неплохо бросается в глаза.

Вот вы лишнюю букву в слове «длина» напечатали, и ничего, в глаза на бросилось :).
но сразу видеть глубину цикла удобно

man табуляция
И как она поможет различить переменные из разных уровней?
Называй переменными логичными именами и будет понятно, какая откуда и для чего.
хы, так тоже делал, но не от рекомендации, а сам пришел. Но это не лучшее.
Само собой. Это скорее «дёшево и сердито». Правильные имена — это хорошо, но не всегда удобно.
Для себя я еще вынес полезный совет из книги «Чистый код» Роберта Мартина — чтобы не делать много вложенности (не только в циклах, но и в конструкциях if), можно тело цикла оборачивать в функцию (а внутри этой функции будет второй цикл). Это повышает читаемость и уменьшает шанс на подобные ошибки.
Тоже соглашусь насчет осмысленных названий для счетчиков, сам так поступаю в подобных случаях.

В таких случаях главное в стек не упереться ;)
И в зависимости от языка может быть медленно. Всякие там паковки и пр.

Добро пожаловать в 2019, компиляторы уже давно умеют оптимизировать код
Такое «удобство» неминуемо стрельнёт себе в ногу.
Особенно если надеяться на умный компилятор:
ideone.com/ilKvzM
Use «inline», Luk.

Выше написал пример, где возможны всякие неприятные казусы.

Именованные переменные это конечно хорошо, но что насчет


for (auto interest: user->interests) {
    for (auto keyword: interest->keywords) {
        keywords->add(keyword);
    }
}

?


Ну а в идеале декларативно конечно:


keywords.extend(
    user.interests
        .into_iter()
        .flat_map(|x| x.keywords),
);

Как на cpp это выражается сходу не скажу.

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

UPD: Выше уже написали. Был невнимателен. Но очищать коммент не буду. Всякие «del» и «удалено» меня смущают больше, чем дублирующая информация.
Я думал это только я такой странный, что не люблю короткие имена даже для счётчиков. А насчёт конкретно i и j вообще ужасный выбор, т.к. их легко перепутать на многих шрифтах, не понимаю, как так исторически сложилось, что используют их.
Как же я люблю эту картинку!
Простите.
Нууу нее знаааюю…

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

Что касается кода который я писал несколько лет назад… Ну да, бывает такое, что благодаря опыту сейчас некоторые вещи выглядят диковато, но также полно мест, на которые я смотрю сейчас и думаю «Вау, нихрена себе, это я написал?». Походу мы с автором как-то очень по разному мыслим.
Да уж, позорно
Предлагаю под этим комментарием поделится своими «успехами» в денежном эквиваленте, мой суммарный урон который нанесен работодателю за 10 лет: 1200$
что-то мало. Как рассчитывался урон? Он включает в себя только стоимость исправления ошибки? Или есть еще репутационные издержки, недополученная прибыль из-за плохой репутации?
Урон рассчитан по себестоимости использованных материалов + временные затраты + утилизация ненужного изделия. Репутация работодателя не пострадала. Исправлялась ошибка с горящим стулом, бесплатно )
Вы серьзно? У вас завышено чувство вины. Не смешите копейками. Такими суммами можно смело гордится. Кривая морда и дурной характер могут куда больший урон нанести, если на нее клиент натыкается.
Чем оптимальнее код, тем сложнее его поддерживать
Чем проще код, тем его проще поддерживать
Простой код не оптимален, а значит требует больше ресурсов
Отсюда вывод — чем больше ресурсов потребляет код, тем более он поддерживаемый
Исключение из правил — MS Windows
С прискорбием вынужден не согласиться. Нередко код потребляет много ресурсов не потому, что он простой, а потому, что он одновременно сложный и неоптимальный.

Меня больше удивляет, что такой код (никем не тестированный и написанной сырой программисткой) попадает в прод. А мы потом ругаемся на качество ОС Windows или студию. Так все же закономерно: просто разработчик сэкономил на тестерах и на кошечках, т.е. на нас, пользователях, проверяют новую версию...

На самом деле нужно было указать x- и y-координаты центра круга, как этому учит любой учебник математики и любой другой источник, упоминающий круги.

Но надо оперировать не только шариками, но и звездочками, линиями, и вообще произвольными растровыми изображениями. Специальный паттерн описания круга — разрушает целостность подхода к управлению спрайта! Почему было не сделать маску (тень) объекта — которая определяла бы где объект спрайта, а где уже нет? Причем, эту маску можно было бы вычислять автоматически (если пользователь ее не задал) или использовать преопределенную пользователем! Мне кажется, что как раз выпуск патча, описывающий круг как специальный объект, — ошибка. А действительно полезный патч, был бы добавление маски к спрайту. Причем он бы не ломал совместимости со старыми приложениями, ведь если маски нет — ее создают автоматически.

Не совершает ошибок тот, кто ничего не делает.

А используй они PVS Studio, на одну ошибку было бы меньше…
Есть ошибки на которых многие не учаться. Например не использование TDD ошибка, но это мало кого заставляет изменяться пока что-то в проде не отвалиться. Тогда возможно программисту станет ясно, что если бы он меньше думал как оно будет работать, а больше о том как проверить результат работы, то ошибку бы не пропустил уже на уровне написания кода.
Есть ошибки на которых многие не учаться.

Правописание "*т(ь), *т(ь)ся", кстати, тоже к ним относятся.

если с "ь" и без текст работает одинаково, то ничего менять не нужно ))

По-разному работает. Сразу не доверяешь мнению человека, который школьные правила освоить не в силах.
Kак вам повезло что тут ресурс для программистов и кроме знаний русского и немного программирования больше ничего не нужно показывать, но в школьном курсе есть другие предметы и вот тут не факт что вы выучили больше чем я :P
В метрополитене лет 15 назад, когда вводили бесконтактные билеты заметил, что если приложить билет одновременно: я к одному турникету, другой пассажир в другой турникет, то проходит только один, у второго ошибка возникала и нужно было либо еще раз приложить, либо подождать 7 минут, если билет безлимитный. Наверное, программист чувствовал в тот момент, когда обнаружили ошибку: анти-Робин Гудом, можно сказать все пассажиры вложились в его обучение.

была интересная история про то, как в большой компании выбирали между Linux и Windows для постройки инфраструктуры с нуля. Выбрали Windows, потому что в тестах Oracle на ней стартовала на 30 секунд быстрее. А через пару лет админ залез в скрипт запуска базы на Linux и нашел строчку sleep 30.

Самая моя большая ошибка, это просидеть 3 года в компании, занимаясь реализацией скриптов для сборки проектов и их тестирования. 3 года моей жизни просто в никуда.
devops, 3 года опыта. Звучит неплохо на первый взгляд.
НЛО прилетело и опубликовало эту надпись здесь

Блин, а ведь это не баг а фича, чуваки расслабились и втянулись, а потом закономерно все слили.

та ладно. мне как-то пришлось откатывать банковскую бд на бэкап четырехчасовой свежести и около сотни сотрудников переделывало свою работу второй раз.
НЛО прилетело и опубликовало эту надпись здесь
От статьи ощущение, что автор про эти свои «ошибки» HR'у рассказывает при приеме на работу.

Это все равно что на вопрос «назовите свои худшие качества» ответить — я трудоголик и перфекционист! (вместо лентяй и рукожоп)
Нет чтоб написать — неправильно поделила 4 на 2 и это из-за меня взорвался «Челленджер».

ЗЫ Меня в микрософт работать не взяли, поэтому ошибки поэпичнее: неправильно проинициализировал выходные регистры в регуляторе тока — в результате сгорели все огни ВПП на аэродроме. Потом через несколько лет из-за косяка стерлись все видео у какого-то телеканала )
Насчет координат круга в левом верхнем углу описанного квадрата — это боль. Боль, которую знает каждый, кто хоть раз рисовал круги в mspaint. Видимо, в MS тоже есть такой злодей, но он своих ошибок не признает, очевидно. Потому что столько лет прошло, а воз и ныне там.

Одной из позорнейших моих ошибок было изменение кода поля ввода пароля в приложении ВК для iOS. Тогда началась мода на то, чтобы можно было показывать пароль в закрытых полях (понять, что ты ввёл вообще), и я решил «ну а что бы нет», хотя это делать было вообще не нужно («работает, не трожь», да да) и задачи тоже не стояло.
Я запилил красивый глазик рядом с полем пароля, протестил и всё было ок. Влил код в dev ветку, затем он ушёл на прод. И началось… Приложение крашилось тысячами раз. Куча людей просто не могли зайти в вк из-за меня. Трейс краша, однако, был совсем ничем не намекающий на проблему.
На моем девайсе, конечно же, работало, как и на девайсах людей вокруг. Думали, что iOS как-то в этом замешана, людям помогал сброс настроек телефона.
Когда мы нашли девайс, на котором воспроизводится, я обнаружил, что ошибка была невероятно тупейшей. Дело в том, что Objective-C код использует подсчёт ссылок. Он может быть ручной или автоматический. Тогла приложение ВК ещё использовало ручной, тк проект уже было довольно большой, мигрировать все было немного опасно и проблематично.
Так вот, когда я добавлял функциональность, в одном месте мне нужно было вернуть значение поля пароля, строку (я слегка хачил и наследовался от класса поля ввода, нужно было переопределить некоторые методы). Код был примерно такой
-(NSString*) text { return _textValue; }
Короче, из-за ручного подсчета ссылок ось ожидала получить «дополнительно retained объект», и делала этой строке release (счётчик -1). Дальше строка высвобождалась и всё становилось плохо, sigsev все дела.
Решение было простое, использовать [_textValue copy], чтобы вернуть «новую строку» (на самом деле, возвращается та же строка, просто счётчик +1).
Было очень обидно, потому что сначала я искал проблему в другом месте, и мы даже выпустили промежуточную версию с «теоретическим» исправлением бага, который ничего не исправлял :(

Самая глупая ошибка: функция вида bool IsBusy {return IsBusy}. Это был промышленный сервер Oracle. Он продержался 15 минут и упал. Никто ничего так и не понял. Мне стало стыдно, а я ничего никому не сказал, молча исправил. Перепутал имя функции и переменной (должно было быть что-то вроде return vIsBusy)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий