16 сент. 2009 г.

Слишком универсально

Многие сталкивались в своей жизни со странной процедурой «апгрейда» устройств: где-то надо отпаять перемычку, где-то замкнуть пару контактов, где-то «разлочить» устройство, чтобы удалить один файл, являющийся для него флагом эконом-класса. Это бывает с процессорами и сотовыми телефонами, с велокомпьютерами и GPS-навигаторами... Суть одна - производителю дешевле делать качественные вещи с нужными функциями, но у части экземпляров отключать некоторые из них.

Теперь вопрос: позволяет ли это производителю снизить цену на товары нижнего уровня? Нет, потому что он сначала делает именно полноценное устройство, обладающее всеми функциями (а себестоимость от сокрытия нескольких функций не падает). Это означает, что производитель таким образом может только повысить цену на товары верхнего уровня.

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

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

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

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

int i, j;
for (i=0; i<10; i++) {
for (j=0; i<10; i++) {
// ... сложный код
}
}

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

Есть языки программирования, синтаксис которых не требует трижды указывать имя одной переменной, если необходимо перебрать целые значения от одной величины до другой (я думаю, вы согласитесь, что это самое распространённое применение цикла for). Их ограниченная спецификация не позволяет делать некоторые интересные трюки, которые легко удаются C-программистам, но она не позволяет делать таких ошибок. Полагаю, это хороший пример слишком мощного инструмента, приглашающего наделать глупых ошибок, который крайне редко используется в полную мощь. Кстати, некоторые участники олимпиад по программированию используют специальные макросы вида «FOR(i,a,b)», которые автоматически раскрываются в конструкцию «for(i=(a);i<(b);i++)» - это позволяет быстрее реализовывать простой код, заведомо избегая подобных распространённых граблей.

Вспоминается по этому поводу история, которую рассказывал Терехов Андрей Николаевич - генеральный директор ТЕРКОМ. Когда он только начинал делать программно-аппаратные комплексы для различных военных задач, ему довелось участвовать в обсуждении установки, которую создали за многие годы до того разговора. И он произнёс довольно резкие слова по поводу производительности той системы - «как же так надо было проектировать, что включение установки и её подготовка к работе происходят целых полторы минуты?». На что неожиданно отреагировал очень взрослый и опытный конструктор (как оказалось, это был создатель обсуждаемого комплекса): «Во-первых, личный состав по нормативам должен успевать приготовиться к выполнению боевой задачи за две минуты, поэтому старт за полторы - это вполне достаточно, а во-вторых, попробуйте сначала сами сконструировать систему, которая будет надёжно работать в боевых условиях» (если я правильно помню, то вычислительное устройство могли монтировалось на ГАЗ-66 и БМП, подвеска которых не отличается мягкостью).

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

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

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

Хорошего вам дня!

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

  1. Интересная заметка, но всё же отмечу, что порой некоторая универсальность и даже некоторая избыточность не так уж и плоха.
    И то что сейчас кажется ненужным, позже позволит избежать ошибок, проще расширить возможности продукта (програмного и не только)... Задел на будущее так сказать.
    Возьмём тот же макросс FOR(i,a,b) и попробуем запустить с параметрами FOR(i,0,7^13).
    ^ - это исключающее или (xor), вполне может использоваться для создания маски.
    7^13=10. В чём загвоздка? А вы попробуйте запустить программу.
    А вот «лишние» скобочки for(i=(a);i<(b);i++) сделали бы макрос более универсальным и уберегли бы нас от ошибки.

    Более известный пример пренебрежения скобочками в макросах:
    #include "stdio.h"
    #define SIX 1+5
    #define NINE 8+1
    int main(void)
    {
    int value = SIX * NINE;
    printf("Answer = %d\n", value);
    return 0;
    }


    Что я хотел сказать своим сообщением? А то, что универсальность и избыточность не есть зло само по себе. Просто во всём нужна мера.

    ОтветитьУдалить
  2. Макросы тоже слишком универсальны. Считаю что грамотный плюсист должен помнить об STL, в частности об алгоритмах оттуда, применяемых к коллекциям.

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

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

    И, конечно, надо знать меру.

    ОтветитьУдалить
  4. Анонимный16.09.2009, 15:51

    Мда использование макросов это конечно удел "грамотных плюсистов".
    ИМХО даже для примера не катит

    ОтветитьУдалить
  5. Анонимный16.09.2009, 19:02

    Где спортивное программирование, а где грамотные плюсисты? Для каждой задачи есть своё решение, которое не подойдёт для других задач! Никто же не заставляет отказываться от мощи stl, где это уместно, поэтому нечего называть пользователей макросов дураками! Я использую макросы, где это облегчает жизнь, не зря же их в стандарт языка включили.

    Анатолий

    ОтветитьУдалить
  6. >> как оно работает - хорошо выполняет свои функции или плохо

    По-моему точнее будет - решает оно (устройство) Ваши задачи или нет

    Я не придираюсь, просто "хорошо" и "плохо" очень относительные понятия и субъективные.

    ОтветитьУдалить
  7. Уважаемый аноним, мнение "это не катит" гораздо интереснее читать, когда оно сопровождается объяснением :) И ещё диалог получается конструктивнее, если оппоненту не приписывать высказываний, которые он не делал.

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

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

    ОтветитьУдалить
  8. Анонимный17.09.2009, 10:29

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

    Простой пример извращенной политики производителей. Пример: по ТВ постоянно идет реклама лотереи, проводимой пивной компанией. Обратите внимание, стимулируют потребление не качеством отечественного пива (ужасное качество), а возможностью получить что-то на халяву.

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

    Каждый из вас пусть достанет свою мобилу. Это телефон... Но там есть фотоаппарат, диктофон, плейер, радио, несколько десятков программ, встроенный модем, 2-3 системы безпроводной связи... И все это телефон.

    Основная функция изделия - телефонные разговоры. Стимуляция покупки более новой модели проводится не за счет повышения качества этой функции (хотя там уже нечего улучшать - тут больше зависимость от оператора), сколько ВПАРИВАНИЕ новых "фич"... И тут на лицо правило Паретто: 90% этих функций пользуется меньше 10% времени эксплуатации аппарата.

    При этом, чем сложней аппарат, тем он менее надежен, тем он более чувствителен к внешней среде и т.п.

    А вы, макросы, скобки...

    ОтветитьУдалить
  9. Аноним, ответ про скобочки тоже был в пример того, что универсальность не всегда так уж плохо.

    На счёт мобильного с вами не соглашусь:
    1) Я, например, как плеер/радио использую его значительно чаще, чем для звонков/смс.
    Так что получается, что у меня возможность позвонить - побочная функция, а не главная.
    2) Почему не купить отдельно телефон, отдельно плеер? Потому что мне надо иметь постоянно и то и то и один девайс мне удобней носить, чем 2.
    Вот и первый + универсальности.
    3) В чём полезность остальных фич? Да, на них правило Паретто действует.
    Но! Я же не буду носить с собой постоянно фотоаппарат или отдельный девайс для выхода в интернет.
    Но вот настали те 10%, когда мне эти функции нужны. Да качество фоток и видео будет не очень хорошим, да WAP интернет небыстрый и дороговатый, да с Т9 мне не очень удобно печатать (хотя это уже дело привычки), но зато все эти функции у меня под рукой тогда, когда они мне всё же понадобятся. Вот в этом второй + универсальности, вот за это я и плачу производителю телефона.
    Да если я заранее знаю, что надо что-нибудь сфотографировать, я возьму с собой фотоаппарат, но зачастую же я этого не знаю.
    4) А вот это «чем сложней аппарат, тем он менее надежен» - голословное утверждение. Даже если оно кажется вам очевидным, то читая этот блог, вы должны были понять, что очевидное не всегда оказывается верным.

    ОтветитьУдалить
  10. Анонимный17.09.2009, 22:59

    > Я, например, как плеер/радио использую его значительно чаще, чем для звонков/смс.
    Так что получается, что у меня возможность позвонить - побочная функция, а не главная.

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

    > Вот и первый + универсальности

    это первый минус универсальности. компромис он потому и компромис, что идет в ущерб обеим сторонам... если вас устраивает посредственный плеер, пользуйтесь...

    > голословное утверждение

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

    простой пример: программа Hello World не имеет ошибок... вы можете это сказать о современном текстовом редакторе? браузере?

    второй пример. обычная отвертка ломается? да ее можно поломать или сточить шлицы, но это сделать сложнее чем сломать электрошуруповерт.

    поверьте мне, человеку имеющему ТЕХНИЧЕСКОЕ образование, чем больше узлов и агрегатов используется в изделии, тем менее оно надежно, при прочих равных...

    ОтветитьУдалить
  11. Поверьте мне, как человеку имеющему Техническое образование, что это не всегда так.
    Всё дело в том, что "прочих равных" нету.
    А неравность именно в применяемых технологиях.
    Например компьютеры (по мере технического усложнения):
    1) обычный домашний настольный (ну иди офисный - не суть важно),
    2) специализированный серверный,
    3) супер-компьютер.
    Так вот тут как раз получится, что чем сложнее изделие, тем оно надёжнее.
    Расплатой за более «продвинутые» технологии в данном случае является возрастающая цена и потребляемые ресурсы.
    И это всё на едином временном срезе технологий, а так можно вспомнить и ламповый компьютер, который технологически намного проще, чем современный ПК, но ломался намного чаще.

    ОтветитьУдалить
  12. Анонимный18.09.2009, 9:53

    вы сравниваете мягкое и теплое... вы же домой себе не купите супперЭВМ.

    Мы говорим о потребностях и тратах обычного гражданина.

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

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

    ОтветитьУдалить
  13. > вы же домой себе не купите супперЭВМ
    Не куплю потому, что:
    1) не зарабатываю столько;
    2) в моей квартирке он банально не поместится;
    3) разорюсь на оплате электроэнергии, да и проводка его банально не выдержит.
    А вот серверную комплектацию вполне возможно... со временем...
    ИБП и Raid использую уже сейчас.
    На счёт современных приставок не знаю, возможно они стали стрессоустойчивы.
    На Денди в своё время сгорал блок питания, дважды ломался джостик.
    При этом за всё время работы за компьютерами ни разу не сломал клаву и не спалил блок питания (начиная с 286-ого).
    Сломанных китайских калькуляторов несколько штук.
    ДВД-плеером никогда не пользовался, та что ничего сказать не могу.

    Конечно, опыт одного человека непоказателен, но всё же.

    ОтветитьУдалить
  14. Анонимный21.09.2009, 11:39

    Не согласен с тем, что производители выпускают тот же продукт с искусственными ограничениями просто для того, чтобы продавать то же устройство без ограничений за большую цену. Такие "разлочки" применялись в основном к видеокартам, притом всегда были сопряжены с риском, что оно не заработает после данной операции. Просто процесс производства современных видеокарт довольно сложен, и процент брака на выходе довольно велик. Устройства без брака - это обычные полнофункциональные устройства. Если же в партии произведённых видеокарт на взятых для тестирования образцах выясняется, что не работает часть конвееров обработки графики - что делать с такой видеокартой? Залочить неработающие конвееры и выпустить эту партию в продажу по пониженной стоимости вполне разумное решение. Разумеется, что, поскольку на дефекты тестируется не вся партия, а только часть - среди непртестированного материала встечаются полностью функциональные образцы. Их и можно безопасно разлочить. Процент поддающихся "разлочке" устройств для разных партий разный. Именно поэтому, если почитать форумы фанатов такого "апгрейда", можно найти рекомендации, продукцию каких фирм и каких серий стоит покупать для этого. Если б производители просто блокировали часть функций абсолютно работающего устройства - таких рекомендаций не было бы, как не было бы и неудачных "апгрейдов".

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

    Отмечу только, что Ваши знания о видеокартах не мешают другим людям знать о прочих залоченных устройствах: сотовых телефонах и коммуникаторах, GPS-навигаторах и велокомпьютерах, фотоаппаратах, процессорах и mp3-плеерах, и так далее.

    ОтветитьУдалить
  16. Есть ещё хорошие примеры урезания функциональности - http://sfrolov.livejournal.com/65479.html

    ОтветитьУдалить
  17. Автор, похоже, не в курсе, что стоимость серийных изделий напрямую зависит от объёмов производства, то есть от «тиражности». Это всё равно как напечатать книгу в одном экземпляре — стоимость будет такая же, как на минимальный тираж из 5000 книг, к примеру, то есть цена единичного экземпляра будет в 5000 раз выше, чем у массового. А вот представьте, что мы хотим сделать 5 вариантов одной и той же книги: можно напечатать 5 тиражей по 1000 экземпляров или 1 большой тираж и проводить уже послепечатную подготовку — во втором случае затраты будут почти в 5 раз ниже, чем в первом.

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


    Что касается видеомагнитофонов, а точнее их современных братьев — DVD-плееров. Они тоже по сути являются миникомпьютерами с обычной операционной системой — опять же, ради удешевления, чтобы не приходилось тратить годы и много денег на собственные разработки. И поэтому такие плееры так же часто глючат и виснут, как и самостоятельно собранные медиацентры. Но, если медиацентр можно расширять, то фиксированный набор функций плеера изначально очень скудный: как правило, поддержка только MPEG-1 / MPEG-2 и ещё, может, DivX 3/4/5. Ни других кодеков, ни HD-разрешения вы от них не добьётесь, хотя теоретических препятствий тому нет — есть лишь чисто конструктивные ограничения, проектная непродуманность. Точнее, продуманность, что, мол, это всё равно никому не надо, да и в техзадании не прописано — «солдафонское мышление» во всей своей красе.

    ОтветитьУдалить
  18. Anton, если бы в Вашем примере кто-то делал большую серию книг, а потом специально заливал краской некоторые страницы у некоторых из них (у "книг для бедных"), то получился бы случай, о котором я говорил выше: цена "чистых" книг существенно взлетает, потому что многие хотят читать нормальное издание, а не испачканное краской.

    ОтветитьУдалить
  19. int i, j;
    for (i=0; i<10; i++) {
    for (j=0; i<10; i++) {
    // ... сложный код
    }
    }

    По-моему, за такой стиль именования переменных надо отрывать руки и отлучать от компьютера на века.

    int column, row;
    for (row=0; row<10; i++) {
    for (column=0; column<10; i++) {
    // ... сложный код
    }
    }

    Код стал чуть-чуть понятнее. И ошибиться незаметно уже не получится.

    ОтветитьУдалить
  20. deadyaga, Вы правы, переменные надо называть нормально. Но даже это не помешало Вам написать i++ в обоих циклах в своей версии кода. Соответственно, если где-то ранее переменная i была объявлена, то компилятор не укажет на эту ошибку, из-за чего будет, скорее всего, бесконечный цикл.

    ОтветитьУдалить
  21. Илья Весенний я часа четыре потратил на написания ответа, мне надо ещё часа два, чтобы раскрыть тему полностью. :-) Прерываюсь, на выходные, как только закончу дам ссылку.

    ОтветитьУдалить
  22. Извиняюсь, были более срочные дела, чем дописать пост. Надеюсь в пятницу я допишу-таки его. А пока в качестве компенсации предлагаю пост о моих впечатления о книге "Побеждают все" Карла Лионса. Эта книга о том, как вести переговоры. Здесь я выложил отдельно часть упомянутых там техник.

    ОтветитьУдалить
  23. Тут прозвучало как-то много комментариев на тему "за такие имена переменных надо руки отрывать" - плохое утверждение, особенно если дело касается математических расчетов.
    Еще с университета будучи приученным именовать индексы матриц i,j,k это кажется на много естественнее чем row, column, slice.
    Особенно в длинных именах легко заблудиться если они участвуют в больших формулах и помимо индексов там присутствуют еще правильно проименованные внешние переменные.

    По поводу устройств. Сравнительное качество девайсов из одной линейки - это еще пол беды.
    Беда же на мой взгляд заключается в другом: сами по себе устройства со временем становятся все менее и менее надежными.
    Взять например жесткий диск: в 1999 или 2000 (точнее не помню) купленный 13ГБ жесткий диск служил до 2008года, купленный же в 2007 году 320Гб диск служил до 2009го.
    Если прикинуть пропорции, то срок жизни гигабайта сократился просто таки драматически.
    То же самое и с другими вещами: недавно выкинул телевизор деу проработавший 17 лет и переставший работать вероятно из-за скопившейся где-то внутри пыли и спустя месяц выкинул жк телевизор, проработавший 4 года.

    Да что там говорить... с людьми та же хрень, у меня прадед дожил до 124, дед до 85 - пугающая прогрессия :)

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

Понравилась заметка? Подпишитесь на RSS-feed или email-рассылку.

Хотите поделиться ссылкой с другими? Добавьте в закладки:



Есть вопросы или предложения? Пишите письма на адрес mytribune АТ yandex.ru.

С уважением,
      Илья Весенний