29 мая 2010 г.

90% кода в интернете - говно

Дополнение к предыдущей заметке.

Предварительное примечание: Моё определение "говна" может не совпадать с вашим. (С) Ларри Остерман. Пожалуйста, дочитайте до конца, чтобы увидеть, что я имею ввиду. Я не имел цели оскорблять кого-то или чью-то работу. Это просто рассуждения по поводу сложившейся ситуации и типичных практик.

Задаёте ли вы вопросы на форумах? Или же ищите ли ответы на них в поисковиках или в FAQ (типа DRKB или Delphi World)? Если да, то копировали ли вы к себе в программу код из ответов? Производили ли вы переписывание или хотя бы анализ кода, перед тем как это сделать, или же дело закончилось отпиской "огромное спасибо, этот код подошёл!"?

Если вы ответили да, то вы только что создали говно-программу, в которой участвует говно-код (*).

Сейчас я поясню, почему это так.

Что такое ответ на форуме, в котором приводится код для решения проблемы? Я уверен, что вы получаете ответы на свои вопросы на бесплатных форумах, что означает, что отвечающий вам человек никак не мотивирован в предоставлении вам наилучшего отлаженного и универсального решения. Он просто берёт какое-то решение или состряпывает его тут же и даёт его вам. Это - сырой полуфабрикат, решение, написанное "на коленке". Просто пример, показывающий как добиться желаемого, иллюстрация решения проблемы. Это не готовый код, который можно взять и вставить в свою программу, как вы обычно это делаете. Почему? Позвольте, я отвечу на этот вопрос чуть позже. Чтобы не быть голословным, я разберу ниже несколько примеров. Но это не останавливает людей от использования такого кода в реальных проектах.

Что такое FAQ? Это сборник ответов на самые популярные вопросы на форумах. Иными словами, это просто некое "избранное" веток с форумов. Откуда что следует? Что качество кода в FAQ равно качеству кода на форумах. Это не сборник рецептов, как многие привыкли думать, бездумно копируя куски кода из FAQ. Это ответы на "Часто Задаваемые Вопросы".

Критической стадией этого заблуждения является появление книжек вроде этой. Узнали? Довольно известная книжка. На одном моём давнем месте работы был её экземплярчик, который постоянно использовался как "книжка рецептов", отчего был весьма потёрт. Печально, скажу я вам.

Ещё одной проблемой FAQ является копирование материала из старой версии FAQ в новую. Это приводит к повсеместному распространению кода времён хорошо если Win9x, а в худшем случае - и Win3.11.

Я не хочу сказать, что эти книги и FAQ плохи сами по себе. Нет, это отличные сборники советов (окей, не в случае Win9x/Win3.11) - большой респект их авторам, потратившим гору усилий на прочёсывание, сортировку и поиск вопросов и решений. Проблема в том, что их используют неправильно. Указанные проблемы вполне допустимы в примерах, который демонстрирует последовательность вызовов функций, но совершенно недопустимы как готовое решение в реальных программах. У меня не было бы вообще никаких претензий, если бы из них убрали готовый код, вставив вместо него текстовое описание. Это хотя бы не дало вам заниматься Copy&Paste.

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

1. Пример 1 - код с запуском консольной программы и чтения его вывода. Считай, классическая задача в исполнении Zarko Gajic - опять же, не самой безызвестной личности (в англоязычном интернете). Я прошу прощения за англоязычный пример, но просто я совсем недавно увидел, как кто-то рекомендует этот код к использованию на StackOverflow (автор вопроса ответил "Очень полезный код, он решил мою проблему, спасибо"). Вы можете выбрать аналогичный код из вашего любимого FAQ или форума - результат будет примерно аналогичным. Что мы видим в этом примере? Да вот хотя бы: что будет если вы передадите имя несуществующей программы? Хм, ну наверное CreateProcess вернёт False. Закроем пока глаза на отсутствие контроля ошибок (а это ещё одна проблема с этим кодом!), что у нас идёт дальше? CloseHandle на поля TProcessInformation. Но если процесс не создан, то что у нас будет там? Не закроют ли эти вызовы CloseHandle какие-то произвольные описатели в нашей программе? Это было бы просто ужасно. К счастью, конкретно CreateProcess обнуляет последний параметр до проверки параметров, но это - недокументированная деталь реализации (см. ниже перечисление типичных проблем с кодом). Это пример частой ошибки при вызове функций. Другие функции не так милы, что обнуляют нам параметры при неудачном вызове (если это не часть протокола, конечно же). Ладно, если вы не слишком опытный программист, вы можете не проникнуться этим примером, давайте перейдём к чему попроще, поочевиднее.

2. Пример 2 (читайте пожалуйста, только первые три сообщения - которые снизу, это для последовательности изложения; всё, что выше, я и так скажу здесь) - ещё одна "классическая" задача: выключение Windows. Целых два примера кода (первый - со ссылкой, второй - прямо в вопросе). Оба варианта кода никак не проверяют результат выполнения ExitWindowsEx. Что означает, что если мы делаем shutdown и тут же выходим, то в ситуации когда ExitWindowsEx провалится (например, мы запущены под учёткой без права на перезапуск), мы просто вывалимся (ничего не сделав) вместо того, чтобы продолжать работу. Более того, мы никак не указываем, почему же мы ничего не сделали. Для пользователя программа просто втихую перестаёт работать (не выполняет своей функции) и нет никакого способа узнать, что же пошло не так. Далее, в обоих вариантах кода утечка описателей. Мы открываем их, но никогда не закрываем. Конечно, если вы убиваете свой процесс сразу после выхода из этой функции, то это не будет иметь значения. Но если вместо этого вы ждёте стандартного уведомления о завершения работы, а оно по какой-то причине не пришло (например, вызов ExitWindowsEx оказался неудачен - напоминаю: вы не проверяете её результат; или же другой процесс отменил завершение работы до того, как вы получили уведомление) - то вы получаете утечку ресурсов. А потом вы будете удивляться, а чего же это моя программа так много жрёт памяти после нескольких часов/дней работы. Ещё одна частая проблема подобных примеров - если какая-то обработка ошибок всё же стоит (не в этом примере, но в других), то проверка правильности выполнения AdjustTokenPrivileges выполняется не верно: недостаточно просто проверить результат функции, надо ещё и GetLastError смотреть. И почти нигде вы не увидите отключение привилегии после вызова ExitWindows(Ex). А ведь это базовый принцип использования привилегий! Вы включаете привилегию, выполняете функцию, её требующую, и отключаете привилегию.

3. Пример 3 - пример из FAQ, который был написан 1 раз во времена Win95 и кочует неизменным по всем FAQ и ответам на форумах до сих пор. Несмотря на то, что в линейке NT он не работает. Почему? Потому что HKCR - это не настоящий ключ реестра, это комбинированная проекция подключей из HKCU и HKLM. По одной только этой причине в него не стоит писать - кто знает, куда пойдёт ваша запись? Но это не самое главное. А главное в том, что HKLM - это глобальные настройки всех пользователей. Что это значит? Во-первых, что для их изменения нужны права администратора. Во-вторых, что изменения, вносимые вами, затронут всех пользователей. Сравните это с HKCU - это лично ваши данные и вам не нужны никакие особые привилегии, чтобы туда писать. Эти моменты обычно не замечают при работе в Windows XP или младше - потому что обычно вы работаете под администратором. И подобный код, хотя он неверен (окей, он корректен технически), будет отрабатывать успешно и давать вам, что вы и хотели. Но стоит вам запустить программу под обычным пользователем (на любой Windows, включая Windows XP) или как обычный процесс (без элевации) на Windows Vista и выше с включенным UAC - как этот код весьма впечатляюще вылетит с ошибкой. И хорошо ещё, если эту ошибку вы обрабатываете - ещё один больной вопрос подобных кусков кода (в примере по ссылке ничего такого нет!). Философский вопрос: если что-то никогда не работало, является ли багом то, что это не работает сегодня? Ну, а что с этим делать? Правило простое: регистрацию ассоциаций должен выполнять установщик программы, а не сама программа. Точка. Пример: при установке программы, установщик, который работает под админом, должен зарегистрировать программу в HKLM\Software\Classes - он сможет это сделать, потому что он запущен под админом и у него есть права на запись в HKLM. Если установщик не работает под админом (ужасно редкий случай, но всё же) - пишите в HKCU\Software\Classes. В дальнейшем (при штатной работе), вам не следует писать в \Software\Classes. Если сильно охота - пишите в HKCU\Software\Classes, но не трогайте HKLM.

4. Пример 4 - ещё один пример из динозаврических времён, заполонивший интернеты. Проблема примера заключается в использовании поля shi2_permissions для установки права "Полный доступ" на файловую шару. Что здесь не так? Да то, что согласно MSDN, это поле работает только для "servers running with share-level security" (серверов, работающих с доступом уровня шары). А что это за сервера? А это Windows 95, 98, ME (ну и мож ещё кто не из семейства Windows). Windows NT, 2000, XP, Vista и 7-ка используют обычные ACL - "user-level security". Выход? Использовать другой вариант структуры, в котором есть привычный нам security descriptor - например, SHARE_INFO_502. Вот более подробное обсуждение с решением.

5. Бонус-пример - код-решение для Base64 из моего предыдущего поста, попадая под категорию "опубликовано в интернете", также является говно-кодом. Почему? Потому что я выдрал этот код из рабочего проекта без малейшей попытки адаптации. И потому что это была просто демонстрация другого подхода, способного дать лучшие результаты (читабельность и скорость), чем оригинальный бажный код. Я руководствовался ровно теми же побуждениями: показать пример решения. У меня не было ни малейшего желания вылизывать за кого-то код. Но что же не так в том коде? Обработка ошибок. Этот код спроектирован так, чтобы втихую ничего не делать при ошибках. Это было целью в проекте, откуда он взят, потому что этот код вызывается в обработчиках ошибок. Вероятно, это не лучшая идея для кода общего назначения. Поэтому, прежде чем использовать этот код, пройдитесь по нему, расставив обработку ошибок. Будет хорошей идеей возбуждать исключение при неверном входном потоке данных, вместо молчаливого игнорирования.

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

Это, мягко говоря, не так.

Во-первых, как я уже сказал, я вовсе не говорю, что эти куски кода плохи сами по себе. Даже если они содержат явные ошибки (обычно: по недосмотру, а не фундаментальные). Потому что это примеры. Вот она, ключевая фраза. Примеры, примеры, примеры. Если вы смотрите на этот код как на примеры - нет никаких проблем. Это просто отличные куски кода. Но если вы вставляете этот код в свою программу, то это - говно. Всё зависит от контекста. Фраза "весь код в интернете - говно" означает, что не стоит брать код из интернета в свою программу, а вовсе не то, что код плох сам по себе. Надеюсь, смысл заголовка поста прояснился (уф, это заняло немало времени).

Во-вторых, относительно заявления о ненужности педантичного разбора якобы "годного кода" - ну да, а потом вы будете удивляться, а чего это моя программа выдаёт Access Violation на соседней машине или временами виснет намертво? А вот ещё пример - занимательно, как AlekVolsk (простите меня за тырканье, ничего не имею против AlekVolsk - он просто чисто случайно попался под руку), не глядя, отправил код, содержащий ровно тот баг, что обсуждался в последних сообщениях до него. Типичный пример, "эй, смотри сюда, вот я нашёл кусок кода, который делает то, что тебе нужно, попробуй его! Это рабочий код, я гарантирую это". Copy&Paste во всей красе.

Писать качественный код - тяжело, но это не означает, что это невозможно.

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

1. Явные ошибки. Пример с Base64 является ярким примером. Помимо этого, частым вариантом бывает, что код отработает корректно для ожидаемых данных или только в определённых условиях, но не сработает или, что ещё хуже, приведёт к явному багу в неожиданной ситуации. Часто это следствие отсутствия правильной обработки ошибок (см. ниже). Примеры последнего сценария мы разобрали выше. К счастью, явные ошибки можно обнаружить анализом кода и тестированием, но только если они не скрыты в говно-коде - см. следующий пункт. Но для этого надо хорошо представлять, что же и как делает написанный код. Для этого надо бы читать документацию. Кроме доков тут хорошо работает набор опыта - чтение умных книжек и блогов. Всё это упрощает работу :) Иногда вы используете код, даже не задумываясь о его возможной некорректности. "Ну, все же это используют да? Как это может работать неверно?". Например, способны ли вы без этой ссылки найти проблемы в секции initialization многих модулей? (да простят меня за изжёванную проблему) Или вот (пояснение, почему это баг). Сколько раз вы лично видели (или даже делали) вещи вроде LoadLibrary в initialization или советов с rundll32?

2. Быдло-код и индусский код. Код даже может решать проблему. Причём решать её качественно. Быть устойчивым к ошибкам. (окей: как теоретически возможный случай, недостижимый на практике :D ) Но при этом быть написанным ужасно криво, зачастую нечитабельно. Из-за чего, даже если код корректен, проверить его правильность не представляется никакой возможности. А из-за того, что корректность кода нормально не проверить, то такой код крайне редко бывает хотя бы корректным, не говоря уже о качественности. Обычно такой код нужно/проще выбросить и написать всё с нуля. Этот случай очень легко заметить (код выглядит ужасно), но очень тяжело исправить - обычно нужно писать заново.

3. Обработка ошибок. Вот уж чего вы почти никогда не увидите в примерах кода. Никто не будет с этим заморачиваться. Вам просто выпишут линейную последовательность вызовов функций - что за чем надо вызывать, чтобы добиться результата, а добавить реакцию на ошибки - это уже ваша забота. Примеры мы видели выше. К счастью, вы можете доработать данный код. Но только если речь идёт о работе с API или аналогичными механизмами. Если же код-пример включает в себя работу с исключениями - вы попали. В последнем случае вам придётся переписать код с нуля самому.

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

5. Использование недокументированных возможностей. Это, пожалуй, самый популярный раздел. Этим страдают очень многие. Более того, в определённых кругах считается "высшим шиком" сделать что-нибудь "этакое", что другие не могут, написать какое-то решение с "вкусными" возможностями, которое не создать стандартными средствами (это совсем не обязательно ассемблер). Проблема в том, что они не считают, что программист, садящийся писать под Windows, что-то кому-то там должен (**). Считается, что если ты написал код, который решает задачу любым способом - это достаточно, всё остальное значения не имеет (я не говорю сейчас про сам код, а лишь про то, что он делает). Пример 1 ("а как часто ты ищешь значения в реестре?"). Пример 2. Пример 3. Часто сюда относится неприятие Microsoft и её решений буквально на генетическом уровне. Например, наличие лютой, бешеной ненависти к реестру не даёт вам возможности увидеть красивые решения с его участием. Кроме того, нужно понимать, что правильный ответ на некоторые вопросы вида "как сделать X", - это "не делать X вообще". Этот пункт (использование недокументированных возможностей) не очень сложен в проверке, если только вы понимаете границу между "можно" и "нельзя" - достаточно просто внимательно сравнить код с документацией на используемые им функции. Если функции документированы и описывают поведение, которое использует код - значит всё в порядке. Если же описания поведения нет (например, для какой-то специальной комбинации параметров) или документация вовсе отсутствует - вам лучше бы переписать код или ваша программа имеет высокие шансы сломаться при выходе следующей версии Windows или даже сервис-пака. Вероятно, если вы никогда раньше не задумывались о такой философии (документированный контракт vs детали реализации), вам будет сложно это проверять. Собственно, чаще всего эти проблемы возникают из-за того, что люди просто не читают документацию. Если ты не читаешь документацию, то как ты узнаешь, что документировано и разрешено, а что нет? Когда последний раз вы заглядывали в MSDN или MSDN Library?

6. Повторный вызов или использование. Часто бывает достаточно легко определить некачественный код, если задать себе вопрос: "что будет, если этот код вызовут два раза"? Сюда же входит использование глобальных переменных или невозможность корректно использовать более одного экземпляра класса.

7. Кодировки. Самый важный факт для любого программиста (без исключений): не бывает такой вещи как "просто текст". Очень часто можно видеть код, который не учитывает кодировку текстовых данных. Предположение, что размер символа - 1 байт, - ещё один пример. В 2010-м году вы не можете просто зарыть голову в песок и сделать вид, что ничего этого не существует. Возвращайтесь, пожалуйста, в свои 80-е, но не пишите больше ни строчки кода, спасибо.

8. Безопасность. К сожалению, это очень важная тема, в которой, не то что мало кто разбирается, а часто даже не имеют ни малейшего представления о ней. Но она очень важна. Для любого разработчика без исключений. Это примерно как кодировки: в современном мире вы просто не можете сделать вид, что ничего такого нет. Только о безопасности имеют ещё меньше представления, чем о кодировках, хотя это более важная тема, чем кодировки. Я действительно рекомендую вам прочитать хорошую книжку по этой теме. Это значительно поднимет ваш профессиональный уровень. К счастью, вам не нужно быть экспертом (что действительно сложно), если только вы не разрабатываете решения безопасности, но иметь минимальный обзорный объём знаний вы обязаны (а вот это не так сложно). Это избавит вас от таких типичных ошибок как написание кода, требующего админа (несоблюдение принципа минимальных привилегий), world-writable файлы и PAGE_EXECUTEREADWRITE на секцию кода (я видел такое в реализации хуков, но не могу найти ссылку).

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

Правильный ответ - вы можете использовать готовые библиотеки, где все эти вопросы уже написаны, обсосаны и протестированы. Если хотите качественный код - возьмите его из нормальной библиотеки (JCL, например) или нормальный компонент (***). Нет, люди предпочитают сказать "я хочу написать сам!"/"я не хочу использовать внешние библиотеки!" (кстати, персональный наезд: вы реально задрали уже своим "я не хочу тащить за собой ABC" и минусованием любого решения, использующего стороннюю библиотеку), после чего скопировать в свою программу первый же попавшийся кусок кода в интернете (это называется у них "писать сам"). Почему-то вариант "написать код по аналогии из функции в библиотеке кода" они даже не рассматривают как возможный (видимо, подразумевая, что все качественные библиотеки написаны божьим духом и принципиально невоспроизводимы в коде простых смертных). Нет, я не хочу сказать, что "я хочу написать сам" - это плохо. Пишите. Но пишите сами и думая головой. Взять код в интернете потому что вам не нравится подключение библиотеки - это не называется "писать самому". И нет, я не хочу сказать, что код в больших и известных библиотеках всегда идеален и безошибочен. Люди делают ошибки, поэтому и в библиотеках могут быть баги. Но у нормальных библиотек хотя бы качество кода выше на порядки. Потому что код писали как код общего назначения, пригодный к использованию в самых различных ситуациях, а не как пример. Ключевое различие: библиотеки кода пишут для использования в реальных программах; ответы на форумах и FAQ пишут для ответа на вопрос. Чувствуете разницу? Если да, то я буду считать сегодняшнюю цель выполненной :)

Дополнение: интересная заметка в тему про любителей спрашивать вопросы на форумах. Проблема в том, что предлагая готовое решение на форума, вы ничему не учите человека. Что означает, что возникни в будущем похожая ситуация - он снова задаст вопрос. Он не сумеет с ней справиться самостоятельно. Намного лучше подсказать, направить, посоветовать, подтолкнуть (можно ногой под зад :) ) - т.е. сделать так, чтобы человек сам решил бы проблему. Иными словами, "голодному человеку лучше дать удочку, чем рыбу" (C) Riply.

Примечания:

(*) Этот процесс называется копипейстинг (Copy&Paste). Код, который получается в итоге, называют "быдло-код", а программиста, который так делает - "быдло-кодер", "быдло-программист" или "code monkey" (да, мой ник на некоторых форумах - CodeMonkey :) ).

(**) Я не раз встречал такую реакцию на некоторые ответы: "Почему я обязан так делать? Почему Microsoft имеет право диктовать мне, как мне поступать? Вот я хочу сделать иначе - и я это сделаю". Дело в том, что Windows - это продукт Microsoft (сюрприз, да). И она диктует здесь правила. Равно как и Apple диктует правила для MacOS. Почему-то это удивляет многих людей. К примеру, Microsoft может использовать недокументированные функции, а вы - нет. Нет, формально говоря, вы никому ничего не должны. Вы можете писать программу, как вам вздумается. Только не удивляйтесь потом, почему её выкидывают на помойку. Почаще заглядывайте в MSDN почитать guideline-ы. Бывает довольно полезно.

(***) Ключевой момент - нормальной библиотеки. Дело в том, что существуют библиотеки или компоненты, которые пишутся примерно по тому же принципу, что и составляются FAQ - просто копированием кода из форумов и собирания его в кучу. Конечно же, вам такая библиотека не нужна. Как узнать, нормальная это библиотека или нет? А вы посмотрите на её код. Только так и никак иначе. С набором опыта вам достаточно будет бегло пробежаться по коду, чтобы примерно оценить его качество. Именно поэтому я искренне не понимаю людей, которые ставят компоненты или библиотеки без исходных кодов (неважно: бесплатные или платные). Ребята, неужели вы не хотите убедиться, что вставляете в свою программу не говно-код? Замечу, что показатель популярности не является хоть каким-то показателем качественности кода. Пальцем показывать не буду, наверняка, все и так видели примеры.

(без звёздочки, для педантов): да, я знаю, что из сказанного выше бывают исключения. Что есть ситуации, когда вам приходится нарушать правила. Но это - 0.01%. Да, и, пожалуйста, не надо в комментариях холивара Windows vs Linux vs MacOS, спасибо.

30 комментариев :

  1. В принципе, соглашусь со всем вышесказанным :)

    ОтветитьУдалить
  2. Пост просто замечательный.Спасибо.

    >> Это - сырой полуфабрикат
    Ну можно же "пожарить" (адаптировать) =) Это ведь просто форум. На форуме люди просто помогают, а не пишут за вас проекты. Просто помогают двигаться в нужном направлении.

    >> Предположение, что размер символа - 1 байт
    Имхо, это дефакто на всех форумах, если конечно явно не указывается например что это юникод версия итд.

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

    ОтветитьУдалить
  3. не согласен, песня ни о чем.

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

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

    ОтветитьУдалить
  4. >>> Имхо, это дефакто на всех форумах, если конечно явно не указывается например что это юникод версия итд.

    Имеется ввиду данные вне программы. То, чем вы обмениваетесь с другими программами, содержание файлов и т.п., а вовсе не размерность Char, как вы подумали. Кодировки должна учитывать и программа на D2010 и на D7.

    >>> Это должны сделать вы сами

    Если вы это понимаете, то этот пост просто не для вас ;)

    Это пост для тех, кто, увидев в ответе код, говорят: "это работает, спасибо".

    ОтветитьУдалить
  5. >> Имеется ввиду данные вне программы.
    Ой, действительно не в ту степь, извеняюсь =)

    ОтветитьУдалить
  6. Иными словами, "голодному человеку лучше дать удочку, чем рыбу" (C) Riply.
    Хе-хе. С копирайтиком тут ошибочка вышла. Это древне-китайская мудрость (часто приписываемая Лао-Цзы). "Дай человеку рыбу, и он будет сыт весь день. Научи человека ловить рыбу, и он будет сыт всю жизнь."

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

    ОтветитьУдалить
  7. >> Первую версию нужно выпустить как можно скорее, накопипастить чего угодно. Потом сервис-паками латать. Так уж повелось. В большинстве случаев такой подход "катит".

    Точно ) Главное чтобы работало, или хотябы грамотно притворялось )

    ОтветитьУдалить
  8. Я не со всем согласен.

    Библиотеки это хорошо, но не всегда.
    У опенсорсных библиотек есть беда - плохая документация. Я долго пользовался ICS. Хорошая библиотека. Но образцом кода ее не назовешь - это код, который получился в результате длительной эволюции. Об этом можно судить по структуре кода.

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

    ОтветитьУдалить
  9. Я не видел ICS, но специально указал в посте - смотря какая библиотека.

    В качестве хорошей, годной библиотеки кода я привёл JCL.

    ОтветитьУдалить
  10. Насколько я понимаю JCL - это JEDI? Или нет?
    Я из JEDI взял как раз раскрутку стека. Насколько я знаю именно библиотека JEDI использовалась в Д2007 для вывода стека.
    Я вчера посмотрел - в JCL даже дока есть! Но если JCL = JEDI, то дока появилась сравнительно недавно. Видимо, кто-то спонсировал создание документации, наличие которой, согласитесь для опенсорсных проектов вещь редкая.

    Вообще Internet Component Suite достаточно известная библиотека. Француа Пиетт (автор) достаточно известный был персонаж (на 2007 год) в группах Кодгира. Думаю, что он остался таковым, т.к. по рассылке ICS он периодически пишет.

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

    Поясню.

    Для того, чтобы разобраться в опенсорсной библиотеке навык нужен очень серьезный. Я не жалею, что изрядно изучил ICS - я безусловно вырос.

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

    А в целом, с посылом поста согласен - надо изучать примеры, а не передирать их.

    ОтветитьУдалить
  11. JCL - это JEDI Code Library.

    JVCL - JEDI Visual Component Library.

    JWA - JEDI Windows API.

    JWSCL - JEDI Windows Security Code Library (в последнее время входит в состав JWAPI).

    Всё это Project JEDI - джедаи.

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

    Изучение библиотек даёт бонус больший чем решение одной конкретной задачи. В следующий раз, когда у меня возникнет другая задача - я не буду писать для неё решение сам и даже не полезу на форумы (ладно, когда последний раз я вообще задавал вопрос? :) ) - я просто возьму один или несколько кусочков из библиотеки и соединю их вместе, чтобы получить желаемый результат. А использование библиотек общего назначения (типа JCL) существенно упрощает даже повседневные операции. Я, например, без JCL уже никуда - всё равно как с D2010 на D7 пересесть - этого не хватает, того не хватает, всё руками надо делать.

    Не смотреть библиотеки... хм, ну, давайте ещё VCL и RTL не будем изучать. Лучше выбрать библиотеку по каждому направлению (система, сеть, и т.п.) и хорошо её изучить. Выбирать, понятно, надо не абы какую, а... самую лучшую =))) В понятие "самая лучшая" входит и наличие документации, если вам это нужно. Лично я в доки обычно не смотрю - если надо смотреть в доки, это либо очень сложная либа (типа некоторых DevExpress-ских продуктов), либо у неё плохой и не интуитивный дизайн - а зачем она тогда мне нужна?

    Нужна была тебе дока - взял бы Indy или Synapse. А у ICS, несмотря на отсутствие доков, есть демки.

    ОтветитьУдалить
  12. P.S. Почему-то перепутал вас с Тимохиным Алексеем - видимо, поздно уже :) Просто обычно я на "вы", да и отвечал вроде как ему :)))

    ОтветитьУдалить
  13. Александр, программисты всегда на "ты" )))
    Я сам удивился схожести фамилий с Алексеем )))

    Фу, Indy - сами пользуйтесь этим говном (я так понял, это разрешенное слово). ))

    Опять же - надо выбрать библиотеку. Это не так просто. Т.к. работать вроде как надо. На выборы особенно времени нет. Так еще риск немалый - потратишь время, а окажется так себе.

    Ладно, не будем спорить - у всех своя часть правды )

    PS У JEDI стала дока однозначно лучше за последние 5 лет. Честно говоря, у меня появилось большое желание поизучать библиотеку. Благодарю.

    ОтветитьУдалить
  14. >>> К примеру, Microsoft может использовать недокументированные функции, а вы - нет
    Если собираешься делать аналог программы Микрософт (но лучше ;-)), то вынужден будешь использовать те же недокументированные возможности. Иначе просто не получится лучше. Но при этом нужно:

    1. Явно указывать для какой версии (и, может быть, даже подверсии) написана программа.

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

    --
    Geo

    ОтветитьУдалить
  15. >>> вынужден будешь использовать

    См.

    >>> да, я знаю, что из сказанного выше бывают исключения.

    ;)

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

    ОтветитьУдалить
  16. Очень часто человек просто не хочет включать голову. Вообще. Принципиально.

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

    ОтветитьУдалить
  17. Несерьезный подход покатит для разработки только неответственных программ, как правило - это не системные программы являющиеся по сути интерфейсом для пользователя.

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

    ОтветитьУдалить
  18. Тогда вы тоже говнокодерствуете!

    ОтветитьУдалить
  19. У вас это личное. С вязаное тем что написали. Баттхэрт какой то.

    ОтветитьУдалить
  20. Этот пост был написан "кидаться ссылкой". Как уже выше сказали - многие не понимают таких простых вещей.

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

    ОтветитьУдалить
  22. прошло 6 лет и теперь можно с увереностью сказать 99%

    ОтветитьУдалить
  23. Этот комментарий был удален автором.

    ОтветитьУдалить
  24. Пример говонкода: "Производили ли вы переписывание или хотя бы анализ кода, перед тем как это сделать, или же дело закончилось отпиской "огромное спасибо, этот код подошёл!"?
    Если вы ответили да, то вы только что создали...."

    Не отвечают на или-вопросы - "да". type mismatch :-D

    ОтветитьУдалить
  25. > Самый важный факт для любого программиста (без исключений): не бывает такой вещи как "просто текст".

    404 :-D

    ОтветитьУдалить
  26. https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ - возможно, переводов больше нет

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и (опционально) ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

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

Примечание. Отправлять комментарии могут только участники этого блога.